@prisma-next/sql-orm-lane 0.3.0-dev.3 → 0.3.0-dev.30
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 +2 -2
- package/dist/{chunk-3DNKIXXB.js → chunk-C4EECZ4E.js} +106 -119
- package/dist/chunk-C4EECZ4E.js.map +1 -0
- package/dist/exports/orm.d.ts +3 -5
- package/dist/exports/orm.d.ts.map +1 -0
- package/dist/exports/orm.js +1 -1
- package/dist/index.d.ts +4 -42
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -1
- package/dist/mutations/delete-builder.d.ts +9 -0
- package/dist/mutations/delete-builder.d.ts.map +1 -0
- package/dist/mutations/insert-builder.d.ts +7 -0
- package/dist/mutations/insert-builder.d.ts.map +1 -0
- package/dist/mutations/update-builder.d.ts +9 -0
- package/dist/mutations/update-builder.d.ts.map +1 -0
- package/dist/orm/builder.d.ts +38 -0
- package/dist/orm/builder.d.ts.map +1 -0
- package/dist/orm/capabilities.d.ts +3 -0
- package/dist/orm/capabilities.d.ts.map +1 -0
- package/dist/orm/context.d.ts +5 -0
- package/dist/orm/context.d.ts.map +1 -0
- package/dist/orm/state.d.ts +45 -0
- package/dist/orm/state.d.ts.map +1 -0
- package/dist/orm-include-child.d.ts +35 -0
- package/dist/orm-include-child.d.ts.map +1 -0
- package/dist/orm-relation-filter.d.ts +19 -0
- package/dist/orm-relation-filter.d.ts.map +1 -0
- package/dist/{orm-DAnGd7z2.d.ts → orm-types.d.ts} +16 -27
- package/dist/orm-types.d.ts.map +1 -0
- package/dist/orm.d.ts +5 -0
- package/dist/orm.d.ts.map +1 -0
- package/dist/plan/lowering.d.ts +2 -0
- package/dist/plan/lowering.d.ts.map +1 -0
- package/dist/plan/plan-assembly.d.ts +24 -0
- package/dist/plan/plan-assembly.d.ts.map +1 -0
- package/dist/plan/result-typing.d.ts +2 -0
- package/dist/plan/result-typing.d.ts.map +1 -0
- package/dist/relations/include-plan.d.ts +38 -0
- package/dist/relations/include-plan.d.ts.map +1 -0
- package/dist/selection/join.d.ts +3 -0
- package/dist/selection/join.d.ts.map +1 -0
- package/dist/selection/ordering.d.ts +11 -0
- package/dist/selection/ordering.d.ts.map +1 -0
- package/dist/selection/pagination.d.ts +6 -0
- package/dist/selection/pagination.d.ts.map +1 -0
- package/dist/selection/predicates.d.ts +10 -0
- package/dist/selection/predicates.d.ts.map +1 -0
- package/dist/selection/projection.d.ts +28 -0
- package/dist/selection/projection.d.ts.map +1 -0
- package/dist/selection/select-builder.d.ts +22 -0
- package/dist/selection/select-builder.d.ts.map +1 -0
- package/dist/types/internal.d.ts +4 -0
- package/dist/types/internal.d.ts.map +1 -0
- package/dist/utils/ast.d.ts +2 -0
- package/dist/utils/ast.d.ts.map +1 -0
- package/dist/utils/errors.d.ts +29 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/param-descriptor.d.ts +10 -0
- package/dist/utils/param-descriptor.d.ts.map +1 -0
- package/package.json +21 -21
- package/src/exports/orm.ts +12 -0
- package/src/index.ts +11 -0
- package/src/mutations/delete-builder.ts +87 -0
- package/src/mutations/insert-builder.ts +148 -0
- package/src/mutations/update-builder.ts +141 -0
- package/src/orm/builder.ts +744 -0
- package/src/orm/capabilities.ts +14 -0
- package/src/orm/context.ts +10 -0
- package/src/orm/state.ts +52 -0
- package/src/orm-include-child.ts +169 -0
- package/src/orm-relation-filter.ts +93 -0
- package/src/orm-types.ts +271 -0
- package/src/orm.ts +51 -0
- package/src/plan/lowering.ts +1 -0
- package/src/plan/plan-assembly.ts +312 -0
- package/src/plan/result-typing.ts +1 -0
- package/src/relations/include-plan.ts +324 -0
- package/src/selection/join.ts +13 -0
- package/src/selection/ordering.ts +52 -0
- package/src/selection/pagination.ts +11 -0
- package/src/selection/predicates.ts +104 -0
- package/src/selection/projection.ts +142 -0
- package/src/selection/select-builder.ts +80 -0
- package/src/types/internal.ts +3 -0
- package/src/utils/ast.ts +12 -0
- package/src/utils/errors.ts +130 -0
- package/src/utils/param-descriptor.ts +19 -0
- package/dist/chunk-3DNKIXXB.js.map +0 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { ParamDescriptor } from '@prisma-next/contract/types';
|
|
2
|
+
import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
3
|
+
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
4
|
+
import type { AnyBinaryBuilder, BuildOptions } from '@prisma-next/sql-relational-core/types';
|
|
5
|
+
import type { OrmContext } from '../orm/context';
|
|
6
|
+
import type { ModelColumnAccessor } from '../orm-types';
|
|
7
|
+
import { buildWhereExpr } from '../selection/predicates';
|
|
8
|
+
import { createDeleteAst, createTableRef } from '../utils/ast';
|
|
9
|
+
import { errorFailedToBuildWhereClause, errorModelNotFound } from '../utils/errors';
|
|
10
|
+
|
|
11
|
+
export function buildDeletePlan<
|
|
12
|
+
TContract extends SqlContract<SqlStorage>,
|
|
13
|
+
CodecTypes extends Record<string, { output: unknown }>,
|
|
14
|
+
ModelName extends string,
|
|
15
|
+
>(
|
|
16
|
+
context: OrmContext<TContract>,
|
|
17
|
+
modelName: ModelName,
|
|
18
|
+
where: (model: ModelColumnAccessor<TContract, CodecTypes, ModelName>) => AnyBinaryBuilder,
|
|
19
|
+
getModelAccessor: () => ModelColumnAccessor<TContract, CodecTypes, ModelName>,
|
|
20
|
+
options?: BuildOptions,
|
|
21
|
+
): SqlQueryPlan<number> {
|
|
22
|
+
const modelAccessor = getModelAccessor();
|
|
23
|
+
const wherePredicate = where(modelAccessor);
|
|
24
|
+
|
|
25
|
+
const tableName = context.contract.mappings.modelToTable?.[modelName];
|
|
26
|
+
if (!tableName) {
|
|
27
|
+
errorModelNotFound(modelName);
|
|
28
|
+
}
|
|
29
|
+
const table = createTableRef(tableName);
|
|
30
|
+
|
|
31
|
+
const paramsMap = (options?.params ?? {}) as Record<string, unknown>;
|
|
32
|
+
const paramDescriptors: ParamDescriptor[] = [];
|
|
33
|
+
const paramValues: unknown[] = [];
|
|
34
|
+
const paramCodecs: Record<string, string> = {};
|
|
35
|
+
|
|
36
|
+
const whereResult = buildWhereExpr(
|
|
37
|
+
wherePredicate,
|
|
38
|
+
context.contract,
|
|
39
|
+
paramsMap,
|
|
40
|
+
paramDescriptors,
|
|
41
|
+
paramValues,
|
|
42
|
+
);
|
|
43
|
+
const whereExpr = whereResult.expr;
|
|
44
|
+
if (!whereExpr) {
|
|
45
|
+
errorFailedToBuildWhereClause();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (whereResult?.codecId && whereResult.paramName) {
|
|
49
|
+
paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const ast = createDeleteAst({
|
|
53
|
+
table,
|
|
54
|
+
where: whereExpr,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return Object.freeze({
|
|
58
|
+
ast,
|
|
59
|
+
params: paramValues,
|
|
60
|
+
meta: {
|
|
61
|
+
target: context.contract.target,
|
|
62
|
+
targetFamily: context.contract.targetFamily,
|
|
63
|
+
coreHash: context.contract.coreHash,
|
|
64
|
+
lane: 'orm',
|
|
65
|
+
refs: {
|
|
66
|
+
tables: [tableName],
|
|
67
|
+
columns: [],
|
|
68
|
+
},
|
|
69
|
+
projection: {},
|
|
70
|
+
paramDescriptors,
|
|
71
|
+
...(Object.keys(paramCodecs).length > 0
|
|
72
|
+
? {
|
|
73
|
+
annotations: {
|
|
74
|
+
codecs: paramCodecs,
|
|
75
|
+
intent: 'write',
|
|
76
|
+
isMutation: true,
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
: {
|
|
80
|
+
annotations: {
|
|
81
|
+
intent: 'write',
|
|
82
|
+
isMutation: true,
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import type { ParamDescriptor } from '@prisma-next/contract/types';
|
|
2
|
+
import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
3
|
+
import type { ColumnRef, ParamRef } from '@prisma-next/sql-relational-core/ast';
|
|
4
|
+
import { param } from '@prisma-next/sql-relational-core/param';
|
|
5
|
+
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
6
|
+
import type { BuildOptions, ParamPlaceholder } from '@prisma-next/sql-relational-core/types';
|
|
7
|
+
import type { OrmContext } from '../orm/context';
|
|
8
|
+
import { createInsertAst, createParamRef, createTableRef } from '../utils/ast';
|
|
9
|
+
import {
|
|
10
|
+
assertColumnExists,
|
|
11
|
+
assertParameterExists,
|
|
12
|
+
errorCreateRequiresFields,
|
|
13
|
+
errorModelNotFound,
|
|
14
|
+
errorUnknownTable,
|
|
15
|
+
} from '../utils/errors';
|
|
16
|
+
import { createParamDescriptor } from '../utils/param-descriptor';
|
|
17
|
+
|
|
18
|
+
export function convertModelFieldsToColumns<TContract extends SqlContract<SqlStorage>>(
|
|
19
|
+
contract: TContract,
|
|
20
|
+
modelName: string,
|
|
21
|
+
fields: Record<string, unknown>,
|
|
22
|
+
): Record<string, ParamPlaceholder> {
|
|
23
|
+
const model = contract.models[modelName];
|
|
24
|
+
if (!model || typeof model !== 'object' || !('fields' in model)) {
|
|
25
|
+
throw new Error(`Model ${modelName} does not have fields`);
|
|
26
|
+
}
|
|
27
|
+
const modelFields = model.fields as Record<string, { column?: string }>;
|
|
28
|
+
|
|
29
|
+
const result: Record<string, ParamPlaceholder> = {};
|
|
30
|
+
|
|
31
|
+
for (const fieldName in fields) {
|
|
32
|
+
if (!Object.hasOwn(fields, fieldName)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!Object.hasOwn(modelFields, fieldName)) {
|
|
37
|
+
throw new Error(`Field ${fieldName} does not exist on model ${modelName}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const field = modelFields[fieldName];
|
|
41
|
+
if (!field) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const columnName =
|
|
46
|
+
contract.mappings.fieldToColumn?.[modelName]?.[fieldName] ?? field.column ?? fieldName;
|
|
47
|
+
|
|
48
|
+
result[columnName] = param(fieldName);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function buildInsertPlan<TContract extends SqlContract<SqlStorage>>(
|
|
55
|
+
context: OrmContext<TContract>,
|
|
56
|
+
modelName: string,
|
|
57
|
+
data: Record<string, unknown>,
|
|
58
|
+
options?: BuildOptions,
|
|
59
|
+
): SqlQueryPlan<number> {
|
|
60
|
+
if (!data || Object.keys(data).length === 0) {
|
|
61
|
+
errorCreateRequiresFields();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const values = convertModelFieldsToColumns(context.contract, modelName, data);
|
|
65
|
+
|
|
66
|
+
const tableName = context.contract.mappings.modelToTable?.[modelName];
|
|
67
|
+
if (!tableName) {
|
|
68
|
+
errorModelNotFound(modelName);
|
|
69
|
+
}
|
|
70
|
+
const table = createTableRef(tableName);
|
|
71
|
+
|
|
72
|
+
const paramsMap = {
|
|
73
|
+
...(options?.params ?? {}),
|
|
74
|
+
...data,
|
|
75
|
+
} as Record<string, unknown>;
|
|
76
|
+
const paramDescriptors: ParamDescriptor[] = [];
|
|
77
|
+
const paramValues: unknown[] = [];
|
|
78
|
+
const paramCodecs: Record<string, string> = {};
|
|
79
|
+
|
|
80
|
+
const contractTable = context.contract.storage.tables[tableName];
|
|
81
|
+
if (!contractTable) {
|
|
82
|
+
errorUnknownTable(tableName);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const insertValues: Record<string, ColumnRef | ParamRef> = {};
|
|
86
|
+
for (const [columnName, placeholder] of Object.entries(values)) {
|
|
87
|
+
const columnMeta = contractTable.columns[columnName];
|
|
88
|
+
assertColumnExists(columnMeta, columnName, tableName);
|
|
89
|
+
|
|
90
|
+
const paramName = placeholder.name;
|
|
91
|
+
const value = assertParameterExists(paramsMap, paramName);
|
|
92
|
+
const index = paramValues.push(value);
|
|
93
|
+
|
|
94
|
+
const codecId = columnMeta.codecId;
|
|
95
|
+
if (paramName) {
|
|
96
|
+
paramCodecs[paramName] = codecId;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
paramDescriptors.push(
|
|
100
|
+
createParamDescriptor({
|
|
101
|
+
name: paramName,
|
|
102
|
+
table: tableName,
|
|
103
|
+
column: columnName,
|
|
104
|
+
codecId: codecId,
|
|
105
|
+
nativeType: columnMeta.nativeType,
|
|
106
|
+
nullable: columnMeta.nullable,
|
|
107
|
+
}),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
insertValues[columnName] = createParamRef(index, paramName);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const ast = createInsertAst({
|
|
114
|
+
table,
|
|
115
|
+
values: insertValues,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return Object.freeze({
|
|
119
|
+
ast,
|
|
120
|
+
params: paramValues,
|
|
121
|
+
meta: {
|
|
122
|
+
target: context.contract.target,
|
|
123
|
+
targetFamily: context.contract.targetFamily,
|
|
124
|
+
coreHash: context.contract.coreHash,
|
|
125
|
+
lane: 'orm',
|
|
126
|
+
refs: {
|
|
127
|
+
tables: [tableName],
|
|
128
|
+
columns: [],
|
|
129
|
+
},
|
|
130
|
+
projection: {},
|
|
131
|
+
paramDescriptors,
|
|
132
|
+
...(Object.keys(paramCodecs).length > 0
|
|
133
|
+
? {
|
|
134
|
+
annotations: {
|
|
135
|
+
codecs: paramCodecs,
|
|
136
|
+
intent: 'write',
|
|
137
|
+
isMutation: true,
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
: {
|
|
141
|
+
annotations: {
|
|
142
|
+
intent: 'write',
|
|
143
|
+
isMutation: true,
|
|
144
|
+
},
|
|
145
|
+
}),
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import type { ParamDescriptor } from '@prisma-next/contract/types';
|
|
2
|
+
import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
3
|
+
import type { ColumnRef, ParamRef } from '@prisma-next/sql-relational-core/ast';
|
|
4
|
+
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
5
|
+
import type { AnyBinaryBuilder, BuildOptions } from '@prisma-next/sql-relational-core/types';
|
|
6
|
+
import type { OrmContext } from '../orm/context';
|
|
7
|
+
import type { ModelColumnAccessor } from '../orm-types';
|
|
8
|
+
import { buildWhereExpr } from '../selection/predicates';
|
|
9
|
+
import { createParamRef, createTableRef, createUpdateAst } from '../utils/ast';
|
|
10
|
+
import {
|
|
11
|
+
assertColumnExists,
|
|
12
|
+
assertParameterExists,
|
|
13
|
+
errorFailedToBuildWhereClause,
|
|
14
|
+
errorModelNotFound,
|
|
15
|
+
errorUnknownTable,
|
|
16
|
+
errorUpdateRequiresFields,
|
|
17
|
+
} from '../utils/errors';
|
|
18
|
+
import { createParamDescriptor } from '../utils/param-descriptor';
|
|
19
|
+
import { convertModelFieldsToColumns } from './insert-builder';
|
|
20
|
+
|
|
21
|
+
export function buildUpdatePlan<
|
|
22
|
+
TContract extends SqlContract<SqlStorage>,
|
|
23
|
+
CodecTypes extends Record<string, { output: unknown }>,
|
|
24
|
+
ModelName extends string,
|
|
25
|
+
>(
|
|
26
|
+
context: OrmContext<TContract>,
|
|
27
|
+
modelName: ModelName,
|
|
28
|
+
where: (model: ModelColumnAccessor<TContract, CodecTypes, ModelName>) => AnyBinaryBuilder,
|
|
29
|
+
getModelAccessor: () => ModelColumnAccessor<TContract, CodecTypes, ModelName>,
|
|
30
|
+
data: Record<string, unknown>,
|
|
31
|
+
options?: BuildOptions,
|
|
32
|
+
): SqlQueryPlan<number> {
|
|
33
|
+
if (!data || Object.keys(data).length === 0) {
|
|
34
|
+
errorUpdateRequiresFields();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const set = convertModelFieldsToColumns(context.contract, modelName, data);
|
|
38
|
+
|
|
39
|
+
const modelAccessor = getModelAccessor();
|
|
40
|
+
const wherePredicate = where(modelAccessor);
|
|
41
|
+
|
|
42
|
+
const tableName = context.contract.mappings.modelToTable?.[modelName];
|
|
43
|
+
if (!tableName) {
|
|
44
|
+
errorModelNotFound(modelName);
|
|
45
|
+
}
|
|
46
|
+
const table = createTableRef(tableName);
|
|
47
|
+
|
|
48
|
+
const paramsMap = {
|
|
49
|
+
...(options?.params ?? {}),
|
|
50
|
+
...data,
|
|
51
|
+
} as Record<string, unknown>;
|
|
52
|
+
const paramDescriptors: ParamDescriptor[] = [];
|
|
53
|
+
const paramValues: unknown[] = [];
|
|
54
|
+
const paramCodecs: Record<string, string> = {};
|
|
55
|
+
|
|
56
|
+
const contractTable = context.contract.storage.tables[tableName];
|
|
57
|
+
if (!contractTable) {
|
|
58
|
+
errorUnknownTable(tableName);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const updateSet: Record<string, ColumnRef | ParamRef> = {};
|
|
62
|
+
for (const [columnName, placeholder] of Object.entries(set)) {
|
|
63
|
+
const columnMeta = contractTable.columns[columnName];
|
|
64
|
+
assertColumnExists(columnMeta, columnName, tableName);
|
|
65
|
+
|
|
66
|
+
const paramName = placeholder.name;
|
|
67
|
+
const value = assertParameterExists(paramsMap, paramName);
|
|
68
|
+
const index = paramValues.push(value);
|
|
69
|
+
|
|
70
|
+
const codecId = columnMeta.codecId;
|
|
71
|
+
if (paramName) {
|
|
72
|
+
paramCodecs[paramName] = codecId;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
paramDescriptors.push(
|
|
76
|
+
createParamDescriptor({
|
|
77
|
+
name: paramName,
|
|
78
|
+
table: tableName,
|
|
79
|
+
column: columnName,
|
|
80
|
+
codecId: codecId,
|
|
81
|
+
nativeType: columnMeta.nativeType,
|
|
82
|
+
nullable: columnMeta.nullable,
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
updateSet[columnName] = createParamRef(index, paramName);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const whereResult = buildWhereExpr(
|
|
90
|
+
wherePredicate,
|
|
91
|
+
context.contract,
|
|
92
|
+
paramsMap,
|
|
93
|
+
paramDescriptors,
|
|
94
|
+
paramValues,
|
|
95
|
+
);
|
|
96
|
+
const whereExpr = whereResult.expr;
|
|
97
|
+
if (!whereExpr) {
|
|
98
|
+
errorFailedToBuildWhereClause();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (whereResult?.codecId && whereResult.paramName) {
|
|
102
|
+
paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const ast = createUpdateAst({
|
|
106
|
+
table,
|
|
107
|
+
set: updateSet,
|
|
108
|
+
where: whereExpr,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return Object.freeze({
|
|
112
|
+
ast,
|
|
113
|
+
params: paramValues,
|
|
114
|
+
meta: {
|
|
115
|
+
target: context.contract.target,
|
|
116
|
+
targetFamily: context.contract.targetFamily,
|
|
117
|
+
coreHash: context.contract.coreHash,
|
|
118
|
+
lane: 'orm',
|
|
119
|
+
refs: {
|
|
120
|
+
tables: [tableName],
|
|
121
|
+
columns: [],
|
|
122
|
+
},
|
|
123
|
+
projection: {},
|
|
124
|
+
paramDescriptors,
|
|
125
|
+
...(Object.keys(paramCodecs).length > 0
|
|
126
|
+
? {
|
|
127
|
+
annotations: {
|
|
128
|
+
codecs: paramCodecs,
|
|
129
|
+
intent: 'write',
|
|
130
|
+
isMutation: true,
|
|
131
|
+
},
|
|
132
|
+
}
|
|
133
|
+
: {
|
|
134
|
+
annotations: {
|
|
135
|
+
intent: 'write',
|
|
136
|
+
isMutation: true,
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|