package artifacts import ( "context" "database/sql" "errors" "fmt" "git.wntrmute.dev/kyle/exo/core" ) // Publisher represents a publishing entity. type Publisher struct { ID string Name string Address string } // findPublisher looks up a publisher by name and address, returning its ID. func findPublisher(ctx context.Context, tx *sql.Tx, name, address string) (string, error) { var id string row := tx.QueryRowContext(ctx, `SELECT id FROM publishers WHERE name=? AND address=?`, name, address) if err := row.Scan(&id); err != nil { return "", err } return id, nil } // Store persists a Publisher. If a publisher with the same name and address // already exists, it reuses that record. func (p *Publisher) Store(ctx context.Context, tx *sql.Tx) error { if p.ID == "" { id, err := findPublisher(ctx, tx, p.Name, p.Address) if err == nil { p.ID = id return nil } if !errors.Is(err, sql.ErrNoRows) { return fmt.Errorf("artifacts: failed to look up publisher: %w", err) } p.ID = core.NewUUID() } _, err := tx.ExecContext(ctx, `INSERT INTO publishers (id, name, address) VALUES (?, ?, ?)`, p.ID, p.Name, p.Address) if err != nil { return fmt.Errorf("artifacts: failed to store publisher: %w", err) } return nil } // Get retrieves a Publisher by its ID. func (p *Publisher) Get(ctx context.Context, tx *sql.Tx) (bool, error) { if p.ID == "" { return false, fmt.Errorf("artifacts: publisher missing ID: %w", core.ErrNoID) } row := tx.QueryRowContext(ctx, `SELECT name, address FROM publishers WHERE id=?`, p.ID) err := row.Scan(&p.Name, &p.Address) if err != nil { if errors.Is(err, sql.ErrNoRows) { return false, nil } return false, fmt.Errorf("artifacts: failed to look up publisher: %w", err) } return true, nil }