orchid-orm 1.76.5 → 1.77.1

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/index.js CHANGED
@@ -152,6 +152,422 @@ function createBaseTable({ schemaConfig = pqb_internal.defaultSchemaConfig, 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 pqb_internal.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 ?? pqb_internal.defaultSchemaConfig)();
320
+ const defaultColumnTypes = (0, pqb_internal.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 || (0, pqb_internal.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 = (0, pqb_internal.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 = (0, pqb_internal.toSnakeCase)(key);
338
+ if (snakeName !== key) column.data.name = snakeName;
339
+ }
340
+ const nameInDb = tableOptions?.nameInDb ?? (snakeCase ? (0, pqb_internal.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
+ (0, pqb_internal.parseTableDataInput)(tableData, pqb_internal.tableDataMethods.primaryKey(...args));
393
+ return definition;
394
+ };
395
+ definition.index = (...args) => {
396
+ (0, pqb_internal.parseTableDataInput)(tableData, pqb_internal.tableDataMethods.index(...args));
397
+ return definition;
398
+ };
399
+ definition.searchIndex = (...args) => {
400
+ (0, pqb_internal.parseTableDataInput)(tableData, pqb_internal.tableDataMethods.searchIndex(...args));
401
+ return definition;
402
+ };
403
+ definition.unique = (...args) => {
404
+ (0, pqb_internal.parseTableDataInput)(tableData, pqb_internal.tableDataMethods.unique(...args));
405
+ return definition;
406
+ };
407
+ definition.exclude = (...args) => {
408
+ (0, pqb_internal.parseTableDataInput)(tableData, pqb_internal.tableDataMethods.exclude(...args));
409
+ return definition;
410
+ };
411
+ definition.check = (...args) => {
412
+ (0, pqb_internal.parseTableDataInput)(tableData, pqb_internal.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
+ (0, pqb_internal.parseTableDataInput)(tableData, pqb_internal.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 = (0, pqb_internal.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 = (0, pqb_internal.getColumnTypes)(columnTypes, t, options?.nowSQL, language);
472
+ const tableData = {};
473
+ const nameInDb = viewOptions?.nameInDb ?? (snakeCase ? (0, pqb_internal.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 = (0, pqb_internal.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: (0, pqb_internal._createDbSqlMethod)(columnTypes),
568
+ exportAs: defineTableExportAs
569
+ };
570
+ };
155
571
  const throwIfQueryReturnsAllForNestedUpdate = (q, params) => {
156
572
  if (!(params.set || params.create || params.upsert) || !(0, pqb_internal.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().instance();
650
+ const instance = (0, pqb_internal.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().instance();
666
+ const instance = (0, pqb_internal.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,40 @@ var BelongsToVirtualColumn = class extends pqb_internal.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) (0, pqb_internal._prependWith)(queryForCreate, (as) => {
398
- const count = create.items.length;
399
- foreignKeys.forEach((foreignKey, i) => {
400
- const primaryKey = primaryKeys[i];
401
- create.items.forEach((item, i) => {
402
- item[foreignKey]._sql = selectCteColumnFromManySql(as, primaryKey, i, count);
813
+ if (create) {
814
+ const selectPKeys = query.select(...primaryKeys);
815
+ let createQuery;
816
+ if (queryForCreate.q.type === "upsert") {
817
+ const createWhereNotExists = new pqb_internal.RawSql("");
818
+ (0, pqb_internal._onUpsertUpdate)(queryForCreate, (as) => {
819
+ createWhereNotExists._sql = `NOT EXISTS (SELECT 1 FROM "${as}")`;
403
820
  });
404
- });
405
- }, (0, pqb_internal._queryInsertMany)(query.select(...primaryKeys), create.values));
821
+ const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(query.qb), [{}])), [createWhereNotExists]);
822
+ createQuery = (0, pqb_internal._queryInsertManyFrom)(selectPKeys, sourceQuery, create.values);
823
+ } else createQuery = (0, pqb_internal._queryInsertMany)(selectPKeys, create.values);
824
+ const setForeignKeys = (as) => {
825
+ const count = create.items.length;
826
+ foreignKeys.forEach((foreignKey, i) => {
827
+ const primaryKey = primaryKeys[i];
828
+ create.items.forEach((item, i) => {
829
+ item[foreignKey]._sql = selectCteColumnFromManySql(as, primaryKey, i, count);
830
+ });
831
+ });
832
+ };
833
+ if (queryForCreate.q.type === "upsert") (0, pqb_internal._prependWithOnUpsertCreate)(queryForCreate, setForeignKeys, createQuery);
834
+ else (0, pqb_internal._prependWith)(queryForCreate, setForeignKeys, createQuery);
835
+ }
406
836
  if (connect) connect.values.forEach((value, itemI) => {
407
837
  const as = (0, pqb_internal.getFreeAlias)(queryForCreate.q.withShapes, "q");
408
- (0, pqb_internal._prependWith)(queryForCreate, as, query.select(...primaryKeys).findBy(value));
838
+ (queryForCreate.q.type === "upsert" ? pqb_internal._prependWithOnUpsertCreate : pqb_internal._prependWith)(queryForCreate, as, query.select(...primaryKeys).findBy(value));
409
839
  foreignKeys.map((foreignKey, i) => {
410
840
  connect.items[itemI][foreignKey] = new pqb_internal.RawSql(selectCteColumnMustExistSql(i, as, primaryKeys[i]));
411
841
  });
412
842
  });
413
843
  if (connectOrCreate) connectOrCreate.values.forEach((value, itemI) => {
414
- (0, pqb_internal._prependWith)(queryForCreate, setForeignKeysFromCte(connectOrCreate.items[itemI], primaryKeys, foreignKeys), (0, pqb_internal._orCreate)((0, pqb_internal._queryWhere)(query.select(...primaryKeys), [value.where]), value.create));
844
+ const asFn = setForeignKeysFromCte(connectOrCreate.items[itemI], primaryKeys, foreignKeys);
845
+ const selectPKeys = query.select(...primaryKeys);
846
+ (queryForCreate.q.type === "upsert" ? pqb_internal._prependWithOnUpsertCreate : pqb_internal._prependWith)(queryForCreate, asFn, (0, pqb_internal._orCreate)((0, pqb_internal._queryWhere)(selectPKeys, [value.where]), value.create));
415
847
  });
416
848
  }
417
849
  update(q, set) {
@@ -472,7 +904,8 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
472
904
  return ((self, update, params) => {
473
905
  if (params.create) {
474
906
  const createQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryCreate)(query.clone(), params.create), primaryKeys);
475
- (0, pqb_internal._prependWith)(self, setForeignKeysFromCte(update, primaryKeys, foreignKeys), createQuery);
907
+ const asFn = setForeignKeysFromCte(update, primaryKeys, foreignKeys);
908
+ (0, pqb_internal._prependWith)(self, asFn, createQuery);
476
909
  } else if (params.update) {
477
910
  let appendedAs;
478
911
  (0, pqb_internal._hookSelectColumns)(self, foreignKeys, (aliasedForeignKeys) => {
@@ -486,7 +919,8 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
486
919
  if ((0, pqb_internal.isQueryReturnsAll)(self)) throw new Error("`upsert` option is not allowed in a batch update");
487
920
  const { relQuery } = relWithSelectIds(self, query, primaryKeys, foreignKeys);
488
921
  const upsertQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)(relQuery, params.upsert), primaryKeys);
489
- (0, pqb_internal._prependWith)(self, setForeignKeysFromCte(update, primaryKeys, foreignKeys), upsertQuery);
922
+ const asFn = setForeignKeysFromCte(update, primaryKeys, foreignKeys);
923
+ (0, pqb_internal._prependWith)(self, asFn, upsertQuery);
490
924
  } else if (params.delete) {
491
925
  (0, pqb_internal._hookSelectColumns)(self, foreignKeys, pqb_internal.noop);
492
926
  disconnect(update, foreignKeys);
@@ -508,7 +942,10 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys, len }) => {
508
942
  (loadForeignKeys ??= []).push(foreignKeys[i]);
509
943
  }
510
944
  }
511
- if (loadPrimaryKeys) (0, pqb_internal._prependWith)(self, setForeignKeysFromCte(update, loadPrimaryKeys, loadForeignKeys, true), (0, pqb_internal._queryFindBy)(query.select(...loadPrimaryKeys), params.set));
945
+ if (loadPrimaryKeys) {
946
+ const asFn = setForeignKeysFromCte(update, loadPrimaryKeys, loadForeignKeys, true);
947
+ (0, pqb_internal._prependWith)(self, asFn, (0, pqb_internal._queryFindBy)(query.select(...loadPrimaryKeys), params.set));
948
+ }
512
949
  }
513
950
  });
514
951
  };
@@ -580,31 +1017,100 @@ var HasOneVirtualColumn = class extends pqb_internal.VirtualColumn {
580
1017
  });
581
1018
  if (!nestedCreateItems) return;
582
1019
  let createAs;
1020
+ let createWhereExists;
1021
+ let createSelectAs;
1022
+ let createAliasedPrimaryKeys;
1023
+ let upsertCreateAs;
583
1024
  let connectAs;
584
1025
  let connectOrCreateAs;
1026
+ const setUpsertCreatePlaceholders = () => {
1027
+ if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
1028
+ const aliasedPrimaryKeys = createAliasedPrimaryKeys;
1029
+ if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
1030
+ if (createSelectAs) foreignKeys.forEach((key, keyI) => {
1031
+ createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
1032
+ });
1033
+ if (connect) foreignKeys.forEach((key, keyI) => {
1034
+ const primaryKey = aliasedPrimaryKeys[keyI];
1035
+ for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
1036
+ });
1037
+ if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
1038
+ const primaryKey = aliasedPrimaryKeys[keyI];
1039
+ for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
1040
+ });
1041
+ };
585
1042
  (0, pqb_internal._hookSelectColumns)(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
1043
+ createAliasedPrimaryKeys = aliasedPrimaryKeys;
586
1044
  foreignKeys.forEach((key, keyI) => {
587
1045
  const primaryKey = aliasedPrimaryKeys[keyI];
588
1046
  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
1047
  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
1048
  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
1049
  });
1050
+ setUpsertCreatePlaceholders();
592
1051
  });
593
1052
  const { create, connect, connectOrCreate } = nestedCreateItems;
594
- if (create) (0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items), (as) => createAs = as);
1053
+ if (create) {
1054
+ let query;
1055
+ if (querySelf.q.type === "upsert") {
1056
+ createWhereExists = new pqb_internal.RawSql("");
1057
+ createSelectAs = {};
1058
+ for (const key of foreignKeys) createSelectAs[key] = new pqb_internal.RawSql("");
1059
+ const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [createSelectAs])), [createWhereExists]);
1060
+ query = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._clone)(rel), sourceQuery, create.items);
1061
+ } else query = (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items);
1062
+ if (querySelf.q.type === "upsert") (0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, query, (as) => {
1063
+ upsertCreateAs = as;
1064
+ setUpsertCreatePlaceholders();
1065
+ });
1066
+ else (0, pqb_internal._appendQuery)(querySelf, query, (as) => createAs = as);
1067
+ }
595
1068
  if (connect) connect.values.forEach((value, i) => {
1069
+ const connectWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
596
1070
  const query = (0, pqb_internal._queryUpdateOrThrow)(rel.where(value), connect.items[i]);
1071
+ if (connectWhereExists) (0, pqb_internal._queryWhere)(query, [connectWhereExists]);
597
1072
  query.q.ensureCount = 1;
598
- (0, pqb_internal._appendQuery)(querySelf, query, (as) => connectAs = as);
1073
+ (querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
1074
+ upsertCreateAs = as;
1075
+ setUpsertCreatePlaceholders();
1076
+ connectAs = as;
1077
+ if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1078
+ });
599
1079
  });
