@prisma-next/sql-orm-lane 0.3.0-pr.94.2 → 0.3.0-pr.95.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/chunk-C4EECZ4E.js +1723 -0
- package/dist/chunk-C4EECZ4E.js.map +1 -0
- package/dist/exports/orm.d.ts +3 -0
- package/dist/exports/orm.d.ts.map +1 -0
- package/dist/exports/orm.js +7 -0
- package/dist/exports/orm.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/mutations/delete-builder.d.ts +9 -0
- package/dist/mutations/delete-builder.d.ts.map +1 -0
- package/dist/mutations/insert-builder.d.ts +7 -0
- package/dist/mutations/insert-builder.d.ts.map +1 -0
- package/dist/mutations/update-builder.d.ts +9 -0
- package/dist/mutations/update-builder.d.ts.map +1 -0
- package/dist/orm/builder.d.ts +38 -0
- package/dist/orm/builder.d.ts.map +1 -0
- package/dist/orm/capabilities.d.ts +3 -0
- package/dist/orm/capabilities.d.ts.map +1 -0
- package/dist/orm/context.d.ts +5 -0
- package/dist/orm/context.d.ts.map +1 -0
- package/dist/orm/state.d.ts +45 -0
- package/dist/orm/state.d.ts.map +1 -0
- package/dist/orm-include-child.d.ts +35 -0
- package/dist/orm-include-child.d.ts.map +1 -0
- package/dist/orm-relation-filter.d.ts +19 -0
- package/dist/orm-relation-filter.d.ts.map +1 -0
- package/dist/orm-types.d.ts +86 -0
- package/dist/orm-types.d.ts.map +1 -0
- package/dist/orm.d.ts +5 -0
- package/dist/orm.d.ts.map +1 -0
- package/dist/plan/lowering.d.ts +2 -0
- package/dist/plan/lowering.d.ts.map +1 -0
- package/dist/plan/plan-assembly.d.ts +24 -0
- package/dist/plan/plan-assembly.d.ts.map +1 -0
- package/dist/plan/result-typing.d.ts +2 -0
- package/dist/plan/result-typing.d.ts.map +1 -0
- package/dist/relations/include-plan.d.ts +38 -0
- package/dist/relations/include-plan.d.ts.map +1 -0
- package/dist/selection/join.d.ts +3 -0
- package/dist/selection/join.d.ts.map +1 -0
- package/dist/selection/ordering.d.ts +11 -0
- package/dist/selection/ordering.d.ts.map +1 -0
- package/dist/selection/pagination.d.ts +6 -0
- package/dist/selection/pagination.d.ts.map +1 -0
- package/dist/selection/predicates.d.ts +10 -0
- package/dist/selection/predicates.d.ts.map +1 -0
- package/dist/selection/projection.d.ts +28 -0
- package/dist/selection/projection.d.ts.map +1 -0
- package/dist/selection/select-builder.d.ts +22 -0
- package/dist/selection/select-builder.d.ts.map +1 -0
- package/dist/types/internal.d.ts +4 -0
- package/dist/types/internal.d.ts.map +1 -0
- package/dist/utils/ast.d.ts +2 -0
- package/dist/utils/ast.d.ts.map +1 -0
- package/dist/utils/errors.d.ts +29 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/param-descriptor.d.ts +10 -0
- package/dist/utils/param-descriptor.d.ts.map +1 -0
- package/package.json +21 -23
- package/dist/exports/orm.d.mts +0 -2
- package/dist/exports/orm.mjs +0 -3
- package/dist/index.d.mts +0 -42
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -3
- package/dist/orm-BYJaTDLm.mjs +0 -1286
- package/dist/orm-BYJaTDLm.mjs.map +0 -1
- package/dist/orm-DxyXF2Wh.d.mts +0 -89
- package/dist/orm-DxyXF2Wh.d.mts.map +0 -1
package/dist/orm-BYJaTDLm.mjs
DELETED
|
@@ -1,1286 +0,0 @@
|
|
|
1
|
-
import { planInvalid } from "@prisma-next/plan";
|
|
2
|
-
import { schema } from "@prisma-next/sql-relational-core/schema";
|
|
3
|
-
import { augmentDescriptorWithColumnMeta } from "@prisma-next/sql-relational-core/plan";
|
|
4
|
-
import { collectColumnRefs, extractBaseColumnRef, getColumnMeta, isColumnBuilder, isExpressionBuilder, isOperationExpr, isParamPlaceholder } from "@prisma-next/sql-relational-core/utils/guards";
|
|
5
|
-
import { compact, createBinaryExpr, createColumnRef, createDeleteAst, createInsertAst, createJoinOnExpr, createOrderByItem, createParamRef, createSelectAst, createTableRef, createUpdateAst } from "@prisma-next/sql-relational-core/ast";
|
|
6
|
-
import { param } from "@prisma-next/sql-relational-core/param";
|
|
7
|
-
|
|
8
|
-
//#region src/utils/errors.ts
|
|
9
|
-
function errorModelNotFound(modelName) {
|
|
10
|
-
throw planInvalid(`Model ${modelName} not found in mappings`);
|
|
11
|
-
}
|
|
12
|
-
function errorTableNotFound(tableName) {
|
|
13
|
-
throw planInvalid(`Table ${tableName} not found in schema`);
|
|
14
|
-
}
|
|
15
|
-
function errorUnknownTable(tableName) {
|
|
16
|
-
throw planInvalid(`Unknown table ${tableName}`);
|
|
17
|
-
}
|
|
18
|
-
function errorUnknownColumn(columnName, tableName) {
|
|
19
|
-
throw planInvalid(`Unknown column ${columnName} in table ${tableName}`);
|
|
20
|
-
}
|
|
21
|
-
function errorMissingParameter(paramName) {
|
|
22
|
-
throw planInvalid(`Missing value for parameter ${paramName}`);
|
|
23
|
-
}
|
|
24
|
-
function errorAliasPathEmpty() {
|
|
25
|
-
throw planInvalid("Alias path cannot be empty");
|
|
26
|
-
}
|
|
27
|
-
function errorAliasCollision(path, alias, existingPath) {
|
|
28
|
-
throw planInvalid(`Alias collision: path ${path.join(".")} would generate alias "${alias}" which conflicts with path ${existingPath?.join(".") ?? "unknown"}`);
|
|
29
|
-
}
|
|
30
|
-
function errorInvalidProjectionValue(path) {
|
|
31
|
-
throw planInvalid(`Invalid projection value at path ${path.join(".")}: expected ColumnBuilder or nested object`);
|
|
32
|
-
}
|
|
33
|
-
function errorIncludeAliasNotFound(alias) {
|
|
34
|
-
throw planInvalid(`Include alias "${alias}" not found. Did you call includeMany() with alias "${alias}"?`);
|
|
35
|
-
}
|
|
36
|
-
function errorInvalidProjectionKey(key) {
|
|
37
|
-
throw planInvalid(`Invalid projection value at key "${key}": expected ColumnBuilder, boolean true (for includes), or nested object`);
|
|
38
|
-
}
|
|
39
|
-
function errorProjectionEmpty() {
|
|
40
|
-
throw planInvalid("select() requires at least one column or include");
|
|
41
|
-
}
|
|
42
|
-
function errorCreateRequiresFields() {
|
|
43
|
-
throw planInvalid("create() requires at least one field");
|
|
44
|
-
}
|
|
45
|
-
function errorUpdateRequiresFields() {
|
|
46
|
-
throw planInvalid("update() requires at least one field");
|
|
47
|
-
}
|
|
48
|
-
function errorIncludeRequiresCapabilities() {
|
|
49
|
-
throw planInvalid("includeMany requires lateral and jsonAgg capabilities");
|
|
50
|
-
}
|
|
51
|
-
function errorIncludeCapabilitiesNotTrue() {
|
|
52
|
-
throw planInvalid("includeMany requires lateral and jsonAgg capabilities to be true");
|
|
53
|
-
}
|
|
54
|
-
function errorMultiColumnJoinsNotSupported() {
|
|
55
|
-
throw planInvalid("Multi-column joins in includes are not yet supported");
|
|
56
|
-
}
|
|
57
|
-
function errorJoinColumnsMustBeDefined() {
|
|
58
|
-
throw planInvalid("Join columns must be defined");
|
|
59
|
-
}
|
|
60
|
-
function errorColumnNotFound(columnName, tableName) {
|
|
61
|
-
throw planInvalid(`Column ${columnName} not found in table ${tableName}`);
|
|
62
|
-
}
|
|
63
|
-
function errorChildProjectionMustBeSpecified() {
|
|
64
|
-
throw planInvalid("Child projection must be specified");
|
|
65
|
-
}
|
|
66
|
-
function errorChildProjectionEmpty() {
|
|
67
|
-
throw planInvalid("Child projection must not be empty after filtering boolean values");
|
|
68
|
-
}
|
|
69
|
-
function errorMissingAlias(index) {
|
|
70
|
-
throw planInvalid(`Missing alias at index ${index}`);
|
|
71
|
-
}
|
|
72
|
-
function errorMissingColumn(alias, index) {
|
|
73
|
-
throw planInvalid(`Missing column for alias "${alias}" at index ${index}`);
|
|
74
|
-
}
|
|
75
|
-
function errorInvalidColumn(alias, index) {
|
|
76
|
-
throw planInvalid(`Invalid column for alias "${alias}" at index ${index}`);
|
|
77
|
-
}
|
|
78
|
-
function errorFailedToBuildWhereClause() {
|
|
79
|
-
throw planInvalid("Failed to build WHERE clause");
|
|
80
|
-
}
|
|
81
|
-
function assertColumnExists(columnMeta, columnName, tableName) {
|
|
82
|
-
if (!columnMeta) errorUnknownColumn(columnName, tableName);
|
|
83
|
-
}
|
|
84
|
-
function assertParameterExists(paramsMap, paramName) {
|
|
85
|
-
if (!Object.hasOwn(paramsMap, paramName)) errorMissingParameter(paramName);
|
|
86
|
-
return paramsMap[paramName];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
//#endregion
|
|
90
|
-
//#region src/selection/predicates.ts
|
|
91
|
-
function buildWhereExpr(where, contract, paramsMap, descriptors, values) {
|
|
92
|
-
let leftExpr;
|
|
93
|
-
let codecId;
|
|
94
|
-
let rightExpr;
|
|
95
|
-
let paramName;
|
|
96
|
-
leftExpr = where.left;
|
|
97
|
-
if (leftExpr.kind === "col") {
|
|
98
|
-
const { table, column } = leftExpr;
|
|
99
|
-
const contractTable = contract.storage.tables[table];
|
|
100
|
-
if (!contractTable) errorUnknownTable(table);
|
|
101
|
-
const columnMeta = contractTable.columns[column];
|
|
102
|
-
if (columnMeta) codecId = columnMeta.codecId;
|
|
103
|
-
}
|
|
104
|
-
if (isParamPlaceholder(where.right)) {
|
|
105
|
-
paramName = where.right.name;
|
|
106
|
-
if (!Object.hasOwn(paramsMap, paramName)) errorMissingParameter(paramName);
|
|
107
|
-
const value = paramsMap[paramName];
|
|
108
|
-
const index = values.push(value);
|
|
109
|
-
if (leftExpr.kind === "col") {
|
|
110
|
-
const { table, column } = leftExpr;
|
|
111
|
-
const columnMeta = contract.storage.tables[table]?.columns[column];
|
|
112
|
-
descriptors.push({
|
|
113
|
-
name: paramName,
|
|
114
|
-
source: "dsl",
|
|
115
|
-
refs: {
|
|
116
|
-
table,
|
|
117
|
-
column
|
|
118
|
-
},
|
|
119
|
-
...columnMeta && typeof columnMeta.nullable === "boolean" ? { nullable: columnMeta.nullable } : {}
|
|
120
|
-
});
|
|
121
|
-
augmentDescriptorWithColumnMeta(descriptors, columnMeta);
|
|
122
|
-
}
|
|
123
|
-
rightExpr = createParamRef(index, paramName);
|
|
124
|
-
} else if (isColumnBuilder(where.right) || isExpressionBuilder(where.right)) {
|
|
125
|
-
rightExpr = where.right.toExpr();
|
|
126
|
-
paramName = "";
|
|
127
|
-
} else errorFailedToBuildWhereClause();
|
|
128
|
-
return {
|
|
129
|
-
expr: createBinaryExpr(where.op, leftExpr, rightExpr),
|
|
130
|
-
...codecId ? { codecId } : {},
|
|
131
|
-
paramName
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
//#endregion
|
|
136
|
-
//#region src/mutations/delete-builder.ts
|
|
137
|
-
function buildDeletePlan(context, modelName, where, getModelAccessor, options) {
|
|
138
|
-
const wherePredicate = where(getModelAccessor());
|
|
139
|
-
const tableName = context.contract.mappings.modelToTable?.[modelName];
|
|
140
|
-
if (!tableName) errorModelNotFound(modelName);
|
|
141
|
-
const table = createTableRef(tableName);
|
|
142
|
-
const paramsMap = options?.params ?? {};
|
|
143
|
-
const paramDescriptors = [];
|
|
144
|
-
const paramValues = [];
|
|
145
|
-
const paramCodecs = {};
|
|
146
|
-
const whereResult = buildWhereExpr(wherePredicate, context.contract, paramsMap, paramDescriptors, paramValues);
|
|
147
|
-
const whereExpr = whereResult.expr;
|
|
148
|
-
if (!whereExpr) errorFailedToBuildWhereClause();
|
|
149
|
-
if (whereResult?.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
150
|
-
const ast = createDeleteAst({
|
|
151
|
-
table,
|
|
152
|
-
where: whereExpr
|
|
153
|
-
});
|
|
154
|
-
return Object.freeze({
|
|
155
|
-
ast,
|
|
156
|
-
params: paramValues,
|
|
157
|
-
meta: {
|
|
158
|
-
target: context.contract.target,
|
|
159
|
-
targetFamily: context.contract.targetFamily,
|
|
160
|
-
coreHash: context.contract.coreHash,
|
|
161
|
-
lane: "orm",
|
|
162
|
-
refs: {
|
|
163
|
-
tables: [tableName],
|
|
164
|
-
columns: []
|
|
165
|
-
},
|
|
166
|
-
projection: {},
|
|
167
|
-
paramDescriptors,
|
|
168
|
-
...Object.keys(paramCodecs).length > 0 ? { annotations: {
|
|
169
|
-
codecs: paramCodecs,
|
|
170
|
-
intent: "write",
|
|
171
|
-
isMutation: true
|
|
172
|
-
} } : { annotations: {
|
|
173
|
-
intent: "write",
|
|
174
|
-
isMutation: true
|
|
175
|
-
} }
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
//#endregion
|
|
181
|
-
//#region src/utils/param-descriptor.ts
|
|
182
|
-
function createParamDescriptor(args) {
|
|
183
|
-
return {
|
|
184
|
-
name: args.name,
|
|
185
|
-
source: "dsl",
|
|
186
|
-
refs: {
|
|
187
|
-
table: args.table,
|
|
188
|
-
column: args.column
|
|
189
|
-
},
|
|
190
|
-
...args.codecId ? { codecId: args.codecId } : {},
|
|
191
|
-
...args.nativeType ? { nativeType: args.nativeType } : {},
|
|
192
|
-
nullable: args.nullable
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
//#endregion
|
|
197
|
-
//#region src/mutations/insert-builder.ts
|
|
198
|
-
function convertModelFieldsToColumns(contract, modelName, fields) {
|
|
199
|
-
const model = contract.models[modelName];
|
|
200
|
-
if (!model || typeof model !== "object" || !("fields" in model)) throw new Error(`Model ${modelName} does not have fields`);
|
|
201
|
-
const modelFields = model.fields;
|
|
202
|
-
const result = {};
|
|
203
|
-
for (const fieldName in fields) {
|
|
204
|
-
if (!Object.hasOwn(fields, fieldName)) continue;
|
|
205
|
-
if (!Object.hasOwn(modelFields, fieldName)) throw new Error(`Field ${fieldName} does not exist on model ${modelName}`);
|
|
206
|
-
const field = modelFields[fieldName];
|
|
207
|
-
if (!field) continue;
|
|
208
|
-
const columnName = contract.mappings.fieldToColumn?.[modelName]?.[fieldName] ?? field.column ?? fieldName;
|
|
209
|
-
result[columnName] = param(fieldName);
|
|
210
|
-
}
|
|
211
|
-
return result;
|
|
212
|
-
}
|
|
213
|
-
function buildInsertPlan(context, modelName, data, options) {
|
|
214
|
-
if (!data || Object.keys(data).length === 0) errorCreateRequiresFields();
|
|
215
|
-
const values = convertModelFieldsToColumns(context.contract, modelName, data);
|
|
216
|
-
const tableName = context.contract.mappings.modelToTable?.[modelName];
|
|
217
|
-
if (!tableName) errorModelNotFound(modelName);
|
|
218
|
-
const table = createTableRef(tableName);
|
|
219
|
-
const paramsMap = {
|
|
220
|
-
...options?.params ?? {},
|
|
221
|
-
...data
|
|
222
|
-
};
|
|
223
|
-
const paramDescriptors = [];
|
|
224
|
-
const paramValues = [];
|
|
225
|
-
const paramCodecs = {};
|
|
226
|
-
const contractTable = context.contract.storage.tables[tableName];
|
|
227
|
-
if (!contractTable) errorUnknownTable(tableName);
|
|
228
|
-
const insertValues = {};
|
|
229
|
-
for (const [columnName, placeholder] of Object.entries(values)) {
|
|
230
|
-
const columnMeta = contractTable.columns[columnName];
|
|
231
|
-
assertColumnExists(columnMeta, columnName, tableName);
|
|
232
|
-
const paramName = placeholder.name;
|
|
233
|
-
const value = assertParameterExists(paramsMap, paramName);
|
|
234
|
-
const index = paramValues.push(value);
|
|
235
|
-
const codecId = columnMeta.codecId;
|
|
236
|
-
if (paramName) paramCodecs[paramName] = codecId;
|
|
237
|
-
paramDescriptors.push(createParamDescriptor({
|
|
238
|
-
name: paramName,
|
|
239
|
-
table: tableName,
|
|
240
|
-
column: columnName,
|
|
241
|
-
codecId,
|
|
242
|
-
nativeType: columnMeta.nativeType,
|
|
243
|
-
nullable: columnMeta.nullable
|
|
244
|
-
}));
|
|
245
|
-
insertValues[columnName] = createParamRef(index, paramName);
|
|
246
|
-
}
|
|
247
|
-
const ast = createInsertAst({
|
|
248
|
-
table,
|
|
249
|
-
values: insertValues
|
|
250
|
-
});
|
|
251
|
-
return Object.freeze({
|
|
252
|
-
ast,
|
|
253
|
-
params: paramValues,
|
|
254
|
-
meta: {
|
|
255
|
-
target: context.contract.target,
|
|
256
|
-
targetFamily: context.contract.targetFamily,
|
|
257
|
-
coreHash: context.contract.coreHash,
|
|
258
|
-
lane: "orm",
|
|
259
|
-
refs: {
|
|
260
|
-
tables: [tableName],
|
|
261
|
-
columns: []
|
|
262
|
-
},
|
|
263
|
-
projection: {},
|
|
264
|
-
paramDescriptors,
|
|
265
|
-
...Object.keys(paramCodecs).length > 0 ? { annotations: {
|
|
266
|
-
codecs: paramCodecs,
|
|
267
|
-
intent: "write",
|
|
268
|
-
isMutation: true
|
|
269
|
-
} } : { annotations: {
|
|
270
|
-
intent: "write",
|
|
271
|
-
isMutation: true
|
|
272
|
-
} }
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
//#endregion
|
|
278
|
-
//#region src/mutations/update-builder.ts
|
|
279
|
-
function buildUpdatePlan(context, modelName, where, getModelAccessor, data, options) {
|
|
280
|
-
if (!data || Object.keys(data).length === 0) errorUpdateRequiresFields();
|
|
281
|
-
const set = convertModelFieldsToColumns(context.contract, modelName, data);
|
|
282
|
-
const wherePredicate = where(getModelAccessor());
|
|
283
|
-
const tableName = context.contract.mappings.modelToTable?.[modelName];
|
|
284
|
-
if (!tableName) errorModelNotFound(modelName);
|
|
285
|
-
const table = createTableRef(tableName);
|
|
286
|
-
const paramsMap = {
|
|
287
|
-
...options?.params ?? {},
|
|
288
|
-
...data
|
|
289
|
-
};
|
|
290
|
-
const paramDescriptors = [];
|
|
291
|
-
const paramValues = [];
|
|
292
|
-
const paramCodecs = {};
|
|
293
|
-
const contractTable = context.contract.storage.tables[tableName];
|
|
294
|
-
if (!contractTable) errorUnknownTable(tableName);
|
|
295
|
-
const updateSet = {};
|
|
296
|
-
for (const [columnName, placeholder] of Object.entries(set)) {
|
|
297
|
-
const columnMeta = contractTable.columns[columnName];
|
|
298
|
-
assertColumnExists(columnMeta, columnName, tableName);
|
|
299
|
-
const paramName = placeholder.name;
|
|
300
|
-
const value = assertParameterExists(paramsMap, paramName);
|
|
301
|
-
const index = paramValues.push(value);
|
|
302
|
-
const codecId = columnMeta.codecId;
|
|
303
|
-
if (paramName) paramCodecs[paramName] = codecId;
|
|
304
|
-
paramDescriptors.push(createParamDescriptor({
|
|
305
|
-
name: paramName,
|
|
306
|
-
table: tableName,
|
|
307
|
-
column: columnName,
|
|
308
|
-
codecId,
|
|
309
|
-
nativeType: columnMeta.nativeType,
|
|
310
|
-
nullable: columnMeta.nullable
|
|
311
|
-
}));
|
|
312
|
-
updateSet[columnName] = createParamRef(index, paramName);
|
|
313
|
-
}
|
|
314
|
-
const whereResult = buildWhereExpr(wherePredicate, context.contract, paramsMap, paramDescriptors, paramValues);
|
|
315
|
-
const whereExpr = whereResult.expr;
|
|
316
|
-
if (!whereExpr) errorFailedToBuildWhereClause();
|
|
317
|
-
if (whereResult?.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
318
|
-
const ast = createUpdateAst({
|
|
319
|
-
table,
|
|
320
|
-
set: updateSet,
|
|
321
|
-
where: whereExpr
|
|
322
|
-
});
|
|
323
|
-
return Object.freeze({
|
|
324
|
-
ast,
|
|
325
|
-
params: paramValues,
|
|
326
|
-
meta: {
|
|
327
|
-
target: context.contract.target,
|
|
328
|
-
targetFamily: context.contract.targetFamily,
|
|
329
|
-
coreHash: context.contract.coreHash,
|
|
330
|
-
lane: "orm",
|
|
331
|
-
refs: {
|
|
332
|
-
tables: [tableName],
|
|
333
|
-
columns: []
|
|
334
|
-
},
|
|
335
|
-
projection: {},
|
|
336
|
-
paramDescriptors,
|
|
337
|
-
...Object.keys(paramCodecs).length > 0 ? { annotations: {
|
|
338
|
-
codecs: paramCodecs,
|
|
339
|
-
intent: "write",
|
|
340
|
-
isMutation: true
|
|
341
|
-
} } : { annotations: {
|
|
342
|
-
intent: "write",
|
|
343
|
-
isMutation: true
|
|
344
|
-
} }
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
//#endregion
|
|
350
|
-
//#region src/orm-include-child.ts
|
|
351
|
-
var OrmIncludeChildBuilderImpl = class OrmIncludeChildBuilderImpl {
|
|
352
|
-
context;
|
|
353
|
-
contract;
|
|
354
|
-
childModelName;
|
|
355
|
-
childWhere;
|
|
356
|
-
childOrderBy;
|
|
357
|
-
childLimit;
|
|
358
|
-
childProjection = void 0;
|
|
359
|
-
constructor(options, childModelName) {
|
|
360
|
-
this.context = options.context;
|
|
361
|
-
this.contract = options.context.contract;
|
|
362
|
-
this.childModelName = childModelName;
|
|
363
|
-
}
|
|
364
|
-
where(fn) {
|
|
365
|
-
const builder = new OrmIncludeChildBuilderImpl({ context: this.context }, this.childModelName);
|
|
366
|
-
builder.childWhere = fn(this._getModelAccessor());
|
|
367
|
-
builder.childOrderBy = this.childOrderBy;
|
|
368
|
-
builder.childLimit = this.childLimit;
|
|
369
|
-
builder.childProjection = this.childProjection;
|
|
370
|
-
return builder;
|
|
371
|
-
}
|
|
372
|
-
orderBy(fn) {
|
|
373
|
-
const builder = new OrmIncludeChildBuilderImpl({ context: this.context }, this.childModelName);
|
|
374
|
-
builder.childWhere = this.childWhere;
|
|
375
|
-
builder.childOrderBy = fn(this._getModelAccessor());
|
|
376
|
-
builder.childLimit = this.childLimit;
|
|
377
|
-
builder.childProjection = this.childProjection;
|
|
378
|
-
return builder;
|
|
379
|
-
}
|
|
380
|
-
take(n) {
|
|
381
|
-
const builder = new OrmIncludeChildBuilderImpl({ context: this.context }, this.childModelName);
|
|
382
|
-
builder.childWhere = this.childWhere;
|
|
383
|
-
builder.childOrderBy = this.childOrderBy;
|
|
384
|
-
builder.childLimit = n;
|
|
385
|
-
builder.childProjection = this.childProjection;
|
|
386
|
-
return builder;
|
|
387
|
-
}
|
|
388
|
-
select(fn) {
|
|
389
|
-
const builder = new OrmIncludeChildBuilderImpl({ context: this.context }, this.childModelName);
|
|
390
|
-
builder.childWhere = this.childWhere;
|
|
391
|
-
builder.childOrderBy = this.childOrderBy;
|
|
392
|
-
builder.childLimit = this.childLimit;
|
|
393
|
-
builder.childProjection = fn(this._getModelAccessor());
|
|
394
|
-
return builder;
|
|
395
|
-
}
|
|
396
|
-
getState() {
|
|
397
|
-
return {
|
|
398
|
-
...this.childWhere !== void 0 ? { childWhere: this.childWhere } : {},
|
|
399
|
-
...this.childOrderBy !== void 0 ? { childOrderBy: this.childOrderBy } : {},
|
|
400
|
-
...this.childLimit !== void 0 ? { childLimit: this.childLimit } : {},
|
|
401
|
-
...this.childProjection !== void 0 ? { childProjection: this.childProjection } : {}
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
_getModelAccessor() {
|
|
405
|
-
const tableName = this.contract.mappings.modelToTable?.[this.childModelName];
|
|
406
|
-
if (!tableName) throw planInvalid(`Model ${this.childModelName} not found in mappings`);
|
|
407
|
-
const table = schema(this.context).tables[tableName];
|
|
408
|
-
if (!table) throw planInvalid(`Table ${tableName} not found in schema`);
|
|
409
|
-
const accessor = {};
|
|
410
|
-
const model = this.contract.models[this.childModelName];
|
|
411
|
-
if (!model || typeof model !== "object" || !("fields" in model)) throw planInvalid(`Model ${this.childModelName} does not have fields`);
|
|
412
|
-
const modelFields = model.fields;
|
|
413
|
-
for (const fieldName in modelFields) {
|
|
414
|
-
const field = modelFields[fieldName];
|
|
415
|
-
if (!field) continue;
|
|
416
|
-
const columnName = this.contract.mappings.fieldToColumn?.[this.childModelName]?.[fieldName] ?? field.column ?? fieldName;
|
|
417
|
-
const column = table.columns[columnName];
|
|
418
|
-
if (column) accessor[fieldName] = column;
|
|
419
|
-
}
|
|
420
|
-
return accessor;
|
|
421
|
-
}
|
|
422
|
-
};
|
|
423
|
-
|
|
424
|
-
//#endregion
|
|
425
|
-
//#region src/orm-relation-filter.ts
|
|
426
|
-
var OrmRelationFilterBuilderImpl = class OrmRelationFilterBuilderImpl {
|
|
427
|
-
context;
|
|
428
|
-
contract;
|
|
429
|
-
childModelName;
|
|
430
|
-
wherePredicate = void 0;
|
|
431
|
-
modelAccessor = void 0;
|
|
432
|
-
constructor(options, childModelName) {
|
|
433
|
-
this.context = options.context;
|
|
434
|
-
this.contract = options.context.contract;
|
|
435
|
-
this.childModelName = childModelName;
|
|
436
|
-
this.modelAccessor = this._getModelAccessor();
|
|
437
|
-
}
|
|
438
|
-
where(fn) {
|
|
439
|
-
const builder = new OrmRelationFilterBuilderImpl({ context: this.context }, this.childModelName);
|
|
440
|
-
builder.modelAccessor = this.modelAccessor;
|
|
441
|
-
if (this.modelAccessor) builder.wherePredicate = fn(this.modelAccessor);
|
|
442
|
-
return builder;
|
|
443
|
-
}
|
|
444
|
-
getWherePredicate() {
|
|
445
|
-
return this.wherePredicate;
|
|
446
|
-
}
|
|
447
|
-
getChildModelName() {
|
|
448
|
-
return this.childModelName;
|
|
449
|
-
}
|
|
450
|
-
getModelAccessor() {
|
|
451
|
-
if (!this.modelAccessor) this.modelAccessor = this._getModelAccessor();
|
|
452
|
-
if (!this.modelAccessor) throw planInvalid(`Failed to get model accessor for ${this.childModelName}`);
|
|
453
|
-
return this.modelAccessor;
|
|
454
|
-
}
|
|
455
|
-
_getModelAccessor() {
|
|
456
|
-
const tableName = this.contract.mappings.modelToTable?.[this.childModelName];
|
|
457
|
-
if (!tableName) throw planInvalid(`Model ${this.childModelName} not found in mappings`);
|
|
458
|
-
const table = schema(this.context).tables[tableName];
|
|
459
|
-
if (!table) throw planInvalid(`Table ${tableName} not found in schema`);
|
|
460
|
-
const accessor = {};
|
|
461
|
-
const model = this.contract.models[this.childModelName];
|
|
462
|
-
if (!model || typeof model !== "object" || !("fields" in model)) throw planInvalid(`Model ${this.childModelName} does not have fields`);
|
|
463
|
-
const modelFields = model.fields;
|
|
464
|
-
for (const fieldName in modelFields) {
|
|
465
|
-
const field = modelFields[fieldName];
|
|
466
|
-
if (!field) continue;
|
|
467
|
-
const columnName = this.contract.mappings.fieldToColumn?.[this.childModelName]?.[fieldName] ?? field.column ?? fieldName;
|
|
468
|
-
const column = table.columns[columnName];
|
|
469
|
-
if (column) accessor[fieldName] = column;
|
|
470
|
-
}
|
|
471
|
-
return accessor;
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
//#endregion
|
|
476
|
-
//#region src/plan/plan-assembly.ts
|
|
477
|
-
/**
|
|
478
|
-
* Extracts column references from an ExpressionSource (ColumnBuilder or ExpressionBuilder).
|
|
479
|
-
* Skips entries with empty table or column names (e.g., placeholder columns for includes).
|
|
480
|
-
*/
|
|
481
|
-
function collectRefsFromExpressionSource(source, refsColumns) {
|
|
482
|
-
if (isExpressionBuilder(source)) {
|
|
483
|
-
const allRefs = collectColumnRefs(source.expr);
|
|
484
|
-
for (const ref of allRefs) if (ref.table && ref.column) refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
485
|
-
table: ref.table,
|
|
486
|
-
column: ref.column
|
|
487
|
-
});
|
|
488
|
-
} else if (isColumnBuilder(source)) {
|
|
489
|
-
const col = source;
|
|
490
|
-
if (col.table && col.column) refsColumns.set(`${col.table}.${col.column}`, {
|
|
491
|
-
table: col.table,
|
|
492
|
-
column: col.column
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Extracts column references from an Expression (AST node).
|
|
498
|
-
*/
|
|
499
|
-
function collectRefsFromExpression(expr, refsColumns) {
|
|
500
|
-
if (isOperationExpr(expr)) {
|
|
501
|
-
const allRefs = collectColumnRefs(expr);
|
|
502
|
-
for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
503
|
-
table: ref.table,
|
|
504
|
-
column: ref.column
|
|
505
|
-
});
|
|
506
|
-
} else if (expr.kind === "col") refsColumns.set(`${expr.table}.${expr.column}`, {
|
|
507
|
-
table: expr.table,
|
|
508
|
-
column: expr.column
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
function buildMeta(args) {
|
|
512
|
-
const refsColumns = /* @__PURE__ */ new Map();
|
|
513
|
-
const refsTables = new Set([args.table.name]);
|
|
514
|
-
for (const column of args.projection.columns) collectRefsFromExpressionSource(column, refsColumns);
|
|
515
|
-
if (args.includes) for (const include of args.includes) {
|
|
516
|
-
refsTables.add(include.table.name);
|
|
517
|
-
const onLeft = include.on.left;
|
|
518
|
-
const onRight = include.on.right;
|
|
519
|
-
if (onLeft.table && onLeft.column && onRight.table && onRight.column) {
|
|
520
|
-
refsColumns.set(`${onLeft.table}.${onLeft.column}`, {
|
|
521
|
-
table: onLeft.table,
|
|
522
|
-
column: onLeft.column
|
|
523
|
-
});
|
|
524
|
-
refsColumns.set(`${onRight.table}.${onRight.column}`, {
|
|
525
|
-
table: onRight.table,
|
|
526
|
-
column: onRight.column
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
for (const column of include.childProjection.columns) {
|
|
530
|
-
const col = column;
|
|
531
|
-
if (col.table && col.column) refsColumns.set(`${col.table}.${col.column}`, {
|
|
532
|
-
table: col.table,
|
|
533
|
-
column: col.column
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
if (include.childWhere) collectRefsFromExpression(include.childWhere.left, refsColumns);
|
|
537
|
-
if (include.childOrderBy) collectRefsFromExpression(include.childOrderBy.expr, refsColumns);
|
|
538
|
-
}
|
|
539
|
-
if (args.where) {
|
|
540
|
-
const leftExpr = args.where.left;
|
|
541
|
-
if (isOperationExpr(leftExpr)) {
|
|
542
|
-
const allRefs = collectColumnRefs(leftExpr);
|
|
543
|
-
for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
544
|
-
table: ref.table,
|
|
545
|
-
column: ref.column
|
|
546
|
-
});
|
|
547
|
-
} else refsColumns.set(`${leftExpr.table}.${leftExpr.column}`, {
|
|
548
|
-
table: leftExpr.table,
|
|
549
|
-
column: leftExpr.column
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
if (args.orderBy) {
|
|
553
|
-
const orderByExpr = args.orderBy.expr;
|
|
554
|
-
if (isOperationExpr(orderByExpr)) {
|
|
555
|
-
const allRefs = collectColumnRefs(orderByExpr);
|
|
556
|
-
for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
557
|
-
table: ref.table,
|
|
558
|
-
column: ref.column
|
|
559
|
-
});
|
|
560
|
-
} else refsColumns.set(`${orderByExpr.table}.${orderByExpr.column}`, {
|
|
561
|
-
table: orderByExpr.table,
|
|
562
|
-
column: orderByExpr.column
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
const includeAliases = new Set(args.includes?.map((inc) => inc.alias) ?? []);
|
|
566
|
-
const projectionMap = Object.fromEntries(args.projection.aliases.map((alias, index) => {
|
|
567
|
-
if (includeAliases.has(alias)) return [alias, `include:${alias}`];
|
|
568
|
-
const column = args.projection.columns[index];
|
|
569
|
-
if (!column) throw planInvalid(`Missing column for alias ${alias} at index ${index}`);
|
|
570
|
-
if (isExpressionBuilder(column)) return [alias, `operation:${column.expr.method}`];
|
|
571
|
-
const col = column;
|
|
572
|
-
if (!col.table || !col.column) return [alias, `include:${alias}`];
|
|
573
|
-
return [alias, `${col.table}.${col.column}`];
|
|
574
|
-
}));
|
|
575
|
-
const projectionTypes = {};
|
|
576
|
-
for (let i = 0; i < args.projection.aliases.length; i++) {
|
|
577
|
-
const alias = args.projection.aliases[i];
|
|
578
|
-
if (!alias || includeAliases.has(alias)) continue;
|
|
579
|
-
const col = args.projection.columns[i];
|
|
580
|
-
if (!col) continue;
|
|
581
|
-
if (isExpressionBuilder(col)) {
|
|
582
|
-
const operationExpr = col.expr;
|
|
583
|
-
if (operationExpr.returns.kind === "typeId") projectionTypes[alias] = operationExpr.returns.type;
|
|
584
|
-
else if (operationExpr.returns.kind === "builtin") projectionTypes[alias] = operationExpr.returns.type;
|
|
585
|
-
} else {
|
|
586
|
-
const codecId = getColumnMeta(col)?.codecId;
|
|
587
|
-
if (codecId) projectionTypes[alias] = codecId;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
const projectionCodecs = {};
|
|
591
|
-
for (let i = 0; i < args.projection.aliases.length; i++) {
|
|
592
|
-
const alias = args.projection.aliases[i];
|
|
593
|
-
if (!alias || includeAliases.has(alias)) continue;
|
|
594
|
-
const column = args.projection.columns[i];
|
|
595
|
-
if (!column) continue;
|
|
596
|
-
if (isExpressionBuilder(column)) {
|
|
597
|
-
const operationExpr = column.expr;
|
|
598
|
-
if (operationExpr.returns.kind === "typeId") projectionCodecs[alias] = operationExpr.returns.type;
|
|
599
|
-
} else {
|
|
600
|
-
const codecId = getColumnMeta(column)?.codecId;
|
|
601
|
-
if (codecId) projectionCodecs[alias] = codecId;
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
const allCodecs = {
|
|
605
|
-
...projectionCodecs,
|
|
606
|
-
...args.paramCodecs ? args.paramCodecs : {}
|
|
607
|
-
};
|
|
608
|
-
return Object.freeze(compact({
|
|
609
|
-
target: args.contract.target,
|
|
610
|
-
targetFamily: args.contract.targetFamily,
|
|
611
|
-
coreHash: args.contract.coreHash,
|
|
612
|
-
lane: "dsl",
|
|
613
|
-
refs: {
|
|
614
|
-
tables: Array.from(refsTables),
|
|
615
|
-
columns: Array.from(refsColumns.values())
|
|
616
|
-
},
|
|
617
|
-
projection: projectionMap,
|
|
618
|
-
projectionTypes: Object.keys(projectionTypes).length > 0 ? projectionTypes : void 0,
|
|
619
|
-
annotations: Object.keys(allCodecs).length > 0 ? Object.freeze({ codecs: Object.freeze(allCodecs) }) : void 0,
|
|
620
|
-
paramDescriptors: args.paramDescriptors,
|
|
621
|
-
profileHash: args.contract.profileHash
|
|
622
|
-
}));
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
//#endregion
|
|
626
|
-
//#region src/orm/capabilities.ts
|
|
627
|
-
function checkIncludeCapabilities(contract) {
|
|
628
|
-
const target = contract.target;
|
|
629
|
-
const capabilities = contract.capabilities;
|
|
630
|
-
if (!capabilities || !capabilities[target]) errorIncludeRequiresCapabilities();
|
|
631
|
-
const targetCapabilities = capabilities[target];
|
|
632
|
-
if (capabilities[target]["lateral"] !== true || targetCapabilities["jsonAgg"] !== true) errorIncludeCapabilitiesNotTrue();
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
//#endregion
|
|
636
|
-
//#region src/selection/join.ts
|
|
637
|
-
function buildJoinOnExpr(parentTableName, parentColName, childTableName, childColName) {
|
|
638
|
-
return createJoinOnExpr(createColumnRef(parentTableName, parentColName), createColumnRef(childTableName, childColName));
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
//#endregion
|
|
642
|
-
//#region src/selection/ordering.ts
|
|
643
|
-
function buildOrderByClause(orderBy) {
|
|
644
|
-
if (!orderBy) return;
|
|
645
|
-
const orderByBuilder = orderBy;
|
|
646
|
-
const orderExpr = orderByBuilder.expr;
|
|
647
|
-
return [createOrderByItem(isOperationExpr(orderExpr) ? orderExpr : (() => {
|
|
648
|
-
const colBuilder = orderExpr;
|
|
649
|
-
return createColumnRef(colBuilder.table, colBuilder.column);
|
|
650
|
-
})(), orderByBuilder.dir)];
|
|
651
|
-
}
|
|
652
|
-
function buildChildOrderByClause(orderBy) {
|
|
653
|
-
if (!orderBy) return;
|
|
654
|
-
const orderByBuilder = orderBy;
|
|
655
|
-
const orderExpr = orderByBuilder.expr;
|
|
656
|
-
return [createOrderByItem((() => {
|
|
657
|
-
if (isOperationExpr(orderExpr)) {
|
|
658
|
-
const baseCol = extractBaseColumnRef(orderExpr);
|
|
659
|
-
return createColumnRef(baseCol.table, baseCol.column);
|
|
660
|
-
}
|
|
661
|
-
const colBuilder = orderExpr;
|
|
662
|
-
return createColumnRef(colBuilder.table, colBuilder.column);
|
|
663
|
-
})(), orderByBuilder.dir)];
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
//#endregion
|
|
667
|
-
//#region src/selection/projection.ts
|
|
668
|
-
function generateAlias(path) {
|
|
669
|
-
if (path.length === 0) errorAliasPathEmpty();
|
|
670
|
-
return path.join("_");
|
|
671
|
-
}
|
|
672
|
-
var AliasTracker = class {
|
|
673
|
-
aliases = /* @__PURE__ */ new Set();
|
|
674
|
-
aliasToPath = /* @__PURE__ */ new Map();
|
|
675
|
-
register(path) {
|
|
676
|
-
const alias = generateAlias(path);
|
|
677
|
-
if (this.aliases.has(alias)) errorAliasCollision(path, alias, this.aliasToPath.get(alias));
|
|
678
|
-
this.aliases.add(alias);
|
|
679
|
-
this.aliasToPath.set(alias, path);
|
|
680
|
-
return alias;
|
|
681
|
-
}
|
|
682
|
-
getPath(alias) {
|
|
683
|
-
return this.aliasToPath.get(alias);
|
|
684
|
-
}
|
|
685
|
-
has(alias) {
|
|
686
|
-
return this.aliases.has(alias);
|
|
687
|
-
}
|
|
688
|
-
};
|
|
689
|
-
function flattenProjection(projection, tracker, currentPath = []) {
|
|
690
|
-
const aliases = [];
|
|
691
|
-
const columns = [];
|
|
692
|
-
for (const [key, value] of Object.entries(projection)) {
|
|
693
|
-
const path = [...currentPath, key];
|
|
694
|
-
if (isColumnBuilder(value) || isExpressionBuilder(value)) {
|
|
695
|
-
const alias = tracker.register(path);
|
|
696
|
-
aliases.push(alias);
|
|
697
|
-
columns.push(value);
|
|
698
|
-
} else if (typeof value === "object" && value !== null) {
|
|
699
|
-
const nested = flattenProjection(value, tracker, path);
|
|
700
|
-
aliases.push(...nested.aliases);
|
|
701
|
-
columns.push(...nested.columns);
|
|
702
|
-
} else errorInvalidProjectionValue(path);
|
|
703
|
-
}
|
|
704
|
-
return {
|
|
705
|
-
aliases,
|
|
706
|
-
columns
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
function buildProjectionState(_table, projection, includes) {
|
|
710
|
-
const tracker = new AliasTracker();
|
|
711
|
-
const aliases = [];
|
|
712
|
-
const columns = [];
|
|
713
|
-
for (const [key, value] of Object.entries(projection)) if (value === true) {
|
|
714
|
-
const matchingInclude = includes?.find((inc) => inc.alias === key);
|
|
715
|
-
if (!matchingInclude) errorIncludeAliasNotFound(key);
|
|
716
|
-
aliases.push(key);
|
|
717
|
-
columns.push({
|
|
718
|
-
kind: "column",
|
|
719
|
-
table: matchingInclude.table.name,
|
|
720
|
-
column: "",
|
|
721
|
-
columnMeta: {
|
|
722
|
-
nativeType: "jsonb",
|
|
723
|
-
codecId: "core/json@1",
|
|
724
|
-
nullable: true
|
|
725
|
-
},
|
|
726
|
-
toExpr() {
|
|
727
|
-
return {
|
|
728
|
-
kind: "col",
|
|
729
|
-
table: matchingInclude.table.name,
|
|
730
|
-
column: ""
|
|
731
|
-
};
|
|
732
|
-
}
|
|
733
|
-
});
|
|
734
|
-
} else if (isColumnBuilder(value) || isExpressionBuilder(value)) {
|
|
735
|
-
const alias = tracker.register([key]);
|
|
736
|
-
aliases.push(alias);
|
|
737
|
-
columns.push(value);
|
|
738
|
-
} else if (typeof value === "object" && value !== null) {
|
|
739
|
-
const nested = flattenProjection(value, tracker, [key]);
|
|
740
|
-
aliases.push(...nested.aliases);
|
|
741
|
-
columns.push(...nested.columns);
|
|
742
|
-
} else errorInvalidProjectionKey(key);
|
|
743
|
-
if (aliases.length === 0) errorProjectionEmpty();
|
|
744
|
-
return {
|
|
745
|
-
aliases,
|
|
746
|
-
columns
|
|
747
|
-
};
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
//#endregion
|
|
751
|
-
//#region src/relations/include-plan.ts
|
|
752
|
-
function buildIncludeAsts(input) {
|
|
753
|
-
const { includes, contract, context, modelName, paramsMap, paramDescriptors, paramValues, paramCodecs } = input;
|
|
754
|
-
const includesAst = [];
|
|
755
|
-
const includesForMeta = [];
|
|
756
|
-
for (const includeState of includes) {
|
|
757
|
-
checkIncludeCapabilities(contract);
|
|
758
|
-
const parentTableName = contract.mappings.modelToTable?.[modelName];
|
|
759
|
-
if (!parentTableName) errorModelNotFound(modelName);
|
|
760
|
-
const parentSchemaTable = schema(context).tables[parentTableName];
|
|
761
|
-
if (!parentSchemaTable) errorTableNotFound(parentTableName);
|
|
762
|
-
const childSchemaTable = schema(context).tables[includeState.childTable.name];
|
|
763
|
-
if (!childSchemaTable) errorTableNotFound(includeState.childTable.name);
|
|
764
|
-
if (includeState.relation.on.parentCols.length !== 1 || includeState.relation.on.childCols.length !== 1) errorMultiColumnJoinsNotSupported();
|
|
765
|
-
const parentColName = includeState.relation.on.parentCols[0];
|
|
766
|
-
const childColName = includeState.relation.on.childCols[0];
|
|
767
|
-
if (!parentColName || !childColName) errorJoinColumnsMustBeDefined();
|
|
768
|
-
const parentCol = parentSchemaTable.columns[parentColName];
|
|
769
|
-
const childCol = childSchemaTable.columns[childColName];
|
|
770
|
-
if (!parentCol) errorColumnNotFound(parentColName, parentTableName);
|
|
771
|
-
if (!childCol) errorColumnNotFound(childColName, includeState.childTable.name);
|
|
772
|
-
const onExpr = buildJoinOnExpr(parentTableName, parentColName, includeState.childTable.name, childColName);
|
|
773
|
-
if (!includeState.childProjection) errorChildProjectionMustBeSpecified();
|
|
774
|
-
const filteredProjection = {};
|
|
775
|
-
for (const [key, value] of Object.entries(includeState.childProjection)) if (value !== true && value !== false) filteredProjection[key] = value;
|
|
776
|
-
if (Object.keys(filteredProjection).length === 0) errorChildProjectionEmpty();
|
|
777
|
-
const childProjectionState = buildProjectionState(includeState.childTable, filteredProjection);
|
|
778
|
-
let childWhere;
|
|
779
|
-
if (includeState.childWhere) {
|
|
780
|
-
const whereResult = buildWhereExpr(includeState.childWhere, contract, paramsMap, paramDescriptors, paramValues);
|
|
781
|
-
childWhere = whereResult.expr;
|
|
782
|
-
if (whereResult.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
783
|
-
}
|
|
784
|
-
const childOrderBy = buildChildOrderByClause(includeState.childOrderBy);
|
|
785
|
-
const childProjectionItems = [];
|
|
786
|
-
for (let i = 0; i < childProjectionState.aliases.length; i++) {
|
|
787
|
-
const alias = childProjectionState.aliases[i];
|
|
788
|
-
if (!alias) errorMissingAlias(i);
|
|
789
|
-
const column = childProjectionState.columns[i];
|
|
790
|
-
if (!column) errorMissingColumn(alias, i);
|
|
791
|
-
if (isExpressionBuilder(column)) childProjectionItems.push({
|
|
792
|
-
alias,
|
|
793
|
-
expr: column.expr
|
|
794
|
-
});
|
|
795
|
-
else childProjectionItems.push({
|
|
796
|
-
alias,
|
|
797
|
-
expr: column.toExpr()
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
const includeAst = compact({
|
|
801
|
-
kind: "includeMany",
|
|
802
|
-
alias: includeState.alias,
|
|
803
|
-
child: compact({
|
|
804
|
-
table: includeState.childTable,
|
|
805
|
-
on: onExpr,
|
|
806
|
-
project: childProjectionItems,
|
|
807
|
-
where: childWhere,
|
|
808
|
-
orderBy: childOrderBy,
|
|
809
|
-
limit: includeState.childLimit
|
|
810
|
-
})
|
|
811
|
-
});
|
|
812
|
-
includesAst.push(includeAst);
|
|
813
|
-
const includeForMeta = compact({
|
|
814
|
-
alias: includeState.alias,
|
|
815
|
-
table: includeState.childTable,
|
|
816
|
-
on: {
|
|
817
|
-
kind: "join-on",
|
|
818
|
-
left: parentCol,
|
|
819
|
-
right: childCol
|
|
820
|
-
},
|
|
821
|
-
childProjection: childProjectionState,
|
|
822
|
-
childWhere: includeState.childWhere,
|
|
823
|
-
childOrderBy: includeState.childOrderBy,
|
|
824
|
-
childLimit: includeState.childLimit
|
|
825
|
-
});
|
|
826
|
-
includesForMeta.push(includeForMeta);
|
|
827
|
-
}
|
|
828
|
-
return {
|
|
829
|
-
includesAst,
|
|
830
|
-
includesForMeta
|
|
831
|
-
};
|
|
832
|
-
}
|
|
833
|
-
function buildExistsSubqueries(relationFilters, contract, modelName, options) {
|
|
834
|
-
const existsExprs = [];
|
|
835
|
-
for (const filter of relationFilters) {
|
|
836
|
-
const childTableName = contract.mappings.modelToTable?.[filter.childModelName];
|
|
837
|
-
if (!childTableName) errorModelNotFound(filter.childModelName);
|
|
838
|
-
const childTable = {
|
|
839
|
-
kind: "table",
|
|
840
|
-
name: childTableName
|
|
841
|
-
};
|
|
842
|
-
const parentTableName = contract.mappings.modelToTable?.[modelName];
|
|
843
|
-
if (!parentTableName) errorModelNotFound(modelName);
|
|
844
|
-
const joinConditions = [];
|
|
845
|
-
for (let i = 0; i < filter.relation.on.parentCols.length; i++) {
|
|
846
|
-
const parentCol = filter.relation.on.parentCols[i];
|
|
847
|
-
const childCol = filter.relation.on.childCols[i];
|
|
848
|
-
if (!parentCol || !childCol) continue;
|
|
849
|
-
joinConditions.push({
|
|
850
|
-
left: {
|
|
851
|
-
kind: "col",
|
|
852
|
-
table: parentTableName,
|
|
853
|
-
column: parentCol
|
|
854
|
-
},
|
|
855
|
-
right: {
|
|
856
|
-
kind: "col",
|
|
857
|
-
table: childTableName,
|
|
858
|
-
column: childCol
|
|
859
|
-
}
|
|
860
|
-
});
|
|
861
|
-
}
|
|
862
|
-
let childWhere;
|
|
863
|
-
if (filter.childWhere) {
|
|
864
|
-
const paramsMap = options?.params ?? {};
|
|
865
|
-
childWhere = buildWhereExpr(filter.childWhere, contract, paramsMap, [], []).expr;
|
|
866
|
-
}
|
|
867
|
-
let subqueryWhere = childWhere;
|
|
868
|
-
if (joinConditions.length > 0) {
|
|
869
|
-
const firstJoinCondition = joinConditions[0];
|
|
870
|
-
if (firstJoinCondition) {
|
|
871
|
-
const joinWhere = {
|
|
872
|
-
kind: "bin",
|
|
873
|
-
op: "eq",
|
|
874
|
-
left: firstJoinCondition.left,
|
|
875
|
-
right: firstJoinCondition.right
|
|
876
|
-
};
|
|
877
|
-
if (childWhere) subqueryWhere = joinWhere;
|
|
878
|
-
else subqueryWhere = joinWhere;
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
const existsExpr = {
|
|
882
|
-
kind: "exists",
|
|
883
|
-
subquery: createSelectAst({
|
|
884
|
-
from: childTable,
|
|
885
|
-
project: [{
|
|
886
|
-
alias: "_exists",
|
|
887
|
-
expr: joinConditions[0]?.right ?? createColumnRef(childTableName, "id")
|
|
888
|
-
}],
|
|
889
|
-
where: subqueryWhere
|
|
890
|
-
}),
|
|
891
|
-
not: filter.filterType === "none" || filter.filterType === "every"
|
|
892
|
-
};
|
|
893
|
-
existsExprs.push(existsExpr);
|
|
894
|
-
}
|
|
895
|
-
return existsExprs;
|
|
896
|
-
}
|
|
897
|
-
function combineWhereClauses(mainWhere, existsExprs) {
|
|
898
|
-
if (existsExprs.length === 1) return existsExprs[0];
|
|
899
|
-
if (mainWhere) return mainWhere;
|
|
900
|
-
if (existsExprs.length > 0) return existsExprs[0];
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
//#endregion
|
|
904
|
-
//#region src/selection/select-builder.ts
|
|
905
|
-
function buildProjectionItems(projectionState, includesForMeta) {
|
|
906
|
-
const projectEntries = [];
|
|
907
|
-
for (let i = 0; i < projectionState.aliases.length; i++) {
|
|
908
|
-
const alias = projectionState.aliases[i];
|
|
909
|
-
if (!alias) errorMissingAlias(i);
|
|
910
|
-
const column = projectionState.columns[i];
|
|
911
|
-
if (!column) errorMissingColumn(alias, i);
|
|
912
|
-
if (includesForMeta.find((inc) => inc.alias === alias)) projectEntries.push({
|
|
913
|
-
alias,
|
|
914
|
-
expr: {
|
|
915
|
-
kind: "includeRef",
|
|
916
|
-
alias
|
|
917
|
-
}
|
|
918
|
-
});
|
|
919
|
-
else if (isExpressionBuilder(column)) projectEntries.push({
|
|
920
|
-
alias,
|
|
921
|
-
expr: column.expr
|
|
922
|
-
});
|
|
923
|
-
else {
|
|
924
|
-
const expr = column.toExpr();
|
|
925
|
-
if (expr.kind === "col" && (!expr.table || !expr.column)) errorInvalidColumn(alias, i);
|
|
926
|
-
projectEntries.push({
|
|
927
|
-
alias,
|
|
928
|
-
expr
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
return projectEntries;
|
|
933
|
-
}
|
|
934
|
-
function buildSelectAst(params) {
|
|
935
|
-
const { table, projectEntries, includesAst, whereExpr, orderByClause, limit } = params;
|
|
936
|
-
return createSelectAst({
|
|
937
|
-
from: createTableRef(table.name),
|
|
938
|
-
project: projectEntries,
|
|
939
|
-
...includesAst ? { includes: includesAst } : {},
|
|
940
|
-
...whereExpr ? { where: whereExpr } : {},
|
|
941
|
-
...orderByClause ? { orderBy: orderByClause } : {},
|
|
942
|
-
...limit !== void 0 ? { limit } : {}
|
|
943
|
-
});
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
//#endregion
|
|
947
|
-
//#region src/orm/context.ts
|
|
948
|
-
function createOrmContext(context) {
|
|
949
|
-
return context;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
//#endregion
|
|
953
|
-
//#region src/orm/builder.ts
|
|
954
|
-
var OrmModelBuilderImpl = class OrmModelBuilderImpl {
|
|
955
|
-
context;
|
|
956
|
-
contract;
|
|
957
|
-
modelName;
|
|
958
|
-
table;
|
|
959
|
-
wherePredicate = void 0;
|
|
960
|
-
relationFilters = [];
|
|
961
|
-
includes = [];
|
|
962
|
-
orderByExpr = void 0;
|
|
963
|
-
limitValue = void 0;
|
|
964
|
-
offsetValue = void 0;
|
|
965
|
-
projection = void 0;
|
|
966
|
-
constructor(options, modelName) {
|
|
967
|
-
this.context = options.context;
|
|
968
|
-
this.contract = options.context.contract;
|
|
969
|
-
this.modelName = modelName;
|
|
970
|
-
const tableName = this.contract.mappings.modelToTable?.[modelName];
|
|
971
|
-
if (!tableName) errorModelNotFound(modelName);
|
|
972
|
-
const table = schema(options.context).tables[tableName];
|
|
973
|
-
if (!table) errorTableNotFound(tableName);
|
|
974
|
-
this.table = table;
|
|
975
|
-
}
|
|
976
|
-
get where() {
|
|
977
|
-
const whereFn = (fn) => {
|
|
978
|
-
const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
|
|
979
|
-
builder["table"] = this.table;
|
|
980
|
-
builder.wherePredicate = fn(this._getModelAccessor());
|
|
981
|
-
builder.relationFilters = this.relationFilters;
|
|
982
|
-
builder.includes = this.includes;
|
|
983
|
-
builder.orderByExpr = this.orderByExpr;
|
|
984
|
-
builder.limitValue = this.limitValue;
|
|
985
|
-
builder.offsetValue = this.offsetValue;
|
|
986
|
-
builder.projection = this.projection;
|
|
987
|
-
return builder;
|
|
988
|
-
};
|
|
989
|
-
const related = this._createRelatedProxy();
|
|
990
|
-
return Object.assign(whereFn, { related });
|
|
991
|
-
}
|
|
992
|
-
get include() {
|
|
993
|
-
return this._createIncludeProxy();
|
|
994
|
-
}
|
|
995
|
-
_createIncludeProxy() {
|
|
996
|
-
const self = this;
|
|
997
|
-
const tableName = this.contract.mappings.modelToTable?.[this.modelName];
|
|
998
|
-
if (!tableName) return {};
|
|
999
|
-
const modelRelations = this.contract.relations?.[tableName];
|
|
1000
|
-
if (!modelRelations || typeof modelRelations !== "object") return {};
|
|
1001
|
-
return new Proxy({}, { get(_target, prop) {
|
|
1002
|
-
if (typeof prop !== "string") return;
|
|
1003
|
-
const relation = modelRelations[prop];
|
|
1004
|
-
if (!relation || typeof relation !== "object" || !("to" in relation)) throw planInvalid(`Relation ${prop} not found on model ${self.modelName}`);
|
|
1005
|
-
const childModelName = relation.to;
|
|
1006
|
-
const relationDef = relation;
|
|
1007
|
-
const relationName = prop;
|
|
1008
|
-
const includeFn = ((child) => {
|
|
1009
|
-
return self._applyInclude(relationName, childModelName, child, relationDef);
|
|
1010
|
-
});
|
|
1011
|
-
return includeFn;
|
|
1012
|
-
} });
|
|
1013
|
-
}
|
|
1014
|
-
_applyInclude(relationName, childModelName, childBuilderFn, relationDef) {
|
|
1015
|
-
const childTableName = this.contract.mappings.modelToTable?.[childModelName];
|
|
1016
|
-
if (!childTableName) errorModelNotFound(childModelName);
|
|
1017
|
-
const childTable = {
|
|
1018
|
-
kind: "table",
|
|
1019
|
-
name: childTableName
|
|
1020
|
-
};
|
|
1021
|
-
const childState = childBuilderFn(new OrmIncludeChildBuilderImpl({ context: this.context }, childModelName)).getState();
|
|
1022
|
-
const includeState = {
|
|
1023
|
-
relationName,
|
|
1024
|
-
childModelName,
|
|
1025
|
-
childTable,
|
|
1026
|
-
childWhere: childState.childWhere,
|
|
1027
|
-
childOrderBy: childState.childOrderBy,
|
|
1028
|
-
childLimit: childState.childLimit,
|
|
1029
|
-
childProjection: childState.childProjection,
|
|
1030
|
-
alias: relationName,
|
|
1031
|
-
relation: relationDef
|
|
1032
|
-
};
|
|
1033
|
-
const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
|
|
1034
|
-
builder["table"] = this.table;
|
|
1035
|
-
builder.wherePredicate = this.wherePredicate;
|
|
1036
|
-
builder.relationFilters = this.relationFilters;
|
|
1037
|
-
builder.includes = [...this.includes, includeState];
|
|
1038
|
-
builder.orderByExpr = this.orderByExpr;
|
|
1039
|
-
builder.limitValue = this.limitValue;
|
|
1040
|
-
builder.offsetValue = this.offsetValue;
|
|
1041
|
-
builder.projection = this.projection;
|
|
1042
|
-
return builder;
|
|
1043
|
-
}
|
|
1044
|
-
_createRelatedProxy() {
|
|
1045
|
-
const self = this;
|
|
1046
|
-
const tableName = this.contract.mappings.modelToTable?.[this.modelName];
|
|
1047
|
-
if (!tableName) return {};
|
|
1048
|
-
const modelRelations = this.contract.relations?.[tableName];
|
|
1049
|
-
if (!modelRelations || typeof modelRelations !== "object") return {};
|
|
1050
|
-
return new Proxy({}, { get(_target, prop) {
|
|
1051
|
-
if (typeof prop !== "string") return;
|
|
1052
|
-
const relation = modelRelations[prop];
|
|
1053
|
-
if (!relation || typeof relation !== "object" || !("to" in relation)) throw planInvalid(`Relation ${prop} not found on model ${self.modelName}`);
|
|
1054
|
-
const childModelName = relation.to;
|
|
1055
|
-
const relationDef = relation;
|
|
1056
|
-
const filterBuilder = new OrmRelationFilterBuilderImpl({ context: self.context }, childModelName);
|
|
1057
|
-
const modelAccessor = filterBuilder.getModelAccessor();
|
|
1058
|
-
const builderWithAccessor = Object.assign(filterBuilder, modelAccessor);
|
|
1059
|
-
return {
|
|
1060
|
-
some: (fn) => {
|
|
1061
|
-
const result = fn(builderWithAccessor);
|
|
1062
|
-
if (result && "kind" in result && result.kind === "binary") {
|
|
1063
|
-
const wrappedBuilder = new OrmRelationFilterBuilderImpl({ context: self.context }, childModelName);
|
|
1064
|
-
wrappedBuilder["wherePredicate"] = result;
|
|
1065
|
-
return self._applyRelationFilter(prop, childModelName, "some", () => wrappedBuilder, relationDef);
|
|
1066
|
-
}
|
|
1067
|
-
return self._applyRelationFilter(prop, childModelName, "some", () => result, relationDef);
|
|
1068
|
-
},
|
|
1069
|
-
none: (fn) => {
|
|
1070
|
-
const result = fn(builderWithAccessor);
|
|
1071
|
-
if (result && "kind" in result && result.kind === "binary") {
|
|
1072
|
-
const wrappedBuilder = new OrmRelationFilterBuilderImpl({ context: self.context }, childModelName);
|
|
1073
|
-
wrappedBuilder["wherePredicate"] = result;
|
|
1074
|
-
return self._applyRelationFilter(prop, childModelName, "none", () => wrappedBuilder, relationDef);
|
|
1075
|
-
}
|
|
1076
|
-
return self._applyRelationFilter(prop, childModelName, "none", () => result, relationDef);
|
|
1077
|
-
},
|
|
1078
|
-
every: (fn) => {
|
|
1079
|
-
const result = fn(builderWithAccessor);
|
|
1080
|
-
if (result && "kind" in result && result.kind === "binary") {
|
|
1081
|
-
const wrappedBuilder = new OrmRelationFilterBuilderImpl({ context: self.context }, childModelName);
|
|
1082
|
-
wrappedBuilder["wherePredicate"] = result;
|
|
1083
|
-
return self._applyRelationFilter(prop, childModelName, "every", () => wrappedBuilder, relationDef);
|
|
1084
|
-
}
|
|
1085
|
-
return self._applyRelationFilter(prop, childModelName, "every", () => result, relationDef);
|
|
1086
|
-
}
|
|
1087
|
-
};
|
|
1088
|
-
} });
|
|
1089
|
-
}
|
|
1090
|
-
_applyRelationFilter(relationName, childModelName, filterType, fn, relationDef) {
|
|
1091
|
-
const relationFilter = {
|
|
1092
|
-
relationName,
|
|
1093
|
-
childModelName,
|
|
1094
|
-
filterType,
|
|
1095
|
-
childWhere: fn(new OrmRelationFilterBuilderImpl({ context: this.context }, childModelName)).getWherePredicate(),
|
|
1096
|
-
relation: relationDef
|
|
1097
|
-
};
|
|
1098
|
-
const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
|
|
1099
|
-
builder["table"] = this.table;
|
|
1100
|
-
builder.wherePredicate = this.wherePredicate;
|
|
1101
|
-
builder.relationFilters = [...this.relationFilters, relationFilter];
|
|
1102
|
-
builder.includes = this.includes;
|
|
1103
|
-
builder.orderByExpr = this.orderByExpr;
|
|
1104
|
-
builder.limitValue = this.limitValue;
|
|
1105
|
-
builder.offsetValue = this.offsetValue;
|
|
1106
|
-
builder.projection = this.projection;
|
|
1107
|
-
return builder;
|
|
1108
|
-
}
|
|
1109
|
-
orderBy(fn) {
|
|
1110
|
-
const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
|
|
1111
|
-
builder["table"] = this.table;
|
|
1112
|
-
builder.wherePredicate = this.wherePredicate;
|
|
1113
|
-
builder.relationFilters = this.relationFilters;
|
|
1114
|
-
builder.includes = this.includes;
|
|
1115
|
-
builder.orderByExpr = fn(this._getModelAccessor());
|
|
1116
|
-
builder.limitValue = this.limitValue;
|
|
1117
|
-
builder.offsetValue = this.offsetValue;
|
|
1118
|
-
builder.projection = this.projection;
|
|
1119
|
-
return builder;
|
|
1120
|
-
}
|
|
1121
|
-
take(n) {
|
|
1122
|
-
const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
|
|
1123
|
-
builder["table"] = this.table;
|
|
1124
|
-
builder.wherePredicate = this.wherePredicate;
|
|
1125
|
-
builder.relationFilters = this.relationFilters;
|
|
1126
|
-
builder.includes = this.includes;
|
|
1127
|
-
builder.orderByExpr = this.orderByExpr;
|
|
1128
|
-
builder.limitValue = n;
|
|
1129
|
-
builder.offsetValue = this.offsetValue;
|
|
1130
|
-
builder.projection = this.projection;
|
|
1131
|
-
return builder;
|
|
1132
|
-
}
|
|
1133
|
-
skip(n) {
|
|
1134
|
-
const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
|
|
1135
|
-
builder["table"] = this.table;
|
|
1136
|
-
builder.wherePredicate = this.wherePredicate;
|
|
1137
|
-
builder.relationFilters = this.relationFilters;
|
|
1138
|
-
builder.includes = this.includes;
|
|
1139
|
-
builder.orderByExpr = this.orderByExpr;
|
|
1140
|
-
builder.limitValue = this.limitValue;
|
|
1141
|
-
builder.offsetValue = n;
|
|
1142
|
-
builder.projection = this.projection;
|
|
1143
|
-
return builder;
|
|
1144
|
-
}
|
|
1145
|
-
select(fn) {
|
|
1146
|
-
const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
|
|
1147
|
-
builder["table"] = this.table;
|
|
1148
|
-
builder.wherePredicate = this.wherePredicate;
|
|
1149
|
-
builder.relationFilters = this.relationFilters;
|
|
1150
|
-
builder.includes = this.includes;
|
|
1151
|
-
builder.orderByExpr = this.orderByExpr;
|
|
1152
|
-
builder.limitValue = this.limitValue;
|
|
1153
|
-
builder.offsetValue = this.offsetValue;
|
|
1154
|
-
builder.projection = fn(this._getModelAccessor());
|
|
1155
|
-
return builder;
|
|
1156
|
-
}
|
|
1157
|
-
findMany(options) {
|
|
1158
|
-
const paramsMap = options?.params ?? {};
|
|
1159
|
-
if (!this.contract.storage.tables[this.table.name]) errorUnknownTable(this.table.name);
|
|
1160
|
-
const paramDescriptors = [];
|
|
1161
|
-
const paramValues = [];
|
|
1162
|
-
const paramCodecs = {};
|
|
1163
|
-
const projectionInput = this.projection ?? (() => {
|
|
1164
|
-
const modelAccessor = this._getModelAccessor();
|
|
1165
|
-
const defaultProjection = {};
|
|
1166
|
-
for (const fieldName in modelAccessor) defaultProjection[fieldName] = modelAccessor[fieldName];
|
|
1167
|
-
return defaultProjection;
|
|
1168
|
-
})();
|
|
1169
|
-
const { includesAst, includesForMeta } = buildIncludeAsts({
|
|
1170
|
-
includes: this.includes,
|
|
1171
|
-
contract: this.contract,
|
|
1172
|
-
context: this.context,
|
|
1173
|
-
modelName: this.modelName,
|
|
1174
|
-
paramsMap,
|
|
1175
|
-
paramDescriptors,
|
|
1176
|
-
paramValues,
|
|
1177
|
-
paramCodecs
|
|
1178
|
-
});
|
|
1179
|
-
const projectionState = buildProjectionState(this.table, projectionInput, includesForMeta.length > 0 ? includesForMeta : void 0);
|
|
1180
|
-
const whereResult = this.wherePredicate ? buildWhereExpr(this.wherePredicate, this.contract, paramsMap, paramDescriptors, paramValues) : void 0;
|
|
1181
|
-
const whereExpr = whereResult?.expr;
|
|
1182
|
-
if (whereResult?.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
1183
|
-
const orderByClause = buildOrderByClause(this.orderByExpr);
|
|
1184
|
-
const projectEntries = buildProjectionItems(projectionState, includesForMeta);
|
|
1185
|
-
const ast = buildSelectAst({
|
|
1186
|
-
table: this.table,
|
|
1187
|
-
projectEntries,
|
|
1188
|
-
...includesAst.length > 0 ? { includesAst } : {},
|
|
1189
|
-
...whereExpr ? { whereExpr } : {},
|
|
1190
|
-
...orderByClause ? { orderByClause } : {},
|
|
1191
|
-
...this.limitValue !== void 0 ? { limit: this.limitValue } : {}
|
|
1192
|
-
});
|
|
1193
|
-
const planMeta = buildMeta({
|
|
1194
|
-
contract: this.contract,
|
|
1195
|
-
table: createTableRef(this.table.name),
|
|
1196
|
-
projection: projectionState,
|
|
1197
|
-
includes: includesForMeta.length > 0 ? includesForMeta : void 0,
|
|
1198
|
-
paramDescriptors,
|
|
1199
|
-
paramCodecs: Object.keys(paramCodecs).length > 0 ? paramCodecs : void 0,
|
|
1200
|
-
where: this.wherePredicate,
|
|
1201
|
-
orderBy: this.orderByExpr
|
|
1202
|
-
});
|
|
1203
|
-
if (this.relationFilters.length > 0) {
|
|
1204
|
-
const existsExprs = buildExistsSubqueries(this.relationFilters, this.contract, this.modelName, options);
|
|
1205
|
-
if (existsExprs.length > 0) {
|
|
1206
|
-
const combinedWhere = combineWhereClauses(ast.where, existsExprs);
|
|
1207
|
-
const modifiedAst = {
|
|
1208
|
-
...ast,
|
|
1209
|
-
...combinedWhere !== void 0 ? { where: combinedWhere } : {}
|
|
1210
|
-
};
|
|
1211
|
-
return Object.freeze({
|
|
1212
|
-
ast: modifiedAst,
|
|
1213
|
-
params: paramValues,
|
|
1214
|
-
meta: {
|
|
1215
|
-
...planMeta,
|
|
1216
|
-
lane: "orm"
|
|
1217
|
-
}
|
|
1218
|
-
});
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
return Object.freeze({
|
|
1222
|
-
ast,
|
|
1223
|
-
params: paramValues,
|
|
1224
|
-
meta: {
|
|
1225
|
-
...planMeta,
|
|
1226
|
-
lane: "orm"
|
|
1227
|
-
}
|
|
1228
|
-
});
|
|
1229
|
-
}
|
|
1230
|
-
findFirst(options) {
|
|
1231
|
-
return this.take(1).findMany(options);
|
|
1232
|
-
}
|
|
1233
|
-
findUnique(where, options) {
|
|
1234
|
-
return this.where(where).take(1).findMany(options);
|
|
1235
|
-
}
|
|
1236
|
-
create(data, options) {
|
|
1237
|
-
return buildInsertPlan(createOrmContext(this.context), this.modelName, data, options);
|
|
1238
|
-
}
|
|
1239
|
-
update(where, data, options) {
|
|
1240
|
-
return buildUpdatePlan(createOrmContext(this.context), this.modelName, where, () => this._getModelAccessor(), data, options);
|
|
1241
|
-
}
|
|
1242
|
-
delete(where, options) {
|
|
1243
|
-
return buildDeletePlan(createOrmContext(this.context), this.modelName, where, () => this._getModelAccessor(), options);
|
|
1244
|
-
}
|
|
1245
|
-
_getModelAccessor() {
|
|
1246
|
-
const tableName = this.contract.mappings.modelToTable?.[this.modelName];
|
|
1247
|
-
if (!tableName) errorModelNotFound(this.modelName);
|
|
1248
|
-
const table = schema(this.context).tables[tableName];
|
|
1249
|
-
if (!table) errorTableNotFound(tableName);
|
|
1250
|
-
const accessor = {};
|
|
1251
|
-
const model = this.contract.models[this.modelName];
|
|
1252
|
-
if (!model || typeof model !== "object" || !("fields" in model)) throw planInvalid(`Model ${this.modelName} does not have fields`);
|
|
1253
|
-
const modelFields = model.fields;
|
|
1254
|
-
for (const fieldName in modelFields) {
|
|
1255
|
-
const field = modelFields[fieldName];
|
|
1256
|
-
if (!field) continue;
|
|
1257
|
-
const columnName = this.contract.mappings.fieldToColumn?.[this.modelName]?.[fieldName] ?? field.column ?? fieldName;
|
|
1258
|
-
const column = table.columns[columnName];
|
|
1259
|
-
if (column) accessor[fieldName] = column;
|
|
1260
|
-
}
|
|
1261
|
-
return accessor;
|
|
1262
|
-
}
|
|
1263
|
-
};
|
|
1264
|
-
|
|
1265
|
-
//#endregion
|
|
1266
|
-
//#region src/orm.ts
|
|
1267
|
-
function orm(options) {
|
|
1268
|
-
const contract = options.context.contract;
|
|
1269
|
-
return new Proxy({}, {
|
|
1270
|
-
get(_target, prop) {
|
|
1271
|
-
if (typeof prop !== "string") return;
|
|
1272
|
-
const modelName = prop.charAt(0).toUpperCase() + prop.slice(1);
|
|
1273
|
-
if (!contract.models || typeof contract.models !== "object" || !(modelName in contract.models)) throw planInvalid(`Model ${prop} (resolved to ${modelName}) not found in contract`);
|
|
1274
|
-
return () => new OrmModelBuilderImpl(options, modelName);
|
|
1275
|
-
},
|
|
1276
|
-
has(_target, prop) {
|
|
1277
|
-
if (typeof prop !== "string") return false;
|
|
1278
|
-
const modelName = prop.charAt(0).toUpperCase() + prop.slice(1);
|
|
1279
|
-
return contract.models && typeof contract.models === "object" && modelName in contract.models;
|
|
1280
|
-
}
|
|
1281
|
-
});
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
|
-
//#endregion
|
|
1285
|
-
export { OrmModelBuilderImpl as n, orm as t };
|
|
1286
|
-
//# sourceMappingURL=orm-BYJaTDLm.mjs.map
|