orchid-orm 1.76.4 → 1.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bun.d.ts +4 -4
- package/dist/bun.js.map +1 -1
- package/dist/bun.mjs.map +1 -1
- package/dist/index.d.ts +871 -133
- package/dist/index.js +611 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +612 -34
- package/dist/index.mjs.map +1 -1
- package/dist/migrations/index.js +104 -63
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/index.mjs +106 -65
- package/dist/migrations/index.mjs.map +1 -1
- package/dist/node-postgres.d.ts +4 -4
- package/dist/node-postgres.js.map +1 -1
- package/dist/node-postgres.mjs.map +1 -1
- package/dist/postgres-js.d.ts +4 -4
- package/dist/postgres-js.js.map +1 -1
- package/dist/postgres-js.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DynamicRawSQL, QueryHooks, RawSql, VirtualColumn, _appendQuery, _appendQueryOnUpsertCreate, _clone, _createDbSqlMethod, _hookSelectColumns, _initQueryBuilder, _orCreate, _prependWith, _queryCreate, _queryCreateMany, _queryCreateManyFrom, _queryDefaults, _queryDelete, _queryFindBy, _queryFindByOptional, _queryHookAfterCreate, _queryHookAfterUpdate, _queryInsert, _queryInsertMany, _queryJoinOn, _queryRows, _querySelect, _queryTake, _queryTakeOptional, _queryUpdate, _queryUpdateOrThrow, _queryUpsert, _queryWhere, _queryWhereExists, _queryWhereIn, applyMixins, cloneQueryBaseUnscoped, defaultSchemaConfig, emptyArray, emptyObject, getCallerFilePath, getClonedQueryData, getColumnTypes, getFreeAlias, getPrimaryKeys, getQueryAs, getShapeFromSelect, getStackTrace, internalSchemaConfig, isExpression, isQueryReturnsAll, makeColumnTypes, noop, objectHasValues, parseTableData, pick, prepareSubQueryForSql, pushQueryOnForOuter, setQueryObjectValueImmutable, toArray, toSnakeCase } from "pqb/internal";
|
|
1
|
+
import { DynamicRawSQL, QueryHooks, RawSql, VirtualColumn, _appendQuery, _appendQueryOnUpsertCreate, _clone, _createDbSqlMethod, _hookSelectColumns, _initQueryBuilder, _onUpsertUpdate, _orCreate, _prependWith, _prependWithOnUpsertCreate, _queryCreate, _queryCreateMany, _queryCreateManyFrom, _queryDefaults, _queryDelete, _queryFindBy, _queryFindByOptional, _queryHookAfterCreate, _queryHookAfterUpdate, _queryInsert, _queryInsertMany, _queryInsertManyFrom, _queryJoinOn, _queryRows, _querySelect, _queryTake, _queryTakeOptional, _queryUpdate, _queryUpdateOrThrow, _queryUpsert, _queryWhere, _queryWhereExists, _queryWhereIn, applyMixins, cloneQueryBaseUnscoped, defaultSchemaConfig, emptyArray, emptyObject, getCallerFilePath, getClonedQueryData, getColumnTypes, getForeignKeyTableInstance, getFreeAlias, getPrimaryKeys, getQueryAs, getShapeFromSelect, getStackTrace, internalSchemaConfig, isExpression, isQueryReturnsAll, makeColumnTypes, noop, objectHasValues, parseTableData, parseTableDataInput, pick, prepareSubQueryForSql, pushQueryOnForOuter, setQueryObjectValueImmutable, tableDataMethods, toArray, toSnakeCase } from "pqb/internal";
|
|
2
2
|
import { Db, NotFoundError, OrchidOrmInternalError } from "pqb";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
export * from "pqb";
|
|
@@ -152,6 +152,422 @@ function createBaseTable({ schemaConfig = defaultSchemaConfig, columnTypes: colu
|
|
|
152
152
|
base.prototype.autoForeignKeys = autoForeignKeys === true ? {} : autoForeignKeys || void 0;
|
|
153
153
|
return base;
|
|
154
154
|
}
|
|
155
|
+
const makeRelationEndpoint = (id, columns, on, through, source) => {
|
|
156
|
+
const endpoint = {
|
|
157
|
+
id,
|
|
158
|
+
columns,
|
|
159
|
+
on,
|
|
160
|
+
relationThrough: through,
|
|
161
|
+
relationSource: source,
|
|
162
|
+
where(conditions) {
|
|
163
|
+
return makeRelationEndpoint(id, columns, {
|
|
164
|
+
...on,
|
|
165
|
+
...conditions
|
|
166
|
+
}, through, source);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
if (through) {
|
|
170
|
+
endpoint.through = through;
|
|
171
|
+
endpoint.source = source;
|
|
172
|
+
} else endpoint.through = (through, source) => makeRelationEndpoint(id, columns, on, through, source);
|
|
173
|
+
return endpoint;
|
|
174
|
+
};
|
|
175
|
+
const getRelationTargetId = (target) => {
|
|
176
|
+
const item = target;
|
|
177
|
+
const id = item.id ?? item.data?.id;
|
|
178
|
+
if (!id) throw new Error("Cannot get relation target id");
|
|
179
|
+
return id;
|
|
180
|
+
};
|
|
181
|
+
const getRelationEndpointOptions = (endpoint) => endpoint.on ? {
|
|
182
|
+
references: endpoint.columns,
|
|
183
|
+
on: endpoint.on
|
|
184
|
+
} : { references: endpoint.columns };
|
|
185
|
+
const getRelationThroughOptions = (endpoint) => {
|
|
186
|
+
const options = {
|
|
187
|
+
through: endpoint.relationThrough,
|
|
188
|
+
source: endpoint.relationSource
|
|
189
|
+
};
|
|
190
|
+
if (endpoint.on) options.on = endpoint.on;
|
|
191
|
+
return options;
|
|
192
|
+
};
|
|
193
|
+
const makeRelationBuilder = () => {
|
|
194
|
+
const withRequired = (relation) => {
|
|
195
|
+
const item = relation;
|
|
196
|
+
item.required = (value = true) => {
|
|
197
|
+
item.options.required = value;
|
|
198
|
+
return item;
|
|
199
|
+
};
|
|
200
|
+
item.foreignKey = (value = true) => {
|
|
201
|
+
item.options.foreignKey = value;
|
|
202
|
+
return item;
|
|
203
|
+
};
|
|
204
|
+
return item;
|
|
205
|
+
};
|
|
206
|
+
const builder = ((...columns) => ({
|
|
207
|
+
belongsTo: (fn) => {
|
|
208
|
+
const endpoint = fn();
|
|
209
|
+
return withRequired({
|
|
210
|
+
type: "belongsTo",
|
|
211
|
+
id: getRelationTargetId(endpoint),
|
|
212
|
+
options: {
|
|
213
|
+
columns,
|
|
214
|
+
...getRelationEndpointOptions(endpoint)
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
hasOne: (fn) => {
|
|
219
|
+
const endpoint = fn();
|
|
220
|
+
return withRequired({
|
|
221
|
+
type: "hasOne",
|
|
222
|
+
id: getRelationTargetId(endpoint),
|
|
223
|
+
options: {
|
|
224
|
+
columns,
|
|
225
|
+
...getRelationEndpointOptions(endpoint)
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
hasMany: (fn) => {
|
|
230
|
+
const endpoint = fn();
|
|
231
|
+
return withRequired({
|
|
232
|
+
type: "hasMany",
|
|
233
|
+
id: getRelationTargetId(endpoint),
|
|
234
|
+
options: {
|
|
235
|
+
columns,
|
|
236
|
+
...getRelationEndpointOptions(endpoint)
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
},
|
|
240
|
+
hasAndBelongsToMany: (fn) => {
|
|
241
|
+
const endpoint = fn();
|
|
242
|
+
const options = { columns };
|
|
243
|
+
return {
|
|
244
|
+
type: "hasAndBelongsToMany",
|
|
245
|
+
id: getRelationTargetId(endpoint),
|
|
246
|
+
options,
|
|
247
|
+
through(joinTable, selfColumns, relColumns, throughOptions) {
|
|
248
|
+
this.options.references = Array.isArray(selfColumns) ? selfColumns : [selfColumns];
|
|
249
|
+
this.options.on = endpoint.on;
|
|
250
|
+
const schemaIndex = joinTable.indexOf(".");
|
|
251
|
+
const parsedSchema = schemaIndex === -1 ? void 0 : joinTable.slice(0, schemaIndex);
|
|
252
|
+
const table = schemaIndex === -1 ? joinTable : joinTable.slice(schemaIndex + 1);
|
|
253
|
+
this.options.through = {
|
|
254
|
+
schema: throughOptions?.schema ?? parsedSchema,
|
|
255
|
+
table,
|
|
256
|
+
snakeCase: throughOptions?.joinTableSnakeCase,
|
|
257
|
+
columns: Array.isArray(relColumns) ? relColumns : [relColumns],
|
|
258
|
+
references: endpoint.columns
|
|
259
|
+
};
|
|
260
|
+
return this;
|
|
261
|
+
},
|
|
262
|
+
foreignKey(value) {
|
|
263
|
+
if (value === false) {
|
|
264
|
+
this.options.foreignKey = false;
|
|
265
|
+
if (this.options.through) this.options.through.foreignKey = false;
|
|
266
|
+
} else if (value === void 0 || value === true) {
|
|
267
|
+
this.options.foreignKey = true;
|
|
268
|
+
if (this.options.through) this.options.through.foreignKey = true;
|
|
269
|
+
} else if ("forBothTables" in value) {
|
|
270
|
+
this.options.foreignKey = value.forBothTables ?? true;
|
|
271
|
+
if (this.options.through) this.options.through.foreignKey = value.forBothTables ?? true;
|
|
272
|
+
} else {
|
|
273
|
+
this.options.foreignKey = value.forThisTable ?? true;
|
|
274
|
+
if (this.options.through) this.options.through.foreignKey = value.forRelatedTable ?? true;
|
|
275
|
+
}
|
|
276
|
+
return this;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}));
|
|
281
|
+
builder.hasOne = (fn) => {
|
|
282
|
+
const endpoint = fn();
|
|
283
|
+
return withRequired({
|
|
284
|
+
type: "hasOne",
|
|
285
|
+
id: getRelationTargetId(endpoint),
|
|
286
|
+
options: getRelationThroughOptions(endpoint)
|
|
287
|
+
});
|
|
288
|
+
};
|
|
289
|
+
builder.hasMany = (fn) => {
|
|
290
|
+
const endpoint = fn();
|
|
291
|
+
return {
|
|
292
|
+
type: "hasMany",
|
|
293
|
+
id: getRelationTargetId(endpoint),
|
|
294
|
+
options: getRelationThroughOptions(endpoint)
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
return builder;
|
|
298
|
+
};
|
|
299
|
+
var InitHookTarget = class extends QueryHooks {
|
|
300
|
+
constructor(q) {
|
|
301
|
+
super();
|
|
302
|
+
this.q = q;
|
|
303
|
+
}
|
|
304
|
+
clone() {
|
|
305
|
+
return this;
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
const setDefinitionSchemaMethods = (definition, schema, shape) => {
|
|
309
|
+
definition.prototype ??= {};
|
|
310
|
+
definition.prototype.columns = { shape };
|
|
311
|
+
definition.inputSchema = schema.inputSchema;
|
|
312
|
+
definition.outputSchema = schema.outputSchema;
|
|
313
|
+
definition.querySchema = schema.querySchema;
|
|
314
|
+
definition.pkeySchema = schema.pkeySchema;
|
|
315
|
+
definition.createSchema = schema.createSchema;
|
|
316
|
+
definition.updateSchema = schema.updateSchema;
|
|
317
|
+
};
|
|
318
|
+
const createTableFactory = (options) => {
|
|
319
|
+
const schema = (options?.schemaConfig ?? defaultSchemaConfig)();
|
|
320
|
+
const defaultColumnTypes = makeColumnTypes(schema);
|
|
321
|
+
const columnTypesOption = options?.columnTypes;
|
|
322
|
+
const columnTypes = typeof columnTypesOption === "function" ? columnTypesOption(defaultColumnTypes) : columnTypesOption || defaultColumnTypes;
|
|
323
|
+
const defineTableExportAs = options?.defineTableExportAs ?? "defineTable";
|
|
324
|
+
const filePathOrStack = options?.filePath || getStackTrace();
|
|
325
|
+
let filePath;
|
|
326
|
+
const defineTable = ((table, optionsOrT, maybeT) => {
|
|
327
|
+
const tableOptions = typeof optionsOrT === "function" ? void 0 : optionsOrT;
|
|
328
|
+
const t = typeof optionsOrT === "function" ? optionsOrT : maybeT;
|
|
329
|
+
if (!t) throw new Error("Column definitions are required");
|
|
330
|
+
const id = tableOptions?.id ?? table;
|
|
331
|
+
const shape = getColumnTypes(columnTypes, t, options?.nowSQL, options?.language);
|
|
332
|
+
const tableData = {};
|
|
333
|
+
const snakeCase = tableOptions?.snakeCase ?? options?.snakeCase;
|
|
334
|
+
if (snakeCase) for (const key in shape) {
|
|
335
|
+
const column = shape[key];
|
|
336
|
+
if (column.data.name) continue;
|
|
337
|
+
const snakeName = toSnakeCase(key);
|
|
338
|
+
if (snakeName !== key) column.data.name = snakeName;
|
|
339
|
+
}
|
|
340
|
+
const nameInDb = tableOptions?.nameInDb ?? (snakeCase ? toSnakeCase(table) : table);
|
|
341
|
+
const autoForeignKeys = tableOptions?.autoForeignKeys !== void 0 ? tableOptions.autoForeignKeys : options?.autoForeignKeys;
|
|
342
|
+
const instance = {
|
|
343
|
+
id,
|
|
344
|
+
table,
|
|
345
|
+
nameInDb,
|
|
346
|
+
schema: tableOptions?.schema,
|
|
347
|
+
noPrimaryKey: tableOptions?.noPrimaryKey,
|
|
348
|
+
snakeCase,
|
|
349
|
+
comment: tableOptions?.comment,
|
|
350
|
+
generatorIgnore: tableOptions?.generatorIgnore,
|
|
351
|
+
readOnly: tableOptions?.readOnly,
|
|
352
|
+
columns: {
|
|
353
|
+
shape,
|
|
354
|
+
data: tableData
|
|
355
|
+
},
|
|
356
|
+
types: columnTypes,
|
|
357
|
+
filePath: options?.filePath ?? "",
|
|
358
|
+
language: options?.language,
|
|
359
|
+
autoForeignKeys: autoForeignKeys === true ? {} : autoForeignKeys || void 0,
|
|
360
|
+
q: {}
|
|
361
|
+
};
|
|
362
|
+
const definition = ((...columns) => makeRelationEndpoint(id, columns));
|
|
363
|
+
definition.data = {
|
|
364
|
+
id,
|
|
365
|
+
table,
|
|
366
|
+
name: void 0,
|
|
367
|
+
relations: void 0,
|
|
368
|
+
columns: shape,
|
|
369
|
+
types: void 0,
|
|
370
|
+
computed: void 0,
|
|
371
|
+
scopes: void 0,
|
|
372
|
+
readOnly: tableOptions?.readOnly,
|
|
373
|
+
tableData
|
|
374
|
+
};
|
|
375
|
+
setDefinitionSchemaMethods(definition, schema, shape);
|
|
376
|
+
definition.exportAs = defineTableExportAs;
|
|
377
|
+
definition.nowSQL = options?.nowSQL;
|
|
378
|
+
definition.instance = () => {
|
|
379
|
+
const { computed, relations, scopes, softDelete, readOnly } = definition.data;
|
|
380
|
+
instance.computed = computed;
|
|
381
|
+
instance.scopes = scopes;
|
|
382
|
+
instance.softDelete = softDelete;
|
|
383
|
+
instance.readOnly = readOnly;
|
|
384
|
+
instance.relations = typeof relations === "function" ? relations(makeRelationBuilder()) : relations;
|
|
385
|
+
return instance;
|
|
386
|
+
};
|
|
387
|
+
definition.where = function(conditions) {
|
|
388
|
+
return makeRelationEndpoint(id, [], conditions);
|
|
389
|
+
};
|
|
390
|
+
definition.through = (through, source) => makeRelationEndpoint(id, [], void 0, through, source);
|
|
391
|
+
definition.primaryKey = (...args) => {
|
|
392
|
+
parseTableDataInput(tableData, tableDataMethods.primaryKey(...args));
|
|
393
|
+
return definition;
|
|
394
|
+
};
|
|
395
|
+
definition.index = (...args) => {
|
|
396
|
+
parseTableDataInput(tableData, tableDataMethods.index(...args));
|
|
397
|
+
return definition;
|
|
398
|
+
};
|
|
399
|
+
definition.searchIndex = (...args) => {
|
|
400
|
+
parseTableDataInput(tableData, tableDataMethods.searchIndex(...args));
|
|
401
|
+
return definition;
|
|
402
|
+
};
|
|
403
|
+
definition.unique = (...args) => {
|
|
404
|
+
parseTableDataInput(tableData, tableDataMethods.unique(...args));
|
|
405
|
+
return definition;
|
|
406
|
+
};
|
|
407
|
+
definition.exclude = (...args) => {
|
|
408
|
+
parseTableDataInput(tableData, tableDataMethods.exclude(...args));
|
|
409
|
+
return definition;
|
|
410
|
+
};
|
|
411
|
+
definition.check = (...args) => {
|
|
412
|
+
parseTableDataInput(tableData, tableDataMethods.check(...args));
|
|
413
|
+
return definition;
|
|
414
|
+
};
|
|
415
|
+
definition.softDelete = (column) => {
|
|
416
|
+
definition.data.softDelete = column || true;
|
|
417
|
+
return definition;
|
|
418
|
+
};
|
|
419
|
+
definition.computed = (computed) => {
|
|
420
|
+
definition.data.computed = computed;
|
|
421
|
+
return definition;
|
|
422
|
+
};
|
|
423
|
+
definition.scopes = (scopes) => {
|
|
424
|
+
definition.data.scopes = scopes;
|
|
425
|
+
return definition;
|
|
426
|
+
};
|
|
427
|
+
definition.grants = (grants) => {
|
|
428
|
+
instance.grants = grants;
|
|
429
|
+
return definition;
|
|
430
|
+
};
|
|
431
|
+
definition.rls = (rls) => {
|
|
432
|
+
instance.rls = rls;
|
|
433
|
+
return definition;
|
|
434
|
+
};
|
|
435
|
+
definition.init = (fn) => {
|
|
436
|
+
instance.init = function(orm) {
|
|
437
|
+
fn(orm, new InitHookTarget(this.q));
|
|
438
|
+
};
|
|
439
|
+
return definition;
|
|
440
|
+
};
|
|
441
|
+
definition.foreignKey = (columns, fnOrTable, foreignColumns, options) => {
|
|
442
|
+
parseTableDataInput(tableData, tableDataMethods.foreignKey(columns, fnOrTable, foreignColumns, options));
|
|
443
|
+
return definition;
|
|
444
|
+
};
|
|
445
|
+
definition.relations = (fn) => {
|
|
446
|
+
definition.data.relations = fn;
|
|
447
|
+
return definition;
|
|
448
|
+
};
|
|
449
|
+
return definition;
|
|
450
|
+
});
|
|
451
|
+
defineTable.getFilePath = () => {
|
|
452
|
+
if (filePath) return filePath;
|
|
453
|
+
if (typeof filePathOrStack === "string") return filePath = filePathOrStack;
|
|
454
|
+
filePath = getCallerFilePath(filePathOrStack);
|
|
455
|
+
if (filePath) return filePath;
|
|
456
|
+
throw new Error("Failed to determine file path of a table factory. Please set the `filePath` option of `createTableFactory` manually.");
|
|
457
|
+
};
|
|
458
|
+
defineTable.types = columnTypes;
|
|
459
|
+
defineTable.exportAs = defineTableExportAs;
|
|
460
|
+
defineTable.nowSQL = options?.nowSQL;
|
|
461
|
+
defineTable.snakeCase = options?.snakeCase;
|
|
462
|
+
defineTable.language = options?.language;
|
|
463
|
+
const defineView = ((name, optionsOrT, maybeT) => {
|
|
464
|
+
const viewOptions = typeof optionsOrT === "function" ? void 0 : optionsOrT;
|
|
465
|
+
const materialized = viewOptions?.materialized;
|
|
466
|
+
const readOnly = materialized || viewOptions?.readOnly !== false;
|
|
467
|
+
const t = typeof optionsOrT === "function" ? optionsOrT : maybeT;
|
|
468
|
+
if (!t) throw new Error("Column definitions are required");
|
|
469
|
+
const language = viewOptions?.language ?? options?.language;
|
|
470
|
+
const snakeCase = viewOptions?.snakeCase ?? options?.snakeCase;
|
|
471
|
+
const shape = getColumnTypes(columnTypes, t, options?.nowSQL, language);
|
|
472
|
+
const tableData = {};
|
|
473
|
+
const nameInDb = viewOptions?.nameInDb ?? (snakeCase ? toSnakeCase(name) : name);
|
|
474
|
+
if (snakeCase) for (const key in shape) {
|
|
475
|
+
const column = shape[key];
|
|
476
|
+
if (column.data.name) continue;
|
|
477
|
+
const snakeName = toSnakeCase(key);
|
|
478
|
+
if (snakeName !== key) column.data.name = snakeName;
|
|
479
|
+
}
|
|
480
|
+
const instance = {
|
|
481
|
+
id: viewOptions?.id ?? name,
|
|
482
|
+
name,
|
|
483
|
+
nameInDb,
|
|
484
|
+
schema: viewOptions?.schema,
|
|
485
|
+
snakeCase,
|
|
486
|
+
columns: {
|
|
487
|
+
shape,
|
|
488
|
+
data: tableData
|
|
489
|
+
},
|
|
490
|
+
types: columnTypes,
|
|
491
|
+
filePath: options?.filePath ?? "",
|
|
492
|
+
language,
|
|
493
|
+
readOnly,
|
|
494
|
+
materialized,
|
|
495
|
+
generatorIgnore: viewOptions?.generatorIgnore,
|
|
496
|
+
withData: viewOptions?.withData,
|
|
497
|
+
sql: viewOptions?.sql,
|
|
498
|
+
recursive: viewOptions?.recursive,
|
|
499
|
+
checkOption: viewOptions?.checkOption,
|
|
500
|
+
securityBarrier: viewOptions?.securityBarrier,
|
|
501
|
+
securityInvoker: viewOptions?.securityInvoker,
|
|
502
|
+
q: {}
|
|
503
|
+
};
|
|
504
|
+
const viewId = viewOptions?.id ?? name;
|
|
505
|
+
const definition = ((...columns) => makeRelationEndpoint(viewId, columns));
|
|
506
|
+
definition.data = {
|
|
507
|
+
id: viewOptions?.id ?? name,
|
|
508
|
+
table: void 0,
|
|
509
|
+
name,
|
|
510
|
+
relations: void 0,
|
|
511
|
+
columns: shape,
|
|
512
|
+
types: void 0,
|
|
513
|
+
computed: void 0,
|
|
514
|
+
scopes: void 0,
|
|
515
|
+
readOnly,
|
|
516
|
+
materialized,
|
|
517
|
+
tableData
|
|
518
|
+
};
|
|
519
|
+
setDefinitionSchemaMethods(definition, schema, shape);
|
|
520
|
+
definition.nowSQL = options?.nowSQL;
|
|
521
|
+
definition.instance = () => {
|
|
522
|
+
const { computed, relations, scopes, softDelete } = definition.data;
|
|
523
|
+
instance.computed = computed;
|
|
524
|
+
instance.scopes = scopes;
|
|
525
|
+
instance.softDelete = softDelete;
|
|
526
|
+
instance.relations = typeof relations === "function" ? relations(makeRelationBuilder()) : relations;
|
|
527
|
+
return instance;
|
|
528
|
+
};
|
|
529
|
+
definition.query = (fn) => {
|
|
530
|
+
instance.init = (orm) => {
|
|
531
|
+
instance.query = fn(orm);
|
|
532
|
+
};
|
|
533
|
+
return definition;
|
|
534
|
+
};
|
|
535
|
+
definition.through = (through, source) => makeRelationEndpoint(viewId, [], void 0, through, source);
|
|
536
|
+
definition.softDelete = (column) => {
|
|
537
|
+
definition.data.softDelete = column || true;
|
|
538
|
+
return definition;
|
|
539
|
+
};
|
|
540
|
+
definition.computed = (computed) => {
|
|
541
|
+
definition.data.computed = computed;
|
|
542
|
+
return definition;
|
|
543
|
+
};
|
|
544
|
+
definition.scopes = (scopes) => {
|
|
545
|
+
definition.data.scopes = scopes;
|
|
546
|
+
return definition;
|
|
547
|
+
};
|
|
548
|
+
definition.grants = (grants) => {
|
|
549
|
+
instance.grants = grants;
|
|
550
|
+
return definition;
|
|
551
|
+
};
|
|
552
|
+
definition.init = (fn) => {
|
|
553
|
+
instance.init = function(orm) {
|
|
554
|
+
fn(orm, new InitHookTarget(this.q));
|
|
555
|
+
};
|
|
556
|
+
return definition;
|
|
557
|
+
};
|
|
558
|
+
definition.relations = (fn) => {
|
|
559
|
+
definition.data.relations = fn;
|
|
560
|
+
return definition;
|
|
561
|
+
};
|
|
562
|
+
return definition;
|
|
563
|
+
});
|
|
564
|
+
return {
|
|
565
|
+
defineTable,
|
|
566
|
+
defineView,
|
|
567
|
+
sql: _createDbSqlMethod(columnTypes),
|
|
568
|
+
exportAs: defineTableExportAs
|
|
569
|
+
};
|
|
570
|
+
};
|
|
155
571
|
const throwIfQueryReturnsAllForNestedUpdate = (q, params) => {
|
|
156
572
|
if (!(params.set || params.create || params.upsert) || !isQueryReturnsAll(q)) return;
|
|
157
573
|
let key;
|
|
@@ -231,7 +647,7 @@ const addAutoForeignKey = (tableConfig, from, to, primaryKeys, foreignKeys, opti
|
|
|
231
647
|
fkeyTable = fkey.fnOrTable;
|
|
232
648
|
fkeyColumn = getColumnKeyFromDbName(to, fkeyColumn);
|
|
233
649
|
} else {
|
|
234
|
-
const instance = fkey.fnOrTable()
|
|
650
|
+
const instance = getForeignKeyTableInstance(fkey.fnOrTable());
|
|
235
651
|
fkeyTable = instance.nameInDb || instance.table;
|
|
236
652
|
}
|
|
237
653
|
if (toTable === fkeyTable && pkey === fkeyColumn) return;
|
|
@@ -247,7 +663,7 @@ const addAutoForeignKey = (tableConfig, from, to, primaryKeys, foreignKeys, opti
|
|
|
247
663
|
let sameForeignTable = false;
|
|
248
664
|
if (typeof refs.fnOrTable === "string") sameForeignTable = refs.fnOrTable === toTable && refs.foreignColumns.every((column, i) => getColumnKeyFromDbName(to, column) === sortedPkeys[i]);
|
|
249
665
|
else {
|
|
250
|
-
const instance = refs.fnOrTable()
|
|
666
|
+
const instance = getForeignKeyTableInstance(refs.fnOrTable());
|
|
251
667
|
sameForeignTable = (instance.nameInDb || instance.table) === toTable && refs.foreignColumns.every((column, i) => column === sortedPkeys[i]);
|
|
252
668
|
}
|
|
253
669
|
if (refs.columns.length === sortedFkeys.length && refs.columns.every((column, i) => column === sortedFkeys[i]) && refs.foreignColumns.length === sortedPkeys.length && sameForeignTable) return;
|
|
@@ -394,24 +810,39 @@ var BelongsToVirtualColumn = class extends VirtualColumn {
|
|
|
394
810
|
if (!nestedCreateItems) return;
|
|
395
811
|
for (const key of foreignKeys) if (!ctx.columns.has(key)) ctx.columns.set(key, ctx.columns.size);
|
|
396
812
|
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
397
|
-
if (create)
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
813
|
+
if (create) {
|
|
814
|
+
const selectPKeys = query.select(...primaryKeys);
|
|
815
|
+
let createQuery;
|
|
816
|
+
if (queryForCreate.q.type === "upsert") {
|
|
817
|
+
const createWhereNotExists = new RawSql("");
|
|
818
|
+
_onUpsertUpdate(queryForCreate, (as) => {
|
|
819
|
+
createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
|
|
403
820
|
});
|
|
404
|
-
|
|
405
|
-
|
|
821
|
+
createQuery = _queryInsertManyFrom(selectPKeys, _queryWhere(_queryTake(_querySelect(_clone(query.qb), [{}])), [createWhereNotExists]), create.values);
|
|
822
|
+
} else createQuery = _queryInsertMany(selectPKeys, create.values);
|
|
823
|
+
const setForeignKeys = (as) => {
|
|
824
|
+
const count = create.items.length;
|
|
825
|
+
foreignKeys.forEach((foreignKey, i) => {
|
|
826
|
+
const primaryKey = primaryKeys[i];
|
|
827
|
+
create.items.forEach((item, i) => {
|
|
828
|
+
item[foreignKey]._sql = selectCteColumnFromManySql(as, primaryKey, i, count);
|
|
829
|
+
});
|
|
830
|
+
});
|
|
831
|
+
};
|
|
832
|
+
if (queryForCreate.q.type === "upsert") _prependWithOnUpsertCreate(queryForCreate, setForeignKeys, createQuery);
|
|
833
|
+
else _prependWith(queryForCreate, setForeignKeys, createQuery);
|
|
834
|
+
}
|
|
406
835
|
if (connect) connect.values.forEach((value, itemI) => {
|
|
407
836
|
const as = getFreeAlias(queryForCreate.q.withShapes, "q");
|
|
408
|
-
_prependWith(queryForCreate, as, query.select(...primaryKeys).findBy(value));
|
|
837
|
+
(queryForCreate.q.type === "upsert" ? _prependWithOnUpsertCreate : _prependWith)(queryForCreate, as, query.select(...primaryKeys).findBy(value));
|
|
409
838
|
foreignKeys.map((foreignKey, i) => {
|
|
410
839
|
connect.items[itemI][foreignKey] = new RawSql(selectCteColumnMustExistSql(i, as, primaryKeys[i]));
|
|
411
840
|
});
|
|
412
841
|
});
|
|
413
842
|
if (connectOrCreate) connectOrCreate.values.forEach((value, itemI) => {
|
|
414
|
-
|
|
843
|
+
const asFn = setForeignKeysFromCte(connectOrCreate.items[itemI], primaryKeys, foreignKeys);
|
|
844
|
+
const selectPKeys = query.select(...primaryKeys);
|
|
845
|
+
(queryForCreate.q.type === "upsert" ? _prependWithOnUpsertCreate : _prependWith)(queryForCreate, asFn, _orCreate(_queryWhere(selectPKeys, [value.where]), value.create));
|
|
415
846
|
});
|
|
416
847
|
}
|
|
417
848
|
update(q, set) {
|
|
@@ -580,31 +1011,100 @@ var HasOneVirtualColumn = class extends VirtualColumn {
|
|
|
580
1011
|
});
|
|
581
1012
|
if (!nestedCreateItems) return;
|
|
582
1013
|
let createAs;
|
|
1014
|
+
let createWhereExists;
|
|
1015
|
+
let createSelectAs;
|
|
1016
|
+
let createAliasedPrimaryKeys;
|
|
1017
|
+
let upsertCreateAs;
|
|
583
1018
|
let connectAs;
|
|
584
1019
|
let connectOrCreateAs;
|
|
1020
|
+
const setUpsertCreatePlaceholders = () => {
|
|
1021
|
+
if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
|
|
1022
|
+
const aliasedPrimaryKeys = createAliasedPrimaryKeys;
|
|
1023
|
+
if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
|
|
1024
|
+
if (createSelectAs) foreignKeys.forEach((key, keyI) => {
|
|
1025
|
+
createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
|
|
1026
|
+
});
|
|
1027
|
+
if (connect) foreignKeys.forEach((key, keyI) => {
|
|
1028
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1029
|
+
for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
|
|
1030
|
+
});
|
|
1031
|
+
if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
|
|
1032
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1033
|
+
for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1034
|
+
});
|
|
1035
|
+
};
|
|
585
1036
|
_hookSelectColumns(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
|
|
1037
|
+
createAliasedPrimaryKeys = aliasedPrimaryKeys;
|
|
586
1038
|
foreignKeys.forEach((key, keyI) => {
|
|
587
1039
|
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
588
1040
|
if (create && createAs) for (let i = 0; i < create.items.length; i++) create.items[i][key]._sql = selectCteColumnFromManySql(createAs, primaryKey, create.indexes[i], count);
|
|
589
1041
|
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
|
|
590
1042
|
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
591
1043
|
});
|
|
1044
|
+
setUpsertCreatePlaceholders();
|
|
592
1045
|
});
|
|
593
1046
|
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
594
|
-
if (create)
|
|
1047
|
+
if (create) {
|
|
1048
|
+
let query;
|
|
1049
|
+
if (querySelf.q.type === "upsert") {
|
|
1050
|
+
createWhereExists = new RawSql("");
|
|
1051
|
+
createSelectAs = {};
|
|
1052
|
+
for (const key of foreignKeys) createSelectAs[key] = new RawSql("");
|
|
1053
|
+
const sourceQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [createSelectAs])), [createWhereExists]);
|
|
1054
|
+
query = _queryInsertManyFrom(_clone(rel), sourceQuery, create.items);
|
|
1055
|
+
} else query = _queryInsertMany(_clone(rel), create.items);
|
|
1056
|
+
if (querySelf.q.type === "upsert") _appendQueryOnUpsertCreate(querySelf, query, (as) => {
|
|
1057
|
+
upsertCreateAs = as;
|
|
1058
|
+
setUpsertCreatePlaceholders();
|
|
1059
|
+
});
|
|
1060
|
+
else _appendQuery(querySelf, query, (as) => createAs = as);
|
|
1061
|
+
}
|
|
595
1062
|
if (connect) connect.values.forEach((value, i) => {
|
|
1063
|
+
const connectWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
|
|
596
1064
|
const query = _queryUpdateOrThrow(rel.where(value), connect.items[i]);
|
|
1065
|
+
if (connectWhereExists) _queryWhere(query, [connectWhereExists]);
|
|
597
1066
|
query.q.ensureCount = 1;
|
|
598
|
-
_appendQuery(querySelf, query, (as) =>
|
|
1067
|
+
(querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
|
|
1068
|
+
upsertCreateAs = as;
|
|
1069
|
+
setUpsertCreatePlaceholders();
|
|
1070
|
+
connectAs = as;
|
|
1071
|
+
if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1072
|
+
});
|
|
599
1073
|
});
|
|
600
1074
|
if (connectOrCreate) connectOrCreate.values.forEach((value, i) => {
|
|
601
|
-
|
|
602
|
-
|
|
1075
|
+
const foreignKeyValues = connectOrCreate.items[i];
|
|
1076
|
+
const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
|
|
1077
|
+
const connectOrCreateSelectAs = {};
|
|
1078
|
+
if (connectOrCreateWhereExists) for (const key of foreignKeys) {
|
|
1079
|
+
const value = foreignKeyValues[key];
|
|
1080
|
+
value.result = { value: rel.qb.shape[key] };
|
|
1081
|
+
connectOrCreateSelectAs[key] = value;
|
|
1082
|
+
}
|
|
1083
|
+
const query = _queryUpsert(rel.where(value.where), {
|
|
1084
|
+
update: foreignKeyValues,
|
|
603
1085
|
create: {
|
|
604
1086
|
...value.create,
|
|
605
|
-
...
|
|
1087
|
+
...foreignKeyValues
|
|
606
1088
|
}
|
|
607
|
-
})
|
|
1089
|
+
});
|
|
1090
|
+
if (connectOrCreateWhereExists) {
|
|
1091
|
+
_queryWhere(query, [connectOrCreateWhereExists]);
|
|
1092
|
+
const guardQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [{ one: new RawSql("1") }])), [connectOrCreateWhereExists]);
|
|
1093
|
+
const sourceQuery = _querySelect(_clone(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
|
|
1094
|
+
const q = query.q;
|
|
1095
|
+
const columns = q.columns || [];
|
|
1096
|
+
const foreignKeysSet = new Set(foreignKeys);
|
|
1097
|
+
q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
|
|
1098
|
+
q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
|
|
1099
|
+
q.queryColumnsCount = foreignKeys.length;
|
|
1100
|
+
q.insertFrom = prepareSubQueryForSql(query, sourceQuery);
|
|
1101
|
+
}
|
|
1102
|
+
(querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
|
|
1103
|
+
upsertCreateAs = as;
|
|
1104
|
+
setUpsertCreatePlaceholders();
|
|
1105
|
+
connectOrCreateAs = as;
|
|
1106
|
+
if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1107
|
+
});
|
|
608
1108
|
});
|
|
609
1109
|
} else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
610
1110
|
}
|
|
@@ -633,7 +1133,8 @@ var HasOneVirtualColumn = class extends VirtualColumn {
|
|
|
633
1133
|
const makeHasOneMethod = (tableConfig, table, relation, relationName, query) => {
|
|
634
1134
|
const relPKeys = getPrimaryKeys(query);
|
|
635
1135
|
if ("through" in relation.options) {
|
|
636
|
-
const { through, source } = relation.options;
|
|
1136
|
+
const { through, source, on } = relation.options;
|
|
1137
|
+
if (on) _queryWhere(query, [on]);
|
|
637
1138
|
const throughRelation = getThroughRelation(table, through);
|
|
638
1139
|
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
639
1140
|
const sourceRelationQuery = sourceRelation.query.as(relationName);
|
|
@@ -777,9 +1278,30 @@ var HasManyVirtualColumn = class extends VirtualColumn {
|
|
|
777
1278
|
});
|
|
778
1279
|
if (!nestedCreateItems) return;
|
|
779
1280
|
let createAs;
|
|
1281
|
+
let createWhereExists;
|
|
1282
|
+
let createSelectAs;
|
|
1283
|
+
let createAliasedPrimaryKeys;
|
|
1284
|
+
let upsertCreateAs;
|
|
780
1285
|
let connectAs;
|
|
781
1286
|
let connectOrCreateAs;
|
|
1287
|
+
const setUpsertCreatePlaceholders = () => {
|
|
1288
|
+
if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
|
|
1289
|
+
const aliasedPrimaryKeys = createAliasedPrimaryKeys;
|
|
1290
|
+
if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
|
|
1291
|
+
if (createSelectAs) foreignKeys.forEach((key, keyI) => {
|
|
1292
|
+
createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
|
|
1293
|
+
});
|
|
1294
|
+
if (connect) foreignKeys.forEach((key, keyI) => {
|
|
1295
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1296
|
+
for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
|
|
1297
|
+
});
|
|
1298
|
+
if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
|
|
1299
|
+
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
1300
|
+
for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
1301
|
+
});
|
|
1302
|
+
};
|
|
782
1303
|
_hookSelectColumns(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
|
|
1304
|
+
createAliasedPrimaryKeys = aliasedPrimaryKeys;
|
|
783
1305
|
foreignKeys.forEach((key, keyI) => {
|
|
784
1306
|
const primaryKey = aliasedPrimaryKeys[keyI];
|
|
785
1307
|
if (create && createAs) for (let i = 0; i < create.items.length; i++) {
|
|
@@ -789,23 +1311,72 @@ var HasManyVirtualColumn = class extends VirtualColumn {
|
|
|
789
1311
|
if (connect && connectAs) for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(connectAs, primaryKey, connect.indexes[i], count);
|
|
790
1312
|
if (connectOrCreate && connectOrCreateAs) for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(connectOrCreateAs, primaryKey, connectOrCreate.indexes[i], count);
|
|
791
1313
|
});
|
|
1314
|
+
setUpsertCreatePlaceholders();
|
|
792
1315
|
});
|
|
793
1316
|
const { create, connect, connectOrCreate } = nestedCreateItems;
|
|
794
|
-
if (create)
|
|
1317
|
+
if (create) {
|
|
1318
|
+
let query;
|
|
1319
|
+
if (querySelf.q.type === "upsert") {
|
|
1320
|
+
createWhereExists = new RawSql("");
|
|
1321
|
+
createSelectAs = {};
|
|
1322
|
+
for (const key of foreignKeys) createSelectAs[key] = new RawSql("");
|
|
1323
|
+
const sourceQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [createSelectAs])), [createWhereExists]);
|
|
1324
|
+
query = _queryInsertManyFrom(_clone(rel), sourceQuery, create.items.flat());
|
|
1325
|
+
} else query = _queryInsertMany(_clone(rel), create.items.flat());
|
|
1326
|
+
if (querySelf.q.type === "upsert") _appendQueryOnUpsertCreate(querySelf, query, (as) => {
|
|
1327
|
+
upsertCreateAs = as;
|
|
1328
|
+
setUpsertCreatePlaceholders();
|
|
1329
|
+
});
|
|
1330
|
+
else _appendQuery(querySelf, query, (as) => createAs = as);
|
|
1331
|
+
}
|
|
795
1332
|
if (connect) connect.values.forEach((value, i) => {
|
|
1333
|
+
const connectWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
|
|
796
1334
|
const query = _queryUpdateOrThrow(rel.whereOneOf(...value), connect.items[i]);
|
|
1335
|
+
if (connectWhereExists) _queryWhere(query, [connectWhereExists]);
|
|
797
1336
|
query.q.ensureCount = value.length;
|
|
798
|
-
_appendQuery(querySelf, query, (as) =>
|
|
1337
|
+
(querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
|
|
1338
|
+
upsertCreateAs = as;
|
|
1339
|
+
setUpsertCreatePlaceholders();
|
|
1340
|
+
connectAs = as;
|
|
1341
|
+
if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1342
|
+
});
|
|
799
1343
|
});
|
|
800
1344
|
if (connectOrCreate) connectOrCreate.values.forEach((array, i) => {
|
|
801
1345
|
const foreignKeyValues = connectOrCreate.items[i];
|
|
802
|
-
for (const value of array)
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
1346
|
+
for (const value of array) {
|
|
1347
|
+
const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new RawSql("") : void 0;
|
|
1348
|
+
const connectOrCreateSelectAs = {};
|
|
1349
|
+
if (connectOrCreateWhereExists) for (const key of foreignKeys) {
|
|
1350
|
+
const value = foreignKeyValues[key];
|
|
1351
|
+
value.result = { value: rel.qb.shape[key] };
|
|
1352
|
+
connectOrCreateSelectAs[key] = value;
|
|
1353
|
+
}
|
|
1354
|
+
const query = _queryUpsert(rel.where(value.where), {
|
|
1355
|
+
update: foreignKeyValues,
|
|
1356
|
+
create: {
|
|
1357
|
+
...value.create,
|
|
1358
|
+
...foreignKeyValues
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
if (connectOrCreateWhereExists) {
|
|
1362
|
+
_queryWhere(query, [connectOrCreateWhereExists]);
|
|
1363
|
+
const guardQuery = _queryWhere(_queryTake(_querySelect(_clone(rel.qb), [{ one: new RawSql("1") }])), [connectOrCreateWhereExists]);
|
|
1364
|
+
const sourceQuery = _querySelect(_clone(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
|
|
1365
|
+
const q = query.q;
|
|
1366
|
+
const columns = q.columns || [];
|
|
1367
|
+
const foreignKeysSet = new Set(foreignKeys);
|
|
1368
|
+
q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
|
|
1369
|
+
q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
|
|
1370
|
+
q.queryColumnsCount = foreignKeys.length;
|
|
1371
|
+
q.insertFrom = prepareSubQueryForSql(query, sourceQuery);
|
|
807
1372
|
}
|
|
808
|
-
|
|
1373
|
+
(querySelf.q.type === "upsert" ? _appendQueryOnUpsertCreate : _appendQuery)(querySelf, query, (as) => {
|
|
1374
|
+
upsertCreateAs = as;
|
|
1375
|
+
setUpsertCreatePlaceholders();
|
|
1376
|
+
connectOrCreateAs = as;
|
|
1377
|
+
if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
809
1380
|
});
|
|
810
1381
|
} else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
|
|
811
1382
|
}
|
|
@@ -826,7 +1397,8 @@ var HasManyVirtualColumn = class extends VirtualColumn {
|
|
|
826
1397
|
const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
|
|
827
1398
|
const relPKeys = getPrimaryKeys(query);
|
|
828
1399
|
if ("through" in relation.options) {
|
|
829
|
-
const { through, source } = relation.options;
|
|
1400
|
+
const { through, source, on } = relation.options;
|
|
1401
|
+
if (on) _queryWhere(query, [on]);
|
|
830
1402
|
const throughRelation = getThroughRelation(table, through);
|
|
831
1403
|
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
832
1404
|
const sourceRelationQuery = sourceRelation.query.as(relationName);
|
|
@@ -1070,7 +1642,7 @@ const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relatio
|
|
|
1070
1642
|
const primaryKeys = options.columns;
|
|
1071
1643
|
const originalForeignKeys = options.references;
|
|
1072
1644
|
const foreignKeys = snakeCase ? [...originalForeignKeys] : originalForeignKeys;
|
|
1073
|
-
const joinTable = options.through.table;
|
|
1645
|
+
const joinTable = snakeCase && options.through.snakeCase !== false ? toSnakeCase(options.through.table) : options.through.table;
|
|
1074
1646
|
const originalThroughForeignKeys = options.through.columns;
|
|
1075
1647
|
const throughForeignKeys = snakeCase ? [...originalThroughForeignKeys] : originalThroughForeignKeys;
|
|
1076
1648
|
const throughPrimaryKeys = options.through.references;
|
|
@@ -1362,9 +1934,15 @@ const applyRelations = (qb, tables, result, schema) => {
|
|
|
1362
1934
|
const dbTable = result[name];
|
|
1363
1935
|
for (const relationName in table.relations) {
|
|
1364
1936
|
const relation = table.relations[relationName];
|
|
1365
|
-
const otherTableClass = relation.fn();
|
|
1366
|
-
const otherTable = tableEntries.find((pair) => pair[1] instanceof otherTableClass)
|
|
1367
|
-
|
|
1937
|
+
const otherTableClass = relation.fn?.();
|
|
1938
|
+
const otherTable = otherTableClass ? tableEntries.find((pair) => pair[1] instanceof otherTableClass) : tableEntries.find(([, table]) => {
|
|
1939
|
+
const { id } = relation;
|
|
1940
|
+
return table.id === id || table.table === id;
|
|
1941
|
+
}) || tableEntries.find(([, table]) => {
|
|
1942
|
+
const { id } = relation;
|
|
1943
|
+
return table.name === id;
|
|
1944
|
+
});
|
|
1945
|
+
if (!otherTable) throw new Error(otherTableClass ? `Cannot find table class for class ${otherTableClass.name}` : `Cannot find table for relation target ${relation.id}`);
|
|
1368
1946
|
const otherTableName = otherTable[0];
|
|
1369
1947
|
const otherDbTable = result[otherTableName];
|
|
1370
1948
|
if (!otherDbTable) throw new Error(`Cannot find table class by name ${otherTableName}`);
|
|
@@ -1690,6 +2268,6 @@ const createRepo = (table, methods) => {
|
|
|
1690
2268
|
return q[key];
|
|
1691
2269
|
} });
|
|
1692
2270
|
};
|
|
1693
|
-
export { bundleOrchidORM, bundleOrchidORMTables, createBaseTable, createRepo, defineRls, makeOrchidOrmDbWithAdapter, orchidORMWithAdapter, setGrants };
|
|
2271
|
+
export { bundleOrchidORM, bundleOrchidORMTables, createBaseTable, createRepo, createTableFactory, defineRls, makeOrchidOrmDbWithAdapter, orchidORMWithAdapter, setGrants };
|
|
1694
2272
|
|
|
1695
2273
|
//# sourceMappingURL=index.mjs.map
|