600
1080
  if (connectOrCreate) connectOrCreate.values.forEach((value, i) => {
601
- (0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._queryUpsert)(rel.where(value.where), {
602
- update: connectOrCreate.items[i],
1081
+ const foreignKeyValues = connectOrCreate.items[i];
1082
+ const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
1083
+ const connectOrCreateSelectAs = {};
1084
+ if (connectOrCreateWhereExists) for (const key of foreignKeys) {
1085
+ const value = foreignKeyValues[key];
1086
+ value.result = { value: rel.qb.shape[key] };
1087
+ connectOrCreateSelectAs[key] = value;
1088
+ }
1089
+ const query = (0, pqb_internal._queryUpsert)(rel.where(value.where), {
1090
+ update: foreignKeyValues,
603
1091
  create: {
604
1092
  ...value.create,
605
- ...connectOrCreate.items[i]
1093
+ ...foreignKeyValues
606
1094
  }
607
- }), (as) => connectOrCreateAs = as);
1095
+ });
1096
+ if (connectOrCreateWhereExists) {
1097
+ (0, pqb_internal._queryWhere)(query, [connectOrCreateWhereExists]);
1098
+ const guardQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [{ one: new pqb_internal.RawSql("1") }])), [connectOrCreateWhereExists]);
1099
+ const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
1100
+ const q = query.q;
1101
+ const columns = q.columns || [];
1102
+ const foreignKeysSet = new Set(foreignKeys);
1103
+ q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
1104
+ q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
1105
+ q.queryColumnsCount = foreignKeys.length;
1106
+ q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(query, sourceQuery);
1107
+ }
1108
+ (querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
1109
+ upsertCreateAs = as;
1110
+ setUpsertCreatePlaceholders();
1111
+ connectOrCreateAs = as;
1112
+ if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1113
+ });
608
1114
  });
