arkormx 2.6.0 → 2.7.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/dist/cli.mjs +53 -7
- package/dist/{index-CpZK_wI9.d.cts → index-C77nMASp.d.mts} +437 -5
- package/dist/{index-DjiQjqkW.d.mts → index-Dnn0lsDy.d.cts} +437 -5
- package/dist/index.cjs +729 -5
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +729 -6
- package/dist/relationship/index.cjs +1 -1
- package/dist/relationship/index.d.cts +1 -1
- package/dist/relationship/index.d.mts +1 -1
- package/dist/relationship/index.mjs +1 -1
- package/dist/{relationship-D9u7BlWh.cjs → relationship-B8FaJYIx.cjs} +135 -7
- package/dist/{relationship-C5hos4aH.mjs → relationship-BuwKUTOb.mjs} +135 -7
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as applyOperationsToPersistedColumnMappingsState, $t as resolvePrismaType, A as getRuntimePrismaClient, An as writeAppliedMigrationsStateToStore, At as buildInverseRelationLine, B as getRegisteredModels, Bt as deriveRelationFieldName, C as getActiveTransactionClient, Cn as markMigrationRun, Ct as applyMigrationRollbackToPrismaSchema, D as getRuntimeDebugHandler, Dn as resolveMigrationStateFilePath, Dt as buildEnumBlock, E as getRuntimeClient, En as removeAppliedMigration, Et as applyOperationsToPrismaSchema, F as loadArkormConfig, Fn as RelationResolutionException, Ft as buildUniqueConstraintLine, G as loadModelsFrom, Gt as formatDefaultValue, H as getRegisteredSeeders, Ht as escapeRegex, I as resetArkormRuntimeForTests, In as ArkormCollection, It as createMigrationTimestamp, J as registerMigrations, Jt as generateMigrationFile, K as loadSeedersFrom, Kt as formatEnumDefaultValue, L as runArkormTransaction, Ln as ArkormException, Lt as deriveCollectionFieldName, M as isDelegateLike, Mn as UnsupportedAdapterFeatureException, Mt as buildModelBlock, N as isQuerySchemaLike, Nn as SetBasedEagerLoader, Nt as buildPrimaryKeyLine, O as getRuntimePaginationCurrentPageResolver, On as supportsDatabaseMigrationState, Ot as buildFieldLine, P as isTransactionCapableClient, Pt as buildRelationLine, Q as resetRuntimeRegistryForTests, Qt as resolveMigrationClassName, R as getRegisteredFactories, Rt as deriveInverseRelationAlias, S as getActiveTransactionAdapter, Sn as markMigrationApplied, St as applyMigrationRollbackToDatabase, T as getRuntimeAdapter, Tn as readAppliedMigrationsStateFromStore, Tt as applyMigrationToPrismaSchema, U as loadFactoriesFrom, Ut as findEnumBlock, V as getRegisteredPaths, Vt as deriveSingularFieldName, W as loadMigrationsFrom, Wt as findModelBlock, X as registerPaths, Xt as pad, Y as registerModels, Yt as getMigrationPlan, Z as registerSeeders, Zt as resolveEnumName, _ as bindAdapterToModels, _n as deleteAppliedMigrationsStateFromStore, _t as PRISMA_ENUM_REGEX, a as HasOneThroughRelation, an as supportsDatabaseReset, at as getPersistedPrimaryKeyGeneration, b as emitRuntimeDebugEvent, bn as getLatestAppliedMigrations, bt as applyCreateTableOperation, c as HasManyRelation, cn as SchemaBuilder, ct as readPersistedColumnMappingsState, d as BelongsToManyRelation, dn as PrimaryKeyGenerationPlanner, dt as resolveColumnMappingsFilePath, en as runMigrationWithPrisma, et as createEmptyPersistedColumnMappingsState, f as Relation, fn as ForeignKeyBuilder, ft as resolvePersistedMetadataFeatures, g as awaitConfiguredModelsRegistration, gn as createEmptyAppliedMigrationsState, gt as PRISMA_ENUM_MEMBER_REGEX, h as URLDriver, hn as computeMigrationChecksum, ht as writePersistedColumnMappingsState, i as MorphManyRelation, in as supportsDatabaseMigrationExecution, it as getPersistedEnumTsType, j as getUserConfig, jn as RuntimeModuleLoader, jt as buildMigrationSource, k as getRuntimePaginationURLDriverFactory, kn as writeAppliedMigrationsState, kt as buildIndexLine, l as BelongsToRelation, ln as EnumBuilder, lt as rebuildPersistedColumnMappingsState, m as Paginator, mn as buildMigrationRunId, mt as validatePersistedMetadataFeaturesForMigrations, n as MorphToManyRelation, nn as stripPrismaSchemaModelsAndEnums, nt as getPersistedColumnMap, o as HasOneRelation, on as toMigrationFileSlug, ot as getPersistedTableMetadata, p as LengthAwarePaginator, pn as buildMigrationIdentity, pt as syncPersistedColumnMappingsFromState, q as registerFactories, qt as formatRelationAction, r as MorphOneRelation, rn as supportsDatabaseCreation, rt as getPersistedEnumMap, s as HasManyThroughRelation, sn as toModelName, st as getPersistedTimestampColumns, t as MorphToRelation, tn as runPrismaCommand, tt as deletePersistedColumnMappingsState, un as TableBuilder, ut as resetPersistedColumnMappingsCache, v as configureArkormRuntime, vn as findAppliedMigration, vt as PRISMA_MODEL_REGEX, w as getDefaultStubsPath, wn as readAppliedMigrationsState, wt as applyMigrationToDatabase, x as ensureArkormConfigLoading, xn as isMigrationApplied, xt as applyDropTableOperation, y as defineConfig, yn as getLastMigrationRun, yt as applyAlterTableOperation, z as getRegisteredMigrations, zt as deriveRelationAlias } from "./relationship-
|
|
1
|
+
import { $ as applyOperationsToPersistedColumnMappingsState, $t as resolvePrismaType, A as getRuntimePrismaClient, An as writeAppliedMigrationsStateToStore, At as buildInverseRelationLine, B as getRegisteredModels, Bt as deriveRelationFieldName, C as getActiveTransactionClient, Cn as markMigrationRun, Ct as applyMigrationRollbackToPrismaSchema, D as getRuntimeDebugHandler, Dn as resolveMigrationStateFilePath, Dt as buildEnumBlock, E as getRuntimeClient, En as removeAppliedMigration, Et as applyOperationsToPrismaSchema, F as loadArkormConfig, Fn as RelationResolutionException, Ft as buildUniqueConstraintLine, G as loadModelsFrom, Gt as formatDefaultValue, H as getRegisteredSeeders, Ht as escapeRegex, I as resetArkormRuntimeForTests, In as ArkormCollection, It as createMigrationTimestamp, J as registerMigrations, Jt as generateMigrationFile, K as loadSeedersFrom, Kt as formatEnumDefaultValue, L as runArkormTransaction, Ln as ArkormException, Lt as deriveCollectionFieldName, M as isDelegateLike, Mn as UnsupportedAdapterFeatureException, Mt as buildModelBlock, N as isQuerySchemaLike, Nn as SetBasedEagerLoader, Nt as buildPrimaryKeyLine, O as getRuntimePaginationCurrentPageResolver, On as supportsDatabaseMigrationState, Ot as buildFieldLine, P as isTransactionCapableClient, Pt as buildRelationLine, Q as resetRuntimeRegistryForTests, Qt as resolveMigrationClassName, R as getRegisteredFactories, Rt as deriveInverseRelationAlias, S as getActiveTransactionAdapter, Sn as markMigrationApplied, St as applyMigrationRollbackToDatabase, T as getRuntimeAdapter, Tn as readAppliedMigrationsStateFromStore, Tt as applyMigrationToPrismaSchema, U as loadFactoriesFrom, Ut as findEnumBlock, V as getRegisteredPaths, Vt as deriveSingularFieldName, W as loadMigrationsFrom, Wt as findModelBlock, X as registerPaths, Xt as pad, Y as registerModels, Yt as getMigrationPlan, Z as registerSeeders, Zt as resolveEnumName, _ as bindAdapterToModels, _n as deleteAppliedMigrationsStateFromStore, _t as PRISMA_ENUM_REGEX, a as HasOneThroughRelation, an as supportsDatabaseReset, at as getPersistedPrimaryKeyGeneration, b as emitRuntimeDebugEvent, bn as getLatestAppliedMigrations, bt as applyCreateTableOperation, c as HasManyRelation, cn as SchemaBuilder, ct as readPersistedColumnMappingsState, d as BelongsToManyRelation, dn as PrimaryKeyGenerationPlanner, dt as resolveColumnMappingsFilePath, en as runMigrationWithPrisma, et as createEmptyPersistedColumnMappingsState, f as Relation, fn as ForeignKeyBuilder, ft as resolvePersistedMetadataFeatures, g as awaitConfiguredModelsRegistration, gn as createEmptyAppliedMigrationsState, gt as PRISMA_ENUM_MEMBER_REGEX, h as URLDriver, hn as computeMigrationChecksum, ht as writePersistedColumnMappingsState, i as MorphManyRelation, in as supportsDatabaseMigrationExecution, it as getPersistedEnumTsType, j as getUserConfig, jn as RuntimeModuleLoader, jt as buildMigrationSource, k as getRuntimePaginationURLDriverFactory, kn as writeAppliedMigrationsState, kt as buildIndexLine, l as BelongsToRelation, ln as EnumBuilder, lt as rebuildPersistedColumnMappingsState, m as Paginator, mn as buildMigrationRunId, mt as validatePersistedMetadataFeaturesForMigrations, n as MorphToManyRelation, nn as stripPrismaSchemaModelsAndEnums, nt as getPersistedColumnMap, o as HasOneRelation, on as toMigrationFileSlug, ot as getPersistedTableMetadata, p as LengthAwarePaginator, pn as buildMigrationIdentity, pt as syncPersistedColumnMappingsFromState, q as registerFactories, qt as formatRelationAction, r as MorphOneRelation, rn as supportsDatabaseCreation, rt as getPersistedEnumMap, s as HasManyThroughRelation, sn as toModelName, st as getPersistedTimestampColumns, t as MorphToRelation, tn as runPrismaCommand, tt as deletePersistedColumnMappingsState, un as TableBuilder, ut as resetPersistedColumnMappingsCache, v as configureArkormRuntime, vn as findAppliedMigration, vt as PRISMA_MODEL_REGEX, w as getDefaultStubsPath, wn as readAppliedMigrationsState, wt as applyMigrationToDatabase, x as ensureArkormConfigLoading, xn as isMigrationApplied, xt as applyDropTableOperation, y as defineConfig, yn as getLastMigrationRun, yt as applyAlterTableOperation, z as getRegisteredMigrations, zt as deriveRelationAlias } from "./relationship-BuwKUTOb.mjs";
|
|
2
2
|
import { Pool } from "pg";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { createRequire } from "module";
|
|
@@ -63,7 +63,8 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
63
63
|
rawSelect: true,
|
|
64
64
|
rawWhere: true,
|
|
65
65
|
distinct: true,
|
|
66
|
-
groupBy: true
|
|
66
|
+
groupBy: true,
|
|
67
|
+
joins: true
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
resolveConfiguredDatabaseName(connectionString) {
|
|
@@ -88,6 +89,85 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
88
89
|
quoteIdentifier(value) {
|
|
89
90
|
return `"${value.replace(/"/g, "\"\"")}"`;
|
|
90
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Wraps bare camelCase identifiers in a fragment of raw SQL with double quotes
|
|
94
|
+
* so PostgreSQL preserves their casing instead of folding them to lower case.
|
|
95
|
+
*
|
|
96
|
+
* Identifiers that are already quoted, string literals, dollar-quoted bodies,
|
|
97
|
+
* comments and function names (a camelCase token immediately followed by `(`)
|
|
98
|
+
* are left untouched. Lower-case identifiers are also left alone since
|
|
99
|
+
* PostgreSQL folds them to the same value with or without quotes.
|
|
100
|
+
*
|
|
101
|
+
* @param sql The raw SQL fragment to normalize.
|
|
102
|
+
* @returns
|
|
103
|
+
*/
|
|
104
|
+
quoteCamelCaseIdentifiers(sql) {
|
|
105
|
+
let result = "";
|
|
106
|
+
let index = 0;
|
|
107
|
+
const isIdentifierStart = (char) => /[A-Za-z_]/.test(char);
|
|
108
|
+
const isIdentifierPart = (char) => /[A-Za-z0-9_$]/.test(char);
|
|
109
|
+
const isMixedCase = (token) => /[A-Z]/.test(token) && /[a-z]/.test(token);
|
|
110
|
+
while (index < sql.length) {
|
|
111
|
+
const char = sql[index];
|
|
112
|
+
if (char === "'") {
|
|
113
|
+
const start = index;
|
|
114
|
+
index += 1;
|
|
115
|
+
while (index < sql.length) {
|
|
116
|
+
if (sql[index] === "'" && sql[index + 1] === "'") {
|
|
117
|
+
index += 2;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (sql[index] === "'") {
|
|
121
|
+
index += 1;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
index += 1;
|
|
125
|
+
}
|
|
126
|
+
result += sql.slice(start, index);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (char === "\"") {
|
|
130
|
+
const start = index;
|
|
131
|
+
index += 1;
|
|
132
|
+
while (index < sql.length) {
|
|
133
|
+
if (sql[index] === "\"" && sql[index + 1] === "\"") {
|
|
134
|
+
index += 2;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (sql[index] === "\"") {
|
|
138
|
+
index += 1;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
index += 1;
|
|
142
|
+
}
|
|
143
|
+
result += sql.slice(start, index);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (char === "$") {
|
|
147
|
+
const tagMatch = /^\$[A-Za-z0-9_]*\$/.exec(sql.slice(index));
|
|
148
|
+
if (tagMatch) {
|
|
149
|
+
const tag = tagMatch[0];
|
|
150
|
+
const closeIndex = sql.indexOf(tag, index + tag.length);
|
|
151
|
+
const end = closeIndex === -1 ? sql.length : closeIndex + tag.length;
|
|
152
|
+
result += sql.slice(index, end);
|
|
153
|
+
index = end;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (isIdentifierStart(char)) {
|
|
158
|
+
const start = index;
|
|
159
|
+
while (index < sql.length && isIdentifierPart(sql[index])) index += 1;
|
|
160
|
+
const token = sql.slice(start, index);
|
|
161
|
+
const isFunctionCall = sql[index] === "(";
|
|
162
|
+
if (isMixedCase(token) && !isFunctionCall) result += this.quoteIdentifier(token);
|
|
163
|
+
else result += token;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
result += char;
|
|
167
|
+
index += 1;
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
91
171
|
quoteLiteral(value) {
|
|
92
172
|
if (value == null) return "null";
|
|
93
173
|
if (typeof value === "number" || typeof value === "bigint") return String(value);
|
|
@@ -107,10 +187,102 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
107
187
|
async executeRawStatement(statement, executor = this.db) {
|
|
108
188
|
await sql.raw(statement).execute(executor);
|
|
109
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Splits a SQL script into individual top-level statements.
|
|
192
|
+
*
|
|
193
|
+
* The PostgreSQL wire protocol used by Kysely rejects scripts that contain
|
|
194
|
+
* more than one command, so multi-statement raw SQL (for example a migration
|
|
195
|
+
* that mixes `do $$ ... $$` blocks with `alter table` statements) must be
|
|
196
|
+
* executed one statement at a time. Semicolons inside single-quoted strings,
|
|
197
|
+
* double-quoted identifiers, dollar-quoted bodies and comments are ignored.
|
|
198
|
+
*
|
|
199
|
+
* @param sql The raw SQL script to split.
|
|
200
|
+
* @returns
|
|
201
|
+
*/
|
|
202
|
+
splitSqlStatements(sql) {
|
|
203
|
+
const statements = [];
|
|
204
|
+
let current = "";
|
|
205
|
+
let index = 0;
|
|
206
|
+
while (index < sql.length) {
|
|
207
|
+
const char = sql[index];
|
|
208
|
+
const next = sql[index + 1];
|
|
209
|
+
if (char === "-" && next === "-") {
|
|
210
|
+
const end = sql.indexOf("\n", index);
|
|
211
|
+
const stop = end === -1 ? sql.length : end;
|
|
212
|
+
current += sql.slice(index, stop);
|
|
213
|
+
index = stop;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
if (char === "/" && next === "*") {
|
|
217
|
+
const end = sql.indexOf("*/", index + 2);
|
|
218
|
+
const stop = end === -1 ? sql.length : end + 2;
|
|
219
|
+
current += sql.slice(index, stop);
|
|
220
|
+
index = stop;
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (char === "'") {
|
|
224
|
+
const start = index;
|
|
225
|
+
index += 1;
|
|
226
|
+
while (index < sql.length) {
|
|
227
|
+
if (sql[index] === "'" && sql[index + 1] === "'") {
|
|
228
|
+
index += 2;
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
if (sql[index] === "'") {
|
|
232
|
+
index += 1;
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
index += 1;
|
|
236
|
+
}
|
|
237
|
+
current += sql.slice(start, index);
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (char === "\"") {
|
|
241
|
+
const start = index;
|
|
242
|
+
index += 1;
|
|
243
|
+
while (index < sql.length) {
|
|
244
|
+
if (sql[index] === "\"" && sql[index + 1] === "\"") {
|
|
245
|
+
index += 2;
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
if (sql[index] === "\"") {
|
|
249
|
+
index += 1;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
index += 1;
|
|
253
|
+
}
|
|
254
|
+
current += sql.slice(start, index);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (char === "$") {
|
|
258
|
+
const tagMatch = /^\$[A-Za-z0-9_]*\$/.exec(sql.slice(index));
|
|
259
|
+
if (tagMatch) {
|
|
260
|
+
const tag = tagMatch[0];
|
|
261
|
+
const closeIndex = sql.indexOf(tag, index + tag.length);
|
|
262
|
+
const end = closeIndex === -1 ? sql.length : closeIndex + tag.length;
|
|
263
|
+
current += sql.slice(index, end);
|
|
264
|
+
index = end;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (char === ";") {
|
|
269
|
+
if (current.trim().length > 0) statements.push(current.trim());
|
|
270
|
+
current = "";
|
|
271
|
+
index += 1;
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
current += char;
|
|
275
|
+
index += 1;
|
|
276
|
+
}
|
|
277
|
+
if (current.trim().length > 0) statements.push(current.trim());
|
|
278
|
+
return statements;
|
|
279
|
+
}
|
|
110
280
|
async rawQuery(spec) {
|
|
111
281
|
const statement = this.interpolateRawSql(spec.sql, spec.bindings);
|
|
282
|
+
const statements = this.splitSqlStatements(statement);
|
|
283
|
+
if (statements.length > 1) return await this.runMultiStatementRawQuery(statements, statement);
|
|
112
284
|
try {
|
|
113
|
-
return (await sql.raw(statement).execute(this.db)).rows ?? [];
|
|
285
|
+
return (await sql.raw(statements[0] ?? statement).execute(this.db)).rows ?? [];
|
|
114
286
|
} catch (error) {
|
|
115
287
|
throw new QueryExecutionException("Raw query execution failed for the Kysely adapter.", {
|
|
116
288
|
code: "QUERY_EXECUTION_FAILED",
|
|
@@ -122,6 +294,45 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
122
294
|
});
|
|
123
295
|
}
|
|
124
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Executes a multi-statement raw SQL script one statement at a time.
|
|
299
|
+
*
|
|
300
|
+
* Each statement is sent individually so the PostgreSQL extended protocol
|
|
301
|
+
* accepts it, and the rows of the last statement that returns any are used as
|
|
302
|
+
* the result. The script is wrapped in a transaction when the adapter is not
|
|
303
|
+
* already operating inside one so partial failures do not leave the database
|
|
304
|
+
* in a half-applied state.
|
|
305
|
+
*
|
|
306
|
+
* @param statements The individual statements to execute in order.
|
|
307
|
+
* @param fullScript The original (joined) script, used for error context.
|
|
308
|
+
* @returns
|
|
309
|
+
*/
|
|
310
|
+
async runMultiStatementRawQuery(statements, fullScript) {
|
|
311
|
+
const execute = async (executor) => {
|
|
312
|
+
let rows = [];
|
|
313
|
+
for (const statement of statements) {
|
|
314
|
+
const result = await sql.raw(statement).execute(executor);
|
|
315
|
+
if (result.rows && result.rows.length > 0) rows = result.rows;
|
|
316
|
+
}
|
|
317
|
+
return rows;
|
|
318
|
+
};
|
|
319
|
+
try {
|
|
320
|
+
if (!this.db.isTransaction) return await this.db.transaction().execute((transaction) => execute(transaction));
|
|
321
|
+
return await execute(this.db);
|
|
322
|
+
} catch (error) {
|
|
323
|
+
throw new QueryExecutionException("Raw query execution failed for the Kysely adapter.", {
|
|
324
|
+
code: "QUERY_EXECUTION_FAILED",
|
|
325
|
+
operation: "adapter.rawQuery",
|
|
326
|
+
delegate: "raw",
|
|
327
|
+
inspection: this.tryInspectRawQuery(fullScript),
|
|
328
|
+
meta: {
|
|
329
|
+
sql: fullScript,
|
|
330
|
+
statements
|
|
331
|
+
},
|
|
332
|
+
cause: error
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
125
336
|
tryInspectRawQuery(statement) {
|
|
126
337
|
return {
|
|
127
338
|
adapter: "kysely",
|
|
@@ -403,6 +614,70 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
403
614
|
if (!groupBy || groupBy.length === 0) return sql``;
|
|
404
615
|
return sql` group by ${sql.join(groupBy.map((column) => sql.ref(this.mapColumn(target, column))), sql`, `)}`;
|
|
405
616
|
}
|
|
617
|
+
buildJoinClause(target, joins) {
|
|
618
|
+
if (!joins || joins.length === 0) return sql``;
|
|
619
|
+
return sql` ${sql.join(joins.map((join) => this.buildSingleJoin(target, join)), sql` `)}`;
|
|
620
|
+
}
|
|
621
|
+
joinKeyword(join) {
|
|
622
|
+
const base = {
|
|
623
|
+
inner: "inner join",
|
|
624
|
+
left: "left join",
|
|
625
|
+
right: "right join",
|
|
626
|
+
full: "full join",
|
|
627
|
+
cross: "cross join"
|
|
628
|
+
}[join.type];
|
|
629
|
+
return join.lateral ? `${base} lateral` : base;
|
|
630
|
+
}
|
|
631
|
+
buildJoinSource(join) {
|
|
632
|
+
if (join.subquery) {
|
|
633
|
+
const subquery = this.buildSelectStatement(join.subquery);
|
|
634
|
+
return join.alias ? sql`(${subquery}) as ${sql.id(join.alias)}` : sql`(${subquery})`;
|
|
635
|
+
}
|
|
636
|
+
if (join.subquerySql) return join.alias ? sql`(${sql.raw(join.subquerySql)}) as ${sql.id(join.alias)}` : sql.raw(`(${join.subquerySql})`);
|
|
637
|
+
const table = this.resolveMappedTable(join.table ?? "");
|
|
638
|
+
return join.alias ? sql`${sql.table(table)} as ${sql.id(join.alias)}` : sql.table(table);
|
|
639
|
+
}
|
|
640
|
+
buildSingleJoin(target, join) {
|
|
641
|
+
const keyword = sql.raw(this.joinKeyword(join));
|
|
642
|
+
const source = this.buildJoinSource(join);
|
|
643
|
+
if (join.type === "cross") return sql`${keyword} ${source}`;
|
|
644
|
+
if (join.constraints.length === 0) return join.lateral ? sql`${keyword} ${source} on true` : sql`${keyword} ${source}`;
|
|
645
|
+
return sql`${keyword} ${source} on ${this.buildJoinConstraints(target, join.constraints)}`;
|
|
646
|
+
}
|
|
647
|
+
buildJoinConstraints(target, constraints) {
|
|
648
|
+
const parts = [];
|
|
649
|
+
constraints.forEach((constraint, index) => {
|
|
650
|
+
if (index > 0) parts.push(sql.raw(` ${constraint.boolean} `));
|
|
651
|
+
parts.push(this.buildJoinConstraint(target, constraint));
|
|
652
|
+
});
|
|
653
|
+
return sql`${sql.join(parts, sql``)}`;
|
|
654
|
+
}
|
|
655
|
+
buildJoinConstraint(target, constraint) {
|
|
656
|
+
if (constraint.type === "column") return sql`${sql.ref(constraint.first)} ${sql.raw(constraint.operator)} ${sql.ref(constraint.second)}`;
|
|
657
|
+
if (constraint.type === "null") return constraint.not ? sql`${sql.ref(constraint.column)} is not null` : sql`${sql.ref(constraint.column)} is null`;
|
|
658
|
+
if (constraint.type === "raw") return this.buildRawWhereCondition({
|
|
659
|
+
type: "raw",
|
|
660
|
+
sql: constraint.sql,
|
|
661
|
+
bindings: constraint.bindings
|
|
662
|
+
});
|
|
663
|
+
if (constraint.type === "nested") return sql`(${this.buildJoinConstraints(target, constraint.constraints)})`;
|
|
664
|
+
const column = sql.ref(constraint.column);
|
|
665
|
+
const operator = constraint.operator;
|
|
666
|
+
if (operator === "is-null") return sql`${column} is null`;
|
|
667
|
+
if (operator === "is-not-null") return sql`${column} is not null`;
|
|
668
|
+
if (operator === "in") {
|
|
669
|
+
const values = this.buildConditionValueList(constraint.value);
|
|
670
|
+
return values.length === 0 ? sql`1 = 0` : sql`${column} in (${sql.join(values)})`;
|
|
671
|
+
}
|
|
672
|
+
if (operator === "not-in") {
|
|
673
|
+
const values = this.buildConditionValueList(constraint.value);
|
|
674
|
+
return values.length === 0 ? sql`1 = 1` : sql`${column} not in (${sql.join(values)})`;
|
|
675
|
+
}
|
|
676
|
+
if (operator === "contains") return sql`${column} like ${`%${String(constraint.value ?? "")}%`}`;
|
|
677
|
+
if (operator === "starts-with") return sql`${column} like ${`${String(constraint.value ?? "")}%`}`;
|
|
678
|
+
if (operator === "ends-with") return sql`${column} like ${`%${String(constraint.value ?? "")}`}`;
|
|
679
|
+
return sql`${column} ${sql.raw(operator)} ${constraint.value}`;
|
|
680
|
+
}
|
|
406
681
|
buildConditionValueList(value) {
|
|
407
682
|
if (Array.isArray(value)) return value;
|
|
408
683
|
return typeof value === "undefined" ? [] : [value];
|
|
@@ -432,7 +707,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
432
707
|
if (segments.length !== bindings.length + 1) throw new ArkormException("Raw where bindings do not match the number of placeholders.");
|
|
433
708
|
const parts = [];
|
|
434
709
|
segments.forEach((segment, index) => {
|
|
435
|
-
if (segment.length > 0) parts.push(sql.raw(segment));
|
|
710
|
+
if (segment.length > 0) parts.push(sql.raw(this.quoteCamelCaseIdentifiers(segment)));
|
|
436
711
|
if (index < bindings.length) parts.push(sql`${bindings[index]}`);
|
|
437
712
|
});
|
|
438
713
|
if (parts.length === 0) return sql`1 = 1`;
|
|
@@ -696,6 +971,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
696
971
|
select ${spec.distinct ? sql`distinct ` : sql``}${this.buildSelectList(spec.target, spec.columns)}
|
|
697
972
|
${this.buildRelationAggregateSelectList(spec.target, spec.relationAggregates)}
|
|
698
973
|
from ${sql.table(this.resolveTable(spec.target))}
|
|
974
|
+
${this.buildJoinClause(spec.target, spec.joins)}
|
|
699
975
|
${this.buildCombinedWhereClause(spec.target, spec.where, spec.relationFilters)}
|
|
700
976
|
${this.buildGroupBy(spec.target, spec.groupBy)}
|
|
701
977
|
${this.buildOrderBy(spec.target, spec.orderBy)}
|
|
@@ -706,6 +982,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
706
982
|
return sql`
|
|
707
983
|
select count(*)::int as count
|
|
708
984
|
from ${sql.table(this.resolveTable(spec.target))}
|
|
985
|
+
${this.buildJoinClause(spec.target, spec.joins)}
|
|
709
986
|
${this.buildCombinedWhereClause(spec.target, spec.where, spec.relationFilters)}
|
|
710
987
|
`;
|
|
711
988
|
}
|
|
@@ -714,6 +991,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
714
991
|
select exists(
|
|
715
992
|
select 1
|
|
716
993
|
from ${sql.table(this.resolveTable(spec.target))}
|
|
994
|
+
${this.buildJoinClause(spec.target, spec.joins)}
|
|
717
995
|
${this.buildCombinedWhereClause(spec.target, spec.where, spec.relationFilters)}
|
|
718
996
|
${this.buildGroupBy(spec.target, spec.groupBy)}
|
|
719
997
|
limit 1
|
|
@@ -1445,6 +1723,10 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
|
|
|
1445
1723
|
operation: "adapter.select",
|
|
1446
1724
|
meta: { feature: "groupBy" }
|
|
1447
1725
|
});
|
|
1726
|
+
if (spec.joins?.length) throw new UnsupportedAdapterFeatureException("Join clauses are not supported by the Prisma compatibility adapter; use a SQL-backed adapter or DB.raw().", {
|
|
1727
|
+
operation: "adapter.select",
|
|
1728
|
+
meta: { feature: "joins" }
|
|
1729
|
+
});
|
|
1448
1730
|
return {
|
|
1449
1731
|
include: this.toQueryInclude(spec.relationLoads),
|
|
1450
1732
|
where: this.toQueryWhere(spec.where),
|
|
@@ -3799,6 +4081,204 @@ const resolveRuntimeCompatibilityQuerySchemaOrThrow = (key, candidates, modelNam
|
|
|
3799
4081
|
return resolved;
|
|
3800
4082
|
};
|
|
3801
4083
|
|
|
4084
|
+
//#endregion
|
|
4085
|
+
//#region src/JoinClause.ts
|
|
4086
|
+
/**
|
|
4087
|
+
* A fluent builder for the `on`/`where` constraints of a join clause.
|
|
4088
|
+
*
|
|
4089
|
+
* Instances are handed to the closure form of the query builder join helpers
|
|
4090
|
+
* (for example `query.join('posts', join => join.on(...).where(...))`) and
|
|
4091
|
+
* mirror Laravel's `JoinClause` surface. Column identifiers are treated as raw
|
|
4092
|
+
* database identifiers (qualify them as `table.column` when needed).
|
|
4093
|
+
*
|
|
4094
|
+
* @author Legacy (3m1n3nc3)
|
|
4095
|
+
*/
|
|
4096
|
+
var JoinClause = class JoinClause {
|
|
4097
|
+
constructor() {
|
|
4098
|
+
this.constraints = [];
|
|
4099
|
+
}
|
|
4100
|
+
/**
|
|
4101
|
+
* Adds a column-to-column `on` constraint, joined with `and`.
|
|
4102
|
+
*
|
|
4103
|
+
* Accepts either a closure (for a nested group) or a column comparison in
|
|
4104
|
+
* the `(first, second)` or `(first, operator, second)` form.
|
|
4105
|
+
*
|
|
4106
|
+
* @param first The left-hand column or a nested closure.
|
|
4107
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
4108
|
+
* @param second The right-hand column.
|
|
4109
|
+
* @returns
|
|
4110
|
+
*/
|
|
4111
|
+
on(first, operator, second) {
|
|
4112
|
+
return this.addOn("and", first, operator, second);
|
|
4113
|
+
}
|
|
4114
|
+
/**
|
|
4115
|
+
* Adds a column-to-column `on` constraint, joined with `or`.
|
|
4116
|
+
*
|
|
4117
|
+
* @param first The left-hand column or a nested closure.
|
|
4118
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
4119
|
+
* @param second The right-hand column.
|
|
4120
|
+
* @returns
|
|
4121
|
+
*/
|
|
4122
|
+
orOn(first, operator, second) {
|
|
4123
|
+
return this.addOn("or", first, operator, second);
|
|
4124
|
+
}
|
|
4125
|
+
/**
|
|
4126
|
+
* Adds a column-to-value constraint, joined with `and`.
|
|
4127
|
+
*
|
|
4128
|
+
* @param column The column being compared.
|
|
4129
|
+
* @param operator The comparison operator or the value when omitted.
|
|
4130
|
+
* @param value The value to compare against.
|
|
4131
|
+
* @returns
|
|
4132
|
+
*/
|
|
4133
|
+
where(column, operator, value) {
|
|
4134
|
+
return this.addWhere("and", column, operator, value);
|
|
4135
|
+
}
|
|
4136
|
+
/**
|
|
4137
|
+
* Adds a column-to-value constraint, joined with `or`.
|
|
4138
|
+
*
|
|
4139
|
+
* @param column The column being compared.
|
|
4140
|
+
* @param operator The comparison operator or the value when omitted.
|
|
4141
|
+
* @param value The value to compare against.
|
|
4142
|
+
* @returns
|
|
4143
|
+
*/
|
|
4144
|
+
orWhere(column, operator, value) {
|
|
4145
|
+
return this.addWhere("or", column, operator, value);
|
|
4146
|
+
}
|
|
4147
|
+
/**
|
|
4148
|
+
* Adds an `is null` constraint joined with `and`.
|
|
4149
|
+
*
|
|
4150
|
+
* @param column The column to test for null.
|
|
4151
|
+
* @returns
|
|
4152
|
+
*/
|
|
4153
|
+
whereNull(column) {
|
|
4154
|
+
this.constraints.push({
|
|
4155
|
+
type: "null",
|
|
4156
|
+
boolean: "and",
|
|
4157
|
+
column,
|
|
4158
|
+
not: false
|
|
4159
|
+
});
|
|
4160
|
+
return this;
|
|
4161
|
+
}
|
|
4162
|
+
/**
|
|
4163
|
+
* Adds an `is null` constraint joined with `or`.
|
|
4164
|
+
*
|
|
4165
|
+
* @param column The column to test for null.
|
|
4166
|
+
* @returns
|
|
4167
|
+
*/
|
|
4168
|
+
orWhereNull(column) {
|
|
4169
|
+
this.constraints.push({
|
|
4170
|
+
type: "null",
|
|
4171
|
+
boolean: "or",
|
|
4172
|
+
column,
|
|
4173
|
+
not: false
|
|
4174
|
+
});
|
|
4175
|
+
return this;
|
|
4176
|
+
}
|
|
4177
|
+
/**
|
|
4178
|
+
* Adds an `is not null` constraint joined with `and`.
|
|
4179
|
+
*
|
|
4180
|
+
* @param column The column to test for non-null.
|
|
4181
|
+
* @returns
|
|
4182
|
+
*/
|
|
4183
|
+
whereNotNull(column) {
|
|
4184
|
+
this.constraints.push({
|
|
4185
|
+
type: "null",
|
|
4186
|
+
boolean: "and",
|
|
4187
|
+
column,
|
|
4188
|
+
not: true
|
|
4189
|
+
});
|
|
4190
|
+
return this;
|
|
4191
|
+
}
|
|
4192
|
+
/**
|
|
4193
|
+
* Adds an `is not null` constraint joined with `or`.
|
|
4194
|
+
*
|
|
4195
|
+
* @param column The column to test for non-null.
|
|
4196
|
+
* @returns
|
|
4197
|
+
*/
|
|
4198
|
+
orWhereNotNull(column) {
|
|
4199
|
+
this.constraints.push({
|
|
4200
|
+
type: "null",
|
|
4201
|
+
boolean: "or",
|
|
4202
|
+
column,
|
|
4203
|
+
not: true
|
|
4204
|
+
});
|
|
4205
|
+
return this;
|
|
4206
|
+
}
|
|
4207
|
+
/**
|
|
4208
|
+
* Adds a raw constraint joined with `and`.
|
|
4209
|
+
*
|
|
4210
|
+
* @param sql The raw SQL fragment (with `?` placeholders for bindings).
|
|
4211
|
+
* @param bindings The values bound to the placeholders.
|
|
4212
|
+
* @returns
|
|
4213
|
+
*/
|
|
4214
|
+
onRaw(sql, bindings = []) {
|
|
4215
|
+
this.constraints.push({
|
|
4216
|
+
type: "raw",
|
|
4217
|
+
boolean: "and",
|
|
4218
|
+
sql,
|
|
4219
|
+
bindings
|
|
4220
|
+
});
|
|
4221
|
+
return this;
|
|
4222
|
+
}
|
|
4223
|
+
/**
|
|
4224
|
+
* Adds a raw constraint joined with `or`.
|
|
4225
|
+
*
|
|
4226
|
+
* @param sql The raw SQL fragment (with `?` placeholders for bindings).
|
|
4227
|
+
* @param bindings The values bound to the placeholders.
|
|
4228
|
+
* @returns
|
|
4229
|
+
*/
|
|
4230
|
+
orOnRaw(sql, bindings = []) {
|
|
4231
|
+
this.constraints.push({
|
|
4232
|
+
type: "raw",
|
|
4233
|
+
boolean: "or",
|
|
4234
|
+
sql,
|
|
4235
|
+
bindings
|
|
4236
|
+
});
|
|
4237
|
+
return this;
|
|
4238
|
+
}
|
|
4239
|
+
/**
|
|
4240
|
+
* Returns the accumulated constraints for this join clause.
|
|
4241
|
+
*
|
|
4242
|
+
* @returns
|
|
4243
|
+
*/
|
|
4244
|
+
getConstraints() {
|
|
4245
|
+
return this.constraints;
|
|
4246
|
+
}
|
|
4247
|
+
addOn(boolean, first, operator, second) {
|
|
4248
|
+
if (typeof first === "function") {
|
|
4249
|
+
const nested = new JoinClause();
|
|
4250
|
+
first(nested);
|
|
4251
|
+
this.constraints.push({
|
|
4252
|
+
type: "nested",
|
|
4253
|
+
boolean,
|
|
4254
|
+
constraints: nested.getConstraints()
|
|
4255
|
+
});
|
|
4256
|
+
return this;
|
|
4257
|
+
}
|
|
4258
|
+
const [resolvedOperator, resolvedSecond] = second === void 0 ? ["=", operator] : [operator, second];
|
|
4259
|
+
if (typeof resolvedSecond !== "string") throw new Error("A join \"on\" constraint requires a second column.");
|
|
4260
|
+
this.constraints.push({
|
|
4261
|
+
type: "column",
|
|
4262
|
+
boolean,
|
|
4263
|
+
first,
|
|
4264
|
+
operator: resolvedOperator ?? "=",
|
|
4265
|
+
second: resolvedSecond
|
|
4266
|
+
});
|
|
4267
|
+
return this;
|
|
4268
|
+
}
|
|
4269
|
+
addWhere(boolean, column, operator, value) {
|
|
4270
|
+
const [resolvedOperator, resolvedValue] = value === void 0 ? ["=", operator] : [operator, value];
|
|
4271
|
+
this.constraints.push({
|
|
4272
|
+
type: "value",
|
|
4273
|
+
boolean,
|
|
4274
|
+
column,
|
|
4275
|
+
operator: resolvedOperator ?? "=",
|
|
4276
|
+
value: resolvedValue
|
|
4277
|
+
});
|
|
4278
|
+
return this;
|
|
4279
|
+
}
|
|
4280
|
+
};
|
|
4281
|
+
|
|
3802
4282
|
//#endregion
|
|
3803
4283
|
//#region src/Exceptions/ModelNotFoundException.ts
|
|
3804
4284
|
/**
|
|
@@ -4770,7 +5250,248 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4770
5250
|
return this;
|
|
4771
5251
|
}
|
|
4772
5252
|
/**
|
|
4773
|
-
* Adds a
|
|
5253
|
+
* Adds a join clause to the query.
|
|
5254
|
+
*
|
|
5255
|
+
* The `first`/`second` arguments are treated as raw database identifiers, so
|
|
5256
|
+
* qualify them as `table.column` when needed. Pass a closure as `first` to
|
|
5257
|
+
* build a compound `on` condition through a {@link JoinClause}.
|
|
5258
|
+
*
|
|
5259
|
+
* @param table The table (or aliased table) to join.
|
|
5260
|
+
* @param first The left-hand column or a closure receiving a JoinClause.
|
|
5261
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
5262
|
+
* @param second The right-hand column.
|
|
5263
|
+
* @param type The join type (defaults to `inner`).
|
|
5264
|
+
* @returns
|
|
5265
|
+
*/
|
|
5266
|
+
join(table, first, operator, second, type = "inner") {
|
|
5267
|
+
return this.addJoin(type, table, first, operator, second);
|
|
5268
|
+
}
|
|
5269
|
+
/**
|
|
5270
|
+
* Adds an inner join clause to the query.
|
|
5271
|
+
*
|
|
5272
|
+
* @param table The table (or aliased table) to join.
|
|
5273
|
+
* @param first The left-hand column or a closure receiving a JoinClause.
|
|
5274
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
5275
|
+
* @param second The right-hand column.
|
|
5276
|
+
* @returns
|
|
5277
|
+
*/
|
|
5278
|
+
innerJoin(table, first, operator, second) {
|
|
5279
|
+
return this.addJoin("inner", table, first, operator, second);
|
|
5280
|
+
}
|
|
5281
|
+
/**
|
|
5282
|
+
* Adds a left join clause to the query.
|
|
5283
|
+
*
|
|
5284
|
+
* @param table The table (or aliased table) to join.
|
|
5285
|
+
* @param first The left-hand column or a closure receiving a JoinClause.
|
|
5286
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
5287
|
+
* @param second The right-hand column.
|
|
5288
|
+
* @returns
|
|
5289
|
+
*/
|
|
5290
|
+
leftJoin(table, first, operator, second) {
|
|
5291
|
+
return this.addJoin("left", table, first, operator, second);
|
|
5292
|
+
}
|
|
5293
|
+
/**
|
|
5294
|
+
* Adds a right join clause to the query.
|
|
5295
|
+
*
|
|
5296
|
+
* @param table The table (or aliased table) to join.
|
|
5297
|
+
* @param first The left-hand column or a closure receiving a JoinClause.
|
|
5298
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
5299
|
+
* @param second The right-hand column.
|
|
5300
|
+
* @returns
|
|
5301
|
+
*/
|
|
5302
|
+
rightJoin(table, first, operator, second) {
|
|
5303
|
+
return this.addJoin("right", table, first, operator, second);
|
|
5304
|
+
}
|
|
5305
|
+
/**
|
|
5306
|
+
* Adds a cross join clause to the query.
|
|
5307
|
+
*
|
|
5308
|
+
* When a `first` column (or closure) is supplied the cross join is promoted
|
|
5309
|
+
* to an inner join with the given constraints, mirroring Laravel's behaviour.
|
|
5310
|
+
*
|
|
5311
|
+
* @param table The table (or aliased table) to join.
|
|
5312
|
+
* @param first Optional column or closure to constrain the join.
|
|
5313
|
+
* @returns
|
|
5314
|
+
*/
|
|
5315
|
+
crossJoin(table, first) {
|
|
5316
|
+
if (first === void 0) return this.addJoin("cross", table);
|
|
5317
|
+
return this.addJoin("inner", table, first);
|
|
5318
|
+
}
|
|
5319
|
+
/**
|
|
5320
|
+
* Adds a join clause that compares a column to a value.
|
|
5321
|
+
*
|
|
5322
|
+
* @param table The table (or aliased table) to join.
|
|
5323
|
+
* @param first The column being compared.
|
|
5324
|
+
* @param operator The comparison operator.
|
|
5325
|
+
* @param value The value to compare against.
|
|
5326
|
+
* @param type The join type (defaults to `inner`).
|
|
5327
|
+
* @returns
|
|
5328
|
+
*/
|
|
5329
|
+
joinWhere(table, first, operator, value, type = "inner") {
|
|
5330
|
+
return this.addJoinWhere(type, table, first, operator, value);
|
|
5331
|
+
}
|
|
5332
|
+
/**
|
|
5333
|
+
* Adds a left join clause that compares a column to a value.
|
|
5334
|
+
*
|
|
5335
|
+
* @param table The table (or aliased table) to join.
|
|
5336
|
+
* @param first The column being compared.
|
|
5337
|
+
* @param operator The comparison operator.
|
|
5338
|
+
* @param value The value to compare against.
|
|
5339
|
+
* @returns
|
|
5340
|
+
*/
|
|
5341
|
+
leftJoinWhere(table, first, operator, value) {
|
|
5342
|
+
return this.addJoinWhere("left", table, first, operator, value);
|
|
5343
|
+
}
|
|
5344
|
+
/**
|
|
5345
|
+
* Adds a right join clause that compares a column to a value.
|
|
5346
|
+
*
|
|
5347
|
+
* @param table The table (or aliased table) to join.
|
|
5348
|
+
* @param first The column being compared.
|
|
5349
|
+
* @param operator The comparison operator.
|
|
5350
|
+
* @param value The value to compare against.
|
|
5351
|
+
* @returns
|
|
5352
|
+
*/
|
|
5353
|
+
rightJoinWhere(table, first, operator, value) {
|
|
5354
|
+
return this.addJoinWhere("right", table, first, operator, value);
|
|
5355
|
+
}
|
|
5356
|
+
/**
|
|
5357
|
+
* Adds a subquery join clause to the query.
|
|
5358
|
+
*
|
|
5359
|
+
* @param query The subquery (a QueryBuilder instance or raw SQL string).
|
|
5360
|
+
* @param alias The alias assigned to the subquery.
|
|
5361
|
+
* @param first The left-hand column or a closure receiving a JoinClause.
|
|
5362
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
5363
|
+
* @param second The right-hand column.
|
|
5364
|
+
* @param type The join type (defaults to `inner`).
|
|
5365
|
+
* @returns
|
|
5366
|
+
*/
|
|
5367
|
+
joinSub(query, alias, first, operator, second, type = "inner") {
|
|
5368
|
+
return this.addJoinSub(type, query, alias, first, operator, second);
|
|
5369
|
+
}
|
|
5370
|
+
/**
|
|
5371
|
+
* Adds a subquery left join clause to the query.
|
|
5372
|
+
*
|
|
5373
|
+
* @param query The subquery (a QueryBuilder instance or raw SQL string).
|
|
5374
|
+
* @param alias The alias assigned to the subquery.
|
|
5375
|
+
* @param first The left-hand column or a closure receiving a JoinClause.
|
|
5376
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
5377
|
+
* @param second The right-hand column.
|
|
5378
|
+
* @returns
|
|
5379
|
+
*/
|
|
5380
|
+
leftJoinSub(query, alias, first, operator, second) {
|
|
5381
|
+
return this.addJoinSub("left", query, alias, first, operator, second);
|
|
5382
|
+
}
|
|
5383
|
+
/**
|
|
5384
|
+
* Adds a subquery right join clause to the query.
|
|
5385
|
+
*
|
|
5386
|
+
* @param query The subquery (a QueryBuilder instance or raw SQL string).
|
|
5387
|
+
* @param alias The alias assigned to the subquery.
|
|
5388
|
+
* @param first The left-hand column or a closure receiving a JoinClause.
|
|
5389
|
+
* @param operator The comparison operator (defaults to `=`).
|
|
5390
|
+
* @param second The right-hand column.
|
|
5391
|
+
* @returns
|
|
5392
|
+
*/
|
|
5393
|
+
rightJoinSub(query, alias, first, operator, second) {
|
|
5394
|
+
return this.addJoinSub("right", query, alias, first, operator, second);
|
|
5395
|
+
}
|
|
5396
|
+
/**
|
|
5397
|
+
* Adds a cross subquery join clause to the query.
|
|
5398
|
+
*
|
|
5399
|
+
* @param query The subquery (a QueryBuilder instance or raw SQL string).
|
|
5400
|
+
* @param alias The alias assigned to the subquery.
|
|
5401
|
+
* @returns
|
|
5402
|
+
*/
|
|
5403
|
+
crossJoinSub(query, alias) {
|
|
5404
|
+
return this.addJoinSub("cross", query, alias);
|
|
5405
|
+
}
|
|
5406
|
+
/**
|
|
5407
|
+
* Adds a lateral join clause to the query.
|
|
5408
|
+
*
|
|
5409
|
+
* @param query The subquery (a QueryBuilder instance or raw SQL string).
|
|
5410
|
+
* @param alias The alias assigned to the subquery.
|
|
5411
|
+
* @param type The join type (defaults to `inner`).
|
|
5412
|
+
* @returns
|
|
5413
|
+
*/
|
|
5414
|
+
joinLateral(query, alias, type = "inner") {
|
|
5415
|
+
return this.addJoinSub(type, query, alias, void 0, void 0, void 0, true);
|
|
5416
|
+
}
|
|
5417
|
+
/**
|
|
5418
|
+
* Adds a lateral left join clause to the query.
|
|
5419
|
+
*
|
|
5420
|
+
* @param query The subquery (a QueryBuilder instance or raw SQL string).
|
|
5421
|
+
* @param alias The alias assigned to the subquery.
|
|
5422
|
+
* @returns
|
|
5423
|
+
*/
|
|
5424
|
+
leftJoinLateral(query, alias) {
|
|
5425
|
+
return this.addJoinSub("left", query, alias, void 0, void 0, void 0, true);
|
|
5426
|
+
}
|
|
5427
|
+
/**
|
|
5428
|
+
* Builds a self-contained select specification used when this query is joined
|
|
5429
|
+
* as a subquery by another query builder.
|
|
5430
|
+
*
|
|
5431
|
+
* @returns
|
|
5432
|
+
*/
|
|
5433
|
+
buildJoinSubquerySpec() {
|
|
5434
|
+
const spec = this.tryBuildSelectSpec(this.buildWhere());
|
|
5435
|
+
if (!spec) throw new UnsupportedAdapterFeatureException("Subquery join could not be compiled into an Arkorm select specification.", {
|
|
5436
|
+
operation: "query.joinSub",
|
|
5437
|
+
model: this.model.name
|
|
5438
|
+
});
|
|
5439
|
+
return spec;
|
|
5440
|
+
}
|
|
5441
|
+
guardJoinSupport() {
|
|
5442
|
+
if (!this.adapter?.capabilities?.joins) throw new UnsupportedAdapterFeatureException("Join clauses are not supported by the current adapter.", {
|
|
5443
|
+
operation: "join",
|
|
5444
|
+
model: this.model.name,
|
|
5445
|
+
meta: { feature: "joins" }
|
|
5446
|
+
});
|
|
5447
|
+
}
|
|
5448
|
+
pushJoin(join) {
|
|
5449
|
+
(this.queryJoins ??= []).push(join);
|
|
5450
|
+
}
|
|
5451
|
+
resolveJoinConstraints(first, operator, second) {
|
|
5452
|
+
if (first === void 0) return [];
|
|
5453
|
+
const clause = new JoinClause();
|
|
5454
|
+
if (typeof first === "function") first(clause);
|
|
5455
|
+
else clause.on(first, operator, second);
|
|
5456
|
+
return clause.getConstraints();
|
|
5457
|
+
}
|
|
5458
|
+
resolveJoinSource(query) {
|
|
5459
|
+
if (typeof query === "string") return { subquerySql: query };
|
|
5460
|
+
return { subquery: query.buildJoinSubquerySpec() };
|
|
5461
|
+
}
|
|
5462
|
+
addJoin(type, table, first, operator, second) {
|
|
5463
|
+
this.guardJoinSupport();
|
|
5464
|
+
this.pushJoin({
|
|
5465
|
+
type,
|
|
5466
|
+
table,
|
|
5467
|
+
constraints: this.resolveJoinConstraints(first, operator, second)
|
|
5468
|
+
});
|
|
5469
|
+
return this;
|
|
5470
|
+
}
|
|
5471
|
+
addJoinWhere(type, table, column, operator, value) {
|
|
5472
|
+
this.guardJoinSupport();
|
|
5473
|
+
const clause = new JoinClause();
|
|
5474
|
+
clause.where(column, operator, value);
|
|
5475
|
+
this.pushJoin({
|
|
5476
|
+
type,
|
|
5477
|
+
table,
|
|
5478
|
+
constraints: clause.getConstraints()
|
|
5479
|
+
});
|
|
5480
|
+
return this;
|
|
5481
|
+
}
|
|
5482
|
+
addJoinSub(type, query, alias, first, operator, second, lateral = false) {
|
|
5483
|
+
this.guardJoinSupport();
|
|
5484
|
+
this.pushJoin({
|
|
5485
|
+
type,
|
|
5486
|
+
alias,
|
|
5487
|
+
...this.resolveJoinSource(query),
|
|
5488
|
+
...lateral ? { lateral: true } : {},
|
|
5489
|
+
constraints: this.resolveJoinConstraints(first, operator, second)
|
|
5490
|
+
});
|
|
5491
|
+
return this;
|
|
5492
|
+
}
|
|
5493
|
+
/**
|
|
5494
|
+
* Adds a skip clause to the query for pagination.
|
|
4774
5495
|
* This will overwrite any existing skip clause.
|
|
4775
5496
|
*
|
|
4776
5497
|
* @param skip
|
|
@@ -6025,6 +6746,7 @@ var QueryBuilder = class QueryBuilder {
|
|
|
6025
6746
|
columns,
|
|
6026
6747
|
distinct: this.queryDistinct || void 0,
|
|
6027
6748
|
groupBy: this.queryGroupBy ? [...this.queryGroupBy] : void 0,
|
|
6749
|
+
joins: this.queryJoins ? [...this.queryJoins] : void 0,
|
|
6028
6750
|
where: condition,
|
|
6029
6751
|
orderBy,
|
|
6030
6752
|
limit: this.limitValue,
|
|
@@ -6041,6 +6763,7 @@ var QueryBuilder = class QueryBuilder {
|
|
|
6041
6763
|
if (this.hasRelationFilters() && this.canExecuteRelationFiltersInAdapter() && relationFilters === null) return null;
|
|
6042
6764
|
return {
|
|
6043
6765
|
target: this.buildQueryTarget(),
|
|
6766
|
+
joins: this.queryJoins ? [...this.queryJoins] : void 0,
|
|
6044
6767
|
where: condition,
|
|
6045
6768
|
relationFilters: this.canExecuteRelationFiltersInAdapter() ? relationFilters ?? void 0 : void 0,
|
|
6046
6769
|
aggregate: { type: "count" }
|
|
@@ -8354,4 +9077,4 @@ var PivotModel = class extends Model {
|
|
|
8354
9077
|
};
|
|
8355
9078
|
|
|
8356
9079
|
//#endregion
|
|
8357
|
-
export { Arkorm, ArkormCollection, ArkormException, Arkormx, Attribute, CliApp, DB, EnumBuilder, ForeignKeyBuilder, InitCommand, InlineFactory, KyselyDatabaseAdapter, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateFreshCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, MissingDelegateException, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_ENUM_MEMBER_REGEX, PRISMA_ENUM_REGEX, PRISMA_MODEL_REGEX, Paginator, PivotModel, PrimaryKeyGenerationPlanner, PrismaDatabaseAdapter, QueryBuilder, QueryConstraintException, QueryExecutionException, RelationResolutionException, RuntimeModuleLoader, SEEDER_BRAND, SchemaBuilder, ScopeNotDefinedException, SeedCommand, Seeder, TableBuilder, URLDriver, UniqueConstraintResolutionException, UnsupportedAdapterFeatureException, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToDatabase, applyMigrationRollbackToPrismaSchema, applyMigrationToDatabase, applyMigrationToPrismaSchema, applyOperationsToPersistedColumnMappingsState, applyOperationsToPrismaSchema, awaitConfiguredModelsRegistration, bindAdapterToModels, buildEnumBlock, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildPrimaryKeyLine, buildRelationLine, buildUniqueConstraintLine, computeMigrationChecksum, configureArkormRuntime, createEmptyAppliedMigrationsState, createEmptyPersistedColumnMappingsState, createKyselyAdapter, createMigrationTimestamp, createPrismaAdapter, createPrismaCompatibilityAdapter, createPrismaDatabaseAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deleteAppliedMigrationsStateFromStore, deletePersistedColumnMappingsState, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationAlias, deriveRelationFieldName, deriveSingularFieldName, emitRuntimeDebugEvent, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findEnumBlock, findModelBlock, formatDefaultValue, formatEnumDefaultValue, formatRelationAction, generateMigrationFile, getActiveTransactionAdapter, getActiveTransactionClient, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getPersistedColumnMap, getPersistedEnumMap, getPersistedEnumTsType, getPersistedPrimaryKeyGeneration, getPersistedTableMetadata, getPersistedTimestampColumns, getRegisteredFactories, getRegisteredMigrations, getRegisteredModels, getRegisteredPaths, getRegisteredSeeders, getRuntimeAdapter, getRuntimeClient, getRuntimeCompatibilityAdapter, getRuntimeDebugHandler, getRuntimePaginationCurrentPageResolver, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, isQuerySchemaLike, isTransactionCapableClient, loadArkormConfig, loadFactoriesFrom, loadMigrationsFrom, loadModelsFrom, loadSeedersFrom, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, readAppliedMigrationsStateFromStore, readPersistedColumnMappingsState, rebuildPersistedColumnMappingsState, registerFactories, registerMigrations, registerModels, registerPaths, registerSeeders, removeAppliedMigration, resetArkormRuntimeForTests, resetPersistedColumnMappingsCache, resetRuntimeRegistryForTests, resolveCast, resolveColumnMappingsFilePath, resolveEnumName, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePersistedMetadataFeatures, resolvePrismaType, resolveRuntimeCompatibilityQuerySchema, resolveRuntimeCompatibilityQuerySchemaOrThrow, runArkormTransaction, runMigrationWithPrisma, runPrismaCommand, stripPrismaSchemaModelsAndEnums, supportsDatabaseCreation, supportsDatabaseMigrationExecution, supportsDatabaseMigrationState, supportsDatabaseReset, syncPersistedColumnMappingsFromState, toMigrationFileSlug, toModelName, validatePersistedMetadataFeaturesForMigrations, writeAppliedMigrationsState, writeAppliedMigrationsStateToStore, writePersistedColumnMappingsState };
|
|
9080
|
+
export { Arkorm, ArkormCollection, ArkormException, Arkormx, Attribute, CliApp, DB, EnumBuilder, ForeignKeyBuilder, InitCommand, InlineFactory, JoinClause, KyselyDatabaseAdapter, LengthAwarePaginator, MIGRATION_BRAND, MakeFactoryCommand, MakeMigrationCommand, MakeModelCommand, MakeSeederCommand, MigrateCommand, MigrateFreshCommand, MigrateRollbackCommand, Migration, MigrationHistoryCommand, MissingDelegateException, Model, ModelFactory, ModelNotFoundException, ModelsSyncCommand, PRISMA_ENUM_MEMBER_REGEX, PRISMA_ENUM_REGEX, PRISMA_MODEL_REGEX, Paginator, PivotModel, PrimaryKeyGenerationPlanner, PrismaDatabaseAdapter, QueryBuilder, QueryConstraintException, QueryExecutionException, RelationResolutionException, RuntimeModuleLoader, SEEDER_BRAND, SchemaBuilder, ScopeNotDefinedException, SeedCommand, Seeder, TableBuilder, URLDriver, UniqueConstraintResolutionException, UnsupportedAdapterFeatureException, applyAlterTableOperation, applyCreateTableOperation, applyDropTableOperation, applyMigrationRollbackToDatabase, applyMigrationRollbackToPrismaSchema, applyMigrationToDatabase, applyMigrationToPrismaSchema, applyOperationsToPersistedColumnMappingsState, applyOperationsToPrismaSchema, awaitConfiguredModelsRegistration, bindAdapterToModels, buildEnumBlock, buildFieldLine, buildIndexLine, buildInverseRelationLine, buildMigrationIdentity, buildMigrationRunId, buildMigrationSource, buildModelBlock, buildPrimaryKeyLine, buildRelationLine, buildUniqueConstraintLine, computeMigrationChecksum, configureArkormRuntime, createEmptyAppliedMigrationsState, createEmptyPersistedColumnMappingsState, createKyselyAdapter, createMigrationTimestamp, createPrismaAdapter, createPrismaCompatibilityAdapter, createPrismaDatabaseAdapter, createPrismaDelegateMap, defineConfig, defineFactory, deleteAppliedMigrationsStateFromStore, deletePersistedColumnMappingsState, deriveCollectionFieldName, deriveInverseRelationAlias, deriveRelationAlias, deriveRelationFieldName, deriveSingularFieldName, emitRuntimeDebugEvent, ensureArkormConfigLoading, escapeRegex, findAppliedMigration, findEnumBlock, findModelBlock, formatDefaultValue, formatEnumDefaultValue, formatRelationAction, generateMigrationFile, getActiveTransactionAdapter, getActiveTransactionClient, getDefaultStubsPath, getLastMigrationRun, getLatestAppliedMigrations, getMigrationPlan, getPersistedColumnMap, getPersistedEnumMap, getPersistedEnumTsType, getPersistedPrimaryKeyGeneration, getPersistedTableMetadata, getPersistedTimestampColumns, getRegisteredFactories, getRegisteredMigrations, getRegisteredModels, getRegisteredPaths, getRegisteredSeeders, getRuntimeAdapter, getRuntimeClient, getRuntimeCompatibilityAdapter, getRuntimeDebugHandler, getRuntimePaginationCurrentPageResolver, getRuntimePaginationURLDriverFactory, getRuntimePrismaClient, getUserConfig, inferDelegateName, isDelegateLike, isMigrationApplied, isQuerySchemaLike, isTransactionCapableClient, loadArkormConfig, loadFactoriesFrom, loadMigrationsFrom, loadModelsFrom, loadSeedersFrom, markMigrationApplied, markMigrationRun, pad, readAppliedMigrationsState, readAppliedMigrationsStateFromStore, readPersistedColumnMappingsState, rebuildPersistedColumnMappingsState, registerFactories, registerMigrations, registerModels, registerPaths, registerSeeders, removeAppliedMigration, resetArkormRuntimeForTests, resetPersistedColumnMappingsCache, resetRuntimeRegistryForTests, resolveCast, resolveColumnMappingsFilePath, resolveEnumName, resolveMigrationClassName, resolveMigrationStateFilePath, resolvePersistedMetadataFeatures, resolvePrismaType, resolveRuntimeCompatibilityQuerySchema, resolveRuntimeCompatibilityQuerySchemaOrThrow, runArkormTransaction, runMigrationWithPrisma, runPrismaCommand, stripPrismaSchemaModelsAndEnums, supportsDatabaseCreation, supportsDatabaseMigrationExecution, supportsDatabaseMigrationState, supportsDatabaseReset, syncPersistedColumnMappingsFromState, toMigrationFileSlug, toModelName, validatePersistedMetadataFeaturesForMigrations, writeAppliedMigrationsState, writeAppliedMigrationsStateToStore, writePersistedColumnMappingsState };
|