neoorm 0.3.0 → 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 (189) 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 +32 -7
  65. package/dist/runtime/client.d.ts.map +1 -1
  66. package/dist/runtime/client.js +68 -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 +1 -1
  73. package/dist/runtime/errors.d.ts.map +1 -1
  74. package/dist/runtime/errors.js +1 -0
  75. package/dist/runtime/errors.js.map +1 -1
  76. package/dist/runtime/executor.d.ts +11 -3
  77. package/dist/runtime/executor.d.ts.map +1 -1
  78. package/dist/runtime/executor.js +69 -37
  79. package/dist/runtime/executor.js.map +1 -1
  80. package/dist/runtime/pg-error.d.ts +1 -1
  81. package/dist/runtime/pg-error.d.ts.map +1 -1
  82. package/dist/runtime/pg-error.js +6 -1
  83. package/dist/runtime/pg-error.js.map +1 -1
  84. package/dist/runtime/query/aggregate.d.ts.map +1 -1
  85. package/dist/runtime/query/aggregate.js +5 -4
  86. package/dist/runtime/query/aggregate.js.map +1 -1
  87. package/dist/runtime/query/compile.d.ts +42 -16
  88. package/dist/runtime/query/compile.d.ts.map +1 -1
  89. package/dist/runtime/query/compile.js +479 -91
  90. package/dist/runtime/query/compile.js.map +1 -1
  91. package/dist/runtime/query/count.d.ts.map +1 -1
  92. package/dist/runtime/query/count.js +7 -3
  93. package/dist/runtime/query/count.js.map +1 -1
  94. package/dist/runtime/query/create.d.ts +5 -0
  95. package/dist/runtime/query/create.d.ts.map +1 -1
  96. package/dist/runtime/query/create.js +89 -23
  97. package/dist/runtime/query/create.js.map +1 -1
  98. package/dist/runtime/query/cursor.d.ts +4 -3
  99. package/dist/runtime/query/cursor.d.ts.map +1 -1
  100. package/dist/runtime/query/cursor.js +13 -9
  101. package/dist/runtime/query/cursor.js.map +1 -1
  102. package/dist/runtime/query/delete.d.ts +2 -1
  103. package/dist/runtime/query/delete.d.ts.map +1 -1
  104. package/dist/runtime/query/delete.js +27 -14
  105. package/dist/runtime/query/delete.js.map +1 -1
  106. package/dist/runtime/query/execute.d.ts +11 -4
  107. package/dist/runtime/query/execute.d.ts.map +1 -1
  108. package/dist/runtime/query/execute.js +20 -5
  109. package/dist/runtime/query/execute.js.map +1 -1
  110. package/dist/runtime/query/find-or-create.d.ts +17 -0
  111. package/dist/runtime/query/find-or-create.d.ts.map +1 -0
  112. package/dist/runtime/query/find-or-create.js +90 -0
  113. package/dist/runtime/query/find-or-create.js.map +1 -0
  114. package/dist/runtime/query/find.d.ts +13 -4
  115. package/dist/runtime/query/find.d.ts.map +1 -1
  116. package/dist/runtime/query/find.js +201 -47
  117. package/dist/runtime/query/find.js.map +1 -1
  118. package/dist/runtime/query/manifest-lookup.d.ts +3 -2
  119. package/dist/runtime/query/manifest-lookup.d.ts.map +1 -1
  120. package/dist/runtime/query/manifest-lookup.js +5 -4
  121. package/dist/runtime/query/manifest-lookup.js.map +1 -1
  122. package/dist/runtime/query/paginate.d.ts.map +1 -1
  123. package/dist/runtime/query/paginate.js +16 -11
  124. package/dist/runtime/query/paginate.js.map +1 -1
  125. package/dist/runtime/query/primary-key.d.ts +9 -6
  126. package/dist/runtime/query/primary-key.d.ts.map +1 -1
  127. package/dist/runtime/query/primary-key.js +65 -35
  128. package/dist/runtime/query/primary-key.js.map +1 -1
  129. package/dist/runtime/query/relation-planner.d.ts +74 -0
  130. package/dist/runtime/query/relation-planner.d.ts.map +1 -0
  131. package/dist/runtime/query/relation-planner.js +648 -0
  132. package/dist/runtime/query/relation-planner.js.map +1 -0
  133. package/dist/runtime/query/relation-writes.d.ts +2 -1
  134. package/dist/runtime/query/relation-writes.d.ts.map +1 -1
  135. package/dist/runtime/query/relation-writes.js +46 -53
  136. package/dist/runtime/query/relation-writes.js.map +1 -1
  137. package/dist/runtime/query/table-index.d.ts +61 -0
  138. package/dist/runtime/query/table-index.d.ts.map +1 -0
  139. package/dist/runtime/query/table-index.js +152 -0
  140. package/dist/runtime/query/table-index.js.map +1 -0
  141. package/dist/runtime/query/unique.d.ts +3 -2
  142. package/dist/runtime/query/unique.d.ts.map +1 -1
  143. package/dist/runtime/query/unique.js +7 -6
  144. package/dist/runtime/query/unique.js.map +1 -1
  145. package/dist/runtime/query/update.d.ts +3 -1
  146. package/dist/runtime/query/update.d.ts.map +1 -1
  147. package/dist/runtime/query/update.js +117 -36
  148. package/dist/runtime/query/update.js.map +1 -1
  149. package/dist/runtime/query/updated-at.d.ts +6 -4
  150. package/dist/runtime/query/updated-at.d.ts.map +1 -1
  151. package/dist/runtime/query/updated-at.js +23 -9
  152. package/dist/runtime/query/updated-at.js.map +1 -1
  153. package/dist/runtime/query/upsert.d.ts.map +1 -1
  154. package/dist/runtime/query/upsert.js +11 -9
  155. package/dist/runtime/query/upsert.js.map +1 -1
  156. package/dist/runtime/sqlite-open.d.ts +3 -0
  157. package/dist/runtime/sqlite-open.d.ts.map +1 -0
  158. package/dist/runtime/sqlite-open.js +22 -0
  159. package/dist/runtime/sqlite-open.js.map +1 -0
  160. package/dist/runtime/transaction.d.ts +5 -0
  161. package/dist/runtime/transaction.d.ts.map +1 -0
  162. package/dist/runtime/transaction.js +26 -0
  163. package/dist/runtime/transaction.js.map +1 -0
  164. package/dist/runtime/types.d.ts +9 -4
  165. package/dist/runtime/types.d.ts.map +1 -1
  166. package/dist/schema/column.d.ts +1 -1
  167. package/dist/schema/column.d.ts.map +1 -1
  168. package/dist/schema/column.js +1 -1
  169. package/dist/schema/column.js.map +1 -1
  170. package/dist/schema/define-schema.js.map +1 -1
  171. package/dist/schema/index.d.ts +2 -2
  172. package/dist/schema/index.d.ts.map +1 -1
  173. package/dist/schema/index.js +1 -1
  174. package/dist/schema/index.js.map +1 -1
  175. package/dist/schema/relation-types.d.ts +1 -0
  176. package/dist/schema/relation-types.d.ts.map +1 -1
  177. package/dist/schema/types.d.ts +12 -0
  178. package/dist/schema/types.d.ts.map +1 -1
  179. package/dist/sql/builder.d.ts.map +1 -1
  180. package/dist/sql/template.d.ts +7 -0
  181. package/dist/sql/template.d.ts.map +1 -1
  182. package/dist/sql/template.js +89 -3
  183. package/dist/sql/template.js.map +1 -1
  184. package/dist/utils/case.d.ts +4 -0
  185. package/dist/utils/case.d.ts.map +1 -1
  186. package/dist/utils/case.js +11 -0
  187. package/dist/utils/case.js.map +1 -1
  188. package/dist/utils/uuid.js.map +1 -1
  189. 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)}`;
@@ -77,6 +85,15 @@ function compileColumnCondition(col, rawValue, dialect, paramIndex, columnRef) {
77
85
  conditions.push(dialect.whereOperators[operator](sqlCol, nextParamIndex));
78
86
  continue;
79
87
  }
88
+ if (Array.isArray(value) && value.length === 0) {
89
+ if (operator === "in") {
90
+ conditions.push("1=0");
91
+ }
92
+ else if (operator === "notIn") {
93
+ conditions.push("1=1");
94
+ }
95
+ continue;
96
+ }
80
97
  const transform = operatorParamTransform[operator];
81
98
  const paramValue = operator === "in" || operator === "notIn"
82
99
  ? Array.isArray(value)
@@ -94,20 +111,22 @@ function compileColumnCondition(col, rawValue, dialect, paramIndex, columnRef) {
94
111
  function compileExistsSubquery(existsSql, negate) {
95
112
  return negate ? `NOT EXISTS (${existsSql})` : `EXISTS (${existsSql})`;
96
113
  }
97
- function compileRelationCondition(manifest, parentTable, relation, rawValue, dialect, paramIndex) {
114
+ function compileRelationCondition(manifest, parentTable, relation, rawValue, dialect, paramIndex, manifestIndex) {
98
115
  const m2m = findM2M(manifest, parentTable.accessor, relation.name);
99
116
  const targetTable = manifest.tables[relation.targetAccessor];
100
117
  if (!targetTable) {
101
118
  return { sql: "", params: [], nextParamIndex: paramIndex };
102
119
  }
120
+ const parentTableIndex = getTableIndex(manifestIndex, parentTable.accessor);
121
+ const targetTableIndex = getTableIndex(manifestIndex, targetTable.accessor);
103
122
  if (relation.cardinality === "one") {
104
123
  if (!isOperatorObject(rawValue) || Array.isArray(rawValue)) {
105
124
  return { sql: "", params: [], nextParamIndex: paramIndex };
106
125
  }
107
126
  const relAlias = "_rel";
108
127
  const columnRef = (col) => `${quoteIdentifier(relAlias)}.${quoteIdentifier(col.sqlName)}`;
109
- const nested = compileWhereNode(manifest, targetTable, rawValue, dialect, paramIndex, columnRef);
110
- 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);
111
130
  const parentFkRef = parentFkCol
112
131
  ? `${tableRef(parentTable)}.${quoteIdentifier(parentFkCol.sqlName)}`
113
132
  : `${tableRef(parentTable)}.${quoteIdentifier(relation.fkSqlColumn)}`;
@@ -136,7 +155,7 @@ function compileRelationCondition(manifest, parentTable, relation, rawValue, dia
136
155
  }
137
156
  const relAlias = "_rel";
138
157
  const columnRef = (col) => `${quoteIdentifier(relAlias)}.${quoteIdentifier(col.sqlName)}`;
139
- const nested = compileWhereNode(manifest, targetTable, (nestedWhere ?? {}), dialect, paramIndex, columnRef);
158
+ const nested = compileWhereNode(manifest, targetTable, (nestedWhere ?? {}), dialect, paramIndex, columnRef, manifestIndex);
140
159
  let fromClause;
141
160
  let whereParts;
142
161
  if (m2m) {
@@ -193,18 +212,20 @@ function compileRelationCondition(manifest, parentTable, relation, rawValue, dia
193
212
  nextParamIndex: nested.nextParamIndex,
194
213
  };
195
214
  }
196
- function compileWhereNode(manifest, table, where, dialect, startParamIndex, columnRef = defaultColumnRef) {
215
+ function compileWhereNode(manifest, table, where, dialect, startParamIndex, columnRef = defaultColumnRef, manifestIndex) {
197
216
  const conditions = [];
198
217
  const params = [];
199
218
  let paramIndex = startParamIndex;
200
- 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]));
201
222
  for (const [key, value] of Object.entries(where)) {
202
223
  if (key === "AND" && Array.isArray(value)) {
203
224
  const parts = [];
204
225
  for (const item of value) {
205
226
  if (!item || typeof item !== "object" || Array.isArray(item))
206
227
  continue;
207
- const compiled = compileWhereNode(manifest, table, item, dialect, paramIndex, columnRef);
228
+ const compiled = compileWhereNode(manifest, table, item, dialect, paramIndex, columnRef, manifestIndex);
208
229
  if (compiled.sql)
209
230
  parts.push(`(${compiled.sql})`);
210
231
  params.push(...compiled.params);
@@ -219,7 +240,7 @@ function compileWhereNode(manifest, table, where, dialect, startParamIndex, colu
219
240
  for (const item of value) {
220
241
  if (!item || typeof item !== "object" || Array.isArray(item))
221
242
  continue;
222
- const compiled = compileWhereNode(manifest, table, item, dialect, paramIndex, columnRef);
243
+ const compiled = compileWhereNode(manifest, table, item, dialect, paramIndex, columnRef, manifestIndex);
223
244
  if (compiled.sql)
224
245
  parts.push(`(${compiled.sql})`);
225
246
  params.push(...compiled.params);
@@ -230,7 +251,7 @@ function compileWhereNode(manifest, table, where, dialect, startParamIndex, colu
230
251
  continue;
231
252
  }
232
253
  if (key === "NOT" && isOperatorObject(value)) {
233
- const compiled = compileWhereNode(manifest, table, value, dialect, paramIndex, columnRef);
254
+ const compiled = compileWhereNode(manifest, table, value, dialect, paramIndex, columnRef, manifestIndex);
234
255
  if (compiled.sql)
235
256
  conditions.push(`NOT (${compiled.sql})`);
236
257
  params.push(...compiled.params);
@@ -239,14 +260,14 @@ function compileWhereNode(manifest, table, where, dialect, startParamIndex, colu
239
260
  }
240
261
  const relation = relations.get(key);
241
262
  if (relation) {
242
- const compiled = compileRelationCondition(manifest, table, relation, value, dialect, paramIndex);
263
+ const compiled = compileRelationCondition(manifest, table, relation, value, dialect, paramIndex, manifestIndex);
243
264
  if (compiled.sql)
244
265
  conditions.push(compiled.sql);
245
266
  params.push(...compiled.params);
246
267
  paramIndex = compiled.nextParamIndex;
247
268
  continue;
248
269
  }
249
- const col = table.columns.find((c) => c.tsName === key);
270
+ const col = columnByTsName(tableIndex, table, key);
250
271
  if (!col)
251
272
  continue;
252
273
  const compiled = compileColumnCondition(col, value, dialect, paramIndex, columnRef);
@@ -261,16 +282,173 @@ function compileWhereNode(manifest, table, where, dialect, startParamIndex, colu
261
282
  nextParamIndex: paramIndex,
262
283
  };
263
284
  }
264
- export function compileWhere(manifest, table, where, dialect, startParamIndex = 1) {
285
+ export function compileWhere(manifest, table, where, dialect, startParamIndex = 1, manifestIndex, qualifyColumns = false) {
265
286
  if (!where || Object.keys(where).length === 0) {
266
287
  return { sql: "", params: [] };
267
288
  }
268
- 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);
293
+ const impossible = isImpossibleWhereSql(result.sql);
269
294
  return {
270
295
  sql: result.sql ? `WHERE ${result.sql}` : "",
271
296
  params: result.params,
297
+ ...(impossible ? { impossible: true } : {}),
272
298
  };
273
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
+ }
442
+ export function isImpossibleWhereSql(sql) {
443
+ if (!sql)
444
+ return false;
445
+ return /\b1\s*=\s*0\b/.test(sql);
446
+ }
447
+ export function isImpossibleWhere(whereSql) {
448
+ if (!whereSql)
449
+ return false;
450
+ return isImpossibleWhereSql(whereSql.replace(/^WHERE\s+/i, ""));
451
+ }
274
452
  function buildValuePlaceholder(col, paramIndex) {
275
453
  if (!col || col.kind === "fk")
276
454
  return `$${paramIndex}`;
@@ -284,16 +462,20 @@ function buildSetExpression(col, paramIndex) {
284
462
  const sqlCol = quoteIdentifier(col?.sqlName ?? "");
285
463
  return `${sqlCol} = ${buildValuePlaceholder(col, paramIndex)}`;
286
464
  }
287
- export function compileOrderBy(table, orderBy) {
465
+ export function compileOrderBy(table, orderBy, tableAlias, manifestIndex) {
288
466
  if (!orderBy || Object.keys(orderBy).length === 0)
289
467
  return "";
468
+ const tableIndex = getTableIndex(manifestIndex, table.accessor);
469
+ const prefix = tableAlias ? `${quoteIdentifier(tableAlias)}.` : "";
290
470
  const parts = [];
291
471
  for (const [tsKey, direction] of Object.entries(orderBy)) {
292
- 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);
293
475
  if (!col)
294
476
  continue;
295
477
  const dir = direction.toUpperCase() === "DESC" ? "DESC" : "ASC";
296
- parts.push(`${quoteIdentifier(col.sqlName)} ${dir}`);
478
+ parts.push(`${prefix}${quoteIdentifier(col.sqlName)} ${dir}`);
297
479
  }
298
480
  return parts.length > 0 ? `ORDER BY ${parts.join(", ")}` : "";
299
481
  }
@@ -306,90 +488,129 @@ export function normalizeSelectColumns(select) {
306
488
  .filter(([, enabled]) => enabled === true)
307
489
  .map(([key]) => key);
308
490
  }
491
+ function aliasToTsName(expression, col) {
492
+ if (col.sqlName === col.tsName)
493
+ return expression;
494
+ return `${expression} AS ${quoteIdentifier(col.tsName)}`;
495
+ }
309
496
  function selectExpression(col) {
310
497
  if (col.kind === "fk") {
311
- return quoteIdentifier(col.sqlName);
498
+ return aliasToTsName(quoteIdentifier(col.sqlName), col);
312
499
  }
313
500
  const plugin = getColumnType(col.kind);
314
501
  if (plugin?.selectExpression) {
315
- return plugin.selectExpression(col);
502
+ return aliasToTsName(plugin.selectExpression(col), col);
316
503
  }
317
- return quoteIdentifier(col.sqlName);
504
+ return aliasToTsName(quoteIdentifier(col.sqlName), col);
318
505
  }
319
- export function buildSelectColumns(table, select) {
506
+ export function buildSelectColumns(table, select, manifestIndex) {
507
+ const tableIndex = getTableIndex(manifestIndex, table.accessor);
320
508
  const cols = select && select.length > 0
321
- ? table.columns.filter((c) => select.includes(c.tsName))
509
+ ? columnsByTsNames(tableIndex, table, select)
322
510
  : table.columns;
323
511
  return cols.map((c) => selectExpression(c)).join(", ");
324
512
  }
513
+ export function buildQualifiedSelectColumns(table, select, manifestIndex) {
514
+ const ref = tableRef(table);
515
+ const tableIndex = getTableIndex(manifestIndex, table.accessor);
516
+ const cols = select && select.length > 0
517
+ ? columnsByTsNames(tableIndex, table, select)
518
+ : table.columns;
519
+ return cols.map((c) => `${ref}.${selectExpression(c)}`).join(", ");
520
+ }
325
521
  export function buildFindByIdQuery(table) {
326
522
  const { sqlName } = requireScalarPrimaryKey(table);
327
523
  const sqlCol = quoteIdentifier(sqlName);
328
524
  const selectCols = buildSelectColumns(table);
329
525
  return `SELECT ${selectCols} FROM ${tableRef(table)} WHERE ${sqlCol} = $1`;
330
526
  }
331
- export function buildFindManyQuery(table, whereSql, orderSql, limit, offset, distinctOn) {
332
- const selectCols = buildSelectColumns(table);
527
+ export function buildFindAllQuery(table) {
528
+ return `SELECT ${buildSelectColumns(table)} FROM ${tableRef(table)}`;
529
+ }
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) {
537
+ const hasJoins = Boolean(joinClauses && joinClauses.length > 0);
538
+ const tableIndex = getTableIndex(manifestIndex, table.accessor);
539
+ const selectCols = hasJoins
540
+ ? buildQualifiedSelectColumns(table, undefined, manifestIndex)
541
+ : buildSelectColumns(table, undefined, manifestIndex);
333
542
  let sql = "SELECT ";
334
543
  if (distinctOn && distinctOn.length > 0) {
335
- const distinctCols = distinctOn
336
- .map((tsName) => table.columns.find((c) => c.tsName === tsName))
337
- .filter((col) => col !== undefined)
338
- .map((col) => quoteIdentifier(col.sqlName))
544
+ const distinctCols = columnsByTsNames(tableIndex, table, distinctOn)
545
+ .map((col) => hasJoins
546
+ ? `${tableRef(table)}.${quoteIdentifier(col.sqlName)}`
547
+ : quoteIdentifier(col.sqlName))
339
548
  .join(", ");
340
549
  sql += `DISTINCT ON (${distinctCols}) `;
341
550
  }
342
- sql += `${selectCols} FROM ${tableRef(table)}`;
551
+ sql += selectCols;
552
+ if (extraSelectCols && extraSelectCols.length > 0) {
553
+ sql += `, ${extraSelectCols.join(", ")}`;
554
+ }
555
+ sql += ` FROM ${tableRef(table)}`;
556
+ if (joinClauses && joinClauses.length > 0) {
557
+ sql += ` ${joinClauses.join(" ")}`;
558
+ }
343
559
  if (whereSql)
344
560
  sql += ` ${whereSql}`;
561
+ if (groupBySql)
562
+ sql += ` ${groupBySql}`;
345
563
  if (orderSql)
346
564
  sql += ` ${orderSql}`;
347
- if (limit !== undefined)
348
- sql += ` LIMIT ${limit}`;
349
- if (offset !== undefined)
350
- 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
+ }
351
571
  return sql;
352
572
  }
353
- export function buildPaginateQuery(table, whereSql, orderSql, take) {
354
- 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);
355
575
  }
356
- export function buildCountQuery(table, whereSql) {
357
- 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)}`;
358
578
  if (whereSql)
