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() }