package registry import ( "context" "database/sql" "reanimator/internal/domain" "reanimator/internal/idgen" ) type ComponentRepository struct { db *sql.DB idgen *idgen.Generator } func NewComponentRepository(db *sql.DB) *ComponentRepository { return &ComponentRepository{ db: db, idgen: idgen.NewGenerator(db), } } func (r *ComponentRepository) Create(ctx context.Context, component domain.Component) (domain.Component, error) { // Generate string ID id, err := r.idgen.Generate(ctx, idgen.Component) if err != nil { return domain.Component{}, err } var lotID interface{} if component.LotID != nil { lotID = *component.LotID } _, err = r.db.ExecContext(ctx, `INSERT INTO parts (id, lot_id, vendor, model, vendor_serial) VALUES (?, ?, ?, ?, ?)`, id, lotID, component.Vendor, component.Model, component.VendorSerial, ) if err != nil { return domain.Component{}, classifyError(err) } return r.Get(ctx, id) } func (r *ComponentRepository) Get(ctx context.Context, id string) (domain.Component, error) { var component domain.Component var lotID sql.NullString var vendor sql.NullString var model sql.NullString row := r.db.QueryRowContext(ctx, `SELECT id, lot_id, vendor, model, vendor_serial, created_at, updated_at FROM parts WHERE id = ?`, id, ) if err := row.Scan(&component.ID, &lotID, &vendor, &model, &component.VendorSerial, &component.CreatedAt, &component.UpdatedAt); err != nil { if err == sql.ErrNoRows { return domain.Component{}, ErrNotFound } return domain.Component{}, err } component.LotID = nullStringToPtr(lotID) component.Vendor = nullStringToPtr(vendor) component.Model = nullStringToPtr(model) return component, nil } func (r *ComponentRepository) List(ctx context.Context) ([]domain.Component, error) { rows, err := r.db.QueryContext(ctx, `SELECT id, lot_id, vendor, model, vendor_serial, created_at, updated_at FROM parts ORDER BY created_at DESC`, ) if err != nil { return nil, err } defer rows.Close() parts := make([]domain.Component, 0) for rows.Next() { var component domain.Component var lotID sql.NullString var vendor sql.NullString var model sql.NullString if err := rows.Scan(&component.ID, &lotID, &vendor, &model, &component.VendorSerial, &component.CreatedAt, &component.UpdatedAt); err != nil { return nil, err } component.LotID = nullStringToPtr(lotID) component.Vendor = nullStringToPtr(vendor) component.Model = nullStringToPtr(model) parts = append(parts, component) } if err := rows.Err(); err != nil { return nil, err } return parts, nil }