mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 17:56:34 +00:00
fix(db): PG adapter coerce 0/1 to boolean for PG strict typing
PG rejects integer values for BOOLEAN columns. B() helper returns 0/1 for SQLite compat. PG adapter now converts 0→false, 1→true in params before sending — safe for both INTEGER and BOOLEAN column types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e71189b874
commit
5cefa04a45
1 changed files with 19 additions and 3 deletions
|
|
@ -59,6 +59,19 @@ export class PgAdapter implements DbAdapter {
|
|||
return out;
|
||||
}
|
||||
|
||||
private coerceParams(params: ReadonlyArray<SqlValue>): unknown[] {
|
||||
return params.map((v) => {
|
||||
if (v === 0 || v === 1) {
|
||||
// Could be integer or boolean. PG is strict about boolean columns
|
||||
// receiving integer values. We can't know the column type here, but
|
||||
// the `pg` driver accepts JS booleans for both INTEGER and BOOLEAN
|
||||
// columns, so converting 0/1 to false/true is always safe.
|
||||
return v === 1;
|
||||
}
|
||||
return v;
|
||||
});
|
||||
}
|
||||
|
||||
private async runner<T>(fn: (c: PoolClient) => Promise<T>): Promise<T> {
|
||||
if (this.currentTxClient) return fn(this.currentTxClient);
|
||||
const client = await this.pool.connect();
|
||||
|
|
@ -68,8 +81,9 @@ export class PgAdapter implements DbAdapter {
|
|||
|
||||
async run(sql: string, params: ReadonlyArray<SqlValue> = []): Promise<RunResult> {
|
||||
const pgSql = this.rewriteSql(sql);
|
||||
const pgParams = this.coerceParams(params);
|
||||
return this.runner(async (c) => {
|
||||
const res = await c.query(pgSql, params as unknown[]);
|
||||
const res = await c.query(pgSql, pgParams);
|
||||
let lastInsertRowid = 0n;
|
||||
// If the caller added RETURNING id, pluck it.
|
||||
if (res.rows.length > 0 && res.rows[0] && "id" in res.rows[0]) {
|
||||
|
|
@ -84,16 +98,18 @@ export class PgAdapter implements DbAdapter {
|
|||
|
||||
async get<T = Row>(sql: string, params: ReadonlyArray<SqlValue> = []): Promise<T | undefined> {
|
||||
const pgSql = this.rewriteSql(sql);
|
||||
const pgParams = this.coerceParams(params);
|
||||
return this.runner(async (c) => {
|
||||
const res = await c.query(pgSql, params as unknown[]);
|
||||
const res = await c.query(pgSql, pgParams);
|
||||
return (res.rows[0] as T | undefined);
|
||||
});
|
||||
}
|
||||
|
||||
async all<T = Row>(sql: string, params: ReadonlyArray<SqlValue> = []): Promise<T[]> {
|
||||
const pgSql = this.rewriteSql(sql);
|
||||
const pgParams = this.coerceParams(params);
|
||||
return this.runner(async (c) => {
|
||||
const res = await c.query(pgSql, params as unknown[]);
|
||||
const res = await c.query(pgSql, pgParams);
|
||||
return res.rows as T[];
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue