@prisma/orm-family-sql 0.17.0-dev.7 → 0.17.0-dev.9
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/orm-client.mjs +109 -29
- package/dist/orm-client.mjs.map +1 -1
- package/package.json +18 -18
package/dist/orm-client.mjs
CHANGED
|
@@ -2459,7 +2459,91 @@ function isCollectionState(value) {
|
|
|
2459
2459
|
function hasThrough$1(relation) {
|
|
2460
2460
|
return relation.through !== void 0;
|
|
2461
2461
|
}
|
|
2462
|
+
var SqlTableBinding = class SqlTableBinding {
|
|
2463
|
+
#storage;
|
|
2464
|
+
#reference;
|
|
2465
|
+
constructor(storage, reference) {
|
|
2466
|
+
this.#storage = Object.freeze({ ...storage });
|
|
2467
|
+
this.#reference = reference;
|
|
2468
|
+
Object.freeze(this);
|
|
2469
|
+
}
|
|
2470
|
+
static unaliased(storage) {
|
|
2471
|
+
return new SqlTableBinding(storage, storage.tableName);
|
|
2472
|
+
}
|
|
2473
|
+
static aliased(storage, alias) {
|
|
2474
|
+
return new SqlTableBinding(storage, alias);
|
|
2475
|
+
}
|
|
2476
|
+
column(columnName) {
|
|
2477
|
+
return ColumnRef.of(this.#reference, columnName);
|
|
2478
|
+
}
|
|
2479
|
+
tableSource(contract) {
|
|
2480
|
+
return tableSourceForContract(contract, this.#storage.namespaceId, this.#storage.tableName, this.#reference);
|
|
2481
|
+
}
|
|
2482
|
+
isReferencedAs(candidate) {
|
|
2483
|
+
return this.#reference === candidate;
|
|
2484
|
+
}
|
|
2485
|
+
isStoredAt(namespaceId, tableName) {
|
|
2486
|
+
return this.#storage.namespaceId === namespaceId && this.#storage.tableName === tableName;
|
|
2487
|
+
}
|
|
2488
|
+
};
|
|
2489
|
+
var ModelAccessorScope = class ModelAccessorScope {
|
|
2490
|
+
current;
|
|
2491
|
+
#visibleBindings;
|
|
2492
|
+
#aliasCounter;
|
|
2493
|
+
constructor(current, visibleBindings, aliasCounter) {
|
|
2494
|
+
this.current = current;
|
|
2495
|
+
this.#visibleBindings = Object.freeze([...visibleBindings]);
|
|
2496
|
+
this.#aliasCounter = aliasCounter;
|
|
2497
|
+
Object.freeze(this);
|
|
2498
|
+
}
|
|
2499
|
+
static root(namespaceId, tableName) {
|
|
2500
|
+
const binding = SqlTableBinding.unaliased({
|
|
2501
|
+
namespaceId,
|
|
2502
|
+
tableName
|
|
2503
|
+
});
|
|
2504
|
+
return new ModelAccessorScope(binding, [binding], { nextId: 1 });
|
|
2505
|
+
}
|
|
2506
|
+
forRelation(namespaceId, tableName) {
|
|
2507
|
+
const binding = this.#allocateBinding(namespaceId, tableName, "rel");
|
|
2508
|
+
return new ModelAccessorScope(binding, [...this.#visibleBindings, binding], this.#aliasCounter);
|
|
2509
|
+
}
|
|
2510
|
+
forManyToManyRelation(childNamespaceId, childTableName, junctionNamespaceId, junctionTableName) {
|
|
2511
|
+
const initialChildScope = this.forRelation(childNamespaceId, childTableName);
|
|
2512
|
+
const junctionBinding = initialChildScope.#allocateBinding(junctionNamespaceId, junctionTableName, "junction");
|
|
2513
|
+
return {
|
|
2514
|
+
childScope: new ModelAccessorScope(initialChildScope.current, [...initialChildScope.#visibleBindings, junctionBinding], this.#aliasCounter),
|
|
2515
|
+
junctionBinding
|
|
2516
|
+
};
|
|
2517
|
+
}
|
|
2518
|
+
forJoinedSource(namespaceId, tableName) {
|
|
2519
|
+
if (this.current.isStoredAt(namespaceId, tableName)) return this;
|
|
2520
|
+
const binding = SqlTableBinding.unaliased({
|
|
2521
|
+
namespaceId,
|
|
2522
|
+
tableName
|
|
2523
|
+
});
|
|
2524
|
+
return new ModelAccessorScope(binding, [...this.#visibleBindings, binding], this.#aliasCounter);
|
|
2525
|
+
}
|
|
2526
|
+
#allocateBinding(namespaceId, tableName, aliasKind) {
|
|
2527
|
+
const storage = {
|
|
2528
|
+
namespaceId,
|
|
2529
|
+
tableName
|
|
2530
|
+
};
|
|
2531
|
+
if (!this.#visibleBindings.some((binding) => binding.isReferencedAs(tableName))) return SqlTableBinding.unaliased(storage);
|
|
2532
|
+
return SqlTableBinding.aliased(storage, this.#allocateAlias(aliasKind));
|
|
2533
|
+
}
|
|
2534
|
+
#allocateAlias(kind) {
|
|
2535
|
+
while (true) {
|
|
2536
|
+
const alias = `__orm_${kind}_${this.#aliasCounter.nextId}`;
|
|
2537
|
+
this.#aliasCounter.nextId += 1;
|
|
2538
|
+
if (!this.#visibleBindings.some((binding) => binding.isReferencedAs(alias))) return alias;
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
};
|
|
2462
2542
|
function createModelAccessor(context, namespaceId, modelName, variantName) {
|
|
2543
|
+
const tableName = resolveModelTableName(context.contract, namespaceId, modelName);
|
|
2544
|
+
return createModelAccessorInScope(context, namespaceId, modelName, variantName, ModelAccessorScope.root(namespaceId, tableName));
|
|
2545
|
+
}
|
|
2546
|
+
function createModelAccessorInScope(context, namespaceId, modelName, variantName, scope) {
|
|
2463
2547
|
const contract = context.contract;
|
|
2464
2548
|
const fieldToColumn = getFieldToColumnMap(contract, namespaceId, modelName);
|
|
2465
2549
|
const tableName = resolveModelTableName(contract, namespaceId, modelName);
|
|
@@ -2493,19 +2577,20 @@ function createModelAccessor(context, namespaceId, modelName, variantName) {
|
|
|
2493
2577
|
if (typeof prop !== "string") return;
|
|
2494
2578
|
if (variantCoordinates) {
|
|
2495
2579
|
const variantRelation = variantCoordinates.relations[prop];
|
|
2496
|
-
if (variantRelation) return createRelationFilterAccessor(context, namespaceId, variantCoordinates.name, variantCoordinates.tableName,
|
|
2580
|
+
if (variantRelation) return createRelationFilterAccessor(context, namespaceId, variantCoordinates.name, scope.forJoinedSource(namespaceId, variantCoordinates.tableName), variantRelation);
|
|
2497
2581
|
}
|
|
2498
2582
|
const relation = modelRelations[prop];
|
|
2499
|
-
if (relation) return createRelationFilterAccessor(context, namespaceId, modelName,
|
|
2583
|
+
if (relation) return createRelationFilterAccessor(context, namespaceId, modelName, scope, relation);
|
|
2500
2584
|
const variantField = variantFieldColumns[prop];
|
|
2501
2585
|
const resolvedTable = variantField?.table ?? tableName;
|
|
2586
|
+
const fieldBinding = scope.forJoinedSource(namespaceId, resolvedTable).current;
|
|
2502
2587
|
const columnName = variantField?.column ?? fieldToColumn[prop] ?? prop;
|
|
2503
2588
|
const column = resolveColumn(contract, namespaceId, resolvedTable, columnName);
|
|
2504
2589
|
if (!column) return;
|
|
2505
2590
|
const traits = context.codecDescriptors.descriptorFor(column.codecId)?.traits ?? [];
|
|
2506
2591
|
const operations = opsByCodecId.get(column.codecId) ?? [];
|
|
2507
2592
|
const codec = codecRefForStorageColumn(contract.storage, namespaceId, resolvedTable, columnName);
|
|
2508
|
-
return createScalarFieldAccessor(
|
|
2593
|
+
return createScalarFieldAccessor(fieldBinding, columnName, column.codecId, column.nullable, codec, traits, operations, context);
|
|
2509
2594
|
} }));
|
|
2510
2595
|
}
|
|
2511
2596
|
function resolveColumn(contract, namespaceId, tableName, columnName) {
|
|
@@ -2522,8 +2607,8 @@ function resolveColumn(contract, namespaceId, tableName, columnName) {
|
|
|
2522
2607
|
nullable: column.nullable
|
|
2523
2608
|
};
|
|
2524
2609
|
}
|
|
2525
|
-
function createScalarFieldAccessor(
|
|
2526
|
-
const column =
|
|
2610
|
+
function createScalarFieldAccessor(tableBinding, columnName, codecId, nullable, codec, traits, operations, context) {
|
|
2611
|
+
const column = tableBinding.column(columnName);
|
|
2527
2612
|
const comparisonEntries = [];
|
|
2528
2613
|
for (const [name, meta] of Object.entries(COMPARISON_METHODS_META)) {
|
|
2529
2614
|
if (meta.traits.some((t) => !traits.includes(t))) continue;
|
|
@@ -2558,42 +2643,41 @@ function createExtensionMethodFactory(selfExpr, entry, context) {
|
|
|
2558
2643
|
return methods;
|
|
2559
2644
|
};
|
|
2560
2645
|
}
|
|
2561
|
-
function createRelationFilterAccessor(context, parentNamespaceId, parentModelName,
|
|
2646
|
+
function createRelationFilterAccessor(context, parentNamespaceId, parentModelName, parentScope, relation) {
|
|
2562
2647
|
const relatedTableName = resolveModelTableName(context.contract, relation.toNamespace, relation.to);
|
|
2563
2648
|
return {
|
|
2564
|
-
some: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName,
|
|
2649
|
+
some: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, {
|
|
2565
2650
|
mode: "some",
|
|
2566
2651
|
predicate
|
|
2567
2652
|
}),
|
|
2568
|
-
every: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName,
|
|
2653
|
+
every: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, {
|
|
2569
2654
|
mode: "every",
|
|
2570
2655
|
predicate
|
|
2571
2656
|
}),
|
|
2572
|
-
none: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName,
|
|
2657
|
+
none: (predicate) => buildExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, {
|
|
2573
2658
|
mode: "none",
|
|
2574
2659
|
predicate
|
|
2575
2660
|
})
|
|
2576
2661
|
};
|
|
2577
2662
|
}
|
|
2578
|
-
function buildExistsExpr(context, parentNamespaceId, parentModelName,
|
|
2579
|
-
if (hasThrough$1(relation)) return buildManyToManyExistsExpr(context, parentNamespaceId, parentModelName,
|
|
2580
|
-
const
|
|
2663
|
+
function buildExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, options) {
|
|
2664
|
+
if (hasThrough$1(relation)) return buildManyToManyExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, options);
|
|
2665
|
+
const childScope = parentScope.forRelation(relation.toNamespace, relatedTableName);
|
|
2666
|
+
const filterPlan = planRelationFilterMode(buildJoinWhere(context.contract, parentNamespaceId, parentModelName, parentScope.current, childScope.current, relation), toRelationWhereExpr(context, relation.toNamespace, relation.to, options.predicate, childScope), options.mode);
|
|
2581
2667
|
if (filterPlan.kind === "constantTrue") return AndExpr.true();
|
|
2582
2668
|
const selectProjectionColumn = firstTargetColumn(context.contract, relation) ?? "id";
|
|
2583
|
-
const subquery = SelectAst.from(
|
|
2669
|
+
const subquery = SelectAst.from(childScope.current.tableSource(context.contract)).withProjection([ProjectionItem.of("_exists", childScope.current.column(selectProjectionColumn))]).withWhere(filterPlan.where);
|
|
2584
2670
|
return filterPlan.notExists ? ExistsExpr.notExists(subquery) : ExistsExpr.exists(subquery);
|
|
2585
2671
|
}
|
|
2586
|
-
function buildManyToManyExistsExpr(context, parentNamespaceId, parentModelName,
|
|
2672
|
+
function buildManyToManyExistsExpr(context, parentNamespaceId, parentModelName, parentScope, relatedTableName, relation, options) {
|
|
2587
2673
|
const { through } = relation;
|
|
2588
|
-
const
|
|
2589
|
-
const
|
|
2590
|
-
const relatedTableRef = relatedTableAlias ?? relatedTableName;
|
|
2591
|
-
const junctionJoinOn = buildPairedColumnExprs(junctionTable, through.childColumns, relatedTableRef, through.targetColumns);
|
|
2674
|
+
const { childScope, junctionBinding } = parentScope.forManyToManyRelation(relation.toNamespace, relatedTableName, through.namespaceId, through.table);
|
|
2675
|
+
const junctionJoinOn = buildPairedColumnExprs(junctionBinding, through.childColumns, childScope.current, through.targetColumns);
|
|
2592
2676
|
const parentLocalColumns = relation.on.localFields.map((field) => resolveFieldToColumn(context.contract, parentNamespaceId, parentModelName, field));
|
|
2593
|
-
const filterPlan = planRelationFilterMode(buildPairedColumnExprs(
|
|
2677
|
+
const filterPlan = planRelationFilterMode(buildPairedColumnExprs(junctionBinding, through.parentColumns, parentScope.current, parentLocalColumns), toRelationWhereExpr(context, relation.toNamespace, relation.to, options.predicate, childScope), options.mode);
|
|
2594
2678
|
if (filterPlan.kind === "constantTrue") return AndExpr.true();
|
|
2595
2679
|
const firstTargetCol = firstJoinColumn(through.targetColumns, "targetColumns");
|
|
2596
|
-
const subquery = SelectAst.from(
|
|
2680
|
+
const subquery = SelectAst.from(childScope.current.tableSource(context.contract)).withJoins([JoinAst.inner(junctionBinding.tableSource(context.contract), junctionJoinOn)]).withProjection([ProjectionItem.of("_exists", childScope.current.column(firstTargetCol))]).withWhere(filterPlan.where);
|
|
2597
2681
|
return filterPlan.notExists ? ExistsExpr.notExists(subquery) : ExistsExpr.exists(subquery);
|
|
2598
2682
|
}
|
|
2599
2683
|
function planRelationFilterMode(joinWhere, childWhere, mode) {
|
|
@@ -2616,10 +2700,6 @@ function planRelationFilterMode(joinWhere, childWhere, mode) {
|
|
|
2616
2700
|
where: childWhere ? and(joinWhere, childWhere) : joinWhere
|
|
2617
2701
|
};
|
|
2618
2702
|
}
|
|
2619
|
-
function remapColumnRefs(tableName, tableRef, expr) {
|
|
2620
|
-
if (!expr || tableName === tableRef) return expr;
|
|
2621
|
-
return expr.rewrite({ columnRef: (column) => column.table === tableName ? ColumnRef.of(tableRef, column.column) : column });
|
|
2622
|
-
}
|
|
2623
2703
|
function firstJoinColumn(columns, label) {
|
|
2624
2704
|
const first = columns[0];
|
|
2625
2705
|
if (!first) throw new InternalError(`Relation metadata is missing ${label}`);
|
|
@@ -2633,14 +2713,14 @@ function buildPairedColumnExprs(leftTable, leftColumns, rightTable, rightColumns
|
|
|
2633
2713
|
const left = leftColumns[i];
|
|
2634
2714
|
const right = rightColumns[i];
|
|
2635
2715
|
if (!left || !right) throw new InternalError(`Relation metadata is missing a join column pair at index ${i}`);
|
|
2636
|
-
exprs.push(BinaryExpr.eq(
|
|
2716
|
+
exprs.push(BinaryExpr.eq(leftTable.column(left), rightTable.column(right)));
|
|
2637
2717
|
}
|
|
2638
2718
|
if (exprs.length === 1 && exprs[0]) return exprs[0];
|
|
2639
2719
|
return and(...exprs);
|
|
2640
2720
|
}
|
|
2641
|
-
function toRelationWhereExpr(context, relatedNamespaceId, relatedModelName, predicate) {
|
|
2721
|
+
function toRelationWhereExpr(context, relatedNamespaceId, relatedModelName, predicate, scope) {
|
|
2642
2722
|
if (!predicate) return;
|
|
2643
|
-
const accessor =
|
|
2723
|
+
const accessor = createModelAccessorInScope(context, relatedNamespaceId, relatedModelName, void 0, scope);
|
|
2644
2724
|
if (typeof predicate === "function") return predicate(accessor);
|
|
2645
2725
|
const exprs = [];
|
|
2646
2726
|
for (const [fieldName, value] of Object.entries(predicate)) {
|
|
@@ -2665,7 +2745,7 @@ function toRelationWhereExpr(context, relatedNamespaceId, relatedModelName, pred
|
|
|
2665
2745
|
if (exprs.length === 0) return;
|
|
2666
2746
|
return exprs.length === 1 ? exprs[0] : and(...exprs);
|
|
2667
2747
|
}
|
|
2668
|
-
function buildJoinWhere(contract, parentNamespaceId, parentModelName,
|
|
2748
|
+
function buildJoinWhere(contract, parentNamespaceId, parentModelName, parentTable, relatedTable, relation) {
|
|
2669
2749
|
const localFields = relation.on?.localFields ?? [];
|
|
2670
2750
|
const targetFields = relation.on?.targetFields ?? [];
|
|
2671
2751
|
const joinExprs = [];
|
|
@@ -2676,7 +2756,7 @@ function buildJoinWhere(contract, parentNamespaceId, parentModelName, parentTabl
|
|
|
2676
2756
|
if (!localField || !targetField) continue;
|
|
2677
2757
|
const localColumn = resolveFieldToColumn(contract, parentNamespaceId, parentModelName, localField);
|
|
2678
2758
|
const targetColumn = resolveFieldToColumn(contract, relation.toNamespace, relation.to, targetField);
|
|
2679
|
-
joinExprs.push(BinaryExpr.eq(
|
|
2759
|
+
joinExprs.push(BinaryExpr.eq(relatedTable.column(targetColumn), parentTable.column(localColumn)));
|
|
2680
2760
|
}
|
|
2681
2761
|
if (joinExprs.length === 0) throw new InternalError("Relation metadata is missing join columns");
|
|
2682
2762
|
const firstExpr = joinExprs[0];
|