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.
Files changed (179) hide show
  1. package/README.md +12 -6
  2. package/dist/bin/neoorm.js +45 -15
  3. package/dist/bin/neoorm.js.map +1 -1
  4. package/dist/codegen/diff-manifest.d.ts +7 -7
  5. package/dist/codegen/diff-manifest.d.ts.map +1 -1
  6. package/dist/codegen/diff-manifest.js +67 -54
  7. package/dist/codegen/diff-manifest.js.map +1 -1
  8. package/dist/codegen/generate-summary.js.map +1 -1
  9. package/dist/codegen/generate.d.ts.map +1 -1
  10. package/dist/codegen/generate.js +11 -1
  11. package/dist/codegen/generate.js.map +1 -1
  12. package/dist/codegen/manifest-relations.d.ts.map +1 -1
  13. package/dist/codegen/manifest-relations.js +21 -0
  14. package/dist/codegen/manifest-relations.js.map +1 -1
  15. package/dist/codegen/schema-to-manifest.js.map +1 -1
  16. package/dist/config.d.ts +1 -1
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +1 -1
  19. package/dist/config.js.map +1 -1
  20. package/dist/dialect/postgres.d.ts +3 -4
  21. package/dist/dialect/postgres.d.ts.map +1 -1
  22. package/dist/dialect/postgres.js +19 -11
  23. package/dist/dialect/postgres.js.map +1 -1
  24. package/dist/dialect/shared.d.ts +6 -0
  25. package/dist/dialect/shared.d.ts.map +1 -0
  26. package/dist/dialect/shared.js +16 -0
  27. package/dist/dialect/shared.js.map +1 -0
  28. package/dist/dialect/sqlite.d.ts +4 -0
  29. package/dist/dialect/sqlite.d.ts.map +1 -0
  30. package/dist/dialect/sqlite.js +276 -0
  31. package/dist/dialect/sqlite.js.map +1 -0
  32. package/dist/dialect/types.d.ts +7 -0
  33. package/dist/dialect/types.d.ts.map +1 -1
  34. package/dist/init/scaffold.js.map +1 -1
  35. package/dist/introspect/pull.d.ts +3 -2
  36. package/dist/introspect/pull.d.ts.map +1 -1
  37. package/dist/introspect/pull.js +124 -13
  38. package/dist/introspect/pull.js.map +1 -1
  39. package/dist/introspect/queries.d.ts +9 -9
  40. package/dist/introspect/queries.d.ts.map +1 -1
  41. package/dist/introspect/queries.js +16 -16
  42. package/dist/introspect/queries.js.map +1 -1
  43. package/dist/introspect/sqlite/to-manifest.d.ts +4 -0
  44. package/dist/introspect/sqlite/to-manifest.d.ts.map +1 -0
  45. package/dist/introspect/sqlite/to-manifest.js +166 -0
  46. package/dist/introspect/sqlite/to-manifest.js.map +1 -0
  47. package/dist/introspect/to-manifest.d.ts +2 -2
  48. package/dist/introspect/to-manifest.d.ts.map +1 -1
  49. package/dist/introspect/to-manifest.js +20 -12
  50. package/dist/introspect/to-manifest.js.map +1 -1
  51. package/dist/migrate/runner.d.ts +14 -14
  52. package/dist/migrate/runner.d.ts.map +1 -1
  53. package/dist/migrate/runner.js +83 -88
  54. package/dist/migrate/runner.js.map +1 -1
  55. package/dist/plugins/builtin.d.ts +1 -0
  56. package/dist/plugins/builtin.d.ts.map +1 -1
  57. package/dist/plugins/builtin.js +96 -6
  58. package/dist/plugins/builtin.js.map +1 -1
  59. package/dist/plugins/json/operators.d.ts.map +1 -1
  60. package/dist/plugins/json/operators.js +14 -5
  61. package/dist/plugins/json/operators.js.map +1 -1
  62. package/dist/plugins/types.d.ts +4 -4
  63. package/dist/plugins/types.d.ts.map +1 -1
  64. package/dist/runtime/client.d.ts +21 -4
  65. package/dist/runtime/client.d.ts.map +1 -1
  66. package/dist/runtime/client.js +61 -9
  67. package/dist/runtime/client.js.map +1 -1
  68. package/dist/runtime/driver.d.ts +28 -0
  69. package/dist/runtime/driver.d.ts.map +1 -0
  70. package/dist/runtime/driver.js +265 -0
  71. package/dist/runtime/driver.js.map +1 -0
  72. package/dist/runtime/errors.d.ts.map +1 -1
  73. package/dist/runtime/executor.d.ts +6 -3
  74. package/dist/runtime/executor.d.ts.map +1 -1
  75. package/dist/runtime/executor.js +60 -42
  76. package/dist/runtime/executor.js.map +1 -1
  77. package/dist/runtime/query/aggregate.d.ts.map +1 -1
  78. package/dist/runtime/query/aggregate.js +4 -3
  79. package/dist/runtime/query/aggregate.js.map +1 -1
  80. package/dist/runtime/query/compile.d.ts +37 -24
  81. package/dist/runtime/query/compile.d.ts.map +1 -1
  82. package/dist/runtime/query/compile.js +388 -95
  83. package/dist/runtime/query/compile.js.map +1 -1
  84. package/dist/runtime/query/count.d.ts.map +1 -1
  85. package/dist/runtime/query/count.js +7 -3
  86. package/dist/runtime/query/count.js.map +1 -1
  87. package/dist/runtime/query/create.d.ts +5 -0
  88. package/dist/runtime/query/create.d.ts.map +1 -1
  89. package/dist/runtime/query/create.js +63 -23
  90. package/dist/runtime/query/create.js.map +1 -1
  91. package/dist/runtime/query/cursor.d.ts +4 -3
  92. package/dist/runtime/query/cursor.d.ts.map +1 -1
  93. package/dist/runtime/query/cursor.js +10 -8
  94. package/dist/runtime/query/cursor.js.map +1 -1
  95. package/dist/runtime/query/delete.d.ts +1 -0
  96. package/dist/runtime/query/delete.d.ts.map +1 -1
  97. package/dist/runtime/query/delete.js +17 -6
  98. package/dist/runtime/query/delete.js.map +1 -1
  99. package/dist/runtime/query/execute.d.ts +4 -3
  100. package/dist/runtime/query/execute.d.ts.map +1 -1
  101. package/dist/runtime/query/execute.js +5 -4
  102. package/dist/runtime/query/execute.js.map +1 -1
  103. package/dist/runtime/query/find-or-create.d.ts.map +1 -1
  104. package/dist/runtime/query/find-or-create.js +57 -8
  105. package/dist/runtime/query/find-or-create.js.map +1 -1
  106. package/dist/runtime/query/find.d.ts +12 -3
  107. package/dist/runtime/query/find.d.ts.map +1 -1
  108. package/dist/runtime/query/find.js +159 -232
  109. package/dist/runtime/query/find.js.map +1 -1
  110. package/dist/runtime/query/manifest-lookup.d.ts +3 -2
  111. package/dist/runtime/query/manifest-lookup.d.ts.map +1 -1
  112. package/dist/runtime/query/manifest-lookup.js +5 -4
  113. package/dist/runtime/query/manifest-lookup.js.map +1 -1
  114. package/dist/runtime/query/paginate.d.ts.map +1 -1
  115. package/dist/runtime/query/paginate.js +16 -11
  116. package/dist/runtime/query/paginate.js.map +1 -1
  117. package/dist/runtime/query/primary-key.d.ts +8 -6
  118. package/dist/runtime/query/primary-key.d.ts.map +1 -1
  119. package/dist/runtime/query/primary-key.js +45 -17
  120. package/dist/runtime/query/primary-key.js.map +1 -1
  121. package/dist/runtime/query/relation-planner.d.ts +74 -0
  122. package/dist/runtime/query/relation-planner.d.ts.map +1 -0
  123. package/dist/runtime/query/relation-planner.js +648 -0
  124. package/dist/runtime/query/relation-planner.js.map +1 -0
  125. package/dist/runtime/query/relation-writes.d.ts +2 -1
  126. package/dist/runtime/query/relation-writes.d.ts.map +1 -1
  127. package/dist/runtime/query/relation-writes.js +33 -22
  128. package/dist/runtime/query/relation-writes.js.map +1 -1
  129. package/dist/runtime/query/table-index.d.ts +51 -3
  130. package/dist/runtime/query/table-index.d.ts.map +1 -1
  131. package/dist/runtime/query/table-index.js +119 -4
  132. package/dist/runtime/query/table-index.js.map +1 -1
  133. package/dist/runtime/query/unique.d.ts +3 -2
  134. package/dist/runtime/query/unique.d.ts.map +1 -1
  135. package/dist/runtime/query/unique.js +7 -6
  136. package/dist/runtime/query/unique.js.map +1 -1
  137. package/dist/runtime/query/update.d.ts +2 -0
  138. package/dist/runtime/query/update.d.ts.map +1 -1
  139. package/dist/runtime/query/update.js +98 -30
  140. package/dist/runtime/query/update.js.map +1 -1
  141. package/dist/runtime/query/updated-at.d.ts +6 -4
  142. package/dist/runtime/query/updated-at.d.ts.map +1 -1
  143. package/dist/runtime/query/updated-at.js +23 -9
  144. package/dist/runtime/query/updated-at.js.map +1 -1
  145. package/dist/runtime/query/upsert.d.ts.map +1 -1
  146. package/dist/runtime/query/upsert.js +11 -9
  147. package/dist/runtime/query/upsert.js.map +1 -1
  148. package/dist/runtime/sqlite-open.d.ts +3 -0
  149. package/dist/runtime/sqlite-open.d.ts.map +1 -0
  150. package/dist/runtime/sqlite-open.js +22 -0
  151. package/dist/runtime/sqlite-open.js.map +1 -0
  152. package/dist/runtime/transaction.d.ts +5 -0
  153. package/dist/runtime/transaction.d.ts.map +1 -0
  154. package/dist/runtime/transaction.js +26 -0
  155. package/dist/runtime/transaction.js.map +1 -0
  156. package/dist/runtime/types.d.ts +1 -0
  157. package/dist/runtime/types.d.ts.map +1 -1
  158. package/dist/schema/column.d.ts +1 -1
  159. package/dist/schema/column.d.ts.map +1 -1
  160. package/dist/schema/column.js +1 -1
  161. package/dist/schema/column.js.map +1 -1
  162. package/dist/schema/define-schema.js.map +1 -1
  163. package/dist/schema/index.d.ts +1 -1
  164. package/dist/schema/index.d.ts.map +1 -1
  165. package/dist/schema/index.js +1 -1
  166. package/dist/schema/index.js.map +1 -1
  167. package/dist/schema/types.d.ts +3 -0
  168. package/dist/schema/types.d.ts.map +1 -1
  169. package/dist/sql/builder.d.ts.map +1 -1
  170. package/dist/sql/template.d.ts +7 -0
  171. package/dist/sql/template.d.ts.map +1 -1
  172. package/dist/sql/template.js +89 -3
  173. package/dist/sql/template.js.map +1 -1
  174. package/dist/utils/case.d.ts +4 -0
  175. package/dist/utils/case.d.ts.map +1 -1
  176. package/dist/utils/case.js +11 -0
  177. package/dist/utils/case.js.map +1 -1
  178. package/dist/utils/uuid.js.map +1 -1
  179. 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 = parentTable.columns.find((c) => c.tsName === relation.fkColumn);
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 relations = new Map(effectiveRelations(manifest, table).map((rel) => [rel.name, rel]));
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 = table.columns.find((c) => c.tsName === key);
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 result = compileWhereNode(manifest, table, where, dialect, startParamIndex);
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
- const col = table.columns.find((c) => c.tsName === tsKey);
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
- ? table.columns.filter((c) => select.includes(c.tsName))
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
- ? table.columns.filter((c) => select.includes(c.tsName))
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 buildFindManyQuery(table, whereSql, orderSql, limit, offset, distinctOn, extraSelectCols, joinClauses) {
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
- if (offset !== undefined)
394
- sql += ` OFFSET ${offset}`;
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(*)::int AS count FROM ${tableRef(table)}`;
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 col = table.columns.find((c) => c.tsName === tsName);
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 `${sqlCol}::numeric`;
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('COUNT(*)::int AS "__count"');
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 buildUpsertQuery(table, insertKeys, updateKeys, conflictSqlColumns, exprSets = []) {
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.columns.find((c) => c.tsName === k);
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.columns.find((c) => c.tsName === k);
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.columns.find((c) => c.tsName === k);
661
+ const col = colByTs(table, k, manifestIndex);
466
662
  const sqlCol = quoteIdentifier(col?.sqlName ?? k);
467
- return `${sqlCol} = EXCLUDED.${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} = EXCLUDED.${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.columns.find((c) => c.tsName === k);
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.columns.find((c) => c.tsName === k);
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 cols = dataKeys.map((k) => {
514
- const col = table.columns.find((c) => c.tsName === k);
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 = dataKeys
714
+ const placeholders = orderedKeys
518
715
  .map((k, i) => {
519
- const col = table.columns.find((c) => c.tsName === k);
716
+ const col = colByTs(table, k, manifestIndex);
520
717
  return buildValuePlaceholder(col, i + 1);
521
718
  })
522
719
  .join(", ");
523
- const selectCols = buildSelectColumns(table);
524
- return `INSERT INTO ${tableRef(table)} (${cols.join(", ")}) VALUES (${placeholders}) RETURNING ${selectCols}`;
525
- }
526
- export function buildInsertManyValueRows(table, dataKeys, rows) {
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.columns.find((c) => c.tsName === key);
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.columns.find((c) => c.tsName === k);
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 paramSets = dataKeys.map((k, i) => {
568
- const col = table.columns.find((c) => c.tsName === k);
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 selectCols = buildSelectColumns(table);
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.replace(/\$(\d+)/g, (_, n) => {
577
- return `$${Number(n) + whereOffset}`;
578
- });
786
+ const adjustedWhere = rebaseParamRefs(whereSql, whereOffset);
579
787
  sql += ` ${adjustedWhere}`;
580
788
  }
581
- sql += ` RETURNING ${selectCols}`;
582
- return sql;
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 = buildSelectColumns(table);
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 paramSets = dataKeys.map((k, i) => {
600
- const col = table.columns.find((c) => c.tsName === k);
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 = dataKeys.length;
828
+ const whereOffset = orderedKeys.length;
605
829
  let sql = `UPDATE ${tableRef(table)} SET ${sets.join(", ")}`;
606
830
  if (whereSql) {
607
- const adjustedWhere = whereSql.replace(/\$(\d+)/g, (_, n) => {
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 dataToSqlValues(table, data, options) {
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 = table.columns.find((c) => c.tsName === key);
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 { keys, values };
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