@farming-labs/orm-sql 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +310 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +310 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
toUniqueLookupWhere,
|
|
10
10
|
validateUniqueLookupUpdateData
|
|
11
11
|
} from "@farming-labs/orm";
|
|
12
|
+
var nativeNodeIdentity = /* @__PURE__ */ Symbol("nativeNodeIdentity");
|
|
12
13
|
var manifestCache = /* @__PURE__ */ new WeakMap();
|
|
13
14
|
function getManifest(schema) {
|
|
14
15
|
const cached = manifestCache.get(schema);
|
|
@@ -148,12 +149,12 @@ function mergeWhere(...clauses) {
|
|
|
148
149
|
AND: defined
|
|
149
150
|
};
|
|
150
151
|
}
|
|
151
|
-
function compileFieldFilter(model, fieldName, filter, dialect, state) {
|
|
152
|
+
function compileFieldFilter(model, fieldName, filter, dialect, state, tableAlias = model.table) {
|
|
152
153
|
const field = model.fields[fieldName];
|
|
153
154
|
if (!field) {
|
|
154
155
|
throw new Error(`Unknown field "${fieldName}" on model "${model.name}".`);
|
|
155
156
|
}
|
|
156
|
-
const column = `${quoteIdentifier(
|
|
157
|
+
const column = `${quoteIdentifier(tableAlias, dialect)}.${quoteIdentifier(field.column, dialect)}`;
|
|
157
158
|
const createValueExpression = (value) => {
|
|
158
159
|
const placeholder = createPlaceholder(dialect, state, encodeValue(field, dialect, value));
|
|
159
160
|
if (field.kind === "json" && dialect === "mysql") {
|
|
@@ -215,39 +216,39 @@ function compileFieldFilter(model, fieldName, filter, dialect, state) {
|
|
|
215
216
|
if (clauses.length === 1) return clauses[0];
|
|
216
217
|
return `(${clauses.join(" and ")})`;
|
|
217
218
|
}
|
|
218
|
-
function compileWhere(model, where, dialect, state) {
|
|
219
|
+
function compileWhere(model, where, dialect, state, tableAlias = model.table) {
|
|
219
220
|
if (!where) return void 0;
|
|
220
221
|
const clauses = [];
|
|
221
222
|
for (const [key, value] of Object.entries(where)) {
|
|
222
223
|
if (key === "AND") {
|
|
223
224
|
const items = Array.isArray(value) ? value : [];
|
|
224
225
|
if (!items.length) continue;
|
|
225
|
-
const nested = items.map((item) => compileWhere(model, item, dialect, state)).filter(Boolean).map((item) => `(${item})`);
|
|
226
|
+
const nested = items.map((item) => compileWhere(model, item, dialect, state, tableAlias)).filter(Boolean).map((item) => `(${item})`);
|
|
226
227
|
if (nested.length) clauses.push(nested.join(" and "));
|
|
227
228
|
continue;
|
|
228
229
|
}
|
|
229
230
|
if (key === "OR") {
|
|
230
231
|
const items = Array.isArray(value) ? value : [];
|
|
231
232
|
if (!items.length) continue;
|
|
232
|
-
const nested = items.map((item) => compileWhere(model, item, dialect, state)).filter(Boolean).map((item) => `(${item})`);
|
|
233
|
+
const nested = items.map((item) => compileWhere(model, item, dialect, state, tableAlias)).filter(Boolean).map((item) => `(${item})`);
|
|
233
234
|
if (nested.length) clauses.push(`(${nested.join(" or ")})`);
|
|
234
235
|
continue;
|
|
235
236
|
}
|
|
236
237
|
if (key === "NOT") {
|
|
237
|
-
const nested = compileWhere(model, value, dialect, state);
|
|
238
|
+
const nested = compileWhere(model, value, dialect, state, tableAlias);
|
|
238
239
|
if (nested) clauses.push(`not (${nested})`);
|
|
239
240
|
continue;
|
|
240
241
|
}
|
|
241
|
-
clauses.push(compileFieldFilter(model, key, value, dialect, state));
|
|
242
|
+
clauses.push(compileFieldFilter(model, key, value, dialect, state, tableAlias));
|
|
242
243
|
}
|
|
243
244
|
if (!clauses.length) return void 0;
|
|
244
245
|
return clauses.join(" and ");
|
|
245
246
|
}
|
|
246
|
-
function compileOrderBy(model, orderBy, dialect) {
|
|
247
|
+
function compileOrderBy(model, orderBy, dialect, tableAlias = model.table) {
|
|
247
248
|
if (!orderBy) return "";
|
|
248
249
|
const parts = Object.entries(orderBy).filter(([fieldName]) => fieldName in model.fields).map(([fieldName, direction]) => {
|
|
249
250
|
const field = model.fields[fieldName];
|
|
250
|
-
return `${quoteIdentifier(
|
|
251
|
+
return `${quoteIdentifier(tableAlias, dialect)}.${quoteIdentifier(field.column, dialect)} ${direction === "desc" ? "desc" : "asc"}`;
|
|
251
252
|
});
|
|
252
253
|
if (!parts.length) return "";
|
|
253
254
|
return ` order by ${parts.join(", ")}`;
|
|
@@ -270,13 +271,14 @@ function compilePagination(dialect, take, skip) {
|
|
|
270
271
|
}
|
|
271
272
|
function buildSelectStatement(model, dialect, args) {
|
|
272
273
|
const state = { params: [] };
|
|
274
|
+
const tableAlias = args.tableAlias ?? model.table;
|
|
273
275
|
const selectList = Object.values(model.fields).map(
|
|
274
|
-
(field) => `${quoteIdentifier(
|
|
276
|
+
(field) => `${quoteIdentifier(tableAlias, dialect)}.${quoteIdentifier(field.column, dialect)} as ${quoteIdentifier(field.name, dialect)}`
|
|
275
277
|
);
|
|
276
|
-
let sql = `select ${selectList.join(", ")} from ${quoteIdentifier(model.table, dialect)}`;
|
|
277
|
-
const where = compileWhere(model, args.where, dialect, state);
|
|
278
|
+
let sql = `select ${selectList.join(", ")} from ${quoteIdentifier(model.table, dialect)} as ${quoteIdentifier(tableAlias, dialect)}`;
|
|
279
|
+
const where = compileWhere(model, args.where, dialect, state, tableAlias);
|
|
278
280
|
if (where) sql += ` where ${where}`;
|
|
279
|
-
sql += compileOrderBy(model, args.orderBy, dialect);
|
|
281
|
+
sql += compileOrderBy(model, args.orderBy, dialect, tableAlias);
|
|
280
282
|
sql += compilePagination(dialect, args.take, args.skip);
|
|
281
283
|
return { sql, params: state.params };
|
|
282
284
|
}
|
|
@@ -576,8 +578,17 @@ function createMysqlPoolAdapter(pool) {
|
|
|
576
578
|
}
|
|
577
579
|
};
|
|
578
580
|
}
|
|
579
|
-
function createSqlDriver(adapter) {
|
|
581
|
+
function createSqlDriver(adapter, handle) {
|
|
582
|
+
const resolvedHandle = handle ?? {
|
|
583
|
+
kind: "sql",
|
|
584
|
+
client: adapter,
|
|
585
|
+
dialect: adapter.dialect
|
|
586
|
+
};
|
|
580
587
|
async function loadRows(schema, modelName, args) {
|
|
588
|
+
const nativeRows = await loadRowsWithNativeJoins(schema, modelName, args);
|
|
589
|
+
if (nativeRows) {
|
|
590
|
+
return nativeRows;
|
|
591
|
+
}
|
|
581
592
|
const manifest = getManifest(schema);
|
|
582
593
|
const model = manifest.models[modelName];
|
|
583
594
|
const statement = buildSelectStatement(model, adapter.dialect, args);
|
|
@@ -603,6 +614,253 @@ function createSqlDriver(adapter) {
|
|
|
603
614
|
const row = result.rows[0];
|
|
604
615
|
return row ? decodeRow(model, adapter.dialect, row) : null;
|
|
605
616
|
}
|
|
617
|
+
function createNativePresenceAlias(model, alias, includeAllScalars, selectedScalarKeys) {
|
|
618
|
+
const occupiedAliases = new Set(
|
|
619
|
+
(includeAllScalars ? Object.keys(model.fields) : selectedScalarKeys).map(
|
|
620
|
+
(fieldName) => `${alias}__${fieldName}`
|
|
621
|
+
)
|
|
622
|
+
);
|
|
623
|
+
let candidate = `${alias}__orm_presence`;
|
|
624
|
+
let suffix = 0;
|
|
625
|
+
while (occupiedAliases.has(candidate)) {
|
|
626
|
+
suffix += 1;
|
|
627
|
+
candidate = `${alias}__orm_presence_${suffix}`;
|
|
628
|
+
}
|
|
629
|
+
return candidate;
|
|
630
|
+
}
|
|
631
|
+
function buildNativeJoinPlan(schema, modelName, select, aliasState) {
|
|
632
|
+
const manifest = getManifest(schema);
|
|
633
|
+
const model = manifest.models[modelName];
|
|
634
|
+
const alias = `t${aliasState.next++}`;
|
|
635
|
+
const entries = select ? Object.entries(select) : [];
|
|
636
|
+
const selectedScalarKeys = select ? entries.filter(([key, value]) => key in model.fields && value === true).map(([key]) => key) : Object.keys(model.fields);
|
|
637
|
+
const node = {
|
|
638
|
+
modelName,
|
|
639
|
+
model,
|
|
640
|
+
alias,
|
|
641
|
+
presenceAlias: createNativePresenceAlias(model, alias, !select, selectedScalarKeys),
|
|
642
|
+
includeAllScalars: !select,
|
|
643
|
+
selectedScalarKeys,
|
|
644
|
+
children: []
|
|
645
|
+
};
|
|
646
|
+
for (const [key, value] of entries) {
|
|
647
|
+
if (value === void 0 || !(key in schema.models[modelName].relations)) continue;
|
|
648
|
+
const relation = schema.models[modelName].relations[key];
|
|
649
|
+
const relationArgs = value === true ? {} : value;
|
|
650
|
+
if (relationArgs.where !== void 0 || relationArgs.orderBy !== void 0 || relationArgs.take !== void 0 || relationArgs.skip !== void 0) {
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
653
|
+
const child = buildNativeJoinPlan(
|
|
654
|
+
schema,
|
|
655
|
+
relation.target,
|
|
656
|
+
relationArgs.select,
|
|
657
|
+
aliasState
|
|
658
|
+
);
|
|
659
|
+
if (!child) return null;
|
|
660
|
+
child.relationName = key;
|
|
661
|
+
child.relationKind = relation.kind;
|
|
662
|
+
if (relation.kind === "belongsTo") {
|
|
663
|
+
const sourceField = model.fields[relation.foreignKey];
|
|
664
|
+
if (!sourceField) return null;
|
|
665
|
+
const targetReference = parseReference(sourceField.references);
|
|
666
|
+
const targetFieldName = targetReference?.field ?? identityField(manifest.models[relation.target]).name;
|
|
667
|
+
const targetField = child.model.fields[targetFieldName];
|
|
668
|
+
if (!targetField) return null;
|
|
669
|
+
child.sourceField = sourceField;
|
|
670
|
+
child.targetField = targetField;
|
|
671
|
+
} else if (relation.kind === "hasOne" || relation.kind === "hasMany") {
|
|
672
|
+
const targetForeignField = child.model.fields[relation.foreignKey];
|
|
673
|
+
if (!targetForeignField) return null;
|
|
674
|
+
const sourceReference = parseReference(targetForeignField.references);
|
|
675
|
+
const sourceFieldName = sourceReference?.field ?? identityField(manifest.models[modelName]).name;
|
|
676
|
+
const sourceField = model.fields[sourceFieldName];
|
|
677
|
+
if (!sourceField) return null;
|
|
678
|
+
child.sourceField = sourceField;
|
|
679
|
+
child.targetField = targetForeignField;
|
|
680
|
+
} else {
|
|
681
|
+
const throughModel = manifest.models[relation.through];
|
|
682
|
+
const throughFromField = throughModel.fields[relation.from];
|
|
683
|
+
const throughToField = throughModel.fields[relation.to];
|
|
684
|
+
if (!throughFromField || !throughToField) return null;
|
|
685
|
+
const throughFromReference = parseReference(throughFromField.references);
|
|
686
|
+
const throughToReference = parseReference(throughToField.references);
|
|
687
|
+
const sourceFieldName = throughFromReference?.field ?? identityField(manifest.models[modelName]).name;
|
|
688
|
+
const targetFieldName = throughToReference?.field ?? identityField(child.model).name;
|
|
689
|
+
const sourceField = model.fields[sourceFieldName];
|
|
690
|
+
const targetField = child.model.fields[targetFieldName];
|
|
691
|
+
if (!sourceField || !targetField) return null;
|
|
692
|
+
child.sourceField = sourceField;
|
|
693
|
+
child.targetField = targetField;
|
|
694
|
+
child.throughModel = throughModel;
|
|
695
|
+
child.throughAlias = `t${aliasState.next++}`;
|
|
696
|
+
child.throughFromField = throughFromField;
|
|
697
|
+
child.throughToField = throughToField;
|
|
698
|
+
}
|
|
699
|
+
node.children.push(child);
|
|
700
|
+
}
|
|
701
|
+
return node;
|
|
702
|
+
}
|
|
703
|
+
function hasNativeJoinableRelations(schema, modelName, select) {
|
|
704
|
+
if (!select) return false;
|
|
705
|
+
const plan = buildNativeJoinPlan(schema, modelName, select, { next: 0 });
|
|
706
|
+
return !!plan && plan.children.length > 0;
|
|
707
|
+
}
|
|
708
|
+
function collectNativeJoinSelects(node, selectList) {
|
|
709
|
+
const scalarKeys = node.includeAllScalars ? Object.keys(node.model.fields) : node.selectedScalarKeys;
|
|
710
|
+
for (const fieldName of scalarKeys) {
|
|
711
|
+
const field = node.model.fields[fieldName];
|
|
712
|
+
if (!field) continue;
|
|
713
|
+
selectList.push(
|
|
714
|
+
`${quoteIdentifier(node.alias, adapter.dialect)}.${quoteIdentifier(field.column, adapter.dialect)} as ${quoteIdentifier(`${node.alias}__${field.name}`, adapter.dialect)}`
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
const identity = identityField(node.model);
|
|
718
|
+
selectList.push(
|
|
719
|
+
`${quoteIdentifier(node.alias, adapter.dialect)}.${quoteIdentifier(identity.column, adapter.dialect)} as ${quoteIdentifier(node.presenceAlias, adapter.dialect)}`
|
|
720
|
+
);
|
|
721
|
+
for (const child of node.children) {
|
|
722
|
+
collectNativeJoinSelects(child, selectList);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
function collectNativeJoinClauses(node, joins) {
|
|
726
|
+
for (const child of node.children) {
|
|
727
|
+
if (child.relationKind === "manyToMany") {
|
|
728
|
+
joins.push(
|
|
729
|
+
` left join ${quoteIdentifier(child.throughModel.table, adapter.dialect)} as ${quoteIdentifier(child.throughAlias, adapter.dialect)} on ${quoteIdentifier(node.alias, adapter.dialect)}.${quoteIdentifier(child.sourceField.column, adapter.dialect)} = ${quoteIdentifier(child.throughAlias, adapter.dialect)}.${quoteIdentifier(child.throughFromField.column, adapter.dialect)}`
|
|
730
|
+
);
|
|
731
|
+
joins.push(
|
|
732
|
+
` left join ${quoteIdentifier(child.model.table, adapter.dialect)} as ${quoteIdentifier(child.alias, adapter.dialect)} on ${quoteIdentifier(child.throughAlias, adapter.dialect)}.${quoteIdentifier(child.throughToField.column, adapter.dialect)} = ${quoteIdentifier(child.alias, adapter.dialect)}.${quoteIdentifier(child.targetField.column, adapter.dialect)}`
|
|
733
|
+
);
|
|
734
|
+
} else {
|
|
735
|
+
const leftColumn = child.relationKind === "belongsTo" ? `${quoteIdentifier(node.alias, adapter.dialect)}.${quoteIdentifier(child.sourceField.column, adapter.dialect)}` : `${quoteIdentifier(child.alias, adapter.dialect)}.${quoteIdentifier(child.targetField.column, adapter.dialect)}`;
|
|
736
|
+
const rightColumn = child.relationKind === "belongsTo" ? `${quoteIdentifier(child.alias, adapter.dialect)}.${quoteIdentifier(child.targetField.column, adapter.dialect)}` : `${quoteIdentifier(node.alias, adapter.dialect)}.${quoteIdentifier(child.sourceField.column, adapter.dialect)}`;
|
|
737
|
+
joins.push(
|
|
738
|
+
` left join ${quoteIdentifier(child.model.table, adapter.dialect)} as ${quoteIdentifier(child.alias, adapter.dialect)} on ${leftColumn} = ${rightColumn}`
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
collectNativeJoinClauses(child, joins);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
function buildNativeJoinRootSource(root, args) {
|
|
745
|
+
const state = { params: [] };
|
|
746
|
+
const sourceAlias = `${root.alias}__src`;
|
|
747
|
+
const selectList = Object.values(root.model.fields).map(
|
|
748
|
+
(field) => `${quoteIdentifier(sourceAlias, adapter.dialect)}.${quoteIdentifier(field.column, adapter.dialect)} as ${quoteIdentifier(field.column, adapter.dialect)}`
|
|
749
|
+
);
|
|
750
|
+
let sql = `select ${selectList.join(", ")} from ${quoteIdentifier(root.model.table, adapter.dialect)} as ${quoteIdentifier(sourceAlias, adapter.dialect)}`;
|
|
751
|
+
const where = compileWhere(root.model, args.where, adapter.dialect, state, sourceAlias);
|
|
752
|
+
if (where) sql += ` where ${where}`;
|
|
753
|
+
sql += compileOrderBy(root.model, args.orderBy, adapter.dialect, sourceAlias);
|
|
754
|
+
sql += compilePagination(adapter.dialect, args.take, args.skip);
|
|
755
|
+
return {
|
|
756
|
+
sql: `(${sql})`,
|
|
757
|
+
params: state.params
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
function buildNativeJoinStatement(root, args) {
|
|
761
|
+
const state = { params: [] };
|
|
762
|
+
const selectList = [];
|
|
763
|
+
const joins = [];
|
|
764
|
+
collectNativeJoinSelects(root, selectList);
|
|
765
|
+
collectNativeJoinClauses(root, joins);
|
|
766
|
+
const rootSource = buildNativeJoinRootSource(root, args);
|
|
767
|
+
state.params.push(...rootSource.params);
|
|
768
|
+
let sql = `select ${selectList.join(", ")} from ${rootSource.sql} as ${quoteIdentifier(root.alias, adapter.dialect)}`;
|
|
769
|
+
if (joins.length) sql += joins.join("");
|
|
770
|
+
sql += compileOrderBy(root.model, args.orderBy, adapter.dialect, root.alias);
|
|
771
|
+
return { sql, params: state.params };
|
|
772
|
+
}
|
|
773
|
+
function nodePresenceValue(node, rawRow) {
|
|
774
|
+
return rawRow[node.presenceAlias];
|
|
775
|
+
}
|
|
776
|
+
function projectNativeJoinNode(node, rawRow) {
|
|
777
|
+
if (nodePresenceValue(node, rawRow) == null) {
|
|
778
|
+
return null;
|
|
779
|
+
}
|
|
780
|
+
const output = {};
|
|
781
|
+
Object.defineProperty(output, nativeNodeIdentity, {
|
|
782
|
+
value: rawRow[node.presenceAlias],
|
|
783
|
+
enumerable: false,
|
|
784
|
+
configurable: true
|
|
785
|
+
});
|
|
786
|
+
const scalarKeys = node.includeAllScalars ? Object.keys(node.model.fields) : node.selectedScalarKeys;
|
|
787
|
+
for (const fieldName of scalarKeys) {
|
|
788
|
+
const field = node.model.fields[fieldName];
|
|
789
|
+
if (!field) continue;
|
|
790
|
+
output[field.name] = decodeValue(
|
|
791
|
+
field,
|
|
792
|
+
adapter.dialect,
|
|
793
|
+
rawRow[`${node.alias}__${field.name}`]
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
for (const child of node.children) {
|
|
797
|
+
const childValue = projectNativeJoinNode(child, rawRow);
|
|
798
|
+
output[child.relationName] = child.relationKind === "hasMany" || child.relationKind === "manyToMany" ? childValue ? [childValue] : [] : childValue;
|
|
799
|
+
}
|
|
800
|
+
return output;
|
|
801
|
+
}
|
|
802
|
+
function mergeNativeJoinNode(node, target, next) {
|
|
803
|
+
for (const child of node.children) {
|
|
804
|
+
const relationName = child.relationName;
|
|
805
|
+
if (child.relationKind === "hasMany" || child.relationKind === "manyToMany") {
|
|
806
|
+
const targetRows = Array.isArray(target[relationName]) ? target[relationName] : [];
|
|
807
|
+
const nextRows = Array.isArray(next[relationName]) ? next[relationName] : [];
|
|
808
|
+
if (!Array.isArray(target[relationName])) {
|
|
809
|
+
target[relationName] = targetRows;
|
|
810
|
+
}
|
|
811
|
+
for (const nextRow of nextRows) {
|
|
812
|
+
const identity = nextRow[nativeNodeIdentity];
|
|
813
|
+
const existing2 = targetRows.find((entry) => entry[nativeNodeIdentity] === identity);
|
|
814
|
+
if (existing2) {
|
|
815
|
+
mergeNativeJoinNode(child, existing2, nextRow);
|
|
816
|
+
} else {
|
|
817
|
+
targetRows.push(nextRow);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
const nextValue = next[relationName];
|
|
823
|
+
if (nextValue === void 0) continue;
|
|
824
|
+
if (nextValue === null) {
|
|
825
|
+
if (!(relationName in target)) {
|
|
826
|
+
target[relationName] = null;
|
|
827
|
+
}
|
|
828
|
+
continue;
|
|
829
|
+
}
|
|
830
|
+
const existing = target[relationName];
|
|
831
|
+
if (!existing || typeof existing !== "object") {
|
|
832
|
+
target[relationName] = nextValue;
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
mergeNativeJoinNode(child, existing, nextValue);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
async function loadRowsWithNativeJoins(schema, modelName, args) {
|
|
839
|
+
if (!hasNativeJoinableRelations(schema, modelName, args.select)) {
|
|
840
|
+
return null;
|
|
841
|
+
}
|
|
842
|
+
const plan = buildNativeJoinPlan(schema, modelName, args.select, { next: 0 });
|
|
843
|
+
if (!plan || !plan.children.length) {
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
846
|
+
const statement = buildNativeJoinStatement(plan, args);
|
|
847
|
+
const result = await adapter.query(statement.sql, statement.params);
|
|
848
|
+
const groupedRows = [];
|
|
849
|
+
const groupedByIdentity = /* @__PURE__ */ new Map();
|
|
850
|
+
for (const row of result.rows) {
|
|
851
|
+
const projected = projectNativeJoinNode(plan, row);
|
|
852
|
+
if (!projected) continue;
|
|
853
|
+
const identity = projected[nativeNodeIdentity];
|
|
854
|
+
const existing = groupedByIdentity.get(identity);
|
|
855
|
+
if (existing) {
|
|
856
|
+
mergeNativeJoinNode(plan, existing, projected);
|
|
857
|
+
continue;
|
|
858
|
+
}
|
|
859
|
+
groupedByIdentity.set(identity, projected);
|
|
860
|
+
groupedRows.push(projected);
|
|
861
|
+
}
|
|
862
|
+
return groupedRows;
|
|
863
|
+
}
|
|
606
864
|
async function projectRow(schema, modelName, row, select) {
|
|
607
865
|
const manifest = getManifest(schema);
|
|
608
866
|
const model = manifest.models[modelName];
|
|
@@ -720,6 +978,7 @@ function createSqlDriver(adapter) {
|
|
|
720
978
|
});
|
|
721
979
|
}
|
|
722
980
|
const driver = {
|
|
981
|
+
handle: resolvedHandle,
|
|
723
982
|
async findMany(schema, model, args) {
|
|
724
983
|
return loadRows(schema, model, args);
|
|
725
984
|
},
|
|
@@ -866,26 +1125,56 @@ function createSqlDriver(adapter) {
|
|
|
866
1125
|
return result.affectedRows;
|
|
867
1126
|
},
|
|
868
1127
|
async transaction(_schema, run) {
|
|
869
|
-
return adapter.transaction(
|
|
1128
|
+
return adapter.transaction(
|
|
1129
|
+
async (txAdapter) => run(createSqlDriver(txAdapter, resolvedHandle))
|
|
1130
|
+
);
|
|
870
1131
|
}
|
|
871
1132
|
};
|
|
872
1133
|
return driver;
|
|
873
1134
|
}
|
|
874
1135
|
function createSqliteDriver(database) {
|
|
875
|
-
return createSqlDriver(
|
|
1136
|
+
return createSqlDriver(
|
|
1137
|
+
createSqliteAdapter(database),
|
|
1138
|
+
{
|
|
1139
|
+
kind: "sql",
|
|
1140
|
+
client: database,
|
|
1141
|
+
dialect: "sqlite"
|
|
1142
|
+
}
|
|
1143
|
+
);
|
|
876
1144
|
}
|
|
877
|
-
function createSqlDriverFromAdapter(adapter) {
|
|
878
|
-
return createSqlDriver(adapter);
|
|
1145
|
+
function createSqlDriverFromAdapter(adapter, handle) {
|
|
1146
|
+
return createSqlDriver(adapter, handle);
|
|
879
1147
|
}
|
|
880
1148
|
function createPgPoolDriver(pool) {
|
|
881
|
-
return createSqlDriver(
|
|
1149
|
+
return createSqlDriver(
|
|
1150
|
+
createPgPoolAdapter(pool),
|
|
1151
|
+
{
|
|
1152
|
+
kind: "sql",
|
|
1153
|
+
client: pool,
|
|
1154
|
+
dialect: "postgres"
|
|
1155
|
+
}
|
|
1156
|
+
);
|
|
882
1157
|
}
|
|
883
1158
|
function createPgClientDriver(client) {
|
|
884
|
-
return createSqlDriver(
|
|
1159
|
+
return createSqlDriver(
|
|
1160
|
+
createPgTransactionalAdapter(client),
|
|
1161
|
+
{
|
|
1162
|
+
kind: "sql",
|
|
1163
|
+
client,
|
|
1164
|
+
dialect: "postgres"
|
|
1165
|
+
}
|
|
1166
|
+
);
|
|
885
1167
|
}
|
|
886
1168
|
function createMysqlDriver(poolOrConnection) {
|
|
887
1169
|
const adapter = "getConnection" in poolOrConnection ? createMysqlPoolAdapter(poolOrConnection) : createMysqlTransactionalAdapter(poolOrConnection);
|
|
888
|
-
return createSqlDriver(
|
|
1170
|
+
return createSqlDriver(
|
|
1171
|
+
adapter,
|
|
1172
|
+
{
|
|
1173
|
+
kind: "sql",
|
|
1174
|
+
client: poolOrConnection,
|
|
1175
|
+
dialect: "mysql"
|
|
1176
|
+
}
|
|
1177
|
+
);
|
|
889
1178
|
}
|
|
890
1179
|
export {
|
|
891
1180
|
createMysqlDriver,
|