359
579
  sql += ` ${whereSql}`;
360
580
  return sql;
361
581
  }
362
- function aggregateSqlCol(table, tsName) {
363
- 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);
364
585
  if (!col)
365
586
  return undefined;
366
587
  const sqlCol = quoteIdentifier(col.sqlName);
367
588
  if (col.kind === "decimal")
368
- return `${sqlCol}::numeric`;
589
+ return dialect.castToNumeric(sqlCol);
369
590
  return sqlCol;
370
591
  }
371
- export function buildAggregateQuery(table, selectors, whereSql) {
592
+ export function buildAggregateQuery(table, selectors, whereSql, manifestIndex, dialect = postgresDialect) {
372
593
  const parts = [];
373
594
  if (selectors._count) {
374
- parts.push('COUNT(*)::int AS "_count"');
595
+ parts.push(`${dialect.castToInt("COUNT(*)")} AS "__count"`);
375
596
  }
376
597
  for (const colName of Object.keys(selectors._avg ?? {})) {
377
- const sqlCol = aggregateSqlCol(table, colName);
598
+ const sqlCol = aggregateSqlCol(table, colName, dialect, manifestIndex);
378
599
  if (sqlCol)
379
600
  parts.push(`AVG(${sqlCol}) AS "_avg_${colName}"`);
380
601
  }
381
602
  for (const colName of Object.keys(selectors._sum ?? {})) {
382
- const sqlCol = aggregateSqlCol(table, colName);
603
+ const sqlCol = aggregateSqlCol(table, colName, dialect, manifestIndex);
383
604
  if (sqlCol)
384
605
  parts.push(`SUM(${sqlCol}) AS "_sum_${colName}"`);
385
606
  }
386
607
  for (const colName of Object.keys(selectors._min ?? {})) {
387
- const sqlCol = aggregateSqlCol(table, colName);
608
+ const sqlCol = aggregateSqlCol(table, colName, dialect, manifestIndex);
388
609
  if (sqlCol)
389
610
  parts.push(`MIN(${sqlCol}) AS "_min_${colName}"`);
390
611
  }
391
612
  for (const colName of Object.keys(selectors._max ?? {})) {
392
- const sqlCol = aggregateSqlCol(table, colName);
613
+ const sqlCol = aggregateSqlCol(table, colName, dialect, manifestIndex);
393
614
  if (sqlCol)
394
615
  parts.push(`MAX(${sqlCol}) AS "_max_${colName}"`);
395
616
  }
@@ -401,54 +622,118 @@ export function buildAggregateQuery(table, selectors, whereSql) {
401
622
  sql += ` ${whereSql}`;
402
623
  return sql;
403
624
  }
404
- 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) {
405
645
  const insertCols = insertKeys.map((k) => {
406
- const col = table.columns.find((c) => c.tsName === k);
646
+ const col = colByTs(table, k, manifestIndex);
407
647
  return quoteIdentifier(col?.sqlName ?? k);
408
648
  });
409
649
  const insertPlaceholders = insertKeys
410
650
  .map((k, i) => {
411
- const col = table.columns.find((c) => c.tsName === k);
651
+ const col = colByTs(table, k, manifestIndex);
412
652
  return buildValuePlaceholder(col, i + 1);
413
653
  })
414
654
  .join(", ");
415
- const selectCols = buildSelectColumns(table);
655
+ const selectCols = buildSelectColumns(table, undefined, manifestIndex);
416
656
  const conflictCols = conflictSqlColumns
417
657
  .map((c) => quoteIdentifier(c))
418
658
  .join(", ");
419
659
  const updateSets = updateKeys.length > 0
420
660
  ? updateKeys.map((k) => {
421
- const col = table.columns.find((c) => c.tsName === k);
661
+ const col = colByTs(table, k, manifestIndex);
422
662
  const sqlCol = quoteIdentifier(col?.sqlName ?? k);
423
- return `${sqlCol} = EXCLUDED.${sqlCol}`;
663
+ return `${sqlCol} = excluded.${sqlCol}`;
424
664
  })
425
665
  : exprSets.length === 0
426
666
  ? conflictSqlColumns.map((c) => {
427
667
  const sqlCol = quoteIdentifier(c);
428
- return `${sqlCol} = EXCLUDED.${sqlCol}`;
668
+ return `${sqlCol} = excluded.${sqlCol}`;
429
669
  })
430
670
  : [];
431
671
  const allUpdateSets = [...updateSets, ...exprSets];
432
672
  return `INSERT INTO ${tableRef(table)} (${insertCols.join(", ")}) VALUES (${insertPlaceholders}) ON CONFLICT (${conflictCols}) DO UPDATE SET ${allUpdateSets.join(", ")} RETURNING ${selectCols}`;
433
673
  }
434
- export function buildInsertQuery(table, dataKeys) {
674
+ export const FIND_OR_CREATE_FLAG = "__neoorm_created";
675
+ export function buildFindOrCreateQuery(table, insertKeys, conflictSqlColumns, fallbackWhereBody, manifestIndex) {
676
+ const insertCols = insertKeys.map((k) => {
677
+ const col = colByTs(table, k, manifestIndex);
678
+ return quoteIdentifier(col?.sqlName ?? k);
679
+ });
680
+ const insertPlaceholders = insertKeys
681
+ .map((k, i) => {
682
+ const col = colByTs(table, k, manifestIndex);
683
+ return buildValuePlaceholder(col, i + 1);
684
+ })
685
+ .join(", ");
686
+ const selectCols = buildSelectColumns(table, undefined, manifestIndex);
687
+ const conflictCols = conflictSqlColumns
688
+ .map((c) => quoteIdentifier(c))
689
+ .join(", ");
690
+ const tableSql = tableRef(table);
691
+ const fallbackClause = fallbackWhereBody
692
+ ? ` AND (${fallbackWhereBody})`
693
+ : "";
694
+ return `WITH ins AS (
695
+ INSERT INTO ${tableSql} (${insertCols.join(", ")}) VALUES (${insertPlaceholders})
696
+ ON CONFLICT (${conflictCols}) DO NOTHING
697
+ RETURNING ${selectCols}
698
+ )
699
+ SELECT ${selectCols}, true AS "${FIND_OR_CREATE_FLAG}" FROM ins
700
+ UNION ALL
701
+ SELECT ${selectCols}, false AS "${FIND_OR_CREATE_FLAG}" FROM ${tableSql} t
702
+ WHERE NOT EXISTS (SELECT 1 FROM ins)${fallbackClause}
703
+ LIMIT 1`;
704
+ }
705
+ export function buildInsertQuery(table, dataKeys, manifestIndex, returning = "pk") {
435
706
  if (dataKeys.length === 0) {
436
707
  throw new Error("Cannot build INSERT query with no columns");
437
708
  }
438
- const cols = dataKeys.map((k) => {
439
- 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);
440
712
  return quoteIdentifier(col?.sqlName ?? k);
441
713
  });
442
- const placeholders = dataKeys
714
+ const placeholders = orderedKeys
443
715
  .map((k, i) => {
444
- const col = table.columns.find((c) => c.tsName === k);
716
+ const col = colByTs(table, k, manifestIndex);
445
717
  return buildValuePlaceholder(col, i + 1);
446
718
  })
447
719
  .join(", ");
448
- const selectCols = buildSelectColumns(table);
449
- return `INSERT INTO ${tableRef(table)} (${cols.join(", ")}) VALUES (${placeholders}) RETURNING ${selectCols}`;
450
- }
451
- 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) {
452
737
  if (dataKeys.length === 0) {
453
738
  throw new Error("Cannot build INSERT many value rows with no columns");
454
739
  }
@@ -462,7 +747,7 @@ export function buildInsertManyValueRows(table, dataKeys, rows) {
462
747
  if (key === undefined) {
463
748
  throw new Error("dataKeys index out of bounds");
464
749
  }
465
- const col = table.columns.find((c) => c.tsName === key);
750
+ const col = colByTs(table, key, manifestIndex);
466
751
  const val = row[i];
467
752
  if (val === undefined) {
468
753
  placeholders.push("DEFAULT");
@@ -477,37 +762,50 @@ export function buildInsertManyValueRows(table, dataKeys, rows) {
477
762
  }
478
763
  return { valueRows, values };
479
764
  }
480
- export function buildInsertManyQuery(table, dataKeys, valueRows) {
765
+ export function buildInsertManyQuery(table, dataKeys, valueRows, manifestIndex) {
481
766
  if (dataKeys.length === 0) {
482
767
  throw new Error("Cannot build INSERT many query with no columns");
483
768
  }
484
769
  const cols = dataKeys.map((k) => {
485
- const col = table.columns.find((c) => c.tsName === k);
770
+ const col = colByTs(table, k, manifestIndex);
486
771
  return quoteIdentifier(col?.sqlName ?? k);
487
772
  });
488
- const selectCols = buildSelectColumns(table);
773
+ const selectCols = buildSelectColumns(table, undefined, manifestIndex);
489
774
  return `INSERT INTO ${tableRef(table)} (${cols.join(", ")}) VALUES ${valueRows.join(", ")} RETURNING ${selectCols}`;
490
775
  }
491
- export function buildUpdateQuery(table, dataKeys, whereSql, exprSets = []) {
492
- const paramSets = dataKeys.map((k, i) => {
493
- 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);
494
780
  return buildSetExpression(col, i + 1);
495
781
  });
496
782
  const sets = [...paramSets, ...exprSets];
497
- const selectCols = buildSelectColumns(table);
498
- const whereOffset = dataKeys.length;
783
+ const whereOffset = orderedKeys.length;
499
784
  let sql = `UPDATE ${tableRef(table)} SET ${sets.join(", ")}`;
500
785
  if (whereSql) {
501
- const adjustedWhere = whereSql.replace(/\$(\d+)/g, (_, n) => {
502
- return `$${Number(n) + whereOffset}`;
503
- });
786
+ const adjustedWhere = rebaseParamRefs(whereSql, whereOffset);
504
787
  sql += ` ${adjustedWhere}`;
505
788
  }
506
- sql += ` RETURNING ${selectCols}`;
507
- 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(", ");
508
804
  }
509
- export function buildDeleteQuery(table, whereSql) {
510
- 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);
511
809
  let sql = `DELETE FROM ${tableRef(table)}`;
512
810
  if (whereSql)
513
811
  sql += ` ${whereSql}`;
@@ -520,27 +818,40 @@ export function buildDeleteManyQuery(table, whereSql) {
520
818
  sql += ` ${whereSql}`;
521
819
  return sql;
522
820
  }
523
- export function buildUpdateManyQuery(table, dataKeys, whereSql, exprSets = []) {
524
- const paramSets = dataKeys.map((k, i) => {
525
- 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);
526
825
  return buildSetExpression(col, i + 1);
527
826
  });
528
827
  const sets = [...paramSets, ...exprSets];
529
- const whereOffset = dataKeys.length;
828
+ const whereOffset = orderedKeys.length;
530
829
  let sql = `UPDATE ${tableRef(table)} SET ${sets.join(", ")}`;
531
830
  if (whereSql) {
532
- const adjustedWhere = whereSql.replace(/\$(\d+)/g, (_, n) => {
533
- return `$${Number(n) + whereOffset}`;
534
- });
831
+ const adjustedWhere = rebaseParamRefs(whereSql, whereOffset);
535
832
  sql += ` ${adjustedWhere}`;
536
833
  }
537
834
  return sql;
538
835
  }
539
- 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);
540
851
  const keys = [];
