litedbmodel 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/scp/authoring-sql.d.ts +78 -0
  2. package/dist/scp/authoring-sql.d.ts.map +1 -1
  3. package/dist/scp/authoring-sql.js +110 -2
  4. package/dist/scp/authoring-sql.js.map +1 -1
  5. package/dist/scp/catalog.d.ts +5 -2
  6. package/dist/scp/catalog.d.ts.map +1 -1
  7. package/dist/scp/catalog.js +32 -1
  8. package/dist/scp/catalog.js.map +1 -1
  9. package/dist/scp/codegen.d.ts +143 -85
  10. package/dist/scp/codegen.d.ts.map +1 -1
  11. package/dist/scp/codegen.js +374 -90
  12. package/dist/scp/codegen.js.map +1 -1
  13. package/dist/scp/coltype.d.ts +41 -0
  14. package/dist/scp/coltype.d.ts.map +1 -0
  15. package/dist/scp/coltype.js +188 -0
  16. package/dist/scp/coltype.js.map +1 -0
  17. package/dist/scp/dialect.d.ts +12 -3
  18. package/dist/scp/dialect.d.ts.map +1 -1
  19. package/dist/scp/dialect.js +12 -3
  20. package/dist/scp/dialect.js.map +1 -1
  21. package/dist/scp/find-filter-guard.d.ts +68 -0
  22. package/dist/scp/find-filter-guard.d.ts.map +1 -0
  23. package/dist/scp/find-filter-guard.js +88 -0
  24. package/dist/scp/find-filter-guard.js.map +1 -0
  25. package/dist/scp/fragment/assemble.d.ts +61 -0
  26. package/dist/scp/fragment/assemble.d.ts.map +1 -0
  27. package/dist/scp/fragment/assemble.js +156 -0
  28. package/dist/scp/fragment/assemble.js.map +1 -0
  29. package/dist/scp/fragment/compile-pg.d.ts +107 -0
  30. package/dist/scp/fragment/compile-pg.d.ts.map +1 -0
  31. package/dist/scp/fragment/compile-pg.js +142 -0
  32. package/dist/scp/fragment/compile-pg.js.map +1 -0
  33. package/dist/scp/fragment/index.d.ts +16 -0
  34. package/dist/scp/fragment/index.d.ts.map +1 -0
  35. package/dist/scp/fragment/index.js +34 -0
  36. package/dist/scp/fragment/index.js.map +1 -0
  37. package/dist/scp/fragment/model.d.ts +119 -0
  38. package/dist/scp/fragment/model.d.ts.map +1 -0
  39. package/dist/scp/fragment/model.js +66 -0
  40. package/dist/scp/fragment/model.js.map +1 -0
  41. package/dist/scp/fragment/pg-array-type.d.ts +13 -0
  42. package/dist/scp/fragment/pg-array-type.d.ts.map +1 -0
  43. package/dist/scp/fragment/pg-array-type.js +34 -0
  44. package/dist/scp/fragment/pg-array-type.js.map +1 -0
  45. package/dist/scp/guard.d.ts +2 -6
  46. package/dist/scp/guard.d.ts.map +1 -1
  47. package/dist/scp/guard.js +19 -22
  48. package/dist/scp/guard.js.map +1 -1
  49. package/dist/scp/index.cjs +18695 -3921
  50. package/dist/scp/index.d.ts +41 -24
  51. package/dist/scp/index.d.ts.map +1 -1
  52. package/dist/scp/index.js +134 -49
  53. package/dist/scp/index.js.map +1 -1
  54. package/dist/scp/index.mjs +4830 -1432
  55. package/dist/scp/makesql/authoring-compile.d.ts +90 -0
  56. package/dist/scp/makesql/authoring-compile.d.ts.map +1 -0
  57. package/dist/scp/makesql/authoring-compile.js +494 -0
  58. package/dist/scp/makesql/authoring-compile.js.map +1 -0
  59. package/dist/scp/makesql/compile-crud.d.ts +133 -0
  60. package/dist/scp/makesql/compile-crud.d.ts.map +1 -0
  61. package/dist/scp/makesql/compile-crud.js +288 -0
  62. package/dist/scp/makesql/compile-crud.js.map +1 -0
  63. package/dist/scp/makesql/compile-relation.d.ts +157 -0
  64. package/dist/scp/makesql/compile-relation.d.ts.map +1 -0
  65. package/dist/scp/makesql/compile-relation.js +425 -0
  66. package/dist/scp/makesql/compile-relation.js.map +1 -0
  67. package/dist/scp/makesql/compile-select.d.ts +52 -0
  68. package/dist/scp/makesql/compile-select.d.ts.map +1 -0
  69. package/dist/scp/makesql/compile-select.js +58 -0
  70. package/dist/scp/makesql/compile-select.js.map +1 -0
  71. package/dist/scp/makesql/compile.d.ts +63 -0
  72. package/dist/scp/makesql/compile.d.ts.map +1 -0
  73. package/dist/scp/makesql/compile.js +99 -0
  74. package/dist/scp/makesql/compile.js.map +1 -0
  75. package/dist/scp/makesql/handler.d.ts +58 -0
  76. package/dist/scp/makesql/handler.d.ts.map +1 -0
  77. package/dist/scp/makesql/handler.js +113 -0
  78. package/dist/scp/makesql/handler.js.map +1 -0
  79. package/dist/scp/makesql/index.d.ts +33 -0
  80. package/dist/scp/makesql/index.d.ts.map +1 -0
  81. package/dist/scp/makesql/index.js +114 -0
  82. package/dist/scp/makesql/index.js.map +1 -0
  83. package/dist/scp/makesql/ir.d.ts +42 -0
  84. package/dist/scp/makesql/ir.d.ts.map +1 -0
  85. package/dist/scp/makesql/ir.js +66 -0
  86. package/dist/scp/makesql/ir.js.map +1 -0
  87. package/dist/scp/makesql/json-array.d.ts +84 -0
  88. package/dist/scp/makesql/json-array.d.ts.map +1 -0
  89. package/dist/scp/makesql/json-array.js +118 -0
  90. package/dist/scp/makesql/json-array.js.map +1 -0
  91. package/dist/scp/makesql/json-batch.d.ts +102 -0
  92. package/dist/scp/makesql/json-batch.d.ts.map +1 -0
  93. package/dist/scp/makesql/json-batch.js +269 -0
  94. package/dist/scp/makesql/json-batch.js.map +1 -0
  95. package/dist/scp/makesql/makesql.d.ts +99 -0
  96. package/dist/scp/makesql/makesql.d.ts.map +1 -0
  97. package/dist/scp/makesql/makesql.js +122 -0
  98. package/dist/scp/makesql/makesql.js.map +1 -0
  99. package/dist/scp/makesql/outtype.d.ts +44 -0
  100. package/dist/scp/makesql/outtype.d.ts.map +1 -0
  101. package/dist/scp/makesql/outtype.js +197 -0
  102. package/dist/scp/makesql/outtype.js.map +1 -0
  103. package/dist/scp/makesql/pool-executor.d.ts +47 -0
  104. package/dist/scp/makesql/pool-executor.d.ts.map +1 -0
  105. package/dist/scp/makesql/pool-executor.js +50 -0
  106. package/dist/scp/makesql/pool-executor.js.map +1 -0
  107. package/dist/scp/makesql/static-bundle.d.ts +187 -0
  108. package/dist/scp/makesql/static-bundle.d.ts.map +1 -0
  109. package/dist/scp/makesql/static-bundle.js +1113 -0
  110. package/dist/scp/makesql/static-bundle.js.map +1 -0
  111. package/dist/scp/makesql/tx.d.ts +216 -0
  112. package/dist/scp/makesql/tx.d.ts.map +1 -0
  113. package/dist/scp/makesql/tx.js +788 -0
  114. package/dist/scp/makesql/tx.js.map +1 -0
  115. package/dist/scp/makesql/writeouttype.d.ts +66 -0
  116. package/dist/scp/makesql/writeouttype.d.ts.map +1 -0
  117. package/dist/scp/makesql/writeouttype.js +195 -0
  118. package/dist/scp/makesql/writeouttype.js.map +1 -0
  119. package/dist/scp/relation.d.ts +86 -74
  120. package/dist/scp/relation.d.ts.map +1 -1
  121. package/dist/scp/relation.js +186 -120
  122. package/dist/scp/relation.js.map +1 -1
  123. package/dist/scp/runtime.d.ts +158 -211
  124. package/dist/scp/runtime.d.ts.map +1 -1
  125. package/dist/scp/runtime.js +250 -515
  126. package/dist/scp/runtime.js.map +1 -1
  127. package/dist/scp/typed-object.d.ts +12 -1
  128. package/dist/scp/typed-object.d.ts.map +1 -1
  129. package/dist/scp/typed-object.js +25 -4
  130. package/dist/scp/typed-object.js.map +1 -1
  131. package/docs/proposal/litedbmodel-v2-scp-architecture.md +51 -0
  132. package/docs/proposal/v0-coverage-matrix.md +157 -0
  133. package/docs/proposal/v2-completeness-plan.md +90 -0
  134. package/docs/proposal/v2-sql-parity-checklist.md +162 -0
  135. package/package.json +3 -3
  136. package/dist/scp/bridge.d.ts +0 -64
  137. package/dist/scp/bridge.d.ts.map +0 -1
  138. package/dist/scp/bridge.js +0 -329
  139. package/dist/scp/bridge.js.map +0 -1
  140. package/dist/scp/compile-dialect.d.ts +0 -39
  141. package/dist/scp/compile-dialect.d.ts.map +0 -1
  142. package/dist/scp/compile-dialect.js +0 -62
  143. package/dist/scp/compile-dialect.js.map +0 -1
  144. package/dist/scp/compile-sqlite.d.ts +0 -114
  145. package/dist/scp/compile-sqlite.d.ts.map +0 -1
  146. package/dist/scp/compile-sqlite.js +0 -149
  147. package/dist/scp/compile-sqlite.js.map +0 -1
  148. package/dist/scp/ir.d.ts +0 -92
  149. package/dist/scp/ir.d.ts.map +0 -1
  150. package/dist/scp/ir.js +0 -28
  151. package/dist/scp/ir.js.map +0 -1
  152. package/dist/scp/render.d.ts +0 -40
  153. package/dist/scp/render.d.ts.map +0 -1
  154. package/dist/scp/render.js +0 -170
  155. package/dist/scp/render.js.map +0 -1
  156. package/dist/scp/write-plan.d.ts +0 -161
  157. package/dist/scp/write-plan.d.ts.map +0 -1
  158. package/dist/scp/write-plan.js +0 -528
  159. package/dist/scp/write-plan.js.map +0 -1
  160. package/dist/scp/write-runtime.d.ts +0 -80
  161. package/dist/scp/write-runtime.d.ts.map +0 -1
  162. package/dist/scp/write-runtime.js +0 -167
  163. package/dist/scp/write-runtime.js.map +0 -1