609
1115
  } else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
610
1116
  }
@@ -618,11 +1124,13 @@ var HasOneVirtualColumn = class extends pqb_internal.VirtualColumn {
618
1124
  const nullifyOrDeleteQuery = params.update ? (0, pqb_internal._queryUpdate)(ids.existingRelQuery, params.update) : params.upsert ? (0, pqb_internal._queryUpsert)(ids.existingRelQuery, makeNestedUpdateUpsertData(params.upsert, ids.setIds)) : params.delete ? (0, pqb_internal._queryDelete)(ids.existingRelQuery) : (0, pqb_internal._queryUpdate)(ids.existingRelQuery, this.setNulls);
619
1125
  nullifyOrDeleteQuery.q.returnType = "void";
620
1126
  (0, pqb_internal._appendQuery)(querySelf, nullifyOrDeleteQuery, ids.setAppendedAs);
621
- if (params.create) (0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._queryInsert)((0, pqb_internal._clone)(relQuery), {
622
- ...params.create,
623
- ...ids.setIds
624
- }), pqb_internal.noop);
625
- else if (params.set) {
1127
+ if (params.create) {
1128
+ const createQuery = (0, pqb_internal._queryInsert)((0, pqb_internal._clone)(relQuery), {
1129
+ ...params.create,
1130
+ ...ids.setIds
1131
+ });
1132
+ (0, pqb_internal._appendQuery)(querySelf, createQuery, pqb_internal.noop);
1133
+ } else if (params.set) {
626
1134
  const setQuery = (0, pqb_internal._queryUpdate)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(relQuery), [params.set]), ids.setIds);