541
852
  const values = [];
542
853
  for (const [key, value] of Object.entries(data)) {
543
- const col = table.columns.find((c) => c.tsName === key);
854
+ const col = columnByTsName(tableIndex, table, key);
544
855
  if (!col)
545
856
  continue;
546
857
  if (options?.excludePrimary && col.primary)
@@ -548,9 +859,9 @@ export function dataToSqlValues(table, data, options) {
548
859
  if (value === undefined)
549
860
  continue;
550
861
  keys.push(key);
551
- values.push(serializeColumnValue(col, value));
862
+ values.push(serializeColumnValue(col, value, dialect));
552
863
  }
553
- return { keys, values };
864
+ return reorderKeyValues(keys, values);
554
865
  }
555
866
  export function rowToTs(table, row) {
556
867
  const result = {};
@@ -569,7 +880,84 @@ export function rowToTs(table, row) {
569
880
  }
570
881
  return result;
571
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
+ }
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
+ }
923
+ const result = {};
924
+ for (const col of table.columns) {
925
+ if (col.sqlName in row) {
926
+ result[col.tsName] = row[col.sqlName];
927
+ }
928
+ }
929
+ for (const col of index.deserializeColumns) {
930
+ if (col.sqlName in row) {
931
+ const plugin = getColumnType(col.kind);
932
+ if (plugin?.deserializeValue) {
933
+ result[col.tsName] = plugin.deserializeValue(col, row[col.sqlName]);
934
+ }
935
+ }
936
+ }
937
+ return result;
938
+ }
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
+ }
948
+ return rows.map((row) => rowToTsIndexed(index, table, row));
949
+ }
572
950
  export function rowsToTs(table, rows) {
573
951
  return rows.map((row) => rowToTs(table, row));
574
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
+ }
575
963
  //# sourceMappingURL=compile.js.map