drizzle-databend 0.1.9 → 0.1.11
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.
- package/dist/client.d.ts +8 -4
- package/dist/dialect.d.ts +2 -2
- package/dist/driver.d.ts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +705 -589
- package/dist/session.d.ts +5 -4
- package/package.json +11 -5
- package/src/client.ts +71 -27
- package/src/columns.ts +1 -1
- package/src/dialect.ts +17 -7
- package/src/driver.ts +9 -9
- package/src/index.ts +3 -3
- package/src/migrator.ts +1 -1
- package/src/pool.ts +3 -1
- package/src/session.ts +15 -15
- package/src/sql/result-mapper.ts +3 -4
- package/src/sql/selection.ts +1 -1
package/dist/session.d.ts
CHANGED
|
@@ -2,13 +2,13 @@ import { entityKind } from 'drizzle-orm/entity';
|
|
|
2
2
|
import type { Logger } from 'drizzle-orm/logger';
|
|
3
3
|
import { PgTransaction } from 'drizzle-orm/pg-core';
|
|
4
4
|
import type { SelectedFieldsOrdered } from 'drizzle-orm/pg-core/query-builders/select.types';
|
|
5
|
-
import type { PgTransactionConfig, PreparedQueryConfig
|
|
5
|
+
import type { PgQueryResultHKT, PgTransactionConfig, PreparedQueryConfig } from 'drizzle-orm/pg-core/session';
|
|
6
6
|
import { PgPreparedQuery, PgSession } from 'drizzle-orm/pg-core/session';
|
|
7
7
|
import type { RelationalSchemaConfig, TablesRelationalConfig } from 'drizzle-orm/relations';
|
|
8
|
-
import { type Query, SQL } from 'drizzle-orm/sql/sql';
|
|
8
|
+
import { type Query, type QueryTypingsValue, type SQL } from 'drizzle-orm/sql/sql';
|
|
9
9
|
import type { Assume } from 'drizzle-orm/utils';
|
|
10
|
-
import type { DatabendDialect } from './dialect.ts';
|
|
11
10
|
import type { DatabendClientLike, RowData } from './client.ts';
|
|
11
|
+
import type { DatabendDialect } from './dialect.ts';
|
|
12
12
|
export type { DatabendClientLike, RowData } from './client.ts';
|
|
13
13
|
export declare class DatabendPreparedQuery<T extends PreparedQueryConfig> extends PgPreparedQuery<T> {
|
|
14
14
|
private client;
|
|
@@ -18,8 +18,9 @@ export declare class DatabendPreparedQuery<T extends PreparedQueryConfig> extend
|
|
|
18
18
|
private fields;
|
|
19
19
|
private _isResponseInArrayMode;
|
|
20
20
|
private customResultMapper;
|
|
21
|
+
private typings?;
|
|
21
22
|
static readonly [entityKind]: string;
|
|
22
|
-
constructor(client: DatabendClientLike, queryString: string, params: unknown[], logger: Logger, fields: SelectedFieldsOrdered | undefined, _isResponseInArrayMode: boolean, customResultMapper: ((rows: unknown[][]) => T['execute']) | undefined);
|
|
23
|
+
constructor(client: DatabendClientLike, queryString: string, params: unknown[], logger: Logger, fields: SelectedFieldsOrdered | undefined, _isResponseInArrayMode: boolean, customResultMapper: ((rows: unknown[][]) => T['execute']) | undefined, typings?: QueryTypingsValue[] | undefined);
|
|
23
24
|
execute(placeholderValues?: Record<string, unknown> | undefined): Promise<T['execute']>;
|
|
24
25
|
all(placeholderValues?: Record<string, unknown> | undefined): Promise<T['all']>;
|
|
25
26
|
isResponseInArrayMode(): boolean;
|
package/package.json
CHANGED
|
@@ -3,13 +3,18 @@
|
|
|
3
3
|
"module": "./dist/index.mjs",
|
|
4
4
|
"main": "./dist/index.mjs",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.11",
|
|
7
7
|
"description": "A drizzle ORM driver for use with Databend. Based on drizzle's Postgres driver surface.",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "
|
|
10
|
+
"build": "esbuild src/index.ts --bundle --format=esm --platform=node --packages=external --outfile=dist/index.mjs && npm run build:declarations",
|
|
11
11
|
"build:declarations": "tsc --emitDeclarationOnly --project tsconfig.types.json",
|
|
12
|
-
"test": "vitest"
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"db:start": "docker start databend 2>/dev/null || docker run -d --name databend -p 8000:8000 datafuselabs/databend",
|
|
14
|
+
"db:stop": "docker stop databend",
|
|
15
|
+
"db:restart": "docker restart databend",
|
|
16
|
+
"lint": "biome check src/ test/",
|
|
17
|
+
"typecheck": "tsc --noEmit"
|
|
13
18
|
},
|
|
14
19
|
"peerDependencies": {
|
|
15
20
|
"databend-driver": ">=0.33.0",
|
|
@@ -21,9 +26,11 @@
|
|
|
21
26
|
}
|
|
22
27
|
},
|
|
23
28
|
"devDependencies": {
|
|
29
|
+
"@biomejs/biome": "^2.4.7",
|
|
30
|
+
"@types/node": "^25.5.0",
|
|
24
31
|
"databend-driver": "^0.33.6",
|
|
25
|
-
"@types/bun": "^1.2.5",
|
|
26
32
|
"drizzle-orm": "0.40.0",
|
|
33
|
+
"esbuild": "^0.25.0",
|
|
27
34
|
"typescript": "^5.8.2",
|
|
28
35
|
"vitest": "^1.6.0"
|
|
29
36
|
},
|
|
@@ -39,7 +46,6 @@
|
|
|
39
46
|
"engines": {
|
|
40
47
|
"node": ">=18.17"
|
|
41
48
|
},
|
|
42
|
-
"packageManager": "bun@1.3.6",
|
|
43
49
|
"keywords": [
|
|
44
50
|
"drizzle",
|
|
45
51
|
"databend"
|
package/src/client.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Connection } from 'databend-driver';
|
|
2
|
+
import type { QueryTypingsValue } from 'drizzle-orm';
|
|
2
3
|
|
|
3
4
|
export interface DatabendConnectionPool {
|
|
4
5
|
acquire(): Promise<Connection>;
|
|
@@ -20,16 +21,50 @@ export function isPool(
|
|
|
20
21
|
/**
|
|
21
22
|
* Convert Drizzle param array to a JSON value accepted by databend-driver's Params.
|
|
22
23
|
* Databend's Params is serde_json::Value, so we pass an array of JSON-serializable values.
|
|
24
|
+
*
|
|
25
|
+
* The databend-driver does client-side parameter substitution with no string escaping,
|
|
26
|
+
* so we must pre-escape single quotes here (SQL standard '' escaping).
|
|
23
27
|
*/
|
|
24
|
-
export function prepareParams(params: unknown[]): unknown[] {
|
|
25
|
-
return params.map((param) => {
|
|
28
|
+
export function prepareParams(params: unknown[], typings?: QueryTypingsValue[]): unknown[] {
|
|
29
|
+
return params.map((param, i) => {
|
|
26
30
|
if (param === undefined) return null;
|
|
27
|
-
if (param instanceof Date) return param.toISOString();
|
|
31
|
+
if (param instanceof Date) return param.toISOString().replace(/'/g, "''");
|
|
28
32
|
if (typeof param === 'bigint') return param.toString();
|
|
33
|
+
if (typeof param === 'string') {
|
|
34
|
+
const typing = typings?.[i];
|
|
35
|
+
if (typing === 'decimal' && /^-?\d+(\.\d+)?([eE][+-]?\d+)?$/.test(param)) {
|
|
36
|
+
return Number(param);
|
|
37
|
+
}
|
|
38
|
+
return param.replace(/'/g, "''");
|
|
39
|
+
}
|
|
40
|
+
if (typeof param === 'object' && param !== null) {
|
|
41
|
+
return JSON.stringify(param).replace(/'/g, "''");
|
|
42
|
+
}
|
|
29
43
|
return param;
|
|
30
44
|
});
|
|
31
45
|
}
|
|
32
46
|
|
|
47
|
+
function isTransientError(error: unknown): boolean {
|
|
48
|
+
if (!(error instanceof Error)) return false;
|
|
49
|
+
const msg = error.message?.toLowerCase() ?? '';
|
|
50
|
+
return msg.includes('connection closed') || msg.includes('econnreset') ||
|
|
51
|
+
msg.includes('epipe') || msg.includes('socket hang up') ||
|
|
52
|
+
msg.includes('connection refused');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 2): Promise<T> {
|
|
56
|
+
let lastError: unknown;
|
|
57
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
58
|
+
try { return await fn(); }
|
|
59
|
+
catch (error) {
|
|
60
|
+
lastError = error;
|
|
61
|
+
if (!isTransientError(error) || attempt === maxRetries) throw error;
|
|
62
|
+
await new Promise(r => setTimeout(r, 100 * 2 ** attempt));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
throw lastError;
|
|
66
|
+
}
|
|
67
|
+
|
|
33
68
|
function deduplicateColumns(columns: string[]): string[] {
|
|
34
69
|
const counts = new Map<string, number>();
|
|
35
70
|
let hasDuplicates = false;
|
|
@@ -58,18 +93,21 @@ function deduplicateColumns(columns: string[]): string[] {
|
|
|
58
93
|
export async function executeOnClient(
|
|
59
94
|
client: DatabendClientLike,
|
|
60
95
|
query: string,
|
|
61
|
-
params: unknown[]
|
|
96
|
+
params: unknown[],
|
|
97
|
+
typings?: QueryTypingsValue[]
|
|
62
98
|
): Promise<RowData[]> {
|
|
63
99
|
if (isPool(client)) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
100
|
+
return withRetry(async () => {
|
|
101
|
+
const connection = await client.acquire();
|
|
102
|
+
try {
|
|
103
|
+
return await executeOnClient(connection, query, params, typings);
|
|
104
|
+
} finally {
|
|
105
|
+
await client.release(connection);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
70
108
|
}
|
|
71
109
|
|
|
72
|
-
const prepared = prepareParams(params);
|
|
110
|
+
const prepared = prepareParams(params, typings);
|
|
73
111
|
const paramValue = prepared.length > 0 ? prepared : undefined;
|
|
74
112
|
const rows = await client.queryAll(query, paramValue);
|
|
75
113
|
|
|
@@ -83,18 +121,21 @@ export async function executeOnClient(
|
|
|
83
121
|
export async function executeArraysOnClient(
|
|
84
122
|
client: DatabendClientLike,
|
|
85
123
|
query: string,
|
|
86
|
-
params: unknown[]
|
|
124
|
+
params: unknown[],
|
|
125
|
+
typings?: QueryTypingsValue[]
|
|
87
126
|
): Promise<ExecuteArraysResult> {
|
|
88
127
|
if (isPool(client)) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
128
|
+
return withRetry(async () => {
|
|
129
|
+
const connection = await client.acquire();
|
|
130
|
+
try {
|
|
131
|
+
return await executeArraysOnClient(connection, query, params, typings);
|
|
132
|
+
} finally {
|
|
133
|
+
await client.release(connection);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
95
136
|
}
|
|
96
137
|
|
|
97
|
-
const prepared = prepareParams(params);
|
|
138
|
+
const prepared = prepareParams(params, typings);
|
|
98
139
|
const paramValue = prepared.length > 0 ? prepared : undefined;
|
|
99
140
|
const iter = await client.queryIter(query, paramValue);
|
|
100
141
|
const schema = iter.schema();
|
|
@@ -115,18 +156,21 @@ export async function executeArraysOnClient(
|
|
|
115
156
|
export async function execOnClient(
|
|
116
157
|
client: DatabendClientLike,
|
|
117
158
|
query: string,
|
|
118
|
-
params: unknown[]
|
|
159
|
+
params: unknown[],
|
|
160
|
+
typings?: QueryTypingsValue[]
|
|
119
161
|
): Promise<number> {
|
|
120
162
|
if (isPool(client)) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
163
|
+
return withRetry(async () => {
|
|
164
|
+
const connection = await client.acquire();
|
|
165
|
+
try {
|
|
166
|
+
return await execOnClient(connection, query, params, typings);
|
|
167
|
+
} finally {
|
|
168
|
+
await client.release(connection);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
127
171
|
}
|
|
128
172
|
|
|
129
|
-
const prepared = prepareParams(params);
|
|
173
|
+
const prepared = prepareParams(params, typings);
|
|
130
174
|
const paramValue = prepared.length > 0 ? prepared : undefined;
|
|
131
175
|
return await client.exec(query, paramValue);
|
|
132
176
|
}
|
package/src/columns.ts
CHANGED
package/src/dialect.ts
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type DriverValueEncoder,
|
|
3
|
+
type QueryTypingsValue,
|
|
4
|
+
sql,
|
|
5
|
+
} from 'drizzle-orm';
|
|
1
6
|
import { entityKind, is } from 'drizzle-orm/entity';
|
|
2
7
|
import type { MigrationConfig, MigrationMeta } from 'drizzle-orm/migrator';
|
|
3
8
|
import {
|
|
9
|
+
PgBigInt53,
|
|
10
|
+
PgBigInt64,
|
|
4
11
|
PgDate,
|
|
5
12
|
PgDateString,
|
|
6
13
|
PgDialect,
|
|
14
|
+
PgDoublePrecision,
|
|
15
|
+
PgInteger,
|
|
7
16
|
PgNumeric,
|
|
8
|
-
|
|
17
|
+
PgReal,
|
|
18
|
+
type PgSession,
|
|
19
|
+
PgSmallInt,
|
|
9
20
|
PgTime,
|
|
10
21
|
PgTimestamp,
|
|
11
22
|
PgTimestampString,
|
|
12
23
|
PgUUID,
|
|
13
24
|
} from 'drizzle-orm/pg-core';
|
|
14
|
-
import {
|
|
15
|
-
sql,
|
|
16
|
-
type DriverValueEncoder,
|
|
17
|
-
type QueryTypingsValue,
|
|
18
|
-
} from 'drizzle-orm';
|
|
19
25
|
|
|
20
26
|
export class DatabendDialect extends PgDialect {
|
|
21
27
|
static readonly [entityKind]: string = 'DatabendPgDialect';
|
|
@@ -92,7 +98,11 @@ export class DatabendDialect extends PgDialect {
|
|
|
92
98
|
override prepareTyping(
|
|
93
99
|
encoder: DriverValueEncoder<unknown, unknown>
|
|
94
100
|
): QueryTypingsValue {
|
|
95
|
-
if (
|
|
101
|
+
if (
|
|
102
|
+
is(encoder, PgNumeric) || is(encoder, PgInteger) || is(encoder, PgSmallInt)
|
|
103
|
+
|| is(encoder, PgReal) || is(encoder, PgDoublePrecision)
|
|
104
|
+
|| is(encoder, PgBigInt53) || is(encoder, PgBigInt64)
|
|
105
|
+
) {
|
|
96
106
|
return 'decimal';
|
|
97
107
|
} else if (is(encoder, PgTime)) {
|
|
98
108
|
return 'time';
|
package/src/driver.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Connection } from 'databend-driver';
|
|
1
2
|
import { Client } from 'databend-driver';
|
|
2
3
|
import { entityKind } from 'drizzle-orm/entity';
|
|
3
4
|
import type { Logger } from 'drizzle-orm/logger';
|
|
@@ -5,25 +6,24 @@ import { DefaultLogger } from 'drizzle-orm/logger';
|
|
|
5
6
|
import { PgDatabase } from 'drizzle-orm/pg-core/db';
|
|
6
7
|
import {
|
|
7
8
|
createTableRelationsHelpers,
|
|
8
|
-
extractTablesRelationalConfig,
|
|
9
9
|
type ExtractTablesWithRelations,
|
|
10
|
+
extractTablesRelationalConfig,
|
|
10
11
|
type RelationalSchemaConfig,
|
|
11
12
|
type TablesRelationalConfig,
|
|
12
13
|
} from 'drizzle-orm/relations';
|
|
13
|
-
import {
|
|
14
|
+
import type { DrizzleConfig } from 'drizzle-orm/utils';
|
|
15
|
+
import { closeClientConnection, isPool } from './client.ts';
|
|
16
|
+
import { DatabendDialect } from './dialect.ts';
|
|
17
|
+
import {
|
|
18
|
+
createDatabendConnectionPool,
|
|
19
|
+
type DatabendPoolConfig,
|
|
20
|
+
} from './pool.ts';
|
|
14
21
|
import type {
|
|
15
22
|
DatabendClientLike,
|
|
16
23
|
DatabendQueryResultHKT,
|
|
17
24
|
DatabendTransaction,
|
|
18
25
|
} from './session.ts';
|
|
19
26
|
import { DatabendSession } from './session.ts';
|
|
20
|
-
import { DatabendDialect } from './dialect.ts';
|
|
21
|
-
import { isPool, closeClientConnection } from './client.ts';
|
|
22
|
-
import {
|
|
23
|
-
createDatabendConnectionPool,
|
|
24
|
-
type DatabendPoolConfig,
|
|
25
|
-
} from './pool.ts';
|
|
26
|
-
import type { Connection } from 'databend-driver';
|
|
27
27
|
|
|
28
28
|
export interface DatabendDriverOptions {
|
|
29
29
|
logger?: Logger;
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './session.ts';
|
|
1
|
+
export * from './client.ts';
|
|
3
2
|
export * from './columns.ts';
|
|
3
|
+
export * from './driver.ts';
|
|
4
4
|
export * from './migrator.ts';
|
|
5
|
-
export * from './client.ts';
|
|
6
5
|
export * from './pool.ts';
|
|
6
|
+
export * from './session.ts';
|
package/src/migrator.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MigrationConfig } from 'drizzle-orm/migrator';
|
|
2
2
|
import { readMigrationFiles } from 'drizzle-orm/migrator';
|
|
3
|
-
import type { DatabendDatabase } from './driver.ts';
|
|
4
3
|
import type { PgSession } from 'drizzle-orm/pg-core/session';
|
|
4
|
+
import type { DatabendDatabase } from './driver.ts';
|
|
5
5
|
|
|
6
6
|
export type DatabendMigrationConfig = MigrationConfig | string;
|
|
7
7
|
|
package/src/pool.ts
CHANGED
|
@@ -215,7 +215,9 @@ export function createDatabendConnectionPool(
|
|
|
215
215
|
toClose.map((item) => closeClientConnection(item.connection))
|
|
216
216
|
);
|
|
217
217
|
total = Math.max(0, total - toClose.length);
|
|
218
|
-
|
|
218
|
+
for (const item of toClose) {
|
|
219
|
+
metadata.delete(item.connection);
|
|
220
|
+
}
|
|
219
221
|
|
|
220
222
|
const maxWait = 5000;
|
|
221
223
|
const start = Date.now();
|
package/src/session.ts
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
|
+
import type { Connection } from 'databend-driver';
|
|
1
2
|
import { entityKind } from 'drizzle-orm/entity';
|
|
3
|
+
import { TransactionRollbackError } from 'drizzle-orm/errors';
|
|
2
4
|
import type { Logger } from 'drizzle-orm/logger';
|
|
3
5
|
import { NoopLogger } from 'drizzle-orm/logger';
|
|
4
6
|
import { PgTransaction } from 'drizzle-orm/pg-core';
|
|
5
7
|
import type { SelectedFieldsOrdered } from 'drizzle-orm/pg-core/query-builders/select.types';
|
|
6
8
|
import type {
|
|
9
|
+
PgQueryResultHKT,
|
|
7
10
|
PgTransactionConfig,
|
|
8
11
|
PreparedQueryConfig,
|
|
9
|
-
PgQueryResultHKT,
|
|
10
12
|
} from 'drizzle-orm/pg-core/session';
|
|
11
13
|
import { PgPreparedQuery, PgSession } from 'drizzle-orm/pg-core/session';
|
|
12
14
|
import type {
|
|
13
15
|
RelationalSchemaConfig,
|
|
14
16
|
TablesRelationalConfig,
|
|
15
17
|
} from 'drizzle-orm/relations';
|
|
16
|
-
import { fillPlaceholders, type Query, SQL, sql } from 'drizzle-orm/sql/sql';
|
|
18
|
+
import { fillPlaceholders, type Query, type QueryTypingsValue, type SQL, sql } from 'drizzle-orm/sql/sql';
|
|
17
19
|
import type { Assume } from 'drizzle-orm/utils';
|
|
18
|
-
import { mapResultRow } from './sql/result-mapper.ts';
|
|
19
|
-
import { TransactionRollbackError } from 'drizzle-orm/errors';
|
|
20
|
-
import type { DatabendDialect } from './dialect.ts';
|
|
21
20
|
import type {
|
|
22
21
|
DatabendClientLike,
|
|
23
22
|
DatabendConnectionPool,
|
|
@@ -26,10 +25,10 @@ import type {
|
|
|
26
25
|
import {
|
|
27
26
|
executeArraysOnClient,
|
|
28
27
|
executeOnClient,
|
|
29
|
-
prepareParams,
|
|
30
28
|
isPool,
|
|
31
29
|
} from './client.ts';
|
|
32
|
-
import type {
|
|
30
|
+
import type { DatabendDialect } from './dialect.ts';
|
|
31
|
+
import { mapResultRow } from './sql/result-mapper.ts';
|
|
33
32
|
|
|
34
33
|
export type { DatabendClientLike, RowData } from './client.ts';
|
|
35
34
|
|
|
@@ -47,7 +46,8 @@ export class DatabendPreparedQuery<
|
|
|
47
46
|
private _isResponseInArrayMode: boolean,
|
|
48
47
|
private customResultMapper:
|
|
49
48
|
| ((rows: unknown[][]) => T['execute'])
|
|
50
|
-
| undefined
|
|
49
|
+
| undefined,
|
|
50
|
+
private typings?: QueryTypingsValue[]
|
|
51
51
|
) {
|
|
52
52
|
super({ sql: queryString, params });
|
|
53
53
|
}
|
|
@@ -55,19 +55,18 @@ export class DatabendPreparedQuery<
|
|
|
55
55
|
async execute(
|
|
56
56
|
placeholderValues: Record<string, unknown> | undefined = {}
|
|
57
57
|
): Promise<T['execute']> {
|
|
58
|
-
const params =
|
|
59
|
-
fillPlaceholders(this.params, placeholderValues)
|
|
60
|
-
);
|
|
58
|
+
const params = fillPlaceholders(this.params, placeholderValues);
|
|
61
59
|
this.logger.logQuery(this.queryString, params);
|
|
62
60
|
|
|
63
|
-
const { fields, joinsNotNullableMap, customResultMapper } =
|
|
61
|
+
const { fields, joinsNotNullableMap, customResultMapper, typings } =
|
|
64
62
|
this as typeof this & { joinsNotNullableMap?: Record<string, boolean> };
|
|
65
63
|
|
|
66
64
|
if (fields) {
|
|
67
65
|
const { rows } = await executeArraysOnClient(
|
|
68
66
|
this.client,
|
|
69
67
|
this.queryString,
|
|
70
|
-
params
|
|
68
|
+
params,
|
|
69
|
+
typings
|
|
71
70
|
);
|
|
72
71
|
|
|
73
72
|
if (rows.length === 0) {
|
|
@@ -81,7 +80,7 @@ export class DatabendPreparedQuery<
|
|
|
81
80
|
);
|
|
82
81
|
}
|
|
83
82
|
|
|
84
|
-
const rows = await executeOnClient(this.client, this.queryString, params);
|
|
83
|
+
const rows = await executeOnClient(this.client, this.queryString, params, typings);
|
|
85
84
|
|
|
86
85
|
return rows as T['execute'];
|
|
87
86
|
}
|
|
@@ -137,7 +136,8 @@ export class DatabendSession<
|
|
|
137
136
|
this.logger,
|
|
138
137
|
fields,
|
|
139
138
|
isResponseInArrayMode,
|
|
140
|
-
customResultMapper
|
|
139
|
+
customResultMapper,
|
|
140
|
+
(query as any).typings
|
|
141
141
|
);
|
|
142
142
|
}
|
|
143
143
|
|
package/src/sql/result-mapper.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type AnyColumn,
|
|
2
3
|
Column,
|
|
3
|
-
|
|
4
|
+
type DriverValueDecoder,
|
|
4
5
|
getTableName,
|
|
5
6
|
is,
|
|
6
|
-
type AnyColumn,
|
|
7
|
-
type DriverValueDecoder,
|
|
8
7
|
type SelectedFieldsOrdered,
|
|
8
|
+
SQL,
|
|
9
9
|
} from 'drizzle-orm';
|
|
10
10
|
import {
|
|
11
11
|
PgCustomColumn,
|
|
@@ -214,7 +214,6 @@ export function mapResultRow<TResult>(
|
|
|
214
214
|
if (nullifyMap[objectName] && nullifyMap[objectName] !== tableName) {
|
|
215
215
|
nullifyMap[objectName] = false;
|
|
216
216
|
}
|
|
217
|
-
continue;
|
|
218
217
|
}
|
|
219
218
|
}
|
|
220
219
|
return acc;
|
package/src/sql/selection.ts
CHANGED