627
1135
  setQuery.q.returnType = "void";
628
1136
  (0, pqb_internal._appendQuery)(querySelf, setQuery, pqb_internal.noop);
@@ -633,7 +1141,8 @@ var HasOneVirtualColumn = class extends pqb_internal.VirtualColumn {
633
1141
  const makeHasOneMethod = (tableConfig, table, relation, relationName, query) => {
634
1142
  const relPKeys = (0, pqb_internal.getPrimaryKeys)(query);
635
1143
  if ("through" in relation.options) {
636
- const { through, source } = relation.options;
1144
+ const { through, source, on } = relation.options;
1145
+ if (on) (0, pqb_internal._queryWhere)(query, [on]);
637
1146
  const throughRelation = getThroughRelation(table, through);
638
1147
  const sourceRelation = getSourceRelation(throughRelation, source);
639
1148
  const sourceRelationQuery = sourceRelation.query.as(relationName);
@@ -777,9 +1286,30 @@ var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
777
1286
  });
778
1287
  if (!nestedCreateItems) return;
779
1288
  let createAs;
1289
+ let createWhereExists;
1290
+ let createSelectAs;
1291
+ let createAliasedPrimaryKeys;
1292
+ let upsertCreateAs;
780
1293
  let connectAs;
781
1294
  let connectOrCreateAs;
1295
+ const setUpsertCreatePlaceholders = () => {
1296
+ if (!upsertCreateAs || !createAliasedPrimaryKeys) return;
1297
+ const aliasedPrimaryKeys = createAliasedPrimaryKeys;
1298
+ if (createWhereExists) createWhereExists._sql = `EXISTS (SELECT 1 FROM "${upsertCreateAs}")`;
1299
+ if (createSelectAs) foreignKeys.forEach((key, keyI) => {
1300
+ createSelectAs[key]._sql = selectCteColumnFromManySql(upsertCreateAs, aliasedPrimaryKeys[keyI], 0, 1);
1301
+ });
1302
+ if (connect) foreignKeys.forEach((key, keyI) => {
1303
+ const primaryKey = aliasedPrimaryKeys[keyI];
1304
+ for (let i = 0; i < connect.items.length; i++) connect.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connect.indexes[i], count);
1305
+ });
1306
+ if (connectOrCreate) foreignKeys.forEach((key, keyI) => {
1307
+ const primaryKey = aliasedPrimaryKeys[keyI];
1308
+ for (let i = 0; i < connectOrCreate.items.length; i++) connectOrCreate.items[i][key]._sql = selectCteColumnFromManySql(upsertCreateAs, primaryKey, connectOrCreate.indexes[i], count);
1309
+ });
1310
+ };
782
1311
  (0, pqb_internal._hookSelectColumns)(querySelf, primaryKeys, (aliasedPrimaryKeys) => {
1312
+ createAliasedPrimaryKeys = aliasedPrimaryKeys;
783
1313
  foreignKeys.forEach((key, keyI) => {
784
1314
  const primaryKey = aliasedPrimaryKeys[keyI];
785
1315
  if (create && createAs) for (let i = 0; i < create.items.length; i++) {
@@ -789,23 +1319,72 @@ var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
789
1319
  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
1320
  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
1321
  });
1322
+ setUpsertCreatePlaceholders();
792
1323
  });
793
1324
  const { create, connect, connectOrCreate } = nestedCreateItems;
794
- if (create) (0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items.flat()), (as) => createAs = as);
1325
+ if (create) {
1326
+ let query;
1327
+ if (querySelf.q.type === "upsert") {
1328
+ createWhereExists = new pqb_internal.RawSql("");
1329
+ createSelectAs = {};
1330
+ for (const key of foreignKeys) createSelectAs[key] = new pqb_internal.RawSql("");
1331
+ const sourceQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [createSelectAs])), [createWhereExists]);
1332
+ query = (0, pqb_internal._queryInsertManyFrom)((0, pqb_internal._clone)(rel), sourceQuery, create.items.flat());
1333
+ } else query = (0, pqb_internal._queryInsertMany)((0, pqb_internal._clone)(rel), create.items.flat());
1334
+ if (querySelf.q.type === "upsert") (0, pqb_internal._appendQueryOnUpsertCreate)(querySelf, query, (as) => {
1335
+ upsertCreateAs = as;
1336
+ setUpsertCreatePlaceholders();
1337
+ });
1338
+ else (0, pqb_internal._appendQuery)(querySelf, query, (as) => createAs = as);
1339
+ }
795
1340
  if (connect) connect.values.forEach((value, i) => {
1341
+ const connectWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
796
1342
  const query = (0, pqb_internal._queryUpdateOrThrow)(rel.whereOneOf(...value), connect.items[i]);
1343
+ if (connectWhereExists) (0, pqb_internal._queryWhere)(query, [connectWhereExists]);
797
1344
  query.q.ensureCount = value.length;
798
- (0, pqb_internal._appendQuery)(querySelf, query, (as) => connectAs = as);
1345
+ (querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
1346
+ upsertCreateAs = as;
1347
+ setUpsertCreatePlaceholders();
1348
+ connectAs = as;
1349
+ if (connectWhereExists) connectWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1350
+ });
799
1351
  });