@@ -0,0 +1,425 @@
1
+ "use strict";
2
+ /**
3
+ * litedbmodel v2 SCP — RELATION batch-load compile → `makeSQL`, reproducing the
4
+ * ORIGINAL `LazyRelation` SQL text byte-for-byte across all shapes and dialects:
5
+ *
6
+ * single-key, unlimited:
7
+ * PG `SELECT … FROM t WHERE t.key = ANY(?::type[])[ AND <filters>][ ORDER BY …]`
8
+ * MySQL/SQLite `SELECT … FROM t WHERE t.key IN (?, …)[ AND <filters>][ ORDER BY …]`
9
+ * single-key, per-parent limit:
10
+ * PG `SELECT t.* FROM unnest(?::type[]) AS _keys(key) CROSS JOIN LATERAL
11
+ * (SELECT * FROM t WHERE t.key = _keys.key[ AND <filters>] ORDER BY … LIMIT n) t`
12
+ * MySQL/SQLite `WITH ranked AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY key ORDER BY …) AS _rn
13
+ * FROM t WHERE key IN (?, …)[ AND <filters>]) SELECT * FROM ranked WHERE _rn <= n`
14
+ * composite-key, unlimited:
15
+ * PG `SELECT … FROM t JOIN unnest(?::t1[], ?::t2[]) AS _u(a1, a2) ON t.k1=_u.a1 AND …`
16
+ * MySQL/SQLite `SELECT … FROM t WHERE (k1, k2) IN ((?, ?), …)`
17
+ * composite-key, per-parent limit: PG LATERAL composite / others ROW_NUMBER composite.
18
+ *
19
+ * The PG type text (`?::type[]`) comes from the ORIGINAL `inferPgArrayType` (sqlCast
20
+ * wins, else element-type inference). The .rs regressions are NOT reproduced: PG
21
+ * per-parent-limit is LATERAL (not ROW_NUMBER), and PG types are sqlCast-driven (not
22
+ * text-folded).
23
+ *
24
+ * Inner SELECTs reuse {@link compileSelect} — the same text `buildSelectSQL` yields —
25
+ * so the whole shape is byte-faithful to the original relation builder.
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.PG_ARRAY_CAST_TOKEN = void 0;
29
+ exports.inferPgArrayType = inferPgArrayType;
30
+ exports.resolvePgArrayCast = resolvePgArrayCast;
31
+ exports.compileCompositeKeyStaticUnlimited = compileCompositeKeyStaticUnlimited;
32
+ exports.compileSingleKeyUnlimited = compileSingleKeyUnlimited;
33
+ exports.compileSingleKeyLimited = compileSingleKeyLimited;
34
+ exports.compileCompositeKeyUnlimited = compileCompositeKeyUnlimited;
35
+ exports.compileCompositeKeyLimited = compileCompositeKeyLimited;
36
+ exports.compileCompositeKeyStaticLimited = compileCompositeKeyStaticLimited;
37
+ const DBConditions_1 = require("../../DBConditions");
38
+ const compile_select_1 = require("./compile-select");
39
+ /**
40
+ * Reproduce the ORIGINAL `LazyRelation.inferPgArrayType`: sqlCast wins (`<cast>[]`);
41
+ * otherwise infer the element type from the sample values. Byte-identical to the
42
+ * original (which is the PG anchor — NOT the .rs coarse text-folding).
43
+ */
44
+ function inferPgArrayType(values, sqlCast) {
45
+ if (sqlCast)
46
+ return `${sqlCast}[]`;
47
+ if (values.length === 0)
48
+ return 'text[]';
49
+ const sample = values[0];
50
+ if (typeof sample === 'number') {
51
+ if (values.every((v) => Number.isInteger(v)))
52
+ return 'int[]';
53
+ return 'numeric[]';
54
+ }
55
+ if (typeof sample === 'bigint')
56
+ return 'bigint[]';
57
+ if (typeof sample === 'boolean')
58
+ return 'boolean[]';
59
+ if (sample instanceof Date)
60
+ return 'timestamp[]';
61
+ return 'text[]';
62
+ }
63
+ /**
64
+ * The DEFERRED PG array-cast token (#46): a placeholder emitted in the STATIC SQL text where
65
+ * the `= ANY(?::<T>[])` / `UNNEST(?::<T>[])` element type `<T>` cannot be known at symbolic
66
+ * compile time (a schema-less `whereIn`, or a relation batch compiled without concrete keys).
67
+ * The render/handler layer resolves it from the BOUND values via {@link inferPgArrayType} — a
68
+ * mechanical dialect-render step, the same category as the `?`→`$N` placeholder render. This
69
+ * reproduces v1's live-PG-correct cast (`::int[]` for int keys, etc.), which v1 got because
70
+ * `inferPgArrayType` saw the real values at runtime.
71
+ *
72
+ * A byte sequence no legitimate SQL identifier/type text contains, so the resolve is a safe
73
+ * literal substring replace (never a regex over user text).
74
+ */
75
+ exports.PG_ARRAY_CAST_TOKEN = '@@PG_ARRAY_CAST@@';
76
+ /**
77
+ * Resolve the FIRST unresolved {@link PG_ARRAY_CAST_TOKEN} in a PG SQL fragment to the element
78
+ * type inferred from the bound `values` (v1 `inferPgArrayType`). Called at render time, once per
79
+ * array param, left-to-right — so each deferred array cast binds the type of its own value set.
80
+ * SQL with no token is returned unchanged (every non-deferred cast is already concrete).
81
+ */
82
+ function resolvePgArrayCast(sql, values) {
83
+ const at = sql.indexOf(exports.PG_ARRAY_CAST_TOKEN);
84
+ if (at < 0)
85
+ return sql;
86
+ return sql.slice(0, at) + inferPgArrayType(values) + sql.slice(at + exports.PG_ARRAY_CAST_TOKEN.length);
87
+ }
88
+ /**
89
+ * The PG array-cast element type for a batch cast, honoring `sqlCast` (concrete column type) →
90
+ * the deferred {@link PG_ARRAY_CAST_TOKEN} (resolve at render from bound values) → inference from
91
+ * the compile-time sample `values`. Centralizes the #43/#46 precedence for every relation shape.
92
+ */
93
+ function pgArrayCastType(values, sqlCast, defer) {
94
+ if (sqlCast)
95
+ return `${sqlCast}[]`;
96
+ if (defer)
97
+ return exports.PG_ARRAY_CAST_TOKEN;
98
+ return inferPgArrayType(values);
99
+ }
100
+ /**
101
+ * The STATIC composite-key batch forms (#47 item 1) — length-INDEPENDENT so the compiled `op.sql`
102
+ * is fixed (one param per column on PG; ONE JSON param on MySQL/SQLite), the SAME static-op
103
+ * property the single-key relation forms have. PG stays byte-identical to v1's `unnest`-JOIN
104
+ * (`batchLoadWithUnnestJoin`), with the element-type cast DEFERRED (#46) to render from the real
105
+ * keys. MySQL/SQLite use the single-JSON tuple form (the owner-approved deviation the single-key
106
+ * IN-list and the batch UPDATE composite already use — RESULT parity, NOT byte-identity): a
107
+ * `JSON_TABLE`/`json_each` subquery over one JSON array-of-tuples param. The v1 literal
108
+ * `(k1,k2) IN ((?,?),…)` byte-form stays proven by the golden `compileCompositeKeyUnlimited`.
109
+ *
110
+ * The JSON tuple param is `[[k1a,k2a],[k1b,k2b],…]` (positional element arrays), read back by
111
+ * ordinal path (`$[0]`, `$[1]`, …) so no per-column JSON key names are needed.
112
+ */
113
+ function compileCompositeKeyStaticUnlimited(opts) {
114
+ const { tableName, targetKeys } = opts;
115
+ if (opts.dialect === 'postgres') {
116
+ // PG unnest-JOIN — ONE array param per key column (length-independent). Deferred cast (#46):
117
+ // the element type is resolved at render from the real per-column key arrays.
118
+ const unnestParams = targetKeys
119
+ .map((k) => `?::${pgArrayCastType([], opts.sqlCastMap?.get(k), opts.deferPgArrayCast)}`)
120
+ .join(', ');
121
+ const unnestAlias = `_unnest_${tableName}`;
122
+ const columnAliases = targetKeys.map((k) => `_unnest_${tableName}_${k}`).join(', ');
123
+ const joinConditions = targetKeys
124
+ .map((key) => `${tableName}.${key} = ${unnestAlias}._unnest_${tableName}_${key}`)
125
+ .join(' AND ');
126
+ const joinClause = `JOIN unnest(${unnestParams}) AS ${unnestAlias}(${columnAliases}) ON ${joinConditions}`;
127
+ // One placeholder array PER column fixes the arity of the JOIN params (each binds one array).
128
+ return (0, compile_select_1.compileSelect)({
129
+ dialect: opts.dialect,
130
+ tableName,
131
+ select: opts.select,
132
+ join: joinClause,
133
+ joinParams: targetKeys.map(() => [null]),
134
+ conditions: opts.conditions,
135
+ order: opts.order,
136
+ });
137
+ }
138
+ // MySQL/SQLite: composite membership via ONE JSON array-of-tuples param, read by ORDINAL path.
139
+ const jsonSubquery = compositeJsonMembership(opts.dialect, tableName, targetKeys);
140
+ const conditions = { ...opts.conditions, __raw__: [jsonSubquery, [[null]]] };
141
+ return (0, compile_select_1.compileSelect)({
142
+ dialect: opts.dialect,
143
+ tableName,
144
+ select: opts.select,
145
+ conditions,
146
+ order: opts.order,
147
+ });
148
+ }
149
+ /**
150
+ * The MySQL/SQLite composite-membership predicate over ONE JSON array-of-tuples param (ordinal
151
+ * paths). MySQL: `(k1,k2) IN (SELECT c0, c1 FROM JSON_TABLE(?, '$[*]' COLUMNS(c0 JSON PATH '$[0]',
152
+ * …)))` — an IN-subquery so it inherits the SAME per-column type coercion `(k1,k2) IN ((?,?),…)`
153
+ * would (the single-key rationale). SQLite: `EXISTS (SELECT 1 FROM json_each(?) je WHERE
154
+ * json_extract(je.value,'$[0]') = t.k1 AND …)` — the composite json_each form the batch UPDATE uses.
155
+ */
156
+ function compositeJsonMembership(dialect, tableName, targetKeys) {
157
+ if (dialect === 'mysql') {
158
+ const cols = targetKeys.map((_, i) => `c${i}`);
159
+ const jtCols = cols.map((c, i) => `${c} JSON PATH '$[${i}]'`).join(', ');
160
+ const selectCols = cols.map((c) => `JSON_UNQUOTE(${c})`).join(', ');
161
+ const keyTuple = targetKeys.map((k) => `${tableName}.${k}`).join(', ');
162
+ return `(${keyTuple}) IN (SELECT ${selectCols} FROM JSON_TABLE(?, '$[*]' COLUMNS(${jtCols})) jt)`;
163
+ }
164
+ // SQLite: EXISTS over json_each, matching every key column by ordinal element.
165
+ const match = targetKeys
166
+ .map((k, i) => `json_extract(je.value, '$[${i}]') = ${tableName}.${k}`)
167
+ .join(' AND ');
168
+ return `EXISTS (SELECT 1 FROM json_each(?) je WHERE ${match})`;
169
+ }
170
+ // ============================================================================
171
+ // Single-key, unlimited.
172
+ // ============================================================================
173
+ /**
174
+ * `= ANY(?::type[])` (PG) / `IN (?, …)` (MySQL/SQLite) single-key unlimited batch load.
175
+ * Reproduces `batchLoadWithAnyArray` (PG) and `batchLoadWithIn` (others).
176
+ *
177
+ * The key array binds as ONE param on PG (`values` is a single array param); on
178
+ * MySQL/SQLite the original passes the array to `DBConditions` which expands it to
179
+ * `IN (?, ?, …)` with one param per element — reproduced here verbatim.
180
+ */
181
+ function compileSingleKeyUnlimited(opts) {
182
+ if (opts.dialect === 'postgres') {
183
+ const sqlCast = opts.sqlCastMap?.get(opts.targetKey);
184
+ const pgType = pgArrayCastType(opts.values, sqlCast, opts.deferPgArrayCast);
185
+ const conditions = {
186
+ __raw__: [`${opts.tableName}.${opts.targetKey} = ANY(?::${pgType})`, [opts.values]],
187
+ ...opts.conditions,
188
+ };
189
+ return (0, compile_select_1.compileSelect)({
190
+ dialect: opts.dialect,
191
+ tableName: opts.tableName,
192
+ select: opts.select,
193
+ conditions,
194
+ order: opts.order,
195
+ });
196
+ }
197
+ // MySQL/SQLite: `{ ...conditions, [targetKey]: values }` → `IN (?, …)` (array expand).
198
+ const conditions = { ...opts.conditions, [opts.targetKey]: opts.values };
199
+ return (0, compile_select_1.compileSelect)({
200
+ dialect: opts.dialect,
201
+ tableName: opts.tableName,
202
+ select: opts.select,
203
+ conditions,
204
+ order: opts.order,
205
+ });
206
+ }
207
+ // ============================================================================
208
+ // Single-key, per-parent limit.
209
+ // ============================================================================
210
+ /**
211
+ * Per-parent-limit single-key batch load: PG `CROSS JOIN LATERAL` (the v1 anchor —
212
+ * NOT the .rs ROW_NUMBER regression); MySQL/SQLite `ROW_NUMBER() OVER (PARTITION BY …)`.
213
+ * Reproduces `batchLoadWithLateral` / `batchLoadWithRowNumber`.
214
+ */
215
+ function compileSingleKeyLimited(opts) {
216
+ if (opts.dialect === 'postgres') {
217
+ const sqlCast = opts.sqlCastMap?.get(opts.targetKey);
218
+ const pgType = pgArrayCastType(opts.values, sqlCast, opts.deferPgArrayCast);
219
+ const lateralConditions = {
220
+ __raw__: `${opts.tableName}.${opts.targetKey} = _keys.key`,
221
+ ...opts.conditions,
222
+ };
223
+ const inner = (0, compile_select_1.compileSelect)({
224
+ dialect: opts.dialect,
225
+ tableName: opts.tableName,
226
+ conditions: lateralConditions,
227
+ order: opts.order,
228
+ limit: opts.limit,
229
+ });
230
+ const sql = `SELECT ${opts.tableName}.* FROM unnest(?::${pgType}) AS _keys(key) ` +
231
+ `CROSS JOIN LATERAL (${inner.sql}) ${opts.tableName}`;
232
+ return { sql, params: [opts.values, ...inner.params] };
233
+ }
234
+ // MySQL/SQLite: ROW_NUMBER() CTE.
235
+ const orderBy = opts.order || opts.targetKey;
236
+ const cteConditions = { [opts.targetKey]: opts.values, ...opts.conditions };
237
+ const cte = (0, compile_select_1.compileSelect)({
238
+ dialect: opts.dialect,
239
+ tableName: opts.tableName,
240
+ select: `*, ROW_NUMBER() OVER (PARTITION BY ${opts.targetKey} ORDER BY ${orderBy}) AS _rn`,
241
+ conditions: cteConditions,
242
+ });
243
+ return (0, compile_select_1.compileSelect)({
244
+ dialect: opts.dialect,
245
+ tableName: 'ranked',
246
+ conditions: { __raw__: `_rn <= ${opts.limit}` },
247
+ cte: { name: 'ranked', sql: cte.sql, params: cte.params },
248
+ });
249
+ }
250
+ // ============================================================================
251
+ // Composite-key, unlimited.
252
+ // ============================================================================
253
+ /** Transpose tuples to per-column arrays: `[[1,a],[2,b]] → [[1,2],[a,b]]`. */
254
+ function transpose(targetKeys, tuples) {
255
+ return targetKeys.map((_, colIndex) => tuples.map((t) => t[colIndex]));
256
+ }
257
+ /**
258
+ * Composite-key unlimited batch load: PG `JOIN unnest(?::t1[], ?::t2[]) AS _u(a,b) ON …`
259
+ * (reproduces `batchLoadWithUnnestJoin`); MySQL/SQLite `(k1, k2) IN ((?, ?), …)`
260
+ * (reproduces `batchLoadWithCompositeIn` via `DBTupleIn`).
261
+ */
262
+ function compileCompositeKeyUnlimited(opts) {
263
+ const { tableName, targetKeys, tuples } = opts;
264
+ if (opts.dialect === 'postgres') {
265
+ const columnArrays = transpose(targetKeys, tuples);
266
+ const unnestParams = columnArrays
267
+ .map((arr, i) => `?::${inferPgArrayType(arr, opts.sqlCastMap?.get(targetKeys[i]))}`)
268
+ .join(', ');
269
+ const unnestAlias = `_unnest_${tableName}`;
270
+ const columnAliases = targetKeys.map((k) => `_unnest_${tableName}_${k}`).join(', ');
271
+ const joinConditions = targetKeys
272
+ .map((key) => `${tableName}.${key} = ${unnestAlias}._unnest_${tableName}_${key}`)
273
+ .join(' AND ');
274
+ const joinClause = `JOIN unnest(${unnestParams}) AS ${unnestAlias}(${columnAliases}) ON ${joinConditions}`;
275
+ return (0, compile_select_1.compileSelect)({
276
+ dialect: opts.dialect,
277
+ tableName,
278
+ select: opts.select,
279
+ join: joinClause,
280
+ joinParams: columnArrays,
281
+ conditions: opts.conditions,
282
+ order: opts.order,
283
+ });
284
+ }
285
+ // MySQL/SQLite: (k1, k2) IN ((?, ?), …) built exactly as `batchLoadWithCompositeIn`.
286
+ const tuplePlaceholders = tuples
287
+ .map(() => `(${targetKeys.map(() => '?').join(', ')})`)
288
+ .join(', ');
289
+ const inClause = `(${targetKeys.join(', ')}) IN (${tuplePlaceholders})`;
290
+ // The original builds base conditions FIRST then the composite IN last; DBConditions
291
+ // preserves object key insertion order, so replicate that order.
292
+ const conditions = { ...opts.conditions, __raw__: [inClause, tuples.flat()] };
293
+ return (0, compile_select_1.compileSelect)({
294
+ dialect: opts.dialect,
295
+ tableName,
296
+ select: opts.select,
297
+ conditions,
298
+ order: opts.order,
299
+ });
300
+ }
301
+ // ============================================================================
302
+ // Composite-key, per-parent limit.
303
+ // ============================================================================
304
+ /**
305
+ * Composite-key per-parent-limit: PG LATERAL composite (reproduces
306
+ * `batchLoadWithLateralComposite`); MySQL/SQLite ROW_NUMBER composite (reproduces
307
+ * `batchLoadWithRowNumberComposite`).
308
+ */
309
+ function compileCompositeKeyLimited(opts) {
310
+ const { tableName, targetKeys, tuples, limit } = opts;
311
+ if (opts.dialect === 'postgres') {
312
+ const columnArrays = transpose(targetKeys, tuples);
313
+ const unnestParams = columnArrays
314
+ .map((arr, i) => `?::${inferPgArrayType(arr, opts.sqlCastMap?.get(targetKeys[i]))}`)
315
+ .join(', ');
316
+ const keyAliases = targetKeys.map((_, i) => `key${i}`).join(', ');
317
+ const keyConditions = targetKeys
318
+ .map((key, i) => `${tableName}.${key} = _keys.key${i}`)
319
+ .join(' AND ');
320
+ const lateralConditions = { __raw__: keyConditions, ...opts.conditions };
321
+ const inner = (0, compile_select_1.compileSelect)({
322
+ dialect: opts.dialect,
323
+ tableName,
324
+ conditions: lateralConditions,
325
+ order: opts.order,
326
+ limit,
327
+ });
328
+ const sql = `SELECT ${tableName}.* FROM unnest(${unnestParams}) AS _keys(${keyAliases}) ` +
329
+ `CROSS JOIN LATERAL (${inner.sql}) ${tableName}`;
330
+ return { sql, params: [...columnArrays, ...inner.params] };
331
+ }
332
+ // MySQL/SQLite ROW_NUMBER composite.
333
+ const orderBy = opts.order || targetKeys.join(', ');
334
+ const partitionBy = targetKeys.join(', ');
335
+ const tuplePlaceholders = tuples
336
+ .map(() => `(${targetKeys.map(() => '?').join(', ')})`)
337
+ .join(', ');
338
+ const inClause = `(${targetKeys.join(', ')}) IN (${tuplePlaceholders})`;
339
+ const cteParams = tuples.flat();
340
+ const cteConditions = { __raw__: [inClause, cteParams], ...opts.conditions };
341
+ const cte = (0, compile_select_1.compileSelect)({
342
+ dialect: opts.dialect,
343
+ tableName,
344
+ select: `*, ROW_NUMBER() OVER (PARTITION BY ${partitionBy} ORDER BY ${orderBy}) AS _rn`,
345
+ conditions: cteConditions,
346
+ });
347
+ return (0, compile_select_1.compileSelect)({
348
+ dialect: opts.dialect,
349
+ tableName: 'ranked',
350
+ conditions: { __raw__: `_rn <= ${limit}` },
351
+ cte: { name: 'ranked', sql: cte.sql, params: cte.params },
352
+ });
353
+ }
354
+ // ============================================================================
355
+ // Composite-key, per-parent limit — STATIC (length-independent) form (#47 last gap).
356
+ // ============================================================================
357
+ /**
358
+ * The STATIC composite-key per-parent-LIMIT batch form (#47 last completeness gap) — the
359
+ * length-INDEPENDENT sibling of {@link compileCompositeKeyLimited}, so the compiled `op.sql` is
360
+ * FIXED (one array param per key column on PG; ONE JSON array-of-tuples param on MySQL/SQLite) and
361
+ * can be a STATIC bundle op — exactly the property {@link compileSingleKeyLimited} and
362
+ * {@link compileCompositeKeyStaticUnlimited} already have.
363
+ *
364
+ * The per-parent window is IDENTICAL to the single-key-limited path:
365
+ * - **PG**: `CROSS JOIN LATERAL` over `unnest(?::t1[], ?::t2[])` — BYTE-identical to v1's
366
+ * `batchLoadWithLateralComposite` (the composite LATERAL is already structurally
367
+ * length-independent; only the element-type cast was value-derived, and that is DEFERRED (#46)
368
+ * to render from the real keys via {@link PG_ARRAY_CAST_TOKEN}). No deviation on PG.
369
+ * - **MySQL/SQLite**: the SAME `ROW_NUMBER() OVER (PARTITION BY <keys> ORDER BY <order>)` CTE +
370
+ * `_rn <= limit` filter v1's `batchLoadWithRowNumberComposite` emits — but the CTE membership
371
+ * WHERE is the STATIC JSON-tuple predicate ({@link compositeJsonMembership}) instead of v1's
372
+ * value-dependent `(k1,k2) IN ((?,?),…)`. This is the owner-sanctioned static deviation the
373
+ * composite UNLIMITED form ({@link compileCompositeKeyStaticUnlimited}) and the single-key
374
+ * IN-list already use: the JSON subquery selects the SAME child rows the tuple-IN would, the
375
+ * window partitions/orders identically, so it is RESULT-parity to v1 (proven live). The v1
376
+ * literal `(k1,k2) IN ((?,?),…)` byte-form stays proven by the golden
377
+ * {@link compileCompositeKeyLimited}.
378
+ */
379
+ function compileCompositeKeyStaticLimited(opts) {
380
+ const { tableName, targetKeys, limit } = opts;
381
+ if (opts.dialect === 'postgres') {
382
+ // PG LATERAL composite — ONE array param per key column (length-independent). Deferred cast
383
+ // (#46): each element type resolved at render from that column's real key array.
384
+ const unnestParams = targetKeys
385
+ .map((k) => `?::${pgArrayCastType([], opts.sqlCastMap?.get(k), opts.deferPgArrayCast)}`)
386
+ .join(', ');
387
+ const keyAliases = targetKeys.map((_, i) => `key${i}`).join(', ');
388
+ const keyConditions = targetKeys
389
+ .map((key, i) => `${tableName}.${key} = _keys.key${i}`)
390
+ .join(' AND ');
391
+ const lateralConditions = { __raw__: keyConditions, ...opts.conditions };
392
+ const inner = (0, compile_select_1.compileSelect)({
393
+ dialect: opts.dialect,
394
+ tableName,
395
+ conditions: lateralConditions,
396
+ order: opts.order,
397
+ limit,
398
+ });
399
+ const sql = `SELECT ${tableName}.* FROM unnest(${unnestParams}) AS _keys(${keyAliases}) ` +
400
+ `CROSS JOIN LATERAL (${inner.sql}) ${tableName}`;
401
+ // One placeholder array PER column fixes the arity (each binds one array param at execute time).
402
+ return { sql, params: [...targetKeys.map(() => [null]), ...inner.params] };
403
+ }
404
+ // MySQL/SQLite: the SAME ROW_NUMBER composite CTE + `_rn <= limit` as v1, but with the STATIC
405
+ // JSON-membership WHERE (one JSON array-of-tuples param) in place of v1's `(k1,k2) IN ((?,?),…)`.
406
+ const orderBy = opts.order || targetKeys.join(', ');
407
+ const partitionBy = targetKeys.join(', ');
408
+ const jsonSubquery = compositeJsonMembership(opts.dialect, tableName, targetKeys);
409
+ const cteConditions = { __raw__: [jsonSubquery, [[null]]], ...opts.conditions };
410
+ const cte = (0, compile_select_1.compileSelect)({
411
+ dialect: opts.dialect,
412
+ tableName,
413
+ select: `*, ROW_NUMBER() OVER (PARTITION BY ${partitionBy} ORDER BY ${orderBy}) AS _rn`,
414
+ conditions: cteConditions,
415
+ });
416
+ return (0, compile_select_1.compileSelect)({
417
+ dialect: opts.dialect,
418
+ tableName: 'ranked',
419
+ conditions: { __raw__: `_rn <= ${limit}` },
420
+ cte: { name: 'ranked', sql: cte.sql, params: cte.params },
421
+ });
422
+ }
423
+ // Silence unused import in builds where DBConditions is only referenced via ConditionObject.
424
+ void DBConditions_1.DBConditions;
425
+ //# sourceMappingURL=compile-relation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-relation.js","sourceRoot":"","sources":["../../../src/scp/makesql/compile-relation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * litedbmodel v2 SCP — SELECT compile → `makeSQL`, reproducing the ORIGINAL
3
+ * `DBModel._buildSelectSQL` text byte-for-byte (the internal builder `find()` uses):
4
+ *
5
+ * [WITH <cte> AS (…) ]SELECT <cols> FROM <t>[ <join>][ WHERE <cond>]
6
+ * [ GROUP BY <group>][ ORDER BY <order>][ LIMIT <n>][ OFFSET <n>][ FOR UPDATE][ <append>]
7
+ *
8
+ * LIMIT/OFFSET are INLINE literals (`LIMIT 10`), NOT parameters — the original inlines
9
+ * them (`sql += \` LIMIT ${options.limit}\``); reproduced here. FOR UPDATE / GROUP BY /
10
+ * raw `append` tail are the original's exact text. HAVING is carried through `append`
11
+ * (v1 core has no dedicated HAVING; the .rs-only HAVING is not the PG anchor).
12
+ *
13
+ * Param order matches the original exactly: CTE params → JOIN params → WHERE params.
14
+ */
15
+ import type { ConditionObject } from '../../DBConditions';
16
+ import type { OrderSpec } from '../../Column';
17
+ import type { MakeSQL } from './makesql';
18
+ import type { Dialect } from './handler';
19
+ /** SELECT descriptor — mirrors the fields `_buildSelectSQL` reads from `SelectOptions`. */
20
+ export interface SelectDesc {
21
+ dialect: Dialect;
22
+ tableName: string;
23
+ /** SELECT column list (an explicit `options.select`). Empty/absent → falls back to {@link selectColumn}. */
24
+ select?: string;
25
+ /**
26
+ * The model's `SELECT_COLUMN` (v1 `DBModel.SELECT_COLUMN`) — the fallback projection when no explicit
27
+ * `select` is given. v1 derives the SELECT list as `options.select || this.SELECT_COLUMN`
28
+ * (`DBModel._buildSelectSQL`:572), so a subclass that overrides `SELECT_COLUMN` must flow through here
29
+ * rather than being hardcoded to `'*'`. Absent → the base-class default `'*'` (`DBModel.SELECT_COLUMN`).
30
+ */
31
+ selectColumn?: string;
32
+ conditions?: ConditionObject;
33
+ join?: string;
34
+ joinParams?: unknown[];
35
+ cte?: {
36
+ name: string;
37
+ sql: string;
38
+ params: unknown[];
39
+ };
40
+ group?: string;
41
+ order?: OrderSpec | string;
42
+ limit?: number;
43
+ offset?: number;
44
+ forUpdate?: boolean;
45
+ append?: string;
46
+ }
47
+ /**
48
+ * Compile a SELECT to a `makeSQL` bundle, byte-identical to `_buildSelectSQL`.
49
+ * Empty WHERE ⇒ no ` WHERE` (matches the original's `if (whereClause)` guard).
50
+ */
51
+ export declare function compileSelect(desc: SelectDesc): MakeSQL;
52
+ //# sourceMappingURL=compile-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-select.d.ts","sourceRoot":"","sources":["../../../src/scp/makesql/compile-select.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,2FAA2F;AAC3F,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,4GAA4G;IAC5G,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CA6BvD"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ /**
3
+ * litedbmodel v2 SCP — SELECT compile → `makeSQL`, reproducing the ORIGINAL
4
+ * `DBModel._buildSelectSQL` text byte-for-byte (the internal builder `find()` uses):
5
+ *
6
+ * [WITH <cte> AS (…) ]SELECT <cols> FROM <t>[ <join>][ WHERE <cond>]
7
+ * [ GROUP BY <group>][ ORDER BY <order>][ LIMIT <n>][ OFFSET <n>][ FOR UPDATE][ <append>]
8
+ *
9
+ * LIMIT/OFFSET are INLINE literals (`LIMIT 10`), NOT parameters — the original inlines
10
+ * them (`sql += \` LIMIT ${options.limit}\``); reproduced here. FOR UPDATE / GROUP BY /
11
+ * raw `append` tail are the original's exact text. HAVING is carried through `append`
12
+ * (v1 core has no dedicated HAVING; the .rs-only HAVING is not the PG anchor).
13
+ *
14
+ * Param order matches the original exactly: CTE params → JOIN params → WHERE params.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.compileSelect = compileSelect;
18
+ const Column_1 = require("../../Column");
19
+ const compile_1 = require("./compile");
20
+ const json_array_1 = require("./json-array");
21
+ /**
22
+ * Compile a SELECT to a `makeSQL` bundle, byte-identical to `_buildSelectSQL`.
23
+ * Empty WHERE ⇒ no ` WHERE` (matches the original's `if (whereClause)` guard).
24
+ */
25
+ function compileSelect(desc) {
26
+ const params = [];
27
+ const selectCols = desc.select || (desc.selectColumn ?? '*');
28
+ const formatter = (0, compile_1.formatterFor)(desc.dialect);
29
+ // Param order (matches SQL order): CTE params → JOIN params → WHERE params.
30
+ if (desc.cte?.params && desc.cte.params.length > 0)
31
+ params.push(...desc.cte.params);
32
+ if (desc.joinParams && desc.joinParams.length > 0)
33
+ params.push(...desc.joinParams);
34
+ const whereClause = (0, json_array_1.conditionsFor)(desc.conditions ?? {}, desc.dialect).compile(params, formatter);
35
+ let sql = '';
36
+ if (desc.cte)
37
+ sql = `WITH ${desc.cte.name} AS (${desc.cte.sql}) `;
38
+ sql += `SELECT ${selectCols} FROM ${desc.tableName}`;
39
+ if (desc.join)
40
+ sql += ` ${desc.join}`;
41
+ if (whereClause)
42
+ sql += ` WHERE ${whereClause}`;
43
+ if (desc.group)
44
+ sql += ` GROUP BY ${desc.group}`;
45
+ const orderClause = typeof desc.order === 'string' ? desc.order : (0, Column_1.orderToString)(desc.order);
46
+ if (orderClause)
47
+ sql += ` ORDER BY ${orderClause}`;
48
+ if (desc.limit !== undefined)
49
+ sql += ` LIMIT ${desc.limit}`;
50
+ if (desc.offset !== undefined)
51
+ sql += ` OFFSET ${desc.offset}`;
52
+ if (desc.forUpdate)
53
+ sql += ' FOR UPDATE';
54
+ if (desc.append)
55
+ sql += ` ${desc.append}`;
56
+ return { sql, params };
57
+ }
58
+ //# sourceMappingURL=compile-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-select.js","sourceRoot":"","sources":["../../../src/scp/makesql/compile-select.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;AAuCH,sCA6BC;AAjED,yCAA6C;AAG7C,uCAAyC;AACzC,6CAA6C;AA4B7C;;;GAGG;AACH,SAAgB,aAAa,CAAC,IAAgB;IAC5C,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,GAAG,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,IAAA,sBAAY,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE7C,4EAA4E;IAC5E,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpF,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IAEnF,MAAM,WAAW,GAAG,IAAA,0BAAa,EAAC,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAElG,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,IAAI,CAAC,GAAG;QAAE,GAAG,GAAG,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAElE,GAAG,IAAI,UAAU,UAAU,SAAS,IAAI,CAAC,SAAS,EAAE,CAAC;IACrD,IAAI,IAAI,CAAC,IAAI;QAAE,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,WAAW;QAAE,GAAG,IAAI,UAAU,WAAW,EAAE,CAAC;IAChD,IAAI,IAAI,CAAC,KAAK;QAAE,GAAG,IAAI,aAAa,IAAI,CAAC,KAAK,EAAE,CAAC;IAEjD,MAAM,WAAW,GACf,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,sBAAa,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1E,IAAI,WAAW;QAAE,GAAG,IAAI,aAAa,WAAW,EAAE,CAAC;IAEnD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,GAAG,IAAI,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;IAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,GAAG,IAAI,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC;IAC/D,IAAI,IAAI,CAAC,SAAS;QAAE,GAAG,IAAI,aAAa,CAAC;IACzC,IAAI,IAAI,CAAC,MAAM;QAAE,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;IAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * litedbmodel v2 SCP — the COMPILE step (build time, TS). Emits the tuned dialect SQL
3
+ * TEXT for every surface as `makeSQL` port bundles, by REUSING the ORIGINAL tuned
4
+ * builders (`DBConditions`/`DBValues`, `LazyRelationContext`, `Postgres/Mysql/Sqlite
5
+ * SqlBuilder`, `DBModel.buildSelectSQL` + single INSERT/UPDATE/DELETE). Because each
6
+ * bundle's `sql`/`params` come from driving the original, the assembled + rendered
7
+ * output is byte-identical to what the original library sends over the wire.
8
+ *
9
+ * There is NO abstract IR here and NO reduced form. The produced artifact is ONLY
10
+ * `makeSQL` port bundles (`{ sql, params, skip? }`) — SQL structure (`= ANY`,
11
+ * `CROSS JOIN LATERAL`, `UNNEST`, cast, subquery, batch shapes) is TEXT inside `sql`.
12
+ *
13
+ * The three dialects share this compile: PG compiled text is the anchor and stays
14
+ * byte-identical to v1 (`= ANY(?::t[])` / `UNNEST` / LATERAL). MySQL/SQLite array &
15
+ * batch surfaces INTENTIONALLY DEVIATE from v1 (epic #43/#45): instead of v1's
16
+ * N-placeholder `IN (?, …)` / multi-VALUES / `VALUES ROW` / `CASE WHEN`, they now emit a
17
+ * SINGLE JSON param expanded server-side (`MEMBER OF` / `JSON_TABLE` / `json_each`; see
18
+ * `json-array.ts` / `json-batch.ts`). Result parity with v1 is proven on real MySQL 8 +
19
+ * SQLite (`test/scp/json-array-parity.test.ts`). Everything else stays v1 byte-match.
20
+ */
21
+ import { type ConditionObject } from '../../DBConditions';
22
+ import type { SqlCastFormatter } from '../../DBValues';
23
+ import type { MakeSQL } from './makesql';
24
+ import type { Dialect } from './handler';
25
+ /** PostgreSQL cast formatter: `?` → `?::type` (matches `DBValues` default formatter). */
26
+ export declare const pgCastFormatter: SqlCastFormatter;
27
+ /** MySQL/SQLite cast formatter: no cast (placeholder unchanged). */
28
+ export declare const noCastFormatter: SqlCastFormatter;
29
+ /** The cast formatter the original builders use for a given dialect. */
30
+ export declare function formatterFor(dialect: Dialect): SqlCastFormatter;
31
+ /**
32
+ * Compile a WHERE clause (bare, without the `WHERE` keyword) from a condition object
33
+ * to a `makeSQL` bundle. The text + params come STRAIGHT from the original
34
+ * `DBConditions.compile(params, formatter)`, so every construct it supports —
35
+ * eq/ne/cmp (custom-op key), IN-list, empty-IN (`1 = 0`), IS NULL, IS NOT NULL
36
+ * (`dbNotNull`), boolean literal (`= TRUE`), LIKE/ILIKE/BETWEEN (custom-op/raw),
37
+ * IN/NOT IN subquery (`DBSubquery`), EXISTS/NOT EXISTS (`DBExists`), correlated
38
+ * parentRef, raw (`__raw__`), AND/OR grouping with parens (`__or__` / nested
39
+ * DBConditions), cast (`dbCast`/`dbCastIn`, dialect-gated), immediate inline
40
+ * (`dbImmediate`/`dbRaw`), dynamic (`dbDynamic`), tuple/composite IN (`dbTupleIn`) —
41
+ * is reproduced byte-for-byte.
42
+ *
43
+ * Empty clause → `{ sql: '', params: [] }` (the original returns `''` when no part is
44
+ * present; folded here into an empty bundle so composition drops it).
45
+ */
46
+ export declare function compileWhere(conditions: ConditionObject, dialect: Dialect): MakeSQL;
47
+ /**
48
+ * Wrap a bare WHERE core (from {@link compileWhere}) as the ` WHERE <core>` clause a
49
+ * SELECT/UPDATE/DELETE appends — byte-identical to the originals which do
50
+ * `sql += \` WHERE ${whereClause}\`` only when `whereClause` is non-empty. An empty
51
+ * core yields an empty bundle (no ` WHERE`).
52
+ */
53
+ export declare function whereClause(where: MakeSQL): MakeSQL;
54
+ /**
55
+ * Compose a leading condition with an ordered list of optional (SKIP-guarded) trailing
56
+ * conditions joined by ` AND `, exactly as the original relation/select path appends
57
+ * `config.conditions` after a mandatory key predicate. Each optional member carries
58
+ * its own connector (` AND <core>`), so a skipped member drops its connector too.
59
+ *
60
+ * Returns the list of `makeSQL` components (head + guarded tails); the caller composes.
61
+ */
62
+ export declare function andTrailing(head: MakeSQL, tails: MakeSQL[]): MakeSQL[];
63
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/scp/makesql/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,yFAAyF;AACzF,eAAO,MAAM,eAAe,EAAE,gBAAyE,CAAC;AACxG,oEAAoE;AACpE,eAAO,MAAM,eAAe,EAAE,gBAA+C,CAAC;AAE9E,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAE/D;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAKnF;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGnD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAOtE"}