orchid-orm 1.40.1 → 1.41.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/index.d.ts +26 -24
- package/dist/index.js +165 -53
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +167 -55
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TableData, Query, SelectableFromShape, CreateMethodsNames, CreateData, CreateBelongsToData, AddQueryDefaults, RelationConfigBase, SetQueryReturnsOne, SetQueryReturnsOneOptional, UpdateData, WhereArg, JoinQueryMethod, DeleteMethodsNames, Db, IsolationLevel, TransactionOptions, Adapter, FromArg, FromResult, AdapterOptions, DbSharedOptions, RelationsBase, ShapeColumnPrimaryKeys, ShapeUniqueColumns, TableDataItemsUniqueColumns, TableDataItemsUniqueColumnTuples, UniqueConstraints, TableDataItemsUniqueConstraints, ComputedColumnsFromOptions, MapTableScopesOption, TableDataItem, ComputedOptionsFactory, QueryData, TableDataFn, DbTableOptionScopes, RawSQL, DynamicRawSQL, DefaultSchemaConfig, DefaultColumnTypes, QueryBeforeHook, QueryAfterHook, AfterHook, WhereResult, MergeQuery } from 'pqb';
|
|
2
2
|
export * from 'pqb';
|
|
3
|
-
import { ColumnsShapeBase, EmptyObject, MaybeArray, RecordUnknown, ShallowSimplify, ColumnShapeOutput, DefaultSelectColumns, ColumnShapeInput,
|
|
3
|
+
import { ColumnsShapeBase, ColumnShapeInputPartial, EmptyObject, MaybeArray, RecordUnknown, ShallowSimplify, ColumnShapeOutput, DefaultSelectColumns, ColumnShapeInput, IsQuery, CoreQueryScopes, ColumnSchemaConfig, StaticSQLArgs, QueryColumn, DynamicSQLArg, QueryColumns, QueryReturnType } from 'orchid-core';
|
|
4
4
|
export * from 'orchid-core';
|
|
5
5
|
|
|
6
|
-
interface
|
|
7
|
-
scope?: ScopeFn<Related, Scope>;
|
|
6
|
+
interface RelationRefsOptions<Column extends PropertyKey = string, Shape extends ColumnsShapeBase = ColumnsShapeBase> {
|
|
8
7
|
required?: boolean;
|
|
9
|
-
}
|
|
10
|
-
interface RelationRefsOptions<Column extends PropertyKey = string, Ref extends PropertyKey = string> {
|
|
11
8
|
columns: Column[];
|
|
12
|
-
references:
|
|
9
|
+
references: (keyof Shape)[];
|
|
13
10
|
foreignKey?: boolean | TableData.References.Options;
|
|
11
|
+
on?: ColumnShapeInputPartial<Shape>;
|
|
14
12
|
}
|
|
15
13
|
interface RelationThroughOptions<Through extends PropertyKey = string, Source extends PropertyKey = string> {
|
|
16
14
|
through: Through;
|
|
@@ -21,7 +19,10 @@ interface HasOne extends RelationThunkBase {
|
|
|
21
19
|
type: 'hasOne';
|
|
22
20
|
options: HasOneOptions;
|
|
23
21
|
}
|
|
24
|
-
|
|
22
|
+
interface RelationHasOneThroughOptions<Through extends string, Source extends string> extends RelationThroughOptions<Through, Source> {
|
|
23
|
+
required?: boolean;
|
|
24
|
+
}
|
|
25
|
+
type HasOneOptions<Columns extends ColumnsShapeBase = ColumnsShapeBase, Related extends TableClass = TableClass, Through extends string = string, Source extends string = string> = RelationRefsOptions<keyof Columns, InstanceType<Related>['columns']['shape']> | RelationHasOneThroughOptions<Through, Source>;
|
|
25
26
|
type HasOneParams<T extends RelationConfigSelf, Relation extends RelationThunkBase> = Relation['options'] extends RelationRefsOptions ? {
|
|
26
27
|
[Name in Relation['options']['columns'][number]]: T['columns']['shape'][Name]['type'];
|
|
27
28
|
} : Relation['options'] extends RelationThroughOptions ? RelationConfigParams<T, T['relations'][Relation['options']['through']]> : never;
|
|
@@ -114,6 +115,7 @@ interface HasManyInfo<T extends RelationConfigSelf, Name extends string, Rel ext
|
|
|
114
115
|
data: UpdateData<Q>;
|
|
115
116
|
};
|
|
116
117
|
set?: MaybeArray<WhereArg<Q>>;
|
|
118
|
+
add?: MaybeArray<WhereArg<Q>>;
|
|
117
119
|
create?: CreateData<T['relations'][Name]['options'] extends RelationThroughOptions ? Q : AddQueryDefaults<Q, HasOnePopulate<T, Name>>>[];
|
|
118
120
|
};
|
|
119
121
|
}
|
|
@@ -126,8 +128,7 @@ interface BelongsTo extends RelationThunkBase {
|
|
|
126
128
|
type: 'belongsTo';
|
|
127
129
|
options: BelongsToOptions;
|
|
128
130
|
}
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
+
type BelongsToOptions<Columns extends ColumnsShapeBase = ColumnsShapeBase, Related extends TableClass = TableClass> = RelationRefsOptions<keyof Columns, InstanceType<Related>['columns']['shape']>;
|
|
131
132
|
type BelongsToFKey<Relation extends RelationThunkBase> = Relation['options'] extends RelationRefsOptions ? Relation['options']['columns'][number] : never;
|
|
132
133
|
type BelongsToParams<T extends RelationConfigSelf, Relation extends BelongsTo> = {
|
|
133
134
|
[Name in BelongsToFKey<Relation>]: T['columns']['shape'][Name]['type'];
|
|
@@ -290,8 +291,7 @@ interface HasAndBelongsToMany extends RelationThunkBase {
|
|
|
290
291
|
type: 'hasAndBelongsToMany';
|
|
291
292
|
options: HasAndBelongsToManyOptions;
|
|
292
293
|
}
|
|
293
|
-
interface HasAndBelongsToManyOptions<Columns extends ColumnsShapeBase = ColumnsShapeBase, Related extends TableClass = TableClass
|
|
294
|
-
scope?: ScopeFn<Related, Scope>;
|
|
294
|
+
interface HasAndBelongsToManyOptions<Columns extends ColumnsShapeBase = ColumnsShapeBase, Related extends TableClass = TableClass> {
|
|
295
295
|
required?: boolean;
|
|
296
296
|
columns: (keyof Columns)[];
|
|
297
297
|
references: string[];
|
|
@@ -302,6 +302,7 @@ interface HasAndBelongsToManyOptions<Columns extends ColumnsShapeBase = ColumnsS
|
|
|
302
302
|
references: (keyof InstanceType<Related>['columns']['shape'])[];
|
|
303
303
|
foreignKey?: boolean | TableData.References.Options;
|
|
304
304
|
};
|
|
305
|
+
on?: ColumnShapeInputPartial<InstanceType<Related>['columns']['shape']>;
|
|
305
306
|
}
|
|
306
307
|
type HasAndBelongsToManyParams<T extends RelationConfigSelf, Relation extends HasAndBelongsToMany> = {
|
|
307
308
|
[Name in Relation['options']['columns'][number]]: T['columns']['shape'][Name]['type'];
|
|
@@ -332,6 +333,7 @@ interface HasAndBelongsToManyInfo<T extends RelationConfigSelf, Name extends str
|
|
|
332
333
|
dataForUpdate: {
|
|
333
334
|
disconnect?: MaybeArray<WhereArg<Q>>;
|
|
334
335
|
set?: MaybeArray<WhereArg<Q>>;
|
|
336
|
+
add?: MaybeArray<WhereArg<Q>>;
|
|
335
337
|
delete?: MaybeArray<WhereArg<Q>>;
|
|
336
338
|
update?: {
|
|
337
339
|
where: MaybeArray<WhereArg<Q>>;
|
|
@@ -342,6 +344,7 @@ interface HasAndBelongsToManyInfo<T extends RelationConfigSelf, Name extends str
|
|
|
342
344
|
dataForUpdateOne: {
|
|
343
345
|
disconnect?: MaybeArray<WhereArg<Q>>;
|
|
344
346
|
set?: MaybeArray<WhereArg<Q>>;
|
|
347
|
+
add?: MaybeArray<WhereArg<Q>>;
|
|
345
348
|
delete?: MaybeArray<WhereArg<Q>>;
|
|
346
349
|
update?: {
|
|
347
350
|
where: MaybeArray<WhereArg<Q>>;
|
|
@@ -389,13 +392,13 @@ type RelationToOneDataForCreateSameQuery<Q extends Query> = {
|
|
|
389
392
|
interface RelationThunkBase {
|
|
390
393
|
type: string;
|
|
391
394
|
fn(): TableClass;
|
|
392
|
-
options:
|
|
395
|
+
options: unknown;
|
|
393
396
|
}
|
|
394
397
|
type RelationThunk = BelongsTo | HasOne | HasMany | HasAndBelongsToMany;
|
|
395
398
|
interface RelationThunks {
|
|
396
399
|
[K: string]: RelationThunk;
|
|
397
400
|
}
|
|
398
|
-
type
|
|
401
|
+
type RelationTableToQuery<Relation extends RelationThunkBase> = ORMTableInputToQueryBuilder<InstanceType<ReturnType<Relation['fn']>>>;
|
|
399
402
|
interface RelationConfigSelf {
|
|
400
403
|
columns: {
|
|
401
404
|
shape: ColumnsShapeBase;
|
|
@@ -404,13 +407,13 @@ interface RelationConfigSelf {
|
|
|
404
407
|
}
|
|
405
408
|
type RelationConfigParams<T extends RelationConfigSelf, Relation extends RelationThunk> = Relation extends BelongsTo ? BelongsToParams<T, Relation> : Relation extends HasOne | HasMany ? HasOneParams<T, Relation> : Relation extends HasAndBelongsToMany ? HasAndBelongsToManyParams<T, Relation> : never;
|
|
406
409
|
type MapRelation<T extends RelationConfigSelf, K extends keyof T['relations'] & string> = T['relations'][K] extends BelongsTo ? {
|
|
407
|
-
relationConfig: BelongsToInfo<T, K, T['relations'][K], T['relations'][K]['options']['columns'][number] & string, T['relations'][K]['options']['required'], BelongsToQuery<
|
|
410
|
+
relationConfig: BelongsToInfo<T, K, T['relations'][K], T['relations'][K]['options']['columns'][number] & string, T['relations'][K]['options']['required'], BelongsToQuery<RelationTableToQuery<T['relations'][K]>, K>>;
|
|
408
411
|
} : T['relations'][K] extends HasOne ? {
|
|
409
|
-
relationConfig: HasOneInfo<T, K, T['relations'][K], HasOneQuery<T, K,
|
|
412
|
+
relationConfig: HasOneInfo<T, K, T['relations'][K], HasOneQuery<T, K, RelationTableToQuery<T['relations'][K]>>>;
|
|
410
413
|
} : T['relations'][K] extends HasMany ? {
|
|
411
|
-
relationConfig: HasManyInfo<T, K, T['relations'][K], HasOneQuery<T, K,
|
|
414
|
+
relationConfig: HasManyInfo<T, K, T['relations'][K], HasOneQuery<T, K, RelationTableToQuery<T['relations'][K]>>>;
|
|
412
415
|
} : T['relations'][K] extends HasAndBelongsToMany ? {
|
|
413
|
-
relationConfig: HasAndBelongsToManyInfo<T, K, T['relations'][K], HasAndBelongsToManyQuery<K,
|
|
416
|
+
relationConfig: HasAndBelongsToManyInfo<T, K, T['relations'][K], HasAndBelongsToManyQuery<K, RelationTableToQuery<T['relations'][K]>>>;
|
|
414
417
|
} : never;
|
|
415
418
|
type MapRelations<T> = T extends RelationConfigSelf ? {
|
|
416
419
|
[K in keyof T['relations'] & string]: MapRelation<T, K>;
|
|
@@ -437,7 +440,6 @@ interface TableToDb<T extends ORMTableInput, Relations extends RelationsBase> ex
|
|
|
437
440
|
};
|
|
438
441
|
}
|
|
439
442
|
type ORMTableInputToQueryBuilder<T extends ORMTableInput> = T extends RelationConfigSelf ? TableToDb<T, MapRelations<T>> : TableToDb<T, EmptyObject>;
|
|
440
|
-
type ScopeFn<Related extends TableClass, Scope extends Query> = (q: ORMTableInputToQueryBuilder<InstanceType<Related>>) => Scope;
|
|
441
443
|
interface ORMTableInput {
|
|
442
444
|
table: string;
|
|
443
445
|
columns: {
|
|
@@ -596,7 +598,7 @@ interface BaseTableInstance<ColumnTypes> {
|
|
|
596
598
|
shape: Shape;
|
|
597
599
|
};
|
|
598
600
|
}, scopes: DbTableOptionScopes<Table, Shape, Keys>): CoreQueryScopes<Keys>;
|
|
599
|
-
belongsTo<Columns extends ColumnsShapeBase, Related extends TableClass,
|
|
601
|
+
belongsTo<Columns extends ColumnsShapeBase, Related extends TableClass, Options extends BelongsToOptions<Columns, Related>>(this: {
|
|
600
602
|
columns: {
|
|
601
603
|
shape: Columns;
|
|
602
604
|
};
|
|
@@ -605,7 +607,7 @@ interface BaseTableInstance<ColumnTypes> {
|
|
|
605
607
|
fn: () => Related;
|
|
606
608
|
options: Options;
|
|
607
609
|
};
|
|
608
|
-
hasOne<Columns extends ColumnsShapeBase, Related extends TableClass,
|
|
610
|
+
hasOne<Columns extends ColumnsShapeBase, Related extends TableClass, Through extends string, Source extends string, Options extends HasOneOptions<Columns, Related, Through, Source>>(this: {
|
|
609
611
|
columns: {
|
|
610
612
|
shape: Columns;
|
|
611
613
|
};
|
|
@@ -614,7 +616,7 @@ interface BaseTableInstance<ColumnTypes> {
|
|
|
614
616
|
fn: () => Related;
|
|
615
617
|
options: Options;
|
|
616
618
|
};
|
|
617
|
-
hasMany<Columns extends ColumnsShapeBase, Related extends TableClass,
|
|
619
|
+
hasMany<Columns extends ColumnsShapeBase, Related extends TableClass, Through extends string, Source extends string, Options extends HasOneOptions<Columns, Related, Through, Source>>(this: {
|
|
618
620
|
columns: {
|
|
619
621
|
shape: Columns;
|
|
620
622
|
};
|
|
@@ -623,7 +625,7 @@ interface BaseTableInstance<ColumnTypes> {
|
|
|
623
625
|
fn: () => Related;
|
|
624
626
|
options: Options;
|
|
625
627
|
};
|
|
626
|
-
hasAndBelongsToMany<Columns extends ColumnsShapeBase, Related extends TableClass,
|
|
628
|
+
hasAndBelongsToMany<Columns extends ColumnsShapeBase, Related extends TableClass, Options extends HasAndBelongsToManyOptions<Columns, Related>>(this: {
|
|
627
629
|
columns: {
|
|
628
630
|
shape: Columns;
|
|
629
631
|
};
|
|
@@ -715,4 +717,4 @@ declare const createRepo: <T extends Query, Methods extends MethodsBase<T>>(tabl
|
|
|
715
717
|
shape: T['shape'];
|
|
716
718
|
}>(q: Q) => Query & Q & MapMethods<T, Methods>) & T, Methods>;
|
|
717
719
|
|
|
718
|
-
export { type BaseTableClass, type BaseTableInstance, type Insertable, type MapMethods, type MapQueryMethods, type MethodsBase, type ORMTableInput, type ORMTableInputToQueryBuilder, type OrchidORM, type Queryable, type Repo, type
|
|
720
|
+
export { type BaseTableClass, type BaseTableInstance, type Insertable, type MapMethods, type MapQueryMethods, type MethodsBase, type ORMTableInput, type ORMTableInputToQueryBuilder, type OrchidORM, type Queryable, type Repo, type Selectable, type SetColumnsResult, type Table, type TableClass, type TableClasses, type TableInfo, type TableToDb, type Updatable, createBaseTable, createRepo, orchidORM };
|
package/dist/index.js
CHANGED
|
@@ -181,7 +181,7 @@ const hasRelationHandleCreate = (q, ctx, item, rowIndex, key, primaryKeys, neste
|
|
|
181
181
|
};
|
|
182
182
|
const hasRelationHandleUpdate = (q, set, key, primaryKeys, nestedUpdate) => {
|
|
183
183
|
const value = set[key];
|
|
184
|
-
if (!value.set && !("upsert" in value) && (!value.disconnect || Array.isArray(value.disconnect) && value.disconnect.length === 0) && (!value.delete || Array.isArray(value.delete) && value.delete.length === 0) && (!value.update || Array.isArray(value.update.where) && value.update.where.length === 0) && (!value.create || Array.isArray(value.create) && value.create.length === 0))
|
|
184
|
+
if (!value.set && !("upsert" in value) && (!value.add || Array.isArray(value.add) && value.add.length === 0) && (!value.disconnect || Array.isArray(value.disconnect) && value.disconnect.length === 0) && (!value.delete || Array.isArray(value.delete) && value.delete.length === 0) && (!value.update || Array.isArray(value.update.where) && value.update.where.length === 0) && (!value.create || Array.isArray(value.create) && value.create.length === 0))
|
|
185
185
|
return;
|
|
186
186
|
selectIfNotSelected(q, primaryKeys);
|
|
187
187
|
q.q.wrapInTransaction = true;
|
|
@@ -204,13 +204,6 @@ const selectIfNotSelected = (q, columns) => {
|
|
|
204
204
|
q.q.select = select;
|
|
205
205
|
}
|
|
206
206
|
};
|
|
207
|
-
const relationWhere = (len, keys, valueKeys) => (params) => {
|
|
208
|
-
const obj = {};
|
|
209
|
-
for (let i = 0; i < len; i++) {
|
|
210
|
-
obj[keys[i]] = params[valueKeys[i]];
|
|
211
|
-
}
|
|
212
|
-
return obj;
|
|
213
|
-
};
|
|
214
207
|
function joinHasThrough(q, baseQuery, joiningQuery, throughRelation, sourceRelation) {
|
|
215
208
|
return q.whereExists(
|
|
216
209
|
throughRelation.joinQuery(throughRelation.query, baseQuery),
|
|
@@ -224,14 +217,9 @@ function joinHasThrough(q, baseQuery, joiningQuery, throughRelation, sourceRelat
|
|
|
224
217
|
);
|
|
225
218
|
}
|
|
226
219
|
function joinHasRelation(baseQuery, joiningQuery, primaryKeys, foreignKeys, len) {
|
|
227
|
-
const q = joiningQuery.clone();
|
|
228
|
-
pqb.setQueryObjectValue(
|
|
229
|
-
q,
|
|
230
|
-
"joinedShapes",
|
|
231
|
-
baseQuery.q.as || baseQuery.table,
|
|
232
|
-
baseQuery.q.shape
|
|
233
|
-
);
|
|
234
220
|
const baseAs = pqb.getQueryAs(baseQuery);
|
|
221
|
+
const q = joiningQuery.clone();
|
|
222
|
+
pqb.setQueryObjectValueImmutable(q, "joinedShapes", baseAs, baseQuery.q.shape);
|
|
235
223
|
for (let i = 0; i < len; i++) {
|
|
236
224
|
pqb.pushQueryOnForOuter(
|
|
237
225
|
q,
|
|
@@ -340,7 +328,7 @@ class BelongsToVirtualColumn extends pqb.VirtualColumn {
|
|
|
340
328
|
const relationData = [values];
|
|
341
329
|
store.belongsTo[key] = relationData;
|
|
342
330
|
q.q.wrapInTransaction = true;
|
|
343
|
-
pqb.
|
|
331
|
+
pqb.pushQueryValueImmutable(q, "beforeCreate", async (q2) => {
|
|
344
332
|
const inserted = await this.nestedInsert(
|
|
345
333
|
q2,
|
|
346
334
|
relationData.map(([, , data]) => data)
|
|
@@ -364,9 +352,13 @@ class BelongsToVirtualColumn extends pqb.VirtualColumn {
|
|
|
364
352
|
const makeBelongsToMethod = (tableConfig, table, relation, relationName, query) => {
|
|
365
353
|
const primaryKeys = relation.options.references;
|
|
366
354
|
const foreignKeys = relation.options.columns;
|
|
355
|
+
const { on } = relation.options;
|
|
356
|
+
if (on) {
|
|
357
|
+
pqb._queryWhere(query, [on]);
|
|
358
|
+
pqb._queryDefaults(query, on);
|
|
359
|
+
}
|
|
367
360
|
const len = primaryKeys.length;
|
|
368
|
-
const state = { query, primaryKeys, foreignKeys, len };
|
|
369
|
-
const makeWhere = relationWhere(len, primaryKeys, foreignKeys);
|
|
361
|
+
const state = { query, primaryKeys, foreignKeys, len, on };
|
|
370
362
|
addAutoForeignKey(
|
|
371
363
|
tableConfig,
|
|
372
364
|
table,
|
|
@@ -376,14 +368,9 @@ const makeBelongsToMethod = (tableConfig, table, relation, relationName, query)
|
|
|
376
368
|
relation.options
|
|
377
369
|
);
|
|
378
370
|
const join = (baseQuery, joiningQuery, primaryKeys2, foreignKeys2) => {
|
|
379
|
-
const q = joiningQuery.clone();
|
|
380
|
-
pqb.setQueryObjectValue(
|
|
381
|
-
q,
|
|
382
|
-
"joinedShapes",
|
|
383
|
-
baseQuery.q.as || baseQuery.table,
|
|
384
|
-
baseQuery.q.shape
|
|
385
|
-
);
|
|
386
371
|
const baseAs = pqb.getQueryAs(baseQuery);
|
|
372
|
+
const q = joiningQuery.clone();
|
|
373
|
+
pqb.setQueryObjectValueImmutable(q, "joinedShapes", baseAs, baseQuery.q.shape);
|
|
387
374
|
for (let i = 0; i < len; i++) {
|
|
388
375
|
pqb.pushQueryOnForOuter(
|
|
389
376
|
q,
|
|
@@ -406,7 +393,11 @@ const makeBelongsToMethod = (tableConfig, table, relation, relationName, query)
|
|
|
406
393
|
return {
|
|
407
394
|
returns: "one",
|
|
408
395
|
queryRelated(params) {
|
|
409
|
-
|
|
396
|
+
const obj = {};
|
|
397
|
+
for (let i = 0; i < len; i++) {
|
|
398
|
+
obj[primaryKeys[i]] = params[foreignKeys[i]];
|
|
399
|
+
}
|
|
400
|
+
return query.where(obj);
|
|
410
401
|
},
|
|
411
402
|
virtualColumn: new BelongsToVirtualColumn(
|
|
412
403
|
pqb.defaultSchemaConfig,
|
|
@@ -420,13 +411,21 @@ const makeBelongsToMethod = (tableConfig, table, relation, relationName, query)
|
|
|
420
411
|
reverseJoin
|
|
421
412
|
};
|
|
422
413
|
};
|
|
423
|
-
const nestedInsert$3 = ({ query, primaryKeys }) => {
|
|
414
|
+
const nestedInsert$3 = ({ query, primaryKeys, on }) => {
|
|
424
415
|
return async (_, data) => {
|
|
425
416
|
const t = query.clone();
|
|
426
417
|
const items = [];
|
|
427
418
|
for (const item of data) {
|
|
428
419
|
if (item.connectOrCreate) {
|
|
429
|
-
items.push(
|
|
420
|
+
items.push(
|
|
421
|
+
on ? {
|
|
422
|
+
...item,
|
|
423
|
+
connectOrCreate: {
|
|
424
|
+
...item.connectOrCreate,
|
|
425
|
+
where: { ...item.connectOrCreate.where, ...on }
|
|
426
|
+
}
|
|
427
|
+
} : item
|
|
428
|
+
);
|
|
430
429
|
}
|
|
431
430
|
}
|
|
432
431
|
let connectOrCreated;
|
|
@@ -464,7 +463,9 @@ const nestedInsert$3 = ({ query, primaryKeys }) => {
|
|
|
464
463
|
items.length = 0;
|
|
465
464
|
for (const item of data) {
|
|
466
465
|
if (item.connect) {
|
|
467
|
-
items.push(
|
|
466
|
+
items.push(
|
|
467
|
+
on ? { ...item, connect: { ...item.connect, ...on } } : item
|
|
468
|
+
);
|
|
468
469
|
}
|
|
469
470
|
}
|
|
470
471
|
let connected;
|
|
@@ -551,12 +552,11 @@ const nestedUpdate$3 = ({ query, primaryKeys, foreignKeys, len }) => {
|
|
|
551
552
|
}
|
|
552
553
|
obj[primaryKeys[i]] = id;
|
|
553
554
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
} else {
|
|
555
|
+
const count = obj ? await pqb._queryUpdate(
|
|
556
|
+
query.findBy(obj),
|
|
557
|
+
upsert.update
|
|
558
|
+
) : 0;
|
|
559
|
+
if (!count) {
|
|
560
560
|
const data = typeof upsert.create === "function" ? upsert.create() : upsert.create;
|
|
561
561
|
const result = await pqb._queryCreate(
|
|
562
562
|
query.select(...primaryKeys),
|
|
@@ -647,10 +647,13 @@ const makeHasOneMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
647
647
|
const { through, source } = relation.options;
|
|
648
648
|
const throughRelation = getThroughRelation(table, through);
|
|
649
649
|
const sourceRelation = getSourceRelation(throughRelation, source);
|
|
650
|
+
const sourceRelationQuery = sourceRelation.query.as(
|
|
651
|
+
relationName
|
|
652
|
+
);
|
|
650
653
|
const sourceQuery = sourceRelation.joinQuery(
|
|
651
|
-
|
|
654
|
+
sourceRelationQuery,
|
|
652
655
|
throughRelation.query
|
|
653
|
-
)
|
|
656
|
+
);
|
|
654
657
|
const whereExistsCallback = () => sourceQuery;
|
|
655
658
|
const reverseJoin2 = (baseQuery, joiningQuery) => {
|
|
656
659
|
return joinHasThrough(
|
|
@@ -682,6 +685,11 @@ const makeHasOneMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
682
685
|
}
|
|
683
686
|
const primaryKeys = relation.options.columns;
|
|
684
687
|
const foreignKeys = relation.options.references;
|
|
688
|
+
const { on } = relation.options;
|
|
689
|
+
if (on) {
|
|
690
|
+
pqb._queryWhere(query, [on]);
|
|
691
|
+
pqb._queryDefaults(query, on);
|
|
692
|
+
}
|
|
685
693
|
addAutoForeignKey(
|
|
686
694
|
tableConfig,
|
|
687
695
|
query,
|
|
@@ -690,7 +698,7 @@ const makeHasOneMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
690
698
|
foreignKeys,
|
|
691
699
|
relation.options
|
|
692
700
|
);
|
|
693
|
-
const state = { query, primaryKeys, foreignKeys };
|
|
701
|
+
const state = { query, primaryKeys, foreignKeys, on };
|
|
694
702
|
const len = primaryKeys.length;
|
|
695
703
|
const reversedOn = {};
|
|
696
704
|
for (let i = 0; i < len; i++) {
|
|
@@ -713,7 +721,7 @@ const makeHasOneMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
713
721
|
for (let i = 0; i < len; i++) {
|
|
714
722
|
values[foreignKeys[i]] = params[primaryKeys[i]];
|
|
715
723
|
}
|
|
716
|
-
return pqb._queryDefaults(query.where(values), values);
|
|
724
|
+
return pqb._queryDefaults(query.where(values), { ...on, ...values });
|
|
717
725
|
},
|
|
718
726
|
virtualColumn: new HasOneVirtualColumn(
|
|
719
727
|
pqb.defaultSchemaConfig,
|
|
@@ -837,7 +845,9 @@ const nestedUpdate$2 = ({ query, primaryKeys, foreignKeys }) => {
|
|
|
837
845
|
} else if (params.update) {
|
|
838
846
|
await pqb._queryUpdate(currentRelationsQuery, params.update);
|
|
839
847
|
} else if (params.delete) {
|
|
840
|
-
|
|
848
|
+
const q = pqb._queryDelete(currentRelationsQuery);
|
|
849
|
+
q.q.returnType = "value";
|
|
850
|
+
await q;
|
|
841
851
|
} else if (params.upsert) {
|
|
842
852
|
const { update, create } = params.upsert;
|
|
843
853
|
currentRelationsQuery.q.select = foreignKeys;
|
|
@@ -946,6 +956,11 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
946
956
|
}
|
|
947
957
|
const primaryKeys = relation.options.columns;
|
|
948
958
|
const foreignKeys = relation.options.references;
|
|
959
|
+
const { on } = relation.options;
|
|
960
|
+
if (on) {
|
|
961
|
+
pqb._queryWhere(query, [on]);
|
|
962
|
+
pqb._queryDefaults(query, on);
|
|
963
|
+
}
|
|
949
964
|
addAutoForeignKey(
|
|
950
965
|
tableConfig,
|
|
951
966
|
query,
|
|
@@ -954,7 +969,7 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
954
969
|
foreignKeys,
|
|
955
970
|
relation.options
|
|
956
971
|
);
|
|
957
|
-
const state = { query, primaryKeys, foreignKeys };
|
|
972
|
+
const state = { query, primaryKeys, foreignKeys, on };
|
|
958
973
|
const len = primaryKeys.length;
|
|
959
974
|
const reversedOn = {};
|
|
960
975
|
for (let i = 0; i < len; i++) {
|
|
@@ -977,7 +992,7 @@ const makeHasManyMethod = (tableConfig, table, relation, relationName, query) =>
|
|
|
977
992
|
for (let i = 0; i < len; i++) {
|
|
978
993
|
values[foreignKeys[i]] = params[primaryKeys[i]];
|
|
979
994
|
}
|
|
980
|
-
return pqb._queryDefaults(query.where(values), values);
|
|
995
|
+
return pqb._queryDefaults(query.where(values), { ...on, ...values });
|
|
981
996
|
},
|
|
982
997
|
virtualColumn: new HasManyVirtualColumn(
|
|
983
998
|
pqb.defaultSchemaConfig,
|
|
@@ -1033,7 +1048,7 @@ const nestedInsert$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
|
1033
1048
|
obj[foreignKeys[i2]] = selfData[primaryKeys[i2]];
|
|
1034
1049
|
}
|
|
1035
1050
|
items[i] = pqb._queryUpdateOrThrow(
|
|
1036
|
-
t.
|
|
1051
|
+
t.where({ OR: connect }),
|
|
1037
1052
|
obj
|
|
1038
1053
|
);
|
|
1039
1054
|
}
|
|
@@ -1131,6 +1146,29 @@ const nestedUpdate$1 = ({ query, primaryKeys, foreignKeys }) => {
|
|
|
1131
1146
|
);
|
|
1132
1147
|
delete t.q.sqlCache;
|
|
1133
1148
|
}
|
|
1149
|
+
if (params.add) {
|
|
1150
|
+
if (data.length > 1) {
|
|
1151
|
+
throw new pqb.OrchidOrmInternalError(
|
|
1152
|
+
query,
|
|
1153
|
+
"`connect` is not available when updating multiple records, it is only applicable for a single record update"
|
|
1154
|
+
);
|
|
1155
|
+
}
|
|
1156
|
+
const obj = {};
|
|
1157
|
+
for (let i = 0; i < len; i++) {
|
|
1158
|
+
obj[foreignKeys[i]] = data[0][primaryKeys[i]];
|
|
1159
|
+
}
|
|
1160
|
+
const relatedWheres = orchidCore.toArray(params.add);
|
|
1161
|
+
const count = await pqb._queryUpdate(
|
|
1162
|
+
t.where({ OR: relatedWheres }),
|
|
1163
|
+
obj
|
|
1164
|
+
);
|
|
1165
|
+
if (count < relatedWheres.length) {
|
|
1166
|
+
throw new pqb.OrchidOrmInternalError(
|
|
1167
|
+
query,
|
|
1168
|
+
`Expected to find at least ${relatedWheres.length} record(s) based on \`add\` conditions, but found ${count}`
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1134
1172
|
if (params.disconnect || params.set) {
|
|
1135
1173
|
const obj = {};
|
|
1136
1174
|
for (const foreignKey of foreignKeys) {
|
|
@@ -1223,6 +1261,11 @@ const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relatio
|
|
|
1223
1261
|
const joinTable = options.through.table;
|
|
1224
1262
|
const throughForeignKeys = options.through.columns;
|
|
1225
1263
|
const throughPrimaryKeys = options.through.references;
|
|
1264
|
+
const { on } = options;
|
|
1265
|
+
if (on) {
|
|
1266
|
+
pqb._queryWhere(query, [on]);
|
|
1267
|
+
pqb._queryDefaults(query, on);
|
|
1268
|
+
}
|
|
1226
1269
|
const { snakeCase } = table.internal;
|
|
1227
1270
|
const foreignKeysFull = foreignKeys.map((key, i) => {
|
|
1228
1271
|
if (snakeCase) key = foreignKeys[i] = orchidCore.toSnakeCase(key);
|
|
@@ -1242,10 +1285,11 @@ const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relatio
|
|
|
1242
1285
|
baseQuery.baseQuery = baseQuery;
|
|
1243
1286
|
baseQuery.table = joinTable;
|
|
1244
1287
|
const shape = {};
|
|
1288
|
+
const primaryKeysShape = {};
|
|
1245
1289
|
for (let i = 0; i < len; i++) {
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1290
|
+
const pk = primaryKeys[i];
|
|
1291
|
+
shape[foreignKeys[i]] = removeColumnName(table.shape[pk]);
|
|
1292
|
+
primaryKeysShape[pk] = table.shape[pk];
|
|
1249
1293
|
}
|
|
1250
1294
|
for (let i = 0; i < throughLen; i++) {
|
|
1251
1295
|
shape[throughForeignKeys[i]] = removeColumnName(
|
|
@@ -1283,7 +1327,9 @@ const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relatio
|
|
|
1283
1327
|
throughPrimaryKeys,
|
|
1284
1328
|
foreignKeysFull,
|
|
1285
1329
|
throughForeignKeysFull,
|
|
1286
|
-
throughPrimaryKeysFull
|
|
1330
|
+
throughPrimaryKeysFull,
|
|
1331
|
+
primaryKeysShape,
|
|
1332
|
+
on
|
|
1287
1333
|
};
|
|
1288
1334
|
const joinQuery = (joiningQuery, tableAs, foreignAs, joinedShapes) => {
|
|
1289
1335
|
const cloned = joiningQuery.clone();
|
|
@@ -1323,20 +1369,21 @@ const makeHasAndBelongsToManyMethod = (tableConfig, table, qb, relation, relatio
|
|
|
1323
1369
|
return {
|
|
1324
1370
|
returns: "many",
|
|
1325
1371
|
queryRelated(params) {
|
|
1326
|
-
|
|
1327
|
-
|
|
1372
|
+
const q = query.whereExists(subQuery, (q2) => {
|
|
1373
|
+
q2 = q2.clone();
|
|
1328
1374
|
const where = {};
|
|
1329
1375
|
for (let i = 0; i < len; i++) {
|
|
1330
1376
|
where[foreignKeysFull[i]] = params[primaryKeys[i]];
|
|
1331
1377
|
}
|
|
1332
1378
|
for (let i = 0; i < throughLen; i++) {
|
|
1333
|
-
pqb._queryJoinOn(
|
|
1379
|
+
pqb._queryJoinOn(q2, [
|
|
1334
1380
|
throughForeignKeysFull[i],
|
|
1335
1381
|
throughPrimaryKeysFull[i]
|
|
1336
1382
|
]);
|
|
1337
1383
|
}
|
|
1338
|
-
return pqb._queryWhere(
|
|
1384
|
+
return pqb._queryWhere(q2, [where]);
|
|
1339
1385
|
});
|
|
1386
|
+
return on ? pqb._queryDefaults(q, on) : q;
|
|
1340
1387
|
},
|
|
1341
1388
|
virtualColumn: new HasAndBelongsToManyVirtualColumn(
|
|
1342
1389
|
subQuery,
|
|
@@ -1411,6 +1458,19 @@ const queryJoinTable = (state, data, conditions) => {
|
|
|
1411
1458
|
}
|
|
1412
1459
|
]);
|
|
1413
1460
|
}
|
|
1461
|
+
if (state.on) {
|
|
1462
|
+
pqb._queryWhereExists(t, state.relatedTableQuery, [
|
|
1463
|
+
(q) => {
|
|
1464
|
+
for (let i = 0; i < state.throughPrimaryKeys.length; i++) {
|
|
1465
|
+
pqb._queryJoinOn(q, [
|
|
1466
|
+
state.throughPrimaryKeysFull[i],
|
|
1467
|
+
state.throughForeignKeysFull[i]
|
|
1468
|
+
]);
|
|
1469
|
+
}
|
|
1470
|
+
return q;
|
|
1471
|
+
}
|
|
1472
|
+
]);
|
|
1473
|
+
}
|
|
1414
1474
|
return t;
|
|
1415
1475
|
};
|
|
1416
1476
|
const conditionsToWhereArg = (conditions) => Array.isArray(conditions) ? { OR: conditions } : conditions;
|
|
@@ -1580,7 +1640,7 @@ const nestedInsert = ({
|
|
|
1580
1640
|
const nestedUpdate = (state) => {
|
|
1581
1641
|
const len = state.primaryKeys.length;
|
|
1582
1642
|
const throughLen = state.throughPrimaryKeys.length;
|
|
1583
|
-
return async (
|
|
1643
|
+
return async (query, data, params) => {
|
|
1584
1644
|
if (params.create) {
|
|
1585
1645
|
const idsRows = await pqb._queryCreateMany(
|
|
1586
1646
|
pqb._queryRows(state.relatedTableQuery.select(...state.throughPrimaryKeys)),
|
|
@@ -1628,6 +1688,58 @@ const nestedUpdate = (state) => {
|
|
|
1628
1688
|
params.update.data
|
|
1629
1689
|
);
|
|
1630
1690
|
}
|
|
1691
|
+
if (params.add) {
|
|
1692
|
+
const as = query.table;
|
|
1693
|
+
const relatedWheres = orchidCore.toArray(params.add);
|
|
1694
|
+
const joinTableColumns = [
|
|
1695
|
+
...state.foreignKeys,
|
|
1696
|
+
...state.throughForeignKeys
|
|
1697
|
+
];
|
|
1698
|
+
try {
|
|
1699
|
+
const count = await state.joinTableQuery.insertManyFrom(
|
|
1700
|
+
pqb._querySelect(
|
|
1701
|
+
state.relatedTableQuery.whereOneOf(...relatedWheres),
|
|
1702
|
+
[
|
|
1703
|
+
Object.fromEntries([
|
|
1704
|
+
...state.primaryKeys.map((key, i) => [
|
|
1705
|
+
state.foreignKeys[i],
|
|
1706
|
+
as + "." + (state.primaryKeysShape[key].data.name || key)
|
|
1707
|
+
]),
|
|
1708
|
+
...state.throughForeignKeys.map((key, i) => [
|
|
1709
|
+
key,
|
|
1710
|
+
state.throughPrimaryKeys[i]
|
|
1711
|
+
])
|
|
1712
|
+
])
|
|
1713
|
+
]
|
|
1714
|
+
).joinData(
|
|
1715
|
+
as,
|
|
1716
|
+
() => Object.fromEntries(
|
|
1717
|
+
state.primaryKeys.map((key) => [
|
|
1718
|
+
key,
|
|
1719
|
+
state.primaryKeysShape[key]
|
|
1720
|
+
])
|
|
1721
|
+
),
|
|
1722
|
+
data.map((x) => orchidCore.pick(x, state.primaryKeys))
|
|
1723
|
+
)
|
|
1724
|
+
).onConflict(joinTableColumns).merge([state.foreignKeys[0]]);
|
|
1725
|
+
if (count < data.length * relatedWheres.length) {
|
|
1726
|
+
throw new pqb.OrchidOrmInternalError(
|
|
1727
|
+
query,
|
|
1728
|
+
`Expected to find at least ${relatedWheres.length} record(s) based on \`add\` conditions, but found ${count / data.length}`
|
|
1729
|
+
);
|
|
1730
|
+
}
|
|
1731
|
+
} catch (err) {
|
|
1732
|
+
if (err.code === "42P10") {
|
|
1733
|
+
throw new pqb.OrchidOrmInternalError(
|
|
1734
|
+
query,
|
|
1735
|
+
`"${state.joinTableQuery.table}" must have a primary key or a unique index on columns (${joinTableColumns.join(
|
|
1736
|
+
", "
|
|
1737
|
+
)}) for this kind of query.`
|
|
1738
|
+
);
|
|
1739
|
+
}
|
|
1740
|
+
throw err;
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1631
1743
|
if (params.disconnect) {
|
|
1632
1744
|
await pqb._queryDelete(
|
|
1633
1745
|
queryJoinTable(state, data, params.disconnect)
|
|
@@ -1755,7 +1867,7 @@ const delayRelation = (delayedRelations, table, relationName, data) => {
|
|
|
1755
1867
|
const applyRelation = (table, qb, { relationName, relation, dbTable, otherDbTable }, delayedRelations) => {
|
|
1756
1868
|
const baseQuery = Object.create(otherDbTable);
|
|
1757
1869
|
baseQuery.baseQuery = baseQuery;
|
|
1758
|
-
const query =
|
|
1870
|
+
const query = baseQuery.as(relationName);
|
|
1759
1871
|
const definedAs = query.definedAs;
|
|
1760
1872
|
if (!definedAs) {
|
|
1761
1873
|
throw new Error(
|