pqb 0.56.4 → 0.56.6
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 +209 -116
- package/dist/index.js +470 -282
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +467 -280
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -169,9 +169,7 @@ class ColumnType extends orchidCore.ColumnTypeBase {
|
|
|
169
169
|
* // options are described below:
|
|
170
170
|
* name: t.text().index({ ...options }),
|
|
171
171
|
* // with a database-level name:
|
|
172
|
-
* name: t.text().index('custom_index_name'),
|
|
173
|
-
* // with name and options:
|
|
174
|
-
* name: t.text().index('custom_index_name', { ...options }),
|
|
172
|
+
* name: t.text().index({ name: 'custom_index_name', ...indexOptions }),
|
|
175
173
|
* }));
|
|
176
174
|
* });
|
|
177
175
|
* ```
|
|
@@ -180,6 +178,7 @@ class ColumnType extends orchidCore.ColumnTypeBase {
|
|
|
180
178
|
*
|
|
181
179
|
* ```ts
|
|
182
180
|
* type IndexOptions = {
|
|
181
|
+
* name?: string,
|
|
183
182
|
* // NULLS NOT DISTINCT: availabe in Postgres 15+, makes sense only for unique index
|
|
184
183
|
* nullsNotDistinct?: true;
|
|
185
184
|
* // index algorithm to use such as GIST, GIN
|
|
@@ -206,9 +205,9 @@ class ColumnType extends orchidCore.ColumnTypeBase {
|
|
|
206
205
|
* @param args
|
|
207
206
|
*/
|
|
208
207
|
index(...args) {
|
|
208
|
+
const a = args;
|
|
209
209
|
return orchidCore.pushColumnData(this, "indexes", {
|
|
210
|
-
options: (typeof
|
|
211
|
-
name: typeof args[0] === "string" ? args[0] : void 0
|
|
210
|
+
options: (typeof a[0] === "string" ? { ...a[1], name: a[0] } : a[0]) ?? orchidCore.emptyObject
|
|
212
211
|
});
|
|
213
212
|
}
|
|
214
213
|
/**
|
|
@@ -314,21 +313,21 @@ class ColumnType extends orchidCore.ColumnTypeBase {
|
|
|
314
313
|
* @param options - index options
|
|
315
314
|
*/
|
|
316
315
|
searchIndex(...args) {
|
|
316
|
+
const a = args;
|
|
317
317
|
return orchidCore.pushColumnData(this, "indexes", {
|
|
318
318
|
options: {
|
|
319
|
-
...typeof
|
|
319
|
+
...typeof a[0] === "string" ? { ...a[1], name: a[0] } : a[0],
|
|
320
320
|
...this.dataType === "tsvector" ? { using: "GIN" } : { tsVector: true }
|
|
321
|
-
}
|
|
322
|
-
name: typeof args[0] === "string" ? args[0] : void 0
|
|
321
|
+
}
|
|
323
322
|
});
|
|
324
323
|
}
|
|
325
324
|
unique(...args) {
|
|
325
|
+
const a = args;
|
|
326
326
|
return orchidCore.pushColumnData(this, "indexes", {
|
|
327
327
|
options: {
|
|
328
|
-
...typeof
|
|
328
|
+
...typeof a[0] === "string" ? { ...a[1], name: a[0] } : a[0],
|
|
329
329
|
unique: true
|
|
330
|
-
}
|
|
331
|
-
name: typeof args[0] === "string" ? args[0] : void 0
|
|
330
|
+
}
|
|
332
331
|
});
|
|
333
332
|
}
|
|
334
333
|
/**
|
|
@@ -376,11 +375,11 @@ class ColumnType extends orchidCore.ColumnTypeBase {
|
|
|
376
375
|
* }
|
|
377
376
|
* ```
|
|
378
377
|
*/
|
|
379
|
-
exclude(...args) {
|
|
378
|
+
exclude(op, ...args) {
|
|
379
|
+
const a = args;
|
|
380
380
|
return orchidCore.pushColumnData(this, "excludes", {
|
|
381
|
-
with:
|
|
382
|
-
options: (typeof
|
|
383
|
-
name: typeof args[1] === "string" ? args[1] : void 0
|
|
381
|
+
with: op,
|
|
382
|
+
options: (typeof a[0] === "string" ? { ...a[1], name: a[0] } : a[0]) ?? orchidCore.emptyObject
|
|
384
383
|
});
|
|
385
384
|
}
|
|
386
385
|
comment(comment) {
|
|
@@ -541,6 +540,7 @@ const indexInnerToCode = (index, t) => {
|
|
|
541
540
|
const columnOptions = ["collate", "opclass", "order", "weight"];
|
|
542
541
|
const indexOptionsKeys = [
|
|
543
542
|
index.options.tsVector ? "unique" : void 0,
|
|
543
|
+
"name",
|
|
544
544
|
"using",
|
|
545
545
|
"nullsNotDistinct",
|
|
546
546
|
"include",
|
|
@@ -586,18 +586,12 @@ const indexInnerToCode = (index, t) => {
|
|
|
586
586
|
objects.push("{", props, "},");
|
|
587
587
|
}
|
|
588
588
|
}
|
|
589
|
-
code.push(["[", objects, hasOptions
|
|
590
|
-
if (index.name) {
|
|
591
|
-
orchidCore.addCode(code, ` ${orchidCore.singleQuote(index.name)},`);
|
|
592
|
-
}
|
|
589
|
+
code.push(["[", objects, hasOptions ? "]," : "]"]);
|
|
593
590
|
} else {
|
|
594
591
|
orchidCore.addCode(
|
|
595
592
|
code,
|
|
596
593
|
`[${index.columns.map((it) => orchidCore.singleQuote(it.column)).join(", ")}]`
|
|
597
594
|
);
|
|
598
|
-
if (index.name) {
|
|
599
|
-
orchidCore.addCode(code, `, ${orchidCore.singleQuote(index.name)}`);
|
|
600
|
-
}
|
|
601
595
|
}
|
|
602
596
|
if (hasOptions) {
|
|
603
597
|
if (columnsMultiline) {
|
|
@@ -633,6 +627,7 @@ const excludeInnerToCode = (item, t) => {
|
|
|
633
627
|
const code = [`${t}.exclude(`];
|
|
634
628
|
const columnOptions = ["collate", "opclass", "order", "with"];
|
|
635
629
|
const optionsKeys = [
|
|
630
|
+
"name",
|
|
636
631
|
"using",
|
|
637
632
|
"include",
|
|
638
633
|
"with",
|
|
@@ -657,10 +652,7 @@ const excludeInnerToCode = (item, t) => {
|
|
|
657
652
|
}
|
|
658
653
|
objects.push("{", props, "},");
|
|
659
654
|
}
|
|
660
|
-
code.push(["[", objects, hasOptions
|
|
661
|
-
if (item.name) {
|
|
662
|
-
orchidCore.addCode(code, ` ${orchidCore.singleQuote(item.name)},`);
|
|
663
|
-
}
|
|
655
|
+
code.push(["[", objects, hasOptions ? "]," : "]"]);
|
|
664
656
|
if (hasOptions) {
|
|
665
657
|
code.push(["{"]);
|
|
666
658
|
const options = [];
|
|
@@ -768,12 +760,10 @@ const foreignKeyArgumentToCode = ({
|
|
|
768
760
|
};
|
|
769
761
|
const columnIndexesToCode = (items) => {
|
|
770
762
|
const code = [];
|
|
771
|
-
for (const { options
|
|
772
|
-
orchidCore.addCode(
|
|
773
|
-
code,
|
|
774
|
-
`.${options.unique ? "unique" : "index"}(${name ? `${orchidCore.singleQuote(name)}` : ""}`
|
|
775
|
-
);
|
|
763
|
+
for (const { options } of items) {
|
|
764
|
+
orchidCore.addCode(code, `.${options.unique ? "unique" : "index"}(`);
|
|
776
765
|
const arr = [
|
|
766
|
+
options.name && `name: ${orchidCore.singleQuote(options.name)},`,
|
|
777
767
|
options.collate && `collate: ${orchidCore.singleQuote(options.collate)},`,
|
|
778
768
|
options.opclass && `opclass: ${orchidCore.singleQuote(options.opclass)},`,
|
|
779
769
|
options.order && `order: ${orchidCore.singleQuote(options.order)},`,
|
|
@@ -785,7 +775,7 @@ const columnIndexesToCode = (items) => {
|
|
|
785
775
|
options.where && `where: ${orchidCore.singleQuote(options.where)},`
|
|
786
776
|
].filter((x) => !!x);
|
|
787
777
|
if (arr.length) {
|
|
788
|
-
orchidCore.addCode(code,
|
|
778
|
+
orchidCore.addCode(code, "{");
|
|
789
779
|
orchidCore.addCode(code, arr);
|
|
790
780
|
orchidCore.addCode(code, "}");
|
|
791
781
|
}
|
|
@@ -795,13 +785,13 @@ const columnIndexesToCode = (items) => {
|
|
|
795
785
|
};
|
|
796
786
|
const columnExcludesToCode = (items) => {
|
|
797
787
|
const code = [];
|
|
798
|
-
for (const { options,
|
|
788
|
+
for (const { options, with: w } of items) {
|
|
799
789
|
orchidCore.addCode(code, `.exclude('${w}'`);
|
|
800
790
|
const arr = [
|
|
791
|
+
options.name && `name: ${orchidCore.singleQuote(options.name)},`,
|
|
801
792
|
options.collate && `collate: ${orchidCore.singleQuote(options.collate)},`,
|
|
802
793
|
options.opclass && `opclass: ${orchidCore.singleQuote(options.opclass)},`,
|
|
803
794
|
options.order && `order: ${orchidCore.singleQuote(options.order)},`,
|
|
804
|
-
name && `name: ${orchidCore.singleQuote(name)},`,
|
|
805
795
|
options.using && `using: ${orchidCore.singleQuote(options.using)},`,
|
|
806
796
|
options.include && `include: ${typeof options.include === "string" ? orchidCore.singleQuote(options.include) : `[${options.include.map(orchidCore.singleQuote).join(", ")}]`},`,
|
|
807
797
|
options.with && `with: ${orchidCore.singleQuote(options.with)},`,
|
|
@@ -880,7 +870,9 @@ const columnCode = (type, ctx, key, code) => {
|
|
|
880
870
|
}
|
|
881
871
|
if (data.explicitSelect) orchidCore.addCode(code, ".select(false)");
|
|
882
872
|
if (data.isNullable) orchidCore.addCode(code, ".nullable()");
|
|
883
|
-
if (data.as
|
|
873
|
+
if (data.as && !ctx.migration) {
|
|
874
|
+
orchidCore.addCode(code, `.as(${data.as.toCode(ctx, key)})`);
|
|
875
|
+
}
|
|
884
876
|
if (data.default !== void 0 && data.default !== data.defaultDefault && (!ctx.migration || typeof data.default !== "function")) {
|
|
885
877
|
orchidCore.addCode(
|
|
886
878
|
code,
|
|
@@ -1189,6 +1181,17 @@ const quoteJsonValue = (arg, ctx, quotedAs, IN) => {
|
|
|
1189
1181
|
}
|
|
1190
1182
|
return orchidCore.addValue(ctx.values, JSON.stringify(arg)) + "::jsonb";
|
|
1191
1183
|
};
|
|
1184
|
+
const serializeJsonValue = (arg, ctx, quotedAs) => {
|
|
1185
|
+
if (arg && typeof arg === "object") {
|
|
1186
|
+
if (orchidCore.isExpression(arg)) {
|
|
1187
|
+
return "to_jsonb(" + arg.toSQL(ctx, quotedAs) + ")";
|
|
1188
|
+
}
|
|
1189
|
+
if ("toSQL" in arg) {
|
|
1190
|
+
return `to_jsonb((${getSqlText(arg.toSQL(ctx))}))`;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
return orchidCore.addValue(ctx.values, JSON.stringify(arg));
|
|
1194
|
+
};
|
|
1192
1195
|
const json = {
|
|
1193
1196
|
equals: make(
|
|
1194
1197
|
(key, value, ctx, quotedAs) => value === null ? `nullif(${key}, 'null'::jsonb) IS NULL` : `${key} = ${quoteJsonValue(value, ctx, quotedAs)}`
|
|
@@ -1231,21 +1234,24 @@ const json = {
|
|
|
1231
1234
|
(key, value, ctx, quotedAs) => `${key} <@ ${quoteValue(value, ctx, quotedAs)}`
|
|
1232
1235
|
),
|
|
1233
1236
|
jsonSet: makeVarArg(
|
|
1234
|
-
(key, [path, value], ctx) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
+
(key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(
|
|
1238
|
+
value,
|
|
1239
|
+
ctx,
|
|
1240
|
+
quotedAs
|
|
1237
1241
|
)})`
|
|
1238
1242
|
),
|
|
1239
1243
|
jsonReplace: makeVarArg(
|
|
1240
|
-
(key, [path, value], ctx) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${
|
|
1241
|
-
|
|
1242
|
-
|
|
1244
|
+
(key, [path, value], ctx, quotedAs) => `jsonb_set(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(
|
|
1245
|
+
value,
|
|
1246
|
+
ctx,
|
|
1247
|
+
quotedAs
|
|
1243
1248
|
)}, false)`
|
|
1244
1249
|
),
|
|
1245
1250
|
jsonInsert: makeVarArg(
|
|
1246
|
-
(key, [path, value, options], ctx) => `jsonb_insert(${key}, ${encodeJsonPath(ctx, path)}, ${
|
|
1247
|
-
|
|
1248
|
-
|
|
1251
|
+
(key, [path, value, options], ctx, quotedAs) => `jsonb_insert(${key}, ${encodeJsonPath(ctx, path)}, ${serializeJsonValue(
|
|
1252
|
+
value,
|
|
1253
|
+
ctx,
|
|
1254
|
+
quotedAs
|
|
1249
1255
|
)}${options?.after ? ", true" : ""})`
|
|
1250
1256
|
),
|
|
1251
1257
|
jsonRemove: makeVarArg(
|
|
@@ -4235,14 +4241,7 @@ const throwIfJoinLateral = (q, method) => {
|
|
|
4235
4241
|
};
|
|
4236
4242
|
const saveAliasedShape = (q, as, key) => {
|
|
4237
4243
|
const shapes = q.q[key];
|
|
4238
|
-
|
|
4239
|
-
let suffix = 2;
|
|
4240
|
-
let name;
|
|
4241
|
-
while (shapes[name = `${as}${suffix}`]) {
|
|
4242
|
-
suffix++;
|
|
4243
|
-
}
|
|
4244
|
-
as = name;
|
|
4245
|
-
}
|
|
4244
|
+
as = orchidCore.getFreeAlias(shapes, as);
|
|
4246
4245
|
setQueryObjectValueImmutable(q, key, as, orchidCore.emptyObject);
|
|
4247
4246
|
return as;
|
|
4248
4247
|
};
|
|
@@ -6354,15 +6353,26 @@ const pushWithSql = (ctx, items) => {
|
|
|
6354
6353
|
const sql = withToSql(ctx, items);
|
|
6355
6354
|
if (sql) ctx.sql.push("WITH", sql);
|
|
6356
6355
|
};
|
|
6356
|
+
const pushOrAppendWithSql = (ctx, query, items) => {
|
|
6357
|
+
const sql = withToSql(ctx, items);
|
|
6358
|
+
if (sql) {
|
|
6359
|
+
if (query.with) {
|
|
6360
|
+
ctx.sql[ctx.sql.length - 1] += ",";
|
|
6361
|
+
} else {
|
|
6362
|
+
ctx.sql.push("WITH");
|
|
6363
|
+
}
|
|
6364
|
+
ctx.sql.push(sql);
|
|
6365
|
+
}
|
|
6366
|
+
};
|
|
6357
6367
|
|
|
6358
6368
|
const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
6359
6369
|
let { columns } = query;
|
|
6360
6370
|
const { shape, inCTE, hookCreateSet } = query;
|
|
6361
6371
|
const QueryClass = ctx.qb.constructor;
|
|
6362
|
-
let values = query
|
|
6372
|
+
let { insertFrom, queryColumnsCount, values } = query;
|
|
6363
6373
|
let hookSetSql;
|
|
6364
6374
|
if (hookCreateSet) {
|
|
6365
|
-
({ hookSetSql, columns, values } = processHookSet(
|
|
6375
|
+
({ hookSetSql, columns, insertFrom, queryColumnsCount, values } = processHookSet(
|
|
6366
6376
|
ctx,
|
|
6367
6377
|
q,
|
|
6368
6378
|
values,
|
|
@@ -6381,6 +6391,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6381
6391
|
for (const key of q.internal.runtimeDefaultColumns) {
|
|
6382
6392
|
if (!columns.includes(key)) {
|
|
6383
6393
|
const column = shape[key];
|
|
6394
|
+
columns.push(key);
|
|
6384
6395
|
quotedColumns.push(`"${column.data.name || key}"`);
|
|
6385
6396
|
runtimeDefaults.push(column.data.runtimeDefault);
|
|
6386
6397
|
}
|
|
@@ -6398,8 +6409,22 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6398
6409
|
}
|
|
6399
6410
|
const insertSql = `INSERT INTO ${quotedAs}${quotedColumns.length ? "(" + quotedColumns.join(", ") + ")" : ""}`;
|
|
6400
6411
|
const hasNonSelect = ctx.hasNonSelect;
|
|
6401
|
-
|
|
6402
|
-
|
|
6412
|
+
let hasWith = !!query.with;
|
|
6413
|
+
if (insertFrom) {
|
|
6414
|
+
if (values.length < 2) {
|
|
6415
|
+
if (query.insertWith) {
|
|
6416
|
+
hasWith = true;
|
|
6417
|
+
pushOrAppendWithSql(ctx, query, Object.values(query.insertWith).flat());
|
|
6418
|
+
}
|
|
6419
|
+
} else {
|
|
6420
|
+
hasWith = true;
|
|
6421
|
+
pushOrAppendWithSql(ctx, query, [
|
|
6422
|
+
{
|
|
6423
|
+
n: getQueryAs(insertFrom),
|
|
6424
|
+
q: insertFrom
|
|
6425
|
+
}
|
|
6426
|
+
]);
|
|
6427
|
+
}
|
|
6403
6428
|
}
|
|
6404
6429
|
const valuesPos = ctx.sql.length + 1;
|
|
6405
6430
|
ctx.sql.push(insertSql, null);
|
|
@@ -6475,28 +6500,38 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6475
6500
|
);
|
|
6476
6501
|
}
|
|
6477
6502
|
if (returning.select) ctx.sql.push("RETURNING", returning.select);
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6503
|
+
let insertManyFromValuesAs;
|
|
6504
|
+
if (insertFrom) {
|
|
6505
|
+
if (values.length < 2) {
|
|
6506
|
+
const q2 = insertFrom.clone();
|
|
6507
|
+
if (values[0]?.length) {
|
|
6508
|
+
orchidCore.pushQueryValueImmutable(
|
|
6509
|
+
q2,
|
|
6510
|
+
"select",
|
|
6511
|
+
new RawSQL(
|
|
6512
|
+
encodeRow(
|
|
6513
|
+
ctx,
|
|
6514
|
+
ctx.values,
|
|
6515
|
+
q2,
|
|
6516
|
+
QueryClass,
|
|
6517
|
+
values[0],
|
|
6518
|
+
runtimeDefaults,
|
|
6519
|
+
quotedAs
|
|
6520
|
+
)
|
|
6494
6521
|
)
|
|
6495
|
-
)
|
|
6496
|
-
|
|
6522
|
+
);
|
|
6523
|
+
}
|
|
6524
|
+
ctx.sql[valuesPos] = getSqlText(toSQL(q2, ctx));
|
|
6525
|
+
} else {
|
|
6526
|
+
insertManyFromValuesAs = query.insertValuesAs;
|
|
6527
|
+
const queryAs = getQueryAs(insertFrom);
|
|
6528
|
+
ctx.sql[valuesPos - 1] += ` SELECT "${queryAs}".*, ${columns.slice(queryColumnsCount || 0).map((key) => {
|
|
6529
|
+
const column = shape[key];
|
|
6530
|
+
return column ? `${insertManyFromValuesAs}."${column.data.name || key}"::${column.dataType}` : `${insertManyFromValuesAs}."${key}"`;
|
|
6531
|
+
}).join(", ")} FROM "${queryAs}",`;
|
|
6497
6532
|
}
|
|
6498
|
-
|
|
6499
|
-
|
|
6533
|
+
}
|
|
6534
|
+
if (!insertFrom || insertManyFromValuesAs) {
|
|
6500
6535
|
const valuesSql = [];
|
|
6501
6536
|
let ctxValues = ctx.values;
|
|
6502
6537
|
const restValuesLen = ctxValues.length;
|
|
@@ -6505,6 +6540,8 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6505
6540
|
const { insertWith } = query;
|
|
6506
6541
|
const { skipBatchCheck } = ctx;
|
|
6507
6542
|
const withSqls = [];
|
|
6543
|
+
const startingKeyword = (insertManyFromValuesAs ? "(" : "") + (inCTE ? "SELECT " : "VALUES ");
|
|
6544
|
+
const valuesAppend = insertManyFromValuesAs ? `) ${insertManyFromValuesAs}(${quotedColumns.slice(queryColumnsCount || 0).join(", ")})` : "";
|
|
6508
6545
|
for (let i = 0; i < values.length; i++) {
|
|
6509
6546
|
const withes = insertWith?.[i];
|
|
6510
6547
|
ctx.skipBatchCheck = true;
|
|
@@ -6528,11 +6565,8 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6528
6565
|
);
|
|
6529
6566
|
}
|
|
6530
6567
|
if (!skipBatchCheck) {
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
withSqls.length = 0;
|
|
6534
|
-
}
|
|
6535
|
-
ctx.sql[valuesPos] = (inCTE ? "SELECT " : "VALUES ") + valuesSql.join(", ");
|
|
6568
|
+
addWithSqls(ctx, hasWith, withSqls, valuesPos, insertSql);
|
|
6569
|
+
ctx.sql[valuesPos] = startingKeyword + valuesSql.join(", ") + valuesAppend;
|
|
6536
6570
|
ctxValues.length = currentValuesLen;
|
|
6537
6571
|
batch = orchidCore.pushOrNewArray(batch, {
|
|
6538
6572
|
text: ctx.sql.join(" "),
|
|
@@ -6548,9 +6582,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6548
6582
|
if (withSql) withSqls.push(withSql);
|
|
6549
6583
|
valuesSql.push(encodedRow);
|
|
6550
6584
|
}
|
|
6551
|
-
|
|
6552
|
-
ctx.sql[valuesPos - 1] = "WITH " + withSqls.join(", ") + " " + insertSql;
|
|
6553
|
-
}
|
|
6585
|
+
addWithSqls(ctx, hasWith, withSqls, valuesPos, insertSql);
|
|
6554
6586
|
if (batch) {
|
|
6555
6587
|
if (hasNonSelect) {
|
|
6556
6588
|
throw new orchidCore.OrchidOrmInternalError(
|
|
@@ -6558,7 +6590,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6558
6590
|
`Cannot insert many records when having a non-select sub-query`
|
|
6559
6591
|
);
|
|
6560
6592
|
}
|
|
6561
|
-
ctx.sql[valuesPos] =
|
|
6593
|
+
ctx.sql[valuesPos] = startingKeyword + valuesSql.join(", ") + valuesAppend;
|
|
6562
6594
|
batch.push({
|
|
6563
6595
|
text: ctx.sql.join(" "),
|
|
6564
6596
|
values: ctxValues
|
|
@@ -6569,7 +6601,7 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6569
6601
|
batch
|
|
6570
6602
|
};
|
|
6571
6603
|
} else {
|
|
6572
|
-
ctx.sql[valuesPos] =
|
|
6604
|
+
ctx.sql[valuesPos] = startingKeyword + valuesSql.join(", ") + valuesAppend;
|
|
6573
6605
|
}
|
|
6574
6606
|
if (inCTE) {
|
|
6575
6607
|
ctx.sql[valuesPos] += ' WHERE NOT EXISTS (SELECT 1 FROM "f")';
|
|
@@ -6582,6 +6614,15 @@ const makeInsertSql = (ctx, q, query, quotedAs) => {
|
|
|
6582
6614
|
values: ctx.values
|
|
6583
6615
|
};
|
|
6584
6616
|
};
|
|
6617
|
+
const addWithSqls = (ctx, hasWith, withSqls, valuesPos, insertSql) => {
|
|
6618
|
+
if (withSqls.length) {
|
|
6619
|
+
if (hasWith) {
|
|
6620
|
+
ctx.sql[valuesPos - 2] += ",";
|
|
6621
|
+
}
|
|
6622
|
+
ctx.sql[valuesPos - 1] = (hasWith ? "" : "WITH ") + withSqls.join(", ") + " " + insertSql;
|
|
6623
|
+
withSqls.length = 0;
|
|
6624
|
+
}
|
|
6625
|
+
};
|
|
6585
6626
|
const processHookSet = (ctx, q, values, hookCreateSet, columns, QueryClass, quotedAs) => {
|
|
6586
6627
|
const hookSet = {};
|
|
6587
6628
|
for (const item of hookCreateSet) {
|
|
@@ -6590,48 +6631,54 @@ const processHookSet = (ctx, q, values, hookCreateSet, columns, QueryClass, quot
|
|
|
6590
6631
|
const addHookSetColumns = Object.keys(hookSet).filter(
|
|
6591
6632
|
(key) => !columns.includes(key)
|
|
6592
6633
|
);
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
const newColumns =
|
|
6596
|
-
const originalSelect =
|
|
6634
|
+
let insertFrom = q.q.insertFrom;
|
|
6635
|
+
if (insertFrom) {
|
|
6636
|
+
const newColumns = /* @__PURE__ */ new Set();
|
|
6637
|
+
const originalSelect = insertFrom.q.select;
|
|
6597
6638
|
if (originalSelect) {
|
|
6598
|
-
|
|
6639
|
+
insertFrom = _clone(insertFrom);
|
|
6599
6640
|
const select = [];
|
|
6600
6641
|
for (const s of originalSelect) {
|
|
6601
6642
|
if (typeof s === "string" && !hookSet[s]) {
|
|
6602
6643
|
select.push(s);
|
|
6603
|
-
newColumns.
|
|
6644
|
+
newColumns.add(s);
|
|
6604
6645
|
} else if (typeof s === "object" && "selectAs" in s) {
|
|
6605
6646
|
const filtered = {};
|
|
6606
6647
|
for (const key in s.selectAs) {
|
|
6607
6648
|
if (!hookSet[key]) {
|
|
6608
6649
|
filtered[key] = s.selectAs[key];
|
|
6609
|
-
newColumns.
|
|
6650
|
+
newColumns.add(key);
|
|
6610
6651
|
}
|
|
6611
6652
|
}
|
|
6612
6653
|
select.push({ selectAs: filtered });
|
|
6613
6654
|
}
|
|
6614
6655
|
}
|
|
6615
|
-
|
|
6616
|
-
}
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
const
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6656
|
+
insertFrom.q.select = select;
|
|
6657
|
+
}
|
|
6658
|
+
if (values.length) {
|
|
6659
|
+
const newValues = [];
|
|
6660
|
+
const valuesColumnsSet = /* @__PURE__ */ new Set();
|
|
6661
|
+
values.forEach((originalRow, i) => {
|
|
6662
|
+
const valuesColumns = columns.slice(-originalRow.length);
|
|
6663
|
+
const row = [];
|
|
6664
|
+
newValues[i] = row;
|
|
6665
|
+
valuesColumns.forEach((c, i2) => {
|
|
6666
|
+
if (!hookSet[c] && !newColumns.has(c)) {
|
|
6667
|
+
valuesColumnsSet.add(c);
|
|
6668
|
+
row.push(originalRow[i2]);
|
|
6669
|
+
}
|
|
6670
|
+
});
|
|
6627
6671
|
});
|
|
6672
|
+
for (const valueColumn of valuesColumnsSet) {
|
|
6673
|
+
newColumns.add(valueColumn);
|
|
6674
|
+
}
|
|
6675
|
+
values = newValues;
|
|
6628
6676
|
} else {
|
|
6629
|
-
|
|
6677
|
+
values = [[]];
|
|
6630
6678
|
}
|
|
6631
|
-
v.values = row;
|
|
6632
6679
|
columns.forEach((column) => {
|
|
6633
6680
|
if (column in hookSet) {
|
|
6634
|
-
newColumns.
|
|
6681
|
+
newColumns.add(column);
|
|
6635
6682
|
const fromHook = {
|
|
6636
6683
|
fromHook: encodeValue(
|
|
6637
6684
|
ctx,
|
|
@@ -6642,28 +6689,35 @@ const processHookSet = (ctx, q, values, hookCreateSet, columns, QueryClass, quot
|
|
|
6642
6689
|
quotedAs
|
|
6643
6690
|
)
|
|
6644
6691
|
};
|
|
6645
|
-
row
|
|
6692
|
+
for (const row of values) {
|
|
6693
|
+
row.push(fromHook);
|
|
6694
|
+
}
|
|
6646
6695
|
}
|
|
6647
6696
|
});
|
|
6697
|
+
const queryColumnsCount = insertFrom.q.select?.length;
|
|
6648
6698
|
if (addHookSetColumns) {
|
|
6649
6699
|
for (const key of addHookSetColumns) {
|
|
6650
|
-
row
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6700
|
+
for (const row of values) {
|
|
6701
|
+
row.push({
|
|
6702
|
+
fromHook: encodeValue(
|
|
6703
|
+
ctx,
|
|
6704
|
+
ctx.values,
|
|
6705
|
+
q,
|
|
6706
|
+
QueryClass,
|
|
6707
|
+
hookSet[key],
|
|
6708
|
+
quotedAs
|
|
6709
|
+
)
|
|
6710
|
+
});
|
|
6711
|
+
}
|
|
6660
6712
|
}
|
|
6661
6713
|
return {
|
|
6662
6714
|
columns: [...newColumns, ...addHookSetColumns],
|
|
6663
|
-
|
|
6715
|
+
insertFrom,
|
|
6716
|
+
queryColumnsCount,
|
|
6717
|
+
values
|
|
6664
6718
|
};
|
|
6665
6719
|
}
|
|
6666
|
-
return { columns: newColumns, values
|
|
6720
|
+
return { columns: [...newColumns], insertFrom, queryColumnsCount, values };
|
|
6667
6721
|
}
|
|
6668
6722
|
columns.forEach((column, i) => {
|
|
6669
6723
|
if (column in hookSet) {
|
|
@@ -6979,8 +7033,7 @@ const selectToSql = (ctx, table, query, quotedAs, hookSelect = query.hookSelect,
|
|
|
6979
7033
|
hookSelect.delete(column);
|
|
6980
7034
|
continue;
|
|
6981
7035
|
}
|
|
6982
|
-
|
|
6983
|
-
while (selected[name = `${column}${i}`]) i++;
|
|
7036
|
+
name = orchidCore.getFreeAlias(selected, column);
|
|
6984
7037
|
item.as = name;
|
|
6985
7038
|
item.temp = name;
|
|
6986
7039
|
sql += ` "${name}"`;
|
|
@@ -8623,7 +8676,7 @@ class Union {
|
|
|
8623
8676
|
}
|
|
8624
8677
|
}
|
|
8625
8678
|
|
|
8626
|
-
const
|
|
8679
|
+
const _addWith = (query, withStore, item, key = "with") => {
|
|
8627
8680
|
if (item.q) {
|
|
8628
8681
|
item.q.q.with?.forEach((item2, i, arr) => {
|
|
8629
8682
|
if (item2?.q?.q.type) {
|
|
@@ -8634,7 +8687,8 @@ const addWith = (q, withStore, item, key = "with") => {
|
|
|
8634
8687
|
if (item.q.q.insertWith) {
|
|
8635
8688
|
const values = Object.values(item.q.q.insertWith).flat();
|
|
8636
8689
|
item.q.q.insertWith = void 0;
|
|
8637
|
-
|
|
8690
|
+
const { q } = query;
|
|
8691
|
+
q.with = q.with ? [...q.with, ...values] : values;
|
|
8638
8692
|
}
|
|
8639
8693
|
}
|
|
8640
8694
|
orchidCore.pushOrNewArrayToObjectImmutable(withStore, key, item);
|
|
@@ -8642,7 +8696,7 @@ const addWith = (q, withStore, item, key = "with") => {
|
|
|
8642
8696
|
const moveQueryValueToWith = (q, withStore, value, withKey, set, key) => {
|
|
8643
8697
|
if (value.q.type) {
|
|
8644
8698
|
const as = saveAliasedShape(q, "q", "withShapes");
|
|
8645
|
-
|
|
8699
|
+
_addWith(
|
|
8646
8700
|
q,
|
|
8647
8701
|
withStore,
|
|
8648
8702
|
{
|
|
@@ -8676,7 +8730,7 @@ class WithMethods {
|
|
|
8676
8730
|
columns: Object.keys(query.shape)
|
|
8677
8731
|
};
|
|
8678
8732
|
}
|
|
8679
|
-
|
|
8733
|
+
_addWith(q, q.q, { n: name, o: options, q: query });
|
|
8680
8734
|
const shape = getShapeFromSelect(query, true);
|
|
8681
8735
|
return setQueryObjectValueImmutable(q, "withShapes", name, {
|
|
8682
8736
|
shape,
|
|
@@ -8702,7 +8756,7 @@ class WithMethods {
|
|
|
8702
8756
|
columns: Object.keys(shape)
|
|
8703
8757
|
};
|
|
8704
8758
|
}
|
|
8705
|
-
|
|
8759
|
+
_addWith(q, q.q, { n: name, o: options, q: query });
|
|
8706
8760
|
return setQueryObjectValueImmutable(q, "withShapes", name, withConfig);
|
|
8707
8761
|
}
|
|
8708
8762
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -8720,6 +8774,248 @@ class WithMethods {
|
|
|
8720
8774
|
}
|
|
8721
8775
|
}
|
|
8722
8776
|
|
|
8777
|
+
const insertFrom = (query, from, many, queryMany, data) => {
|
|
8778
|
+
const ctx = createCtx();
|
|
8779
|
+
const obj = data && (Array.isArray(data) ? handleManyData(query, data, ctx) : handleOneData(query, data, ctx));
|
|
8780
|
+
return insert(
|
|
8781
|
+
query,
|
|
8782
|
+
{
|
|
8783
|
+
insertFrom: from,
|
|
8784
|
+
columns: obj?.columns || [],
|
|
8785
|
+
values: obj?.values || []
|
|
8786
|
+
},
|
|
8787
|
+
many,
|
|
8788
|
+
queryMany
|
|
8789
|
+
);
|
|
8790
|
+
};
|
|
8791
|
+
const getFromSelectColumns = (q, from, obj, many) => {
|
|
8792
|
+
if (!many && !queryTypeWithLimitOne[from.q.returnType]) {
|
|
8793
|
+
throw new Error(
|
|
8794
|
+
"Cannot create based on a query which returns multiple records"
|
|
8795
|
+
);
|
|
8796
|
+
}
|
|
8797
|
+
const queryColumns = /* @__PURE__ */ new Set();
|
|
8798
|
+
from.q.select?.forEach((item) => {
|
|
8799
|
+
if (typeof item === "string") {
|
|
8800
|
+
const index = item.indexOf(".");
|
|
8801
|
+
queryColumns.add(index === -1 ? item : item.slice(index + 1));
|
|
8802
|
+
} else if (item && "selectAs" in item) {
|
|
8803
|
+
for (const column in item.selectAs) {
|
|
8804
|
+
queryColumns.add(column);
|
|
8805
|
+
}
|
|
8806
|
+
}
|
|
8807
|
+
});
|
|
8808
|
+
const allColumns = new Set(queryColumns);
|
|
8809
|
+
const queryColumnsCount = queryColumns.size;
|
|
8810
|
+
const allValues = [];
|
|
8811
|
+
if (obj?.columns) {
|
|
8812
|
+
for (const objectValues of obj.values) {
|
|
8813
|
+
const values = [];
|
|
8814
|
+
allValues.push(values);
|
|
8815
|
+
obj.columns.forEach((column, i) => {
|
|
8816
|
+
if (!queryColumns.has(column)) {
|
|
8817
|
+
allColumns.add(column);
|
|
8818
|
+
values.push(objectValues[i]);
|
|
8819
|
+
}
|
|
8820
|
+
});
|
|
8821
|
+
}
|
|
8822
|
+
}
|
|
8823
|
+
for (const key of queryColumns) {
|
|
8824
|
+
const column = q.shape[key];
|
|
8825
|
+
if (column) throwOnReadOnly$1(from, column, key);
|
|
8826
|
+
}
|
|
8827
|
+
return {
|
|
8828
|
+
columns: [...allColumns],
|
|
8829
|
+
queryColumnsCount,
|
|
8830
|
+
values: allValues
|
|
8831
|
+
};
|
|
8832
|
+
};
|
|
8833
|
+
const _queryCreateOneFrom = (q, query, data) => {
|
|
8834
|
+
createSelect(q);
|
|
8835
|
+
return insertFrom(q, query, false, false, data);
|
|
8836
|
+
};
|
|
8837
|
+
const _queryInsertOneFrom = (q, query, data) => {
|
|
8838
|
+
return insertFrom(q, query, false, false, data);
|
|
8839
|
+
};
|
|
8840
|
+
const _queryCreateManyFrom = (q, query, data) => {
|
|
8841
|
+
createSelect(q);
|
|
8842
|
+
return insertFrom(q, query, true, false, data);
|
|
8843
|
+
};
|
|
8844
|
+
const _queryInsertManyFrom = (q, query, data) => {
|
|
8845
|
+
return insertFrom(q, query, true, false, data);
|
|
8846
|
+
};
|
|
8847
|
+
const _queryCreateForEachFrom = (q, query) => {
|
|
8848
|
+
createSelect(q);
|
|
8849
|
+
return insertFrom(q, query, true, true);
|
|
8850
|
+
};
|
|
8851
|
+
const _queryInsertForEachFrom = (q, query) => {
|
|
8852
|
+
return insertFrom(q, query, true, true);
|
|
8853
|
+
};
|
|
8854
|
+
class QueryCreateFrom {
|
|
8855
|
+
/**
|
|
8856
|
+
* Inserts a single record based on a query that selects a single record.
|
|
8857
|
+
*
|
|
8858
|
+
* Performs a single SQL query based on `INSERT ... SELECT ... FROM`.
|
|
8859
|
+
*
|
|
8860
|
+
* See {@link createManyFrom} to insert multiple records based on a single record query,
|
|
8861
|
+
* and {@link createForEachFrom} to insert a record per every one found by the query.
|
|
8862
|
+
*
|
|
8863
|
+
* The first argument is a query of a **single** record, it should have `find`, `take`, or similar.
|
|
8864
|
+
*
|
|
8865
|
+
* The second optional argument is a data which will be merged with columns returned by the query.
|
|
8866
|
+
*
|
|
8867
|
+
* The data for the second argument is the same as in {@link create}.
|
|
8868
|
+
*
|
|
8869
|
+
* Columns with runtime defaults (defined with a callback) are supported here.
|
|
8870
|
+
* The value for such a column will be injected unless selected from a related table or provided in a data object.
|
|
8871
|
+
*
|
|
8872
|
+
* ```ts
|
|
8873
|
+
* const oneRecord = await db.table.createOneFrom(
|
|
8874
|
+
* db.relatedTable
|
|
8875
|
+
* // use select to map columns from one table to another
|
|
8876
|
+
* .select({
|
|
8877
|
+
* // relatedTable's id will be inserted as "relatedId"
|
|
8878
|
+
* relatedId: 'id',
|
|
8879
|
+
* })
|
|
8880
|
+
* .findBy({ key: 'value' }),
|
|
8881
|
+
* // optional argument:
|
|
8882
|
+
* {
|
|
8883
|
+
* key: 'value',
|
|
8884
|
+
* // supports sql, nested select, create, update, delete queries
|
|
8885
|
+
* fromSql: () => sql`custom sql`,
|
|
8886
|
+
* fromQuery: () => db.otherTable.find(id).update(data).get('column'),
|
|
8887
|
+
* fromRelated: (q) => q.relatedTable.create(data).get('column'),
|
|
8888
|
+
* },
|
|
8889
|
+
* );
|
|
8890
|
+
* ```
|
|
8891
|
+
*
|
|
8892
|
+
* The query above will produce such a SQL (omitting `from*` values):
|
|
8893
|
+
*
|
|
8894
|
+
* ```sql
|
|
8895
|
+
* INSERT INTO "table"("relatedId", "key")
|
|
8896
|
+
* SELECT "relatedTable"."id" AS "relatedId", 'value'
|
|
8897
|
+
* FROM "relatedTable"
|
|
8898
|
+
* WHERE "relatedTable"."key" = 'value'
|
|
8899
|
+
* LIMIT 1
|
|
8900
|
+
* RETURNING *
|
|
8901
|
+
* ```
|
|
8902
|
+
*
|
|
8903
|
+
* @param query - query to create new records from
|
|
8904
|
+
* @param data - additionally you can set some columns
|
|
8905
|
+
*/
|
|
8906
|
+
createOneFrom(query, data) {
|
|
8907
|
+
return _queryCreateOneFrom(_clone(this), query, data);
|
|
8908
|
+
}
|
|
8909
|
+
/**
|
|
8910
|
+
* Works exactly as {@link createOneFrom}, except that it returns inserted row count by default.
|
|
8911
|
+
*
|
|
8912
|
+
* @param query - query to create new records from
|
|
8913
|
+
* @param data - additionally you can set some columns
|
|
8914
|
+
*/
|
|
8915
|
+
insertOneFrom(query, data) {
|
|
8916
|
+
return _queryInsertOneFrom(_clone(this), query, data);
|
|
8917
|
+
}
|
|
8918
|
+
/**
|
|
8919
|
+
* Inserts multiple records based on a query that selects a single record.
|
|
8920
|
+
*
|
|
8921
|
+
* Performs a single SQL query based on `INSERT ... SELECT ... FROM`.
|
|
8922
|
+
*
|
|
8923
|
+
* See {@link createOneFrom} to insert a single record based on a single record query,
|
|
8924
|
+
* and {@link createForEachFrom} to insert a record per every one found by the query.
|
|
8925
|
+
*
|
|
8926
|
+
* The first argument is a query of a **single** record, it should have `find`, `take`, or similar.
|
|
8927
|
+
*
|
|
8928
|
+
* The second argument is array of objects to be merged with columns returned by the query.
|
|
8929
|
+
*
|
|
8930
|
+
* The data for the second argument is the same as in {@link createMany}.
|
|
8931
|
+
*
|
|
8932
|
+
* Columns with runtime defaults (defined with a callback) are supported here.
|
|
8933
|
+
* The value for such a column will be injected unless selected from a related table or provided in a data object.
|
|
8934
|
+
*
|
|
8935
|
+
* ```ts
|
|
8936
|
+
* const twoRecords = await db.table.createManyFrom(
|
|
8937
|
+
* db.relatedTable
|
|
8938
|
+
* // use select to map columns from one table to another
|
|
8939
|
+
* .select({
|
|
8940
|
+
* // relatedTable's id will be inserted as "relatedId"
|
|
8941
|
+
* relatedId: 'id',
|
|
8942
|
+
* })
|
|
8943
|
+
* .findBy({ key: 'value' }),
|
|
8944
|
+
* [
|
|
8945
|
+
* {
|
|
8946
|
+
* key: 'value 1',
|
|
8947
|
+
* // supports sql, nested select, create, update, delete queries
|
|
8948
|
+
* fromSql: () => sql`custom sql`,
|
|
8949
|
+
* fromQuery: () => db.otherTable.find(id).update(data).get('column'),
|
|
8950
|
+
* fromRelated: (q) => q.relatedTable.create(data).get('column'),
|
|
8951
|
+
* },
|
|
8952
|
+
* {
|
|
8953
|
+
* key: 'value 2',
|
|
8954
|
+
* },
|
|
8955
|
+
* ],
|
|
8956
|
+
* );
|
|
8957
|
+
* ```
|
|
8958
|
+
*
|
|
8959
|
+
* The query above will produce such a SQL (omitting `from*` values):
|
|
8960
|
+
*
|
|
8961
|
+
* ```sql
|
|
8962
|
+
* WITH "relatedTable" AS (
|
|
8963
|
+
* SELECT "relatedTable"."id" AS "relatedId", 'value'
|
|
8964
|
+
* FROM "relatedTable"
|
|
8965
|
+
* WHERE "relatedTable"."key" = 'value'
|
|
8966
|
+
* LIMIT 1
|
|
8967
|
+
* )
|
|
8968
|
+
* INSERT INTO "table"("relatedId", "key")
|
|
8969
|
+
* SELECT "relatedTable".*, v."key"::text
|
|
8970
|
+
* FROM "relatedTable", (VALUES ('value1'), ('value2')) v("key")
|
|
8971
|
+
* RETURNING *
|
|
8972
|
+
* ```
|
|
8973
|
+
*
|
|
8974
|
+
* @param query - query to create new records from
|
|
8975
|
+
* @param data - array of records to create
|
|
8976
|
+
*/
|
|
8977
|
+
createManyFrom(query, data) {
|
|
8978
|
+
return _queryCreateManyFrom(_clone(this), query, data);
|
|
8979
|
+
}
|
|
8980
|
+
/**
|
|
8981
|
+
* Works exactly as {@link createManyFrom}, except that it returns inserted row count by default.
|
|
8982
|
+
*
|
|
8983
|
+
* @param query - query to create new records from
|
|
8984
|
+
* @param data - array of records to create
|
|
8985
|
+
*/
|
|
8986
|
+
insertManyFrom(query, data) {
|
|
8987
|
+
return _queryInsertManyFrom(_clone(this), query, data);
|
|
8988
|
+
}
|
|
8989
|
+
/**
|
|
8990
|
+
* Inserts a single record per every record found in a given query.
|
|
8991
|
+
*
|
|
8992
|
+
* Performs a single SQL query based on `INSERT ... SELECT ... FROM`.
|
|
8993
|
+
*
|
|
8994
|
+
* Unlike {@link createOneFrom}, it doesn't accept second argument with data.
|
|
8995
|
+
*
|
|
8996
|
+
* Runtime defaults cannot work with it.
|
|
8997
|
+
*
|
|
8998
|
+
* ```ts
|
|
8999
|
+
* const manyRecords = await db.table.createForEachFrom(
|
|
9000
|
+
* RelatedTable.select({ relatedId: 'id' }).where({ key: 'value' }),
|
|
9001
|
+
* );
|
|
9002
|
+
* ```
|
|
9003
|
+
*
|
|
9004
|
+
* @param query - query to create new records from
|
|
9005
|
+
*/
|
|
9006
|
+
createForEachFrom(query) {
|
|
9007
|
+
return _queryCreateForEachFrom(_clone(this), query);
|
|
9008
|
+
}
|
|
9009
|
+
/**
|
|
9010
|
+
* Works exactly as {@link createForEachFrom}, except that it returns inserted row count by default.
|
|
9011
|
+
*
|
|
9012
|
+
* @param query - query to create new records from
|
|
9013
|
+
*/
|
|
9014
|
+
insertForEachFrom(query) {
|
|
9015
|
+
return _queryInsertForEachFrom(_clone(this), query);
|
|
9016
|
+
}
|
|
9017
|
+
}
|
|
9018
|
+
|
|
8723
9019
|
const createSelect = (q) => {
|
|
8724
9020
|
if (q.q.returnType === "void" || isSelectingCount(q)) {
|
|
8725
9021
|
q.q.select = void 0;
|
|
@@ -8818,8 +9114,9 @@ const handleManyData = (q, data, ctx) => {
|
|
|
8818
9114
|
};
|
|
8819
9115
|
const insert = (self, {
|
|
8820
9116
|
columns,
|
|
9117
|
+
insertFrom,
|
|
8821
9118
|
values
|
|
8822
|
-
}, many) => {
|
|
9119
|
+
}, many, queryMany) => {
|
|
8823
9120
|
const { q } = self;
|
|
8824
9121
|
if (!q.select?.length) {
|
|
8825
9122
|
q.returning = true;
|
|
@@ -8828,6 +9125,28 @@ const insert = (self, {
|
|
|
8828
9125
|
delete q.or;
|
|
8829
9126
|
delete q.scopes;
|
|
8830
9127
|
q.type = "insert";
|
|
9128
|
+
insertFrom = insertFrom ? q.insertFrom = insertFrom : q.insertFrom;
|
|
9129
|
+
if (insertFrom) {
|
|
9130
|
+
if (q.insertFrom) {
|
|
9131
|
+
const obj = getFromSelectColumns(
|
|
9132
|
+
self,
|
|
9133
|
+
q.insertFrom,
|
|
9134
|
+
{
|
|
9135
|
+
columns,
|
|
9136
|
+
values
|
|
9137
|
+
},
|
|
9138
|
+
queryMany
|
|
9139
|
+
);
|
|
9140
|
+
columns = obj.columns;
|
|
9141
|
+
values = obj.values;
|
|
9142
|
+
q.queryColumnsCount = obj.queryColumnsCount;
|
|
9143
|
+
}
|
|
9144
|
+
if (values.length > 1) {
|
|
9145
|
+
const insertValuesAs = orchidCore._getQueryFreeAlias(q, "v");
|
|
9146
|
+
orchidCore._setQueryAlias(self, "v", insertValuesAs);
|
|
9147
|
+
q.insertValuesAs = insertValuesAs;
|
|
9148
|
+
}
|
|
9149
|
+
}
|
|
8831
9150
|
q.columns = columns;
|
|
8832
9151
|
q.values = values;
|
|
8833
9152
|
const { select, returnType } = q;
|
|
@@ -8843,63 +9162,20 @@ const insert = (self, {
|
|
|
8843
9162
|
q.returnType = "pluck";
|
|
8844
9163
|
}
|
|
8845
9164
|
} else if (!returnType || returnType === "all") {
|
|
8846
|
-
q.returnType =
|
|
9165
|
+
q.returnType = insertFrom ? insertFrom.q.returnType : "one";
|
|
8847
9166
|
} else if (returnType === "pluck") {
|
|
8848
9167
|
q.returnType = "valueOrThrow";
|
|
8849
9168
|
}
|
|
8850
9169
|
return self;
|
|
8851
9170
|
};
|
|
8852
|
-
const getFromSelectColumns = (q, from, obj, many) => {
|
|
8853
|
-
if (!many && !queryTypeWithLimitOne[from.q.returnType]) {
|
|
8854
|
-
throw new Error(
|
|
8855
|
-
"Cannot create based on a query which returns multiple records"
|
|
8856
|
-
);
|
|
8857
|
-
}
|
|
8858
|
-
const queryColumns = [];
|
|
8859
|
-
from.q.select?.forEach((item) => {
|
|
8860
|
-
if (typeof item === "string") {
|
|
8861
|
-
const index = item.indexOf(".");
|
|
8862
|
-
queryColumns.push(index === -1 ? item : item.slice(index + 1));
|
|
8863
|
-
} else if (item && "selectAs" in item) {
|
|
8864
|
-
queryColumns.push(...Object.keys(item.selectAs));
|
|
8865
|
-
}
|
|
8866
|
-
});
|
|
8867
|
-
if (obj?.columns) {
|
|
8868
|
-
queryColumns.push(...obj.columns);
|
|
8869
|
-
}
|
|
8870
|
-
for (const key of queryColumns) {
|
|
8871
|
-
const column = q.shape[key];
|
|
8872
|
-
if (column) throwOnReadOnly$1(from, column, key);
|
|
8873
|
-
}
|
|
8874
|
-
return queryColumns;
|
|
8875
|
-
};
|
|
8876
|
-
const insertFromQuery = (q, from, many, data) => {
|
|
8877
|
-
const ctx = createCtx();
|
|
8878
|
-
const obj = data && handleOneData(q, data, ctx);
|
|
8879
|
-
const columns = getFromSelectColumns(q, from, obj, many);
|
|
8880
|
-
return insert(
|
|
8881
|
-
q,
|
|
8882
|
-
{
|
|
8883
|
-
columns,
|
|
8884
|
-
values: { from, values: obj?.values[0] }
|
|
8885
|
-
},
|
|
8886
|
-
many
|
|
8887
|
-
);
|
|
8888
|
-
};
|
|
8889
9171
|
const _queryCreate = (q, data) => {
|
|
8890
9172
|
createSelect(q);
|
|
8891
9173
|
return _queryInsert(q, data);
|
|
8892
9174
|
};
|
|
8893
|
-
const _queryInsert = (
|
|
9175
|
+
const _queryInsert = (query, data) => {
|
|
8894
9176
|
const ctx = createCtx();
|
|
8895
|
-
const obj = handleOneData(
|
|
8896
|
-
|
|
8897
|
-
if (values && "from" in values) {
|
|
8898
|
-
obj.columns = getFromSelectColumns(q, values.from, obj);
|
|
8899
|
-
values.values = obj.values[0];
|
|
8900
|
-
obj.values = values;
|
|
8901
|
-
}
|
|
8902
|
-
return insert(q, obj);
|
|
9177
|
+
const obj = handleOneData(query, data, ctx);
|
|
9178
|
+
return insert(query, obj);
|
|
8903
9179
|
};
|
|
8904
9180
|
const _queryCreateMany = (q, data) => {
|
|
8905
9181
|
createSelect(q);
|
|
@@ -8911,20 +9187,6 @@ const _queryInsertMany = (q, data) => {
|
|
|
8911
9187
|
if (!data.length) result = result.none();
|
|
8912
9188
|
return result;
|
|
8913
9189
|
};
|
|
8914
|
-
const _queryCreateFrom = (q, query, data) => {
|
|
8915
|
-
createSelect(q);
|
|
8916
|
-
return insertFromQuery(q, query, false, data);
|
|
8917
|
-
};
|
|
8918
|
-
const _queryInsertFrom = (q, query, data) => {
|
|
8919
|
-
return insertFromQuery(q, query, false, data);
|
|
8920
|
-
};
|
|
8921
|
-
const _queryCreateManyFrom = (q, query) => {
|
|
8922
|
-
createSelect(q);
|
|
8923
|
-
return insertFromQuery(q, query, true);
|
|
8924
|
-
};
|
|
8925
|
-
const _queryInsertManyFrom = (q, query) => {
|
|
8926
|
-
return insertFromQuery(q, query, true);
|
|
8927
|
-
};
|
|
8928
9190
|
const _queryDefaults = (q, data) => {
|
|
8929
9191
|
q.q.defaults = data;
|
|
8930
9192
|
return q;
|
|
@@ -9042,85 +9304,6 @@ class QueryCreate {
|
|
|
9042
9304
|
insertMany(data) {
|
|
9043
9305
|
return _queryInsertMany(_clone(this), data);
|
|
9044
9306
|
}
|
|
9045
|
-
/**
|
|
9046
|
-
* These methods are for creating a single record, for batch creating see {@link createManyFrom}.
|
|
9047
|
-
*
|
|
9048
|
-
* `createFrom` is to perform the `INSERT ... SELECT ...` SQL statement, it does select and insert by performing a single query.
|
|
9049
|
-
*
|
|
9050
|
-
* The first argument is a query for a **single** record, it should have `find`, `take`, or similar.
|
|
9051
|
-
*
|
|
9052
|
-
* The second optional argument is a data which will be merged with columns returned from the select query.
|
|
9053
|
-
*
|
|
9054
|
-
* The data for the second argument is the same as in {@link create}.
|
|
9055
|
-
*
|
|
9056
|
-
* Columns with runtime defaults (defined with a callback) are supported here.
|
|
9057
|
-
* The value for such a column will be injected unless selected from a related table or provided in a data object.
|
|
9058
|
-
*
|
|
9059
|
-
* ```ts
|
|
9060
|
-
* const oneRecord = await db.table.createFrom(
|
|
9061
|
-
* // In the select, key is a related table column, value is a column to insert as
|
|
9062
|
-
* RelatedTable.select({ relatedId: 'id' }).findBy({ key: 'value' }),
|
|
9063
|
-
* // optional argument:
|
|
9064
|
-
* {
|
|
9065
|
-
* key: 'value',
|
|
9066
|
-
* // supports sql, nested select, create, update, delete queries
|
|
9067
|
-
* fromSql: () => sql`custom sql`,
|
|
9068
|
-
* fromQuery: () => db.otherTable.find(id).update(data).get('column'),
|
|
9069
|
-
* fromRelated: (q) => q.relatedTable.create(data).get('column'),
|
|
9070
|
-
* },
|
|
9071
|
-
* );
|
|
9072
|
-
* ```
|
|
9073
|
-
*
|
|
9074
|
-
* The query above will produce such SQL:
|
|
9075
|
-
*
|
|
9076
|
-
* ```sql
|
|
9077
|
-
* INSERT INTO "table"("relatedId", "key")
|
|
9078
|
-
* SELECT "relatedTable"."id" AS "relatedId", 'value'
|
|
9079
|
-
* FROM "relatedTable"
|
|
9080
|
-
* WHERE "relatedTable"."key" = 'value'
|
|
9081
|
-
* LIMIT 1
|
|
9082
|
-
* RETURNING *
|
|
9083
|
-
* ```
|
|
9084
|
-
*
|
|
9085
|
-
* @param query - query to create new records from
|
|
9086
|
-
* @param data - additionally you can set some columns
|
|
9087
|
-
*/
|
|
9088
|
-
createFrom(query, data) {
|
|
9089
|
-
return _queryCreateFrom(_clone(this), query, data);
|
|
9090
|
-
}
|
|
9091
|
-
/**
|
|
9092
|
-
* Works exactly as {@link createFrom}, except that it returns inserted row count by default.
|
|
9093
|
-
*
|
|
9094
|
-
* @param query - query to create new records from
|
|
9095
|
-
* @param data - additionally you can set some columns
|
|
9096
|
-
*/
|
|
9097
|
-
insertFrom(query, data) {
|
|
9098
|
-
return _queryInsertFrom(_clone(this), query, data);
|
|
9099
|
-
}
|
|
9100
|
-
/**
|
|
9101
|
-
* Similar to `createFrom`, but intended to create many records.
|
|
9102
|
-
*
|
|
9103
|
-
* Unlike `createFrom`, it doesn't accept second argument with data, and runtime defaults cannot work with it.
|
|
9104
|
-
*
|
|
9105
|
-
* ```ts
|
|
9106
|
-
* const manyRecords = await db.table.createManyFrom(
|
|
9107
|
-
* RelatedTable.select({ relatedId: 'id' }).where({ key: 'value' }),
|
|
9108
|
-
* );
|
|
9109
|
-
* ```
|
|
9110
|
-
*
|
|
9111
|
-
* @param query - query to create new records from
|
|
9112
|
-
*/
|
|
9113
|
-
createManyFrom(query) {
|
|
9114
|
-
return _queryCreateManyFrom(_clone(this), query);
|
|
9115
|
-
}
|
|
9116
|
-
/**
|
|
9117
|
-
* Works exactly as {@link createManyFrom}, except that it returns inserted row count by default.
|
|
9118
|
-
*
|
|
9119
|
-
* @param query - query to create new records from
|
|
9120
|
-
*/
|
|
9121
|
-
insertManyFrom(query) {
|
|
9122
|
-
return _queryInsertManyFrom(_clone(this), query);
|
|
9123
|
-
}
|
|
9124
9307
|
/**
|
|
9125
9308
|
* `defaults` allows setting values that will be used later in `create`.
|
|
9126
9309
|
*
|
|
@@ -10505,9 +10688,9 @@ class Join {
|
|
|
10505
10688
|
}
|
|
10506
10689
|
/**
|
|
10507
10690
|
* This method may be useful
|
|
10508
|
-
* for combining with [
|
|
10691
|
+
* for combining with [createForEachFrom](/guide/create-update-delete.html#createForEachFrom-insertForEachFrom).
|
|
10509
10692
|
*
|
|
10510
|
-
* `
|
|
10693
|
+
* `createForEachFrom` creates multiple record based on a selecting query:
|
|
10511
10694
|
*
|
|
10512
10695
|
* ```sql
|
|
10513
10696
|
* INSERT INTO t1(c1, c2)
|
|
@@ -10521,7 +10704,7 @@ class Join {
|
|
|
10521
10704
|
* ```ts
|
|
10522
10705
|
* const data = [{ column2: 'one' }, { column2: 'two' }, { column2: 'three' }];
|
|
10523
10706
|
*
|
|
10524
|
-
* await db.table.
|
|
10707
|
+
* await db.table.createForEachFrom(
|
|
10525
10708
|
* db.otherTable
|
|
10526
10709
|
* .joinData('data', (t) => ({ column2: t.text() }), data)
|
|
10527
10710
|
* .select('otherTable.column1', 'data.column2'),
|
|
@@ -12618,6 +12801,7 @@ orchidCore.applyMixins(QueryMethods, [
|
|
|
12618
12801
|
Union,
|
|
12619
12802
|
JsonMethods,
|
|
12620
12803
|
QueryCreate,
|
|
12804
|
+
QueryCreateFrom,
|
|
12621
12805
|
Update,
|
|
12622
12806
|
Delete,
|
|
12623
12807
|
Transaction,
|
|
@@ -12641,9 +12825,9 @@ orchidCore.applyMixins(QueryMethods, [
|
|
|
12641
12825
|
|
|
12642
12826
|
const makeIndex = (columns, first, second) => {
|
|
12643
12827
|
if (typeof first === "string") {
|
|
12644
|
-
const options = second
|
|
12828
|
+
const options = { ...second, name: first };
|
|
12645
12829
|
return {
|
|
12646
|
-
index: { columns, options
|
|
12830
|
+
index: { columns, options }
|
|
12647
12831
|
};
|
|
12648
12832
|
} else {
|
|
12649
12833
|
const options = first ?? {};
|
|
@@ -12656,24 +12840,27 @@ const tableDataMethods = {
|
|
|
12656
12840
|
primaryKey(columns, name) {
|
|
12657
12841
|
return { primaryKey: { columns, name } };
|
|
12658
12842
|
},
|
|
12659
|
-
unique(columns, ...
|
|
12843
|
+
unique(columns, ...args) {
|
|
12844
|
+
const [first, second] = args;
|
|
12660
12845
|
const input = makeIndex(columns, first, second);
|
|
12661
12846
|
input.index.options.unique = true;
|
|
12662
12847
|
return input;
|
|
12663
12848
|
},
|
|
12664
12849
|
index: makeIndex,
|
|
12665
|
-
searchIndex(columns, ...
|
|
12850
|
+
searchIndex(columns, ...args) {
|
|
12666
12851
|
var _a;
|
|
12852
|
+
const [first, second] = args;
|
|
12667
12853
|
const input = makeIndex(columns, first, second);
|
|
12668
12854
|
(_a = input.index.options).using ?? (_a.using = "gin");
|
|
12669
12855
|
input.index.options.tsVector = true;
|
|
12670
12856
|
return input;
|
|
12671
12857
|
},
|
|
12672
|
-
exclude(columns, ...
|
|
12858
|
+
exclude(columns, ...args) {
|
|
12859
|
+
const [first, second] = args;
|
|
12673
12860
|
if (typeof first === "string") {
|
|
12674
12861
|
const options = second ?? {};
|
|
12675
12862
|
return {
|
|
12676
|
-
exclude: { columns, options, name: first }
|
|
12863
|
+
exclude: { columns, options: { ...options, name: first } }
|
|
12677
12864
|
};
|
|
12678
12865
|
} else {
|
|
12679
12866
|
const options = first ?? {};
|
|
@@ -13307,7 +13494,6 @@ exports.MergeQueryMethods = MergeQueryMethods;
|
|
|
13307
13494
|
exports.MoneyColumn = MoneyColumn;
|
|
13308
13495
|
exports.NumberAsStringBaseColumn = NumberAsStringBaseColumn;
|
|
13309
13496
|
exports.NumberBaseColumn = NumberBaseColumn;
|
|
13310
|
-
exports.OnConflictQueryBuilder = OnConflictQueryBuilder;
|
|
13311
13497
|
exports.OnMethods = OnMethods;
|
|
13312
13498
|
exports.Operators = Operators;
|
|
13313
13499
|
exports.OrExpression = OrExpression;
|
|
@@ -13316,7 +13502,6 @@ exports.PointColumn = PointColumn;
|
|
|
13316
13502
|
exports.PolygonColumn = PolygonColumn;
|
|
13317
13503
|
exports.PostgisGeographyPointColumn = PostgisGeographyPointColumn;
|
|
13318
13504
|
exports.QueryAsMethods = QueryAsMethods;
|
|
13319
|
-
exports.QueryCreate = QueryCreate;
|
|
13320
13505
|
exports.QueryGet = QueryGet;
|
|
13321
13506
|
exports.QueryHooks = QueryHooks;
|
|
13322
13507
|
exports.QueryLog = QueryLog;
|
|
@@ -13351,6 +13536,7 @@ exports.VirtualColumn = VirtualColumn;
|
|
|
13351
13536
|
exports.Where = Where;
|
|
13352
13537
|
exports.WithMethods = WithMethods;
|
|
13353
13538
|
exports.XMLColumn = XMLColumn;
|
|
13539
|
+
exports._addWith = _addWith;
|
|
13354
13540
|
exports._clone = _clone;
|
|
13355
13541
|
exports._getSelectableColumn = _getSelectableColumn;
|
|
13356
13542
|
exports._initQueryBuilder = _initQueryBuilder;
|
|
@@ -13358,9 +13544,10 @@ exports._queryAfterSaveCommit = _queryAfterSaveCommit;
|
|
|
13358
13544
|
exports._queryAll = _queryAll;
|
|
13359
13545
|
exports._queryChangeCounter = _queryChangeCounter;
|
|
13360
13546
|
exports._queryCreate = _queryCreate;
|
|
13361
|
-
exports.
|
|
13547
|
+
exports._queryCreateForEachFrom = _queryCreateForEachFrom;
|
|
13362
13548
|
exports._queryCreateMany = _queryCreateMany;
|
|
13363
13549
|
exports._queryCreateManyFrom = _queryCreateManyFrom;
|
|
13550
|
+
exports._queryCreateOneFrom = _queryCreateOneFrom;
|
|
13364
13551
|
exports._queryDefaults = _queryDefaults;
|
|
13365
13552
|
exports._queryDelete = _queryDelete;
|
|
13366
13553
|
exports._queryExec = _queryExec;
|
|
@@ -13382,9 +13569,10 @@ exports._queryHookBeforeQuery = _queryHookBeforeQuery;
|
|
|
13382
13569
|
exports._queryHookBeforeSave = _queryHookBeforeSave;
|
|
13383
13570
|
exports._queryHookBeforeUpdate = _queryHookBeforeUpdate;
|
|
13384
13571
|
exports._queryInsert = _queryInsert;
|
|
13385
|
-
exports.
|
|
13572
|
+
exports._queryInsertForEachFrom = _queryInsertForEachFrom;
|
|
13386
13573
|
exports._queryInsertMany = _queryInsertMany;
|
|
13387
13574
|
exports._queryInsertManyFrom = _queryInsertManyFrom;
|
|
13575
|
+
exports._queryInsertOneFrom = _queryInsertOneFrom;
|
|
13388
13576
|
exports._queryJoinOn = _queryJoinOn;
|
|
13389
13577
|
exports._queryJoinOnJsonPathEquals = _queryJoinOnJsonPathEquals;
|
|
13390
13578
|
exports._queryJoinOrOn = _queryJoinOrOn;
|