package registry import ( "database/sql" "fmt" "time" ) // Service represents a service in the registry. type Service struct { Name string Active bool CreatedAt time.Time UpdatedAt time.Time } // CreateService creates a new service in the registry. func CreateService(db *sql.DB, name string, active bool) error { _, err := db.Exec( "INSERT INTO services (name, active) VALUES (?, ?)", name, active, ) if err != nil { return fmt.Errorf("create service %q: %w", name, err) } return nil } // GetService retrieves a service by name. func GetService(db *sql.DB, name string) (*Service, error) { s := &Service{} var createdAt, updatedAt string err := db.QueryRow( "SELECT name, active, created_at, updated_at FROM services WHERE name = ?", name, ).Scan(&s.Name, &s.Active, &createdAt, &updatedAt) if err != nil { return nil, fmt.Errorf("get service %q: %w", name, err) } s.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt) s.UpdatedAt, _ = time.Parse("2006-01-02 15:04:05", updatedAt) return s, nil } // ListServices returns all services. func ListServices(db *sql.DB) ([]Service, error) { rows, err := db.Query("SELECT name, active, created_at, updated_at FROM services ORDER BY name") if err != nil { return nil, fmt.Errorf("list services: %w", err) } defer func() { _ = rows.Close() }() var services []Service for rows.Next() { var s Service var createdAt, updatedAt string if err := rows.Scan(&s.Name, &s.Active, &createdAt, &updatedAt); err != nil { return nil, fmt.Errorf("scan service: %w", err) } s.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt) s.UpdatedAt, _ = time.Parse("2006-01-02 15:04:05", updatedAt) services = append(services, s) } return services, rows.Err() } // UpdateServiceActive updates a service's active flag. func UpdateServiceActive(db *sql.DB, name string, active bool) error { res, err := db.Exec( "UPDATE services SET active = ?, updated_at = datetime('now') WHERE name = ?", active, name, ) if err != nil { return fmt.Errorf("update service %q: %w", name, err) } n, _ := res.RowsAffected() if n == 0 { return fmt.Errorf("update service %q: %w", name, sql.ErrNoRows) } return nil } // DeleteService removes a service and all its components (via CASCADE). func DeleteService(db *sql.DB, name string) error { res, err := db.Exec("DELETE FROM services WHERE name = ?", name) if err != nil { return fmt.Errorf("delete service %q: %w", name, err) } n, _ := res.RowsAffected() if n == 0 { return fmt.Errorf("delete service %q: %w", name, sql.ErrNoRows) } return nil }