package accounts import ( "context" "errors" "fmt" "ruben/inventory2/internal/consts" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) type ( Store struct { db *pgxpool.Pool } StoreWithContext struct { ctx context.Context db *Store } Account struct { ID int64 Email string } ) func NewStore(db *pgxpool.Pool) *Store { return &Store{ db: db, } } func (db *Store) WithContext(ctx context.Context) *StoreWithContext { return &StoreWithContext{ ctx: ctx, db: db, } } func (db *Store) CreateAccount(ctx context.Context, email string) (Account, error) { rows, err := db.db.Query( ctx, "INSERT INTO accounts (email) VALUES (@email) RETURNING account_id", pgx.NamedArgs{ "email": email, }, ) if err != nil { return Account{}, fmt.Errorf("failed to perform query: %w", err) } acctID, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[int64]) if err != nil { return Account{}, fmt.Errorf("failed to scan row: %w", err) } return Account{ ID: acctID, Email: email, }, nil } func (db *Store) GetAccount(ctx context.Context, id int64) (Account, error) { rows, err := db.db.Query( ctx, "SELECT email FROM accounts WHERE account_id = @account_id", pgx.NamedArgs{ "account_id": id, }, ) if err != nil { return Account{}, fmt.Errorf("failed to perform query: %w", err) } email, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[string]) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return Account{}, consts.ErrNotFound } return Account{}, fmt.Errorf("failed to scan row: %w", err) } return Account{ ID: id, Email: email, }, nil } func (db *Store) GetAccountByEmail(ctx context.Context, email string) (Account, error) { rows, err := db.db.Query( ctx, "SELECT account_id FROM accounts WHERE email = @email", pgx.NamedArgs{ "email": email, }, ) if err != nil { return Account{}, fmt.Errorf("failed to perform query: %w", err) } id, err := pgx.CollectExactlyOneRow(rows, pgx.RowTo[int64]) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return Account{}, consts.ErrNotFound } return Account{}, fmt.Errorf("failed to scan row: %w", err) } return Account{ ID: id, Email: email, }, nil } func (db *StoreWithContext) CreateAccount(email string) (Account, error) { return db.db.CreateAccount(db.ctx, email) } func (db *StoreWithContext) GetAccount(id int64) (Account, error) { return db.db.GetAccount(db.ctx, id) }