@vantreeseba/drizzle-graphql 2.0.0 → 3.0.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/README.md +390 -0
- package/dist/README.md +390 -0
- package/dist/index.cjs +1760 -463
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +216 -5
- package/dist/index.d.ts +216 -5
- package/dist/index.js +1712 -401
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,29 +4,19 @@ import { MySqlDatabase } from "drizzle-orm/mysql-core";
|
|
|
4
4
|
import { PgAsyncDatabase } from "drizzle-orm/pg-core";
|
|
5
5
|
import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core";
|
|
6
6
|
import {
|
|
7
|
-
GraphQLObjectType as
|
|
7
|
+
GraphQLObjectType as GraphQLObjectType5,
|
|
8
8
|
GraphQLSchema
|
|
9
9
|
} from "graphql";
|
|
10
10
|
|
|
11
|
-
// src/util/builders/mysql.ts
|
|
12
|
-
import { is as is4, One as One3 } from "drizzle-orm";
|
|
13
|
-
import { getTableConfig, MySqlTable } from "drizzle-orm/mysql-core";
|
|
14
|
-
import {
|
|
15
|
-
GraphQLBoolean as GraphQLBoolean3,
|
|
16
|
-
GraphQLError as GraphQLError3,
|
|
17
|
-
GraphQLList as GraphQLList3,
|
|
18
|
-
GraphQLNonNull as GraphQLNonNull3,
|
|
19
|
-
GraphQLObjectType as GraphQLObjectType3
|
|
20
|
-
} from "graphql";
|
|
21
|
-
import { parseResolveInfo } from "graphql-parse-resolve-info";
|
|
22
|
-
|
|
23
11
|
// src/util/builders/common.ts
|
|
24
12
|
import {
|
|
13
|
+
aliasedTable,
|
|
25
14
|
and,
|
|
26
15
|
asc,
|
|
27
16
|
desc,
|
|
28
17
|
eq,
|
|
29
18
|
getColumns,
|
|
19
|
+
getTableAsAliasSQL,
|
|
30
20
|
gt,
|
|
31
21
|
gte,
|
|
32
22
|
ilike,
|
|
@@ -38,17 +28,19 @@ import {
|
|
|
38
28
|
lt,
|
|
39
29
|
lte,
|
|
40
30
|
ne,
|
|
31
|
+
not,
|
|
41
32
|
notIlike,
|
|
42
33
|
notInArray,
|
|
43
34
|
notLike,
|
|
44
35
|
One as One2,
|
|
45
36
|
or,
|
|
37
|
+
relationsFilterToSQL,
|
|
46
38
|
sql
|
|
47
39
|
} from "drizzle-orm";
|
|
48
40
|
import {
|
|
49
41
|
GraphQLBoolean as GraphQLBoolean2,
|
|
50
42
|
GraphQLEnumType as GraphQLEnumType2,
|
|
51
|
-
GraphQLError as
|
|
43
|
+
GraphQLError as GraphQLError3,
|
|
52
44
|
GraphQLInputObjectType as GraphQLInputObjectType2,
|
|
53
45
|
GraphQLInt as GraphQLInt2,
|
|
54
46
|
GraphQLList as GraphQLList2,
|
|
@@ -111,6 +103,7 @@ var capitalize = (input) => input?.length ? `${input[0].toLocaleUpperCase()}${in
|
|
|
111
103
|
// src/util/data-mappers/index.ts
|
|
112
104
|
import { getTableColumns, is, One } from "drizzle-orm";
|
|
113
105
|
import { GraphQLError } from "graphql";
|
|
106
|
+
var isJsonColumn = (column) => (column.dataType ?? "").includes("json") && column.columnType !== "PgGeometryObject";
|
|
114
107
|
var remapToGraphQLCore = (key, value, tableName, column, relationMap) => {
|
|
115
108
|
if (Array.isArray(value)) {
|
|
116
109
|
const relations = relationMap?.[tableName];
|
|
@@ -140,6 +133,9 @@ var remapToGraphQLCore = (key, value, tableName, column, relationMap) => {
|
|
|
140
133
|
if (!column) {
|
|
141
134
|
return value;
|
|
142
135
|
}
|
|
136
|
+
if (isJsonColumn(column)) {
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
143
139
|
if (value instanceof Date) {
|
|
144
140
|
return value.toISOString();
|
|
145
141
|
}
|
|
@@ -217,17 +213,7 @@ var remapFromGraphQLCore = (value, column, columnName) => {
|
|
|
217
213
|
}
|
|
218
214
|
}
|
|
219
215
|
if (dataType.includes("json") && column.columnType !== "PgGeometryObject") {
|
|
220
|
-
|
|
221
|
-
return value;
|
|
222
|
-
}
|
|
223
|
-
try {
|
|
224
|
-
return JSON.parse(value);
|
|
225
|
-
} catch (e) {
|
|
226
|
-
throw new GraphQLError(
|
|
227
|
-
`Invalid JSON in field '${columnName}':
|
|
228
|
-
${e instanceof Error ? e.message : "Unknown error"}`
|
|
229
|
-
);
|
|
230
|
-
}
|
|
216
|
+
return value;
|
|
231
217
|
}
|
|
232
218
|
switch (dataType) {
|
|
233
219
|
case "date": {
|
|
@@ -310,7 +296,7 @@ var remapFromGraphQLArrayInput = (queryInput, table) => {
|
|
|
310
296
|
// src/util/type-converter/index.ts
|
|
311
297
|
import { extractExtendedColumnType, is as is2 } from "drizzle-orm";
|
|
312
298
|
import { MySqlInt, MySqlSerial } from "drizzle-orm/mysql-core";
|
|
313
|
-
import { PgDate, PgDateString, PgInteger, PgSerial, PgTimestamp, PgTimestampString } from "drizzle-orm/pg-core";
|
|
299
|
+
import { PgDate, PgDateString, PgInteger, PgSerial, PgTimestamp, PgTimestampString, PgUUID } from "drizzle-orm/pg-core";
|
|
314
300
|
import { SQLiteInteger } from "drizzle-orm/sqlite-core";
|
|
315
301
|
import {
|
|
316
302
|
GraphQLBoolean,
|
|
@@ -323,7 +309,47 @@ import {
|
|
|
323
309
|
GraphQLObjectType,
|
|
324
310
|
GraphQLString
|
|
325
311
|
} from "graphql";
|
|
326
|
-
|
|
312
|
+
|
|
313
|
+
// src/util/scalars/index.ts
|
|
314
|
+
import { GraphQLError as GraphQLError2, GraphQLScalarType, Kind } from "graphql";
|
|
315
|
+
import { GraphQLDate, GraphQLDateTime, GraphQLJSON, GraphQLUUID } from "graphql-scalars";
|
|
316
|
+
var asDecimalString = (value) => {
|
|
317
|
+
if (typeof value === "bigint") {
|
|
318
|
+
return value.toString();
|
|
319
|
+
}
|
|
320
|
+
if (typeof value === "number") {
|
|
321
|
+
if (!Number.isInteger(value)) {
|
|
322
|
+
throw new GraphQLError2(`BigInt cannot represent non-integer value: ${value}`);
|
|
323
|
+
}
|
|
324
|
+
if (!Number.isSafeInteger(value)) {
|
|
325
|
+
throw new GraphQLError2(
|
|
326
|
+
`BigInt cannot represent the number ${value} without precision loss \u2014 pass it as a string instead`
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
return String(value);
|
|
330
|
+
}
|
|
331
|
+
if (typeof value === "string") {
|
|
332
|
+
if (!/^-?\d+$/.test(value)) {
|
|
333
|
+
throw new GraphQLError2(`BigInt cannot represent non-integer value: "${value}"`);
|
|
334
|
+
}
|
|
335
|
+
return value;
|
|
336
|
+
}
|
|
337
|
+
throw new GraphQLError2(`BigInt cannot represent value: ${JSON.stringify(value)}`);
|
|
338
|
+
};
|
|
339
|
+
var GraphQLBigIntString = new GraphQLScalarType({
|
|
340
|
+
name: "BigInt",
|
|
341
|
+
description: "A 64-bit integer, transported as a decimal string so that values beyond JavaScript's safe integer range survive the round-trip intact.",
|
|
342
|
+
serialize: asDecimalString,
|
|
343
|
+
parseValue: asDecimalString,
|
|
344
|
+
parseLiteral: (ast) => {
|
|
345
|
+
if (ast.kind !== Kind.STRING && ast.kind !== Kind.INT) {
|
|
346
|
+
throw new GraphQLError2(`BigInt cannot represent a ${ast.kind}`, { nodes: ast });
|
|
347
|
+
}
|
|
348
|
+
return asDecimalString(ast.value);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// src/util/type-converter/index.ts
|
|
327
353
|
var allowedNameChars = /^[a-zA-Z0-9_]+$/;
|
|
328
354
|
var enumMap = /* @__PURE__ */ new WeakMap();
|
|
329
355
|
var generateEnumCached = (column, columnName, tableName) => {
|
|
@@ -374,7 +400,7 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
|
|
|
374
400
|
} : column.columnType === "PgBytea" ? {
|
|
375
401
|
type: new GraphQLList(new GraphQLNonNull(GraphQLInt)),
|
|
376
402
|
description: "Buffer"
|
|
377
|
-
} : { type:
|
|
403
|
+
} : { type: GraphQLJSON, description: "JSON" };
|
|
378
404
|
case "string":
|
|
379
405
|
if (column.enumValues?.length) {
|
|
380
406
|
return { type: generateEnumCached(column, columnName, tableName) };
|
|
@@ -382,12 +408,15 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
|
|
|
382
408
|
if (column instanceof PgTimestamp || column instanceof PgTimestampString) {
|
|
383
409
|
return { type: GraphQLDateTime, description: "DateTime" };
|
|
384
410
|
}
|
|
411
|
+
if (column instanceof PgUUID) {
|
|
412
|
+
return { type: GraphQLUUID, description: "UUID" };
|
|
413
|
+
}
|
|
385
414
|
if (column instanceof PgDateString) {
|
|
386
415
|
return isInput ? { type: GraphQLString, description: "Date" } : { type: GraphQLDate, description: "Date" };
|
|
387
416
|
}
|
|
388
417
|
return { type: GraphQLString, description: "String" };
|
|
389
418
|
case "bigint":
|
|
390
|
-
return { type:
|
|
419
|
+
return { type: GraphQLBigIntString, description: "BigInt" };
|
|
391
420
|
case "number": {
|
|
392
421
|
const dims = column.dimensions;
|
|
393
422
|
if (dims !== void 0 && dims > 0) {
|
|
@@ -518,6 +547,23 @@ var extractRelationJoinColumns = (relEntry, parentTable, targetTable) => {
|
|
|
518
547
|
}
|
|
519
548
|
return { localColPropName, foreignCol: targetCol, foreignColPropName };
|
|
520
549
|
};
|
|
550
|
+
var drizzleExecutorKey = /* @__PURE__ */ Symbol.for("drizzle-graphql:executor");
|
|
551
|
+
var resolveExecutor = (db, context) => {
|
|
552
|
+
if (context && typeof context === "object") {
|
|
553
|
+
const executor = context[drizzleExecutorKey];
|
|
554
|
+
if (executor) {
|
|
555
|
+
return executor;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return db;
|
|
559
|
+
};
|
|
560
|
+
var resolveQueryExecutor = (db, context, tableName, buildTimeQueryBase) => {
|
|
561
|
+
const executor = resolveExecutor(db, context);
|
|
562
|
+
return {
|
|
563
|
+
executor,
|
|
564
|
+
queryBase: buildTimeQueryBase ? executor?.query?.[tableName] ?? buildTimeQueryBase : buildTimeQueryBase
|
|
565
|
+
};
|
|
566
|
+
};
|
|
521
567
|
var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames) => {
|
|
522
568
|
const cols = getColumns(targetTable);
|
|
523
569
|
const orderExprs = [
|
|
@@ -539,7 +585,7 @@ var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCon
|
|
|
539
585
|
}
|
|
540
586
|
return rows;
|
|
541
587
|
};
|
|
542
|
-
var createRelationResolverFactory = (db, tables) => ({ tableName, relationName, relEntry, isOne }) => {
|
|
588
|
+
var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, relationName, relEntry, isOne }) => {
|
|
543
589
|
const parentTable = tables[tableName];
|
|
544
590
|
const targetTableName = relEntry.targetTableName;
|
|
545
591
|
const targetTable = tables[targetTableName];
|
|
@@ -569,15 +615,16 @@ var createRelationResolverFactory = (db, tables) => ({ tableName, relationName,
|
|
|
569
615
|
});
|
|
570
616
|
const loaderKey = `${tableName}::${relationName}::${argsKey}`;
|
|
571
617
|
const loader = getOrCreateLoader(context, loaderKey, async (parentIds) => {
|
|
618
|
+
const executor = resolveExecutor(db, context);
|
|
572
619
|
const uniqueIds = [...new Set(parentIds)];
|
|
573
620
|
const whereCondition = and(
|
|
574
621
|
inArray(foreignCol, uniqueIds),
|
|
575
|
-
whereArg ? extractFilters(targetTable, targetTableName, whereArg) : void 0
|
|
622
|
+
whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName)) : void 0
|
|
576
623
|
);
|
|
577
624
|
let rows;
|
|
578
625
|
if (limit != null || offset != null) {
|
|
579
626
|
rows = await batchedPaginatedRelationQuery(
|
|
580
|
-
|
|
627
|
+
executor,
|
|
581
628
|
targetTable,
|
|
582
629
|
foreignCol,
|
|
583
630
|
whereCondition,
|
|
@@ -587,7 +634,7 @@ var createRelationResolverFactory = (db, tables) => ({ tableName, relationName,
|
|
|
587
634
|
targetPkNames
|
|
588
635
|
);
|
|
589
636
|
} else {
|
|
590
|
-
let q =
|
|
637
|
+
let q = executor.select().from(targetTable).where(whereCondition);
|
|
591
638
|
if (orderByArg) {
|
|
592
639
|
q = q.orderBy(...extractOrderBy(targetTable, orderByArg));
|
|
593
640
|
}
|
|
@@ -608,7 +655,31 @@ var createRelationResolverFactory = (db, tables) => ({ tableName, relationName,
|
|
|
608
655
|
return loader.load(localValue);
|
|
609
656
|
};
|
|
610
657
|
};
|
|
611
|
-
var
|
|
658
|
+
var AGGREGATE_FIELD_SUFFIX = "Aggregate";
|
|
659
|
+
var relationAggregateJoinColumns = (tree, table, selectionCtx) => {
|
|
660
|
+
const relations = selectionCtx?.relationMap[selectionCtx.tableName];
|
|
661
|
+
if (!relations || !selectionCtx) {
|
|
662
|
+
return [];
|
|
663
|
+
}
|
|
664
|
+
const tableColumns = getColumns(table);
|
|
665
|
+
const needed = [];
|
|
666
|
+
for (const fieldData of Object.values(tree)) {
|
|
667
|
+
if (tableColumns[fieldData.name] || !fieldData.name.endsWith(AGGREGATE_FIELD_SUFFIX)) {
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
const relEntry = relations[fieldData.name.slice(0, -AGGREGATE_FIELD_SUFFIX.length)];
|
|
671
|
+
const targetTable = relEntry ? selectionCtx.tables[relEntry.targetTableName] : void 0;
|
|
672
|
+
if (!relEntry || !targetTable) {
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
const joinCols = extractRelationJoinColumns(relEntry, table, targetTable);
|
|
676
|
+
if (joinCols) {
|
|
677
|
+
needed.push(joinCols.localColPropName);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return needed;
|
|
681
|
+
};
|
|
682
|
+
var extractSelectedColumnsFromTree = (tree, table, selectionCtx) => {
|
|
612
683
|
const tableColumns = getColumns(table);
|
|
613
684
|
const treeEntries = Object.entries(tree);
|
|
614
685
|
const selectedColumns = [];
|
|
@@ -618,6 +689,9 @@ var extractSelectedColumnsFromTree = (tree, table) => {
|
|
|
618
689
|
}
|
|
619
690
|
selectedColumns.push([fieldData.name, true]);
|
|
620
691
|
}
|
|
692
|
+
for (const columnName of relationAggregateJoinColumns(tree, table, selectionCtx)) {
|
|
693
|
+
selectedColumns.push([columnName, true]);
|
|
694
|
+
}
|
|
621
695
|
if (!selectedColumns.length) {
|
|
622
696
|
const columnKeys = Object.entries(tableColumns);
|
|
623
697
|
const columnName = columnKeys.find((e) => rqbCrashTypes.find((haram) => e[1].columnType !== haram))?.[0] ?? columnKeys[0][0];
|
|
@@ -625,7 +699,7 @@ var extractSelectedColumnsFromTree = (tree, table) => {
|
|
|
625
699
|
}
|
|
626
700
|
return Object.fromEntries(selectedColumns);
|
|
627
701
|
};
|
|
628
|
-
var extractSelectedColumnsFromTreeSQLFormat = (tree, table) => {
|
|
702
|
+
var extractSelectedColumnsFromTreeSQLFormat = (tree, table, selectionCtx) => {
|
|
629
703
|
const tableColumns = getColumns(table);
|
|
630
704
|
const treeEntries = Object.entries(tree);
|
|
631
705
|
const selectedColumns = [];
|
|
@@ -635,6 +709,9 @@ var extractSelectedColumnsFromTreeSQLFormat = (tree, table) => {
|
|
|
635
709
|
}
|
|
636
710
|
selectedColumns.push([fieldData.name, tableColumns[fieldData.name]]);
|
|
637
711
|
}
|
|
712
|
+
for (const columnName of relationAggregateJoinColumns(tree, table, selectionCtx)) {
|
|
713
|
+
selectedColumns.push([columnName, tableColumns[columnName]]);
|
|
714
|
+
}
|
|
638
715
|
if (!selectedColumns.length) {
|
|
639
716
|
const columnKeys = Object.entries(tableColumns);
|
|
640
717
|
const columnName = columnKeys.find((e) => rqbCrashTypes.find((haram) => e[1].columnType !== haram))?.[0] ?? columnKeys[0][0];
|
|
@@ -797,34 +874,102 @@ var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx)
|
|
|
797
874
|
cacheCtx.orderTypeCache.set(table, order);
|
|
798
875
|
return order;
|
|
799
876
|
};
|
|
800
|
-
var
|
|
877
|
+
var isFilterableRelation = (relation) => !relation.through;
|
|
878
|
+
var generateListRelationFilterCached = (targetTable, targetTableName, cacheCtx, typeNameMapper, relationMap, tables) => {
|
|
879
|
+
const cached = cacheCtx.listRelationFilterCache.get(targetTableName);
|
|
880
|
+
if (cached) {
|
|
881
|
+
return cached;
|
|
882
|
+
}
|
|
883
|
+
const listFilter = new GraphQLInputObjectType2({
|
|
884
|
+
name: `${resolveTypeName(targetTableName, typeNameMapper)}ListRelationFilter`,
|
|
885
|
+
fields: () => {
|
|
886
|
+
const targetFilters = generateTableFilterTypeCached(
|
|
887
|
+
targetTable,
|
|
888
|
+
targetTableName,
|
|
889
|
+
cacheCtx,
|
|
890
|
+
typeNameMapper,
|
|
891
|
+
relationMap,
|
|
892
|
+
tables
|
|
893
|
+
);
|
|
894
|
+
return {
|
|
895
|
+
some: { type: targetFilters, description: "At least one related row matches" },
|
|
896
|
+
none: { type: targetFilters, description: "No related row matches" },
|
|
897
|
+
every: { type: targetFilters, description: "Every related row matches" }
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
cacheCtx.listRelationFilterCache.set(targetTableName, listFilter);
|
|
902
|
+
return listFilter;
|
|
903
|
+
};
|
|
904
|
+
var generateRelationFilterFields = (tableName, cacheCtx, typeNameMapper, columnFields, relationMap, tables) => {
|
|
905
|
+
const relations = relationMap?.[tableName];
|
|
906
|
+
if (!relations || !tables) {
|
|
907
|
+
return {};
|
|
908
|
+
}
|
|
909
|
+
const fields = {};
|
|
910
|
+
for (const [relationName, relEntry] of Object.entries(relations)) {
|
|
911
|
+
if (relationName in columnFields) {
|
|
912
|
+
continue;
|
|
913
|
+
}
|
|
914
|
+
const targetTable = tables[relEntry.targetTableName];
|
|
915
|
+
const relation = relEntry.relation ?? relEntry;
|
|
916
|
+
if (!targetTable || !isFilterableRelation(relation)) {
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
919
|
+
fields[relationName] = is3(relation, One2) ? {
|
|
920
|
+
type: generateTableFilterTypeCached(
|
|
921
|
+
targetTable,
|
|
922
|
+
relEntry.targetTableName,
|
|
923
|
+
cacheCtx,
|
|
924
|
+
typeNameMapper,
|
|
925
|
+
relationMap,
|
|
926
|
+
tables
|
|
927
|
+
),
|
|
928
|
+
description: `Matches rows whose ${relationName} matches these filters`
|
|
929
|
+
} : {
|
|
930
|
+
type: generateListRelationFilterCached(
|
|
931
|
+
targetTable,
|
|
932
|
+
relEntry.targetTableName,
|
|
933
|
+
cacheCtx,
|
|
934
|
+
typeNameMapper,
|
|
935
|
+
relationMap,
|
|
936
|
+
tables
|
|
937
|
+
)
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
return fields;
|
|
941
|
+
};
|
|
942
|
+
var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper, relationMap, tables) => {
|
|
801
943
|
if (cacheCtx.filterTypeCache.has(table)) {
|
|
802
944
|
return cacheCtx.filterTypeCache.get(table);
|
|
803
945
|
}
|
|
804
|
-
const
|
|
946
|
+
const buildFields = () => {
|
|
947
|
+
const filterColumns = generateTableFilterValuesCached(table, tableName, cacheCtx);
|
|
948
|
+
return {
|
|
949
|
+
...filterColumns,
|
|
950
|
+
...generateRelationFilterFields(tableName, cacheCtx, typeNameMapper, filterColumns, relationMap, tables)
|
|
951
|
+
};
|
|
952
|
+
};
|
|
953
|
+
const orFilters = new GraphQLInputObjectType2({
|
|
954
|
+
name: `${resolveTypeName(tableName, typeNameMapper)}FiltersOr`,
|
|
955
|
+
fields: buildFields
|
|
956
|
+
});
|
|
805
957
|
const filters = new GraphQLInputObjectType2({
|
|
806
958
|
name: `${resolveTypeName(tableName, typeNameMapper)}Filters`,
|
|
807
|
-
fields: {
|
|
808
|
-
...
|
|
959
|
+
fields: () => ({
|
|
960
|
+
...buildFields(),
|
|
809
961
|
OR: {
|
|
810
|
-
type: new GraphQLList2(
|
|
811
|
-
new GraphQLNonNull2(
|
|
812
|
-
new GraphQLInputObjectType2({
|
|
813
|
-
name: `${resolveTypeName(tableName, typeNameMapper)}FiltersOr`,
|
|
814
|
-
fields: filterColumns
|
|
815
|
-
})
|
|
816
|
-
)
|
|
817
|
-
)
|
|
962
|
+
type: new GraphQLList2(new GraphQLNonNull2(orFilters))
|
|
818
963
|
}
|
|
819
|
-
}
|
|
964
|
+
})
|
|
820
965
|
});
|
|
821
966
|
cacheCtx.filterTypeCache.set(table, filters);
|
|
822
967
|
return filters;
|
|
823
968
|
};
|
|
824
|
-
var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, relationsDepthLimit, cacheCtx, typeNameMapper, usedTables = /* @__PURE__ */ new Set(), resolverFactory, currentDepth = 0) => {
|
|
969
|
+
var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, relationsDepthLimit, cacheCtx, typeNameMapper, usedTables = /* @__PURE__ */ new Set(), resolverFactory, currentDepth = 0, relationAggregateFactory) => {
|
|
825
970
|
const table = tables[tableName];
|
|
826
971
|
const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx) : void 0;
|
|
827
|
-
const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, typeNameMapper);
|
|
972
|
+
const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, typeNameMapper, relationMap, tables);
|
|
828
973
|
const tableFields = generateTableSelectTypeFieldsCached(table, tableName);
|
|
829
974
|
const relationsForTable = relationMap[tableName];
|
|
830
975
|
const relationEntries = relationsForTable ? Object.entries(relationsForTable) : [];
|
|
@@ -888,7 +1033,8 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
|
|
|
888
1033
|
typeNameMapper,
|
|
889
1034
|
nextUsedTables,
|
|
890
1035
|
resolverFactory,
|
|
891
|
-
currentDepth + 1
|
|
1036
|
+
currentDepth + 1,
|
|
1037
|
+
relationAggregateFactory
|
|
892
1038
|
);
|
|
893
1039
|
let relType = cacheCtx.objectTypeCache.get(targetTableName);
|
|
894
1040
|
if (!relType) {
|
|
@@ -933,6 +1079,26 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
|
|
|
933
1079
|
resolve
|
|
934
1080
|
}
|
|
935
1081
|
]);
|
|
1082
|
+
const aggregateFieldName = `${relationName}Aggregate`;
|
|
1083
|
+
if (!tableFields[aggregateFieldName] && !relationsForTable?.[aggregateFieldName]) {
|
|
1084
|
+
const relationAggregate = relationAggregateFactory?.({
|
|
1085
|
+
tableName,
|
|
1086
|
+
relationName,
|
|
1087
|
+
relEntry
|
|
1088
|
+
});
|
|
1089
|
+
if (relationAggregate) {
|
|
1090
|
+
rawRelationFields.push([
|
|
1091
|
+
aggregateFieldName,
|
|
1092
|
+
{
|
|
1093
|
+
type: new GraphQLNonNull2(relationAggregate.type),
|
|
1094
|
+
args: {
|
|
1095
|
+
where: { type: relSelectData.filters }
|
|
1096
|
+
},
|
|
1097
|
+
resolve: relationAggregate.resolve
|
|
1098
|
+
}
|
|
1099
|
+
]);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
936
1102
|
}
|
|
937
1103
|
const builtRelationFields = Object.fromEntries(rawRelationFields);
|
|
938
1104
|
if (isRootCall) {
|
|
@@ -956,7 +1122,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
|
|
|
956
1122
|
relationFields: {}
|
|
957
1123
|
};
|
|
958
1124
|
};
|
|
959
|
-
var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, typeNameMapper = void 0, insertPrefix = "create", updatePrefix = "update", resolverFactory) => {
|
|
1125
|
+
var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, typeNameMapper = void 0, insertPrefix = "create", updatePrefix = "update", resolverFactory, relationAggregateFactory) => {
|
|
960
1126
|
const { tableFields, relationFields, filters, order } = generateSelectFields(
|
|
961
1127
|
tables,
|
|
962
1128
|
tableName,
|
|
@@ -971,7 +1137,8 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
|
|
|
971
1137
|
typeNameMapper,
|
|
972
1138
|
/* @__PURE__ */ new Set(),
|
|
973
1139
|
resolverFactory,
|
|
974
|
-
0
|
|
1140
|
+
0,
|
|
1141
|
+
relationAggregateFactory
|
|
975
1142
|
);
|
|
976
1143
|
const table = tables[tableName];
|
|
977
1144
|
const columns = getColumns(table);
|
|
@@ -1026,19 +1193,10 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
|
|
|
1026
1193
|
outputs
|
|
1027
1194
|
};
|
|
1028
1195
|
};
|
|
1029
|
-
var
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
)) {
|
|
1034
|
-
if (!config) {
|
|
1035
|
-
continue;
|
|
1036
|
-
}
|
|
1037
|
-
const { direction } = config;
|
|
1038
|
-
res.push(direction === "asc" ? asc(getColumns(table)[column]) : desc(getColumns(table)[column]));
|
|
1039
|
-
}
|
|
1040
|
-
return res;
|
|
1041
|
-
};
|
|
1196
|
+
var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) => [column, config.direction]);
|
|
1197
|
+
var extractOrderBy = (table, orderArgs) => orderByEntries(orderArgs).map(
|
|
1198
|
+
([column, direction]) => direction === "asc" ? asc(getColumns(table)[column]) : desc(getColumns(table)[column])
|
|
1199
|
+
);
|
|
1042
1200
|
var extractFiltersColumn = (column, columnName, operators) => {
|
|
1043
1201
|
if (!operators.OR?.length) {
|
|
1044
1202
|
delete operators.OR;
|
|
@@ -1046,7 +1204,7 @@ var extractFiltersColumn = (column, columnName, operators) => {
|
|
|
1046
1204
|
const entries = Object.entries(operators);
|
|
1047
1205
|
if (operators.OR) {
|
|
1048
1206
|
if (entries.length > 1) {
|
|
1049
|
-
throw new
|
|
1207
|
+
throw new GraphQLError3(`WHERE ${columnName}: Cannot specify both fields and 'OR' in column operators!`);
|
|
1050
1208
|
}
|
|
1051
1209
|
const variants2 = [];
|
|
1052
1210
|
for (const variant of operators.OR) {
|
|
@@ -1073,7 +1231,7 @@ var extractFiltersColumn = (column, columnName, operators) => {
|
|
|
1073
1231
|
variants.push(stringValueOps[operatorName](column, operatorValue));
|
|
1074
1232
|
} else if (operatorName in arrayValueOps) {
|
|
1075
1233
|
if (!operatorValue.length) {
|
|
1076
|
-
throw new
|
|
1234
|
+
throw new GraphQLError3(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
|
|
1077
1235
|
}
|
|
1078
1236
|
const arrayValue = operatorValue.map((val) => remapFromGraphQLCore(val, column, columnName));
|
|
1079
1237
|
variants.push(arrayValueOps[operatorName](column, arrayValue));
|
|
@@ -1083,7 +1241,67 @@ var extractFiltersColumn = (column, columnName, operators) => {
|
|
|
1083
1241
|
}
|
|
1084
1242
|
return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
|
|
1085
1243
|
};
|
|
1086
|
-
var
|
|
1244
|
+
var relationFilterCtx = (base, tableKey) => base ? { ...base, tableKey } : void 0;
|
|
1245
|
+
var buildRelationJoinCondition = (parentTable, relation, aliasedTarget, relationName) => {
|
|
1246
|
+
const sourceColumns = relation.sourceColumns;
|
|
1247
|
+
const targetColumns = relation.targetColumns;
|
|
1248
|
+
if (!sourceColumns?.length || sourceColumns.length !== targetColumns?.length) {
|
|
1249
|
+
throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1250
|
+
}
|
|
1251
|
+
const parentColumns = Object.values(getColumns(parentTable));
|
|
1252
|
+
const targetColumnsByName = Object.values(getColumns(aliasedTarget));
|
|
1253
|
+
const conditions = [];
|
|
1254
|
+
for (let i = 0; i < sourceColumns.length; i++) {
|
|
1255
|
+
const localColumn = parentColumns.find((c) => c.name === sourceColumns[i].name);
|
|
1256
|
+
const foreignColumn = targetColumnsByName.find((c) => c.name === targetColumns[i].name);
|
|
1257
|
+
if (!localColumn || !foreignColumn) {
|
|
1258
|
+
throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1259
|
+
}
|
|
1260
|
+
conditions.push(eq(localColumn, foreignColumn));
|
|
1261
|
+
}
|
|
1262
|
+
return conditions.length > 1 ? and(...conditions) : conditions[0];
|
|
1263
|
+
};
|
|
1264
|
+
var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mode, ctx) => {
|
|
1265
|
+
const { targetTableName } = relEntry;
|
|
1266
|
+
const targetTable = ctx.tables[targetTableName];
|
|
1267
|
+
const relation = relEntry.relation ?? relEntry;
|
|
1268
|
+
if (!targetTable || !isFilterableRelation(relation)) {
|
|
1269
|
+
throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1270
|
+
}
|
|
1271
|
+
ctx.aliases ??= { n: 0 };
|
|
1272
|
+
const aliases = ctx.aliases;
|
|
1273
|
+
const aliasedTarget = aliasedTable(targetTable, `dgql_rel_${aliases.n++}`);
|
|
1274
|
+
const joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
|
|
1275
|
+
const relationWhere = relation.where ? relationsFilterToSQL(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
|
|
1276
|
+
const inner = innerFilters ? extractFilters(aliasedTarget, targetTableName, innerFilters, { ...ctx, tableKey: targetTableName, aliases }) : void 0;
|
|
1277
|
+
if (mode === "every") {
|
|
1278
|
+
if (!inner) {
|
|
1279
|
+
return void 0;
|
|
1280
|
+
}
|
|
1281
|
+
return sql`not exists (select 1 from ${getTableAsAliasSQL(aliasedTarget)} where ${and(joinCondition, relationWhere, not(inner))})`;
|
|
1282
|
+
}
|
|
1283
|
+
const condition = and(joinCondition, relationWhere, inner);
|
|
1284
|
+
return mode === "none" ? sql`not exists (select 1 from ${getTableAsAliasSQL(aliasedTarget)} where ${condition})` : sql`exists (select 1 from ${getTableAsAliasSQL(aliasedTarget)} where ${condition})`;
|
|
1285
|
+
};
|
|
1286
|
+
var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) => {
|
|
1287
|
+
const relation = relEntry.relation ?? relEntry;
|
|
1288
|
+
if (is3(relation, One2)) {
|
|
1289
|
+
return buildRelationExists(parentTable, relationName, relEntry, value, "some", ctx);
|
|
1290
|
+
}
|
|
1291
|
+
const variants = [];
|
|
1292
|
+
for (const mode of ["some", "none", "every"]) {
|
|
1293
|
+
const inner = value[mode];
|
|
1294
|
+
if (inner === void 0 || inner === null) {
|
|
1295
|
+
continue;
|
|
1296
|
+
}
|
|
1297
|
+
const extracted = buildRelationExists(parentTable, relationName, relEntry, inner, mode, ctx);
|
|
1298
|
+
if (extracted) {
|
|
1299
|
+
variants.push(extracted);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
|
|
1303
|
+
};
|
|
1304
|
+
var extractFilters = (table, tableName, filters, relationCtx) => {
|
|
1087
1305
|
if (!filters.OR?.length) {
|
|
1088
1306
|
delete filters.OR;
|
|
1089
1307
|
}
|
|
@@ -1093,28 +1311,33 @@ var extractFilters = (table, tableName, filters) => {
|
|
|
1093
1311
|
}
|
|
1094
1312
|
if (filters.OR) {
|
|
1095
1313
|
if (entries.length > 1) {
|
|
1096
|
-
throw new
|
|
1314
|
+
throw new GraphQLError3(`WHERE ${tableName}: Cannot specify both fields and 'OR' in table filters!`);
|
|
1097
1315
|
}
|
|
1098
1316
|
const variants2 = [];
|
|
1099
1317
|
for (const variant of filters.OR) {
|
|
1100
|
-
const extracted = extractFilters(table, tableName, variant);
|
|
1318
|
+
const extracted = extractFilters(table, tableName, variant, relationCtx);
|
|
1101
1319
|
if (extracted) {
|
|
1102
1320
|
variants2.push(extracted);
|
|
1103
1321
|
}
|
|
1104
1322
|
}
|
|
1105
1323
|
return variants2.length ? variants2.length > 1 ? or(...variants2) : variants2[0] : void 0;
|
|
1106
1324
|
}
|
|
1325
|
+
const columns = getColumns(table);
|
|
1326
|
+
const relations = relationCtx?.relationMap[relationCtx.tableKey];
|
|
1107
1327
|
const variants = [];
|
|
1108
|
-
for (const [
|
|
1109
|
-
if (operators === null) {
|
|
1328
|
+
for (const [fieldName, operators] of entries) {
|
|
1329
|
+
if (operators === null || operators === void 0) {
|
|
1110
1330
|
continue;
|
|
1111
1331
|
}
|
|
1112
|
-
const column =
|
|
1113
|
-
|
|
1332
|
+
const column = columns[fieldName];
|
|
1333
|
+
const extracted = column ? extractFiltersColumn(column, fieldName, operators) : relations?.[fieldName] && relationCtx ? extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx) : void 0;
|
|
1334
|
+
if (extracted) {
|
|
1335
|
+
variants.push(extracted);
|
|
1336
|
+
}
|
|
1114
1337
|
}
|
|
1115
1338
|
return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
|
|
1116
1339
|
};
|
|
1117
|
-
var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false) => {
|
|
1340
|
+
var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx) => {
|
|
1118
1341
|
const relationsForTable = relationMap[tableName];
|
|
1119
1342
|
if (!relationsForTable) {
|
|
1120
1343
|
return void 0;
|
|
@@ -1136,7 +1359,11 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
|
|
|
1136
1359
|
if (!relFieldSelection) {
|
|
1137
1360
|
continue;
|
|
1138
1361
|
}
|
|
1139
|
-
const columns = extractSelectedColumnsFromTree(relFieldSelection, tables[targetTableName]
|
|
1362
|
+
const columns = extractSelectedColumnsFromTree(relFieldSelection, tables[targetTableName], {
|
|
1363
|
+
tableName: targetTableName,
|
|
1364
|
+
relationMap,
|
|
1365
|
+
tables
|
|
1366
|
+
});
|
|
1140
1367
|
const thisRecord = {};
|
|
1141
1368
|
thisRecord.columns = columns;
|
|
1142
1369
|
const relationField = Object.values(baseField).find((e) => e.name === relName);
|
|
@@ -1144,23 +1371,34 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
|
|
|
1144
1371
|
const offset = relationArgs?.offset ?? void 0;
|
|
1145
1372
|
const limit = relationArgs?.limit ?? void 0;
|
|
1146
1373
|
const relWhere = relationArgs?.where;
|
|
1147
|
-
thisRecord.where = relWhere ? {
|
|
1374
|
+
thisRecord.where = relWhere ? {
|
|
1375
|
+
RAW: (aliasedTable2) => extractFilters(aliasedTable2, relName, relWhere, relationFilterCtx(filterCtx, targetTableName))
|
|
1376
|
+
} : void 0;
|
|
1148
1377
|
const hasPagination = offset != null || limit != null;
|
|
1149
1378
|
const pkNames = targetPkNames ?? [];
|
|
1150
|
-
thisRecord.orderBy = relationArgs?.orderBy ? (
|
|
1379
|
+
thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
|
|
1151
1380
|
thisRecord.offset = offset;
|
|
1152
1381
|
thisRecord.limit = limit;
|
|
1153
|
-
const relWith = relationField ? extractRelationsParamsInner(
|
|
1382
|
+
const relWith = relationField ? extractRelationsParamsInner(
|
|
1383
|
+
relationMap,
|
|
1384
|
+
tables,
|
|
1385
|
+
targetTableName,
|
|
1386
|
+
relTypeName,
|
|
1387
|
+
relationField,
|
|
1388
|
+
typeNameMapper,
|
|
1389
|
+
false,
|
|
1390
|
+
filterCtx
|
|
1391
|
+
) : void 0;
|
|
1154
1392
|
thisRecord.with = relWith;
|
|
1155
1393
|
args[relName] = thisRecord;
|
|
1156
1394
|
}
|
|
1157
1395
|
return args;
|
|
1158
1396
|
};
|
|
1159
|
-
var extractRelationsParams = (relationMap, tables, tableName, info, typeName, typeNameMapper) => {
|
|
1397
|
+
var extractRelationsParams = (relationMap, tables, tableName, info, typeName, typeNameMapper, filterCtx) => {
|
|
1160
1398
|
if (!info) {
|
|
1161
1399
|
return void 0;
|
|
1162
1400
|
}
|
|
1163
|
-
return extractRelationsParamsInner(relationMap, tables, tableName, typeName, info, typeNameMapper, true);
|
|
1401
|
+
return extractRelationsParamsInner(relationMap, tables, tableName, typeName, info, typeNameMapper, true, filterCtx);
|
|
1164
1402
|
};
|
|
1165
1403
|
var pruneNonEagerRelations = (relationMap, shouldEagerLoad) => {
|
|
1166
1404
|
const out = {};
|
|
@@ -1204,39 +1442,307 @@ var primaryKeyOrderExprs = (table, pkNames) => {
|
|
|
1204
1442
|
const cols = getColumns(table);
|
|
1205
1443
|
return pkNames.map((n) => cols[n]).filter(Boolean).map((col) => asc(col));
|
|
1206
1444
|
};
|
|
1445
|
+
var getUniqueColumnSets = (table, getTableConfig4) => {
|
|
1446
|
+
const cols = getColumns(table);
|
|
1447
|
+
const propNameByColumnName = new Map(Object.entries(cols).map(([propName, col]) => [col.name, propName]));
|
|
1448
|
+
const toPropNames = (columnNames) => {
|
|
1449
|
+
const propNames = [];
|
|
1450
|
+
for (const columnName of columnNames) {
|
|
1451
|
+
const propName = columnName === void 0 ? void 0 : propNameByColumnName.get(columnName);
|
|
1452
|
+
if (!propName) {
|
|
1453
|
+
return void 0;
|
|
1454
|
+
}
|
|
1455
|
+
propNames.push(propName);
|
|
1456
|
+
}
|
|
1457
|
+
return propNames.length ? propNames : void 0;
|
|
1458
|
+
};
|
|
1459
|
+
const config = getTableConfig4(table);
|
|
1460
|
+
const candidates = [
|
|
1461
|
+
// Inline `.primaryKey()` columns, then table-level `primaryKey({ columns })`.
|
|
1462
|
+
Object.entries(cols).filter(([, col]) => col.primary).map(([propName]) => propName),
|
|
1463
|
+
...config.primaryKeys.map((pk) => toPropNames(pk.columns.map((c) => c.name))),
|
|
1464
|
+
...(config.uniqueConstraints ?? []).map((uc) => toPropNames(uc.columns.map((c) => c.name))),
|
|
1465
|
+
...(config.indexes ?? []).filter((index) => index.config.unique).map((index) => toPropNames(index.config.columns.map((c) => c?.name))),
|
|
1466
|
+
...Object.entries(cols).filter(([, col]) => col.isUnique).map(([propName]) => [propName])
|
|
1467
|
+
];
|
|
1468
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1469
|
+
const sets = [];
|
|
1470
|
+
for (const set of candidates) {
|
|
1471
|
+
if (!set?.length) {
|
|
1472
|
+
continue;
|
|
1473
|
+
}
|
|
1474
|
+
const key = [...set].sort().join(",");
|
|
1475
|
+
if (seen.has(key)) {
|
|
1476
|
+
continue;
|
|
1477
|
+
}
|
|
1478
|
+
seen.add(key);
|
|
1479
|
+
sets.push(set);
|
|
1480
|
+
}
|
|
1481
|
+
return sets;
|
|
1482
|
+
};
|
|
1483
|
+
var DISTINCT_RN = "__drizzle_graphql_distinct_rn";
|
|
1484
|
+
var columnEnumCache = /* @__PURE__ */ new WeakMap();
|
|
1485
|
+
var generateColumnEnum = (table, enumName, description, predicate = () => true) => {
|
|
1486
|
+
let tableCache = columnEnumCache.get(table);
|
|
1487
|
+
const cached = tableCache?.get(enumName);
|
|
1488
|
+
if (cached) {
|
|
1489
|
+
return cached;
|
|
1490
|
+
}
|
|
1491
|
+
const columnNames = Object.entries(getColumns(table)).filter(([columnName, column]) => predicate(column, columnName)).map(([columnName]) => columnName);
|
|
1492
|
+
if (!columnNames.length) {
|
|
1493
|
+
return void 0;
|
|
1494
|
+
}
|
|
1495
|
+
const enumType = new GraphQLEnumType2({
|
|
1496
|
+
name: enumName,
|
|
1497
|
+
description,
|
|
1498
|
+
values: Object.fromEntries(columnNames.map((columnName) => [columnName, { value: columnName }]))
|
|
1499
|
+
});
|
|
1500
|
+
if (!tableCache) {
|
|
1501
|
+
tableCache = /* @__PURE__ */ new Map();
|
|
1502
|
+
columnEnumCache.set(table, tableCache);
|
|
1503
|
+
}
|
|
1504
|
+
tableCache.set(enumName, enumType);
|
|
1505
|
+
return enumType;
|
|
1506
|
+
};
|
|
1507
|
+
var generateDistinctEnum = (table, typeName) => generateColumnEnum(table, `${typeName}DistinctColumn`, `Columns of ${typeName} that a query can be made distinct on`);
|
|
1508
|
+
var conflictActionEnum = new GraphQLEnumType2({
|
|
1509
|
+
name: "ConflictAction",
|
|
1510
|
+
description: "What an upsert does when a row with the same unique key already exists",
|
|
1511
|
+
values: {
|
|
1512
|
+
UPDATE: { value: "UPDATE", description: "Overwrite the conflicting row with the supplied values" },
|
|
1513
|
+
NOTHING: { value: "NOTHING", description: "Keep the existing row and insert nothing" }
|
|
1514
|
+
}
|
|
1515
|
+
});
|
|
1516
|
+
var generateOnConflictInput = (params) => {
|
|
1517
|
+
const { table, typeName, uniqueSets, tableFilters, withTarget } = params;
|
|
1518
|
+
const updateEnum = generateColumnEnum(
|
|
1519
|
+
table,
|
|
1520
|
+
`${typeName}UpdateColumn`,
|
|
1521
|
+
`Columns of ${typeName} that an upsert can overwrite`
|
|
1522
|
+
);
|
|
1523
|
+
if (!updateEnum) {
|
|
1524
|
+
return void 0;
|
|
1525
|
+
}
|
|
1526
|
+
const fields = {
|
|
1527
|
+
action: {
|
|
1528
|
+
type: conflictActionEnum,
|
|
1529
|
+
defaultValue: "UPDATE",
|
|
1530
|
+
description: "Whether a conflicting row is overwritten or left alone. Defaults to UPDATE."
|
|
1531
|
+
},
|
|
1532
|
+
update: {
|
|
1533
|
+
type: new GraphQLList2(new GraphQLNonNull2(updateEnum)),
|
|
1534
|
+
description: "Columns to overwrite on conflict. Defaults to every column the request supplied, minus the conflict target. Columns the request did not supply cannot be listed here \u2014 there would be no value to write."
|
|
1535
|
+
}
|
|
1536
|
+
};
|
|
1537
|
+
if (withTarget) {
|
|
1538
|
+
const uniqueColumns = new Set(uniqueSets.flat());
|
|
1539
|
+
const targetEnum = generateColumnEnum(
|
|
1540
|
+
table,
|
|
1541
|
+
`${typeName}ConflictTarget`,
|
|
1542
|
+
`Columns of ${typeName} that carry a unique constraint, and so can be conflicted on`,
|
|
1543
|
+
(_column, columnName) => uniqueColumns.has(columnName)
|
|
1544
|
+
);
|
|
1545
|
+
if (!targetEnum) {
|
|
1546
|
+
return void 0;
|
|
1547
|
+
}
|
|
1548
|
+
fields["target"] = {
|
|
1549
|
+
type: new GraphQLList2(new GraphQLNonNull2(targetEnum)),
|
|
1550
|
+
description: "The unique column set a conflict is detected on. Must match one of the table\u2019s unique constraints exactly. Defaults to the primary key."
|
|
1551
|
+
};
|
|
1552
|
+
fields["where"] = {
|
|
1553
|
+
type: tableFilters,
|
|
1554
|
+
description: "Only overwrite conflicting rows that match this filter. Others are left alone."
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
return new GraphQLInputObjectType2({
|
|
1558
|
+
name: `${typeName}OnConflict`,
|
|
1559
|
+
description: `Conflict handling for an upsert of ${typeName}`,
|
|
1560
|
+
fields
|
|
1561
|
+
});
|
|
1562
|
+
};
|
|
1563
|
+
var resolveConflictPlan = (params) => {
|
|
1564
|
+
const { table, values, onConflict, pkNames, uniqueSets, excludedRef, withTarget, buildWhere } = params;
|
|
1565
|
+
const columns = getColumns(table);
|
|
1566
|
+
let target;
|
|
1567
|
+
if (withTarget) {
|
|
1568
|
+
const targetNames2 = onConflict?.target?.length ? onConflict.target : [...pkNames];
|
|
1569
|
+
if (!targetNames2.length) {
|
|
1570
|
+
throw new GraphQLError3(
|
|
1571
|
+
"Unable to upsert: no conflict target was given and this table has no primary key. Pass onConflict.target."
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
const requested = [...targetNames2].sort().join(",");
|
|
1575
|
+
if (!uniqueSets.some((set2) => [...set2].sort().join(",") === requested)) {
|
|
1576
|
+
throw new GraphQLError3(
|
|
1577
|
+
`Unable to upsert: [${targetNames2.join(", ")}] is not a unique constraint on this table. Valid conflict targets: ${uniqueSets.map((set2) => `[${set2.join(", ")}]`).join(", ")}.`
|
|
1578
|
+
);
|
|
1579
|
+
}
|
|
1580
|
+
target = targetNames2.map((name) => columns[name]);
|
|
1581
|
+
}
|
|
1582
|
+
if ((onConflict?.action ?? "UPDATE") === "NOTHING") {
|
|
1583
|
+
return { action: "NOTHING", target, set: {}, setWhere: void 0 };
|
|
1584
|
+
}
|
|
1585
|
+
const supplied = new Set(values.flatMap((row) => Object.keys(row)));
|
|
1586
|
+
const targetNames = new Set(withTarget ? onConflict?.target?.length ? onConflict.target : pkNames : []);
|
|
1587
|
+
let updateNames;
|
|
1588
|
+
if (onConflict?.update?.length) {
|
|
1589
|
+
const unsupplied = onConflict.update.filter((name) => !supplied.has(name));
|
|
1590
|
+
if (unsupplied.length) {
|
|
1591
|
+
throw new GraphQLError3(
|
|
1592
|
+
`Unable to upsert: onConflict.update lists ${unsupplied.join(", ")}, which the values do not supply.`
|
|
1593
|
+
);
|
|
1594
|
+
}
|
|
1595
|
+
updateNames = onConflict.update;
|
|
1596
|
+
} else {
|
|
1597
|
+
updateNames = [...supplied].filter((name) => !targetNames.has(name));
|
|
1598
|
+
}
|
|
1599
|
+
if (!updateNames.length) {
|
|
1600
|
+
return { action: "NOTHING", target, set: {}, setWhere: void 0 };
|
|
1601
|
+
}
|
|
1602
|
+
const set = Object.fromEntries(updateNames.map((name) => [name, excludedRef(columns[name].name)]));
|
|
1603
|
+
const setWhere = onConflict?.where && buildWhere ? buildWhere(onConflict.where) : void 0;
|
|
1604
|
+
return { action: "UPDATE", target, set, setWhere };
|
|
1605
|
+
};
|
|
1606
|
+
var excludedColumnRef = (columnName) => sql`excluded.${sql.identifier(columnName)}`;
|
|
1607
|
+
var mysqlValuesColumnRef = (columnName) => sql`values(${sql.identifier(columnName)})`;
|
|
1608
|
+
var selectDistinctKeys = async (params) => {
|
|
1609
|
+
const { db, table, tableName, distinct, pkNames, where, orderBy, limit, offset } = params;
|
|
1610
|
+
const cols = getColumns(table);
|
|
1611
|
+
if (!pkNames.length) {
|
|
1612
|
+
throw new GraphQLError3(`Table ${tableName} has no primary key, so 'distinct' cannot be applied to it.`);
|
|
1613
|
+
}
|
|
1614
|
+
const partitionCols = distinct.map((name) => cols[name]).filter(Boolean);
|
|
1615
|
+
if (!partitionCols.length) {
|
|
1616
|
+
throw new GraphQLError3(`No known columns were given to 'distinct' on ${tableName}.`);
|
|
1617
|
+
}
|
|
1618
|
+
const orderEntries = orderBy ? orderByEntries(orderBy) : [];
|
|
1619
|
+
const windowOrder = [
|
|
1620
|
+
...orderEntries.map(([column, direction]) => direction === "asc" ? asc(cols[column]) : desc(cols[column])),
|
|
1621
|
+
...primaryKeyOrderExprs(table, pkNames)
|
|
1622
|
+
];
|
|
1623
|
+
const rowNumber = sql`row_number() over (partition by ${sql.join(partitionCols, sql`, `)} order by ${sql.join(
|
|
1624
|
+
windowOrder,
|
|
1625
|
+
sql`, `
|
|
1626
|
+
)})`.as(DISTINCT_RN);
|
|
1627
|
+
const sub = db.select({ ...cols, [DISTINCT_RN]: rowNumber }).from(table).where(where).as("__dgql_distinct");
|
|
1628
|
+
const outerOrder = [
|
|
1629
|
+
...orderEntries.map(([column, direction]) => direction === "asc" ? asc(sub[column]) : desc(sub[column])),
|
|
1630
|
+
...pkNames.filter((name) => sub[name]).map((name) => asc(sub[name]))
|
|
1631
|
+
];
|
|
1632
|
+
let query = db.select(Object.fromEntries(pkNames.map((name) => [name, sub[name]]))).from(sub).where(eq(sub[DISTINCT_RN], 1)).orderBy(...outerOrder);
|
|
1633
|
+
if (offset) {
|
|
1634
|
+
query = query.offset(offset);
|
|
1635
|
+
}
|
|
1636
|
+
if (limit != null) {
|
|
1637
|
+
query = query.limit(limit);
|
|
1638
|
+
}
|
|
1639
|
+
return await query;
|
|
1640
|
+
};
|
|
1641
|
+
var primaryKeyRestriction = (table, pkNames, keys) => {
|
|
1642
|
+
const cols = getColumns(table);
|
|
1643
|
+
if (pkNames.length === 1) {
|
|
1644
|
+
const name = pkNames[0];
|
|
1645
|
+
return inArray(
|
|
1646
|
+
cols[name],
|
|
1647
|
+
keys.map((key) => key[name])
|
|
1648
|
+
);
|
|
1649
|
+
}
|
|
1650
|
+
return or(...keys.map((key) => and(...pkNames.map((name) => eq(cols[name], key[name])))));
|
|
1651
|
+
};
|
|
1207
1652
|
var prepareMutationRelationColumns = (params) => {
|
|
1208
1653
|
const { relationMap, tables, tableName, typeName, typeNameMapper, table, pkNames, parsedInfo } = params;
|
|
1209
1654
|
const withParams = relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, typeNameMapper) : void 0;
|
|
1210
1655
|
const hasRelations = !!(withParams && Object.keys(withParams).length);
|
|
1211
|
-
const baseColumns = extractSelectedColumnsFromTreeSQLFormat(parsedInfo.fieldsByTypeName[typeName], table
|
|
1656
|
+
const baseColumns = extractSelectedColumnsFromTreeSQLFormat(parsedInfo.fieldsByTypeName[typeName], table, {
|
|
1657
|
+
tableName,
|
|
1658
|
+
relationMap,
|
|
1659
|
+
tables
|
|
1660
|
+
});
|
|
1212
1661
|
const columns = hasRelations ? withPrimaryKeyColumns(baseColumns, table, pkNames) : baseColumns;
|
|
1213
1662
|
return { columns, hasRelations, withParams };
|
|
1214
1663
|
};
|
|
1215
|
-
var toGraphQLError = (e) =>
|
|
1664
|
+
var toGraphQLError = (e) => {
|
|
1665
|
+
if (e instanceof GraphQLError3) {
|
|
1666
|
+
return e;
|
|
1667
|
+
}
|
|
1668
|
+
return e instanceof Error ? new GraphQLError3(e.message, { originalError: e }) : e;
|
|
1669
|
+
};
|
|
1670
|
+
var defaultErrorMapper = (error) => {
|
|
1671
|
+
if (error instanceof GraphQLError3 && !error.originalError) {
|
|
1672
|
+
return error;
|
|
1673
|
+
}
|
|
1674
|
+
return new GraphQLError3("Internal server error", {
|
|
1675
|
+
originalError: error instanceof GraphQLError3 ? error.originalError ?? error : error instanceof Error ? error : null,
|
|
1676
|
+
extensions: { code: "INTERNAL_SERVER_ERROR" }
|
|
1677
|
+
});
|
|
1678
|
+
};
|
|
1679
|
+
var applyErrorMapper = (entities, mapError) => {
|
|
1680
|
+
const wrap = (resolve) => (...args) => {
|
|
1681
|
+
try {
|
|
1682
|
+
const result = resolve(...args);
|
|
1683
|
+
if (result && typeof result.then === "function") {
|
|
1684
|
+
return result.then(void 0, (e) => {
|
|
1685
|
+
throw mapError(e);
|
|
1686
|
+
});
|
|
1687
|
+
}
|
|
1688
|
+
return result;
|
|
1689
|
+
} catch (e) {
|
|
1690
|
+
throw mapError(e);
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
for (const field of [...Object.values(entities.queries), ...Object.values(entities.mutations)]) {
|
|
1694
|
+
if (field?.resolve) {
|
|
1695
|
+
field.resolve = wrap(field.resolve);
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
for (const type of Object.values(entities.types)) {
|
|
1699
|
+
if (typeof type?.getFields !== "function") {
|
|
1700
|
+
continue;
|
|
1701
|
+
}
|
|
1702
|
+
for (const field of Object.values(type.getFields())) {
|
|
1703
|
+
if (field?.resolve) {
|
|
1704
|
+
field.resolve = wrap(field.resolve);
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
for (const tableResolvers of Object.values(entities.fieldResolvers ?? {})) {
|
|
1709
|
+
for (const [relationName, resolve] of Object.entries(tableResolvers)) {
|
|
1710
|
+
tableResolvers[relationName] = wrap(resolve);
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
};
|
|
1216
1714
|
var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes) => {
|
|
1217
1715
|
const mapped = typeNameMapper?.(tableName);
|
|
1218
1716
|
const typeName = mapped ? capitalize(mapped.singular) : capitalize(tableName);
|
|
1219
1717
|
const listFieldName = (mapped?.plural ?? uncapitalize(tableName)) + suffixes.list;
|
|
1220
1718
|
const singleFieldName = mapped?.singular ?? uncapitalize(tableName) + suffixes.single;
|
|
1719
|
+
const aggregateFieldName = `${mapped?.plural ?? uncapitalize(tableName)}Aggregate`;
|
|
1221
1720
|
const createArrayFieldName = `${prefixes.insert}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
|
|
1222
1721
|
const createSingleFieldName = mapped ? `${prefixes.insert}${capitalize(mapped.singular)}` : `${prefixes.insert}${capitalize(tableName)}${suffixes.single}`;
|
|
1722
|
+
const upsertPrefix = prefixes.upsert ?? "upsert";
|
|
1723
|
+
const upsertArrayFieldName = `${upsertPrefix}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
|
|
1724
|
+
const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
|
|
1223
1725
|
const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
|
|
1224
1726
|
const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
|
|
1225
1727
|
return {
|
|
1226
1728
|
typeName,
|
|
1227
1729
|
listFieldName,
|
|
1228
1730
|
singleFieldName,
|
|
1731
|
+
aggregateFieldName,
|
|
1229
1732
|
createArrayFieldName,
|
|
1230
1733
|
createSingleFieldName,
|
|
1734
|
+
upsertArrayFieldName,
|
|
1735
|
+
upsertSingleFieldName,
|
|
1231
1736
|
updateFieldName,
|
|
1232
1737
|
deleteFieldName
|
|
1233
1738
|
};
|
|
1234
1739
|
};
|
|
1235
|
-
var selectArrayArgs = (orderArgs, filterArgs) => ({
|
|
1740
|
+
var selectArrayArgs = (orderArgs, filterArgs, distinctEnum) => ({
|
|
1236
1741
|
offset: { type: GraphQLInt2 },
|
|
1237
1742
|
limit: { type: GraphQLInt2 },
|
|
1238
1743
|
orderBy: { type: orderArgs },
|
|
1239
|
-
where: { type: filterArgs }
|
|
1744
|
+
where: { type: filterArgs },
|
|
1745
|
+
...distinctEnum ? { distinct: { type: new GraphQLList2(new GraphQLNonNull2(distinctEnum)) } } : {}
|
|
1240
1746
|
});
|
|
1241
1747
|
var selectSingleArgs = (orderArgs, filterArgs) => ({
|
|
1242
1748
|
offset: { type: GraphQLInt2 },
|
|
@@ -1256,22 +1762,52 @@ var runRelationalSelect = async (opts) => {
|
|
|
1256
1762
|
offset,
|
|
1257
1763
|
orderBy,
|
|
1258
1764
|
where,
|
|
1259
|
-
single
|
|
1765
|
+
single,
|
|
1766
|
+
filterCtx,
|
|
1767
|
+
pkNames
|
|
1260
1768
|
} = opts;
|
|
1769
|
+
const distinct = opts.distinct?.length ? opts.distinct : void 0;
|
|
1770
|
+
const needsDefaultOrder = single || offset != null || opts.limit != null;
|
|
1771
|
+
let distinctKeys;
|
|
1772
|
+
if (distinct) {
|
|
1773
|
+
distinctKeys = await selectDistinctKeys({
|
|
1774
|
+
db: opts.db,
|
|
1775
|
+
table,
|
|
1776
|
+
tableName,
|
|
1777
|
+
distinct,
|
|
1778
|
+
pkNames: pkNames ?? [],
|
|
1779
|
+
where: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0,
|
|
1780
|
+
orderBy,
|
|
1781
|
+
limit: single ? 1 : opts.limit,
|
|
1782
|
+
offset
|
|
1783
|
+
});
|
|
1784
|
+
if (!distinctKeys.length) {
|
|
1785
|
+
return single ? void 0 : [];
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1261
1788
|
const params = {
|
|
1262
|
-
columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table
|
|
1263
|
-
|
|
1789
|
+
columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table, {
|
|
1790
|
+
tableName,
|
|
1791
|
+
relationMap,
|
|
1792
|
+
tables
|
|
1793
|
+
}),
|
|
1794
|
+
offset: distinctKeys ? void 0 : offset,
|
|
1264
1795
|
// drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
|
|
1265
1796
|
// directly so column refs match the CTE alias.
|
|
1266
|
-
orderBy:
|
|
1267
|
-
|
|
1268
|
-
|
|
1797
|
+
orderBy: distinctKeys ? (aliasedTable2) => [
|
|
1798
|
+
...orderBy ? extractOrderBy(aliasedTable2, orderBy) : [],
|
|
1799
|
+
...primaryKeyOrderExprs(aliasedTable2, pkNames)
|
|
1800
|
+
] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
|
|
1801
|
+
where: distinctKeys ? { RAW: (aliasedTable2) => primaryKeyRestriction(aliasedTable2, pkNames, distinctKeys) } : where ? {
|
|
1802
|
+
RAW: (aliasedTable2) => extractFilters(aliasedTable2, tableName, where, relationFilterCtx(filterCtx, tableName))
|
|
1803
|
+
} : void 0,
|
|
1804
|
+
with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, typeNameMapper, filterCtx) : void 0
|
|
1269
1805
|
};
|
|
1270
1806
|
if (single) {
|
|
1271
1807
|
const result2 = await queryBase.findFirst(params);
|
|
1272
1808
|
return result2 ? remapToGraphQLSingleOutput(result2, tableName, table, relationMap) : void 0;
|
|
1273
1809
|
}
|
|
1274
|
-
params.limit = opts.limit;
|
|
1810
|
+
params.limit = distinctKeys ? void 0 : opts.limit;
|
|
1275
1811
|
const result = await queryBase.findMany(params);
|
|
1276
1812
|
return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
|
|
1277
1813
|
};
|
|
@@ -1344,32 +1880,233 @@ var eagerLoadMutationRelations = async (db, tableName, rows, pkNames, withParams
|
|
|
1344
1880
|
};
|
|
1345
1881
|
|
|
1346
1882
|
// src/util/builders/mysql.ts
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1883
|
+
import { is as is4, One as One3 } from "drizzle-orm";
|
|
1884
|
+
import { getTableConfig, MySqlTable } from "drizzle-orm/mysql-core";
|
|
1885
|
+
import {
|
|
1886
|
+
GraphQLBoolean as GraphQLBoolean3,
|
|
1887
|
+
GraphQLError as GraphQLError4,
|
|
1888
|
+
GraphQLList as GraphQLList4,
|
|
1889
|
+
GraphQLNonNull as GraphQLNonNull4,
|
|
1890
|
+
GraphQLObjectType as GraphQLObjectType4
|
|
1891
|
+
} from "graphql";
|
|
1892
|
+
import { parseResolveInfo as parseResolveInfo2 } from "graphql-parse-resolve-info";
|
|
1893
|
+
|
|
1894
|
+
// src/util/builders/aggregates.ts
|
|
1895
|
+
import {
|
|
1896
|
+
and as and2,
|
|
1897
|
+
avg,
|
|
1898
|
+
count,
|
|
1899
|
+
countDistinct,
|
|
1900
|
+
extractExtendedColumnType as extractExtendedColumnType2,
|
|
1901
|
+
getColumns as getColumns2,
|
|
1902
|
+
inArray as inArray2,
|
|
1903
|
+
max,
|
|
1904
|
+
min,
|
|
1905
|
+
sum
|
|
1906
|
+
} from "drizzle-orm";
|
|
1907
|
+
import {
|
|
1908
|
+
GraphQLFloat as GraphQLFloat2,
|
|
1909
|
+
GraphQLInt as GraphQLInt3,
|
|
1910
|
+
GraphQLList as GraphQLList3,
|
|
1911
|
+
GraphQLNonNull as GraphQLNonNull3,
|
|
1912
|
+
GraphQLObjectType as GraphQLObjectType3
|
|
1913
|
+
} from "graphql";
|
|
1914
|
+
import { parseResolveInfo } from "graphql-parse-resolve-info";
|
|
1915
|
+
var AGGREGATE_OPS = ["avg", "sum", "min", "max", "countNonNull", "countDistinct"];
|
|
1916
|
+
var COUNT_OPS = /* @__PURE__ */ new Set(["countNonNull", "countDistinct"]);
|
|
1917
|
+
var OP_FNS = {
|
|
1918
|
+
avg,
|
|
1919
|
+
sum,
|
|
1920
|
+
min,
|
|
1921
|
+
max,
|
|
1922
|
+
countNonNull: count,
|
|
1923
|
+
countDistinct
|
|
1924
|
+
};
|
|
1925
|
+
var SEP = "__";
|
|
1926
|
+
var classifyAggregateColumns = (table, tableName) => {
|
|
1927
|
+
const numeric = {};
|
|
1928
|
+
const orderable = {};
|
|
1929
|
+
const all = {};
|
|
1930
|
+
for (const [columnName, column] of Object.entries(getColumns2(table))) {
|
|
1931
|
+
all[columnName] = column;
|
|
1932
|
+
const converted = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, false);
|
|
1933
|
+
const gqlType = converted.type;
|
|
1934
|
+
if (gqlType instanceof GraphQLList3 || gqlType instanceof GraphQLObjectType3) {
|
|
1935
|
+
continue;
|
|
1936
|
+
}
|
|
1937
|
+
const { type: dataType, constraint } = extractExtendedColumnType2(column);
|
|
1938
|
+
if (dataType === "boolean" || dataType === "array" || dataType === "custom") {
|
|
1939
|
+
continue;
|
|
1940
|
+
}
|
|
1941
|
+
if (dataType === "object" && constraint !== "date") {
|
|
1942
|
+
continue;
|
|
1943
|
+
}
|
|
1944
|
+
orderable[columnName] = { column, converted };
|
|
1945
|
+
if (dataType === "number") {
|
|
1946
|
+
numeric[columnName] = column;
|
|
1947
|
+
}
|
|
1353
1948
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1949
|
+
return { numeric, orderable, all };
|
|
1950
|
+
};
|
|
1951
|
+
var generateAggregateTypes = (table, tableName, typeName, cacheCtx) => {
|
|
1952
|
+
const cached = cacheCtx?.aggregateTypeCache.get(tableName);
|
|
1953
|
+
if (cached) {
|
|
1954
|
+
return cached;
|
|
1955
|
+
}
|
|
1956
|
+
const { numeric, orderable, all } = classifyAggregateColumns(table, tableName);
|
|
1957
|
+
const fields = {
|
|
1958
|
+
count: { type: new GraphQLNonNull3(GraphQLInt3) }
|
|
1959
|
+
};
|
|
1960
|
+
if (Object.keys(numeric).length) {
|
|
1961
|
+
for (const op of ["avg", "sum"]) {
|
|
1962
|
+
fields[op] = {
|
|
1963
|
+
type: new GraphQLObjectType3({
|
|
1964
|
+
name: `${typeName}${capitalize(op)}Aggregate`,
|
|
1965
|
+
fields: Object.fromEntries(Object.keys(numeric).map((columnName) => [columnName, { type: GraphQLFloat2 }]))
|
|
1966
|
+
})
|
|
1967
|
+
};
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
if (Object.keys(orderable).length) {
|
|
1971
|
+
for (const op of ["min", "max"]) {
|
|
1972
|
+
fields[op] = {
|
|
1973
|
+
type: new GraphQLObjectType3({
|
|
1974
|
+
name: `${typeName}${capitalize(op)}Aggregate`,
|
|
1975
|
+
fields: Object.fromEntries(
|
|
1976
|
+
Object.entries(orderable).map(([columnName, { converted }]) => [
|
|
1977
|
+
columnName,
|
|
1978
|
+
{ type: converted.type, description: converted.description }
|
|
1979
|
+
])
|
|
1980
|
+
)
|
|
1981
|
+
})
|
|
1982
|
+
};
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
const countSets = { countNonNull: all, countDistinct: orderable };
|
|
1986
|
+
for (const [op, columns] of Object.entries(countSets)) {
|
|
1987
|
+
const columnNames = Object.keys(columns);
|
|
1988
|
+
if (!columnNames.length) {
|
|
1989
|
+
continue;
|
|
1990
|
+
}
|
|
1991
|
+
fields[op] = {
|
|
1992
|
+
type: new GraphQLObjectType3({
|
|
1993
|
+
name: `${typeName}${capitalize(op)}Aggregate`,
|
|
1994
|
+
fields: Object.fromEntries(
|
|
1995
|
+
columnNames.map((columnName) => [columnName, { type: new GraphQLNonNull3(GraphQLInt3) }])
|
|
1996
|
+
)
|
|
1997
|
+
})
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
const aggregateType = new GraphQLObjectType3({
|
|
2001
|
+
name: `${typeName}Aggregate`,
|
|
2002
|
+
fields
|
|
2003
|
+
});
|
|
2004
|
+
cacheCtx?.aggregateTypeCache.set(tableName, aggregateType);
|
|
2005
|
+
return aggregateType;
|
|
2006
|
+
};
|
|
2007
|
+
var parseDriverDateTime = (raw) => {
|
|
2008
|
+
let v = raw.includes(" ") ? raw.replace(" ", "T") : raw;
|
|
2009
|
+
if (!v.includes("T")) {
|
|
2010
|
+
v = `${v}T00:00:00`;
|
|
2011
|
+
}
|
|
2012
|
+
if (!/(?:[Zz]|[+-]\d{2}(?::?\d{2})?)$/.test(v)) {
|
|
2013
|
+
v = `${v}Z`;
|
|
2014
|
+
}
|
|
2015
|
+
const parsed = new Date(v);
|
|
2016
|
+
return Number.isNaN(parsed.getTime()) ? new Date(raw) : parsed;
|
|
2017
|
+
};
|
|
2018
|
+
var aggregateTarget = (table, tableName, typeName) => {
|
|
2019
|
+
const { orderable } = classifyAggregateColumns(table, tableName);
|
|
2020
|
+
return {
|
|
2021
|
+
tableName,
|
|
2022
|
+
typeName,
|
|
2023
|
+
columns: getColumns2(table),
|
|
2024
|
+
dateTimeColumns: new Set(
|
|
2025
|
+
Object.entries(orderable).filter(([, { converted }]) => converted.description === "DateTime").map(([columnName]) => columnName)
|
|
2026
|
+
)
|
|
2027
|
+
};
|
|
2028
|
+
};
|
|
2029
|
+
var parseAggregateRequest = (info, target) => {
|
|
2030
|
+
const parsedInfo = parseResolveInfo(info, { deep: true });
|
|
2031
|
+
const selectionTree = parsedInfo.fieldsByTypeName[`${target.typeName}Aggregate`] ?? {};
|
|
2032
|
+
const request = {
|
|
2033
|
+
count: false,
|
|
2034
|
+
ops: { avg: [], sum: [], min: [], max: [], countNonNull: [], countDistinct: [] },
|
|
2035
|
+
selection: {}
|
|
2036
|
+
};
|
|
2037
|
+
for (const field of Object.values(selectionTree)) {
|
|
2038
|
+
if (field.name === "count") {
|
|
2039
|
+
request.count = true;
|
|
2040
|
+
request.selection.count = count();
|
|
2041
|
+
continue;
|
|
2042
|
+
}
|
|
2043
|
+
if (!AGGREGATE_OPS.includes(field.name)) {
|
|
2044
|
+
continue;
|
|
2045
|
+
}
|
|
2046
|
+
const op = field.name;
|
|
2047
|
+
const subTree = field.fieldsByTypeName[`${target.typeName}${capitalize(op)}Aggregate`];
|
|
2048
|
+
if (!subTree) {
|
|
2049
|
+
continue;
|
|
2050
|
+
}
|
|
2051
|
+
for (const subField of Object.values(subTree)) {
|
|
2052
|
+
const columnName = subField.name;
|
|
2053
|
+
const column = target.columns[columnName];
|
|
2054
|
+
if (!column || request.ops[op].includes(columnName)) {
|
|
2055
|
+
continue;
|
|
2056
|
+
}
|
|
2057
|
+
request.ops[op].push(columnName);
|
|
2058
|
+
request.selection[`${op}${SEP}${columnName}`] = OP_FNS[op](column);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
return request;
|
|
2062
|
+
};
|
|
2063
|
+
var assembleAggregateRow = (row, request, target) => {
|
|
2064
|
+
const result = {};
|
|
2065
|
+
if (request.count) {
|
|
2066
|
+
result.count = row.count == null ? 0 : Number(row.count);
|
|
2067
|
+
}
|
|
2068
|
+
for (const op of AGGREGATE_OPS) {
|
|
2069
|
+
if (!request.ops[op].length) {
|
|
2070
|
+
continue;
|
|
2071
|
+
}
|
|
2072
|
+
const opResult = {};
|
|
2073
|
+
for (const columnName of request.ops[op]) {
|
|
2074
|
+
const value = row[`${op}${SEP}${columnName}`];
|
|
2075
|
+
if (COUNT_OPS.has(op)) {
|
|
2076
|
+
opResult[columnName] = value == null ? 0 : Number(value);
|
|
2077
|
+
} else if (value == null) {
|
|
2078
|
+
opResult[columnName] = null;
|
|
2079
|
+
} else if (op === "avg" || op === "sum") {
|
|
2080
|
+
opResult[columnName] = Number(value);
|
|
2081
|
+
} else {
|
|
2082
|
+
const column = target.columns[columnName];
|
|
2083
|
+
const decoded = typeof value === "string" && target.dateTimeColumns.has(columnName) ? parseDriverDateTime(value) : value;
|
|
2084
|
+
opResult[columnName] = remapToGraphQLCore(columnName, decoded, target.tableName, column);
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
result[op] = opResult;
|
|
2088
|
+
}
|
|
2089
|
+
return result;
|
|
2090
|
+
};
|
|
2091
|
+
var generateAggregate = (db, tableName, table, typeName, fieldName, filterArgs, filterCtx) => {
|
|
2092
|
+
const target = aggregateTarget(table, tableName, typeName);
|
|
2093
|
+
const queryArgs = {
|
|
2094
|
+
where: { type: filterArgs }
|
|
2095
|
+
};
|
|
2096
|
+
return {
|
|
2097
|
+
name: fieldName,
|
|
2098
|
+
resolver: async (_source, args, context, info) => {
|
|
2099
|
+
try {
|
|
2100
|
+
const request = parseAggregateRequest(info, target);
|
|
2101
|
+
if (!Object.keys(request.selection).length) {
|
|
2102
|
+
return {};
|
|
2103
|
+
}
|
|
2104
|
+
let query = resolveExecutor(db, context).select(request.selection).from(table);
|
|
2105
|
+
if (args.where) {
|
|
2106
|
+
query = query.where(extractFilters(table, tableName, args.where, relationFilterCtx(filterCtx, tableName)));
|
|
2107
|
+
}
|
|
2108
|
+
const rows = await query;
|
|
2109
|
+
return assembleAggregateRow(rows[0] ?? {}, request, target);
|
|
1373
2110
|
} catch (e) {
|
|
1374
2111
|
throw toGraphQLError(e);
|
|
1375
2112
|
}
|
|
@@ -1377,7 +2114,103 @@ var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filter
|
|
|
1377
2114
|
args: queryArgs
|
|
1378
2115
|
};
|
|
1379
2116
|
};
|
|
1380
|
-
var
|
|
2117
|
+
var GROUP_KEY = "__dgql_group_key";
|
|
2118
|
+
var createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, filterCtx) => {
|
|
2119
|
+
return ({ tableName, relationName, relEntry }) => {
|
|
2120
|
+
const parentTable = tables[tableName];
|
|
2121
|
+
const targetTableName = relEntry.targetTableName;
|
|
2122
|
+
const targetTable = tables[targetTableName];
|
|
2123
|
+
if (!parentTable || !targetTable) {
|
|
2124
|
+
return void 0;
|
|
2125
|
+
}
|
|
2126
|
+
const joinCols = extractRelationJoinColumns(relEntry, parentTable, targetTable);
|
|
2127
|
+
if (!joinCols) {
|
|
2128
|
+
return void 0;
|
|
2129
|
+
}
|
|
2130
|
+
const { localColPropName, foreignCol } = joinCols;
|
|
2131
|
+
const targetTypeName = resolveTypeName(targetTableName, typeNameMapper);
|
|
2132
|
+
const type = generateAggregateTypes(targetTable, targetTableName, targetTypeName, cacheCtx);
|
|
2133
|
+
const target = aggregateTarget(targetTable, targetTableName, targetTypeName);
|
|
2134
|
+
const resolve = async (parent, args, context, info) => {
|
|
2135
|
+
try {
|
|
2136
|
+
const request = parseAggregateRequest(info, target);
|
|
2137
|
+
if (!Object.keys(request.selection).length) {
|
|
2138
|
+
return {};
|
|
2139
|
+
}
|
|
2140
|
+
const localValue = parent[localColPropName];
|
|
2141
|
+
if (localValue == null) {
|
|
2142
|
+
return assembleAggregateRow({}, request, target);
|
|
2143
|
+
}
|
|
2144
|
+
const whereArg = args?.where;
|
|
2145
|
+
const argsKey = JSON.stringify({
|
|
2146
|
+
where: whereArg ?? null,
|
|
2147
|
+
selection: Object.keys(request.selection).sort()
|
|
2148
|
+
});
|
|
2149
|
+
const loaderKey = `${tableName}::${relationName}::aggregate::${argsKey}`;
|
|
2150
|
+
const loader = getOrCreateLoader(context, loaderKey, async (parentIds) => {
|
|
2151
|
+
const executor = resolveExecutor(db, context);
|
|
2152
|
+
const uniqueIds = [...new Set(parentIds)];
|
|
2153
|
+
const whereCondition = and2(
|
|
2154
|
+
inArray2(foreignCol, uniqueIds),
|
|
2155
|
+
whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName)) : void 0
|
|
2156
|
+
);
|
|
2157
|
+
const rows = await executor.select({ [GROUP_KEY]: foreignCol, ...request.selection }).from(targetTable).where(whereCondition).groupBy(foreignCol);
|
|
2158
|
+
const byKey = new Map(rows.map((row) => [row[GROUP_KEY], row]));
|
|
2159
|
+
return parentIds.map((id) => byKey.get(id) ?? {});
|
|
2160
|
+
});
|
|
2161
|
+
return assembleAggregateRow(await loader.load(localValue), request, target);
|
|
2162
|
+
} catch (e) {
|
|
2163
|
+
throw toGraphQLError(e);
|
|
2164
|
+
}
|
|
2165
|
+
};
|
|
2166
|
+
return { type, resolve };
|
|
2167
|
+
};
|
|
2168
|
+
};
|
|
2169
|
+
|
|
2170
|
+
// src/util/builders/mysql.ts
|
|
2171
|
+
var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
|
|
2172
|
+
const queryBase = db.query[tableName];
|
|
2173
|
+
if (!queryBase) {
|
|
2174
|
+
throw new Error(
|
|
2175
|
+
`Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
|
|
2176
|
+
);
|
|
2177
|
+
}
|
|
2178
|
+
const table = tables[tableName];
|
|
2179
|
+
const pkNames = mysqlPrimaryKeyPropNames(table);
|
|
2180
|
+
const queryArgs = selectArrayArgs(
|
|
2181
|
+
orderArgs,
|
|
2182
|
+
filterArgs,
|
|
2183
|
+
distinctEnabled ? generateDistinctEnum(table, typeName) : void 0
|
|
2184
|
+
);
|
|
2185
|
+
return {
|
|
2186
|
+
name: fieldName,
|
|
2187
|
+
resolver: async (_source, args, context, info) => {
|
|
2188
|
+
try {
|
|
2189
|
+
const parsedInfo = parseResolveInfo2(info, { deep: true });
|
|
2190
|
+
const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
|
|
2191
|
+
return await runRelationalSelect({
|
|
2192
|
+
queryBase: requestQueryBase,
|
|
2193
|
+
tables,
|
|
2194
|
+
tableName,
|
|
2195
|
+
table,
|
|
2196
|
+
relationMap,
|
|
2197
|
+
typeName,
|
|
2198
|
+
typeNameMapper,
|
|
2199
|
+
parsedInfo,
|
|
2200
|
+
...args,
|
|
2201
|
+
single: false,
|
|
2202
|
+
filterCtx,
|
|
2203
|
+
pkNames,
|
|
2204
|
+
db: executor
|
|
2205
|
+
});
|
|
2206
|
+
} catch (e) {
|
|
2207
|
+
throw toGraphQLError(e);
|
|
2208
|
+
}
|
|
2209
|
+
},
|
|
2210
|
+
args: queryArgs
|
|
2211
|
+
};
|
|
2212
|
+
};
|
|
2213
|
+
var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
1381
2214
|
const queryBase = db.query[tableName];
|
|
1382
2215
|
if (!queryBase) {
|
|
1383
2216
|
throw new Error(
|
|
@@ -1386,13 +2219,15 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
1386
2219
|
}
|
|
1387
2220
|
const queryArgs = selectSingleArgs(orderArgs, filterArgs);
|
|
1388
2221
|
const table = tables[tableName];
|
|
2222
|
+
const pkNames = mysqlPrimaryKeyPropNames(table);
|
|
1389
2223
|
return {
|
|
1390
2224
|
name: fieldName,
|
|
1391
|
-
resolver: async (_source, args,
|
|
2225
|
+
resolver: async (_source, args, context, info) => {
|
|
1392
2226
|
try {
|
|
1393
|
-
const parsedInfo =
|
|
2227
|
+
const parsedInfo = parseResolveInfo2(info, { deep: true });
|
|
2228
|
+
const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
|
|
1394
2229
|
return await runRelationalSelect({
|
|
1395
|
-
queryBase,
|
|
2230
|
+
queryBase: requestQueryBase,
|
|
1396
2231
|
tables,
|
|
1397
2232
|
tableName,
|
|
1398
2233
|
table,
|
|
@@ -1401,7 +2236,10 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
1401
2236
|
typeNameMapper,
|
|
1402
2237
|
parsedInfo,
|
|
1403
2238
|
...args,
|
|
1404
|
-
single: true
|
|
2239
|
+
single: true,
|
|
2240
|
+
filterCtx,
|
|
2241
|
+
pkNames,
|
|
2242
|
+
db: executor
|
|
1405
2243
|
});
|
|
1406
2244
|
} catch (e) {
|
|
1407
2245
|
throw toGraphQLError(e);
|
|
@@ -1413,18 +2251,18 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
1413
2251
|
var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
|
|
1414
2252
|
const queryArgs = {
|
|
1415
2253
|
values: {
|
|
1416
|
-
type: new
|
|
2254
|
+
type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(baseType)))
|
|
1417
2255
|
}
|
|
1418
2256
|
};
|
|
1419
2257
|
return {
|
|
1420
2258
|
name: fieldName,
|
|
1421
|
-
resolver: async (_source, args,
|
|
2259
|
+
resolver: async (_source, args, context, _info) => {
|
|
1422
2260
|
try {
|
|
1423
2261
|
const input = remapFromGraphQLArrayInput(args.values, table);
|
|
1424
2262
|
if (!input.length) {
|
|
1425
|
-
throw new
|
|
2263
|
+
throw new GraphQLError4("No values were provided!");
|
|
1426
2264
|
}
|
|
1427
|
-
await db.insert(table).values(input);
|
|
2265
|
+
await resolveExecutor(db, context).insert(table).values(input);
|
|
1428
2266
|
return { isSuccess: true };
|
|
1429
2267
|
} catch (e) {
|
|
1430
2268
|
throw toGraphQLError(e);
|
|
@@ -1436,15 +2274,15 @@ var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
|
|
|
1436
2274
|
var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
|
|
1437
2275
|
const queryArgs = {
|
|
1438
2276
|
values: {
|
|
1439
|
-
type: new
|
|
2277
|
+
type: new GraphQLNonNull4(baseType)
|
|
1440
2278
|
}
|
|
1441
2279
|
};
|
|
1442
2280
|
return {
|
|
1443
2281
|
name: fieldName,
|
|
1444
|
-
resolver: async (_source, args,
|
|
2282
|
+
resolver: async (_source, args, context, _info) => {
|
|
1445
2283
|
try {
|
|
1446
2284
|
const input = remapFromGraphQLSingleInput(args.values, table);
|
|
1447
|
-
await db.insert(table).values(input);
|
|
2285
|
+
await resolveExecutor(db, context).insert(table).values(input);
|
|
1448
2286
|
return { isSuccess: true };
|
|
1449
2287
|
} catch (e) {
|
|
1450
2288
|
throw toGraphQLError(e);
|
|
@@ -1453,10 +2291,52 @@ var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
|
|
|
1453
2291
|
args: queryArgs
|
|
1454
2292
|
};
|
|
1455
2293
|
};
|
|
1456
|
-
var
|
|
2294
|
+
var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) => {
|
|
2295
|
+
const queryArgs = {
|
|
2296
|
+
values: {
|
|
2297
|
+
type: single ? new GraphQLNonNull4(baseType) : new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(baseType)))
|
|
2298
|
+
},
|
|
2299
|
+
onConflict: {
|
|
2300
|
+
type: onConflictType,
|
|
2301
|
+
description: "How a conflicting row is resolved. Defaults to overwriting it."
|
|
2302
|
+
}
|
|
2303
|
+
};
|
|
2304
|
+
const pkNames = mysqlPrimaryKeyPropNames(table);
|
|
2305
|
+
return {
|
|
2306
|
+
name: fieldName,
|
|
2307
|
+
resolver: async (_source, args, context, _info) => {
|
|
2308
|
+
try {
|
|
2309
|
+
const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
|
|
2310
|
+
if (!input.length) {
|
|
2311
|
+
throw new GraphQLError4("No values were provided!");
|
|
2312
|
+
}
|
|
2313
|
+
const plan = resolveConflictPlan({
|
|
2314
|
+
table,
|
|
2315
|
+
values: input,
|
|
2316
|
+
onConflict: args.onConflict,
|
|
2317
|
+
pkNames,
|
|
2318
|
+
uniqueSets: [],
|
|
2319
|
+
excludedRef: mysqlValuesColumnRef,
|
|
2320
|
+
withTarget: false
|
|
2321
|
+
});
|
|
2322
|
+
const executor = resolveExecutor(db, context);
|
|
2323
|
+
if (plan.action === "NOTHING") {
|
|
2324
|
+
await executor.insert(table).ignore().values(input);
|
|
2325
|
+
} else {
|
|
2326
|
+
await executor.insert(table).values(input).onDuplicateKeyUpdate({ set: plan.set });
|
|
2327
|
+
}
|
|
2328
|
+
return { isSuccess: true };
|
|
2329
|
+
} catch (e) {
|
|
2330
|
+
throw toGraphQLError(e);
|
|
2331
|
+
}
|
|
2332
|
+
},
|
|
2333
|
+
args: queryArgs
|
|
2334
|
+
};
|
|
2335
|
+
};
|
|
2336
|
+
var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filterCtx) => {
|
|
1457
2337
|
const queryArgs = {
|
|
1458
2338
|
set: {
|
|
1459
|
-
type: new
|
|
2339
|
+
type: new GraphQLNonNull4(setArgs)
|
|
1460
2340
|
},
|
|
1461
2341
|
where: {
|
|
1462
2342
|
type: filterArgs
|
|
@@ -1464,16 +2344,17 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName) => {
|
|
|
1464
2344
|
};
|
|
1465
2345
|
return {
|
|
1466
2346
|
name: fieldName,
|
|
1467
|
-
resolver: async (_source, args,
|
|
2347
|
+
resolver: async (_source, args, context, _info) => {
|
|
1468
2348
|
try {
|
|
1469
2349
|
const { where, set } = args;
|
|
1470
2350
|
const input = remapFromGraphQLSingleInput(set, table);
|
|
1471
2351
|
if (!Object.keys(input).length) {
|
|
1472
|
-
throw new
|
|
2352
|
+
throw new GraphQLError4("Unable to update with no values specified!");
|
|
1473
2353
|
}
|
|
1474
|
-
|
|
2354
|
+
const executor = resolveExecutor(db, context);
|
|
2355
|
+
let query = executor.update(table).set(input);
|
|
1475
2356
|
if (where) {
|
|
1476
|
-
const filters = extractFilters(table, tableName, where);
|
|
2357
|
+
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
1477
2358
|
query = query.where(filters);
|
|
1478
2359
|
}
|
|
1479
2360
|
await query;
|
|
@@ -1485,7 +2366,7 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName) => {
|
|
|
1485
2366
|
args: queryArgs
|
|
1486
2367
|
};
|
|
1487
2368
|
};
|
|
1488
|
-
var generateDelete = (db, tableName, table, filterArgs, fieldName) => {
|
|
2369
|
+
var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) => {
|
|
1489
2370
|
const queryArgs = {
|
|
1490
2371
|
where: {
|
|
1491
2372
|
type: filterArgs
|
|
@@ -1493,12 +2374,13 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName) => {
|
|
|
1493
2374
|
};
|
|
1494
2375
|
return {
|
|
1495
2376
|
name: fieldName,
|
|
1496
|
-
resolver: async (_source, args,
|
|
2377
|
+
resolver: async (_source, args, context, _info) => {
|
|
1497
2378
|
try {
|
|
1498
2379
|
const { where } = args;
|
|
1499
|
-
|
|
2380
|
+
const executor = resolveExecutor(db, context);
|
|
2381
|
+
let query = executor.delete(table);
|
|
1500
2382
|
if (where) {
|
|
1501
|
-
const filters = extractFilters(table, tableName, where);
|
|
2383
|
+
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
1502
2384
|
query = query.where(filters);
|
|
1503
2385
|
}
|
|
1504
2386
|
await query;
|
|
@@ -1511,7 +2393,8 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName) => {
|
|
|
1511
2393
|
};
|
|
1512
2394
|
};
|
|
1513
2395
|
var mysqlPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig);
|
|
1514
|
-
var generateSchemaData = (db, schema, relations,
|
|
2396
|
+
var generateSchemaData = (db, schema, relations, options) => {
|
|
2397
|
+
const { relationsDepthLimit, prefixes, suffixes, typeNameMapper, shouldEagerLoad, features } = options;
|
|
1515
2398
|
const rawSchema = schema;
|
|
1516
2399
|
const schemaEntries = Object.entries(rawSchema);
|
|
1517
2400
|
const tableEntries = schemaEntries.filter(([_key, value]) => is4(value, MySqlTable));
|
|
@@ -1524,7 +2407,8 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
1524
2407
|
const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
|
|
1525
2408
|
attachTargetPrimaryKeys(namedRelations, tables, mysqlPrimaryKeyPropNames);
|
|
1526
2409
|
const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
|
|
1527
|
-
const
|
|
2410
|
+
const filterCtx = { tables, relationMap: namedRelations };
|
|
2411
|
+
const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
|
|
1528
2412
|
const cacheCtx = {
|
|
1529
2413
|
genericFilterCache: /* @__PURE__ */ new Map(),
|
|
1530
2414
|
objectTypeCache: /* @__PURE__ */ new Map(),
|
|
@@ -1532,8 +2416,11 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
1532
2416
|
fullyBuiltTables: /* @__PURE__ */ new Set(),
|
|
1533
2417
|
relationTypeCache: /* @__PURE__ */ new Map(),
|
|
1534
2418
|
orderTypeCache: /* @__PURE__ */ new WeakMap(),
|
|
1535
|
-
filterTypeCache: /* @__PURE__ */ new WeakMap()
|
|
2419
|
+
filterTypeCache: /* @__PURE__ */ new WeakMap(),
|
|
2420
|
+
listRelationFilterCache: /* @__PURE__ */ new Map(),
|
|
2421
|
+
aggregateTypeCache: /* @__PURE__ */ new Map()
|
|
1536
2422
|
};
|
|
2423
|
+
const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
|
|
1537
2424
|
const queries = {};
|
|
1538
2425
|
const mutations = {};
|
|
1539
2426
|
const gqlSchemaTypes = Object.fromEntries(
|
|
@@ -1549,22 +2436,24 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
1549
2436
|
typeNameMapper,
|
|
1550
2437
|
prefixes.insert,
|
|
1551
2438
|
prefixes.update,
|
|
1552
|
-
resolverFactory
|
|
2439
|
+
resolverFactory,
|
|
2440
|
+
relationAggregateFactory
|
|
1553
2441
|
)
|
|
1554
2442
|
])
|
|
1555
2443
|
);
|
|
1556
|
-
const mutationReturnType = new
|
|
2444
|
+
const mutationReturnType = new GraphQLObjectType4({
|
|
1557
2445
|
name: "MutationReturn",
|
|
1558
2446
|
fields: {
|
|
1559
2447
|
isSuccess: {
|
|
1560
|
-
type: new
|
|
2448
|
+
type: new GraphQLNonNull4(GraphQLBoolean3)
|
|
1561
2449
|
}
|
|
1562
2450
|
}
|
|
1563
2451
|
});
|
|
1564
2452
|
const inputs = {};
|
|
1565
|
-
const outputs = {
|
|
1566
|
-
|
|
1567
|
-
|
|
2453
|
+
const outputs = {};
|
|
2454
|
+
if (features.insert || features.upsert || features.update || features.delete) {
|
|
2455
|
+
outputs.MutationReturn = mutationReturnType;
|
|
2456
|
+
}
|
|
1568
2457
|
for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
|
|
1569
2458
|
const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
|
|
1570
2459
|
const { selectSingleOutput, selectArrOutput } = tableTypes.outputs;
|
|
@@ -1572,8 +2461,11 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
1572
2461
|
typeName,
|
|
1573
2462
|
listFieldName,
|
|
1574
2463
|
singleFieldName,
|
|
2464
|
+
aggregateFieldName,
|
|
1575
2465
|
createArrayFieldName,
|
|
1576
2466
|
createSingleFieldName,
|
|
2467
|
+
upsertArrayFieldName,
|
|
2468
|
+
upsertSingleFieldName,
|
|
1577
2469
|
updateFieldName,
|
|
1578
2470
|
deleteFieldName
|
|
1579
2471
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
@@ -1586,7 +2478,9 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
1586
2478
|
tableFilters,
|
|
1587
2479
|
listFieldName,
|
|
1588
2480
|
typeName,
|
|
1589
|
-
typeNameMapper
|
|
2481
|
+
typeNameMapper,
|
|
2482
|
+
filterCtx,
|
|
2483
|
+
features.distinct
|
|
1590
2484
|
);
|
|
1591
2485
|
const selectSingleGenerated = generateSelectSingle(
|
|
1592
2486
|
db,
|
|
@@ -1597,37 +2491,40 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
1597
2491
|
tableFilters,
|
|
1598
2492
|
singleFieldName,
|
|
1599
2493
|
typeName,
|
|
1600
|
-
typeNameMapper
|
|
1601
|
-
|
|
1602
|
-
const insertArrGenerated = generateInsertArray(
|
|
1603
|
-
db,
|
|
1604
|
-
tableName,
|
|
1605
|
-
schema[tableName],
|
|
1606
|
-
insertInput,
|
|
1607
|
-
createArrayFieldName
|
|
1608
|
-
);
|
|
1609
|
-
const insertSingleGenerated = generateInsertSingle(
|
|
1610
|
-
db,
|
|
1611
|
-
tableName,
|
|
1612
|
-
schema[tableName],
|
|
1613
|
-
insertInput,
|
|
1614
|
-
createSingleFieldName
|
|
2494
|
+
typeNameMapper,
|
|
2495
|
+
filterCtx
|
|
1615
2496
|
);
|
|
1616
|
-
const
|
|
2497
|
+
const insertArrGenerated = features.insert ? generateInsertArray(db, tableName, schema[tableName], insertInput, createArrayFieldName) : void 0;
|
|
2498
|
+
const insertSingleGenerated = features.insert ? generateInsertSingle(db, tableName, schema[tableName], insertInput, createSingleFieldName) : void 0;
|
|
2499
|
+
const onConflictInput = features.upsert ? generateOnConflictInput({
|
|
2500
|
+
table: schema[tableName],
|
|
2501
|
+
typeName,
|
|
2502
|
+
uniqueSets: [],
|
|
2503
|
+
tableFilters,
|
|
2504
|
+
withTarget: false
|
|
2505
|
+
}) : void 0;
|
|
2506
|
+
const upsertArrGenerated = onConflictInput ? generateUpsert(db, schema[tableName], insertInput, onConflictInput, upsertArrayFieldName, false) : void 0;
|
|
2507
|
+
const upsertSingleGenerated = onConflictInput ? generateUpsert(db, schema[tableName], insertInput, onConflictInput, upsertSingleFieldName, true) : void 0;
|
|
2508
|
+
const updateGenerated = features.update ? generateUpdate(
|
|
1617
2509
|
db,
|
|
1618
2510
|
tableName,
|
|
1619
2511
|
schema[tableName],
|
|
1620
2512
|
updateInput,
|
|
1621
2513
|
tableFilters,
|
|
1622
|
-
updateFieldName
|
|
1623
|
-
|
|
1624
|
-
|
|
2514
|
+
updateFieldName,
|
|
2515
|
+
filterCtx
|
|
2516
|
+
) : void 0;
|
|
2517
|
+
const deleteGenerated = features.delete ? generateDelete(db, tableName, schema[tableName], tableFilters, deleteFieldName, filterCtx) : void 0;
|
|
2518
|
+
const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
|
|
2519
|
+
const aggregateGenerated = features.aggregates ? generateAggregate(
|
|
1625
2520
|
db,
|
|
1626
2521
|
tableName,
|
|
1627
2522
|
schema[tableName],
|
|
2523
|
+
typeName,
|
|
2524
|
+
aggregateFieldName,
|
|
1628
2525
|
tableFilters,
|
|
1629
|
-
|
|
1630
|
-
);
|
|
2526
|
+
filterCtx
|
|
2527
|
+
) : void 0;
|
|
1631
2528
|
queries[selectArrGenerated.name] = {
|
|
1632
2529
|
type: selectArrOutput,
|
|
1633
2530
|
args: selectArrGenerated.args,
|
|
@@ -1638,30 +2535,44 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
1638
2535
|
args: selectSingleGenerated.args,
|
|
1639
2536
|
resolve: selectSingleGenerated.resolver
|
|
1640
2537
|
};
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
2538
|
+
if (aggregateGenerated && aggregateType) {
|
|
2539
|
+
queries[aggregateGenerated.name] = {
|
|
2540
|
+
type: new GraphQLNonNull4(aggregateType),
|
|
2541
|
+
args: aggregateGenerated.args,
|
|
2542
|
+
resolve: aggregateGenerated.resolver
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
for (const generated of [
|
|
2546
|
+
insertArrGenerated,
|
|
2547
|
+
insertSingleGenerated,
|
|
2548
|
+
upsertArrGenerated,
|
|
2549
|
+
upsertSingleGenerated,
|
|
2550
|
+
updateGenerated,
|
|
2551
|
+
deleteGenerated
|
|
2552
|
+
]) {
|
|
2553
|
+
if (generated) {
|
|
2554
|
+
mutations[generated.name] = {
|
|
2555
|
+
type: mutationReturnType,
|
|
2556
|
+
args: generated.args,
|
|
2557
|
+
resolve: generated.resolver
|
|
2558
|
+
};
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
const activeInputs = [
|
|
2562
|
+
// The insert input types the upsert mutations too, so either feature keeps it.
|
|
2563
|
+
...features.insert || onConflictInput ? [insertInput] : [],
|
|
2564
|
+
...onConflictInput ? [onConflictInput] : [],
|
|
2565
|
+
...features.update ? [updateInput] : [],
|
|
2566
|
+
tableFilters,
|
|
2567
|
+
tableOrder
|
|
2568
|
+
];
|
|
2569
|
+
activeInputs.forEach((e) => {
|
|
1662
2570
|
inputs[e.name] = e;
|
|
1663
2571
|
});
|
|
1664
2572
|
outputs[selectSingleOutput.name] = selectSingleOutput;
|
|
2573
|
+
if (aggregateType) {
|
|
2574
|
+
outputs[aggregateType.name] = aggregateType;
|
|
2575
|
+
}
|
|
1665
2576
|
}
|
|
1666
2577
|
const fieldResolvers = {};
|
|
1667
2578
|
for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
|
|
@@ -1684,23 +2595,29 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
1684
2595
|
import { is as is5, One as One4 } from "drizzle-orm";
|
|
1685
2596
|
import { getTableConfig as getTableConfig2, PgTable } from "drizzle-orm/pg-core";
|
|
1686
2597
|
import {
|
|
1687
|
-
GraphQLError as
|
|
1688
|
-
GraphQLList as
|
|
1689
|
-
GraphQLNonNull as
|
|
2598
|
+
GraphQLError as GraphQLError5,
|
|
2599
|
+
GraphQLList as GraphQLList5,
|
|
2600
|
+
GraphQLNonNull as GraphQLNonNull5
|
|
1690
2601
|
} from "graphql";
|
|
1691
|
-
import { parseResolveInfo as
|
|
1692
|
-
var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
|
|
2602
|
+
import { parseResolveInfo as parseResolveInfo3 } from "graphql-parse-resolve-info";
|
|
2603
|
+
var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
|
|
1693
2604
|
const queryBase = db.query[tableName];
|
|
1694
|
-
const queryArgs = selectArrayArgs(orderArgs, filterArgs);
|
|
1695
2605
|
const table = tables[tableName];
|
|
2606
|
+
const pkNames = pgPrimaryKeyPropNames(table);
|
|
2607
|
+
const queryArgs = selectArrayArgs(
|
|
2608
|
+
orderArgs,
|
|
2609
|
+
filterArgs,
|
|
2610
|
+
distinctEnabled ? generateDistinctEnum(table, typeName) : void 0
|
|
2611
|
+
);
|
|
1696
2612
|
return {
|
|
1697
2613
|
name: fieldName,
|
|
1698
|
-
resolver: async (_source, args,
|
|
2614
|
+
resolver: async (_source, args, context, info) => {
|
|
1699
2615
|
try {
|
|
1700
|
-
const parsedInfo =
|
|
1701
|
-
|
|
2616
|
+
const parsedInfo = parseResolveInfo3(info, { deep: true });
|
|
2617
|
+
const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
|
|
2618
|
+
if (requestQueryBase) {
|
|
1702
2619
|
return await runRelationalSelect({
|
|
1703
|
-
queryBase,
|
|
2620
|
+
queryBase: requestQueryBase,
|
|
1704
2621
|
tables,
|
|
1705
2622
|
tableName,
|
|
1706
2623
|
table,
|
|
@@ -1709,26 +2626,57 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
1709
2626
|
typeNameMapper,
|
|
1710
2627
|
parsedInfo,
|
|
1711
2628
|
...args,
|
|
1712
|
-
single: false
|
|
2629
|
+
single: false,
|
|
2630
|
+
filterCtx,
|
|
2631
|
+
pkNames,
|
|
2632
|
+
db: executor
|
|
1713
2633
|
});
|
|
1714
2634
|
}
|
|
1715
|
-
const { offset, limit, orderBy, where } = args;
|
|
2635
|
+
const { offset, limit, orderBy, where, distinct } = args;
|
|
1716
2636
|
const selectedColumnsSql = extractSelectedColumnsFromTreeSQLFormat(
|
|
1717
2637
|
parsedInfo.fieldsByTypeName[typeName],
|
|
1718
|
-
table
|
|
2638
|
+
table,
|
|
2639
|
+
{ tableName, relationMap, tables }
|
|
1719
2640
|
);
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
2641
|
+
const whereSql = where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0;
|
|
2642
|
+
let distinctKeys;
|
|
2643
|
+
if (distinct?.length) {
|
|
2644
|
+
distinctKeys = await selectDistinctKeys({
|
|
2645
|
+
db: executor,
|
|
2646
|
+
table,
|
|
2647
|
+
tableName,
|
|
2648
|
+
distinct,
|
|
2649
|
+
pkNames,
|
|
2650
|
+
where: whereSql,
|
|
2651
|
+
orderBy,
|
|
2652
|
+
limit,
|
|
2653
|
+
offset
|
|
2654
|
+
});
|
|
2655
|
+
if (!distinctKeys.length) {
|
|
2656
|
+
return [];
|
|
2657
|
+
}
|
|
1723
2658
|
}
|
|
1724
|
-
|
|
1725
|
-
|
|
2659
|
+
let q = executor.select(selectedColumnsSql).from(table);
|
|
2660
|
+
if (distinctKeys) {
|
|
2661
|
+
q = q.where(primaryKeyRestriction(table, pkNames, distinctKeys));
|
|
2662
|
+
} else if (whereSql) {
|
|
2663
|
+
q = q.where(whereSql);
|
|
1726
2664
|
}
|
|
1727
|
-
if (
|
|
1728
|
-
q = q.
|
|
2665
|
+
if (orderBy) {
|
|
2666
|
+
q = q.orderBy(
|
|
2667
|
+
...extractOrderBy(table, orderBy),
|
|
2668
|
+
...distinctKeys ? primaryKeyOrderExprs(table, pkNames) : []
|
|
2669
|
+
);
|
|
2670
|
+
} else if ((distinctKeys || offset != null || limit != null) && pkNames.length) {
|
|
2671
|
+
q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
|
|
1729
2672
|
}
|
|
1730
|
-
if (
|
|
1731
|
-
|
|
2673
|
+
if (!distinctKeys) {
|
|
2674
|
+
if (offset) {
|
|
2675
|
+
q = q.offset(offset);
|
|
2676
|
+
}
|
|
2677
|
+
if (limit) {
|
|
2678
|
+
q = q.limit(limit);
|
|
2679
|
+
}
|
|
1732
2680
|
}
|
|
1733
2681
|
return remapToGraphQLArrayOutput(await q, tableName, table, relationMap);
|
|
1734
2682
|
} catch (e) {
|
|
@@ -1738,18 +2686,20 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
1738
2686
|
args: queryArgs
|
|
1739
2687
|
};
|
|
1740
2688
|
};
|
|
1741
|
-
var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
|
|
2689
|
+
var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
1742
2690
|
const queryBase = db.query[tableName];
|
|
1743
2691
|
const queryArgs = selectSingleArgs(orderArgs, filterArgs);
|
|
1744
2692
|
const table = tables[tableName];
|
|
2693
|
+
const pkNames = pgPrimaryKeyPropNames(table);
|
|
1745
2694
|
return {
|
|
1746
2695
|
name: fieldName,
|
|
1747
|
-
resolver: async (_source, args,
|
|
2696
|
+
resolver: async (_source, args, context, info) => {
|
|
1748
2697
|
try {
|
|
1749
|
-
const parsedInfo =
|
|
1750
|
-
|
|
2698
|
+
const parsedInfo = parseResolveInfo3(info, { deep: true });
|
|
2699
|
+
const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
|
|
2700
|
+
if (requestQueryBase) {
|
|
1751
2701
|
return await runRelationalSelect({
|
|
1752
|
-
queryBase,
|
|
2702
|
+
queryBase: requestQueryBase,
|
|
1753
2703
|
tables,
|
|
1754
2704
|
tableName,
|
|
1755
2705
|
table,
|
|
@@ -1758,20 +2708,26 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
|
|
|
1758
2708
|
typeNameMapper,
|
|
1759
2709
|
parsedInfo,
|
|
1760
2710
|
...args,
|
|
1761
|
-
single: true
|
|
2711
|
+
single: true,
|
|
2712
|
+
filterCtx,
|
|
2713
|
+
pkNames,
|
|
2714
|
+
db: executor
|
|
1762
2715
|
});
|
|
1763
2716
|
}
|
|
1764
2717
|
const { offset, orderBy, where } = args;
|
|
1765
2718
|
const selectedColumnsSql = extractSelectedColumnsFromTreeSQLFormat(
|
|
1766
2719
|
parsedInfo.fieldsByTypeName[typeName],
|
|
1767
|
-
table
|
|
2720
|
+
table,
|
|
2721
|
+
{ tableName, relationMap, tables }
|
|
1768
2722
|
);
|
|
1769
|
-
let q =
|
|
2723
|
+
let q = executor.select(selectedColumnsSql).from(table);
|
|
1770
2724
|
if (where) {
|
|
1771
|
-
q = q.where(extractFilters(table, tableName, where));
|
|
2725
|
+
q = q.where(extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)));
|
|
1772
2726
|
}
|
|
1773
2727
|
if (orderBy) {
|
|
1774
2728
|
q = q.orderBy(...extractOrderBy(table, orderBy));
|
|
2729
|
+
} else if (pkNames.length) {
|
|
2730
|
+
q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
|
|
1775
2731
|
}
|
|
1776
2732
|
if (offset) {
|
|
1777
2733
|
q = q.offset(offset);
|
|
@@ -1790,19 +2746,19 @@ var pgPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, g
|
|
|
1790
2746
|
var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
|
|
1791
2747
|
const queryArgs = {
|
|
1792
2748
|
values: {
|
|
1793
|
-
type: new
|
|
2749
|
+
type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
|
|
1794
2750
|
}
|
|
1795
2751
|
};
|
|
1796
2752
|
const pkNames = pgPrimaryKeyPropNames(table);
|
|
1797
2753
|
return {
|
|
1798
2754
|
name: fieldName,
|
|
1799
|
-
resolver: async (_source, args,
|
|
2755
|
+
resolver: async (_source, args, context, info) => {
|
|
1800
2756
|
try {
|
|
1801
2757
|
const input = remapFromGraphQLArrayInput(args.values, table);
|
|
1802
2758
|
if (!input.length) {
|
|
1803
|
-
throw new
|
|
2759
|
+
throw new GraphQLError5("No values were provided!");
|
|
1804
2760
|
}
|
|
1805
|
-
const parsedInfo =
|
|
2761
|
+
const parsedInfo = parseResolveInfo3(info, {
|
|
1806
2762
|
deep: true
|
|
1807
2763
|
});
|
|
1808
2764
|
const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
|
|
@@ -1815,12 +2771,13 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
|
|
|
1815
2771
|
pkNames,
|
|
1816
2772
|
parsedInfo
|
|
1817
2773
|
});
|
|
1818
|
-
|
|
2774
|
+
const executor = resolveExecutor(db, context);
|
|
2775
|
+
let query = executor.insert(table).values(input).returning(columns);
|
|
1819
2776
|
if (conflictDoNothing) {
|
|
1820
2777
|
query = query.onConflictDoNothing();
|
|
1821
2778
|
}
|
|
1822
2779
|
const result = await query;
|
|
1823
|
-
const enriched = hasRelations ? await eagerLoadMutationRelations(
|
|
2780
|
+
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
1824
2781
|
return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
1825
2782
|
} catch (e) {
|
|
1826
2783
|
throw toGraphQLError(e);
|
|
@@ -1832,16 +2789,16 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
|
|
|
1832
2789
|
var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
|
|
1833
2790
|
const queryArgs = {
|
|
1834
2791
|
values: {
|
|
1835
|
-
type: new
|
|
2792
|
+
type: new GraphQLNonNull5(baseType)
|
|
1836
2793
|
}
|
|
1837
2794
|
};
|
|
1838
2795
|
const pkNames = pgPrimaryKeyPropNames(table);
|
|
1839
2796
|
return {
|
|
1840
2797
|
name: fieldName,
|
|
1841
|
-
resolver: async (_source, args,
|
|
2798
|
+
resolver: async (_source, args, context, info) => {
|
|
1842
2799
|
try {
|
|
1843
2800
|
const input = remapFromGraphQLSingleInput(args.values, table);
|
|
1844
|
-
const parsedInfo =
|
|
2801
|
+
const parsedInfo = parseResolveInfo3(info, {
|
|
1845
2802
|
deep: true
|
|
1846
2803
|
});
|
|
1847
2804
|
const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
|
|
@@ -1854,7 +2811,8 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
|
|
|
1854
2811
|
pkNames,
|
|
1855
2812
|
parsedInfo
|
|
1856
2813
|
});
|
|
1857
|
-
|
|
2814
|
+
const executor = resolveExecutor(db, context);
|
|
2815
|
+
let query = executor.insert(table).values(input).returning(columns);
|
|
1858
2816
|
if (conflictDoNothing) {
|
|
1859
2817
|
query = query.onConflictDoNothing();
|
|
1860
2818
|
}
|
|
@@ -1862,7 +2820,7 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
|
|
|
1862
2820
|
if (!result[0]) {
|
|
1863
2821
|
return void 0;
|
|
1864
2822
|
}
|
|
1865
|
-
const enriched = hasRelations ? await eagerLoadMutationRelations(
|
|
2823
|
+
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
1866
2824
|
return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
|
|
1867
2825
|
} catch (e) {
|
|
1868
2826
|
throw toGraphQLError(e);
|
|
@@ -1871,10 +2829,66 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
|
|
|
1871
2829
|
args: queryArgs
|
|
1872
2830
|
};
|
|
1873
2831
|
};
|
|
1874
|
-
var
|
|
2832
|
+
var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx) => {
|
|
2833
|
+
const queryArgs = {
|
|
2834
|
+
values: {
|
|
2835
|
+
type: single ? new GraphQLNonNull5(baseType) : new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
|
|
2836
|
+
},
|
|
2837
|
+
onConflict: {
|
|
2838
|
+
type: onConflictType,
|
|
2839
|
+
description: "How a conflicting row is resolved. Defaults to overwriting it on the primary key."
|
|
2840
|
+
}
|
|
2841
|
+
};
|
|
2842
|
+
const pkNames = pgPrimaryKeyPropNames(table);
|
|
2843
|
+
return {
|
|
2844
|
+
name: fieldName,
|
|
2845
|
+
resolver: async (_source, args, context, info) => {
|
|
2846
|
+
try {
|
|
2847
|
+
const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
|
|
2848
|
+
if (!input.length) {
|
|
2849
|
+
throw new GraphQLError5("No values were provided!");
|
|
2850
|
+
}
|
|
2851
|
+
const parsedInfo = parseResolveInfo3(info, { deep: true });
|
|
2852
|
+
const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
|
|
2853
|
+
relationMap,
|
|
2854
|
+
tables,
|
|
2855
|
+
tableName,
|
|
2856
|
+
typeName,
|
|
2857
|
+
typeNameMapper,
|
|
2858
|
+
table,
|
|
2859
|
+
pkNames,
|
|
2860
|
+
parsedInfo
|
|
2861
|
+
});
|
|
2862
|
+
const plan = resolveConflictPlan({
|
|
2863
|
+
table,
|
|
2864
|
+
values: input,
|
|
2865
|
+
onConflict: args.onConflict,
|
|
2866
|
+
pkNames,
|
|
2867
|
+
uniqueSets,
|
|
2868
|
+
excludedRef: excludedColumnRef,
|
|
2869
|
+
withTarget: true,
|
|
2870
|
+
buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
|
|
2871
|
+
});
|
|
2872
|
+
const executor = resolveExecutor(db, context);
|
|
2873
|
+
let query = executor.insert(table).values(input).returning(columns);
|
|
2874
|
+
query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
|
|
2875
|
+
const result = await query;
|
|
2876
|
+
if (single && !result[0]) {
|
|
2877
|
+
return void 0;
|
|
2878
|
+
}
|
|
2879
|
+
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
2880
|
+
return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
2881
|
+
} catch (e) {
|
|
2882
|
+
throw toGraphQLError(e);
|
|
2883
|
+
}
|
|
2884
|
+
},
|
|
2885
|
+
args: queryArgs
|
|
2886
|
+
};
|
|
2887
|
+
};
|
|
2888
|
+
var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
1875
2889
|
const queryArgs = {
|
|
1876
2890
|
set: {
|
|
1877
|
-
type: new
|
|
2891
|
+
type: new GraphQLNonNull5(setArgs)
|
|
1878
2892
|
},
|
|
1879
2893
|
where: {
|
|
1880
2894
|
type: filterArgs
|
|
@@ -1883,10 +2897,10 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
1883
2897
|
const pkNames = pgPrimaryKeyPropNames(table);
|
|
1884
2898
|
return {
|
|
1885
2899
|
name: fieldName,
|
|
1886
|
-
resolver: async (_source, args,
|
|
2900
|
+
resolver: async (_source, args, context, info) => {
|
|
1887
2901
|
try {
|
|
1888
2902
|
const { where, set } = args;
|
|
1889
|
-
const parsedInfo =
|
|
2903
|
+
const parsedInfo = parseResolveInfo3(info, {
|
|
1890
2904
|
deep: true
|
|
1891
2905
|
});
|
|
1892
2906
|
const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
|
|
@@ -1901,16 +2915,17 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
1901
2915
|
});
|
|
1902
2916
|
const input = remapFromGraphQLSingleInput(set, table);
|
|
1903
2917
|
if (!Object.keys(input).length) {
|
|
1904
|
-
throw new
|
|
2918
|
+
throw new GraphQLError5("Unable to update with no values specified!");
|
|
1905
2919
|
}
|
|
1906
|
-
|
|
2920
|
+
const executor = resolveExecutor(db, context);
|
|
2921
|
+
let query = executor.update(table).set(input);
|
|
1907
2922
|
if (where) {
|
|
1908
|
-
const filters = extractFilters(table, tableName, where);
|
|
2923
|
+
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
1909
2924
|
query = query.where(filters);
|
|
1910
2925
|
}
|
|
1911
2926
|
query = query.returning(columns);
|
|
1912
2927
|
const result = await query;
|
|
1913
|
-
const enriched = hasRelations ? await eagerLoadMutationRelations(
|
|
2928
|
+
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
1914
2929
|
return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
1915
2930
|
} catch (e) {
|
|
1916
2931
|
throw toGraphQLError(e);
|
|
@@ -1919,7 +2934,7 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
1919
2934
|
args: queryArgs
|
|
1920
2935
|
};
|
|
1921
2936
|
};
|
|
1922
|
-
var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName) => {
|
|
2937
|
+
var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
|
|
1923
2938
|
const queryArgs = {
|
|
1924
2939
|
where: {
|
|
1925
2940
|
type: filterArgs
|
|
@@ -1927,19 +2942,21 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName) =>
|
|
|
1927
2942
|
};
|
|
1928
2943
|
return {
|
|
1929
2944
|
name: fieldName,
|
|
1930
|
-
resolver: async (_source, args,
|
|
2945
|
+
resolver: async (_source, args, context, info) => {
|
|
1931
2946
|
try {
|
|
1932
2947
|
const { where } = args;
|
|
1933
|
-
const parsedInfo =
|
|
2948
|
+
const parsedInfo = parseResolveInfo3(info, {
|
|
1934
2949
|
deep: true
|
|
1935
2950
|
});
|
|
1936
2951
|
const columns = extractSelectedColumnsFromTreeSQLFormat(
|
|
1937
2952
|
parsedInfo.fieldsByTypeName[typeName],
|
|
1938
|
-
table
|
|
2953
|
+
table,
|
|
2954
|
+
selectionCtx
|
|
1939
2955
|
);
|
|
1940
|
-
|
|
2956
|
+
const executor = resolveExecutor(db, context);
|
|
2957
|
+
let query = executor.delete(table);
|
|
1941
2958
|
if (where) {
|
|
1942
|
-
const filters = extractFilters(table, tableName, where);
|
|
2959
|
+
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
1943
2960
|
query = query.where(filters);
|
|
1944
2961
|
}
|
|
1945
2962
|
query = query.returning(columns);
|
|
@@ -1952,7 +2969,8 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName) =>
|
|
|
1952
2969
|
args: queryArgs
|
|
1953
2970
|
};
|
|
1954
2971
|
};
|
|
1955
|
-
function generateSchemaData2(db, schema, relations,
|
|
2972
|
+
function generateSchemaData2(db, schema, relations, options) {
|
|
2973
|
+
const { relationsDepthLimit, prefixes, suffixes, conflictDoNothing, typeNameMapper, shouldEagerLoad, features } = options;
|
|
1956
2974
|
const schemaEntries = Object.entries(schema);
|
|
1957
2975
|
const tableEntries = schemaEntries.filter(([_key, value]) => is5(value, PgTable));
|
|
1958
2976
|
const tables = Object.fromEntries(tableEntries);
|
|
@@ -1964,7 +2982,8 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
1964
2982
|
const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
|
|
1965
2983
|
attachTargetPrimaryKeys(namedRelations, tables, pgPrimaryKeyPropNames);
|
|
1966
2984
|
const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
|
|
1967
|
-
const
|
|
2985
|
+
const filterCtx = { tables, relationMap: namedRelations };
|
|
2986
|
+
const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
|
|
1968
2987
|
const cacheCtx = {
|
|
1969
2988
|
genericFilterCache: /* @__PURE__ */ new Map(),
|
|
1970
2989
|
objectTypeCache: /* @__PURE__ */ new Map(),
|
|
@@ -1972,8 +2991,11 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
1972
2991
|
fullyBuiltTables: /* @__PURE__ */ new Set(),
|
|
1973
2992
|
relationTypeCache: /* @__PURE__ */ new Map(),
|
|
1974
2993
|
orderTypeCache: /* @__PURE__ */ new WeakMap(),
|
|
1975
|
-
filterTypeCache: /* @__PURE__ */ new WeakMap()
|
|
2994
|
+
filterTypeCache: /* @__PURE__ */ new WeakMap(),
|
|
2995
|
+
listRelationFilterCache: /* @__PURE__ */ new Map(),
|
|
2996
|
+
aggregateTypeCache: /* @__PURE__ */ new Map()
|
|
1976
2997
|
};
|
|
2998
|
+
const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
|
|
1977
2999
|
const queries = {};
|
|
1978
3000
|
const mutations = {};
|
|
1979
3001
|
const gqlSchemaTypes = Object.fromEntries(
|
|
@@ -1989,7 +3011,8 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
1989
3011
|
typeNameMapper,
|
|
1990
3012
|
prefixes.insert,
|
|
1991
3013
|
prefixes.update,
|
|
1992
|
-
resolverFactory
|
|
3014
|
+
resolverFactory,
|
|
3015
|
+
relationAggregateFactory
|
|
1993
3016
|
)
|
|
1994
3017
|
])
|
|
1995
3018
|
);
|
|
@@ -2002,8 +3025,11 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
2002
3025
|
typeName,
|
|
2003
3026
|
listFieldName,
|
|
2004
3027
|
singleFieldName,
|
|
3028
|
+
aggregateFieldName,
|
|
2005
3029
|
createArrayFieldName,
|
|
2006
3030
|
createSingleFieldName,
|
|
3031
|
+
upsertArrayFieldName,
|
|
3032
|
+
upsertSingleFieldName,
|
|
2007
3033
|
updateFieldName,
|
|
2008
3034
|
deleteFieldName
|
|
2009
3035
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
@@ -2016,7 +3042,9 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
2016
3042
|
tableFilters,
|
|
2017
3043
|
listFieldName,
|
|
2018
3044
|
typeName,
|
|
2019
|
-
typeNameMapper
|
|
3045
|
+
typeNameMapper,
|
|
3046
|
+
filterCtx,
|
|
3047
|
+
features.distinct
|
|
2020
3048
|
);
|
|
2021
3049
|
const selectSingleGenerated = generateSelectSingle2(
|
|
2022
3050
|
db,
|
|
@@ -2027,9 +3055,10 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
2027
3055
|
tableFilters,
|
|
2028
3056
|
singleFieldName,
|
|
2029
3057
|
typeName,
|
|
2030
|
-
typeNameMapper
|
|
3058
|
+
typeNameMapper,
|
|
3059
|
+
filterCtx
|
|
2031
3060
|
);
|
|
2032
|
-
const insertArrGenerated = generateInsertArray2(
|
|
3061
|
+
const insertArrGenerated = features.insert ? generateInsertArray2(
|
|
2033
3062
|
db,
|
|
2034
3063
|
tableName,
|
|
2035
3064
|
schema[tableName],
|
|
@@ -2040,8 +3069,8 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
2040
3069
|
typeName,
|
|
2041
3070
|
typeNameMapper,
|
|
2042
3071
|
conflictDoNothing
|
|
2043
|
-
);
|
|
2044
|
-
const insertSingleGenerated = generateInsertSingle2(
|
|
3072
|
+
) : void 0;
|
|
3073
|
+
const insertSingleGenerated = features.insert ? generateInsertSingle2(
|
|
2045
3074
|
db,
|
|
2046
3075
|
tableName,
|
|
2047
3076
|
schema[tableName],
|
|
@@ -2052,8 +3081,46 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
2052
3081
|
typeName,
|
|
2053
3082
|
typeNameMapper,
|
|
2054
3083
|
conflictDoNothing
|
|
2055
|
-
);
|
|
2056
|
-
const
|
|
3084
|
+
) : void 0;
|
|
3085
|
+
const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], getTableConfig2) : [];
|
|
3086
|
+
const onConflictInput = features.upsert ? generateOnConflictInput({
|
|
3087
|
+
table: schema[tableName],
|
|
3088
|
+
typeName,
|
|
3089
|
+
uniqueSets,
|
|
3090
|
+
tableFilters,
|
|
3091
|
+
withTarget: true
|
|
3092
|
+
}) : void 0;
|
|
3093
|
+
const upsertArrGenerated = onConflictInput ? generateUpsert2(
|
|
3094
|
+
db,
|
|
3095
|
+
tableName,
|
|
3096
|
+
schema[tableName],
|
|
3097
|
+
tables,
|
|
3098
|
+
eagerRelations,
|
|
3099
|
+
insertInput,
|
|
3100
|
+
onConflictInput,
|
|
3101
|
+
uniqueSets,
|
|
3102
|
+
upsertArrayFieldName,
|
|
3103
|
+
typeName,
|
|
3104
|
+
false,
|
|
3105
|
+
typeNameMapper,
|
|
3106
|
+
filterCtx
|
|
3107
|
+
) : void 0;
|
|
3108
|
+
const upsertSingleGenerated = onConflictInput ? generateUpsert2(
|
|
3109
|
+
db,
|
|
3110
|
+
tableName,
|
|
3111
|
+
schema[tableName],
|
|
3112
|
+
tables,
|
|
3113
|
+
eagerRelations,
|
|
3114
|
+
insertInput,
|
|
3115
|
+
onConflictInput,
|
|
3116
|
+
uniqueSets,
|
|
3117
|
+
upsertSingleFieldName,
|
|
3118
|
+
typeName,
|
|
3119
|
+
true,
|
|
3120
|
+
typeNameMapper,
|
|
3121
|
+
filterCtx
|
|
3122
|
+
) : void 0;
|
|
3123
|
+
const updateGenerated = features.update ? generateUpdate2(
|
|
2057
3124
|
db,
|
|
2058
3125
|
tableName,
|
|
2059
3126
|
schema[tableName],
|
|
@@ -2063,16 +3130,29 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
2063
3130
|
tableFilters,
|
|
2064
3131
|
updateFieldName,
|
|
2065
3132
|
typeName,
|
|
2066
|
-
typeNameMapper
|
|
2067
|
-
|
|
2068
|
-
|
|
3133
|
+
typeNameMapper,
|
|
3134
|
+
filterCtx
|
|
3135
|
+
) : void 0;
|
|
3136
|
+
const deleteGenerated = features.delete ? generateDelete2(
|
|
2069
3137
|
db,
|
|
2070
3138
|
tableName,
|
|
2071
3139
|
schema[tableName],
|
|
2072
3140
|
tableFilters,
|
|
2073
3141
|
deleteFieldName,
|
|
2074
|
-
typeName
|
|
2075
|
-
|
|
3142
|
+
typeName,
|
|
3143
|
+
filterCtx,
|
|
3144
|
+
{ tableName, relationMap: namedRelations, tables }
|
|
3145
|
+
) : void 0;
|
|
3146
|
+
const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
|
|
3147
|
+
const aggregateGenerated = features.aggregates ? generateAggregate(
|
|
3148
|
+
db,
|
|
3149
|
+
tableName,
|
|
3150
|
+
schema[tableName],
|
|
3151
|
+
typeName,
|
|
3152
|
+
aggregateFieldName,
|
|
3153
|
+
tableFilters,
|
|
3154
|
+
filterCtx
|
|
3155
|
+
) : void 0;
|
|
2076
3156
|
queries[selectArrGenerated.name] = {
|
|
2077
3157
|
type: selectArrOutput,
|
|
2078
3158
|
args: selectArrGenerated.args,
|
|
@@ -2083,31 +3163,71 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
2083
3163
|
args: selectSingleGenerated.args,
|
|
2084
3164
|
resolve: selectSingleGenerated.resolver
|
|
2085
3165
|
};
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
3166
|
+
if (aggregateGenerated && aggregateType) {
|
|
3167
|
+
queries[aggregateGenerated.name] = {
|
|
3168
|
+
type: new GraphQLNonNull5(aggregateType),
|
|
3169
|
+
args: aggregateGenerated.args,
|
|
3170
|
+
resolve: aggregateGenerated.resolver
|
|
3171
|
+
};
|
|
3172
|
+
}
|
|
3173
|
+
if (insertArrGenerated) {
|
|
3174
|
+
mutations[insertArrGenerated.name] = {
|
|
3175
|
+
type: arrTableItemOutput,
|
|
3176
|
+
args: insertArrGenerated.args,
|
|
3177
|
+
resolve: insertArrGenerated.resolver
|
|
3178
|
+
};
|
|
3179
|
+
}
|
|
3180
|
+
if (insertSingleGenerated) {
|
|
3181
|
+
mutations[insertSingleGenerated.name] = {
|
|
3182
|
+
type: singleTableItemOutput,
|
|
3183
|
+
args: insertSingleGenerated.args,
|
|
3184
|
+
resolve: insertSingleGenerated.resolver
|
|
3185
|
+
};
|
|
3186
|
+
}
|
|
3187
|
+
if (upsertArrGenerated) {
|
|
3188
|
+
mutations[upsertArrGenerated.name] = {
|
|
3189
|
+
type: arrTableItemOutput,
|
|
3190
|
+
args: upsertArrGenerated.args,
|
|
3191
|
+
resolve: upsertArrGenerated.resolver
|
|
3192
|
+
};
|
|
3193
|
+
}
|
|
3194
|
+
if (upsertSingleGenerated) {
|
|
3195
|
+
mutations[upsertSingleGenerated.name] = {
|
|
3196
|
+
type: singleTableItemOutput,
|
|
3197
|
+
args: upsertSingleGenerated.args,
|
|
3198
|
+
resolve: upsertSingleGenerated.resolver
|
|
3199
|
+
};
|
|
3200
|
+
}
|
|
3201
|
+
if (updateGenerated) {
|
|
3202
|
+
mutations[updateGenerated.name] = {
|
|
3203
|
+
type: arrTableItemOutput,
|
|
3204
|
+
args: updateGenerated.args,
|
|
3205
|
+
resolve: updateGenerated.resolver
|
|
3206
|
+
};
|
|
3207
|
+
}
|
|
3208
|
+
if (deleteGenerated) {
|
|
3209
|
+
mutations[deleteGenerated.name] = {
|
|
3210
|
+
type: arrTableItemOutput,
|
|
3211
|
+
args: deleteGenerated.args,
|
|
3212
|
+
resolve: deleteGenerated.resolver
|
|
3213
|
+
};
|
|
3214
|
+
}
|
|
3215
|
+
const activeInputs = [
|
|
3216
|
+
// The insert input types the upsert mutations too, so either feature keeps it.
|
|
3217
|
+
...features.insert || onConflictInput ? [insertInput] : [],
|
|
3218
|
+
...onConflictInput ? [onConflictInput] : [],
|
|
3219
|
+
...features.update ? [updateInput] : [],
|
|
3220
|
+
tableFilters,
|
|
3221
|
+
tableOrder
|
|
3222
|
+
];
|
|
3223
|
+
activeInputs.forEach((e) => {
|
|
2107
3224
|
inputs[e.name] = e;
|
|
2108
3225
|
});
|
|
2109
3226
|
outputs[selectSingleOutput.name] = selectSingleOutput;
|
|
2110
3227
|
outputs[singleTableItemOutput.name] = singleTableItemOutput;
|
|
3228
|
+
if (aggregateType) {
|
|
3229
|
+
outputs[aggregateType.name] = aggregateType;
|
|
3230
|
+
}
|
|
2111
3231
|
}
|
|
2112
3232
|
const fieldResolvers = {};
|
|
2113
3233
|
for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
|
|
@@ -2130,27 +3250,33 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
|
|
|
2130
3250
|
import { is as is6, One as One5 } from "drizzle-orm";
|
|
2131
3251
|
import { getTableConfig as getTableConfig3, SQLiteTable } from "drizzle-orm/sqlite-core";
|
|
2132
3252
|
import {
|
|
2133
|
-
GraphQLError as
|
|
2134
|
-
GraphQLList as
|
|
2135
|
-
GraphQLNonNull as
|
|
3253
|
+
GraphQLError as GraphQLError6,
|
|
3254
|
+
GraphQLList as GraphQLList6,
|
|
3255
|
+
GraphQLNonNull as GraphQLNonNull6
|
|
2136
3256
|
} from "graphql";
|
|
2137
|
-
import { parseResolveInfo as
|
|
2138
|
-
var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
|
|
3257
|
+
import { parseResolveInfo as parseResolveInfo4 } from "graphql-parse-resolve-info";
|
|
3258
|
+
var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
|
|
2139
3259
|
const queryBase = db.query[tableName];
|
|
2140
3260
|
if (!queryBase) {
|
|
2141
3261
|
throw new Error(
|
|
2142
3262
|
`Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
|
|
2143
3263
|
);
|
|
2144
3264
|
}
|
|
2145
|
-
const queryArgs = selectArrayArgs(orderArgs, filterArgs);
|
|
2146
3265
|
const table = tables[tableName];
|
|
3266
|
+
const pkNames = sqlitePrimaryKeyPropNames(table);
|
|
3267
|
+
const queryArgs = selectArrayArgs(
|
|
3268
|
+
orderArgs,
|
|
3269
|
+
filterArgs,
|
|
3270
|
+
distinctEnabled ? generateDistinctEnum(table, typeName) : void 0
|
|
3271
|
+
);
|
|
2147
3272
|
return {
|
|
2148
3273
|
name: fieldName,
|
|
2149
|
-
resolver: async (_source, args,
|
|
3274
|
+
resolver: async (_source, args, context, info) => {
|
|
2150
3275
|
try {
|
|
2151
|
-
const parsedInfo =
|
|
3276
|
+
const parsedInfo = parseResolveInfo4(info, { deep: true });
|
|
3277
|
+
const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
|
|
2152
3278
|
return await runRelationalSelect({
|
|
2153
|
-
queryBase,
|
|
3279
|
+
queryBase: requestQueryBase,
|
|
2154
3280
|
tables,
|
|
2155
3281
|
tableName,
|
|
2156
3282
|
table,
|
|
@@ -2159,7 +3285,10 @@ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
2159
3285
|
typeNameMapper,
|
|
2160
3286
|
parsedInfo,
|
|
2161
3287
|
...args,
|
|
2162
|
-
single: false
|
|
3288
|
+
single: false,
|
|
3289
|
+
filterCtx,
|
|
3290
|
+
pkNames,
|
|
3291
|
+
db: executor
|
|
2163
3292
|
});
|
|
2164
3293
|
} catch (e) {
|
|
2165
3294
|
throw toGraphQLError(e);
|
|
@@ -2168,7 +3297,7 @@ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
2168
3297
|
args: queryArgs
|
|
2169
3298
|
};
|
|
2170
3299
|
};
|
|
2171
|
-
var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
|
|
3300
|
+
var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
2172
3301
|
const queryBase = db.query[tableName];
|
|
2173
3302
|
if (!queryBase) {
|
|
2174
3303
|
throw new Error(
|
|
@@ -2177,13 +3306,15 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
|
|
|
2177
3306
|
}
|
|
2178
3307
|
const queryArgs = selectSingleArgs(orderArgs, filterArgs);
|
|
2179
3308
|
const table = tables[tableName];
|
|
3309
|
+
const pkNames = sqlitePrimaryKeyPropNames(table);
|
|
2180
3310
|
return {
|
|
2181
3311
|
name: fieldName,
|
|
2182
|
-
resolver: async (_source, args,
|
|
3312
|
+
resolver: async (_source, args, context, info) => {
|
|
2183
3313
|
try {
|
|
2184
|
-
const parsedInfo =
|
|
3314
|
+
const parsedInfo = parseResolveInfo4(info, { deep: true });
|
|
3315
|
+
const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
|
|
2185
3316
|
return await runRelationalSelect({
|
|
2186
|
-
queryBase,
|
|
3317
|
+
queryBase: requestQueryBase,
|
|
2187
3318
|
tables,
|
|
2188
3319
|
tableName,
|
|
2189
3320
|
table,
|
|
@@ -2192,7 +3323,10 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
|
|
|
2192
3323
|
typeNameMapper,
|
|
2193
3324
|
parsedInfo,
|
|
2194
3325
|
...args,
|
|
2195
|
-
single: true
|
|
3326
|
+
single: true,
|
|
3327
|
+
filterCtx,
|
|
3328
|
+
pkNames,
|
|
3329
|
+
db: executor
|
|
2196
3330
|
});
|
|
2197
3331
|
} catch (e) {
|
|
2198
3332
|
throw toGraphQLError(e);
|
|
@@ -2202,22 +3336,22 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
|
|
|
2202
3336
|
};
|
|
2203
3337
|
};
|
|
2204
3338
|
var sqlitePrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig3);
|
|
2205
|
-
var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper) => {
|
|
3339
|
+
var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
|
|
2206
3340
|
const queryArgs = {
|
|
2207
3341
|
values: {
|
|
2208
|
-
type: new
|
|
3342
|
+
type: new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(baseType)))
|
|
2209
3343
|
}
|
|
2210
3344
|
};
|
|
2211
3345
|
const pkNames = sqlitePrimaryKeyPropNames(table);
|
|
2212
3346
|
return {
|
|
2213
3347
|
name: fieldName,
|
|
2214
|
-
resolver: async (_source, args,
|
|
3348
|
+
resolver: async (_source, args, context, info) => {
|
|
2215
3349
|
try {
|
|
2216
3350
|
const input = remapFromGraphQLArrayInput(args.values, table);
|
|
2217
3351
|
if (!input.length) {
|
|
2218
|
-
throw new
|
|
3352
|
+
throw new GraphQLError6("No values were provided!");
|
|
2219
3353
|
}
|
|
2220
|
-
const parsedInfo =
|
|
3354
|
+
const parsedInfo = parseResolveInfo4(info, {
|
|
2221
3355
|
deep: true
|
|
2222
3356
|
});
|
|
2223
3357
|
const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
|
|
@@ -2230,8 +3364,13 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
|
|
|
2230
3364
|
pkNames,
|
|
2231
3365
|
parsedInfo
|
|
2232
3366
|
});
|
|
2233
|
-
const
|
|
2234
|
-
|
|
3367
|
+
const executor = resolveExecutor(db, context);
|
|
3368
|
+
let query = executor.insert(table).values(input).returning(columns);
|
|
3369
|
+
if (conflictDoNothing) {
|
|
3370
|
+
query = query.onConflictDoNothing();
|
|
3371
|
+
}
|
|
3372
|
+
const result = await query;
|
|
3373
|
+
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
2235
3374
|
return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
2236
3375
|
} catch (e) {
|
|
2237
3376
|
throw toGraphQLError(e);
|
|
@@ -2240,19 +3379,19 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
|
|
|
2240
3379
|
args: queryArgs
|
|
2241
3380
|
};
|
|
2242
3381
|
};
|
|
2243
|
-
var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper) => {
|
|
3382
|
+
var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
|
|
2244
3383
|
const queryArgs = {
|
|
2245
3384
|
values: {
|
|
2246
|
-
type: new
|
|
3385
|
+
type: new GraphQLNonNull6(baseType)
|
|
2247
3386
|
}
|
|
2248
3387
|
};
|
|
2249
3388
|
const pkNames = sqlitePrimaryKeyPropNames(table);
|
|
2250
3389
|
return {
|
|
2251
3390
|
name: fieldName,
|
|
2252
|
-
resolver: async (_source, args,
|
|
3391
|
+
resolver: async (_source, args, context, info) => {
|
|
2253
3392
|
try {
|
|
2254
3393
|
const input = remapFromGraphQLSingleInput(args.values, table);
|
|
2255
|
-
const parsedInfo =
|
|
3394
|
+
const parsedInfo = parseResolveInfo4(info, {
|
|
2256
3395
|
deep: true
|
|
2257
3396
|
});
|
|
2258
3397
|
const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
|
|
@@ -2265,11 +3404,16 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
|
|
|
2265
3404
|
pkNames,
|
|
2266
3405
|
parsedInfo
|
|
2267
3406
|
});
|
|
2268
|
-
const
|
|
3407
|
+
const executor = resolveExecutor(db, context);
|
|
3408
|
+
let query = executor.insert(table).values(input).returning(columns);
|
|
3409
|
+
if (conflictDoNothing) {
|
|
3410
|
+
query = query.onConflictDoNothing();
|
|
3411
|
+
}
|
|
3412
|
+
const result = await query;
|
|
2269
3413
|
if (!result[0]) {
|
|
2270
3414
|
return void 0;
|
|
2271
3415
|
}
|
|
2272
|
-
const enriched = hasRelations ? await eagerLoadMutationRelations(
|
|
3416
|
+
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
2273
3417
|
return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
|
|
2274
3418
|
} catch (e) {
|
|
2275
3419
|
throw toGraphQLError(e);
|
|
@@ -2278,10 +3422,66 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
|
|
|
2278
3422
|
args: queryArgs
|
|
2279
3423
|
};
|
|
2280
3424
|
};
|
|
2281
|
-
var
|
|
3425
|
+
var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx) => {
|
|
3426
|
+
const queryArgs = {
|
|
3427
|
+
values: {
|
|
3428
|
+
type: single ? new GraphQLNonNull6(baseType) : new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(baseType)))
|
|
3429
|
+
},
|
|
3430
|
+
onConflict: {
|
|
3431
|
+
type: onConflictType,
|
|
3432
|
+
description: "How a conflicting row is resolved. Defaults to overwriting it on the primary key."
|
|
3433
|
+
}
|
|
3434
|
+
};
|
|
3435
|
+
const pkNames = sqlitePrimaryKeyPropNames(table);
|
|
3436
|
+
return {
|
|
3437
|
+
name: fieldName,
|
|
3438
|
+
resolver: async (_source, args, context, info) => {
|
|
3439
|
+
try {
|
|
3440
|
+
const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
|
|
3441
|
+
if (!input.length) {
|
|
3442
|
+
throw new GraphQLError6("No values were provided!");
|
|
3443
|
+
}
|
|
3444
|
+
const parsedInfo = parseResolveInfo4(info, { deep: true });
|
|
3445
|
+
const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
|
|
3446
|
+
relationMap,
|
|
3447
|
+
tables,
|
|
3448
|
+
tableName,
|
|
3449
|
+
typeName,
|
|
3450
|
+
typeNameMapper,
|
|
3451
|
+
table,
|
|
3452
|
+
pkNames,
|
|
3453
|
+
parsedInfo
|
|
3454
|
+
});
|
|
3455
|
+
const plan = resolveConflictPlan({
|
|
3456
|
+
table,
|
|
3457
|
+
values: input,
|
|
3458
|
+
onConflict: args.onConflict,
|
|
3459
|
+
pkNames,
|
|
3460
|
+
uniqueSets,
|
|
3461
|
+
excludedRef: excludedColumnRef,
|
|
3462
|
+
withTarget: true,
|
|
3463
|
+
buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
|
|
3464
|
+
});
|
|
3465
|
+
const executor = resolveExecutor(db, context);
|
|
3466
|
+
let query = executor.insert(table).values(input).returning(columns);
|
|
3467
|
+
query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
|
|
3468
|
+
const result = await query;
|
|
3469
|
+
if (single && !result[0]) {
|
|
3470
|
+
return void 0;
|
|
3471
|
+
}
|
|
3472
|
+
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
3473
|
+
return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
3474
|
+
} catch (e) {
|
|
3475
|
+
throw toGraphQLError(e);
|
|
3476
|
+
}
|
|
3477
|
+
},
|
|
3478
|
+
args: queryArgs
|
|
3479
|
+
};
|
|
3480
|
+
};
|
|
3481
|
+
var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
2282
3482
|
const queryArgs = {
|
|
2283
3483
|
set: {
|
|
2284
|
-
type: new
|
|
3484
|
+
type: new GraphQLNonNull6(setArgs)
|
|
2285
3485
|
},
|
|
2286
3486
|
where: {
|
|
2287
3487
|
type: filterArgs
|
|
@@ -2290,10 +3490,10 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
2290
3490
|
const pkNames = sqlitePrimaryKeyPropNames(table);
|
|
2291
3491
|
return {
|
|
2292
3492
|
name: fieldName,
|
|
2293
|
-
resolver: async (_source, args,
|
|
3493
|
+
resolver: async (_source, args, context, info) => {
|
|
2294
3494
|
try {
|
|
2295
3495
|
const { where, set } = args;
|
|
2296
|
-
const parsedInfo =
|
|
3496
|
+
const parsedInfo = parseResolveInfo4(info, {
|
|
2297
3497
|
deep: true
|
|
2298
3498
|
});
|
|
2299
3499
|
const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
|
|
@@ -2308,16 +3508,17 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
2308
3508
|
});
|
|
2309
3509
|
const input = remapFromGraphQLSingleInput(set, table);
|
|
2310
3510
|
if (!Object.keys(input).length) {
|
|
2311
|
-
throw new
|
|
3511
|
+
throw new GraphQLError6("Unable to update with no values specified!");
|
|
2312
3512
|
}
|
|
2313
|
-
|
|
3513
|
+
const executor = resolveExecutor(db, context);
|
|
3514
|
+
let query = executor.update(table).set(input);
|
|
2314
3515
|
if (where) {
|
|
2315
|
-
const filters = extractFilters(table, tableName, where);
|
|
3516
|
+
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
2316
3517
|
query = query.where(filters);
|
|
2317
3518
|
}
|
|
2318
3519
|
query = query.returning(columns);
|
|
2319
3520
|
const result = await query;
|
|
2320
|
-
const enriched = hasRelations ? await eagerLoadMutationRelations(
|
|
3521
|
+
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
2321
3522
|
return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
2322
3523
|
} catch (e) {
|
|
2323
3524
|
throw toGraphQLError(e);
|
|
@@ -2326,7 +3527,7 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
2326
3527
|
args: queryArgs
|
|
2327
3528
|
};
|
|
2328
3529
|
};
|
|
2329
|
-
var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName) => {
|
|
3530
|
+
var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
|
|
2330
3531
|
const queryArgs = {
|
|
2331
3532
|
where: {
|
|
2332
3533
|
type: filterArgs
|
|
@@ -2334,19 +3535,21 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName) =>
|
|
|
2334
3535
|
};
|
|
2335
3536
|
return {
|
|
2336
3537
|
name: fieldName,
|
|
2337
|
-
resolver: async (_source, args,
|
|
3538
|
+
resolver: async (_source, args, context, info) => {
|
|
2338
3539
|
try {
|
|
2339
3540
|
const { where } = args;
|
|
2340
|
-
const parsedInfo =
|
|
3541
|
+
const parsedInfo = parseResolveInfo4(info, {
|
|
2341
3542
|
deep: true
|
|
2342
3543
|
});
|
|
2343
3544
|
const columns = extractSelectedColumnsFromTreeSQLFormat(
|
|
2344
3545
|
parsedInfo.fieldsByTypeName[typeName],
|
|
2345
|
-
table
|
|
3546
|
+
table,
|
|
3547
|
+
selectionCtx
|
|
2346
3548
|
);
|
|
2347
|
-
|
|
3549
|
+
const executor = resolveExecutor(db, context);
|
|
3550
|
+
let query = executor.delete(table);
|
|
2348
3551
|
if (where) {
|
|
2349
|
-
const filters = extractFilters(table, tableName, where);
|
|
3552
|
+
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
2350
3553
|
query = query.where(filters);
|
|
2351
3554
|
}
|
|
2352
3555
|
query = query.returning(columns);
|
|
@@ -2359,7 +3562,8 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName) =>
|
|
|
2359
3562
|
args: queryArgs
|
|
2360
3563
|
};
|
|
2361
3564
|
};
|
|
2362
|
-
var generateSchemaData3 = (db, schema, relations,
|
|
3565
|
+
var generateSchemaData3 = (db, schema, relations, options) => {
|
|
3566
|
+
const { relationsDepthLimit, prefixes, suffixes, conflictDoNothing, typeNameMapper, shouldEagerLoad, features } = options;
|
|
2363
3567
|
const rawSchema = schema;
|
|
2364
3568
|
const schemaEntries = Object.entries(rawSchema);
|
|
2365
3569
|
const tableEntries = schemaEntries.filter(([_key, value]) => is6(value, SQLiteTable));
|
|
@@ -2372,7 +3576,8 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2372
3576
|
const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
|
|
2373
3577
|
attachTargetPrimaryKeys(namedRelations, tables, sqlitePrimaryKeyPropNames);
|
|
2374
3578
|
const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
|
|
2375
|
-
const
|
|
3579
|
+
const filterCtx = { tables, relationMap: namedRelations };
|
|
3580
|
+
const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
|
|
2376
3581
|
const cacheCtx = {
|
|
2377
3582
|
genericFilterCache: /* @__PURE__ */ new Map(),
|
|
2378
3583
|
objectTypeCache: /* @__PURE__ */ new Map(),
|
|
@@ -2380,8 +3585,11 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2380
3585
|
fullyBuiltTables: /* @__PURE__ */ new Set(),
|
|
2381
3586
|
relationTypeCache: /* @__PURE__ */ new Map(),
|
|
2382
3587
|
orderTypeCache: /* @__PURE__ */ new WeakMap(),
|
|
2383
|
-
filterTypeCache: /* @__PURE__ */ new WeakMap()
|
|
3588
|
+
filterTypeCache: /* @__PURE__ */ new WeakMap(),
|
|
3589
|
+
listRelationFilterCache: /* @__PURE__ */ new Map(),
|
|
3590
|
+
aggregateTypeCache: /* @__PURE__ */ new Map()
|
|
2384
3591
|
};
|
|
3592
|
+
const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
|
|
2385
3593
|
const queries = {};
|
|
2386
3594
|
const mutations = {};
|
|
2387
3595
|
const gqlSchemaTypes = Object.fromEntries(
|
|
@@ -2397,7 +3605,8 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2397
3605
|
typeNameMapper,
|
|
2398
3606
|
prefixes.insert,
|
|
2399
3607
|
prefixes.update,
|
|
2400
|
-
resolverFactory
|
|
3608
|
+
resolverFactory,
|
|
3609
|
+
relationAggregateFactory
|
|
2401
3610
|
)
|
|
2402
3611
|
])
|
|
2403
3612
|
);
|
|
@@ -2410,8 +3619,11 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2410
3619
|
typeName,
|
|
2411
3620
|
listFieldName,
|
|
2412
3621
|
singleFieldName,
|
|
3622
|
+
aggregateFieldName,
|
|
2413
3623
|
createArrayFieldName,
|
|
2414
3624
|
createSingleFieldName,
|
|
3625
|
+
upsertArrayFieldName,
|
|
3626
|
+
upsertSingleFieldName,
|
|
2415
3627
|
updateFieldName,
|
|
2416
3628
|
deleteFieldName
|
|
2417
3629
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
@@ -2424,7 +3636,9 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2424
3636
|
tableFilters,
|
|
2425
3637
|
listFieldName,
|
|
2426
3638
|
typeName,
|
|
2427
|
-
typeNameMapper
|
|
3639
|
+
typeNameMapper,
|
|
3640
|
+
filterCtx,
|
|
3641
|
+
features.distinct
|
|
2428
3642
|
);
|
|
2429
3643
|
const selectSingleGenerated = generateSelectSingle3(
|
|
2430
3644
|
db,
|
|
@@ -2435,9 +3649,10 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2435
3649
|
tableFilters,
|
|
2436
3650
|
singleFieldName,
|
|
2437
3651
|
typeName,
|
|
2438
|
-
typeNameMapper
|
|
3652
|
+
typeNameMapper,
|
|
3653
|
+
filterCtx
|
|
2439
3654
|
);
|
|
2440
|
-
const insertArrGenerated = generateInsertArray3(
|
|
3655
|
+
const insertArrGenerated = features.insert ? generateInsertArray3(
|
|
2441
3656
|
db,
|
|
2442
3657
|
tableName,
|
|
2443
3658
|
schema[tableName],
|
|
@@ -2446,9 +3661,10 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2446
3661
|
insertInput,
|
|
2447
3662
|
createArrayFieldName,
|
|
2448
3663
|
typeName,
|
|
2449
|
-
typeNameMapper
|
|
2450
|
-
|
|
2451
|
-
|
|
3664
|
+
typeNameMapper,
|
|
3665
|
+
conflictDoNothing
|
|
3666
|
+
) : void 0;
|
|
3667
|
+
const insertSingleGenerated = features.insert ? generateInsertSingle3(
|
|
2452
3668
|
db,
|
|
2453
3669
|
tableName,
|
|
2454
3670
|
schema[tableName],
|
|
@@ -2457,9 +3673,48 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2457
3673
|
insertInput,
|
|
2458
3674
|
createSingleFieldName,
|
|
2459
3675
|
typeName,
|
|
2460
|
-
typeNameMapper
|
|
2461
|
-
|
|
2462
|
-
|
|
3676
|
+
typeNameMapper,
|
|
3677
|
+
conflictDoNothing
|
|
3678
|
+
) : void 0;
|
|
3679
|
+
const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], getTableConfig3) : [];
|
|
3680
|
+
const onConflictInput = features.upsert ? generateOnConflictInput({
|
|
3681
|
+
table: schema[tableName],
|
|
3682
|
+
typeName,
|
|
3683
|
+
uniqueSets,
|
|
3684
|
+
tableFilters,
|
|
3685
|
+
withTarget: true
|
|
3686
|
+
}) : void 0;
|
|
3687
|
+
const upsertArrGenerated = onConflictInput ? generateUpsert3(
|
|
3688
|
+
db,
|
|
3689
|
+
tableName,
|
|
3690
|
+
schema[tableName],
|
|
3691
|
+
tables,
|
|
3692
|
+
eagerRelations,
|
|
3693
|
+
insertInput,
|
|
3694
|
+
onConflictInput,
|
|
3695
|
+
uniqueSets,
|
|
3696
|
+
upsertArrayFieldName,
|
|
3697
|
+
typeName,
|
|
3698
|
+
false,
|
|
3699
|
+
typeNameMapper,
|
|
3700
|
+
filterCtx
|
|
3701
|
+
) : void 0;
|
|
3702
|
+
const upsertSingleGenerated = onConflictInput ? generateUpsert3(
|
|
3703
|
+
db,
|
|
3704
|
+
tableName,
|
|
3705
|
+
schema[tableName],
|
|
3706
|
+
tables,
|
|
3707
|
+
eagerRelations,
|
|
3708
|
+
insertInput,
|
|
3709
|
+
onConflictInput,
|
|
3710
|
+
uniqueSets,
|
|
3711
|
+
upsertSingleFieldName,
|
|
3712
|
+
typeName,
|
|
3713
|
+
true,
|
|
3714
|
+
typeNameMapper,
|
|
3715
|
+
filterCtx
|
|
3716
|
+
) : void 0;
|
|
3717
|
+
const updateGenerated = features.update ? generateUpdate3(
|
|
2463
3718
|
db,
|
|
2464
3719
|
tableName,
|
|
2465
3720
|
schema[tableName],
|
|
@@ -2469,16 +3724,29 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2469
3724
|
tableFilters,
|
|
2470
3725
|
updateFieldName,
|
|
2471
3726
|
typeName,
|
|
2472
|
-
typeNameMapper
|
|
2473
|
-
|
|
2474
|
-
|
|
3727
|
+
typeNameMapper,
|
|
3728
|
+
filterCtx
|
|
3729
|
+
) : void 0;
|
|
3730
|
+
const deleteGenerated = features.delete ? generateDelete3(
|
|
2475
3731
|
db,
|
|
2476
3732
|
tableName,
|
|
2477
3733
|
schema[tableName],
|
|
2478
3734
|
tableFilters,
|
|
2479
3735
|
deleteFieldName,
|
|
2480
|
-
typeName
|
|
2481
|
-
|
|
3736
|
+
typeName,
|
|
3737
|
+
filterCtx,
|
|
3738
|
+
{ tableName, relationMap: namedRelations, tables }
|
|
3739
|
+
) : void 0;
|
|
3740
|
+
const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
|
|
3741
|
+
const aggregateGenerated = features.aggregates ? generateAggregate(
|
|
3742
|
+
db,
|
|
3743
|
+
tableName,
|
|
3744
|
+
schema[tableName],
|
|
3745
|
+
typeName,
|
|
3746
|
+
aggregateFieldName,
|
|
3747
|
+
tableFilters,
|
|
3748
|
+
filterCtx
|
|
3749
|
+
) : void 0;
|
|
2482
3750
|
queries[selectArrGenerated.name] = {
|
|
2483
3751
|
type: selectArrOutput,
|
|
2484
3752
|
args: selectArrGenerated.args,
|
|
@@ -2489,31 +3757,71 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
|
|
|
2489
3757
|
args: selectSingleGenerated.args,
|
|
2490
3758
|
resolve: selectSingleGenerated.resolver
|
|
2491
3759
|
};
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
3760
|
+
if (aggregateGenerated && aggregateType) {
|
|
3761
|
+
queries[aggregateGenerated.name] = {
|
|
3762
|
+
type: new GraphQLNonNull6(aggregateType),
|
|
3763
|
+
args: aggregateGenerated.args,
|
|
3764
|
+
resolve: aggregateGenerated.resolver
|
|
3765
|
+
};
|
|
3766
|
+
}
|
|
3767
|
+
if (insertArrGenerated) {
|
|
3768
|
+
mutations[insertArrGenerated.name] = {
|
|
3769
|
+
type: arrTableItemOutput,
|
|
3770
|
+
args: insertArrGenerated.args,
|
|
3771
|
+
resolve: insertArrGenerated.resolver
|
|
3772
|
+
};
|
|
3773
|
+
}
|
|
3774
|
+
if (insertSingleGenerated) {
|
|
3775
|
+
mutations[insertSingleGenerated.name] = {
|
|
3776
|
+
type: singleTableItemOutput,
|
|
3777
|
+
args: insertSingleGenerated.args,
|
|
3778
|
+
resolve: insertSingleGenerated.resolver
|
|
3779
|
+
};
|
|
3780
|
+
}
|
|
3781
|
+
if (upsertArrGenerated) {
|
|
3782
|
+
mutations[upsertArrGenerated.name] = {
|
|
3783
|
+
type: arrTableItemOutput,
|
|
3784
|
+
args: upsertArrGenerated.args,
|
|
3785
|
+
resolve: upsertArrGenerated.resolver
|
|
3786
|
+
};
|
|
3787
|
+
}
|
|
3788
|
+
if (upsertSingleGenerated) {
|
|
3789
|
+
mutations[upsertSingleGenerated.name] = {
|
|
3790
|
+
type: singleTableItemOutput,
|
|
3791
|
+
args: upsertSingleGenerated.args,
|
|
3792
|
+
resolve: upsertSingleGenerated.resolver
|
|
3793
|
+
};
|
|
3794
|
+
}
|
|
3795
|
+
if (updateGenerated) {
|
|
3796
|
+
mutations[updateGenerated.name] = {
|
|
3797
|
+
type: arrTableItemOutput,
|
|
3798
|
+
args: updateGenerated.args,
|
|
3799
|
+
resolve: updateGenerated.resolver
|
|
3800
|
+
};
|
|
3801
|
+
}
|
|
3802
|
+
if (deleteGenerated) {
|
|
3803
|
+
mutations[deleteGenerated.name] = {
|
|
3804
|
+
type: arrTableItemOutput,
|
|
3805
|
+
args: deleteGenerated.args,
|
|
3806
|
+
resolve: deleteGenerated.resolver
|
|
3807
|
+
};
|
|
3808
|
+
}
|
|
3809
|
+
const activeInputs = [
|
|
3810
|
+
// The insert input types the upsert mutations too, so either feature keeps it.
|
|
3811
|
+
...features.insert || onConflictInput ? [insertInput] : [],
|
|
3812
|
+
...onConflictInput ? [onConflictInput] : [],
|
|
3813
|
+
...features.update ? [updateInput] : [],
|
|
3814
|
+
tableFilters,
|
|
3815
|
+
tableOrder
|
|
3816
|
+
];
|
|
3817
|
+
activeInputs.forEach((e) => {
|
|
2513
3818
|
inputs[e.name] = e;
|
|
2514
3819
|
});
|
|
2515
3820
|
outputs[selectSingleOutput.name] = selectSingleOutput;
|
|
2516
3821
|
outputs[singleTableItemOutput.name] = singleTableItemOutput;
|
|
3822
|
+
if (aggregateType) {
|
|
3823
|
+
outputs[aggregateType.name] = aggregateType;
|
|
3824
|
+
}
|
|
2517
3825
|
}
|
|
2518
3826
|
const fieldResolvers = {};
|
|
2519
3827
|
for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
|
|
@@ -2546,13 +3854,23 @@ var buildSchema = (db, config) => {
|
|
|
2546
3854
|
const prefixes = {
|
|
2547
3855
|
insert: config?.prefixes?.insert ?? "create",
|
|
2548
3856
|
delete: config?.prefixes?.delete ?? "delete",
|
|
2549
|
-
update: config?.prefixes?.update ?? "update"
|
|
3857
|
+
update: config?.prefixes?.update ?? "update",
|
|
3858
|
+
upsert: config?.prefixes?.upsert ?? "upsert"
|
|
2550
3859
|
};
|
|
2551
3860
|
const suffixes = {
|
|
2552
3861
|
list: config?.suffixes?.list ?? "",
|
|
2553
3862
|
single: config?.suffixes?.single ?? "Single"
|
|
2554
3863
|
};
|
|
2555
3864
|
const typeNameMapper = config?.typeNameMapper;
|
|
3865
|
+
const features = {
|
|
3866
|
+
aggregates: config?.features?.aggregates ?? true,
|
|
3867
|
+
relationAggregates: config?.features?.relationAggregates ?? true,
|
|
3868
|
+
distinct: config?.features?.distinct ?? true,
|
|
3869
|
+
insert: config?.features?.insert ?? true,
|
|
3870
|
+
update: config?.features?.update ?? true,
|
|
3871
|
+
delete: config?.features?.delete ?? true,
|
|
3872
|
+
upsert: config?.features?.upsert ?? false
|
|
3873
|
+
};
|
|
2556
3874
|
const eagerOpt = config?.eagerLoadRelations;
|
|
2557
3875
|
const shouldEagerLoad = eagerOpt === void 0 || eagerOpt === true ? () => true : eagerOpt === false ? () => false : eagerOpt;
|
|
2558
3876
|
if (!typeNameMapper && suffixes.list === suffixes.single) {
|
|
@@ -2572,54 +3890,40 @@ var buildSchema = (db, config) => {
|
|
|
2572
3890
|
);
|
|
2573
3891
|
}
|
|
2574
3892
|
}
|
|
3893
|
+
const generatorOptions = {
|
|
3894
|
+
relationsDepthLimit: config?.relationsDepthLimit,
|
|
3895
|
+
prefixes,
|
|
3896
|
+
suffixes,
|
|
3897
|
+
conflictDoNothing: config?.conflictDoNothing ?? false,
|
|
3898
|
+
typeNameMapper,
|
|
3899
|
+
shouldEagerLoad,
|
|
3900
|
+
features
|
|
3901
|
+
};
|
|
2575
3902
|
let generatorOutput;
|
|
2576
3903
|
if (is7(db, MySqlDatabase)) {
|
|
2577
|
-
generatorOutput = generateSchemaData(
|
|
2578
|
-
db,
|
|
2579
|
-
schema,
|
|
2580
|
-
relations,
|
|
2581
|
-
config?.relationsDepthLimit,
|
|
2582
|
-
prefixes,
|
|
2583
|
-
suffixes,
|
|
2584
|
-
typeNameMapper,
|
|
2585
|
-
shouldEagerLoad
|
|
2586
|
-
);
|
|
3904
|
+
generatorOutput = generateSchemaData(db, schema, relations, generatorOptions);
|
|
2587
3905
|
} else if (is7(db, PgAsyncDatabase)) {
|
|
2588
|
-
generatorOutput = generateSchemaData2(
|
|
2589
|
-
db,
|
|
2590
|
-
schema,
|
|
2591
|
-
relations,
|
|
2592
|
-
config?.relationsDepthLimit,
|
|
2593
|
-
prefixes,
|
|
2594
|
-
suffixes,
|
|
2595
|
-
config?.conflictDoNothing ?? false,
|
|
2596
|
-
typeNameMapper,
|
|
2597
|
-
shouldEagerLoad
|
|
2598
|
-
);
|
|
3906
|
+
generatorOutput = generateSchemaData2(db, schema, relations, generatorOptions);
|
|
2599
3907
|
} else if (is7(db, BaseSQLiteDatabase)) {
|
|
2600
|
-
generatorOutput = generateSchemaData3(
|
|
2601
|
-
db,
|
|
2602
|
-
schema,
|
|
2603
|
-
relations,
|
|
2604
|
-
config?.relationsDepthLimit,
|
|
2605
|
-
prefixes,
|
|
2606
|
-
suffixes,
|
|
2607
|
-
typeNameMapper,
|
|
2608
|
-
shouldEagerLoad
|
|
2609
|
-
);
|
|
3908
|
+
generatorOutput = generateSchemaData3(db, schema, relations, generatorOptions);
|
|
2610
3909
|
} else {
|
|
2611
3910
|
throw new Error("Drizzle-GraphQL Error: Unknown database instance type");
|
|
2612
3911
|
}
|
|
3912
|
+
const onError = config?.onError;
|
|
3913
|
+
applyErrorMapper(
|
|
3914
|
+
generatorOutput,
|
|
3915
|
+
onError ? (error) => onError(error) ?? defaultErrorMapper(error) : defaultErrorMapper
|
|
3916
|
+
);
|
|
2613
3917
|
const { queries, mutations, inputs, types } = generatorOutput;
|
|
2614
3918
|
const graphQLSchemaConfig = {
|
|
2615
3919
|
types: [...Object.values(inputs), ...Object.values(types)],
|
|
2616
|
-
query: new
|
|
3920
|
+
query: new GraphQLObjectType5({
|
|
2617
3921
|
name: "Query",
|
|
2618
3922
|
fields: queries
|
|
2619
3923
|
})
|
|
2620
3924
|
};
|
|
2621
|
-
if (config?.mutations !== false) {
|
|
2622
|
-
const mutation = new
|
|
3925
|
+
if (config?.mutations !== false && Object.keys(mutations).length) {
|
|
3926
|
+
const mutation = new GraphQLObjectType5({
|
|
2623
3927
|
name: "Mutation",
|
|
2624
3928
|
fields: mutations
|
|
2625
3929
|
});
|
|
@@ -2629,8 +3933,15 @@ var buildSchema = (db, config) => {
|
|
|
2629
3933
|
return { schema: outputSchema, entities: generatorOutput };
|
|
2630
3934
|
};
|
|
2631
3935
|
export {
|
|
3936
|
+
GraphQLBigIntString,
|
|
3937
|
+
GraphQLDate,
|
|
3938
|
+
GraphQLDateTime,
|
|
3939
|
+
GraphQLJSON,
|
|
3940
|
+
GraphQLUUID,
|
|
2632
3941
|
buildSchema,
|
|
2633
3942
|
createRelationResolverFactory,
|
|
3943
|
+
defaultErrorMapper,
|
|
3944
|
+
drizzleExecutorKey,
|
|
2634
3945
|
extractFilters,
|
|
2635
3946
|
extractOrderBy,
|
|
2636
3947
|
extractRelationJoinColumns
|