diff --git a/backend/db/db.go b/backend/db/db.go index 315118a..366b374 100644 --- a/backend/db/db.go +++ b/backend/db/db.go @@ -23,7 +23,12 @@ func Connect() error { getEnv("POSTGRES_DB"), ) - pool, err := pgxpool.New(context.Background(), dsn) + poolCfg, err := pgxpool.ParseConfig(dsn) + if err != nil { + return err + } + poolCfg.ConnConfig.RuntimeParams["timezone"] = "UTC" + pool, err := pgxpool.NewWithConfig(context.Background(), poolCfg) if err != nil { return err } diff --git a/backend/db/db_dev.go b/backend/db/db_dev.go index 3724cf0..ffca459 100644 --- a/backend/db/db_dev.go +++ b/backend/db/db_dev.go @@ -22,7 +22,12 @@ func Connect() error { getEnv("POSTGRES_DB"), ) - pool, err := pgxpool.New(context.Background(), dsn) + poolCfg, err := pgxpool.ParseConfig(dsn) + if err != nil { + return err + } + poolCfg.ConnConfig.RuntimeParams["timezone"] = "UTC" + pool, err := pgxpool.NewWithConfig(context.Background(), poolCfg) if err != nil { return err } diff --git a/backend/db/proxy.go b/backend/db/proxy.go index 82863c1..8a30fa6 100644 --- a/backend/db/proxy.go +++ b/backend/db/proxy.go @@ -11,6 +11,20 @@ import ( // Querier is implemented by *pgxpool.Pool, pgx.Tx, and *PoolProxy. // Fixture functions and internal helpers that need to run queries should // accept Querier to remain decoupled from transaction state. +// +// DISTINCTION: QueryRow vs Querier +// - QueryRow() (lowercase 'r') is a METHOD on Querier. It returns pgx.Row. +// Call it like: row := q.QueryRow(ctx, sql, args...) +// - Querier (uppercase 'Q') is an INTERFACE. It declares the QueryRow method. +// Accept Querier when a helper must work with both pool + transactions. +// - pgx.Row (singular) is the RETURN TYPE of QueryRow(). It is NOT a Querier. +// pgx.Row only has Scan(). You cannot pass a pgx.Row where Querier is expected. +// +// Common mistake: +// // WRONG — pgx.Row does not implement Querier: +// func helper(ctx, row pgx.Row) { ... } +// // CORRECT — accept Querier, call QueryRow inside: +// func helper(ctx, q db.Querier) { row := q.QueryRow(ctx, sql, args...); ... } type Querier interface { Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)