From 320cdc2923e5ed01205e21791805d8a195b3efd6 Mon Sep 17 00:00:00 2001 From: bernard-ng Date: Tue, 17 Mar 2026 19:47:48 +0200 Subject: [PATCH 1/3] fix: #3 move api from T | false to T | undefined --- CHANGELOG.md | 4 +++ .../connection/connection-typed-fetch.test.ts | 2 +- .../driver/driver-result-classes.test.ts | 2 +- src/__tests__/driver/fetch-utils.test.ts | 2 +- .../functional/connection/fetch-empty.test.ts | 12 ++++---- .../functional/lock-mode/none.test.ts | 2 +- src/__tests__/functional/portability.test.ts | 8 +++--- .../platforms/metadata-providers.test.ts | 9 ++++-- ...nnection-charset-metadata-provider.test.ts | 2 +- ...ection-collation-metadata-provider.test.ts | 2 +- src/__tests__/portability/connection.test.ts | 12 ++++---- src/__tests__/portability/converter.test.ts | 6 ++-- src/__tests__/portability/middleware.test.ts | 2 +- src/__tests__/portability/result.test.ts | 18 ++++++------ src/__tests__/portability/statement.test.ts | 12 ++++---- src/__tests__/result/result.test.ts | 14 +++++----- src/connection.ts | 6 ++-- src/driver/array-result.ts | 24 ++++++++-------- src/driver/fetch-utils.ts | 12 ++++---- .../middleware/abstract-result-middleware.ts | 6 ++-- src/driver/mssql/result.ts | 14 +++++----- src/driver/mysql2/result.ts | 14 +++++----- src/driver/pg/connection.ts | 2 +- src/driver/pg/result.ts | 14 +++++----- src/driver/result.ts | 6 ++-- src/driver/sqlite3/result.ts | 14 +++++----- .../connection-charset-metadata-provider.ts | 2 +- .../connection-collation-metadata-provider.ts | 2 +- .../sqlite/sqlite-metadata-provider.ts | 2 +- src/portability/converter.ts | 28 +++++++++++-------- src/portability/result.ts | 18 ++++++------ src/query/query-builder.ts | 8 ++++-- src/result.ts | 12 ++++---- src/schema/mysql-schema-manager.ts | 2 +- 34 files changed, 155 insertions(+), 140 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10442b5..6ba325f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ # Final Doctrine Parity & Production-Ready Release +## 1.1.2 + +- Refactored `fetchNumeric()`, `fetchAssociative()`, and `fetchOne()` across `Result`, `Connection`, `QueryBuilder`, portability wrappers, and all bundled drivers to return `undefined` instead of `false` when no row is available, and aligned unit tests and metadata-provider integrations with the new contract. + # 1.1.1 - Added package subpath entry points like `@devscast/datazen/logging` that resolve directly from published `dist/*` artifacts, including compatibility for older TypeScript `moduleResolution: "node"` projects without shipping extra root wrapper folders. diff --git a/src/__tests__/connection/connection-typed-fetch.test.ts b/src/__tests__/connection/connection-typed-fetch.test.ts index 6275063..8574ed0 100644 --- a/src/__tests__/connection/connection-typed-fetch.test.ts +++ b/src/__tests__/connection/connection-typed-fetch.test.ts @@ -82,7 +82,7 @@ class StaticRowsDriver implements Driver { } } -function expectUserRow(_row: { id: number; name: string } | false): void {} +function expectUserRow(_row: { id: number; name: string } | undefined): void {} describe("Connection typed fetch", () => { it("propagates row type through executeQuery() and Result", async () => { diff --git a/src/__tests__/driver/driver-result-classes.test.ts b/src/__tests__/driver/driver-result-classes.test.ts index bf04276..59d7377 100644 --- a/src/__tests__/driver/driver-result-classes.test.ts +++ b/src/__tests__/driver/driver-result-classes.test.ts @@ -32,7 +32,7 @@ describe("driver result classes", () => { expect(result.fetchOne()).toBe(1); expect(result.fetchNumeric<[number, string]>()).toEqual([2, "Bob"]); - expect(result.fetchAssociative()).toBe(false); + expect(result.fetchAssociative()).toBeUndefined(); expect(result.rowCount()).toBe(2); expect(result.columnCount()).toBe(2); expect( diff --git a/src/__tests__/driver/fetch-utils.test.ts b/src/__tests__/driver/fetch-utils.test.ts index a5fece9..4b5b31e 100644 --- a/src/__tests__/driver/fetch-utils.test.ts +++ b/src/__tests__/driver/fetch-utils.test.ts @@ -22,6 +22,6 @@ describe("FetchUtils parity helpers", () => { 10, 20, ]); expect(FetchUtils.fetchOne(new ArrayResult([{ id: 99 }]))).toBe(99); - expect(FetchUtils.fetchOne(new ArrayResult([]))).toBe(false); + expect(FetchUtils.fetchOne(new ArrayResult([]))).toBeUndefined(); }); }); diff --git a/src/__tests__/functional/connection/fetch-empty.test.ts b/src/__tests__/functional/connection/fetch-empty.test.ts index fa21c7b..d8cc9fa 100644 --- a/src/__tests__/functional/connection/fetch-empty.test.ts +++ b/src/__tests__/functional/connection/fetch-empty.test.ts @@ -13,16 +13,16 @@ describe("Functional/Connection/FetchEmptyTest", () => { query = `SELECT * FROM (${connection.getDatabasePlatform().getDummySelectSQL("1 c")}) t WHERE 1 = 0`; }); - it("returns false for fetchAssociative()", async () => { - expect(await connection.fetchAssociative(query)).toBe(false); + it("returns undefined for fetchAssociative()", async () => { + expect(await connection.fetchAssociative(query)).toBeUndefined(); }); - it("returns false for fetchNumeric()", async () => { - expect(await connection.fetchNumeric(query)).toBe(false); + it("returns undefined for fetchNumeric()", async () => { + expect(await connection.fetchNumeric(query)).toBeUndefined(); }); - it("returns false for fetchOne()", async () => { - expect(await connection.fetchOne(query)).toBe(false); + it("returns undefined for fetchOne()", async () => { + expect(await connection.fetchOne(query)).toBeUndefined(); }); it("returns an empty array for fetchAllAssociative()", async () => { diff --git a/src/__tests__/functional/lock-mode/none.test.ts b/src/__tests__/functional/lock-mode/none.test.ts index 70f56be..658ddf6 100644 --- a/src/__tests__/functional/lock-mode/none.test.ts +++ b/src/__tests__/functional/lock-mode/none.test.ts @@ -78,7 +78,7 @@ describe("Functional/LockMode/NoneTest", () => { let query = "SELECT id FROM users"; query = connection2.getDatabasePlatform().appendLockHint(query, LockMode.NONE); - expect(await connection2.fetchOne(query)).toBe(false); + expect(await connection2.fetchOne(query)).toBeUndefined(); } finally { while (connection2.isTransactionActive()) { await connection2.rollBack(); diff --git a/src/__tests__/functional/portability.test.ts b/src/__tests__/functional/portability.test.ts index fbb7c3a..f352df5 100644 --- a/src/__tests__/functional/portability.test.ts +++ b/src/__tests__/functional/portability.test.ts @@ -35,12 +35,12 @@ describe("Functional/PortabilityTest", () => { assertFetchResultRows(rows); let result = await connection.executeQuery("SELECT * FROM portability_table"); - for (let row = result.fetchAssociative(); row !== false; row = result.fetchAssociative()) { + for (let row = result.fetchAssociative(); row !== undefined; row = result.fetchAssociative()) { assertFetchResultRow(row); } result = await (await connection.prepare("SELECT * FROM portability_table")).executeQuery(); - for (let row = result.fetchAssociative(); row !== false; row = result.fetchAssociative()) { + for (let row = result.fetchAssociative(); row !== undefined; row = result.fetchAssociative()) { assertFetchResultRow(row); } }); @@ -58,8 +58,8 @@ describe("Functional/PortabilityTest", () => { await createPortabilityTable(connection); const row = await connection.fetchAssociative("SELECT * FROM portability_table"); - expect(row).not.toBe(false); - if (row === false) { + expect(row).toBeDefined(); + if (row === undefined) { return; } diff --git a/src/__tests__/platforms/metadata-providers.test.ts b/src/__tests__/platforms/metadata-providers.test.ts index 0cfc1ee..3a44ac7 100644 --- a/src/__tests__/platforms/metadata-providers.test.ts +++ b/src/__tests__/platforms/metadata-providers.test.ts @@ -22,11 +22,14 @@ class StubAsyncQueryConnection { private readonly columns: Record = {}, private readonly numerics: Record = {}, private readonly associatives: Record[]> = {}, - private readonly fetchOneValue: unknown = false, + private readonly fetchOneValue: unknown = undefined, ) {} - public async fetchOne(_sql: string, _params: unknown[] = []): Promise { - return this.fetchOneValue as T | false; + public async fetchOne( + _sql: string, + _params: unknown[] = [], + ): Promise { + return this.fetchOneValue as T | undefined; } public async fetchFirstColumn(sql: string, _params: unknown[] = []): Promise { diff --git a/src/__tests__/platforms/mysql/charset-metadata-provider/connection-charset-metadata-provider.test.ts b/src/__tests__/platforms/mysql/charset-metadata-provider/connection-charset-metadata-provider.test.ts index bb84093..c578ee3 100644 --- a/src/__tests__/platforms/mysql/charset-metadata-provider/connection-charset-metadata-provider.test.ts +++ b/src/__tests__/platforms/mysql/charset-metadata-provider/connection-charset-metadata-provider.test.ts @@ -20,7 +20,7 @@ describe("MySQL ConnectionCharsetMetadataProvider", () => { it("returns null when the charset is not found", async () => { const provider = new ConnectionCharsetMetadataProvider({ - fetchOne: async () => false, + fetchOne: async () => undefined, }); await expect(provider.getDefaultCharsetCollation("missing")).resolves.toBeNull(); diff --git a/src/__tests__/platforms/mysql/collation-metadata-provider/connection-collation-metadata-provider.test.ts b/src/__tests__/platforms/mysql/collation-metadata-provider/connection-collation-metadata-provider.test.ts index 5ad1dfd..7507b99 100644 --- a/src/__tests__/platforms/mysql/collation-metadata-provider/connection-collation-metadata-provider.test.ts +++ b/src/__tests__/platforms/mysql/collation-metadata-provider/connection-collation-metadata-provider.test.ts @@ -18,7 +18,7 @@ describe("MySQL ConnectionCollationMetadataProvider", () => { it("returns null when the collation is not found", async () => { const provider = new ConnectionCollationMetadataProvider({ - fetchOne: async () => false, + fetchOne: async () => undefined, }); await expect(provider.getCollationCharset("missing")).resolves.toBeNull(); diff --git a/src/__tests__/portability/connection.test.ts b/src/__tests__/portability/connection.test.ts index 6272193..79cb5ca 100644 --- a/src/__tests__/portability/connection.test.ts +++ b/src/__tests__/portability/connection.test.ts @@ -8,18 +8,18 @@ import { Connection } from "../../portability/connection"; import { Converter } from "../../portability/converter"; class StubDriverResult implements DriverResult { - public fetchNumeric(): T[] | false { - return false; + public fetchNumeric(): T[] | undefined { + return undefined; } public fetchAssociative = Record>(): | T - | false { - return false; + | undefined { + return undefined; } - public fetchOne(): T | false { - return false; + public fetchOne(): T | undefined { + return undefined; } public fetchAllNumeric(): T[][] { diff --git a/src/__tests__/portability/converter.test.ts b/src/__tests__/portability/converter.test.ts index 4677286..5af2c34 100644 --- a/src/__tests__/portability/converter.test.ts +++ b/src/__tests__/portability/converter.test.ts @@ -18,11 +18,11 @@ describe("Portability Converter parity", () => { expect(converter.convertOne(false)).toBe(false); }); - it("preserves false sentinel for single-row fetch conversions", () => { + it("preserves undefined sentinel for single-row fetch conversions", () => { const converter = new Converter(true, true, ColumnCase.UPPER); - expect(converter.convertNumeric(false)).toBe(false); - expect(converter.convertAssociative(false)).toBe(false); + expect(converter.convertNumeric(undefined)).toBeUndefined(); + expect(converter.convertAssociative(undefined)).toBeUndefined(); }); it("converts fetch-all style arrays and first-column values", () => { diff --git a/src/__tests__/portability/middleware.test.ts b/src/__tests__/portability/middleware.test.ts index a45d6b7..57b7628 100644 --- a/src/__tests__/portability/middleware.test.ts +++ b/src/__tests__/portability/middleware.test.ts @@ -143,7 +143,7 @@ describe("Portability Middleware", () => { id: "A", name: " Bob", }); - expect(result.fetchNumeric()).toBe(false); + expect(result.fetchNumeric()).toBeUndefined(); expect(result.getColumnName(0)).toBe("id"); expect(result.getColumnName(1)).toBe("empty"); }); diff --git a/src/__tests__/portability/result.test.ts b/src/__tests__/portability/result.test.ts index 27023a9..901c77c 100644 --- a/src/__tests__/portability/result.test.ts +++ b/src/__tests__/portability/result.test.ts @@ -17,9 +17,9 @@ class SpyDriverResult implements DriverResult { public constructor( private readonly values: { - numeric?: unknown[] | false; - associative?: Record | false; - one?: unknown | false; + numeric?: unknown[] | undefined; + associative?: Record | undefined; + one?: unknown | undefined; allNumeric?: unknown[][]; allAssociative?: Array>; firstColumn?: unknown[]; @@ -28,21 +28,21 @@ class SpyDriverResult implements DriverResult { } = {}, ) {} - public fetchNumeric(): T[] | false { + public fetchNumeric(): T[] | undefined { this.fetchNumericCalls += 1; - return (this.values.numeric ?? false) as T[] | false; + return this.values.numeric as T[] | undefined; } public fetchAssociative = Record>(): | T - | false { + | undefined { this.fetchAssociativeCalls += 1; - return (this.values.associative ?? false) as T | false; + return this.values.associative as T | undefined; } - public fetchOne(): T | false { + public fetchOne(): T | undefined { this.fetchOneCalls += 1; - return (this.values.one ?? false) as T | false; + return this.values.one as T | undefined; } public fetchAllNumeric(): T[][] { diff --git a/src/__tests__/portability/statement.test.ts b/src/__tests__/portability/statement.test.ts index 9bbd23c..752b72e 100644 --- a/src/__tests__/portability/statement.test.ts +++ b/src/__tests__/portability/statement.test.ts @@ -8,18 +8,18 @@ import { Result as PortabilityResult } from "../../portability/result"; import { DriverStatementWrapper } from "../../portability/statement"; class DummyDriverResult implements DriverResult { - public fetchNumeric(): T[] | false { - return false; + public fetchNumeric(): T[] | undefined { + return undefined; } public fetchAssociative = Record>(): | T - | false { - return false; + | undefined { + return undefined; } - public fetchOne(): T | false { - return false; + public fetchOne(): T | undefined { + return undefined; } public fetchAllNumeric(): T[][] { diff --git a/src/__tests__/result/result.test.ts b/src/__tests__/result/result.test.ts index b0fd120..56f8960 100644 --- a/src/__tests__/result/result.test.ts +++ b/src/__tests__/result/result.test.ts @@ -7,7 +7,7 @@ import { InvalidColumnIndex } from "../../exception/invalid-column-index"; import { NoKeyValue } from "../../exception/no-key-value"; import { Result } from "../../result"; -function expectUserRow(_row: { id: number; name: string } | false): void {} +function expectUserRow(_row: { id: number; name: string } | undefined): void {} const passthroughConnection = { convertException(error: unknown): never { @@ -42,7 +42,7 @@ describe("Result", () => { expect(result.fetchAssociative()).toEqual({ id: 1, name: "Alice" }); expect(result.fetchAssociative()).toEqual({ id: 2, name: "Bob" }); - expect(result.fetchAssociative()).toBe(false); + expect(result.fetchAssociative()).toBeUndefined(); }); it("returns a clone when fetching associative rows", () => { @@ -50,11 +50,11 @@ describe("Result", () => { const row = result.fetchAssociative<{ id: number; name: string }>(); expect(row).toEqual({ id: 1, name: "Alice" }); - if (row !== false) { + if (row !== undefined) { row.name = "Changed"; } - expect(result.fetchAssociative()).toBe(false); + expect(result.fetchAssociative()).toBeUndefined(); }); it("fetches numeric rows using explicit column order", () => { @@ -147,7 +147,7 @@ describe("Result", () => { const result = createResult(new ArrayResult([{ id: 1 }])); result.free(); - expect(result.fetchAssociative()).toBe(false); + expect(result.fetchAssociative()).toBeUndefined(); expect(result.rowCount()).toBe(0); }); @@ -221,8 +221,8 @@ describe("Result", () => { fetchNumeric: () => { throw driverError; }, - fetchAssociative: () => false, - fetchOne: () => false, + fetchAssociative: () => undefined, + fetchOne: () => undefined, fetchAllNumeric: () => [], fetchAllAssociative: () => [], fetchFirstColumn: () => [], diff --git a/src/connection.ts b/src/connection.ts index 80ee2e2..2fb7f7a 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -201,7 +201,7 @@ export class Connection { sql: string, params: QueryParameters = [], types: QueryParameterTypes = [], - ): Promise { + ): Promise { return (await this.executeQuery(sql, params, types)).fetchAssociative(); } @@ -209,7 +209,7 @@ export class Connection { sql: string, params: QueryParameters = [], types: QueryParameterTypes = [], - ): Promise { + ): Promise { return (await this.executeQuery(sql, params, types)).fetchNumeric(); } @@ -217,7 +217,7 @@ export class Connection { sql: string, params: QueryParameters = [], types: QueryParameterTypes = [], - ): Promise { + ): Promise { return (await this.executeQuery(sql, params, types)).fetchOne(); } diff --git a/src/driver/array-result.ts b/src/driver/array-result.ts index 42b9cb1..1cd6619 100644 --- a/src/driver/array-result.ts +++ b/src/driver/array-result.ts @@ -18,40 +18,40 @@ export class ArrayResult implements DriverResult { this.rows = [...rows]; } - public fetchNumeric(): T[] | false { + public fetchNumeric(): T[] | undefined { const row = this.fetchAssociative(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } return this.getColumnsFromRow(row).map((column) => row[column]) as T[]; } - public fetchAssociative(): T | false { + public fetchAssociative(): T | undefined { const row = this.rows[this.cursor]; if (row === undefined) { - return false; + return undefined; } this.cursor += 1; return { ...row } as T; } - public fetchOne(): T | false { + public fetchOne(): T | undefined { const row = this.fetchNumeric(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } const value = row[0]; - return value === undefined ? false : (value as T); + return value as T | undefined; } public fetchAllNumeric(): T[][] { const rows: T[][] = []; let row = this.fetchNumeric(); - while (row !== false) { + while (row !== undefined) { rows.push(row); row = this.fetchNumeric(); } @@ -63,7 +63,7 @@ export class ArrayResult implements DriverResult { const rows: T[] = []; let row = this.fetchAssociative(); - while (row !== false) { + while (row !== undefined) { rows.push(row); row = this.fetchAssociative(); } @@ -75,7 +75,7 @@ export class ArrayResult implements DriverResult { const values: T[] = []; let value = this.fetchOne(); - while (value !== false) { + while (value !== undefined) { values.push(value); value = this.fetchOne(); } diff --git a/src/driver/fetch-utils.ts b/src/driver/fetch-utils.ts index c10285a..e9f1765 100644 --- a/src/driver/fetch-utils.ts +++ b/src/driver/fetch-utils.ts @@ -1,10 +1,10 @@ import { Result } from "./result"; export class FetchUtils { - public static fetchOne(result: Result): T | false { + public static fetchOne(result: Result): T | undefined { const row = result.fetchNumeric(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } return row[0] as T; } @@ -13,7 +13,7 @@ export class FetchUtils { const rows: T[][] = []; let row = result.fetchNumeric(); - while (row !== false) { + while (row !== undefined) { rows.push(row as T[]); row = result.fetchNumeric(); } @@ -27,7 +27,7 @@ export class FetchUtils { const rows: T[] = []; let row = result.fetchAssociative(); - while (row !== false) { + while (row !== undefined) { rows.push(row); row = result.fetchAssociative(); } @@ -39,7 +39,7 @@ export class FetchUtils { const rows: T[] = []; let value = result.fetchOne(); - while (value !== false) { + while (value !== undefined) { rows.push(value); value = result.fetchOne(); } diff --git a/src/driver/middleware/abstract-result-middleware.ts b/src/driver/middleware/abstract-result-middleware.ts index 382665e..19b8cc1 100644 --- a/src/driver/middleware/abstract-result-middleware.ts +++ b/src/driver/middleware/abstract-result-middleware.ts @@ -7,17 +7,17 @@ type ResultWithColumnName = DriverResult & { export abstract class AbstractResultMiddleware implements DriverResult { constructor(private readonly wrappedResult: DriverResult) {} - public fetchNumeric(): T[] | false { + public fetchNumeric(): T[] | undefined { return this.wrappedResult.fetchNumeric(); } public fetchAssociative = Record>(): | T - | false { + | undefined { return this.wrappedResult.fetchAssociative(); } - public fetchOne(): T | false { + public fetchOne(): T | undefined { return this.wrappedResult.fetchOne(); } diff --git a/src/driver/mssql/result.ts b/src/driver/mssql/result.ts index eced29d..ac12fa9 100644 --- a/src/driver/mssql/result.ts +++ b/src/driver/mssql/result.ts @@ -15,19 +15,19 @@ export class Result implements DriverResult { this.rows = [...rows]; } - public fetchNumeric(): T[] | false { + public fetchNumeric(): T[] | undefined { const row = this.fetchAssociative(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } return this.getColumnsFromRow(row).map((column) => row[column]) as T[]; } - public fetchAssociative(): T | false { + public fetchAssociative(): T | undefined { const row = this.rows[this.cursor]; if (row === undefined) { - return false; + return undefined; } this.cursor += 1; @@ -35,7 +35,7 @@ export class Result implements DriverResult { return { ...row } as T; } - public fetchOne(): T | false { + public fetchOne(): T | undefined { return FetchUtils.fetchOne(this); } @@ -47,7 +47,7 @@ export class Result implements DriverResult { const rows: T[] = []; let row = this.fetchAssociative(); - while (row !== false) { + while (row !== undefined) { rows.push(row); row = this.fetchAssociative(); } diff --git a/src/driver/mysql2/result.ts b/src/driver/mysql2/result.ts index eced29d..ac12fa9 100644 --- a/src/driver/mysql2/result.ts +++ b/src/driver/mysql2/result.ts @@ -15,19 +15,19 @@ export class Result implements DriverResult { this.rows = [...rows]; } - public fetchNumeric(): T[] | false { + public fetchNumeric(): T[] | undefined { const row = this.fetchAssociative(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } return this.getColumnsFromRow(row).map((column) => row[column]) as T[]; } - public fetchAssociative(): T | false { + public fetchAssociative(): T | undefined { const row = this.rows[this.cursor]; if (row === undefined) { - return false; + return undefined; } this.cursor += 1; @@ -35,7 +35,7 @@ export class Result implements DriverResult { return { ...row } as T; } - public fetchOne(): T | false { + public fetchOne(): T | undefined { return FetchUtils.fetchOne(this); } @@ -47,7 +47,7 @@ export class Result implements DriverResult { const rows: T[] = []; let row = this.fetchAssociative(); - while (row !== false) { + while (row !== undefined) { rows.push(row); row = this.fetchAssociative(); } diff --git a/src/driver/pg/connection.ts b/src/driver/pg/connection.ts index e5e7ba9..ddf5710 100644 --- a/src/driver/pg/connection.ts +++ b/src/driver/pg/connection.ts @@ -101,7 +101,7 @@ export class PgConnection implements DriverConnection { result.free(); const version = - row !== false + row !== undefined ? (row.server_version ?? row.serverVersion ?? row.version ?? "unknown") : "unknown"; return typeof version === "string" ? version : String(version); diff --git a/src/driver/pg/result.ts b/src/driver/pg/result.ts index eced29d..ac12fa9 100644 --- a/src/driver/pg/result.ts +++ b/src/driver/pg/result.ts @@ -15,19 +15,19 @@ export class Result implements DriverResult { this.rows = [...rows]; } - public fetchNumeric(): T[] | false { + public fetchNumeric(): T[] | undefined { const row = this.fetchAssociative(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } return this.getColumnsFromRow(row).map((column) => row[column]) as T[]; } - public fetchAssociative(): T | false { + public fetchAssociative(): T | undefined { const row = this.rows[this.cursor]; if (row === undefined) { - return false; + return undefined; } this.cursor += 1; @@ -35,7 +35,7 @@ export class Result implements DriverResult { return { ...row } as T; } - public fetchOne(): T | false { + public fetchOne(): T | undefined { return FetchUtils.fetchOne(this); } @@ -47,7 +47,7 @@ export class Result implements DriverResult { const rows: T[] = []; let row = this.fetchAssociative(); - while (row !== false) { + while (row !== undefined) { rows.push(row); row = this.fetchAssociative(); } diff --git a/src/driver/result.ts b/src/driver/result.ts index c8fdac9..30ff553 100644 --- a/src/driver/result.ts +++ b/src/driver/result.ts @@ -1,9 +1,9 @@ type AssociativeRow = Record; export interface Result { - fetchNumeric(): T[] | false; - fetchAssociative(): T | false; - fetchOne(): T | false; + fetchNumeric(): T[] | undefined; + fetchAssociative(): T | undefined; + fetchOne(): T | undefined; fetchAllNumeric(): T[][]; fetchAllAssociative(): T[]; fetchFirstColumn(): T[]; diff --git a/src/driver/sqlite3/result.ts b/src/driver/sqlite3/result.ts index eced29d..ac12fa9 100644 --- a/src/driver/sqlite3/result.ts +++ b/src/driver/sqlite3/result.ts @@ -15,19 +15,19 @@ export class Result implements DriverResult { this.rows = [...rows]; } - public fetchNumeric(): T[] | false { + public fetchNumeric(): T[] | undefined { const row = this.fetchAssociative(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } return this.getColumnsFromRow(row).map((column) => row[column]) as T[]; } - public fetchAssociative(): T | false { + public fetchAssociative(): T | undefined { const row = this.rows[this.cursor]; if (row === undefined) { - return false; + return undefined; } this.cursor += 1; @@ -35,7 +35,7 @@ export class Result implements DriverResult { return { ...row } as T; } - public fetchOne(): T | false { + public fetchOne(): T | undefined { return FetchUtils.fetchOne(this); } @@ -47,7 +47,7 @@ export class Result implements DriverResult { const rows: T[] = []; let row = this.fetchAssociative(); - while (row !== false) { + while (row !== undefined) { rows.push(row); row = this.fetchAssociative(); } diff --git a/src/platforms/mysql/charset-metadata-provider/connection-charset-metadata-provider.ts b/src/platforms/mysql/charset-metadata-provider/connection-charset-metadata-provider.ts index 0016191..d8408eb 100644 --- a/src/platforms/mysql/charset-metadata-provider/connection-charset-metadata-provider.ts +++ b/src/platforms/mysql/charset-metadata-provider/connection-charset-metadata-provider.ts @@ -14,6 +14,6 @@ WHERE CHARACTER_SET_NAME = ?;`, [charset], ); - return collation === false ? null : collation; + return collation === undefined ? null : collation; } } diff --git a/src/platforms/mysql/collation-metadata-provider/connection-collation-metadata-provider.ts b/src/platforms/mysql/collation-metadata-provider/connection-collation-metadata-provider.ts index f5c78d0..63bdedd 100644 --- a/src/platforms/mysql/collation-metadata-provider/connection-collation-metadata-provider.ts +++ b/src/platforms/mysql/collation-metadata-provider/connection-collation-metadata-provider.ts @@ -14,6 +14,6 @@ WHERE COLLATION_NAME = ?;`, [collation], ); - return charset === false ? null : charset; + return charset === undefined ? null : charset; } } diff --git a/src/platforms/sqlite/sqlite-metadata-provider.ts b/src/platforms/sqlite/sqlite-metadata-provider.ts index bc37c09..604f6e8 100644 --- a/src/platforms/sqlite/sqlite-metadata-provider.ts +++ b/src/platforms/sqlite/sqlite-metadata-provider.ts @@ -269,7 +269,7 @@ WHERE type = 'table' [tableName], ); - return sql === false ? "" : String(sql); + return sql === undefined ? "" : String(sql); } private parseColumnCollationFromSQL(columnName: string, tableSql: string): string | null { diff --git a/src/portability/converter.ts b/src/portability/converter.ts index 0f1ab11..7969589 100644 --- a/src/portability/converter.ts +++ b/src/portability/converter.ts @@ -7,8 +7,10 @@ type ConvertibleRow = AssociativeRow | NumericRow; type ValueConverter = (value: unknown) => unknown; export class Converter { - private readonly convertNumericFn: (row: NumericRow | false) => NumericRow | false; - private readonly convertAssociativeFn: (row: AssociativeRow | false) => AssociativeRow | false; + private readonly convertNumericFn: (row: NumericRow | undefined) => NumericRow | undefined; + private readonly convertAssociativeFn: ( + row: AssociativeRow | undefined, + ) => AssociativeRow | undefined; private readonly convertOneFn: (value: unknown) => unknown; private readonly convertAllNumericFn: (rows: NumericRow[]) => NumericRow[]; private readonly convertAllAssociativeFn: (rows: AssociativeRow[]) => AssociativeRow[]; @@ -46,12 +48,14 @@ export class Converter { : (name) => name; } - public convertNumeric(row: T[] | false): T[] | false { - return this.convertNumericFn(row as NumericRow | false) as T[] | false; + public convertNumeric(row: T[] | undefined): T[] | undefined { + return this.convertNumericFn(row as NumericRow | undefined) as T[] | undefined; } - public convertAssociative(row: T | false): T | false { - return this.convertAssociativeFn(row as AssociativeRow | false) as T | false; + public convertAssociative( + row: T | undefined, + ): T | undefined { + return this.convertAssociativeFn(row as AssociativeRow | undefined) as T | undefined; } public convertOne(value: T): T { @@ -156,14 +160,16 @@ export class Converter { return this.compose(...functions) as ((row: T) => T) | null; } - private createConvert(function_: ((value: T) => T) | null): (value: T | false) => T | false { + private createConvert( + function_: ((value: T) => T) | null, + ): (value: T | undefined) => T | undefined { if (function_ === null) { - return Converter.id as (value: T | false) => T | false; + return Converter.id as (value: T | undefined) => T | undefined; } - return (value: T | false): T | false => { - if (value === false) { - return false; + return (value: T | undefined): T | undefined => { + if (value === undefined) { + return undefined; } return function_(value as T); diff --git a/src/portability/result.ts b/src/portability/result.ts index 719f38b..227e233 100644 --- a/src/portability/result.ts +++ b/src/portability/result.ts @@ -11,10 +11,10 @@ export class Result implements DriverResult { private readonly converter: Converter, ) {} - public fetchNumeric(): T[] | false { + public fetchNumeric(): T[] | undefined { const row = this.result.fetchNumeric(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } return row.map((value) => this.converter.convertValue(value)) as T[]; @@ -22,19 +22,19 @@ export class Result implements DriverResult { public fetchAssociative = Record>(): | T - | false { + | undefined { const row = this.result.fetchAssociative>(); - if (row === false) { - return false; + if (row === undefined) { + return undefined; } return this.converter.convertRow(row) as T; } - public fetchOne(): T | false { + public fetchOne(): T | undefined { const value = this.result.fetchOne(); - if (value === false) { - return false; + if (value === undefined) { + return undefined; } return this.converter.convertValue(value) as T; diff --git a/src/query/query-builder.ts b/src/query/query-builder.ts index 56a2eaf..f51ebe1 100644 --- a/src/query/query-builder.ts +++ b/src/query/query-builder.ts @@ -70,15 +70,17 @@ export class QueryBuilder { return this.connection.executeStatement(this.getSQL(), this.params, this.types); } - public async fetchAssociative(): Promise { + public async fetchAssociative(): Promise< + T | undefined + > { return (await this.executeQuery()).fetchAssociative(); } - public async fetchNumeric(): Promise { + public async fetchNumeric(): Promise { return (await this.executeQuery()).fetchNumeric(); } - public async fetchOne(): Promise { + public async fetchOne(): Promise { return (await this.executeQuery()).fetchOne(); } diff --git a/src/result.ts b/src/result.ts index 80f69e5..a43e391 100644 --- a/src/result.ts +++ b/src/result.ts @@ -16,18 +16,18 @@ export class Result { private readonly connection: Connection, ) {} - public fetchNumeric(): T | false { + public fetchNumeric(): T | undefined { return this.convertDriverException( "fetchNumeric", - () => this.result.fetchNumeric() as T | false, + () => this.result.fetchNumeric() as T | undefined, ); } - public fetchAssociative(): T | false { + public fetchAssociative(): T | undefined { return this.convertDriverException("fetchAssociative", () => this.result.fetchAssociative()); } - public fetchOne(): T | false { + public fetchOne(): T | undefined { return this.convertDriverException("fetchOne", () => this.result.fetchOne()); } @@ -87,7 +87,7 @@ export class Result { public *iterateNumeric(): IterableIterator { try { let row = this.fetchNumeric(); - while (row !== false) { + while (row !== undefined) { yield row; row = this.fetchNumeric(); } @@ -99,7 +99,7 @@ export class Result { public *iterateAssociative(): IterableIterator { try { let row = this.fetchAssociative(); - while (row !== false) { + while (row !== undefined) { yield row; row = this.fetchAssociative(); } diff --git a/src/schema/mysql-schema-manager.ts b/src/schema/mysql-schema-manager.ts index e854e23..b72addd 100644 --- a/src/schema/mysql-schema-manager.ts +++ b/src/schema/mysql-schema-manager.ts @@ -545,7 +545,7 @@ FROM information_schema.COLLATIONS`, this.charsetByCollation.set(collation, charset); } - if (databaseDefaultsRow !== false) { + if (databaseDefaultsRow !== undefined) { this.databaseDefaultCharset = readString( databaseDefaultsRow, "character_set_database", From 83a7b4b97f038a955e12a24a2da013b1417fc7b9 Mon Sep 17 00:00:00 2001 From: bernard-ng Date: Tue, 17 Mar 2026 20:00:55 +0200 Subject: [PATCH 2/3] fix: #2 normalize undefined to null when binding parameters --- CHANGELOG.md | 1 + package.json | 2 +- .../connection-parameter-compilation.test.ts | 21 +++++++++++++++++++ .../connection-type-conversion.test.ts | 10 +++++++++ src/connection.ts | 12 +++++++++-- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ba325f..f14a921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## 1.1.2 - Refactored `fetchNumeric()`, `fetchAssociative()`, and `fetchOne()` across `Result`, `Connection`, `QueryBuilder`, portability wrappers, and all bundled drivers to return `undefined` instead of `false` when no row is available, and aligned unit tests and metadata-provider integrations with the new contract. +- Normalized bound query parameter values so `undefined` is treated as SQL `NULL` (`null`) before hitting driver statements, preventing mysql2 bind errors and aligning positional and named parameter flows. # 1.1.1 diff --git a/package.json b/package.json index 4a18f4c..ddab001 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devscast/datazen", - "version": "1.1.1", + "version": "1.1.2", "type": "module", "source": "./src/_index.ts", "main": "./dist/index.cjs", diff --git a/src/__tests__/connection/connection-parameter-compilation.test.ts b/src/__tests__/connection/connection-parameter-compilation.test.ts index 8c667da..1e6a157 100644 --- a/src/__tests__/connection/connection-parameter-compilation.test.ts +++ b/src/__tests__/connection/connection-parameter-compilation.test.ts @@ -120,6 +120,27 @@ class NamedSpyDriver implements Driver { } describe("Connection parameter compilation", () => { + it("treats undefined named parameters as SQL NULL", async () => { + const capture = new CaptureConnection(); + const connection = new Connection({}, new NamedSpyDriver(capture)); + + await connection.executeQuery( + "SELECT * FROM users WHERE deleted_at = :deletedAt", + { deletedAt: undefined }, + { deletedAt: ParameterType.STRING }, + ); + + expect(capture.latestQuery).toEqual({ + parameters: { + p1: null, + }, + sql: "SELECT * FROM users WHERE deleted_at = @p1", + types: { + p1: ParameterType.STRING, + }, + }); + }); + it("compiles named placeholders to sqlserver style named bindings", async () => { const capture = new CaptureConnection(); const connection = new Connection({}, new NamedSpyDriver(capture)); diff --git a/src/__tests__/connection/connection-type-conversion.test.ts b/src/__tests__/connection/connection-type-conversion.test.ts index b094ba5..b3a0359 100644 --- a/src/__tests__/connection/connection-type-conversion.test.ts +++ b/src/__tests__/connection/connection-type-conversion.test.ts @@ -132,6 +132,16 @@ class SpyDriver implements Driver { describe("Connection type conversion", () => { registerBuiltInTypes(); + it("treats undefined positional parameters as SQL NULL", async () => { + const capture = new CaptureConnection(); + const connection = new Connection({}, new SpyDriver(capture)); + + await connection.executeQuery("SELECT ? AS maybe", [undefined], [ParameterType.STRING]); + + expect(capture.latestQuery?.parameters).toEqual([null]); + expect(capture.latestQuery?.types).toEqual([ParameterType.STRING]); + }); + it("converts Datazen Type names to driver values and binding types", async () => { const capture = new CaptureConnection(); const connection = new Connection({}, new SpyDriver(capture)); diff --git a/src/connection.ts b/src/connection.ts index 2fb7f7a..b0f23e8 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -705,7 +705,7 @@ export class Connection { if (Array.isArray(parameters) && Array.isArray(types)) { for (let index = 0; index < parameters.length; index += 1) { const type = (types[index] ?? ParameterType.STRING) as ParameterType; - statement.bindValue(index + 1, parameters[index], type); + statement.bindValue(index + 1, this.normalizeBoundParameterValue(parameters[index]), type); } return; @@ -713,13 +713,21 @@ export class Connection { if (!Array.isArray(parameters) && !Array.isArray(types)) { for (const [name, value] of Object.entries(parameters)) { - statement.bindValue(name, value, (types[name] ?? ParameterType.STRING) as ParameterType); + statement.bindValue( + name, + this.normalizeBoundParameterValue(value), + (types[name] ?? ParameterType.STRING) as ParameterType, + ); } return; } } + private normalizeBoundParameterValue(value: unknown): unknown { + return value === undefined ? null : value; + } + private hasBoundParameters(parameters: Query["parameters"]): boolean { if (Array.isArray(parameters)) { return parameters.length > 0; From 0298a304cf23a62ebba1625aa966706850bd7d20 Mon Sep 17 00:00:00 2001 From: bernard-ng Date: Tue, 17 Mar 2026 20:18:50 +0200 Subject: [PATCH 3/3] test: update functional tests to support new api --- CHANGELOG.md | 1 + .../functional/auto-increment-column.test.ts | 2 +- .../functional/binary-data-access.test.ts | 14 +++++++------- src/__tests__/functional/blob.test.ts | 2 +- src/__tests__/functional/data-access.test.ts | 14 +++++++------- .../functional/platform/alter-column.test.ts | 2 +- .../functional/platform/default-expression.test.ts | 4 ++-- src/__tests__/functional/platform/quoting.test.ts | 4 ++-- src/__tests__/functional/result.test.ts | 6 +++--- .../functional/schema/postgre-sql/schema.test.ts | 4 ++-- src/__tests__/functional/transaction.test.ts | 4 ++-- src/__tests__/functional/write.test.ts | 2 +- 12 files changed, 30 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f14a921..b862153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Refactored `fetchNumeric()`, `fetchAssociative()`, and `fetchOne()` across `Result`, `Connection`, `QueryBuilder`, portability wrappers, and all bundled drivers to return `undefined` instead of `false` when no row is available, and aligned unit tests and metadata-provider integrations with the new contract. - Normalized bound query parameter values so `undefined` is treated as SQL `NULL` (`null`) before hitting driver statements, preventing mysql2 bind errors and aligning positional and named parameter flows. +- Updated remaining functional tests to assert `undefined` (instead of `false`) for empty single-row `fetch*` results and no-row guards. # 1.1.1 diff --git a/src/__tests__/functional/auto-increment-column.test.ts b/src/__tests__/functional/auto-increment-column.test.ts index a84ea2e..dfbce73 100644 --- a/src/__tests__/functional/auto-increment-column.test.ts +++ b/src/__tests__/functional/auto-increment-column.test.ts @@ -64,7 +64,7 @@ describe("Functional/AutoIncrementColumnTest", () => { async function maxId(connection: Connection): Promise { const value = await connection.fetchOne("SELECT MAX(id) FROM auto_increment_table"); - expect(value).not.toBe(false); + expect(value).toBeDefined(); return Number(value); } diff --git a/src/__tests__/functional/binary-data-access.test.ts b/src/__tests__/functional/binary-data-access.test.ts index 2048352..aca2358 100644 --- a/src/__tests__/functional/binary-data-access.test.ts +++ b/src/__tests__/functional/binary-data-access.test.ts @@ -54,7 +54,7 @@ describe("Functional/BinaryDataAccessTest", () => { stmt.bindValue(2, Buffer.from("c0def00d", "hex"), ParameterType.BINARY); const row = lowerCaseKeys((await stmt.executeQuery()).fetchAssociative()); - expect(row).not.toBe(false); + expect(row).toBeDefined(); expect(Object.keys(row as Record)).toEqual(["test_int", "test_binary"]); expect((row as Record).test_int).toBe(1); expect(toBinaryBuffer((row as Record).test_binary)).toEqual( @@ -130,7 +130,7 @@ describe("Functional/BinaryDataAccessTest", () => { { 1: ParameterType.BINARY }, ); - expect(row).not.toBe(false); + expect(row).toBeDefined(); const normalized = lowerCaseKeys(row); expect(normalized.test_int).toBe(1); expect(toBinaryBuffer(normalized.test_binary)).toEqual(Buffer.from("c0def00d", "hex")); @@ -145,7 +145,7 @@ describe("Functional/BinaryDataAccessTest", () => { [ParameterType.STRING, Types.BINARY], ); - expect(row).not.toBe(false); + expect(row).toBeDefined(); const normalized = lowerCaseKeys(row); expect(normalized.test_int).toBe(1); expect(toBinaryBuffer(normalized.test_binary)).toEqual(Buffer.from("c0def00d", "hex")); @@ -160,7 +160,7 @@ describe("Functional/BinaryDataAccessTest", () => { { 1: ParameterType.BINARY }, ); - expect(row).not.toBe(false); + expect(row).toBeDefined(); expect(row?.[0]).toBe(1); expect(toBinaryBuffer(row?.[1])).toEqual(Buffer.from("c0def00d", "hex")); }); @@ -174,7 +174,7 @@ describe("Functional/BinaryDataAccessTest", () => { [ParameterType.STRING, Types.BINARY], ); - expect(row).not.toBe(false); + expect(row).toBeDefined(); expect(row?.[0]).toBe(1); expect(toBinaryBuffer(row?.[1])).toEqual(Buffer.from("c0def00d", "hex")); }); @@ -255,8 +255,8 @@ describe("Functional/BinaryDataAccessTest", () => { }); }); -function lowerCaseKeys(row: false | Record | undefined): Record { - if (row === false || row === undefined) { +function lowerCaseKeys(row: Record | undefined): Record { + if (row === undefined) { throw new Error("Expected a row."); } diff --git a/src/__tests__/functional/blob.test.ts b/src/__tests__/functional/blob.test.ts index 03300f1..07a6a61 100644 --- a/src/__tests__/functional/blob.test.ts +++ b/src/__tests__/functional/blob.test.ts @@ -148,7 +148,7 @@ describe("Functional/BlobTest", () => { const blobs = await functional .connection() .fetchNumeric("SELECT blobcolumn1, blobcolumn2 FROM blob_table"); - expect(blobs).not.toBe(false); + expect(blobs).toBeDefined(); const actual = (blobs ?? []).map((blob) => toText(blob)); expect(actual).toEqual(["test1", "test2"]); diff --git a/src/__tests__/functional/data-access.test.ts b/src/__tests__/functional/data-access.test.ts index e32db42..b0e4b87 100644 --- a/src/__tests__/functional/data-access.test.ts +++ b/src/__tests__/functional/data-access.test.ts @@ -129,7 +129,7 @@ describe("Functional/DataAccessTest", () => { [1, "foo"], ); - expect(row).not.toBe(false); + expect(row).toBeDefined(); const normalized = lowerCaseKeys(row); expect(normalized.test_int).toBe(1); expect(normalized.test_string).toBe("foo"); @@ -146,7 +146,7 @@ describe("Functional/DataAccessTest", () => { [ParameterType.STRING, Types.DATETIME_MUTABLE], ); - expect(row).not.toBe(false); + expect(row).toBeDefined(); const normalized = lowerCaseKeys(row); expect(normalized.test_int).toBe(1); expect(normalizeDateTimeSecondPrecision(normalized.test_datetime)).toBe("2010-01-01 10:10:10"); @@ -160,7 +160,7 @@ describe("Functional/DataAccessTest", () => { [1, "foo"], ); - expect(row).not.toBe(false); + expect(row).toBeDefined(); expect(row?.[0]).toBe(1); expect(row?.[1]).toBe("foo"); }); @@ -176,7 +176,7 @@ describe("Functional/DataAccessTest", () => { [ParameterType.STRING, Types.DATETIME_MUTABLE], ); - expect(row).not.toBe(false); + expect(row).toBeDefined(); expect(row?.[0]).toBe(1); expect(normalizeDateTimeSecondPrecision(row?.[1])).toBe("2010-01-01 10:10:10"); }); @@ -420,12 +420,12 @@ async function assertDateExpression( bindParams(stmt, interval); const date = (await stmt.executeQuery()).fetchOne(); - expect(date).not.toBe(false); + expect(date).toBeDefined(); expect(normalizeDateTimeSecondPrecision(date)).toBe(expected); } -function lowerCaseKeys(row: false | Record | undefined): Record { - if (row === false || row === undefined) { +function lowerCaseKeys(row: Record | undefined): Record { + if (row === undefined) { throw new Error("Expected a row."); } diff --git a/src/__tests__/functional/platform/alter-column.test.ts b/src/__tests__/functional/platform/alter-column.test.ts index f69cf10..43e7408 100644 --- a/src/__tests__/functional/platform/alter-column.test.ts +++ b/src/__tests__/functional/platform/alter-column.test.ts @@ -81,7 +81,7 @@ describe("Functional/Platform/AlterColumnTest", () => { const hasIcuCollations = (await functional .connection() - .fetchOne("SELECT 1 FROM pg_collation WHERE collprovider = 'icu'")) !== false; + .fetchOne("SELECT 1 FROM pg_collation WHERE collprovider = 'icu'")) !== undefined; if (!hasIcuCollations) { skip(); } diff --git a/src/__tests__/functional/platform/default-expression.test.ts b/src/__tests__/functional/platform/default-expression.test.ts index 5cfb23c..8ef6c90 100644 --- a/src/__tests__/functional/platform/default-expression.test.ts +++ b/src/__tests__/functional/platform/default-expression.test.ts @@ -67,8 +67,8 @@ async function assertDefaultExpression( const row = await connection.fetchNumeric<[unknown, unknown]>( "SELECT default_value, actual_value FROM default_expr_test", ); - expect(row).not.toBe(false); - if (row === false) { + expect(row).toBeDefined(); + if (row === undefined) { return; } diff --git a/src/__tests__/functional/platform/quoting.test.ts b/src/__tests__/functional/platform/quoting.test.ts index c167cc1..a6a30ac 100644 --- a/src/__tests__/functional/platform/quoting.test.ts +++ b/src/__tests__/functional/platform/quoting.test.ts @@ -28,8 +28,8 @@ describe("Functional/Platform/QuotingTest", () => { ); const row = await functional.connection().fetchAssociative(query); - expect(row).not.toBe(false); - if (row === false) { + expect(row).toBeDefined(); + if (row === undefined) { return; } diff --git a/src/__tests__/functional/result.test.ts b/src/__tests__/functional/result.test.ts index 425d8c0..03519ed 100644 --- a/src/__tests__/functional/result.test.ts +++ b/src/__tests__/functional/result.test.ts @@ -15,17 +15,17 @@ describe("Functional/ResultTest", () => { [ "fetchNumeric", (result: Awaited>) => result.fetchNumeric(), - false, + undefined, ], [ "fetchAssociative", (result: Awaited>) => result.fetchAssociative(), - false, + undefined, ], [ "fetchOne", (result: Awaited>) => result.fetchOne(), - false, + undefined, ], [ "fetchAllNumeric", diff --git a/src/__tests__/functional/schema/postgre-sql/schema.test.ts b/src/__tests__/functional/schema/postgre-sql/schema.test.ts index c95e807..fed2210 100644 --- a/src/__tests__/functional/schema/postgre-sql/schema.test.ts +++ b/src/__tests__/functional/schema/postgre-sql/schema.test.ts @@ -44,8 +44,8 @@ describe("Functional/Schema/PostgreSQL/SchemaTest", () => { ["my_table"], ); - expect(row).not.toBe(false); - if (row === false) { + expect(row).toBeDefined(); + if (row === undefined) { return; } diff --git a/src/__tests__/functional/transaction.test.ts b/src/__tests__/functional/transaction.test.ts index 25fc595..0b8882d 100644 --- a/src/__tests__/functional/transaction.test.ts +++ b/src/__tests__/functional/transaction.test.ts @@ -135,8 +135,8 @@ async function killCurrentSession( } const currentProcessId = await connection.fetchOne(currentProcessQuery); - expect(currentProcessId).not.toBe(false); - if (currentProcessId === false) { + expect(currentProcessId).toBeDefined(); + if (currentProcessId === undefined) { return; } diff --git a/src/__tests__/functional/write.test.ts b/src/__tests__/functional/write.test.ts index cfd161c..5800089 100644 --- a/src/__tests__/functional/write.test.ts +++ b/src/__tests__/functional/write.test.ts @@ -206,7 +206,7 @@ describe("Functional/WriteTest", () => { expect( await connection.fetchOne("SELECT test_string FROM write_table WHERE test_int = 30"), - ).toBe(false); + ).toBeUndefined(); }); it("supports empty identity insert SQL", async () => {