800
1352
  if (connectOrCreate) connectOrCreate.values.forEach((array, i) => {
801
1353
  const foreignKeyValues = connectOrCreate.items[i];
802
- for (const value of array) (0, pqb_internal._appendQuery)(querySelf, (0, pqb_internal._queryUpsert)(rel.where(value.where), {
803
- update: foreignKeyValues,
804
- create: {
805
- ...value.create,
806
- ...foreignKeyValues
1354
+ for (const value of array) {
1355
+ const connectOrCreateWhereExists = querySelf.q.type === "upsert" ? new pqb_internal.RawSql("") : void 0;
1356
+ const connectOrCreateSelectAs = {};
1357
+ if (connectOrCreateWhereExists) for (const key of foreignKeys) {
1358
+ const value = foreignKeyValues[key];
1359
+ value.result = { value: rel.qb.shape[key] };
1360
+ connectOrCreateSelectAs[key] = value;
1361
+ }
1362
+ const query = (0, pqb_internal._queryUpsert)(rel.where(value.where), {
1363
+ update: foreignKeyValues,
1364
+ create: {
1365
+ ...value.create,
1366
+ ...foreignKeyValues
1367
+ }
1368
+ });
1369
+ if (connectOrCreateWhereExists) {
1370
+ (0, pqb_internal._queryWhere)(query, [connectOrCreateWhereExists]);
1371
+ const guardQuery = (0, pqb_internal._queryWhere)((0, pqb_internal._queryTake)((0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb), [{ one: new pqb_internal.RawSql("1") }])), [connectOrCreateWhereExists]);
1372
+ const sourceQuery = (0, pqb_internal._querySelect)((0, pqb_internal._clone)(rel.qb).from(guardQuery), [connectOrCreateSelectAs]);
1373
+ const q = query.q;
1374
+ const columns = q.columns || [];
1375
+ const foreignKeysSet = new Set(foreignKeys);
1376
+ q.columns = [...foreignKeys, ...columns.filter((column) => !foreignKeysSet.has(column))];
1377
+ q.values = q.values.map((row) => row.filter((_, i) => !foreignKeysSet.has(columns[i])));
1378
+ q.queryColumnsCount = foreignKeys.length;
1379
+ q.insertFrom = (0, pqb_internal.prepareSubQueryForSql)(query, sourceQuery);
807
1380
  }
808
- }), (as) => connectOrCreateAs = as);
1381
+ (querySelf.q.type === "upsert" ? pqb_internal._appendQueryOnUpsertCreate : pqb_internal._appendQuery)(querySelf, query, (as) => {
1382
+ upsertCreateAs = as;
1383
+ setUpsertCreatePlaceholders();
1384
+ connectOrCreateAs = as;
1385
+ if (connectOrCreateWhereExists) connectOrCreateWhereExists._sql = `EXISTS (SELECT 1 FROM "${as}")`;
1386
+ });
1387
+ }
809
1388
  });
