mirror of
https://github.com/hanzoai/base.git
synced 2026-10-21 03:41:50 +00:00
Three things kept the sql tier from being the tier it is described as. Settings encryption refused to boot. The ciphertext is base64 and the column is jsonb, so Postgres rejected the insert while parsing it as JSON. It is marshalled as a JSON string now and unwrapped on read. This changes the stored shape: a legacy row is read as-is and rewritten on the first settings write, after which an older binary refuses to start rather than misreading it. Forward-only, and loud in the one direction that is not. Every schema change caused a burst of failures. A pooled connection holds a prepared plan whose result type the change invalidates, so the next read on that connection fails once. Reads across twenty add-a-field rounds went from 83 of 160 to 160 of 160. The exec mode is describe_exec, which pgx documents as the one that stays safe when the schema changes underneath it; it costs a parse per execution, worst measured on a local socket and pipelined into the same round trip over a real network. The write pool was capped at one connection on every engine. That is SQLite's single-writer rule and Postgres does not need it. The cap is asked of the connection's own driver now, so the aux database answers for itself. Lifting it makes lock-order deadlocks reachable in one process, where a single connection had been serialising them away. Retrying a serialization failure is what turns concurrent writes from possible into correct. Co-authored-by: Hanzo Dev <[email protected]>
38 lines
1014 B
Go
38 lines
1014 B
Go
//go:build !no_pg_driver
|
|
|
|
package core
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/hanzoai/dbx"
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/stdlib"
|
|
)
|
|
|
|
// PostgresDBConnect creates a new PostgreSQL database connection.
|
|
// The dsn should be a PostgreSQL connection string like:
|
|
// "postgres://user:pass@host:5432/dbname?sslmode=disable"
|
|
//
|
|
// Sizing the pool is the caller's, the same as for a SQLite connection.
|
|
func PostgresDBConnect(dsn string) (*dbx.DB, error) {
|
|
config, err := pgx.ParseConfig(dsn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse PostgreSQL DSN: %w", err)
|
|
}
|
|
|
|
// a statement is described where it is executed, so a connection already
|
|
// in the pool serves the schema as it stands rather than as it stood
|
|
config.DefaultQueryExecMode = pgx.QueryExecModeDescribeExec
|
|
|
|
db := dbx.NewFromDB(stdlib.OpenDB(*config), "pgx")
|
|
|
|
// Verify connection
|
|
if err := db.DB().Ping(); err != nil {
|
|
db.Close()
|
|
return nil, fmt.Errorf("failed to connect to PostgreSQL: %w", err)
|
|
}
|
|
|
|
return db, nil
|
|
}
|