@deterministic-code/datasources-postgres 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/PostgresAlterTableStatementRenderer.d.ts +6 -0
  2. package/dist/PostgresAlterTableStatementRenderer.js +20 -0
  3. package/dist/PostgresBulkUpdateStatementTextRenderer.d.ts +4 -0
  4. package/dist/PostgresBulkUpdateStatementTextRenderer.js +24 -0
  5. package/dist/PostgresCreateRoutineStatementRenderer.d.ts +4 -0
  6. package/dist/PostgresCreateTableStatementRenderer.d.ts +6 -0
  7. package/dist/PostgresCreateTableStatementRenderer.js +26 -0
  8. package/dist/PostgresCreateTriggerStatementRenderer.d.ts +4 -0
  9. package/dist/PostgresCreateTriggerStatementRenderer.js +13 -0
  10. package/dist/PostgresDriver.d.ts +16 -0
  11. package/dist/PostgresDriver.js +75 -0
  12. package/dist/PostgresDropRoutineStatementRenderer.d.ts +4 -0
  13. package/dist/PostgresDropRoutineStatementRenderer.js +6 -0
  14. package/dist/PostgresDropTriggerStatementRenderer.d.ts +4 -0
  15. package/dist/PostgresDropTriggerStatementRenderer.js +6 -0
  16. package/dist/PostgresIdentityInsertStatementRenderer.d.ts +4 -0
  17. package/dist/PostgresIdentityInsertStatementRenderer.js +11 -0
  18. package/dist/PostgresStatementRenderer.d.ts +19 -0
  19. package/dist/PostgresStatementRenderer.js +64 -0
  20. package/dist/PostgresStoredProcedureStatementRenderer.d.ts +10 -0
  21. package/dist/PostgresStoredProcedureStatementRenderer.js +111 -0
  22. package/dist/bind.d.ts +7 -0
  23. package/dist/bind.js +35 -0
  24. package/dist/columnTypes.d.ts +1 -0
  25. package/dist/columnTypes.js +10 -0
  26. package/dist/command.d.ts +14 -0
  27. package/dist/command.js +92 -0
  28. package/dist/connection-options.d.ts +6 -0
  29. package/dist/connection-options.js +1 -0
  30. package/dist/connection.d.ts +21 -0
  31. package/dist/connection.js +72 -0
  32. package/dist/converters/BinaryConverter.d.ts +6 -0
  33. package/dist/converters/BinaryConverter.js +14 -0
  34. package/dist/converters/BoolConverter.d.ts +5 -0
  35. package/dist/converters/BoolConverter.js +5 -0
  36. package/dist/converters/DateTimeConverter.d.ts +6 -0
  37. package/dist/converters/DateTimeConverter.js +6 -0
  38. package/dist/converters/DecimalConverter.d.ts +5 -0
  39. package/dist/converters/DecimalConverter.js +5 -0
  40. package/dist/converters/PostgresRowTypeConverters.d.ts +3 -0
  41. package/dist/converters/PostgresRowTypeConverters.js +19 -0
  42. package/dist/converters/UuidConverter.d.ts +5 -0
  43. package/dist/converters/UuidConverter.js +5 -0
  44. package/dist/i-postgres-driver.d.ts +38 -0
  45. package/dist/i-postgres-driver.js +22 -0
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.js +1 -0
  48. package/dist/scalar.js +1 -0
  49. package/dist/transaction.d.ts +9 -0
  50. package/dist/transaction.js +15 -0
  51. package/package.json +10 -7
  52. package/src/PostgresBulkUpdateStatementTextRenderer.ts +0 -27
  53. package/src/PostgresCreateTableStatementRenderer.ts +0 -33
  54. package/src/PostgresDriver.ts +0 -55
  55. package/src/PostgresStatementRenderer.ts +0 -34
  56. package/src/bind.ts +0 -50
  57. package/src/columnTypes.ts +0 -10
  58. package/src/command.ts +0 -129
  59. package/src/connection-options.ts +0 -7
  60. package/src/connection.ts +0 -95
  61. package/src/converters/BinaryConverter.ts +0 -20
  62. package/src/converters/BoolConverter.ts +0 -6
  63. package/src/converters/DateTimeConverter.ts +0 -11
  64. package/src/converters/DecimalConverter.ts +0 -7
  65. package/src/converters/PostgresRowTypeConverters.ts +0 -24
  66. package/src/converters/UuidConverter.ts +0 -6
  67. package/src/i-postgres-driver.ts +0 -61
  68. package/src/index.ts +0 -1
  69. package/src/transaction.ts +0 -21
  70. /package/{src/scalar.ts → dist/scalar.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import { type DatasourceOptions, type ICommand, type IConnection, type IsolationLevelName, type ITransaction } from "@deterministic-code/datasources";
2
+ import type { PostgresConnectionOptions } from "./connection-options.js";
3
+ import { type IPgClient } from "./i-postgres-driver.js";
4
+ export declare class PostgresConnection implements IConnection {
5
+ readonly provider = "postgres";
6
+ url: string;
7
+ schema?: string;
8
+ isOpen: boolean;
9
+ private client?;
10
+ private readonly Client?;
11
+ static from: (options?: DatasourceOptions) => PostgresConnection;
12
+ constructor(options?: PostgresConnectionOptions);
13
+ createCommand: () => ICommand;
14
+ open(): Promise<void>;
15
+ close(): Promise<void>;
16
+ [Symbol.asyncDispose]: () => Promise<void>;
17
+ startTransaction(isolation?: IsolationLevelName): Promise<ITransaction>;
18
+ ensureOpen(): void;
19
+ require(): IPgClient;
20
+ exec(sql: string): Promise<void>;
21
+ }
@@ -0,0 +1,72 @@
1
+ import { DatasourceError, DatasourceUrlParser, IsolationLevel, StatementTextRenderer, } from "@deterministic-code/datasources";
2
+ import { createRequire } from "node:module";
3
+ import { PostgresCommand } from "./command.js";
4
+ import { pgClient } from "./i-postgres-driver.js";
5
+ import { PostgresStatementRenderer } from "./PostgresStatementRenderer.js";
6
+ import { PostgresTransaction } from "./transaction.js";
7
+ const require = createRequire(import.meta.url);
8
+ const isoSql = (isolation) => isolation === IsolationLevel.ReadUncommitted
9
+ ? "READ UNCOMMITTED"
10
+ : isolation === IsolationLevel.ReadCommitted
11
+ ? "READ COMMITTED"
12
+ : isolation === IsolationLevel.RepeatableRead
13
+ ? "REPEATABLE READ"
14
+ : "SERIALIZABLE";
15
+ export class PostgresConnection {
16
+ provider = "postgres";
17
+ url;
18
+ schema;
19
+ isOpen = false;
20
+ client;
21
+ Client;
22
+ static from = (options) => {
23
+ const url = options?.DATASOURCE_URL ?? "";
24
+ return new PostgresConnection({
25
+ url,
26
+ schema: DatasourceUrlParser.parse(url)?.schema,
27
+ Client: pgClient(require("pg")),
28
+ });
29
+ };
30
+ constructor(options = {}) {
31
+ this.url = options.url ?? "";
32
+ this.schema = options.schema;
33
+ this.Client = options.Client;
34
+ }
35
+ createCommand = () => new PostgresCommand(this, new StatementTextRenderer(t => new PostgresStatementRenderer(t)));
36
+ async open() {
37
+ if (this.isOpen)
38
+ throw new DatasourceError("Connection is already open");
39
+ if (!this.client) {
40
+ if (!this.Client)
41
+ throw new DatasourceError("Postgres driver is required");
42
+ this.client = new this.Client({ connectionString: this.url });
43
+ }
44
+ await this.client.connect();
45
+ if (this.schema)
46
+ await this.client.query(`SET search_path TO ${this.schema}`);
47
+ this.isOpen = true;
48
+ }
49
+ async close() {
50
+ await this.client?.end();
51
+ this.client = undefined;
52
+ this.isOpen = false;
53
+ }
54
+ [Symbol.asyncDispose] = () => this.close();
55
+ async startTransaction(isolation = IsolationLevel.Serializable) {
56
+ this.ensureOpen();
57
+ await this.exec(`BEGIN ISOLATION LEVEL ${isoSql(isolation)}`);
58
+ return new PostgresTransaction(this, isolation);
59
+ }
60
+ ensureOpen() {
61
+ if (!this.isOpen)
62
+ throw new DatasourceError("Connection is not open");
63
+ }
64
+ require() {
65
+ if (!this.client)
66
+ throw new DatasourceError("Connection is not open");
67
+ return this.client;
68
+ }
69
+ async exec(sql) {
70
+ await this.require().query(sql);
71
+ }
72
+ }
@@ -0,0 +1,6 @@
1
+ import { TypeConverter, type Cell } from "@deterministic-code/datasources";
2
+ export declare const isBase64: (value: string) => boolean;
3
+ export declare class BinaryConverter extends TypeConverter<Cell, Cell> {
4
+ convert: (from: Cell) => Cell;
5
+ reverseConvert: (to: Cell) => Cell;
6
+ }
@@ -0,0 +1,14 @@
1
+ import { TypeConverter } from "@deterministic-code/datasources";
2
+ export const isBase64 = (value) => {
3
+ const text = value.trim();
4
+ return (text.length >= 4 &&
5
+ text.length % 4 === 0 &&
6
+ text.includes("=") &&
7
+ /^[A-Za-z0-9+/]+=*$/.test(text) &&
8
+ Buffer.from(text, "base64").toString("base64") === text);
9
+ };
10
+ const bytes = (value) => typeof value === "string" ? Uint8Array.from(Buffer.from(value, "base64")) : value;
11
+ export class BinaryConverter extends TypeConverter {
12
+ convert = (from) => bytes(from);
13
+ reverseConvert = (to) => bytes(to);
14
+ }
@@ -0,0 +1,5 @@
1
+ import { TypeConverter, type Cell } from "@deterministic-code/datasources";
2
+ export declare class BoolConverter extends TypeConverter<Cell, Cell> {
3
+ convert: (from: Cell) => Cell;
4
+ reverseConvert: (to: Cell) => Cell;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { TypeConverter } from "@deterministic-code/datasources";
2
+ export class BoolConverter extends TypeConverter {
3
+ convert = (from) => (typeof from === "number" ? from !== 0 : from);
4
+ reverseConvert = (to) => to;
5
+ }
@@ -0,0 +1,6 @@
1
+ import { TypeConverter, type Cell } from "@deterministic-code/datasources";
2
+ export declare const isIsoDate: (value: string) => boolean;
3
+ export declare class DateTimeConverter extends TypeConverter<Cell, Cell> {
4
+ convert: (from: Cell) => Cell;
5
+ reverseConvert: (to: Cell) => Cell;
6
+ }
@@ -0,0 +1,6 @@
1
+ import { TypeConverter } from "@deterministic-code/datasources";
2
+ export const isIsoDate = (value) => /^\d{4}-\d{2}-\d{2}T/.test(value) && !Number.isNaN(Date.parse(value));
3
+ export class DateTimeConverter extends TypeConverter {
4
+ convert = (from) => typeof from === "string" ? new Date(from) : from;
5
+ reverseConvert = (to) => to instanceof Date ? to.toISOString() : to;
6
+ }
@@ -0,0 +1,5 @@
1
+ import { TypeConverter, type Cell } from "@deterministic-code/datasources";
2
+ export declare class DecimalConverter extends TypeConverter<Cell, Cell> {
3
+ convert: (from: Cell) => Cell;
4
+ reverseConvert: (to: Cell) => Cell;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { TypeConverter } from "@deterministic-code/datasources";
2
+ export class DecimalConverter extends TypeConverter {
3
+ convert = (from) => from;
4
+ reverseConvert = (to) => typeof to === "number" ? String(to) : to;
5
+ }
@@ -0,0 +1,3 @@
1
+ import { type Cell, type TypeConverter } from "@deterministic-code/datasources";
2
+ export declare const PostgresRowTypeConverters: Record<string, TypeConverter<Cell, Cell>>;
3
+ export declare const reverse: (value: Cell) => Cell;
@@ -0,0 +1,19 @@
1
+ import { BinaryConverter } from "./BinaryConverter.js";
2
+ import { BoolConverter } from "./BoolConverter.js";
3
+ import { DateTimeConverter } from "./DateTimeConverter.js";
4
+ import { DecimalConverter } from "./DecimalConverter.js";
5
+ import { UuidConverter } from "./UuidConverter.js";
6
+ export const PostgresRowTypeConverters = {
7
+ bool: new BoolConverter(),
8
+ datetime: new DateTimeConverter(),
9
+ uuid: new UuidConverter(),
10
+ decimal: new DecimalConverter(),
11
+ binary: new BinaryConverter(),
12
+ };
13
+ export const reverse = (value) => typeof value === "boolean"
14
+ ? PostgresRowTypeConverters.bool.reverseConvert(value)
15
+ : value instanceof Date
16
+ ? PostgresRowTypeConverters.datetime.reverseConvert(value)
17
+ : value instanceof Uint8Array
18
+ ? PostgresRowTypeConverters.binary.reverseConvert(value)
19
+ : value;
@@ -0,0 +1,5 @@
1
+ import { TypeConverter, type Cell } from "@deterministic-code/datasources";
2
+ export declare class UuidConverter extends TypeConverter<Cell, Cell> {
3
+ convert: (from: Cell) => Cell;
4
+ reverseConvert: (to: Cell) => Cell;
5
+ }
@@ -0,0 +1,5 @@
1
+ import { TypeConverter } from "@deterministic-code/datasources";
2
+ export class UuidConverter extends TypeConverter {
3
+ convert = (from) => from;
4
+ reverseConvert = (to) => to;
5
+ }
@@ -0,0 +1,38 @@
1
+ import type { Parameter } from "@deterministic-code/datasources";
2
+ import QueryStream from "pg-query-stream";
3
+ import type { Cells, Scalar, Wire } from "./scalar.js";
4
+ export interface PostgresExecuteResult {
5
+ rowsAffected: number;
6
+ result?: Scalar;
7
+ parameters?: Parameter[];
8
+ }
9
+ export interface PgQueryResult {
10
+ rowCount: number | null;
11
+ rows: Cells[];
12
+ }
13
+ export interface IPgClient {
14
+ connect(): Promise<void>;
15
+ query(text: string, values?: Wire[]): Promise<PgQueryResult>;
16
+ rows(text: string, values?: Wire[]): AsyncIterable<Cells>;
17
+ end(): Promise<void>;
18
+ }
19
+ interface PgNativeClient {
20
+ connect(): Promise<void>;
21
+ query(text: string, values?: Wire[]): Promise<PgQueryResult>;
22
+ query(query: QueryStream): AsyncIterable<Cells>;
23
+ end(): Promise<void>;
24
+ }
25
+ export type PgClientCtor = new (options: {
26
+ connectionString: string;
27
+ }) => IPgClient;
28
+ type PgNativeCtor = new (options: {
29
+ connectionString: string;
30
+ }) => PgNativeClient;
31
+ export type PgModule = {
32
+ Client: PgNativeCtor;
33
+ default?: {
34
+ Client: PgNativeCtor;
35
+ };
36
+ };
37
+ export declare const pgClient: (imported: PgModule) => PgClientCtor;
38
+ export {};
@@ -0,0 +1,22 @@
1
+ import QueryStream from "pg-query-stream";
2
+ export const pgClient = (imported) => {
3
+ const Client = imported.default?.Client ?? imported.Client;
4
+ return class {
5
+ inner;
6
+ constructor(options) {
7
+ this.inner = new Client(options);
8
+ }
9
+ connect() {
10
+ return this.inner.connect();
11
+ }
12
+ query(text, values) {
13
+ return this.inner.query(text, values);
14
+ }
15
+ rows(text, values) {
16
+ return this.inner.query(new QueryStream(text, values ?? []));
17
+ }
18
+ end() {
19
+ return this.inner.end();
20
+ }
21
+ };
22
+ };
@@ -0,0 +1 @@
1
+ export { PostgresDriver } from "./PostgresDriver.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { PostgresDriver } from "./PostgresDriver.js";
package/dist/scalar.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import { type ITransaction, type IsolationLevelName } from "@deterministic-code/datasources";
2
+ import type { PostgresConnection } from "./connection.js";
3
+ export declare class PostgresTransaction implements ITransaction {
4
+ readonly connection: PostgresConnection;
5
+ readonly isolation: IsolationLevelName;
6
+ constructor(connection: PostgresConnection, isolation?: IsolationLevelName);
7
+ commit(): Promise<void>;
8
+ abort(): Promise<void>;
9
+ }
@@ -0,0 +1,15 @@
1
+ import { IsolationLevel, } from "@deterministic-code/datasources";
2
+ export class PostgresTransaction {
3
+ connection;
4
+ isolation;
5
+ constructor(connection, isolation = IsolationLevel.ReadCommitted) {
6
+ this.connection = connection;
7
+ this.isolation = isolation;
8
+ }
9
+ async commit() {
10
+ await this.connection.exec("COMMIT");
11
+ }
12
+ async abort() {
13
+ await this.connection.exec("ROLLBACK");
14
+ }
15
+ }
package/package.json CHANGED
@@ -1,21 +1,24 @@
1
1
  {
2
2
  "name": "@deterministic-code/datasources-postgres",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
- "main": "./src/index.ts",
6
- "types": "./src/index.ts",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.js",
7
7
  "exports": {
8
- ".": "./src/index.ts"
8
+ ".": {
9
+ "types": "./dist/index.d.js",
10
+ "import": "./dist/index.js",
11
+ "default": "./dist/index.js"
12
+ }
9
13
  },
10
14
  "files": [
11
- "src"
15
+ "dist"
12
16
  ],
13
17
  "publishConfig": {
14
18
  "access": "public"
15
19
  },
16
- "license": "MIT",
17
20
  "dependencies": {
18
- "@deterministic-code/datasources": "^0.1.0",
21
+ "@deterministic-code/datasources": "^0.1.2",
19
22
  "@types/pg": "^8.15.5",
20
23
  "pg": "^8.16.0",
21
24
  "pg-query-stream": "^4.17.0"
@@ -1,27 +0,0 @@
1
- import { BulkUpdateStatementTextRenderer, type Cell } from "@deterministic-code/datasources";
2
- import { columnTypes } from "./columnTypes.ts";
3
- import { isBase64 } from "./converters/BinaryConverter.ts";
4
- import { isIsoDate } from "./converters/DateTimeConverter.ts";
5
-
6
- const logical = (value: Cell): string | undefined =>
7
- value === null
8
- ? undefined
9
- : typeof value === "boolean"
10
- ? "bool"
11
- : typeof value === "bigint" || (typeof value === "number" && Number.isInteger(value))
12
- ? "int"
13
- : typeof value === "number"
14
- ? "float"
15
- : value instanceof Date || (typeof value === "string" && isIsoDate(value))
16
- ? "datetime"
17
- : value instanceof Uint8Array || (typeof value === "string" && isBase64(value))
18
- ? "binary"
19
- : "string";
20
-
21
- export class PostgresBulkUpdateStatementTextRenderer extends BulkUpdateStatementTextRenderer {
22
- protected override cell = (column: string, index: number, value: Cell): string => {
23
- const type = logical(value);
24
- const sql = type ? columnTypes[type] : undefined;
25
- return sql ? `$${column}__${index}::${sql} AS ${column}` : `$${column}__${index} AS ${column}`;
26
- };
27
- }
@@ -1,33 +0,0 @@
1
- import {
2
- ColumnDefault,
3
- CreateTableStatementTextRenderer,
4
- type Column,
5
- } from "@deterministic-code/datasources";
6
- import { PostgresRowTypeConverters } from "./converters/PostgresRowTypeConverters.ts";
7
- import { columnTypes } from "./columnTypes.ts";
8
-
9
- export class PostgresCreateTableStatementRenderer extends CreateTableStatementTextRenderer {
10
- protected typeName(column: Column): string {
11
- return columnTypes[column.type] ?? column.type;
12
- }
13
-
14
- protected columnDefault(column: Column): string {
15
- const literal = sqlLiteral(column);
16
- const value = column.default;
17
- return value == null || literal == null
18
- ? super.columnDefault(column)
19
- : super.columnDefault({ ...column, default: new ColumnDefault(literal, value.name) });
20
- }
21
-
22
- protected identity(column: Column): string {
23
- return column.identity ? " GENERATED BY DEFAULT AS IDENTITY" : "";
24
- }
25
- }
26
-
27
- function sqlLiteral(column: Column): string | undefined {
28
- const raw = column.default?.value;
29
- const converter = PostgresRowTypeConverters[column.type];
30
- if (raw == null || !converter || !/^-?\d+$/.test(raw)) return undefined;
31
- const converted = converter.convert(Number(raw));
32
- return converted === true ? "TRUE" : converted === false ? "FALSE" : undefined;
33
- }
@@ -1,55 +0,0 @@
1
- import {
2
- DatasourceError,
3
- StatementTextRenderer,
4
- type Cell,
5
- type DatasourceOptions,
6
- type ICommand,
7
- type IConnection,
8
- type IDriver,
9
- type Information,
10
- type ITransaction,
11
- type IsolationLevel,
12
- type TypeConverter,
13
- } from "@deterministic-code/datasources";
14
- import { PostgresConnection } from "./connection.ts";
15
- import { PostgresCommand } from "./command.ts";
16
- import { PostgresTransaction } from "./transaction.ts";
17
- import { PostgresRowTypeConverters } from "./converters/PostgresRowTypeConverters.ts";
18
- import { PostgresStatementRenderer } from "./PostgresStatementRenderer.ts";
19
- import { columnTypes } from "./columnTypes.ts";
20
-
21
- export { columnTypes };
22
-
23
- const statements = new StatementTextRenderer(t => new PostgresStatementRenderer(t));
24
-
25
- export class PostgresDriver implements IDriver {
26
- readonly statementRenderer = statements;
27
- readonly information: Information = {
28
- descriptions: [
29
- "PostgreSQL server driver.",
30
- "Full connection, command, transaction, and repository support.",
31
- ],
32
- overrides: [
33
- "Overrides SelectInsertedIdStatement to SELECT lastval() AS {column}",
34
- "Overrides CreateTableStatement identity to GENERATED BY DEFAULT AS IDENTITY",
35
- "Overrides CreateTableStatement boolean defaults (0/1 → TRUE/FALSE)",
36
- "Overrides CreateTableStatement type mapping (int→INTEGER, uuid→UUID, string→TEXT, bool→BOOLEAN, decimal→NUMERIC, float→DOUBLE PRECISION, datetime→TIMESTAMPTZ, binary→BYTEA)",
37
- ],
38
- changeLogs: [],
39
- };
40
- rowTypeConverters: Record<string, TypeConverter<Cell, Cell>> = PostgresRowTypeConverters;
41
- columnType = (name: string): string =>
42
- columnTypes[name] ??
43
- (() => {
44
- throw new DatasourceError(`Unknown postgres type "${name}"`);
45
- })();
46
- connection = (options?: DatasourceOptions): IConnection =>
47
- PostgresConnection.from(options);
48
- command = (connection: IConnection): ICommand =>
49
- new PostgresCommand(connection as PostgresConnection, statements);
50
- transaction = (
51
- connection: IConnection,
52
- isolation: IsolationLevel = "readCommitted",
53
- ): ITransaction =>
54
- new PostgresTransaction(connection as PostgresConnection, isolation);
55
- }
@@ -1,34 +0,0 @@
1
- import {
2
- BulkUpdateStatement,
3
- CreateTableStatement,
4
- SelectInsertedIdStatement,
5
- SelectInsertedIdStatementTextRenderer,
6
- StatementRenderer,
7
- type StatementTextRenderer,
8
- } from "@deterministic-code/datasources";
9
- import { PostgresBulkUpdateStatementTextRenderer } from "./PostgresBulkUpdateStatementTextRenderer.ts";
10
- import { PostgresCreateTableStatementRenderer } from "./PostgresCreateTableStatementRenderer.ts";
11
-
12
- class PostgresSelectInsertedIdStatementTextRenderer extends SelectInsertedIdStatementTextRenderer {
13
- override render(statement: SelectInsertedIdStatement): string {
14
- return `SELECT lastval() AS ${statement.column}`;
15
- }
16
- }
17
-
18
- export class PostgresStatementRenderer extends StatementRenderer {
19
- constructor(text: StatementTextRenderer) {
20
- super(text);
21
- }
22
-
23
- protected override visitSelectInsertedId(inserted: SelectInsertedIdStatement): string {
24
- return new PostgresSelectInsertedIdStatementTextRenderer().render(inserted);
25
- }
26
-
27
- protected override visitCreateTable(create: CreateTableStatement): string {
28
- return new PostgresCreateTableStatementRenderer().render(create);
29
- }
30
-
31
- protected override visitBulkUpdate(update: BulkUpdateStatement): string {
32
- return new PostgresBulkUpdateStatementTextRenderer().render(update);
33
- }
34
- }
package/src/bind.ts DELETED
@@ -1,50 +0,0 @@
1
- import { parametersToRecord, type Cell, type Parameter } from "@deterministic-code/datasources";
2
- import { isBase64 } from "./converters/BinaryConverter.ts";
3
- import { isIsoDate } from "./converters/DateTimeConverter.ts";
4
- import { reverse } from "./converters/PostgresRowTypeConverters.ts";
5
- import type { Scalar, Wire } from "./scalar.ts";
6
-
7
- const NAME = /\$([A-Za-z_][A-Za-z0-9_]*)/g;
8
-
9
- const quoteMixedCase = (sql: string): string =>
10
- sql.replace(/\$[A-Za-z_][A-Za-z0-9_]*|'[^']*'|"[^"]*"|`[^`]*`|\b[A-Za-z_][A-Za-z0-9_]*\b/g, (token) =>
11
- token.startsWith("$") || token.startsWith("'") || token.startsWith("\"") || token.startsWith("`")
12
- || !/[A-Z]/.test(token) || !/[a-z]/.test(token)
13
- ? token
14
- : `"${token}"`,
15
- );
16
-
17
- const wire = (value: Scalar): Wire =>
18
- typeof value !== "string"
19
- ? value
20
- : isIsoDate(value)
21
- ? new Date(value)
22
- : isBase64(value)
23
- ? Uint8Array.from(Buffer.from(value, "base64"))
24
- : value;
25
-
26
- export const toPostgres = (
27
- sql: string,
28
- params?: Record<string, Scalar>,
29
- ): { text: string; values: Wire[] } => {
30
- const names: string[] = [];
31
- const text = quoteMixedCase(sql).replace(NAME, (_match, name: string) => {
32
- let index = names.indexOf(name);
33
- if (index < 0) {
34
- names.push(name);
35
- index = names.length - 1;
36
- }
37
- return `$${index + 1}`;
38
- });
39
- return { text, values: names.map((name) => wire(params?.[name] ?? null)) };
40
- };
41
-
42
- export const bindParameters = (
43
- parameters?: Parameter[] | null,
44
- ): Record<string, Scalar> => {
45
- const record = parametersToRecord(parameters);
46
- const bound: Record<string, Scalar> = {};
47
- for (const [name, value] of Object.entries(record))
48
- bound[name] = reverse(value as Cell) as Scalar;
49
- return bound;
50
- };
@@ -1,10 +0,0 @@
1
- export const columnTypes: Record<string, string> = {
2
- int: "INTEGER",
3
- uuid: "UUID",
4
- string: "TEXT",
5
- bool: "BOOLEAN",
6
- decimal: "NUMERIC",
7
- float: "DOUBLE PRECISION",
8
- datetime: "TIMESTAMPTZ",
9
- binary: "BYTEA",
10
- };