810
1389
  } else hasRelationHandleCreate(querySelf, ctx, items, rowIndexes, this.key, this.state.primaryKeys, this.nestedInsert);
811
1390
  }
@@ -826,7 +1405,8 @@ var HasManyVirtualColumn = class extends pqb_internal.VirtualColumn {
826
1405
  const makeHasManyMethod = (tableConfig, table, relation, relationName, query) => {
827
1406
  const relPKeys = (0, pqb_internal.getPrimaryKeys)(query);
828
1407
  if ("through" in relation.options) {
829
- const { through, source } = relation.options;
1408
+ const { through, source, on } = relation.options;
1409
+ if (on) (0, pqb_internal._queryWhere)(query, [on]);
830
1410
  const throughRelation = getThroughRelation(table, through);
831
1411
  const sourceRelation = getSourceRelation(throughRelation, source);
832
1412
  const sourceRelationQuery = sourceRelation.query.as(relationName);
@@ -1034,10 +1614,11 @@ const nestedUpdateUpsert = (querySelf, state, upsert) => {
1034
1614
  parentIdsSql._sql = selectCteColumnsSql(parentAs, aliasedPrimaryKeys);
1035
1615
  for (let i = 0; i < state.foreignKeys.length; i++) parentValues[i]._sql = selectCteColumnSql(parentAs, aliasedPrimaryKeys[i]);
1036
1616
  });
1037
- const upsertQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)((0, pqb_internal._queryWhereExists)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(state.relatedTableQuery), [upsert.findBy]), state.joinTableQuery, [(q) => {
1617
+ const existingRelQuery = (0, pqb_internal._queryWhereExists)((0, pqb_internal._queryWhere)((0, pqb_internal._clone)(state.relatedTableQuery), [upsert.findBy]), state.joinTableQuery, [(q) => {
1038
1618
  for (let i = 0; i < state.throughPrimaryKeys.length; i++) (0, pqb_internal._queryJoinOn)(q, [state.throughForeignKeysFull[i], state.throughPrimaryKeysFull[i]]);
1039
1619
  return (0, pqb_internal._queryWhereIn)(q, true, state.foreignKeysFull, parentIdsSql);
1040
- }]), {
1620
+ }]);
1621
+ const upsertQuery = (0, pqb_internal._querySelect)((0, pqb_internal._queryUpsert)(existingRelQuery, {
1041
1622
  update: upsert.update,
1042
1623
  create: upsert.create || {}
1043
1624
  }), state.throughPrimaryKeys);
@@ -1070,7 +1651,7 @@ const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relatio
1070
1651
  const primaryKeys = options.columns;
1071
1652
  const originalForeignKeys = options.references;
1072
1653
  const foreignKeys = snakeCase ? [...originalForeignKeys] : originalForeignKeys;
1073
- const joinTable = options.through.table;
1654
+ const joinTable = snakeCase && options.through.snakeCase !== false ? (0, pqb_internal.toSnakeCase)(options.through.table) : options.through.table;
1074
1655
  const originalThroughForeignKeys = options.through.columns;
1075
1656
  const throughForeignKeys = snakeCase ? [...originalThroughForeignKeys] : originalThroughForeignKeys;
1076
1657
  const throughPrimaryKeys = options.through.references;
@@ -1340,7 +1921,8 @@ const nestedUpdate = (state) => {
1340
1921
  }
1341
1922
  if (params.disconnect) await (0, pqb_internal._queryDelete)(queryJoinTable(state, data, params.disconnect));
1342
1923
  if (params.delete) {
1343
- const idsRows = await (0, pqb_internal._queryDelete)((0, pqb_internal._queryRows)((0, pqb_internal._querySelect)(queryJoinTable(state, data, params.delete), state.throughForeignKeys)));
1924
+ const j = queryJoinTable(state, data, params.delete);
1925
+ const idsRows = await (0, pqb_internal._queryDelete)((0, pqb_internal._queryRows)((0, pqb_internal._querySelect)(j, state.throughForeignKeys)));
1344
1926
  await (0, pqb_internal._queryDelete)(state.relatedTableQuery.where({ IN: {
1345
1927
  columns: state.throughPrimaryKeys,
1346
1928
  values: idsRows
@@ -1349,7 +1931,10 @@ const nestedUpdate = (state) => {
1349
1931
  if (params.set) {
1350
1932
  const j = queryJoinTable(state, data);
1351
1933
  await (0, pqb_internal._queryDelete)(j);
1352
- if (Array.isArray(params.set) ? params.set.length : (0, pqb_internal.objectHasValues)(params.set)) await insertToJoinTable(state, j, data, await (0, pqb_internal._queryRows)((0, pqb_internal._querySelect)(state.relatedTableQuery.where(conditionsToWhereArg(params.set)), state.throughPrimaryKeys)));
1934
+ if (Array.isArray(params.set) ? params.set.length : (0, pqb_internal.objectHasValues)(params.set)) {
1935
+ const idsRows = await (0, pqb_internal._queryRows)((0, pqb_internal._querySelect)(state.relatedTableQuery.where(conditionsToWhereArg(params.set)), state.throughPrimaryKeys));
1936
+ await insertToJoinTable(state, j, data, idsRows);
1937
+ }
1353
1938
  }
1354
1939
  });
1355
1940
  };
@@ -1362,9 +1947,15 @@ const applyRelations = (qb, tables, result, schema) => {
1362
1947
  const dbTable = result[name];
1363
1948
  for (const relationName in table.relations) {
1364
1949
  const relation = table.relations[relationName];
1365
- const otherTableClass = relation.fn();
1366
- const otherTable = tableEntries.find((pair) => pair[1] instanceof otherTableClass);
1367
- if (!otherTable) throw new Error(`Cannot find table class for class ${otherTableClass.name}`);
1950
+ const otherTableClass = relation.fn?.();
1951
+ const otherTable = otherTableClass ? tableEntries.find((pair) => pair[1] instanceof otherTableClass) : tableEntries.find(([, table]) => {
1952
+ const { id } = relation;
1953
+ return table.id === id || table.table === id;
1954
+ }) || tableEntries.find(([, table]) => {
1955
+ const { id } = relation;
1956
+ return table.name === id;
1957
+ });
1958
+ if (!otherTable) throw new Error(otherTableClass ? `Cannot find table class for class ${otherTableClass.name}` : `Cannot find table for relation target ${relation.id}`);
1368
1959
  const otherTableName = otherTable[0];
1369
1960
  const otherDbTable = result[otherTableName];
1370
1961
  if (!otherDbTable) throw new Error(`Cannot find table class by name ${otherTableName}`);
@@ -1694,6 +2285,7 @@ exports.bundleOrchidORM = bundleOrchidORM;
1694
2285
  exports.bundleOrchidORMTables = bundleOrchidORMTables;
1695
2286
  exports.createBaseTable = createBaseTable;
1696
2287
  exports.createRepo = createRepo;
2288
+ exports.createTableFactory = createTableFactory;
1697
2289
  exports.defineRls = defineRls;
1698
2290
  exports.makeOrchidOrmDbWithAdapter = makeOrchidOrmDbWithAdapter;
1699
2291
  exports.orchidORMWithAdapter = orchidORMWithAdapter;