feat: add ResourcesRepo for standard_resources CRUD
This commit is contained in:
parent
713ee233db
commit
8548c9b18b
125
internal/storage/resources_repo.go
Normal file
125
internal/storage/resources_repo.go
Normal file
@ -0,0 +1,125 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
)
|
||||
|
||||
type StandardResourceRecord struct {
|
||||
Name string
|
||||
ResourceType string
|
||||
Version string
|
||||
SHA256 string
|
||||
SizeBytes int64
|
||||
Description string
|
||||
FilePath string
|
||||
CreatedAt string
|
||||
UpdatedAt string
|
||||
}
|
||||
|
||||
type ResourcesRepo struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func NewResourcesRepo(db *sql.DB) *ResourcesRepo {
|
||||
return &ResourcesRepo{db: db}
|
||||
}
|
||||
|
||||
func (r *ResourcesRepo) Save(item StandardResourceRecord) error {
|
||||
if r == nil || r.db == nil {
|
||||
return nil
|
||||
}
|
||||
now := time.Now().Format(time.RFC3339)
|
||||
createdAt := item.CreatedAt
|
||||
if createdAt == "" {
|
||||
createdAt = now
|
||||
}
|
||||
updatedAt := item.UpdatedAt
|
||||
if updatedAt == "" {
|
||||
updatedAt = now
|
||||
}
|
||||
_, err := r.db.Exec(`
|
||||
INSERT INTO standard_resources(name, resource_type, version, sha256, size_bytes, description, file_path, created_at, updated_at)
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, COALESCE((SELECT created_at FROM standard_resources WHERE name = ?), ?), ?)
|
||||
ON CONFLICT(name) DO UPDATE SET
|
||||
resource_type=excluded.resource_type,
|
||||
version=excluded.version,
|
||||
sha256=excluded.sha256,
|
||||
size_bytes=excluded.size_bytes,
|
||||
description=excluded.description,
|
||||
file_path=excluded.file_path,
|
||||
updated_at=excluded.updated_at
|
||||
`, item.Name, item.ResourceType, item.Version, item.SHA256, item.SizeBytes, item.Description, item.FilePath, item.Name, createdAt, updatedAt)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *ResourcesRepo) List() ([]StandardResourceRecord, error) {
|
||||
if r == nil || r.db == nil {
|
||||
return nil, nil
|
||||
}
|
||||
rows, err := r.db.Query(`
|
||||
SELECT name, resource_type, version, sha256, size_bytes, description, file_path, created_at, updated_at
|
||||
FROM standard_resources
|
||||
ORDER BY resource_type, name
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := make([]StandardResourceRecord, 0)
|
||||
for rows.Next() {
|
||||
var item StandardResourceRecord
|
||||
if err := rows.Scan(
|
||||
&item.Name,
|
||||
&item.ResourceType,
|
||||
&item.Version,
|
||||
&item.SHA256,
|
||||
&item.SizeBytes,
|
||||
&item.Description,
|
||||
&item.FilePath,
|
||||
&item.CreatedAt,
|
||||
&item.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, item)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
func (r *ResourcesRepo) ListByType(resourceType string) ([]StandardResourceRecord, error) {
|
||||
if r == nil || r.db == nil {
|
||||
return nil, nil
|
||||
}
|
||||
rows, err := r.db.Query(`
|
||||
SELECT name, resource_type, version, sha256, size_bytes, description, file_path, created_at, updated_at
|
||||
FROM standard_resources
|
||||
WHERE resource_type = ?
|
||||
ORDER BY name
|
||||
`, resourceType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := make([]StandardResourceRecord, 0)
|
||||
for rows.Next() {
|
||||
var item StandardResourceRecord
|
||||
if err := rows.Scan(
|
||||
&item.Name,
|
||||
&item.ResourceType,
|
||||
&item.Version,
|
||||
&item.SHA256,
|
||||
&item.SizeBytes,
|
||||
&item.Description,
|
||||
&item.FilePath,
|
||||
&item.CreatedAt,
|
||||
&item.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, item)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
85
internal/storage/resources_repo_test.go
Normal file
85
internal/storage/resources_repo_test.go
Normal file
@ -0,0 +1,85 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResourcesRepo_SaveAndList(t *testing.T) {
|
||||
store, err := OpenSQLite(filepath.Join(t.TempDir(), "app.db"))
|
||||
if err != nil {
|
||||
t.Fatalf("OpenSQLite: %v", err)
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
repo := NewResourcesRepo(store.DB())
|
||||
err = repo.Save(StandardResourceRecord{
|
||||
Name: "face_gallery_v1",
|
||||
ResourceType: "face_gallery",
|
||||
Version: "auto",
|
||||
SHA256: "abc123",
|
||||
SizeBytes: 52428800,
|
||||
Description: "默认人脸库",
|
||||
FilePath: "resources/standard_resources/face_gallery_v1.db",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Save: %v", err)
|
||||
}
|
||||
|
||||
items, err := repo.List()
|
||||
if err != nil {
|
||||
t.Fatalf("List: %v", err)
|
||||
}
|
||||
if len(items) != 1 || items[0].ResourceType != "face_gallery" || items[0].Version != "auto" {
|
||||
t.Fatalf("unexpected resources: %#v", items)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourcesRepo_ListByType(t *testing.T) {
|
||||
store, err := OpenSQLite(filepath.Join(t.TempDir(), "app.db"))
|
||||
if err != nil {
|
||||
t.Fatalf("OpenSQLite: %v", err)
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
repo := NewResourcesRepo(store.DB())
|
||||
repo.Save(StandardResourceRecord{
|
||||
Name: "face_gallery_v1", ResourceType: "face_gallery",
|
||||
Version: "v1", SHA256: "abc",
|
||||
})
|
||||
repo.Save(StandardResourceRecord{
|
||||
Name: "ppe_dataset_v1", ResourceType: "dataset",
|
||||
Version: "v2", SHA256: "def",
|
||||
})
|
||||
|
||||
items, err := repo.ListByType("face_gallery")
|
||||
if err != nil {
|
||||
t.Fatalf("ListByType: %v", err)
|
||||
}
|
||||
if len(items) != 1 || items[0].Name != "face_gallery_v1" {
|
||||
t.Fatalf("expected 1 face_gallery, got %#v", items)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResourcesRepo_SaveUpsert(t *testing.T) {
|
||||
store, err := OpenSQLite(filepath.Join(t.TempDir(), "app.db"))
|
||||
if err != nil {
|
||||
t.Fatalf("OpenSQLite: %v", err)
|
||||
}
|
||||
defer store.Close()
|
||||
|
||||
repo := NewResourcesRepo(store.DB())
|
||||
repo.Save(StandardResourceRecord{
|
||||
Name: "face_gallery_v1", ResourceType: "face_gallery",
|
||||
Version: "v1", SHA256: "abc",
|
||||
})
|
||||
repo.Save(StandardResourceRecord{
|
||||
Name: "face_gallery_v1", ResourceType: "face_gallery",
|
||||
Version: "v2", SHA256: "xyz",
|
||||
})
|
||||
|
||||
items, _ := repo.List()
|
||||
if len(items) != 1 || items[0].Version != "v2" || items[0].SHA256 != "xyz" {
|
||||
t.Fatalf("expected upserted record v2/xyz, got %#v", items)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user