neoorm 0.3.1 → 0.4.0
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/README.md +12 -6
- package/dist/bin/neoorm.js +45 -15
- package/dist/bin/neoorm.js.map +1 -1
- package/dist/codegen/diff-manifest.d.ts +7 -7
- package/dist/codegen/diff-manifest.d.ts.map +1 -1
- package/dist/codegen/diff-manifest.js +67 -54
- package/dist/codegen/diff-manifest.js.map +1 -1
- package/dist/codegen/generate-summary.js.map +1 -1
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +11 -1
- package/dist/codegen/generate.js.map +1 -1
- package/dist/codegen/manifest-relations.d.ts.map +1 -1
- package/dist/codegen/manifest-relations.js +21 -0
- package/dist/codegen/manifest-relations.js.map +1 -1
- package/dist/codegen/schema-to-manifest.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/dialect/postgres.d.ts +3 -4
- package/dist/dialect/postgres.d.ts.map +1 -1
- package/dist/dialect/postgres.js +19 -11
- package/dist/dialect/postgres.js.map +1 -1
- package/dist/dialect/shared.d.ts +6 -0
- package/dist/dialect/shared.d.ts.map +1 -0
- package/dist/dialect/shared.js +16 -0
- package/dist/dialect/shared.js.map +1 -0
- package/dist/dialect/sqlite.d.ts +4 -0
- package/dist/dialect/sqlite.d.ts.map +1 -0
- package/dist/dialect/sqlite.js +276 -0
- package/dist/dialect/sqlite.js.map +1 -0
- package/dist/dialect/types.d.ts +7 -0
- package/dist/dialect/types.d.ts.map +1 -1
- package/dist/init/scaffold.js.map +1 -1
- package/dist/introspect/pull.d.ts +3 -2
- package/dist/introspect/pull.d.ts.map +1 -1
- package/dist/introspect/pull.js +124 -13
- package/dist/introspect/pull.js.map +1 -1
- package/dist/introspect/queries.d.ts +9 -9
- package/dist/introspect/queries.d.ts.map +1 -1
- package/dist/introspect/queries.js +16 -16
- package/dist/introspect/queries.js.map +1 -1
- package/dist/introspect/sqlite/to-manifest.d.ts +4 -0
- package/dist/introspect/sqlite/to-manifest.d.ts.map +1 -0
- package/dist/introspect/sqlite/to-manifest.js +166 -0
- package/dist/introspect/sqlite/to-manifest.js.map +1 -0
- package/dist/introspect/to-manifest.d.ts +2 -2
- package/dist/introspect/to-manifest.d.ts.map +1 -1
- package/dist/introspect/to-manifest.js +20 -12
- package/dist/introspect/to-manifest.js.map +1 -1
- package/dist/migrate/runner.d.ts +14 -14
- package/dist/migrate/runner.d.ts.map +1 -1
- package/dist/migrate/runner.js +83 -88
- package/dist/migrate/runner.js.map +1 -1
- package/dist/plugins/builtin.d.ts +1 -0
- package/dist/plugins/builtin.d.ts.map +1 -1
- package/dist/plugins/builtin.js +96 -6
- package/dist/plugins/builtin.js.map +1 -1
- package/dist/plugins/json/operators.d.ts.map +1 -1
- package/dist/plugins/json/operators.js +14 -5
- package/dist/plugins/json/operators.js.map +1 -1
- package/dist/plugins/types.d.ts +4 -4
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/runtime/client.d.ts +21 -4
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +61 -9
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/driver.d.ts +28 -0
- package/dist/runtime/driver.d.ts.map +1 -0
- package/dist/runtime/driver.js +265 -0
- package/dist/runtime/driver.js.map +1 -0
- package/dist/runtime/errors.d.ts.map +1 -1
- package/dist/runtime/executor.d.ts +6 -3
- package/dist/runtime/executor.d.ts.map +1 -1
- package/dist/runtime/executor.js +60 -42
- package/dist/runtime/executor.js.map +1 -1
- package/dist/runtime/query/aggregate.d.ts.map +1 -1
- package/dist/runtime/query/aggregate.js +4 -3
- package/dist/runtime/query/aggregate.js.map +1 -1
- package/dist/runtime/query/compile.d.ts +37 -24
- package/dist/runtime/query/compile.d.ts.map +1 -1
- package/dist/runtime/query/compile.js +388 -95
- package/dist/runtime/query/compile.js.map +1 -1
- package/dist/runtime/query/count.d.ts.map +1 -1
- package/dist/runtime/query/count.js +7 -3
- package/dist/runtime/query/count.js.map +1 -1
- package/dist/runtime/query/create.d.ts +5 -0
- package/dist/runtime/query/create.d.ts.map +1 -1
- package/dist/runtime/query/create.js +63 -23
- package/dist/runtime/query/create.js.map +1 -1
- package/dist/runtime/query/cursor.d.ts +4 -3
- package/dist/runtime/query/cursor.d.ts.map +1 -1
- package/dist/runtime/query/cursor.js +10 -8
- package/dist/runtime/query/cursor.js.map +1 -1
- package/dist/runtime/query/delete.d.ts +1 -0
- package/dist/runtime/query/delete.d.ts.map +1 -1
- package/dist/runtime/query/delete.js +17 -6
- package/dist/runtime/query/delete.js.map +1 -1
- package/dist/runtime/query/execute.d.ts +4 -3
- package/dist/runtime/query/execute.d.ts.map +1 -1
- package/dist/runtime/query/execute.js +5 -4
- package/dist/runtime/query/execute.js.map +1 -1
- package/dist/runtime/query/find-or-create.d.ts.map +1 -1
- package/dist/runtime/query/find-or-create.js +57 -8
- package/dist/runtime/query/find-or-create.js.map +1 -1
- package/dist/runtime/query/find.d.ts +12 -3
- package/dist/runtime/query/find.d.ts.map +1 -1
- package/dist/runtime/query/find.js +159 -232
- package/dist/runtime/query/find.js.map +1 -1
- package/dist/runtime/query/manifest-lookup.d.ts +3 -2
- package/dist/runtime/query/manifest-lookup.d.ts.map +1 -1
- package/dist/runtime/query/manifest-lookup.js +5 -4
- package/dist/runtime/query/manifest-lookup.js.map +1 -1
- package/dist/runtime/query/paginate.d.ts.map +1 -1
- package/dist/runtime/query/paginate.js +16 -11
- package/dist/runtime/query/paginate.js.map +1 -1
- package/dist/runtime/query/primary-key.d.ts +8 -6
- package/dist/runtime/query/primary-key.d.ts.map +1 -1
- package/dist/runtime/query/primary-key.js +45 -17
- package/dist/runtime/query/primary-key.js.map +1 -1
- package/dist/runtime/query/relation-planner.d.ts +74 -0
- package/dist/runtime/query/relation-planner.d.ts.map +1 -0
- package/dist/runtime/query/relation-planner.js +648 -0
- package/dist/runtime/query/relation-planner.js.map +1 -0
- package/dist/runtime/query/relation-writes.d.ts +2 -1
- package/dist/runtime/query/relation-writes.d.ts.map +1 -1
- package/dist/runtime/query/relation-writes.js +33 -22
- package/dist/runtime/query/relation-writes.js.map +1 -1
- package/dist/runtime/query/table-index.d.ts +51 -3
- package/dist/runtime/query/table-index.d.ts.map +1 -1
- package/dist/runtime/query/table-index.js +119 -4
- package/dist/runtime/query/table-index.js.map +1 -1
- package/dist/runtime/query/unique.d.ts +3 -2
- package/dist/runtime/query/unique.d.ts.map +1 -1
- package/dist/runtime/query/unique.js +7 -6
- package/dist/runtime/query/unique.js.map +1 -1
- package/dist/runtime/query/update.d.ts +2 -0
- package/dist/runtime/query/update.d.ts.map +1 -1
- package/dist/runtime/query/update.js +98 -30
- package/dist/runtime/query/update.js.map +1 -1
- package/dist/runtime/query/updated-at.d.ts +6 -4
- package/dist/runtime/query/updated-at.d.ts.map +1 -1
- package/dist/runtime/query/updated-at.js +23 -9
- package/dist/runtime/query/updated-at.js.map +1 -1
- package/dist/runtime/query/upsert.d.ts.map +1 -1
- package/dist/runtime/query/upsert.js +11 -9
- package/dist/runtime/query/upsert.js.map +1 -1
- package/dist/runtime/sqlite-open.d.ts +3 -0
- package/dist/runtime/sqlite-open.d.ts.map +1 -0
- package/dist/runtime/sqlite-open.js +22 -0
- package/dist/runtime/sqlite-open.js.map +1 -0
- package/dist/runtime/transaction.d.ts +5 -0
- package/dist/runtime/transaction.d.ts.map +1 -0
- package/dist/runtime/transaction.js +26 -0
- package/dist/runtime/transaction.js.map +1 -0
- package/dist/runtime/types.d.ts +1 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/schema/column.d.ts +1 -1
- package/dist/schema/column.d.ts.map +1 -1
- package/dist/schema/column.js +1 -1
- package/dist/schema/column.js.map +1 -1
- package/dist/schema/define-schema.js.map +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/types.d.ts +3 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/sql/builder.d.ts.map +1 -1
- package/dist/sql/template.d.ts +7 -0
- package/dist/sql/template.d.ts.map +1 -1
- package/dist/sql/template.js +89 -3
- package/dist/sql/template.js.map +1 -1
- package/dist/utils/case.d.ts +4 -0
- package/dist/utils/case.d.ts.map +1 -1
- package/dist/utils/case.js +11 -0
- package/dist/utils/case.js.map +1 -1
- package/dist/utils/uuid.js.map +1 -1
- package/package.json +21 -4
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { effectiveRelations } from "../../codegen/manifest-relations.js";
|
|
2
|
-
import { quoteIdentifier, tableRef } from "../../dialect/postgres.js";
|
|
2
|
+
import { postgresDialect, quoteIdentifier, tableRef } from "../../dialect/postgres.js";
|
|
3
3
|
import { getColumnType } from "../../plugins/registry.js";
|
|
4
|
+
import { rebaseParamRefs } from "../../sql/template.js";
|
|
4
5
|
import { findM2M } from "./manifest-lookup.js";
|
|
5
6
|
import { primaryKeySqlName, requireScalarPrimaryKey, targetRelationPkSql, } from "./primary-key.js";
|
|
7
|
+
import { columnBySqlName, columnByTsName, columnsByTsNames, getOrSetSqlCache, getTableIndex, reorderKeyValues, sortedKeysCacheKey, } from "./table-index.js";
|
|
8
|
+
function colByTs(table, tsName, manifestIndex) {
|
|
9
|
+
return columnByTsName(getTableIndex(manifestIndex, table.accessor), table, tsName);
|
|
10
|
+
}
|
|
6
11
|
const PARAMLESS_OPERATORS = new Set(["isNull", "isNotNull"]);
|
|
7
12
|
function isOperatorObject(value) {
|
|
8
13
|
return (typeof value === "object" &&
|
|
@@ -20,18 +25,21 @@ function pluginWhereOperators(col) {
|
|
|
20
25
|
return {};
|
|
21
26
|
return getColumnType(col.kind)?.whereOperators ?? {};
|
|
22
27
|
}
|
|
23
|
-
export function serializeColumnValue(col, value) {
|
|
28
|
+
export function serializeColumnValue(col, value, dialect = postgresDialect) {
|
|
24
29
|
if (col.kind === "fk")
|
|
25
30
|
return value;
|
|
26
31
|
const plugin = getColumnType(col.kind);
|
|
27
32
|
if (plugin?.serializeValue) {
|
|
28
|
-
return plugin.serializeValue(col, value);
|
|
33
|
+
return plugin.serializeValue(col, value, dialect);
|
|
29
34
|
}
|
|
30
35
|
return value;
|
|
31
36
|
}
|
|
32
37
|
function defaultColumnRef(col) {
|
|
33
38
|
return quoteIdentifier(col.sqlName);
|
|
34
39
|
}
|
|
40
|
+
function qualifiedColumnRefForTable(table) {
|
|
41
|
+
return (col) => `${tableRef(table)}.${quoteIdentifier(col.sqlName)}`;
|
|
42
|
+
}
|
|
35
43
|
function parentPkRef(table) {
|
|
36
44
|
const pkSql = primaryKeySqlName(table);
|
|
37
45
|
return `${tableRef(table)}.${quoteIdentifier(pkSql)}`;
|
|
@@ -103,20 +111,22 @@ function compileColumnCondition(col, rawValue, dialect, paramIndex, columnRef) {
|
|
|
103
111
|
function compileExistsSubquery(existsSql, negate) {
|
|
104
112
|
return negate ? `NOT EXISTS (${existsSql})` : `EXISTS (${existsSql})`;
|
|
105
113
|
}
|
|
106
|
-
function compileRelationCondition(manifest, parentTable, relation, rawValue, dialect, paramIndex) {
|
|
114
|
+
function compileRelationCondition(manifest, parentTable, relation, rawValue, dialect, paramIndex, manifestIndex) {
|
|
107
115
|
const m2m = findM2M(manifest, parentTable.accessor, relation.name);
|
|
108
116
|
const targetTable = manifest.tables[relation.targetAccessor];
|
|
109
117
|
if (!targetTable) {
|
|
110
118
|
return { sql: "", params: [], nextParamIndex: paramIndex };
|
|
111
119
|
}
|
|
120
|
+
const parentTableIndex = getTableIndex(manifestIndex, parentTable.accessor);
|
|
121
|
+
const targetTableIndex = getTableIndex(manifestIndex, targetTable.accessor);
|
|
112
122
|
if (relation.cardinality === "one") {
|
|
113
123
|
if (!isOperatorObject(rawValue) || Array.isArray(rawValue)) {
|
|
114
124
|
return { sql: "", params: [], nextParamIndex: paramIndex };
|
|
115
125
|
}
|
|
116
126
|
const relAlias = "_rel";
|
|
117
127
|
const columnRef = (col) => `${quoteIdentifier(relAlias)}.${quoteIdentifier(col.sqlName)}`;
|
|
118
|
-
const nested = compileWhereNode(manifest, targetTable, rawValue, dialect, paramIndex, columnRef);
|
|
119
|
-
const parentFkCol =
|
|
128
|
+
const nested = compileWhereNode(manifest, targetTable, rawValue, dialect, paramIndex, columnRef, manifestIndex);
|
|
129
|
+
const parentFkCol = columnByTsName(parentTableIndex, parentTable, relation.fkColumn);
|
|
120
130
|
const parentFkRef = parentFkCol
|
|
121
131
|
? `${tableRef(parentTable)}.${quoteIdentifier(parentFkCol.sqlName)}`
|
|
122
132
|
: `${tableRef(parentTable)}.${quoteIdentifier(relation.fkSqlColumn)}`;
|
|
@@ -145,7 +155,7 @@ function compileRelationCondition(manifest, parentTable, relation, rawValue, dia
|
|
|
145
155
|
}
|
|
146
156
|
const relAlias = "_rel";
|
|
147
157
|
const columnRef = (col) => `${quoteIdentifier(relAlias)}.${quoteIdentifier(col.sqlName)}`;
|
|
148
|
-
const nested = compileWhereNode(manifest, targetTable, (nestedWhere ?? {}), dialect, paramIndex, columnRef);
|
|
158
|
+
const nested = compileWhereNode(manifest, targetTable, (nestedWhere ?? {}), dialect, paramIndex, columnRef, manifestIndex);
|
|
149
159
|
let fromClause;
|
|
150
160
|
let whereParts;
|
|
151
161
|
if (m2m) {
|
|
@@ -202,18 +212,20 @@ function compileRelationCondition(manifest, parentTable, relation, rawValue, dia
|
|
|
202
212
|
nextParamIndex: nested.nextParamIndex,
|
|
203
213
|
};
|
|
204
214
|
}
|
|
205
|
-
function compileWhereNode(manifest, table, where, dialect, startParamIndex, columnRef = defaultColumnRef) {
|
|
215
|
+
function compileWhereNode(manifest, table, where, dialect, startParamIndex, columnRef = defaultColumnRef, manifestIndex) {
|
|
206
216
|
const conditions = [];
|
|
207
217
|
const params = [];
|
|
208
218
|
let paramIndex = startParamIndex;
|
|
209
|
-
const
|
|
219
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
220
|
+
const relations = tableIndex?.effectiveRelationsByName ??
|
|
221
|
+
new Map(effectiveRelations(manifest, table).map((rel) => [rel.name, rel]));
|
|
210
222
|
for (const [key, value] of Object.entries(where)) {
|
|
211
223
|
if (key === "AND" && Array.isArray(value)) {
|
|
212
224
|
const parts = [];
|
|
213
225
|
for (const item of value) {
|
|
214
226
|
if (!item || typeof item !== "object" || Array.isArray(item))
|
|
215
227
|
continue;
|
|
216
|
-
const compiled = compileWhereNode(manifest, table, item, dialect, paramIndex, columnRef);
|
|
228
|
+
const compiled = compileWhereNode(manifest, table, item, dialect, paramIndex, columnRef, manifestIndex);
|
|
217
229
|
if (compiled.sql)
|
|
218
230
|
parts.push(`(${compiled.sql})`);
|
|
219
231
|
params.push(...compiled.params);
|
|
@@ -228,7 +240,7 @@ function compileWhereNode(manifest, table, where, dialect, startParamIndex, colu
|
|
|
228
240
|
for (const item of value) {
|
|
229
241
|
if (!item || typeof item !== "object" || Array.isArray(item))
|
|
230
242
|
continue;
|
|
231
|
-
const compiled = compileWhereNode(manifest, table, item, dialect, paramIndex, columnRef);
|
|
243
|
+
const compiled = compileWhereNode(manifest, table, item, dialect, paramIndex, columnRef, manifestIndex);
|
|
232
244
|
if (compiled.sql)
|
|
233
245
|
parts.push(`(${compiled.sql})`);
|
|
234
246
|
params.push(...compiled.params);
|
|
@@ -239,7 +251,7 @@ function compileWhereNode(manifest, table, where, dialect, startParamIndex, colu
|
|
|
239
251
|
continue;
|
|
240
252
|
}
|
|
241
253
|
if (key === "NOT" && isOperatorObject(value)) {
|
|
242
|
-
const compiled = compileWhereNode(manifest, table, value, dialect, paramIndex, columnRef);
|
|
254
|
+
const compiled = compileWhereNode(manifest, table, value, dialect, paramIndex, columnRef, manifestIndex);
|
|
243
255
|
if (compiled.sql)
|
|
244
256
|
conditions.push(`NOT (${compiled.sql})`);
|
|
245
257
|
params.push(...compiled.params);
|
|
@@ -248,14 +260,14 @@ function compileWhereNode(manifest, table, where, dialect, startParamIndex, colu
|
|
|
248
260
|
}
|
|
249
261
|
const relation = relations.get(key);
|
|
250
262
|
if (relation) {
|
|
251
|
-
const compiled = compileRelationCondition(manifest, table, relation, value, dialect, paramIndex);
|
|
263
|
+
const compiled = compileRelationCondition(manifest, table, relation, value, dialect, paramIndex, manifestIndex);
|
|
252
264
|
if (compiled.sql)
|
|
253
265
|
conditions.push(compiled.sql);
|
|
254
266
|
params.push(...compiled.params);
|
|
255
267
|
paramIndex = compiled.nextParamIndex;
|
|
256
268
|
continue;
|
|
257
269
|
}
|
|
258
|
-
const col =
|
|
270
|
+
const col = columnByTsName(tableIndex, table, key);
|
|
259
271
|
if (!col)
|
|
260
272
|
continue;
|
|
261
273
|
const compiled = compileColumnCondition(col, value, dialect, paramIndex, columnRef);
|
|
@@ -270,11 +282,14 @@ function compileWhereNode(manifest, table, where, dialect, startParamIndex, colu
|
|
|
270
282
|
nextParamIndex: paramIndex,
|
|
271
283
|
};
|
|
272
284
|
}
|
|
273
|
-
export function compileWhere(manifest, table, where, dialect, startParamIndex = 1) {
|
|
285
|
+
export function compileWhere(manifest, table, where, dialect, startParamIndex = 1, manifestIndex, qualifyColumns = false) {
|
|
274
286
|
if (!where || Object.keys(where).length === 0) {
|
|
275
287
|
return { sql: "", params: [] };
|
|
276
288
|
}
|
|
277
|
-
const
|
|
289
|
+
const columnRef = qualifyColumns
|
|
290
|
+
? qualifiedColumnRefForTable(table)
|
|
291
|
+
: defaultColumnRef;
|
|
292
|
+
const result = compileWhereNode(manifest, table, where, dialect, startParamIndex, columnRef, manifestIndex);
|
|
278
293
|
const impossible = isImpossibleWhereSql(result.sql);
|
|
279
294
|
return {
|
|
280
295
|
sql: result.sql ? `WHERE ${result.sql}` : "",
|
|
@@ -282,6 +297,148 @@ export function compileWhere(manifest, table, where, dialect, startParamIndex =
|
|
|
282
297
|
...(impossible ? { impossible: true } : {}),
|
|
283
298
|
};
|
|
284
299
|
}
|
|
300
|
+
function whereShapeKey(where) {
|
|
301
|
+
const parts = [];
|
|
302
|
+
for (const [key, value] of Object.entries(where)) {
|
|
303
|
+
if (key === "AND" && Array.isArray(value)) {
|
|
304
|
+
parts.push(`AND:${value
|
|
305
|
+
.filter((item) => !!item && typeof item === "object" && !Array.isArray(item))
|
|
306
|
+
.map((item) => whereShapeKey(item))
|
|
307
|
+
.join(",")}`);
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
if (key === "OR" && Array.isArray(value)) {
|
|
311
|
+
parts.push(`OR:${value
|
|
312
|
+
.filter((item) => !!item && typeof item === "object" && !Array.isArray(item))
|
|
313
|
+
.map((item) => whereShapeKey(item))
|
|
314
|
+
.join(",")}`);
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (key === "NOT" && isOperatorObject(value)) {
|
|
318
|
+
parts.push(`NOT:${whereShapeKey(value)}`);
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (isOperatorObject(value) && !(value instanceof Date)) {
|
|
322
|
+
const ops = Object.keys(value).sort();
|
|
323
|
+
if (ops.some((op) => op === "some" || op === "every" || op === "none")) {
|
|
324
|
+
const mode = ops.find((op) => op === "some" || op === "every" || op === "none");
|
|
325
|
+
const nested = value[mode ?? ""];
|
|
326
|
+
parts.push(`${key}:rel:${mode}:${isOperatorObject(nested) ? whereShapeKey(nested) : "{}"}`);
|
|
327
|
+
}
|
|
328
|
+
else if (ops.includes("in") || ops.includes("notIn")) {
|
|
329
|
+
const arr = value.in ?? value.notIn;
|
|
330
|
+
const len = Array.isArray(arr) ? arr.length : 0;
|
|
331
|
+
const op = ops.includes("in") ? "in" : "notIn";
|
|
332
|
+
parts.push(`${key}:${op}:${len}`);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
parts.push(`${key}:${ops.join(",")}`);
|
|
336
|
+
}
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
parts.push(`${key}:eq`);
|
|
340
|
+
}
|
|
341
|
+
return parts.join("&");
|
|
342
|
+
}
|
|
343
|
+
function collectWhereParams(manifest, table, where, dialect, manifestIndex) {
|
|
344
|
+
const params = [];
|
|
345
|
+
function walk(node, columnRef) {
|
|
346
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
347
|
+
const relations = tableIndex?.effectiveRelationsByName ??
|
|
348
|
+
new Map(effectiveRelations(manifest, table).map((rel) => [rel.name, rel]));
|
|
349
|
+
for (const [key, value] of Object.entries(node)) {
|
|
350
|
+
if (key === "AND" || key === "OR") {
|
|
351
|
+
if (Array.isArray(value)) {
|
|
352
|
+
for (const item of value) {
|
|
353
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
354
|
+
walk(item, columnRef);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (key === "NOT" && isOperatorObject(value)) {
|
|
361
|
+
walk(value, columnRef);
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (relations.get(key)) {
|
|
365
|
+
const compiled = compileRelationCondition(manifest, table, relations.get(key), value, dialect, 1, manifestIndex);
|
|
366
|
+
params.push(...compiled.params);
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
const col = columnByTsName(tableIndex, table, key);
|
|
370
|
+
if (!col)
|
|
371
|
+
continue;
|
|
372
|
+
const compiled = compileColumnCondition(col, value, dialect, 1, columnRef);
|
|
373
|
+
params.push(...compiled.params);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
walk(where, defaultColumnRef);
|
|
377
|
+
return params;
|
|
378
|
+
}
|
|
379
|
+
function whereValuesFingerprint(manifest, table, where, dialect, manifestIndex) {
|
|
380
|
+
return JSON.stringify(collectWhereParams(manifest, table, where, dialect, manifestIndex));
|
|
381
|
+
}
|
|
382
|
+
export function getCachedWhereClause(manifest, table, where, dialect, startParamIndex = 1, manifestIndex, qualifyColumns = false) {
|
|
383
|
+
if (!where || Object.keys(where).length === 0) {
|
|
384
|
+
return { sql: "", params: [] };
|
|
385
|
+
}
|
|
386
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
387
|
+
const shape = qualifyColumns
|
|
388
|
+
? `${whereShapeKey(where)}|qualified`
|
|
389
|
+
: whereShapeKey(where);
|
|
390
|
+
const shellCached = tableIndex?.whereClauseByShape.get(shape);
|
|
391
|
+
if (shellCached) {
|
|
392
|
+
return {
|
|
393
|
+
sql: shellCached.sql,
|
|
394
|
+
params: collectWhereParams(manifest, table, where, dialect, manifestIndex),
|
|
395
|
+
...(shellCached.impossible ? { impossible: true } : {}),
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
const fingerprint = whereValuesFingerprint(manifest, table, where, dialect, manifestIndex);
|
|
399
|
+
const cacheKey = `${shape}\0${fingerprint}`;
|
|
400
|
+
const cached = tableIndex?.whereClauseByFingerprint.get(cacheKey);
|
|
401
|
+
if (cached)
|
|
402
|
+
return cached;
|
|
403
|
+
const compiled = compileWhere(manifest, table, where, dialect, startParamIndex, manifestIndex, qualifyColumns);
|
|
404
|
+
tableIndex?.whereClauseByShape.set(shape, {
|
|
405
|
+
sql: compiled.sql,
|
|
406
|
+
...(compiled.impossible ? { impossible: true } : {}),
|
|
407
|
+
});
|
|
408
|
+
tableIndex?.whereClauseByFingerprint.set(cacheKey, compiled);
|
|
409
|
+
return compiled;
|
|
410
|
+
}
|
|
411
|
+
export function orderByShapeKey(orderBy, tableAlias) {
|
|
412
|
+
if (!orderBy || Object.keys(orderBy).length === 0)
|
|
413
|
+
return "";
|
|
414
|
+
const entries = Object.entries(orderBy)
|
|
415
|
+
.filter(([key]) => key !== "_count")
|
|
416
|
+
.map(([key, direction]) => typeof direction === "string" ? `${key}:${direction.toUpperCase()}` : "")
|
|
417
|
+
.filter(Boolean)
|
|
418
|
+
.sort((a, b) => a.localeCompare(b));
|
|
419
|
+
if (entries.length === 0)
|
|
420
|
+
return "";
|
|
421
|
+
const base = entries.join("|");
|
|
422
|
+
return tableAlias ? `${base}|@${tableAlias}` : base;
|
|
423
|
+
}
|
|
424
|
+
export function getCachedOrderByClause(table, orderBy, tableAlias, manifestIndex) {
|
|
425
|
+
if (!orderBy || Object.keys(orderBy).length === 0)
|
|
426
|
+
return "";
|
|
427
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
428
|
+
const shape = orderByShapeKey(orderBy, tableAlias);
|
|
429
|
+
if (!shape)
|
|
430
|
+
return "";
|
|
431
|
+
if (!tableIndex) {
|
|
432
|
+
return compileOrderBy(table, orderBy, tableAlias, manifestIndex);
|
|
433
|
+
}
|
|
434
|
+
return getOrSetSqlCache(tableIndex.orderBySqlByShape, shape, () => compileOrderBy(table, orderBy, tableAlias, manifestIndex));
|
|
435
|
+
}
|
|
436
|
+
export function getCachedDeleteManyQuery(tableIndex, table, whereSql) {
|
|
437
|
+
const cacheKey = whereSql || "";
|
|
438
|
+
if (!tableIndex)
|
|
439
|
+
return buildDeleteManyQuery(table, whereSql);
|
|
440
|
+
return getOrSetSqlCache(tableIndex.deleteManySqlByWhereShape, cacheKey, () => buildDeleteManyQuery(table, whereSql));
|
|
441
|
+
}
|
|
285
442
|
export function isImpossibleWhereSql(sql) {
|
|
286
443
|
if (!sql)
|
|
287
444
|
return false;
|
|
@@ -305,13 +462,16 @@ function buildSetExpression(col, paramIndex) {
|
|
|
305
462
|
const sqlCol = quoteIdentifier(col?.sqlName ?? "");
|
|
306
463
|
return `${sqlCol} = ${buildValuePlaceholder(col, paramIndex)}`;
|
|
307
464
|
}
|
|
308
|
-
export function compileOrderBy(table, orderBy, tableAlias) {
|
|
465
|
+
export function compileOrderBy(table, orderBy, tableAlias, manifestIndex) {
|
|
309
466
|
if (!orderBy || Object.keys(orderBy).length === 0)
|
|
310
467
|
return "";
|
|
468
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
311
469
|
const prefix = tableAlias ? `${quoteIdentifier(tableAlias)}.` : "";
|
|
312
470
|
const parts = [];
|
|
313
471
|
for (const [tsKey, direction] of Object.entries(orderBy)) {
|
|
314
|
-
|
|
472
|
+
if (tsKey === "_count" || typeof direction !== "string")
|
|
473
|
+
continue;
|
|
474
|
+
const col = columnByTsName(tableIndex, table, tsKey);
|
|
315
475
|
if (!col)
|
|
316
476
|
continue;
|
|
317
477
|
const dir = direction.toUpperCase() === "DESC" ? "DESC" : "ASC";
|
|
@@ -328,26 +488,33 @@ export function normalizeSelectColumns(select) {
|
|
|
328
488
|
.filter(([, enabled]) => enabled === true)
|
|
329
489
|
.map(([key]) => key);
|
|
330
490
|
}
|
|
491
|
+
function aliasToTsName(expression, col) {
|
|
492
|
+
if (col.sqlName === col.tsName)
|
|
493
|
+
return expression;
|
|
494
|
+
return `${expression} AS ${quoteIdentifier(col.tsName)}`;
|
|
495
|
+
}
|
|
331
496
|
function selectExpression(col) {
|
|
332
497
|
if (col.kind === "fk") {
|
|
333
|
-
return quoteIdentifier(col.sqlName);
|
|
498
|
+
return aliasToTsName(quoteIdentifier(col.sqlName), col);
|
|
334
499
|
}
|
|
335
500
|
const plugin = getColumnType(col.kind);
|
|
336
501
|
if (plugin?.selectExpression) {
|
|
337
|
-
return plugin.selectExpression(col);
|
|
502
|
+
return aliasToTsName(plugin.selectExpression(col), col);
|
|
338
503
|
}
|
|
339
|
-
return quoteIdentifier(col.sqlName);
|
|
504
|
+
return aliasToTsName(quoteIdentifier(col.sqlName), col);
|
|
340
505
|
}
|
|
341
|
-
export function buildSelectColumns(table, select) {
|
|
506
|
+
export function buildSelectColumns(table, select, manifestIndex) {
|
|
507
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
342
508
|
const cols = select && select.length > 0
|
|
343
|
-
?
|
|
509
|
+
? columnsByTsNames(tableIndex, table, select)
|
|
344
510
|
: table.columns;
|
|
345
511
|
return cols.map((c) => selectExpression(c)).join(", ");
|
|
346
512
|
}
|
|
347
|
-
export function buildQualifiedSelectColumns(table, select) {
|
|
513
|
+
export function buildQualifiedSelectColumns(table, select, manifestIndex) {
|
|
348
514
|
const ref = tableRef(table);
|
|
515
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
349
516
|
const cols = select && select.length > 0
|
|
350
|
-
?
|
|
517
|
+
? columnsByTsNames(tableIndex, table, select)
|
|
351
518
|
: table.columns;
|
|
352
519
|
return cols.map((c) => `${ref}.${selectExpression(c)}`).join(", ");
|
|
353
520
|
}
|
|
@@ -360,16 +527,21 @@ export function buildFindByIdQuery(table) {
|
|
|
360
527
|
export function buildFindAllQuery(table) {
|
|
361
528
|
return `SELECT ${buildSelectColumns(table)} FROM ${tableRef(table)}`;
|
|
362
529
|
}
|
|
363
|
-
export function
|
|
530
|
+
export function normalizeLimitOffset(value, label) {
|
|
531
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
532
|
+
throw new Error(`${label} must be a non-negative integer, got ${JSON.stringify(value)}`);
|
|
533
|
+
}
|
|
534
|
+
return value;
|
|
535
|
+
}
|
|
536
|
+
export function buildFindManyQuery(table, whereSql, orderSql, limit, offset, distinctOn, extraSelectCols, joinClauses, manifestIndex, groupBySql) {
|
|
364
537
|
const hasJoins = Boolean(joinClauses && joinClauses.length > 0);
|
|
538
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
365
539
|
const selectCols = hasJoins
|
|
366
|
-
? buildQualifiedSelectColumns(table)
|
|
367
|
-
: buildSelectColumns(table);
|
|
540
|
+
? buildQualifiedSelectColumns(table, undefined, manifestIndex)
|
|
541
|
+
: buildSelectColumns(table, undefined, manifestIndex);
|
|
368
542
|
let sql = "SELECT ";
|
|
369
543
|
if (distinctOn && distinctOn.length > 0) {
|
|
370
|
-
const distinctCols = distinctOn
|
|
371
|
-
.map((tsName) => table.columns.find((c) => c.tsName === tsName))
|
|
372
|
-
.filter((col) => col !== undefined)
|
|
544
|
+
const distinctCols = columnsByTsNames(tableIndex, table, distinctOn)
|
|
373
545
|
.map((col) => hasJoins
|
|
374
546
|
? `${tableRef(table)}.${quoteIdentifier(col.sqlName)}`
|
|
375
547
|
: quoteIdentifier(col.sqlName))
|
|
@@ -386,54 +558,59 @@ export function buildFindManyQuery(table, whereSql, orderSql, limit, offset, dis
|
|
|
386
558
|
}
|
|
387
559
|
if (whereSql)
|
|
388
560
|
sql += ` ${whereSql}`;
|
|
561
|
+
if (groupBySql)
|
|
562
|
+
sql += ` ${groupBySql}`;
|
|
389
563
|
if (orderSql)
|
|
390
564
|
sql += ` ${orderSql}`;
|
|
391
|
-
if (limit !== undefined)
|
|
392
|
-
sql += ` LIMIT ${limit}`;
|
|
393
|
-
|
|
394
|
-
|
|
565
|
+
if (limit !== undefined) {
|
|
566
|
+
sql += ` LIMIT ${normalizeLimitOffset(limit, "limit")}`;
|
|
567
|
+
}
|
|
568
|
+
if (offset !== undefined) {
|
|
569
|
+
sql += ` OFFSET ${normalizeLimitOffset(offset, "offset")}`;
|
|
570
|
+
}
|
|
395
571
|
return sql;
|
|
396
572
|
}
|
|
397
|
-
export function buildPaginateQuery(table, whereSql, orderSql, take) {
|
|
398
|
-
return buildFindManyQuery(table, whereSql, orderSql, take + 1);
|
|
573
|
+
export function buildPaginateQuery(table, whereSql, orderSql, take, extraSelectCols, joinClauses, manifestIndex) {
|
|
574
|
+
return buildFindManyQuery(table, whereSql, orderSql, take + 1, undefined, undefined, extraSelectCols, joinClauses, manifestIndex);
|
|
399
575
|
}
|
|
400
|
-
export function buildCountQuery(table, whereSql) {
|
|
401
|
-
let sql = `SELECT COUNT(*)
|
|
576
|
+
export function buildCountQuery(table, whereSql, dialect = postgresDialect) {
|
|
577
|
+
let sql = `SELECT ${dialect.castToInt("COUNT(*)")} AS count FROM ${tableRef(table)}`;
|
|
402
578
|
if (whereSql)
|
|
403
579
|
sql += ` ${whereSql}`;
|
|
404
580
|
return sql;
|
|
405
581
|
}
|
|
406
|
-
function aggregateSqlCol(table, tsName) {
|
|
407
|
-
const
|
|
582
|
+
function aggregateSqlCol(table, tsName, dialect, manifestIndex) {
|
|
583
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
584
|
+
const col = columnByTsName(tableIndex, table, tsName);
|
|
408
585
|
if (!col)
|
|
409
586
|
return undefined;
|
|
410
587
|
const sqlCol = quoteIdentifier(col.sqlName);
|
|
411
588
|
if (col.kind === "decimal")
|
|
412
|
-
return
|
|
589
|
+
return dialect.castToNumeric(sqlCol);
|
|
413
590
|
return sqlCol;
|
|
414
591
|
}
|
|
415
|
-
export function buildAggregateQuery(table, selectors, whereSql) {
|
|
592
|
+
export function buildAggregateQuery(table, selectors, whereSql, manifestIndex, dialect = postgresDialect) {
|
|
416
593
|
const parts = [];
|
|
417
594
|
if (selectors._count) {
|
|
418
|
-
parts.push(
|
|
595
|
+
parts.push(`${dialect.castToInt("COUNT(*)")} AS "__count"`);
|
|
419
596
|
}
|
|
420
597
|
for (const colName of Object.keys(selectors._avg ?? {})) {
|
|
421
|
-
const sqlCol = aggregateSqlCol(table, colName);
|
|
598
|
+
const sqlCol = aggregateSqlCol(table, colName, dialect, manifestIndex);
|
|
422
599
|
if (sqlCol)
|
|
423
600
|
parts.push(`AVG(${sqlCol}) AS "_avg_${colName}"`);
|
|
424
601
|
}
|
|
425
602
|
for (const colName of Object.keys(selectors._sum ?? {})) {
|
|
426
|
-
const sqlCol = aggregateSqlCol(table, colName);
|
|
603
|
+
const sqlCol = aggregateSqlCol(table, colName, dialect, manifestIndex);
|
|
427
604
|
if (sqlCol)
|
|
428
605
|
parts.push(`SUM(${sqlCol}) AS "_sum_${colName}"`);
|
|
429
606
|
}
|
|
430
607
|
for (const colName of Object.keys(selectors._min ?? {})) {
|
|
431
|
-
const sqlCol = aggregateSqlCol(table, colName);
|
|
608
|
+
const sqlCol = aggregateSqlCol(table, colName, dialect, manifestIndex);
|
|
432
609
|
if (sqlCol)
|
|
433
610
|
parts.push(`MIN(${sqlCol}) AS "_min_${colName}"`);
|
|
434
611
|
}
|
|
435
612
|
for (const colName of Object.keys(selectors._max ?? {})) {
|
|
436
|
-
const sqlCol = aggregateSqlCol(table, colName);
|
|
613
|
+
const sqlCol = aggregateSqlCol(table, colName, dialect, manifestIndex);
|
|
437
614
|
if (sqlCol)
|
|
438
615
|
parts.push(`MAX(${sqlCol}) AS "_max_${colName}"`);
|
|
439
616
|
}
|
|
@@ -445,49 +622,68 @@ export function buildAggregateQuery(table, selectors, whereSql) {
|
|
|
445
622
|
sql += ` ${whereSql}`;
|
|
446
623
|
return sql;
|
|
447
624
|
}
|
|
448
|
-
export function
|
|
625
|
+
export function aggregateSelectorCacheKey(selectors) {
|
|
626
|
+
const parts = [];
|
|
627
|
+
if (selectors._count)
|
|
628
|
+
parts.push("_count");
|
|
629
|
+
for (const key of ["_avg", "_sum", "_min", "_max"]) {
|
|
630
|
+
const fieldMap = selectors[key];
|
|
631
|
+
if (!fieldMap)
|
|
632
|
+
continue;
|
|
633
|
+
parts.push(`${key}:${Object.keys(fieldMap).sort().join(",")}`);
|
|
634
|
+
}
|
|
635
|
+
return parts.join("|");
|
|
636
|
+
}
|
|
637
|
+
export function getCachedAggregateQuery(tableIndex, table, selectors, whereSql, manifestIndex, dialect = postgresDialect) {
|
|
638
|
+
const cacheKey = `${dialect.name}|${aggregateSelectorCacheKey(selectors)}|${whereSql}`;
|
|
639
|
+
if (!tableIndex) {
|
|
640
|
+
return buildAggregateQuery(table, selectors, whereSql, manifestIndex, dialect);
|
|
641
|
+
}
|
|
642
|
+
return getOrSetSqlCache(tableIndex.aggregateSqlBySelector, cacheKey, () => buildAggregateQuery(table, selectors, whereSql, manifestIndex, dialect));
|
|
643
|
+
}
|
|
644
|
+
export function buildUpsertQuery(table, insertKeys, updateKeys, conflictSqlColumns, exprSets = [], manifestIndex) {
|
|
449
645
|
const insertCols = insertKeys.map((k) => {
|
|
450
|
-
const col = table
|
|
646
|
+
const col = colByTs(table, k, manifestIndex);
|
|
451
647
|
return quoteIdentifier(col?.sqlName ?? k);
|
|
452
648
|
});
|
|
453
649
|
const insertPlaceholders = insertKeys
|
|
454
650
|
.map((k, i) => {
|
|
455
|
-
const col = table
|
|
651
|
+
const col = colByTs(table, k, manifestIndex);
|
|
456
652
|
return buildValuePlaceholder(col, i + 1);
|
|
457
653
|
})
|
|
458
654
|
.join(", ");
|
|
459
|
-
const selectCols = buildSelectColumns(table);
|
|
655
|
+
const selectCols = buildSelectColumns(table, undefined, manifestIndex);
|
|
460
656
|
const conflictCols = conflictSqlColumns
|
|
461
657
|
.map((c) => quoteIdentifier(c))
|
|
462
658
|
.join(", ");
|
|
463
659
|
const updateSets = updateKeys.length > 0
|
|
464
660
|
? updateKeys.map((k) => {
|
|
465
|
-
const col = table
|
|
661
|
+
const col = colByTs(table, k, manifestIndex);
|
|
466
662
|
const sqlCol = quoteIdentifier(col?.sqlName ?? k);
|
|
467
|
-
return `${sqlCol} =
|
|
663
|
+
return `${sqlCol} = excluded.${sqlCol}`;
|
|
468
664
|
})
|
|
469
665
|
: exprSets.length === 0
|
|
470
666
|
? conflictSqlColumns.map((c) => {
|
|
471
667
|
const sqlCol = quoteIdentifier(c);
|
|
472
|
-
return `${sqlCol} =
|
|
668
|
+
return `${sqlCol} = excluded.${sqlCol}`;
|
|
473
669
|
})
|
|
474
670
|
: [];
|
|
475
671
|
const allUpdateSets = [...updateSets, ...exprSets];
|
|
476
672
|
return `INSERT INTO ${tableRef(table)} (${insertCols.join(", ")}) VALUES (${insertPlaceholders}) ON CONFLICT (${conflictCols}) DO UPDATE SET ${allUpdateSets.join(", ")} RETURNING ${selectCols}`;
|
|
477
673
|
}
|
|
478
674
|
export const FIND_OR_CREATE_FLAG = "__neoorm_created";
|
|
479
|
-
export function buildFindOrCreateQuery(table, insertKeys, conflictSqlColumns, fallbackWhereBody) {
|
|
675
|
+
export function buildFindOrCreateQuery(table, insertKeys, conflictSqlColumns, fallbackWhereBody, manifestIndex) {
|
|
480
676
|
const insertCols = insertKeys.map((k) => {
|
|
481
|
-
const col = table
|
|
677
|
+
const col = colByTs(table, k, manifestIndex);
|
|
482
678
|
return quoteIdentifier(col?.sqlName ?? k);
|
|
483
679
|
});
|
|
484
680
|
const insertPlaceholders = insertKeys
|
|
485
681
|
.map((k, i) => {
|
|
486
|
-
const col = table
|
|
682
|
+
const col = colByTs(table, k, manifestIndex);
|
|
487
683
|
return buildValuePlaceholder(col, i + 1);
|
|
488
684
|
})
|
|
489
685
|
.join(", ");
|
|
490
|
-
const selectCols = buildSelectColumns(table);
|
|
686
|
+
const selectCols = buildSelectColumns(table, undefined, manifestIndex);
|
|
491
687
|
const conflictCols = conflictSqlColumns
|
|
492
688
|
.map((c) => quoteIdentifier(c))
|
|
493
689
|
.join(", ");
|
|
@@ -506,24 +702,38 @@ SELECT ${selectCols}, false AS "${FIND_OR_CREATE_FLAG}" FROM ${tableSql} t
|
|
|
506
702
|
WHERE NOT EXISTS (SELECT 1 FROM ins)${fallbackClause}
|
|
507
703
|
LIMIT 1`;
|
|
508
704
|
}
|
|
509
|
-
export function buildInsertQuery(table, dataKeys) {
|
|
705
|
+
export function buildInsertQuery(table, dataKeys, manifestIndex, returning = "pk") {
|
|
510
706
|
if (dataKeys.length === 0) {
|
|
511
707
|
throw new Error("Cannot build INSERT query with no columns");
|
|
512
708
|
}
|
|
513
|
-
const
|
|
514
|
-
|
|
709
|
+
const orderedKeys = [...dataKeys].sort();
|
|
710
|
+
const cols = orderedKeys.map((k) => {
|
|
711
|
+
const col = colByTs(table, k, manifestIndex);
|
|
515
712
|
return quoteIdentifier(col?.sqlName ?? k);
|
|
516
713
|
});
|
|
517
|
-
const placeholders =
|
|
714
|
+
const placeholders = orderedKeys
|
|
518
715
|
.map((k, i) => {
|
|
519
|
-
const col = table
|
|
716
|
+
const col = colByTs(table, k, manifestIndex);
|
|
520
717
|
return buildValuePlaceholder(col, i + 1);
|
|
521
718
|
})
|
|
522
719
|
.join(", ");
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
720
|
+
let sql = `INSERT INTO ${tableRef(table)} (${cols.join(", ")}) VALUES (${placeholders})`;
|
|
721
|
+
if (returning === "none")
|
|
722
|
+
return sql;
|
|
723
|
+
const returningCols = returning === "full"
|
|
724
|
+
? buildSelectColumns(table, undefined, manifestIndex)
|
|
725
|
+
: buildReturningPkColumns(table, manifestIndex);
|
|
726
|
+
return `${sql} RETURNING ${returningCols}`;
|
|
727
|
+
}
|
|
728
|
+
export function getCachedInsertQuery(tableIndex, table, dataKeys, returning, manifestIndex) {
|
|
729
|
+
const orderedKeys = [...dataKeys].sort();
|
|
730
|
+
const cacheKey = `${sortedKeysCacheKey(orderedKeys)}:${returning}`;
|
|
731
|
+
if (!tableIndex) {
|
|
732
|
+
return buildInsertQuery(table, orderedKeys, manifestIndex, returning);
|
|
733
|
+
}
|
|
734
|
+
return getOrSetSqlCache(tableIndex.insertSqlByKeys, cacheKey, () => buildInsertQuery(table, orderedKeys, manifestIndex, returning));
|
|
735
|
+
}
|
|
736
|
+
export function buildInsertManyValueRows(table, dataKeys, rows, manifestIndex) {
|
|
527
737
|
if (dataKeys.length === 0) {
|
|
528
738
|
throw new Error("Cannot build INSERT many value rows with no columns");
|
|
529
739
|
}
|
|
@@ -537,7 +747,7 @@ export function buildInsertManyValueRows(table, dataKeys, rows) {
|
|
|
537
747
|
if (key === undefined) {
|
|
538
748
|
throw new Error("dataKeys index out of bounds");
|
|
539
749
|
}
|
|
540
|
-
const col = table
|
|
750
|
+
const col = colByTs(table, key, manifestIndex);
|
|
541
751
|
const val = row[i];
|
|
542
752
|
if (val === undefined) {
|
|
543
753
|
placeholders.push("DEFAULT");
|
|
@@ -552,37 +762,50 @@ export function buildInsertManyValueRows(table, dataKeys, rows) {
|
|
|
552
762
|
}
|
|
553
763
|
return { valueRows, values };
|
|
554
764
|
}
|
|
555
|
-
export function buildInsertManyQuery(table, dataKeys, valueRows) {
|
|
765
|
+
export function buildInsertManyQuery(table, dataKeys, valueRows, manifestIndex) {
|
|
556
766
|
if (dataKeys.length === 0) {
|
|
557
767
|
throw new Error("Cannot build INSERT many query with no columns");
|
|
558
768
|
}
|
|
559
769
|
const cols = dataKeys.map((k) => {
|
|
560
|
-
const col = table
|
|
770
|
+
const col = colByTs(table, k, manifestIndex);
|
|
561
771
|
return quoteIdentifier(col?.sqlName ?? k);
|
|
562
772
|
});
|
|
563
|
-
const selectCols = buildSelectColumns(table);
|
|
773
|
+
const selectCols = buildSelectColumns(table, undefined, manifestIndex);
|
|
564
774
|
return `INSERT INTO ${tableRef(table)} (${cols.join(", ")}) VALUES ${valueRows.join(", ")} RETURNING ${selectCols}`;
|
|
565
775
|
}
|
|
566
|
-
export function buildUpdateQuery(table, dataKeys, whereSql, exprSets = []) {
|
|
567
|
-
const
|
|
568
|
-
|
|
776
|
+
export function buildUpdateQuery(table, dataKeys, whereSql, exprSets = [], manifestIndex, returning = "full") {
|
|
777
|
+
const orderedKeys = [...dataKeys].sort();
|
|
778
|
+
const paramSets = orderedKeys.map((k, i) => {
|
|
779
|
+
const col = colByTs(table, k, manifestIndex);
|
|
569
780
|
return buildSetExpression(col, i + 1);
|
|
570
781
|
});
|
|
571
782
|
const sets = [...paramSets, ...exprSets];
|
|
572
|
-
const
|
|
573
|
-
const whereOffset = dataKeys.length;
|
|
783
|
+
const whereOffset = orderedKeys.length;
|
|
574
784
|
let sql = `UPDATE ${tableRef(table)} SET ${sets.join(", ")}`;
|
|
575
785
|
if (whereSql) {
|
|
576
|
-
const adjustedWhere = whereSql
|
|
577
|
-
return `$${Number(n) + whereOffset}`;
|
|
578
|
-
});
|
|
786
|
+
const adjustedWhere = rebaseParamRefs(whereSql, whereOffset);
|
|
579
787
|
sql += ` ${adjustedWhere}`;
|
|
580
788
|
}
|
|
581
|
-
|
|
582
|
-
|
|
789
|
+
if (returning === "none")
|
|
790
|
+
return sql;
|
|
791
|
+
const returningCols = returning === "full"
|
|
792
|
+
? buildSelectColumns(table, undefined, manifestIndex)
|
|
793
|
+
: buildReturningPkColumns(table, manifestIndex);
|
|
794
|
+
return `${sql} RETURNING ${returningCols}`;
|
|
795
|
+
}
|
|
796
|
+
export function buildReturningPkColumns(table, manifestIndex) {
|
|
797
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
798
|
+
return table.primaryKey
|
|
799
|
+
.map((sqlName) => {
|
|
800
|
+
const col = columnBySqlName(tableIndex, table, sqlName);
|
|
801
|
+
return quoteIdentifier(col?.sqlName ?? sqlName);
|
|
802
|
+
})
|
|
803
|
+
.join(", ");
|
|
583
804
|
}
|
|
584
|
-
export function buildDeleteQuery(table, whereSql) {
|
|
585
|
-
const selectCols =
|
|
805
|
+
export function buildDeleteQuery(table, whereSql, returning, manifestIndex) {
|
|
806
|
+
const selectCols = returning === "full"
|
|
807
|
+
? buildSelectColumns(table, undefined, manifestIndex)
|
|
808
|
+
: buildReturningPkColumns(table, manifestIndex);
|
|
586
809
|
let sql = `DELETE FROM ${tableRef(table)}`;
|
|
587
810
|
if (whereSql)
|
|
588
811
|
sql += ` ${whereSql}`;
|
|
@@ -595,27 +818,40 @@ export function buildDeleteManyQuery(table, whereSql) {
|
|
|
595
818
|
sql += ` ${whereSql}`;
|
|
596
819
|
return sql;
|
|
597
820
|
}
|
|
598
|
-
export function buildUpdateManyQuery(table, dataKeys, whereSql, exprSets = []) {
|
|
599
|
-
const
|
|
600
|
-
|
|
821
|
+
export function buildUpdateManyQuery(table, dataKeys, whereSql, exprSets = [], manifestIndex) {
|
|
822
|
+
const orderedKeys = [...dataKeys].sort();
|
|
823
|
+
const paramSets = orderedKeys.map((k, i) => {
|
|
824
|
+
const col = colByTs(table, k, manifestIndex);
|
|
601
825
|
return buildSetExpression(col, i + 1);
|
|
602
826
|
});
|
|
603
827
|
const sets = [...paramSets, ...exprSets];
|
|
604
|
-
const whereOffset =
|
|
828
|
+
const whereOffset = orderedKeys.length;
|
|
605
829
|
let sql = `UPDATE ${tableRef(table)} SET ${sets.join(", ")}`;
|
|
606
830
|
if (whereSql) {
|
|
607
|
-
const adjustedWhere = whereSql
|
|
608
|
-
return `$${Number(n) + whereOffset}`;
|
|
609
|
-
});
|
|
831
|
+
const adjustedWhere = rebaseParamRefs(whereSql, whereOffset);
|
|
610
832
|
sql += ` ${adjustedWhere}`;
|
|
611
833
|
}
|
|
612
834
|
return sql;
|
|
613
835
|
}
|
|
614
|
-
export function
|
|
836
|
+
export function getCachedUpdateManyQuery(tableIndex, table, dataKeys, whereSql, exprSets, manifestIndex) {
|
|
837
|
+
const orderedKeys = [...dataKeys].sort();
|
|
838
|
+
const cacheKey = `${sortedKeysCacheKey(orderedKeys)}|${exprSets.length}|${whereSql}`;
|
|
839
|
+
if (!tableIndex) {
|
|
840
|
+
return buildUpdateManyQuery(table, orderedKeys, whereSql, exprSets, manifestIndex);
|
|
841
|
+
}
|
|
842
|
+
return getOrSetSqlCache(tableIndex.updateManySqlByKeys, cacheKey, () => buildUpdateManyQuery(table, orderedKeys, whereSql, exprSets, manifestIndex));
|
|
843
|
+
}
|
|
844
|
+
export function getCachedFindManyQuery(tableIndex, signature, build) {
|
|
845
|
+
if (!tableIndex)
|
|
846
|
+
return build();
|
|
847
|
+
return getOrSetSqlCache(tableIndex.findManySqlBySignature, signature, build);
|
|
848
|
+
}
|
|
849
|
+
export function dataToSqlValues(table, data, options, manifestIndex, dialect = postgresDialect) {
|
|
850
|
+
const tableIndex = getTableIndex(manifestIndex, table.accessor);
|
|
615
851
|
const keys = [];
|
|
616
852
|
const values = [];
|
|
617
853
|
for (const [key, value] of Object.entries(data)) {
|
|
618
|
-
const col =
|
|
854
|
+
const col = columnByTsName(tableIndex, table, key);
|
|
619
855
|
if (!col)
|
|
620
856
|
continue;
|
|
621
857
|
if (options?.excludePrimary && col.primary)
|
|
@@ -623,9 +859,9 @@ export function dataToSqlValues(table, data, options) {
|
|
|
623
859
|
if (value === undefined)
|
|
624
860
|
continue;
|
|
625
861
|
keys.push(key);
|
|
626
|
-
values.push(serializeColumnValue(col, value));
|
|
862
|
+
values.push(serializeColumnValue(col, value, dialect));
|
|
627
863
|
}
|
|
628
|
-
return
|
|
864
|
+
return reorderKeyValues(keys, values);
|
|
629
865
|
}
|
|
630
866
|
export function rowToTs(table, row) {
|
|
631
867
|
const result = {};
|
|
@@ -644,7 +880,46 @@ export function rowToTs(table, row) {
|
|
|
644
880
|
}
|
|
645
881
|
return result;
|
|
646
882
|
}
|
|
883
|
+
function rowHasSqlNames(index, row) {
|
|
884
|
+
for (const col of index.renameColumns) {
|
|
885
|
+
if (col.sqlName !== col.tsName && col.sqlName in row) {
|
|
886
|
+
return true;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
return false;
|
|
890
|
+
}
|
|
647
891
|
export function rowToTsIndexed(index, table, row) {
|
|
892
|
+
if (index.selectUsesColumnAliases && !rowHasSqlNames(index, row)) {
|
|
893
|
+
if (index.deserializeColumns.length === 0) {
|
|
894
|
+
return row;
|
|
895
|
+
}
|
|
896
|
+
const result = { ...row };
|
|
897
|
+
for (const col of index.deserializeColumns) {
|
|
898
|
+
const key = col.tsName in row ? col.tsName : col.sqlName;
|
|
899
|
+
if (key in row) {
|
|
900
|
+
const plugin = getColumnType(col.kind);
|
|
901
|
+
if (plugin?.deserializeValue) {
|
|
902
|
+
result[col.tsName] = plugin.deserializeValue(col, row[key]);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return result;
|
|
907
|
+
}
|
|
908
|
+
if (!index.needsRowRename && index.deserializeColumns.length === 0) {
|
|
909
|
+
return row;
|
|
910
|
+
}
|
|
911
|
+
if (!index.needsRowRename) {
|
|
912
|
+
const result = { ...row };
|
|
913
|
+
for (const col of index.deserializeColumns) {
|
|
914
|
+
if (col.sqlName in row) {
|
|
915
|
+
const plugin = getColumnType(col.kind);
|
|
916
|
+
if (plugin?.deserializeValue) {
|
|
917
|
+
result[col.tsName] = plugin.deserializeValue(col, row[col.sqlName]);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return result;
|
|
922
|
+
}
|
|
648
923
|
const result = {};
|
|
649
924
|
for (const col of table.columns) {
|
|
650
925
|
if (col.sqlName in row) {
|
|
@@ -662,9 +937,27 @@ export function rowToTsIndexed(index, table, row) {
|
|
|
662
937
|
return result;
|
|
663
938
|
}
|
|
664
939
|
export function rowsToTsIndexed(index, table, rows) {
|
|
940
|
+
if (index.selectUsesColumnAliases &&
|
|
941
|
+
index.deserializeColumns.length === 0 &&
|
|
942
|
+
!index.needsRowRename) {
|
|
943
|
+
return rows;
|
|
944
|
+
}
|
|
945
|
+
if (!index.needsRowRename && index.deserializeColumns.length === 0) {
|
|
946
|
+
return rows;
|
|
947
|
+
}
|
|
665
948
|
return rows.map((row) => rowToTsIndexed(index, table, row));
|
|
666
949
|
}
|
|
667
950
|
export function rowsToTs(table, rows) {
|
|
668
951
|
return rows.map((row) => rowToTs(table, row));
|
|
669
952
|
}
|
|
953
|
+
export function mapRowToTs(tableIndex, table, row) {
|
|
954
|
+
return tableIndex
|
|
955
|
+
? rowToTsIndexed(tableIndex, table, row)
|
|
956
|
+
: rowToTs(table, row);
|
|
957
|
+
}
|
|
958
|
+
export function mapRowsToTs(tableIndex, table, rows) {
|
|
959
|
+
return tableIndex
|
|
960
|
+
? rowsToTsIndexed(tableIndex, table, rows)
|
|
961
|
+
: rowsToTs(table, rows);
|
|
962
|
+
}
|
|
670
963
|
//# sourceMappingURL=compile.js.map
|