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.
- package/dist/scp/authoring-sql.d.ts +78 -0
- package/dist/scp/authoring-sql.d.ts.map +1 -1
- package/dist/scp/authoring-sql.js +110 -2
- package/dist/scp/authoring-sql.js.map +1 -1
- package/dist/scp/catalog.d.ts +5 -2
- package/dist/scp/catalog.d.ts.map +1 -1
- package/dist/scp/catalog.js +32 -1
- package/dist/scp/catalog.js.map +1 -1
- package/dist/scp/codegen.d.ts +143 -85
- package/dist/scp/codegen.d.ts.map +1 -1
- package/dist/scp/codegen.js +374 -90
- package/dist/scp/codegen.js.map +1 -1
- package/dist/scp/coltype.d.ts +41 -0
- package/dist/scp/coltype.d.ts.map +1 -0
- package/dist/scp/coltype.js +188 -0
- package/dist/scp/coltype.js.map +1 -0
- package/dist/scp/dialect.d.ts +12 -3
- package/dist/scp/dialect.d.ts.map +1 -1
- package/dist/scp/dialect.js +12 -3
- package/dist/scp/dialect.js.map +1 -1
- package/dist/scp/find-filter-guard.d.ts +68 -0
- package/dist/scp/find-filter-guard.d.ts.map +1 -0
- package/dist/scp/find-filter-guard.js +88 -0
- package/dist/scp/find-filter-guard.js.map +1 -0
- package/dist/scp/fragment/assemble.d.ts +61 -0
- package/dist/scp/fragment/assemble.d.ts.map +1 -0
- package/dist/scp/fragment/assemble.js +156 -0
- package/dist/scp/fragment/assemble.js.map +1 -0
- package/dist/scp/fragment/compile-pg.d.ts +107 -0
- package/dist/scp/fragment/compile-pg.d.ts.map +1 -0
- package/dist/scp/fragment/compile-pg.js +142 -0
- package/dist/scp/fragment/compile-pg.js.map +1 -0
- package/dist/scp/fragment/index.d.ts +16 -0
- package/dist/scp/fragment/index.d.ts.map +1 -0
- package/dist/scp/fragment/index.js +34 -0
- package/dist/scp/fragment/index.js.map +1 -0
- package/dist/scp/fragment/model.d.ts +119 -0
- package/dist/scp/fragment/model.d.ts.map +1 -0
- package/dist/scp/fragment/model.js +66 -0
- package/dist/scp/fragment/model.js.map +1 -0
- package/dist/scp/fragment/pg-array-type.d.ts +13 -0
- package/dist/scp/fragment/pg-array-type.d.ts.map +1 -0
- package/dist/scp/fragment/pg-array-type.js +34 -0
- package/dist/scp/fragment/pg-array-type.js.map +1 -0
- package/dist/scp/guard.d.ts +2 -6
- package/dist/scp/guard.d.ts.map +1 -1
- package/dist/scp/guard.js +19 -22
- package/dist/scp/guard.js.map +1 -1
- package/dist/scp/index.cjs +18695 -3921
- package/dist/scp/index.d.ts +41 -24
- package/dist/scp/index.d.ts.map +1 -1
- package/dist/scp/index.js +134 -49
- package/dist/scp/index.js.map +1 -1
- package/dist/scp/index.mjs +4830 -1432
- package/dist/scp/makesql/authoring-compile.d.ts +90 -0
- package/dist/scp/makesql/authoring-compile.d.ts.map +1 -0
- package/dist/scp/makesql/authoring-compile.js +494 -0
- package/dist/scp/makesql/authoring-compile.js.map +1 -0
- package/dist/scp/makesql/compile-crud.d.ts +133 -0
- package/dist/scp/makesql/compile-crud.d.ts.map +1 -0
- package/dist/scp/makesql/compile-crud.js +288 -0
- package/dist/scp/makesql/compile-crud.js.map +1 -0
- package/dist/scp/makesql/compile-relation.d.ts +157 -0
- package/dist/scp/makesql/compile-relation.d.ts.map +1 -0
- package/dist/scp/makesql/compile-relation.js +425 -0
- package/dist/scp/makesql/compile-relation.js.map +1 -0
- package/dist/scp/makesql/compile-select.d.ts +52 -0
- package/dist/scp/makesql/compile-select.d.ts.map +1 -0
- package/dist/scp/makesql/compile-select.js +58 -0
- package/dist/scp/makesql/compile-select.js.map +1 -0
- package/dist/scp/makesql/compile.d.ts +63 -0
- package/dist/scp/makesql/compile.d.ts.map +1 -0
- package/dist/scp/makesql/compile.js +99 -0
- package/dist/scp/makesql/compile.js.map +1 -0
- package/dist/scp/makesql/handler.d.ts +58 -0
- package/dist/scp/makesql/handler.d.ts.map +1 -0
- package/dist/scp/makesql/handler.js +113 -0
- package/dist/scp/makesql/handler.js.map +1 -0
- package/dist/scp/makesql/index.d.ts +33 -0
- package/dist/scp/makesql/index.d.ts.map +1 -0
- package/dist/scp/makesql/index.js +114 -0
- package/dist/scp/makesql/index.js.map +1 -0
- package/dist/scp/makesql/ir.d.ts +42 -0
- package/dist/scp/makesql/ir.d.ts.map +1 -0
- package/dist/scp/makesql/ir.js +66 -0
- package/dist/scp/makesql/ir.js.map +1 -0
- package/dist/scp/makesql/json-array.d.ts +84 -0
- package/dist/scp/makesql/json-array.d.ts.map +1 -0
- package/dist/scp/makesql/json-array.js +118 -0
- package/dist/scp/makesql/json-array.js.map +1 -0
- package/dist/scp/makesql/json-batch.d.ts +102 -0
- package/dist/scp/makesql/json-batch.d.ts.map +1 -0
- package/dist/scp/makesql/json-batch.js +269 -0
- package/dist/scp/makesql/json-batch.js.map +1 -0
- package/dist/scp/makesql/makesql.d.ts +99 -0
- package/dist/scp/makesql/makesql.d.ts.map +1 -0
- package/dist/scp/makesql/makesql.js +122 -0
- package/dist/scp/makesql/makesql.js.map +1 -0
- package/dist/scp/makesql/outtype.d.ts +44 -0
- package/dist/scp/makesql/outtype.d.ts.map +1 -0
- package/dist/scp/makesql/outtype.js +197 -0
- package/dist/scp/makesql/outtype.js.map +1 -0
- package/dist/scp/makesql/pool-executor.d.ts +47 -0
- package/dist/scp/makesql/pool-executor.d.ts.map +1 -0
- package/dist/scp/makesql/pool-executor.js +50 -0
- package/dist/scp/makesql/pool-executor.js.map +1 -0
- package/dist/scp/makesql/static-bundle.d.ts +187 -0
- package/dist/scp/makesql/static-bundle.d.ts.map +1 -0
- package/dist/scp/makesql/static-bundle.js +1113 -0
- package/dist/scp/makesql/static-bundle.js.map +1 -0
- package/dist/scp/makesql/tx.d.ts +216 -0
- package/dist/scp/makesql/tx.d.ts.map +1 -0
- package/dist/scp/makesql/tx.js +788 -0
- package/dist/scp/makesql/tx.js.map +1 -0
- package/dist/scp/makesql/writeouttype.d.ts +66 -0
- package/dist/scp/makesql/writeouttype.d.ts.map +1 -0
- package/dist/scp/makesql/writeouttype.js +195 -0
- package/dist/scp/makesql/writeouttype.js.map +1 -0
- package/dist/scp/relation.d.ts +86 -74
- package/dist/scp/relation.d.ts.map +1 -1
- package/dist/scp/relation.js +186 -120
- package/dist/scp/relation.js.map +1 -1
- package/dist/scp/runtime.d.ts +158 -211
- package/dist/scp/runtime.d.ts.map +1 -1
- package/dist/scp/runtime.js +250 -515
- package/dist/scp/runtime.js.map +1 -1
- package/dist/scp/typed-object.d.ts +12 -1
- package/dist/scp/typed-object.d.ts.map +1 -1
- package/dist/scp/typed-object.js +25 -4
- package/dist/scp/typed-object.js.map +1 -1
- package/docs/proposal/litedbmodel-v2-scp-architecture.md +51 -0
- package/docs/proposal/v0-coverage-matrix.md +157 -0
- package/docs/proposal/v2-completeness-plan.md +90 -0
- package/docs/proposal/v2-sql-parity-checklist.md +162 -0
- package/package.json +3 -3
- package/dist/scp/bridge.d.ts +0 -64
- package/dist/scp/bridge.d.ts.map +0 -1
- package/dist/scp/bridge.js +0 -329
- package/dist/scp/bridge.js.map +0 -1
- package/dist/scp/compile-dialect.d.ts +0 -39
- package/dist/scp/compile-dialect.d.ts.map +0 -1
- package/dist/scp/compile-dialect.js +0 -62
- package/dist/scp/compile-dialect.js.map +0 -1
- package/dist/scp/compile-sqlite.d.ts +0 -114
- package/dist/scp/compile-sqlite.d.ts.map +0 -1
- package/dist/scp/compile-sqlite.js +0 -149
- package/dist/scp/compile-sqlite.js.map +0 -1
- package/dist/scp/ir.d.ts +0 -92
- package/dist/scp/ir.d.ts.map +0 -1
- package/dist/scp/ir.js +0 -28
- package/dist/scp/ir.js.map +0 -1
- package/dist/scp/render.d.ts +0 -40
- package/dist/scp/render.d.ts.map +0 -1
- package/dist/scp/render.js +0 -170
- package/dist/scp/render.js.map +0 -1
- package/dist/scp/write-plan.d.ts +0 -161
- package/dist/scp/write-plan.d.ts.map +0 -1
- package/dist/scp/write-plan.js +0 -528
- package/dist/scp/write-plan.js.map +0 -1
- package/dist/scp/write-runtime.d.ts +0 -80
- package/dist/scp/write-runtime.d.ts.map +0 -1
- package/dist/scp/write-runtime.js +0 -167
- package/dist/scp/write-runtime.js.map +0 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* litedbmodel v2 SCP — CRUD compile → `makeSQL` bundles, by driving the ORIGINAL
|
|
3
|
+
* dialect SQL builders (`postgresSqlBuilder` / `mysqlSqlBuilder` / `sqliteSqlBuilder`)
|
|
4
|
+
* and the original single-row UPDATE/DELETE text. The produced `{ sql, params }` is
|
|
5
|
+
* byte-identical to what the original library sends, for every dialect and every
|
|
6
|
+
* shape:
|
|
7
|
+
*
|
|
8
|
+
* INSERT single (+per-col `?::sqlCast` on PG) & batch (PG UNNEST + type inference /
|
|
9
|
+
* MySQL·SQLite multi-VALUES) + ON CONFLICT (DO NOTHING / DO UPDATE incl. `= 'all'`
|
|
10
|
+
* → all columns) + RETURNING (bare / `t.col` alias / `table.col` / MySQL simulate);
|
|
11
|
+
* UPDATE single (`SET c = ?::sqlCast`) & batch (PG UNNEST / MySQL JOIN-VALUES /
|
|
12
|
+
* SQLite CASE-WHEN) + SKIP-column; DELETE; and the SELECT tail (LIMIT/OFFSET inline,
|
|
13
|
+
* FOR UPDATE, GROUP BY/HAVING) via `buildSelectSQL`.
|
|
14
|
+
*
|
|
15
|
+
* These delegate to the SAME builders the runtime uses, so parity is by construction.
|
|
16
|
+
*/
|
|
17
|
+
import type { SqlBuilder, InsertBuildOptions, UpdateManyBuildOptions } from '../../drivers/types';
|
|
18
|
+
import type { ConditionObject } from '../../DBConditions';
|
|
19
|
+
import type { MakeSQL } from './makesql';
|
|
20
|
+
import type { Dialect } from './handler';
|
|
21
|
+
/** The original dialect builder for a dialect (the exact object the runtime uses). */
|
|
22
|
+
export declare function builderFor(dialect: Dialect): SqlBuilder;
|
|
23
|
+
/**
|
|
24
|
+
* Compile INSERT (single or batch) to a `makeSQL` bundle via the original
|
|
25
|
+
* `buildInsert`. Single-row on PG carries per-col `?::sqlCast`; batch on PG uses UNNEST
|
|
26
|
+
* with type inference; MySQL/SQLite use multi-VALUES. ON CONFLICT / RETURNING are the
|
|
27
|
+
* original's exact verbs. `onConflictUpdate: 'all'` expands to every column (the
|
|
28
|
+
* builder's fallback), so an empty DO-UPDATE never breaks.
|
|
29
|
+
*/
|
|
30
|
+
export declare function compileInsert(dialect: Dialect, options: InsertBuildOptions): MakeSQL;
|
|
31
|
+
/**
|
|
32
|
+
* Options for a heterogeneous `createMany`, mirroring the inputs `DBModel._insert` has
|
|
33
|
+
* AFTER serialization: the serialized `records`, their paired `rawRecords`, the shared
|
|
34
|
+
* `sqlCastMap` / ON CONFLICT / RETURNING. The per-group `columns` are DERIVED here (not
|
|
35
|
+
* supplied) — this is the whole point of the grouping.
|
|
36
|
+
*/
|
|
37
|
+
export interface InsertManyBuildOptions {
|
|
38
|
+
tableName: string;
|
|
39
|
+
/** Serialized records (as `DBModel._insert` holds them after `serializeRecord`). */
|
|
40
|
+
records: Record<string, unknown>[];
|
|
41
|
+
/** Raw records before serialization, paired 1:1 with `records` (PG UNNEST path). */
|
|
42
|
+
rawRecords?: Record<string, unknown>[];
|
|
43
|
+
sqlCastMap?: Map<string, string>;
|
|
44
|
+
onConflict?: string[];
|
|
45
|
+
onConflictIgnore?: boolean;
|
|
46
|
+
onConflictUpdate?: 'all' | string[];
|
|
47
|
+
returning?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Compile a (possibly heterogeneous) `createMany` into a COMPOSITION of `makeSQL`
|
|
51
|
+
* INSERT components — one per column-set group, exactly as `DBModel._insert`
|
|
52
|
+
* (`src/DBModel.ts:928-1020`) groups records and emits one `buildInsert` per group.
|
|
53
|
+
*
|
|
54
|
+
* A `createMany` whose rows carry DIFFERENT column subsets is not one INSERT: the
|
|
55
|
+
* production write path groups rows by their sorted-column-set pattern
|
|
56
|
+
* (`patternKey = recordColumns.sort().join(',')`) so each batch INSERT is homogeneous
|
|
57
|
+
* (no DEFAULT keyword), and emits ONE statement per group. In the `makeSQL` model that
|
|
58
|
+
* is precisely a composition of several INSERT components — no new vocabulary. This
|
|
59
|
+
* function reproduces that grouping byte-for-byte:
|
|
60
|
+
*
|
|
61
|
+
* - column detection per row drops `undefined` and DEFAULT immediates, exactly as
|
|
62
|
+
* `_insert:940-946 / 958-964`;
|
|
63
|
+
* - columns are CANONICAL sorted (`recordColumns.sort()`), the pattern key is the
|
|
64
|
+
* joined sorted columns, group order is first-seen insertion order (`Map`), and each
|
|
65
|
+
* group carries its serialized + raw records paired — mirroring `_insert:955-975`;
|
|
66
|
+
* - each group's SQL text comes from the SAME original `buildInsert` (`compileInsert`),
|
|
67
|
+
* so every component is byte-identical to the statement `_insert` sends for that
|
|
68
|
+
* group.
|
|
69
|
+
*
|
|
70
|
+
* The composition of the returned components (via `composeMakeSQL`) is the full
|
|
71
|
+
* multi-statement `createMany` the production path executes.
|
|
72
|
+
*/
|
|
73
|
+
export declare function compileInsertMany(dialect: Dialect, options: InsertManyBuildOptions): MakeSQL[];
|
|
74
|
+
/**
|
|
75
|
+
* Compile batch UPDATE to a `makeSQL` bundle via the original `buildUpdateMany`: PG
|
|
76
|
+
* UNNEST (`SET c = v.c FROM UNNEST(?::t[],…) AS v(cols) WHERE t.k = v.k`), MySQL
|
|
77
|
+
* JOIN-VALUES (`JOIN (VALUES ROW(…)) AS v(…) ON … SET …`), SQLite CASE-WHEN
|
|
78
|
+
* (`SET c = CASE WHEN k = ? THEN ? … END … WHERE k IN (…)`), with SKIP-column handling
|
|
79
|
+
* (PG `CASE WHEN v._skip_c` / MySQL `IF(v._skip_c,…)` / SQLite `WHEN … THEN t.col`).
|
|
80
|
+
*/
|
|
81
|
+
export declare function compileUpdateMany(dialect: Dialect, options: UpdateManyBuildOptions): MakeSQL;
|
|
82
|
+
/**
|
|
83
|
+
* Compile a single-row UPDATE to a `makeSQL` bundle, reproducing the original
|
|
84
|
+
* `DBModel._update` text byte-for-byte: `UPDATE <t> SET <c = ?[::cast] | token>, … WHERE
|
|
85
|
+
* <cond>[ RETURNING …]`. `serializedValues` is the already-serialized value map
|
|
86
|
+
* (DBToken values compile via their own `.compile`, matching the original), and
|
|
87
|
+
* `sqlCastMap` drives the per-column `?::sqlCast` on PG (skipping timestamp/date, as
|
|
88
|
+
* the original does). Throws `UPDATE requires conditions` when the WHERE is empty
|
|
89
|
+
* (v1 anchor: WHERE mandatory).
|
|
90
|
+
*/
|
|
91
|
+
export declare function compileUpdateSingle(opts: {
|
|
92
|
+
dialect: Dialect;
|
|
93
|
+
tableName: string;
|
|
94
|
+
serializedValues: Record<string, unknown>;
|
|
95
|
+
conditions: ConditionObject;
|
|
96
|
+
sqlCastMap?: Map<string, string>;
|
|
97
|
+
returning?: string;
|
|
98
|
+
}): MakeSQL;
|
|
99
|
+
/**
|
|
100
|
+
* Compile DELETE to a `makeSQL` bundle, reproducing the original `DBModel._delete`
|
|
101
|
+
* text: `DELETE FROM <t> WHERE <cond>[ RETURNING …]`. Throws `DELETE requires
|
|
102
|
+
* conditions` when the WHERE is empty (v1 anchor: WHERE mandatory — the .rs "delete
|
|
103
|
+
* everything" behavior is NOT reproduced).
|
|
104
|
+
*/
|
|
105
|
+
export declare function compileDelete(opts: {
|
|
106
|
+
dialect: Dialect;
|
|
107
|
+
tableName: string;
|
|
108
|
+
conditions: ConditionObject;
|
|
109
|
+
returning?: string;
|
|
110
|
+
}): MakeSQL;
|
|
111
|
+
/**
|
|
112
|
+
* Compile a `deleteMany` — delete the rows whose primary key is in a given SET of key values — as a
|
|
113
|
+
* COMPOSITION of `makeSQL` DELETE components (one per PK column-set group, mirroring the createMany
|
|
114
|
+
* grouping contract). A single-column PK reduces to ONE DELETE with the v1 IN-list condition
|
|
115
|
+
* (`{ pk: [values] }` → PG `= ANY` / MySQL·SQLite JSON-subquery via `conditionsFor`); a COMPOSITE PK
|
|
116
|
+
* groups the key-tuples by their present key set and emits ONE DELETE per group whose WHERE is the
|
|
117
|
+
* v1 conjunction of per-column IN-lists (each group homogeneous). Every group's WHERE text comes
|
|
118
|
+
* from the SAME original `DBConditions`/`conditionsFor` builder ({@link compileDelete}) — NEVER a
|
|
119
|
+
* hand-roll — so the deleteMany SQL is byte-identical to what the v1 condition path emits.
|
|
120
|
+
*
|
|
121
|
+
* The returned components compose (via the batch tx plan) into the full multi-statement `deleteMany`
|
|
122
|
+
* the production path would execute. An empty key set yields NO components (nothing to delete).
|
|
123
|
+
*/
|
|
124
|
+
export declare function compileDeleteMany(opts: {
|
|
125
|
+
dialect: Dialect;
|
|
126
|
+
tableName: string;
|
|
127
|
+
/** The PK column names (single or composite). */
|
|
128
|
+
keyColumns: string[];
|
|
129
|
+
/** The key-tuples to delete: each row maps every PK column → its value. */
|
|
130
|
+
keys: Record<string, unknown>[];
|
|
131
|
+
returning?: string;
|
|
132
|
+
}): MakeSQL[];
|
|
133
|
+
//# sourceMappingURL=compile-crud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-crud.d.ts","sourceRoot":"","sources":["../../../src/scp/makesql/compile-crud.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CASvD;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAGpF;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACnC,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,EAAE,CAwE9F;AAMD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAoB5F;AAMD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CA2BV;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CASV;AAOD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,EAAE,CA8BZ"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* litedbmodel v2 SCP — CRUD compile → `makeSQL` bundles, by driving the ORIGINAL
|
|
4
|
+
* dialect SQL builders (`postgresSqlBuilder` / `mysqlSqlBuilder` / `sqliteSqlBuilder`)
|
|
5
|
+
* and the original single-row UPDATE/DELETE text. The produced `{ sql, params }` is
|
|
6
|
+
* byte-identical to what the original library sends, for every dialect and every
|
|
7
|
+
* shape:
|
|
8
|
+
*
|
|
9
|
+
* INSERT single (+per-col `?::sqlCast` on PG) & batch (PG UNNEST + type inference /
|
|
10
|
+
* MySQL·SQLite multi-VALUES) + ON CONFLICT (DO NOTHING / DO UPDATE incl. `= 'all'`
|
|
11
|
+
* → all columns) + RETURNING (bare / `t.col` alias / `table.col` / MySQL simulate);
|
|
12
|
+
* UPDATE single (`SET c = ?::sqlCast`) & batch (PG UNNEST / MySQL JOIN-VALUES /
|
|
13
|
+
* SQLite CASE-WHEN) + SKIP-column; DELETE; and the SELECT tail (LIMIT/OFFSET inline,
|
|
14
|
+
* FOR UPDATE, GROUP BY/HAVING) via `buildSelectSQL`.
|
|
15
|
+
*
|
|
16
|
+
* These delegate to the SAME builders the runtime uses, so parity is by construction.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.builderFor = builderFor;
|
|
20
|
+
exports.compileInsert = compileInsert;
|
|
21
|
+
exports.compileInsertMany = compileInsertMany;
|
|
22
|
+
exports.compileUpdateMany = compileUpdateMany;
|
|
23
|
+
exports.compileUpdateSingle = compileUpdateSingle;
|
|
24
|
+
exports.compileDelete = compileDelete;
|
|
25
|
+
exports.compileDeleteMany = compileDeleteMany;
|
|
26
|
+
const PostgresSqlBuilder_1 = require("../../drivers/PostgresSqlBuilder");
|
|
27
|
+
const MysqlSqlBuilder_1 = require("../../drivers/MysqlSqlBuilder");
|
|
28
|
+
const SqliteSqlBuilder_1 = require("../../drivers/SqliteSqlBuilder");
|
|
29
|
+
const DBValues_1 = require("../../DBValues");
|
|
30
|
+
const compile_1 = require("./compile");
|
|
31
|
+
const json_array_1 = require("./json-array");
|
|
32
|
+
const json_batch_1 = require("./json-batch");
|
|
33
|
+
/** The original dialect builder for a dialect (the exact object the runtime uses). */
|
|
34
|
+
function builderFor(dialect) {
|
|
35
|
+
switch (dialect) {
|
|
36
|
+
case 'postgres':
|
|
37
|
+
return PostgresSqlBuilder_1.postgresSqlBuilder;
|
|
38
|
+
case 'mysql':
|
|
39
|
+
return MysqlSqlBuilder_1.mysqlSqlBuilder;
|
|
40
|
+
case 'sqlite':
|
|
41
|
+
return SqliteSqlBuilder_1.sqliteSqlBuilder;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// INSERT (single & batch) — driven by the original `buildInsert`.
|
|
46
|
+
// ============================================================================
|
|
47
|
+
/**
|
|
48
|
+
* Compile INSERT (single or batch) to a `makeSQL` bundle via the original
|
|
49
|
+
* `buildInsert`. Single-row on PG carries per-col `?::sqlCast`; batch on PG uses UNNEST
|
|
50
|
+
* with type inference; MySQL/SQLite use multi-VALUES. ON CONFLICT / RETURNING are the
|
|
51
|
+
* original's exact verbs. `onConflictUpdate: 'all'` expands to every column (the
|
|
52
|
+
* builder's fallback), so an empty DO-UPDATE never breaks.
|
|
53
|
+
*/
|
|
54
|
+
function compileInsert(dialect, options) {
|
|
55
|
+
const { sql, params } = builderFor(dialect).buildInsert(options);
|
|
56
|
+
return { sql, params };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Compile a (possibly heterogeneous) `createMany` into a COMPOSITION of `makeSQL`
|
|
60
|
+
* INSERT components — one per column-set group, exactly as `DBModel._insert`
|
|
61
|
+
* (`src/DBModel.ts:928-1020`) groups records and emits one `buildInsert` per group.
|
|
62
|
+
*
|
|
63
|
+
* A `createMany` whose rows carry DIFFERENT column subsets is not one INSERT: the
|
|
64
|
+
* production write path groups rows by their sorted-column-set pattern
|
|
65
|
+
* (`patternKey = recordColumns.sort().join(',')`) so each batch INSERT is homogeneous
|
|
66
|
+
* (no DEFAULT keyword), and emits ONE statement per group. In the `makeSQL` model that
|
|
67
|
+
* is precisely a composition of several INSERT components — no new vocabulary. This
|
|
68
|
+
* function reproduces that grouping byte-for-byte:
|
|
69
|
+
*
|
|
70
|
+
* - column detection per row drops `undefined` and DEFAULT immediates, exactly as
|
|
71
|
+
* `_insert:940-946 / 958-964`;
|
|
72
|
+
* - columns are CANONICAL sorted (`recordColumns.sort()`), the pattern key is the
|
|
73
|
+
* joined sorted columns, group order is first-seen insertion order (`Map`), and each
|
|
74
|
+
* group carries its serialized + raw records paired — mirroring `_insert:955-975`;
|
|
75
|
+
* - each group's SQL text comes from the SAME original `buildInsert` (`compileInsert`),
|
|
76
|
+
* so every component is byte-identical to the statement `_insert` sends for that
|
|
77
|
+
* group.
|
|
78
|
+
*
|
|
79
|
+
* The composition of the returned components (via `composeMakeSQL`) is the full
|
|
80
|
+
* multi-statement `createMany` the production path executes.
|
|
81
|
+
*/
|
|
82
|
+
function compileInsertMany(dialect, options) {
|
|
83
|
+
const { records, rawRecords, tableName, sqlCastMap, onConflict, onConflictIgnore, onConflictUpdate, returning } = options;
|
|
84
|
+
// Group records by their sorted-column-set pattern — mirrors DBModel._insert:928-975
|
|
85
|
+
// exactly (fast single-record path + multi-record Map grouping, same DEFAULT/undefined
|
|
86
|
+
// filtering, same canonical sort, same first-seen group order, same raw/serialized pair).
|
|
87
|
+
const grouped = new Map();
|
|
88
|
+
if (records.length === 1) {
|
|
89
|
+
const record = records[0];
|
|
90
|
+
const recordColumns = [];
|
|
91
|
+
for (const key of Object.keys(record)) {
|
|
92
|
+
const val = record[key];
|
|
93
|
+
if (val !== undefined && !(val instanceof DBValues_1.DBImmediateValue && val.value === 'DEFAULT')) {
|
|
94
|
+
recordColumns.push(key);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
recordColumns.sort();
|
|
98
|
+
grouped.set('_', { columns: recordColumns, records: [record], rawRecords: [rawRecords ? rawRecords[0] : record] });
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
for (let i = 0; i < records.length; i++) {
|
|
102
|
+
const record = records[i];
|
|
103
|
+
const recordColumns = [];
|
|
104
|
+
for (const key of Object.keys(record)) {
|
|
105
|
+
const val = record[key];
|
|
106
|
+
if (val !== undefined && !(val instanceof DBValues_1.DBImmediateValue && val.value === 'DEFAULT')) {
|
|
107
|
+
recordColumns.push(key);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
recordColumns.sort();
|
|
111
|
+
const patternKey = recordColumns.join(',');
|
|
112
|
+
if (!grouped.has(patternKey)) {
|
|
113
|
+
grouped.set(patternKey, { columns: recordColumns, records: [], rawRecords: [] });
|
|
114
|
+
}
|
|
115
|
+
const group = grouped.get(patternKey);
|
|
116
|
+
group.records.push(record);
|
|
117
|
+
group.rawRecords.push(rawRecords ? rawRecords[i] : record);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// One makeSQL INSERT component per group.
|
|
121
|
+
//
|
|
122
|
+
// - PostgreSQL: UNCHANGED — the original `buildInsert` (UNNEST batch, byte-identical).
|
|
123
|
+
// - MySQL/SQLite: the single-JSON-param form (JSON_TABLE / json_each), UNLESS the
|
|
124
|
+
// group carries a DBToken value (e.g. `NOW()`) which can't be JSON-encoded — then it
|
|
125
|
+
// falls back to the original `buildInsert` multi-VALUES for that group (correctness).
|
|
126
|
+
const components = [];
|
|
127
|
+
for (const { columns, records: groupRecords, rawRecords: groupRawRecords } of grouped.values()) {
|
|
128
|
+
if (dialect !== 'postgres' && !(0, json_batch_1.rowsHaveDbToken)(groupRecords, columns)) {
|
|
129
|
+
const jsonOpts = { tableName, columns, records: groupRecords, onConflict, onConflictIgnore, onConflictUpdate, returning };
|
|
130
|
+
components.push(dialect === 'mysql' ? (0, json_batch_1.mysqlInsertJson)(jsonOpts) : (0, json_batch_1.sqliteInsertJson)(jsonOpts));
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
components.push(compileInsert(dialect, {
|
|
134
|
+
tableName,
|
|
135
|
+
columns,
|
|
136
|
+
records: groupRecords,
|
|
137
|
+
rawRecords: groupRawRecords,
|
|
138
|
+
sqlCastMap,
|
|
139
|
+
onConflict,
|
|
140
|
+
onConflictIgnore,
|
|
141
|
+
onConflictUpdate,
|
|
142
|
+
returning,
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
return components;
|
|
146
|
+
}
|
|
147
|
+
// ============================================================================
|
|
148
|
+
// UPDATE batch — driven by the original `buildUpdateMany`.
|
|
149
|
+
// ============================================================================
|
|
150
|
+
/**
|
|
151
|
+
* Compile batch UPDATE to a `makeSQL` bundle via the original `buildUpdateMany`: PG
|
|
152
|
+
* UNNEST (`SET c = v.c FROM UNNEST(?::t[],…) AS v(cols) WHERE t.k = v.k`), MySQL
|
|
153
|
+
* JOIN-VALUES (`JOIN (VALUES ROW(…)) AS v(…) ON … SET …`), SQLite CASE-WHEN
|
|
154
|
+
* (`SET c = CASE WHEN k = ? THEN ? … END … WHERE k IN (…)`), with SKIP-column handling
|
|
155
|
+
* (PG `CASE WHEN v._skip_c` / MySQL `IF(v._skip_c,…)` / SQLite `WHEN … THEN t.col`).
|
|
156
|
+
*/
|
|
157
|
+
function compileUpdateMany(dialect, options) {
|
|
158
|
+
// PostgreSQL: UNCHANGED (UNNEST). MySQL/SQLite: single-JSON-param form (JSON_TABLE
|
|
159
|
+
// join / CASE-over-json_each) with SKIP preserved — unless a DBToken value is present
|
|
160
|
+
// (can't be JSON-encoded), in which case fall back to the original builder.
|
|
161
|
+
if (dialect !== 'postgres') {
|
|
162
|
+
const allCols = [...options.keyColumns, ...options.updateColumns];
|
|
163
|
+
if (!(0, json_batch_1.rowsHaveDbToken)(options.records, allCols)) {
|
|
164
|
+
const jsonOpts = {
|
|
165
|
+
tableName: options.tableName,
|
|
166
|
+
keyColumns: options.keyColumns,
|
|
167
|
+
updateColumns: options.updateColumns,
|
|
168
|
+
records: options.records,
|
|
169
|
+
skipMap: options.skipMap,
|
|
170
|
+
returning: options.returning,
|
|
171
|
+
};
|
|
172
|
+
return dialect === 'mysql' ? (0, json_batch_1.mysqlUpdateManyJson)(jsonOpts) : (0, json_batch_1.sqliteUpdateManyJson)(jsonOpts);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const { sql, params } = builderFor(dialect).buildUpdateMany(options);
|
|
176
|
+
return { sql, params };
|
|
177
|
+
}
|
|
178
|
+
// ============================================================================
|
|
179
|
+
// UPDATE single — reproduces the ORIGINAL `_update` SET-clause + WHERE text exactly.
|
|
180
|
+
// ============================================================================
|
|
181
|
+
/**
|
|
182
|
+
* Compile a single-row UPDATE to a `makeSQL` bundle, reproducing the original
|
|
183
|
+
* `DBModel._update` text byte-for-byte: `UPDATE <t> SET <c = ?[::cast] | token>, … WHERE
|
|
184
|
+
* <cond>[ RETURNING …]`. `serializedValues` is the already-serialized value map
|
|
185
|
+
* (DBToken values compile via their own `.compile`, matching the original), and
|
|
186
|
+
* `sqlCastMap` drives the per-column `?::sqlCast` on PG (skipping timestamp/date, as
|
|
187
|
+
* the original does). Throws `UPDATE requires conditions` when the WHERE is empty
|
|
188
|
+
* (v1 anchor: WHERE mandatory).
|
|
189
|
+
*/
|
|
190
|
+
function compileUpdateSingle(opts) {
|
|
191
|
+
const params = [];
|
|
192
|
+
const formatter = opts.dialect === 'postgres' ? (0, compile_1.formatterFor)(opts.dialect) : undefined;
|
|
193
|
+
const sqlCastMap = opts.sqlCastMap ?? new Map();
|
|
194
|
+
const setClauses = [];
|
|
195
|
+
for (const [col, val] of Object.entries(opts.serializedValues)) {
|
|
196
|
+
if (val instanceof DBValues_1.DBToken) {
|
|
197
|
+
setClauses.push(`${col} = ${val.compile(params, undefined, formatter)}`);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
params.push(val);
|
|
201
|
+
const sqlCast = sqlCastMap.get(col);
|
|
202
|
+
if (sqlCast && formatter && sqlCast !== 'timestamp' && sqlCast !== 'date') {
|
|
203
|
+
setClauses.push(`${col} = ${formatter('?', sqlCast)}`);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
setClauses.push(`${col} = ?`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const whereClause = (0, json_array_1.conditionsFor)(opts.conditions, opts.dialect).compile(params, formatter);
|
|
211
|
+
if (!whereClause)
|
|
212
|
+
throw new Error('UPDATE requires conditions');
|
|
213
|
+
let sql = `UPDATE ${opts.tableName} SET ${setClauses.join(', ')} WHERE ${whereClause}`;
|
|
214
|
+
if (opts.returning)
|
|
215
|
+
sql += ` RETURNING ${opts.returning}`;
|
|
216
|
+
return { sql, params };
|
|
217
|
+
}
|
|
218
|
+
// ============================================================================
|
|
219
|
+
// DELETE single — reproduces the ORIGINAL `_delete` text exactly.
|
|
220
|
+
// ============================================================================
|
|
221
|
+
/**
|
|
222
|
+
* Compile DELETE to a `makeSQL` bundle, reproducing the original `DBModel._delete`
|
|
223
|
+
* text: `DELETE FROM <t> WHERE <cond>[ RETURNING …]`. Throws `DELETE requires
|
|
224
|
+
* conditions` when the WHERE is empty (v1 anchor: WHERE mandatory — the .rs "delete
|
|
225
|
+
* everything" behavior is NOT reproduced).
|
|
226
|
+
*/
|
|
227
|
+
function compileDelete(opts) {
|
|
228
|
+
const params = [];
|
|
229
|
+
const formatter = opts.dialect === 'postgres' ? (0, compile_1.formatterFor)(opts.dialect) : undefined;
|
|
230
|
+
const whereClause = (0, json_array_1.conditionsFor)(opts.conditions, opts.dialect).compile(params, formatter);
|
|
231
|
+
if (!whereClause)
|
|
232
|
+
throw new Error('DELETE requires conditions');
|
|
233
|
+
let sql = `DELETE FROM ${opts.tableName} WHERE ${whereClause}`;
|
|
234
|
+
if (opts.returning)
|
|
235
|
+
sql += ` RETURNING ${opts.returning}`;
|
|
236
|
+
return { sql, params };
|
|
237
|
+
}
|
|
238
|
+
// ============================================================================
|
|
239
|
+
// DELETE batch (deleteMany) — a single DELETE keyed by a PK-set IN-list, driven
|
|
240
|
+
// by the ORIGINAL v1 condition builder (compileDelete → DBConditions/conditionsFor).
|
|
241
|
+
// ============================================================================
|
|
242
|
+
/**
|
|
243
|
+
* Compile a `deleteMany` — delete the rows whose primary key is in a given SET of key values — as a
|
|
244
|
+
* COMPOSITION of `makeSQL` DELETE components (one per PK column-set group, mirroring the createMany
|
|
245
|
+
* grouping contract). A single-column PK reduces to ONE DELETE with the v1 IN-list condition
|
|
246
|
+
* (`{ pk: [values] }` → PG `= ANY` / MySQL·SQLite JSON-subquery via `conditionsFor`); a COMPOSITE PK
|
|
247
|
+
* groups the key-tuples by their present key set and emits ONE DELETE per group whose WHERE is the
|
|
248
|
+
* v1 conjunction of per-column IN-lists (each group homogeneous). Every group's WHERE text comes
|
|
249
|
+
* from the SAME original `DBConditions`/`conditionsFor` builder ({@link compileDelete}) — NEVER a
|
|
250
|
+
* hand-roll — so the deleteMany SQL is byte-identical to what the v1 condition path emits.
|
|
251
|
+
*
|
|
252
|
+
* The returned components compose (via the batch tx plan) into the full multi-statement `deleteMany`
|
|
253
|
+
* the production path would execute. An empty key set yields NO components (nothing to delete).
|
|
254
|
+
*/
|
|
255
|
+
function compileDeleteMany(opts) {
|
|
256
|
+
const { dialect, tableName, keyColumns, keys, returning } = opts;
|
|
257
|
+
if (keyColumns.length === 0)
|
|
258
|
+
throw new Error('compileDeleteMany: keyColumns must be non-empty');
|
|
259
|
+
if (keys.length === 0)
|
|
260
|
+
return [];
|
|
261
|
+
if (keyColumns.length === 1) {
|
|
262
|
+
// Single PK → ONE DELETE with a v1 IN-list condition (`{ pk: [values] }`).
|
|
263
|
+
const col = keyColumns[0];
|
|
264
|
+
const values = keys.map((k) => k[col]);
|
|
265
|
+
const conditions = { [col]: values };
|
|
266
|
+
return [compileDelete({ dialect, tableName, conditions, returning })];
|
|
267
|
+
}
|
|
268
|
+
// Composite PK → group key-tuples by their present-column set (mirrors createMany grouping), one
|
|
269
|
+
// DELETE per group whose WHERE is the v1 conjunction of per-column IN-lists (each group homogeneous).
|
|
270
|
+
const grouped = new Map();
|
|
271
|
+
for (const key of keys) {
|
|
272
|
+
const present = keyColumns.filter((c) => key[c] !== undefined).sort();
|
|
273
|
+
const patternKey = present.join(',');
|
|
274
|
+
if (!grouped.has(patternKey))
|
|
275
|
+
grouped.set(patternKey, []);
|
|
276
|
+
grouped.get(patternKey).push(key);
|
|
277
|
+
}
|
|
278
|
+
const components = [];
|
|
279
|
+
for (const group of grouped.values()) {
|
|
280
|
+
const present = keyColumns.filter((c) => group[0][c] !== undefined);
|
|
281
|
+
const conditions = {};
|
|
282
|
+
for (const c of present)
|
|
283
|
+
conditions[c] = group.map((k) => k[c]);
|
|
284
|
+
components.push(compileDelete({ dialect, tableName, conditions, returning }));
|
|
285
|
+
}
|
|
286
|
+
return components;
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=compile-crud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-crud.js","sourceRoot":"","sources":["../../../src/scp/makesql/compile-crud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* litedbmodel v2 SCP — RELATION batch-load compile → `makeSQL`, reproducing the
|
|
3
|
+
* ORIGINAL `LazyRelation` SQL text byte-for-byte across all shapes and dialects:
|
|
4
|
+
*
|
|
5
|
+
* single-key, unlimited:
|
|
6
|
+
* PG `SELECT … FROM t WHERE t.key = ANY(?::type[])[ AND <filters>][ ORDER BY …]`
|
|
7
|
+
* MySQL/SQLite `SELECT … FROM t WHERE t.key IN (?, …)[ AND <filters>][ ORDER BY …]`
|
|
8
|
+
* single-key, per-parent limit:
|
|
9
|
+
* PG `SELECT t.* FROM unnest(?::type[]) AS _keys(key) CROSS JOIN LATERAL
|
|
10
|
+
* (SELECT * FROM t WHERE t.key = _keys.key[ AND <filters>] ORDER BY … LIMIT n) t`
|
|
11
|
+
* MySQL/SQLite `WITH ranked AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY key ORDER BY …) AS _rn
|
|
12
|
+
* FROM t WHERE key IN (?, …)[ AND <filters>]) SELECT * FROM ranked WHERE _rn <= n`
|
|
13
|
+
* composite-key, unlimited:
|
|
14
|
+
* PG `SELECT … FROM t JOIN unnest(?::t1[], ?::t2[]) AS _u(a1, a2) ON t.k1=_u.a1 AND …`
|
|
15
|
+
* MySQL/SQLite `SELECT … FROM t WHERE (k1, k2) IN ((?, ?), …)`
|
|
16
|
+
* composite-key, per-parent limit: PG LATERAL composite / others ROW_NUMBER composite.
|
|
17
|
+
*
|
|
18
|
+
* The PG type text (`?::type[]`) comes from the ORIGINAL `inferPgArrayType` (sqlCast
|
|
19
|
+
* wins, else element-type inference). The .rs regressions are NOT reproduced: PG
|
|
20
|
+
* per-parent-limit is LATERAL (not ROW_NUMBER), and PG types are sqlCast-driven (not
|
|
21
|
+
* text-folded).
|
|
22
|
+
*
|
|
23
|
+
* Inner SELECTs reuse {@link compileSelect} — the same text `buildSelectSQL` yields —
|
|
24
|
+
* so the whole shape is byte-faithful to the original relation builder.
|
|
25
|
+
*/
|
|
26
|
+
import { type ConditionObject } from '../../DBConditions';
|
|
27
|
+
import type { MakeSQL } from './makesql';
|
|
28
|
+
import type { Dialect } from './handler';
|
|
29
|
+
/**
|
|
30
|
+
* Reproduce the ORIGINAL `LazyRelation.inferPgArrayType`: sqlCast wins (`<cast>[]`);
|
|
31
|
+
* otherwise infer the element type from the sample values. Byte-identical to the
|
|
32
|
+
* original (which is the PG anchor — NOT the .rs coarse text-folding).
|
|
33
|
+
*/
|
|
34
|
+
export declare function inferPgArrayType(values: unknown[], sqlCast?: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* The DEFERRED PG array-cast token (#46): a placeholder emitted in the STATIC SQL text where
|
|
37
|
+
* the `= ANY(?::<T>[])` / `UNNEST(?::<T>[])` element type `<T>` cannot be known at symbolic
|
|
38
|
+
* compile time (a schema-less `whereIn`, or a relation batch compiled without concrete keys).
|
|
39
|
+
* The render/handler layer resolves it from the BOUND values via {@link inferPgArrayType} — a
|
|
40
|
+
* mechanical dialect-render step, the same category as the `?`→`$N` placeholder render. This
|
|
41
|
+
* reproduces v1's live-PG-correct cast (`::int[]` for int keys, etc.), which v1 got because
|
|
42
|
+
* `inferPgArrayType` saw the real values at runtime.
|
|
43
|
+
*
|
|
44
|
+
* A byte sequence no legitimate SQL identifier/type text contains, so the resolve is a safe
|
|
45
|
+
* literal substring replace (never a regex over user text).
|
|
46
|
+
*/
|
|
47
|
+
export declare const PG_ARRAY_CAST_TOKEN = "@@PG_ARRAY_CAST@@";
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the FIRST unresolved {@link PG_ARRAY_CAST_TOKEN} in a PG SQL fragment to the element
|
|
50
|
+
* type inferred from the bound `values` (v1 `inferPgArrayType`). Called at render time, once per
|
|
51
|
+
* array param, left-to-right — so each deferred array cast binds the type of its own value set.
|
|
52
|
+
* SQL with no token is returned unchanged (every non-deferred cast is already concrete).
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolvePgArrayCast(sql: string, values: unknown[]): string;
|
|
55
|
+
export interface RelationCompileBase {
|
|
56
|
+
dialect: Dialect;
|
|
57
|
+
tableName: string;
|
|
58
|
+
/** SELECT column list (default `*`). */
|
|
59
|
+
select?: string;
|
|
60
|
+
/** Optional relation `where`-filter conditions (`config.conditions`), merged in. */
|
|
61
|
+
conditions?: ConditionObject;
|
|
62
|
+
/** ORDER BY clause (raw text), or undefined. */
|
|
63
|
+
order?: string;
|
|
64
|
+
/** Per-column sqlCast map (drives PG `?::type[]`). */
|
|
65
|
+
sqlCastMap?: Map<string, string>;
|
|
66
|
+
/**
|
|
67
|
+
* Emit the {@link PG_ARRAY_CAST_TOKEN} for the PG `?::<T>[]` element type instead of inferring
|
|
68
|
+
* it from `values` NOW (#46). Set when the SQL text is compiled SYMBOLICALLY (placeholder keys),
|
|
69
|
+
* so the element type is resolved at render from the REAL bound keys — never baked to `text[]`.
|
|
70
|
+
* A `sqlCast` (concrete column type) still wins over the token.
|
|
71
|
+
*/
|
|
72
|
+
deferPgArrayCast?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The STATIC composite-key batch forms (#47 item 1) — length-INDEPENDENT so the compiled `op.sql`
|
|
76
|
+
* is fixed (one param per column on PG; ONE JSON param on MySQL/SQLite), the SAME static-op
|
|
77
|
+
* property the single-key relation forms have. PG stays byte-identical to v1's `unnest`-JOIN
|
|
78
|
+
* (`batchLoadWithUnnestJoin`), with the element-type cast DEFERRED (#46) to render from the real
|
|
79
|
+
* keys. MySQL/SQLite use the single-JSON tuple form (the owner-approved deviation the single-key
|
|
80
|
+
* IN-list and the batch UPDATE composite already use — RESULT parity, NOT byte-identity): a
|
|
81
|
+
* `JSON_TABLE`/`json_each` subquery over one JSON array-of-tuples param. The v1 literal
|
|
82
|
+
* `(k1,k2) IN ((?,?),…)` byte-form stays proven by the golden `compileCompositeKeyUnlimited`.
|
|
83
|
+
*
|
|
84
|
+
* The JSON tuple param is `[[k1a,k2a],[k1b,k2b],…]` (positional element arrays), read back by
|
|
85
|
+
* ordinal path (`$[0]`, `$[1]`, …) so no per-column JSON key names are needed.
|
|
86
|
+
*/
|
|
87
|
+
export declare function compileCompositeKeyStaticUnlimited(opts: RelationCompileBase & {
|
|
88
|
+
targetKeys: string[];
|
|
89
|
+
}): MakeSQL;
|
|
90
|
+
/**
|
|
91
|
+
* `= ANY(?::type[])` (PG) / `IN (?, …)` (MySQL/SQLite) single-key unlimited batch load.
|
|
92
|
+
* Reproduces `batchLoadWithAnyArray` (PG) and `batchLoadWithIn` (others).
|
|
93
|
+
*
|
|
94
|
+
* The key array binds as ONE param on PG (`values` is a single array param); on
|
|
95
|
+
* MySQL/SQLite the original passes the array to `DBConditions` which expands it to
|
|
96
|
+
* `IN (?, ?, …)` with one param per element — reproduced here verbatim.
|
|
97
|
+
*/
|
|
98
|
+
export declare function compileSingleKeyUnlimited(opts: RelationCompileBase & {
|
|
99
|
+
targetKey: string;
|
|
100
|
+
values: unknown[];
|
|
101
|
+
}): MakeSQL;
|
|
102
|
+
/**
|
|
103
|
+
* Per-parent-limit single-key batch load: PG `CROSS JOIN LATERAL` (the v1 anchor —
|
|
104
|
+
* NOT the .rs ROW_NUMBER regression); MySQL/SQLite `ROW_NUMBER() OVER (PARTITION BY …)`.
|
|
105
|
+
* Reproduces `batchLoadWithLateral` / `batchLoadWithRowNumber`.
|
|
106
|
+
*/
|
|
107
|
+
export declare function compileSingleKeyLimited(opts: RelationCompileBase & {
|
|
108
|
+
targetKey: string;
|
|
109
|
+
values: unknown[];
|
|
110
|
+
limit: number;
|
|
111
|
+
}): MakeSQL;
|
|
112
|
+
/**
|
|
113
|
+
* Composite-key unlimited batch load: PG `JOIN unnest(?::t1[], ?::t2[]) AS _u(a,b) ON …`
|
|
114
|
+
* (reproduces `batchLoadWithUnnestJoin`); MySQL/SQLite `(k1, k2) IN ((?, ?), …)`
|
|
115
|
+
* (reproduces `batchLoadWithCompositeIn` via `DBTupleIn`).
|
|
116
|
+
*/
|
|
117
|
+
export declare function compileCompositeKeyUnlimited(opts: RelationCompileBase & {
|
|
118
|
+
targetKeys: string[];
|
|
119
|
+
tuples: unknown[][];
|
|
120
|
+
}): MakeSQL;
|
|
121
|
+
/**
|
|
122
|
+
* Composite-key per-parent-limit: PG LATERAL composite (reproduces
|
|
123
|
+
* `batchLoadWithLateralComposite`); MySQL/SQLite ROW_NUMBER composite (reproduces
|
|
124
|
+
* `batchLoadWithRowNumberComposite`).
|
|
125
|
+
*/
|
|
126
|
+
export declare function compileCompositeKeyLimited(opts: RelationCompileBase & {
|
|
127
|
+
targetKeys: string[];
|
|
128
|
+
tuples: unknown[][];
|
|
129
|
+
limit: number;
|
|
130
|
+
}): MakeSQL;
|
|
131
|
+
/**
|
|
132
|
+
* The STATIC composite-key per-parent-LIMIT batch form (#47 last completeness gap) — the
|
|
133
|
+
* length-INDEPENDENT sibling of {@link compileCompositeKeyLimited}, so the compiled `op.sql` is
|
|
134
|
+
* FIXED (one array param per key column on PG; ONE JSON array-of-tuples param on MySQL/SQLite) and
|
|
135
|
+
* can be a STATIC bundle op — exactly the property {@link compileSingleKeyLimited} and
|
|
136
|
+
* {@link compileCompositeKeyStaticUnlimited} already have.
|
|
137
|
+
*
|
|
138
|
+
* The per-parent window is IDENTICAL to the single-key-limited path:
|
|
139
|
+
* - **PG**: `CROSS JOIN LATERAL` over `unnest(?::t1[], ?::t2[])` — BYTE-identical to v1's
|
|
140
|
+
* `batchLoadWithLateralComposite` (the composite LATERAL is already structurally
|
|
141
|
+
* length-independent; only the element-type cast was value-derived, and that is DEFERRED (#46)
|
|
142
|
+
* to render from the real keys via {@link PG_ARRAY_CAST_TOKEN}). No deviation on PG.
|
|
143
|
+
* - **MySQL/SQLite**: the SAME `ROW_NUMBER() OVER (PARTITION BY <keys> ORDER BY <order>)` CTE +
|
|
144
|
+
* `_rn <= limit` filter v1's `batchLoadWithRowNumberComposite` emits — but the CTE membership
|
|
145
|
+
* WHERE is the STATIC JSON-tuple predicate ({@link compositeJsonMembership}) instead of v1's
|
|
146
|
+
* value-dependent `(k1,k2) IN ((?,?),…)`. This is the owner-sanctioned static deviation the
|
|
147
|
+
* composite UNLIMITED form ({@link compileCompositeKeyStaticUnlimited}) and the single-key
|
|
148
|
+
* IN-list already use: the JSON subquery selects the SAME child rows the tuple-IN would, the
|
|
149
|
+
* window partitions/orders identically, so it is RESULT-parity to v1 (proven live). The v1
|
|
150
|
+
* literal `(k1,k2) IN ((?,?),…)` byte-form stays proven by the golden
|
|
151
|
+
* {@link compileCompositeKeyLimited}.
|
|
152
|
+
*/
|
|
153
|
+
export declare function compileCompositeKeyStaticLimited(opts: RelationCompileBase & {
|
|
154
|
+
targetKeys: string[];
|
|
155
|
+
limit: number;
|
|
156
|
+
}): MakeSQL;
|
|
157
|
+
//# sourceMappingURL=compile-relation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-relation.d.ts","sourceRoot":"","sources":["../../../src/scp/makesql/compile-relation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAY5E;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AAEvD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAIzE;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,mBAAmB,GAAG;IAAE,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GACnD,OAAO,CAmCT;AA4BD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,mBAAmB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,GACnE,OAAO,CAyBT;AAMD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,mBAAmB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClF,OAAO,CAoCT;AAWD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,mBAAmB,GAAG;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAA;CAAE,GACxE,OAAO,CAuCT;AAMD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,mBAAmB,GAAG;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACvF,OAAO,CA+CT;AAMD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,mBAAmB,GAAG;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClE,OAAO,CA6CT"}
|