@type32/tauri-sqlite-orm 0.2.13 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -8
- package/dist/index.d.mts +359 -176
- package/dist/index.d.ts +359 -176
- package/dist/index.js +868 -851
- package/dist/index.mjs +868 -848
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -1,174 +1,84 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
1
|
+
// src/orm.ts
|
|
2
|
+
import { Kysely as Kysely4, sql as kyselySql } from "kysely";
|
|
3
|
+
|
|
4
|
+
// src/dialect.ts
|
|
5
|
+
import {
|
|
6
|
+
CompiledQuery,
|
|
7
|
+
SqliteAdapter,
|
|
8
|
+
SqliteIntrospector,
|
|
9
|
+
SqliteQueryCompiler
|
|
10
|
+
} from "kysely";
|
|
11
|
+
var TauriConnection = class {
|
|
3
12
|
constructor(db) {
|
|
4
13
|
this.db = db;
|
|
5
14
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
async executeQuery(compiledQuery) {
|
|
16
|
+
const { sql: sql6, parameters } = compiledQuery;
|
|
17
|
+
const params = parameters;
|
|
18
|
+
const trimmed = sql6.trimStart();
|
|
19
|
+
const isSelect = /^\s*(SELECT|WITH|PRAGMA)/i.test(trimmed);
|
|
20
|
+
const hasReturning = /\bRETURNING\b/i.test(sql6);
|
|
21
|
+
if (isSelect || hasReturning) {
|
|
22
|
+
const rows = await this.db.select(sql6, params);
|
|
23
|
+
return { rows };
|
|
24
|
+
}
|
|
25
|
+
const result = await this.db.execute(sql6, params);
|
|
26
|
+
return {
|
|
27
|
+
rows: [],
|
|
28
|
+
insertId: BigInt(Math.round(result.lastInsertId ?? 0)),
|
|
29
|
+
numAffectedRows: BigInt(result.rowsAffected ?? 0)
|
|
30
|
+
};
|
|
12
31
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.query += ` ORDER BY ${column.sql} ${direction}`;
|
|
16
|
-
this.params.push(...column.params);
|
|
17
|
-
} else {
|
|
18
|
-
this.query += ` ORDER BY ${column._.name} ${direction}`;
|
|
19
|
-
}
|
|
20
|
-
return this;
|
|
32
|
+
async *streamQuery(_compiledQuery) {
|
|
33
|
+
throw new Error("Streaming queries are not supported by @tauri-apps/plugin-sql");
|
|
21
34
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
};
|
|
36
|
+
var TauriDriver = class {
|
|
37
|
+
constructor(db) {
|
|
38
|
+
this.db = db;
|
|
25
39
|
}
|
|
26
|
-
|
|
27
|
-
this.query += ` OFFSET ${count2}`;
|
|
28
|
-
return this;
|
|
40
|
+
async init() {
|
|
29
41
|
}
|
|
30
|
-
|
|
31
|
-
return
|
|
32
|
-
sql: this.query,
|
|
33
|
-
params: this.params
|
|
34
|
-
};
|
|
42
|
+
async acquireConnection() {
|
|
43
|
+
return new TauriConnection(this.db);
|
|
35
44
|
}
|
|
36
|
-
|
|
37
|
-
|
|
45
|
+
async beginTransaction(conn, _settings) {
|
|
46
|
+
await conn.executeQuery(CompiledQuery.raw("BEGIN"));
|
|
38
47
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
};
|
|
49
|
-
var ne = (column, value, tableAlias) => {
|
|
50
|
-
const columnName = tableAlias ? `${tableAlias}.${column._.name}` : column._.name;
|
|
51
|
-
return {
|
|
52
|
-
sql: `${columnName} != ?`,
|
|
53
|
-
params: [value]
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
var and = (...conditions) => ({
|
|
57
|
-
sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
|
|
58
|
-
params: conditions.flatMap((c) => c.params)
|
|
59
|
-
});
|
|
60
|
-
var or = (...conditions) => ({
|
|
61
|
-
sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
|
|
62
|
-
params: conditions.flatMap((c) => c.params)
|
|
63
|
-
});
|
|
64
|
-
var not = (condition) => ({
|
|
65
|
-
sql: `NOT (${condition.sql})`,
|
|
66
|
-
params: condition.params
|
|
67
|
-
});
|
|
68
|
-
var gt = (column, value) => ({
|
|
69
|
-
sql: `${column._.name} > ?`,
|
|
70
|
-
params: [value]
|
|
71
|
-
});
|
|
72
|
-
var gte = (column, value) => ({
|
|
73
|
-
sql: `${column._.name} >= ?`,
|
|
74
|
-
params: [value]
|
|
75
|
-
});
|
|
76
|
-
var lt = (column, value) => ({
|
|
77
|
-
sql: `${column._.name} < ?`,
|
|
78
|
-
params: [value]
|
|
79
|
-
});
|
|
80
|
-
var lte = (column, value) => ({
|
|
81
|
-
sql: `${column._.name} <= ?`,
|
|
82
|
-
params: [value]
|
|
83
|
-
});
|
|
84
|
-
var like = (column, pattern) => ({
|
|
85
|
-
sql: `${column._.name} LIKE ?`,
|
|
86
|
-
params: [pattern]
|
|
87
|
-
});
|
|
88
|
-
var ilike = (column, pattern) => ({
|
|
89
|
-
sql: `${column._.name} LIKE ? COLLATE NOCASE`,
|
|
90
|
-
params: [pattern]
|
|
91
|
-
});
|
|
92
|
-
var startsWith = (column, value) => ({
|
|
93
|
-
sql: `${column._.name} LIKE ?`,
|
|
94
|
-
params: [`${value}%`]
|
|
95
|
-
});
|
|
96
|
-
var endsWith = (column, value) => ({
|
|
97
|
-
sql: `${column._.name} LIKE ?`,
|
|
98
|
-
params: [`%${value}`]
|
|
99
|
-
});
|
|
100
|
-
var contains = (column, value) => ({
|
|
101
|
-
sql: `${column._.name} LIKE ?`,
|
|
102
|
-
params: [`%${value}%`]
|
|
103
|
-
});
|
|
104
|
-
var isNull = (column) => ({
|
|
105
|
-
sql: `${column._.name} IS NULL`,
|
|
106
|
-
params: []
|
|
107
|
-
});
|
|
108
|
-
var isNotNull = (column) => ({
|
|
109
|
-
sql: `${column._.name} IS NOT NULL`,
|
|
110
|
-
params: []
|
|
111
|
-
});
|
|
112
|
-
var exists = (subquery2) => ({
|
|
113
|
-
sql: `EXISTS (${subquery2.sql})`,
|
|
114
|
-
params: subquery2.params
|
|
115
|
-
});
|
|
116
|
-
var notExists = (subquery2) => ({
|
|
117
|
-
sql: `NOT EXISTS (${subquery2.sql})`,
|
|
118
|
-
params: subquery2.params
|
|
119
|
-
});
|
|
120
|
-
var eqSubquery = (column, subquery2) => ({
|
|
121
|
-
sql: `${column._.name} = ${subquery2.sql}`,
|
|
122
|
-
params: subquery2.params
|
|
123
|
-
});
|
|
124
|
-
var neSubquery = (column, subquery2) => ({
|
|
125
|
-
sql: `${column._.name} != ${subquery2.sql}`,
|
|
126
|
-
params: subquery2.params
|
|
127
|
-
});
|
|
128
|
-
var gtSubquery = (column, subquery2) => ({
|
|
129
|
-
sql: `${column._.name} > ${subquery2.sql}`,
|
|
130
|
-
params: subquery2.params
|
|
131
|
-
});
|
|
132
|
-
var gteSubquery = (column, subquery2) => ({
|
|
133
|
-
sql: `${column._.name} >= ${subquery2.sql}`,
|
|
134
|
-
params: subquery2.params
|
|
135
|
-
});
|
|
136
|
-
var ltSubquery = (column, subquery2) => ({
|
|
137
|
-
sql: `${column._.name} < ${subquery2.sql}`,
|
|
138
|
-
params: subquery2.params
|
|
139
|
-
});
|
|
140
|
-
var lteSubquery = (column, subquery2) => ({
|
|
141
|
-
sql: `${column._.name} <= ${subquery2.sql}`,
|
|
142
|
-
params: subquery2.params
|
|
143
|
-
});
|
|
144
|
-
var inArray = (column, values) => {
|
|
145
|
-
if ("_isSubquery" in values && values._isSubquery) {
|
|
146
|
-
return {
|
|
147
|
-
sql: `${column._.name} IN ${values.sql}`,
|
|
148
|
-
params: values.params
|
|
149
|
-
};
|
|
48
|
+
async commitTransaction(conn) {
|
|
49
|
+
await conn.executeQuery(CompiledQuery.raw("COMMIT"));
|
|
50
|
+
}
|
|
51
|
+
async rollbackTransaction(conn) {
|
|
52
|
+
await conn.executeQuery(CompiledQuery.raw("ROLLBACK"));
|
|
53
|
+
}
|
|
54
|
+
async releaseConnection(_conn) {
|
|
55
|
+
}
|
|
56
|
+
async destroy() {
|
|
150
57
|
}
|
|
151
|
-
return {
|
|
152
|
-
sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
|
|
153
|
-
params: values
|
|
154
|
-
};
|
|
155
58
|
};
|
|
156
|
-
var
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
59
|
+
var TauriDialect = class {
|
|
60
|
+
constructor(db) {
|
|
61
|
+
this.db = db;
|
|
62
|
+
}
|
|
63
|
+
createAdapter() {
|
|
64
|
+
return new SqliteAdapter();
|
|
65
|
+
}
|
|
66
|
+
createDriver() {
|
|
67
|
+
return new TauriDriver(this.db);
|
|
68
|
+
}
|
|
69
|
+
createIntrospector(db) {
|
|
70
|
+
return new SqliteIntrospector(db);
|
|
71
|
+
}
|
|
72
|
+
createQueryCompiler() {
|
|
73
|
+
return new SqliteQueryCompiler();
|
|
162
74
|
}
|
|
163
|
-
return {
|
|
164
|
-
sql: `${column._.name} NOT IN (${values.map(() => "?").join(",")})`,
|
|
165
|
-
params: values
|
|
166
|
-
};
|
|
167
75
|
};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
76
|
+
|
|
77
|
+
// src/builders/select.ts
|
|
78
|
+
import { sql as sql2 } from "kysely";
|
|
79
|
+
|
|
80
|
+
// src/operators.ts
|
|
81
|
+
import { isExpression, sql } from "kysely";
|
|
172
82
|
|
|
173
83
|
// src/serialization.ts
|
|
174
84
|
function serializeValue(value, column) {
|
|
@@ -271,72 +181,194 @@ function deserializeValue(value, column) {
|
|
|
271
181
|
return value;
|
|
272
182
|
}
|
|
273
183
|
|
|
184
|
+
// src/operators.ts
|
|
185
|
+
var eq = (column, value, tableAlias) => {
|
|
186
|
+
const colRef = tableAlias ? `${tableAlias}.${column._.name}` : column._.name;
|
|
187
|
+
const serialized = serializeValue(value, column);
|
|
188
|
+
return sql`${sql.ref(colRef)} = ${sql.val(serialized)}`;
|
|
189
|
+
};
|
|
190
|
+
var ne = (column, value, tableAlias) => {
|
|
191
|
+
const colRef = tableAlias ? `${tableAlias}.${column._.name}` : column._.name;
|
|
192
|
+
const serialized = serializeValue(value, column);
|
|
193
|
+
return sql`${sql.ref(colRef)} != ${sql.val(serialized)}`;
|
|
194
|
+
};
|
|
195
|
+
var and = (...conditions) => {
|
|
196
|
+
if (conditions.length === 0) return sql`1 = 1`;
|
|
197
|
+
if (conditions.length === 1) return conditions[0];
|
|
198
|
+
return sql`(${sql.join(conditions.map((c) => sql`(${c})`), sql` AND `)})`;
|
|
199
|
+
};
|
|
200
|
+
var or = (...conditions) => {
|
|
201
|
+
if (conditions.length === 0) return sql`1 = 1`;
|
|
202
|
+
if (conditions.length === 1) return conditions[0];
|
|
203
|
+
return sql`(${sql.join(conditions.map((c) => sql`(${c})`), sql` OR `)})`;
|
|
204
|
+
};
|
|
205
|
+
var not = (condition) => sql`NOT (${condition})`;
|
|
206
|
+
var gt = (column, value) => {
|
|
207
|
+
const serialized = serializeValue(value, column);
|
|
208
|
+
return sql`${sql.ref(column._.name)} > ${sql.val(serialized)}`;
|
|
209
|
+
};
|
|
210
|
+
var gte = (column, value) => {
|
|
211
|
+
const serialized = serializeValue(value, column);
|
|
212
|
+
return sql`${sql.ref(column._.name)} >= ${sql.val(serialized)}`;
|
|
213
|
+
};
|
|
214
|
+
var lt = (column, value) => {
|
|
215
|
+
const serialized = serializeValue(value, column);
|
|
216
|
+
return sql`${sql.ref(column._.name)} < ${sql.val(serialized)}`;
|
|
217
|
+
};
|
|
218
|
+
var lte = (column, value) => {
|
|
219
|
+
const serialized = serializeValue(value, column);
|
|
220
|
+
return sql`${sql.ref(column._.name)} <= ${sql.val(serialized)}`;
|
|
221
|
+
};
|
|
222
|
+
var like = (column, pattern) => sql`${sql.ref(column._.name)} LIKE ${sql.val(pattern)}`;
|
|
223
|
+
var ilike = (column, pattern) => sql`${sql.ref(column._.name)} LIKE ${sql.val(pattern)} COLLATE NOCASE`;
|
|
224
|
+
var startsWith = (column, value) => sql`${sql.ref(column._.name)} LIKE ${sql.val(`${value}%`)}`;
|
|
225
|
+
var endsWith = (column, value) => sql`${sql.ref(column._.name)} LIKE ${sql.val(`%${value}`)}`;
|
|
226
|
+
var contains = (column, value) => sql`${sql.ref(column._.name)} LIKE ${sql.val(`%${value}%`)}`;
|
|
227
|
+
var isNull = (column) => sql`${sql.ref(column._.name)} IS NULL`;
|
|
228
|
+
var isNotNull = (column) => sql`${sql.ref(column._.name)} IS NOT NULL`;
|
|
229
|
+
var exists = (subquery2) => sql`EXISTS ${subquery2}`;
|
|
230
|
+
var notExists = (subquery2) => sql`NOT EXISTS ${subquery2}`;
|
|
231
|
+
var eqSubquery = (column, subquery2) => sql`${sql.ref(column._.name)} = (${subquery2})`;
|
|
232
|
+
var neSubquery = (column, subquery2) => sql`${sql.ref(column._.name)} != (${subquery2})`;
|
|
233
|
+
var gtSubquery = (column, subquery2) => sql`${sql.ref(column._.name)} > (${subquery2})`;
|
|
234
|
+
var gteSubquery = (column, subquery2) => sql`${sql.ref(column._.name)} >= (${subquery2})`;
|
|
235
|
+
var ltSubquery = (column, subquery2) => sql`${sql.ref(column._.name)} < (${subquery2})`;
|
|
236
|
+
var lteSubquery = (column, subquery2) => sql`${sql.ref(column._.name)} <= (${subquery2})`;
|
|
237
|
+
var inArray = (column, values) => {
|
|
238
|
+
if (isExpression(values)) {
|
|
239
|
+
return sql`${sql.ref(column._.name)} IN (${values})`;
|
|
240
|
+
}
|
|
241
|
+
const arr = values;
|
|
242
|
+
if (arr.length === 0) return sql`1 = 0`;
|
|
243
|
+
const serialized = arr.map((v) => sql.val(serializeValue(v, column)));
|
|
244
|
+
return sql`${sql.ref(column._.name)} IN (${sql.join(serialized)})`;
|
|
245
|
+
};
|
|
246
|
+
var notIn = (column, values) => {
|
|
247
|
+
if (isExpression(values)) {
|
|
248
|
+
return sql`${sql.ref(column._.name)} NOT IN (${values})`;
|
|
249
|
+
}
|
|
250
|
+
const arr = values;
|
|
251
|
+
if (arr.length === 0) return sql`1 = 1`;
|
|
252
|
+
const serialized = arr.map((v) => sql.val(serializeValue(v, column)));
|
|
253
|
+
return sql`${sql.ref(column._.name)} NOT IN (${sql.join(serialized)})`;
|
|
254
|
+
};
|
|
255
|
+
var between = (column, min2, max2) => {
|
|
256
|
+
const serializedMin = serializeValue(min2, column);
|
|
257
|
+
const serializedMax = serializeValue(max2, column);
|
|
258
|
+
return sql`${sql.ref(column._.name)} BETWEEN ${sql.val(serializedMin)} AND ${sql.val(serializedMax)}`;
|
|
259
|
+
};
|
|
260
|
+
|
|
274
261
|
// src/builders/select.ts
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
262
|
+
function getDbNameToTsName(table) {
|
|
263
|
+
const map = {};
|
|
264
|
+
for (const [tsName, col] of Object.entries(table._.columns)) {
|
|
265
|
+
map[col._.name] = tsName;
|
|
266
|
+
}
|
|
267
|
+
return map;
|
|
268
|
+
}
|
|
269
|
+
function normalizeRowKey(key) {
|
|
270
|
+
if (key.startsWith('"') && key.endsWith('"')) {
|
|
271
|
+
return key.slice(1, -1);
|
|
272
|
+
}
|
|
273
|
+
return key;
|
|
274
|
+
}
|
|
275
|
+
function resolveRelationColumns(table, include) {
|
|
276
|
+
const allEntries = Object.entries(table._.columns);
|
|
277
|
+
if (include === true || typeof include !== "object") {
|
|
278
|
+
return allEntries.map(([, col]) => col);
|
|
279
|
+
}
|
|
280
|
+
const cols = include.columns;
|
|
281
|
+
if (!cols) {
|
|
282
|
+
return allEntries.map(([, col]) => col);
|
|
283
|
+
}
|
|
284
|
+
const names = Array.isArray(cols) ? cols : Object.entries(cols).filter(([, v]) => v).map(([k]) => k);
|
|
285
|
+
const pkNames = allEntries.filter(([, c]) => c.options.primaryKey).map(([k]) => k);
|
|
286
|
+
const combined = /* @__PURE__ */ new Set([...names, ...pkNames]);
|
|
287
|
+
return allEntries.filter(([tsName]) => combined.has(tsName)).map(([, col]) => col);
|
|
288
|
+
}
|
|
289
|
+
var SelectQueryBuilder = class {
|
|
290
|
+
constructor(kysely, table, columns) {
|
|
291
|
+
this.kysely = kysely;
|
|
292
|
+
this._table = table;
|
|
293
|
+
this._columns = columns;
|
|
294
|
+
const selected = columns ? columns.map((c) => table._.columns[c]) : Object.values(table._.columns);
|
|
295
|
+
const colSelections = selected.map(
|
|
296
|
+
(col) => `${table._.name}.${col._.name} as "${table._.name}.${col._.name}"`
|
|
284
297
|
);
|
|
285
|
-
this.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
298
|
+
this._includedColumnAliases = colSelections;
|
|
299
|
+
this._builder = kysely.selectFrom(table._.name).select(colSelections);
|
|
300
|
+
}
|
|
301
|
+
_builder;
|
|
302
|
+
_table;
|
|
303
|
+
_columns;
|
|
304
|
+
_includeRelations = {};
|
|
305
|
+
_manualJoins = [];
|
|
306
|
+
_isDistinct = false;
|
|
307
|
+
_includedColumnAliases = [];
|
|
294
308
|
distinct() {
|
|
295
|
-
this.
|
|
309
|
+
this._isDistinct = true;
|
|
310
|
+
this._builder = this._builder.distinct();
|
|
311
|
+
return this;
|
|
312
|
+
}
|
|
313
|
+
where(condition) {
|
|
314
|
+
this._builder = this._builder.where(condition);
|
|
315
|
+
return this;
|
|
316
|
+
}
|
|
317
|
+
orderBy(column, direction = "asc") {
|
|
318
|
+
if ("toOperationNode" in column) {
|
|
319
|
+
this._builder = this._builder.orderBy(column, direction);
|
|
320
|
+
} else {
|
|
321
|
+
this._builder = this._builder.orderBy(
|
|
322
|
+
sql2.ref(column._.name),
|
|
323
|
+
direction
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
return this;
|
|
327
|
+
}
|
|
328
|
+
limit(count2) {
|
|
329
|
+
this._builder = this._builder.limit(count2);
|
|
330
|
+
return this;
|
|
331
|
+
}
|
|
332
|
+
offset(count2) {
|
|
333
|
+
this._builder = this._builder.offset(count2);
|
|
296
334
|
return this;
|
|
297
335
|
}
|
|
298
336
|
groupBy(...columns) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
337
|
+
for (const col of columns) {
|
|
338
|
+
this._builder = this._builder.groupBy(
|
|
339
|
+
sql2`${sql2.ref(this._table._.name)}.${sql2.ref(col._.name)}`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
302
342
|
return this;
|
|
303
343
|
}
|
|
304
344
|
having(condition) {
|
|
305
|
-
this.
|
|
306
|
-
this.query += ` HAVING ${condition.sql}`;
|
|
307
|
-
this.params.push(...condition.params);
|
|
345
|
+
this._builder = this._builder.having(condition);
|
|
308
346
|
return this;
|
|
309
347
|
}
|
|
310
348
|
leftJoin(table, condition, alias2) {
|
|
311
|
-
this.
|
|
312
|
-
const
|
|
313
|
-
(col) => `${alias2}.${col._.name}
|
|
349
|
+
this._manualJoins.push({ type: "LEFT", table, condition, alias: alias2 });
|
|
350
|
+
const aliasedCols = Object.values(table._.columns).map(
|
|
351
|
+
(col) => `${alias2}.${col._.name} as "${alias2}.${col._.name}"`
|
|
314
352
|
);
|
|
315
|
-
this.
|
|
353
|
+
this._builder = this._builder.leftJoin(`${table._.name} as ${alias2}`, (join) => join.on(condition)).select(aliasedCols);
|
|
316
354
|
return this;
|
|
317
355
|
}
|
|
318
356
|
innerJoin(table, condition, alias2) {
|
|
319
|
-
this.
|
|
320
|
-
const
|
|
321
|
-
(col) => `${alias2}.${col._.name}
|
|
357
|
+
this._manualJoins.push({ type: "INNER", table, condition, alias: alias2 });
|
|
358
|
+
const aliasedCols = Object.values(table._.columns).map(
|
|
359
|
+
(col) => `${alias2}.${col._.name} as "${alias2}.${col._.name}"`
|
|
322
360
|
);
|
|
323
|
-
this.
|
|
361
|
+
this._builder = this._builder.innerJoin(`${table._.name} as ${alias2}`, (join) => join.on(condition)).select(aliasedCols);
|
|
324
362
|
return this;
|
|
325
363
|
}
|
|
326
364
|
include(relations2) {
|
|
327
|
-
this.
|
|
365
|
+
this._includeRelations = { ...this._includeRelations, ...relations2 };
|
|
328
366
|
return this;
|
|
329
367
|
}
|
|
330
|
-
|
|
331
|
-
let sql2 = "";
|
|
332
|
-
const params = [];
|
|
333
|
-
for (const join of this.joins) {
|
|
334
|
-
sql2 += ` ${join.type} JOIN ${join.table._.name} ${join.alias} ON ${join.condition.sql}`;
|
|
335
|
-
params.push(...join.condition.params);
|
|
336
|
-
}
|
|
368
|
+
applyIncludes() {
|
|
337
369
|
const processRelations = (parentTable, parentAlias, relations2, depth = 0) => {
|
|
338
370
|
if (depth > 10) {
|
|
339
|
-
console.warn("[Tauri-ORM] Maximum relation depth (10) exceeded.
|
|
371
|
+
console.warn("[Tauri-ORM] Maximum relation depth (10) exceeded.");
|
|
340
372
|
return;
|
|
341
373
|
}
|
|
342
374
|
for (const [relationName, include] of Object.entries(relations2)) {
|
|
@@ -344,77 +376,72 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
|
344
376
|
const relation = parentTable.relations[relationName];
|
|
345
377
|
if (!relation) {
|
|
346
378
|
console.warn(
|
|
347
|
-
`[Tauri-ORM] Relation "${relationName}" not found on table "${parentTable._.name}". Skipping
|
|
379
|
+
`[Tauri-ORM] Relation "${relationName}" not found on table "${parentTable._.name}". Skipping.`
|
|
348
380
|
);
|
|
349
381
|
continue;
|
|
350
382
|
}
|
|
351
383
|
const foreignTable = relation.foreignTable;
|
|
352
384
|
const foreignAlias = `${parentAlias}_${relationName}`;
|
|
353
|
-
const
|
|
354
|
-
|
|
385
|
+
const selectedCols = resolveRelationColumns(foreignTable, include);
|
|
386
|
+
const aliasedCols = selectedCols.map(
|
|
387
|
+
(col) => `${foreignAlias}.${col._.name} as "${foreignAlias}.${col._.name}"`
|
|
355
388
|
);
|
|
356
|
-
this.selectedColumns.push(...aliasedColumns);
|
|
357
389
|
if (relation.type === "one" && relation.fields && relation.references) {
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
params.push(...condition.params);
|
|
390
|
+
const onCondition = sql2`${sql2.join(
|
|
391
|
+
relation.fields.map(
|
|
392
|
+
(field, i) => sql2`${sql2.ref(`${parentAlias}.${field._.name}`)} = ${sql2.ref(`${foreignAlias}.${relation.references[i]._.name}`)}`
|
|
393
|
+
),
|
|
394
|
+
sql2` AND `
|
|
395
|
+
)}`;
|
|
396
|
+
this._builder = this._builder.leftJoin(
|
|
397
|
+
`${foreignTable._.name} as ${foreignAlias}`,
|
|
398
|
+
(join) => join.on(onCondition)
|
|
399
|
+
).select(aliasedCols);
|
|
369
400
|
} else if (relation.type === "many") {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
const
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
});
|
|
415
|
-
const foreignCondition = foreignConditions.length > 1 ? and(...foreignConditions) : foreignConditions[0];
|
|
416
|
-
sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${foreignCondition.sql}`;
|
|
417
|
-
params.push(...foreignCondition.params);
|
|
401
|
+
if (relation.junctionTable && relation.fromJunction && relation.toJunction) {
|
|
402
|
+
const junctionTable = relation.junctionTable;
|
|
403
|
+
const junctionAlias = `${foreignAlias}_jn`;
|
|
404
|
+
const fromJ = relation.fromJunction;
|
|
405
|
+
const toJ = relation.toJunction;
|
|
406
|
+
const join1 = sql2`${sql2.ref(`${parentAlias}.${fromJ.column._.name}`)} = ${sql2.ref(`${junctionAlias}.${fromJ.junctionColumn._.name}`)}`;
|
|
407
|
+
let join2 = sql2`${sql2.ref(`${junctionAlias}.${toJ.junctionColumn._.name}`)} = ${sql2.ref(`${foreignAlias}.${toJ.column._.name}`)}`;
|
|
408
|
+
if (relation.where) {
|
|
409
|
+
join2 = and(join2, relation.where(foreignAlias));
|
|
410
|
+
}
|
|
411
|
+
this._builder = this._builder.leftJoin(
|
|
412
|
+
`${junctionTable._.name} as ${junctionAlias}`,
|
|
413
|
+
(join) => join.on(join1)
|
|
414
|
+
).leftJoin(
|
|
415
|
+
`${foreignTable._.name} as ${foreignAlias}`,
|
|
416
|
+
(join) => join.on(join2)
|
|
417
|
+
).select(aliasedCols);
|
|
418
|
+
} else {
|
|
419
|
+
let fields = relation.fields;
|
|
420
|
+
let references = relation.references;
|
|
421
|
+
if (!fields || !references) {
|
|
422
|
+
const refRelation = Object.entries(foreignTable.relations).find(
|
|
423
|
+
([, r]) => r.foreignTable === parentTable
|
|
424
|
+
);
|
|
425
|
+
if (refRelation && refRelation[1].fields && refRelation[1].references) {
|
|
426
|
+
const [, relationConfig] = refRelation;
|
|
427
|
+
fields = relationConfig.fields;
|
|
428
|
+
references = relationConfig.references;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (fields && references) {
|
|
432
|
+
let onCondition = sql2`${sql2.join(
|
|
433
|
+
fields.map(
|
|
434
|
+
(field, i) => sql2`${sql2.ref(`${foreignAlias}.${field._.name}`)} = ${sql2.ref(`${parentAlias}.${references[i]._.name}`)}`
|
|
435
|
+
),
|
|
436
|
+
sql2` AND `
|
|
437
|
+
)}`;
|
|
438
|
+
if (relation.where) {
|
|
439
|
+
onCondition = and(onCondition, relation.where(foreignAlias));
|
|
440
|
+
}
|
|
441
|
+
this._builder = this._builder.leftJoin(
|
|
442
|
+
`${foreignTable._.name} as ${foreignAlias}`,
|
|
443
|
+
(join) => join.on(onCondition)
|
|
444
|
+
).select(aliasedCols);
|
|
418
445
|
}
|
|
419
446
|
}
|
|
420
447
|
}
|
|
@@ -423,184 +450,160 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
|
423
450
|
}
|
|
424
451
|
}
|
|
425
452
|
};
|
|
426
|
-
processRelations(this.
|
|
427
|
-
return { sql: sql2, params };
|
|
453
|
+
processRelations(this._table, this._table._.name, this._includeRelations, 0);
|
|
428
454
|
}
|
|
429
|
-
// Enhanced execute method that handles relation data mapping
|
|
430
455
|
async execute() {
|
|
431
|
-
|
|
432
|
-
const
|
|
433
|
-
const
|
|
434
|
-
let fromPart = this.query;
|
|
435
|
-
let wherePart = "";
|
|
436
|
-
if (whereIndex !== -1) {
|
|
437
|
-
fromPart = this.query.substring(0, whereIndex);
|
|
438
|
-
wherePart = this.query.substring(whereIndex);
|
|
439
|
-
}
|
|
440
|
-
this.query = `SELECT ${distinct}${this.selectedColumns.join(", ")} ${fromPart}${joinSql}${wherePart}`;
|
|
441
|
-
this.params = [...joinParams, ...this.params];
|
|
442
|
-
const { sql: sql2, params } = this.build();
|
|
443
|
-
const rawResults = await this.db.select(sql2, params);
|
|
444
|
-
const hasIncludes = Object.values(this.includeRelations).some((i) => i);
|
|
456
|
+
this.applyIncludes();
|
|
457
|
+
const rawResults = await this._builder.execute();
|
|
458
|
+
const hasIncludes = Object.values(this._includeRelations).some((i) => i);
|
|
445
459
|
if (hasIncludes) {
|
|
446
460
|
return this.processRelationResults(rawResults);
|
|
447
461
|
}
|
|
448
|
-
const
|
|
449
|
-
if (
|
|
462
|
+
const hasManualJoins = this._manualJoins.length > 0;
|
|
463
|
+
if (hasManualJoins) {
|
|
450
464
|
return rawResults;
|
|
451
465
|
}
|
|
452
|
-
const prefix = `${this.
|
|
466
|
+
const prefix = `${this._table._.name}.`;
|
|
467
|
+
const dbNameToTs = getDbNameToTsName(this._table);
|
|
453
468
|
return rawResults.map((row) => {
|
|
454
|
-
const
|
|
469
|
+
const out = {};
|
|
455
470
|
for (const key in row) {
|
|
456
|
-
const
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
newRow[columnName] = row[key];
|
|
462
|
-
}
|
|
471
|
+
const normKey = normalizeRowKey(key);
|
|
472
|
+
const dbColName = normKey.startsWith(prefix) ? normKey.slice(prefix.length) : normKey;
|
|
473
|
+
const tsName = dbNameToTs[dbColName] ?? dbColName;
|
|
474
|
+
const column = this._table._.columns[tsName];
|
|
475
|
+
out[tsName] = column ? deserializeValue(row[key], column) : row[key];
|
|
463
476
|
}
|
|
464
|
-
return
|
|
477
|
+
return out;
|
|
465
478
|
});
|
|
466
479
|
}
|
|
467
480
|
processRelationResults(rawResults) {
|
|
468
481
|
if (!rawResults.length) return [];
|
|
469
|
-
const mainTablePks = Object.values(this.
|
|
470
|
-
if (mainTablePks.length === 0)
|
|
471
|
-
return rawResults;
|
|
472
|
-
}
|
|
482
|
+
const mainTablePks = Object.values(this._table._.columns).filter((c) => c.options.primaryKey).map((c) => c._.name);
|
|
483
|
+
if (mainTablePks.length === 0) return rawResults;
|
|
473
484
|
const groupedResults = /* @__PURE__ */ new Map();
|
|
474
485
|
const parseRelationPath = (tableAlias, baseAlias) => {
|
|
475
|
-
if (!tableAlias.startsWith(baseAlias + "_"))
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
const path = tableAlias.substring(baseAlias.length + 1);
|
|
479
|
-
return path.split("_");
|
|
486
|
+
if (!tableAlias.startsWith(baseAlias + "_")) return [];
|
|
487
|
+
return tableAlias.slice(baseAlias.length + 1).split("_");
|
|
480
488
|
};
|
|
481
|
-
const setNestedValue = (obj, path,
|
|
482
|
-
let
|
|
489
|
+
const setNestedValue = (obj, path, columnName, value) => {
|
|
490
|
+
let cur = obj;
|
|
483
491
|
for (let i = 0; i < path.length; i++) {
|
|
484
492
|
const key = path[i];
|
|
485
493
|
if (i === path.length - 1) {
|
|
486
|
-
if (!
|
|
487
|
-
|
|
494
|
+
if (!cur[key]) cur[key] = {};
|
|
495
|
+
cur[key][columnName] = value;
|
|
488
496
|
} else {
|
|
489
|
-
if (!
|
|
490
|
-
|
|
497
|
+
if (!cur[key]) cur[key] = {};
|
|
498
|
+
cur = cur[key];
|
|
491
499
|
}
|
|
492
500
|
}
|
|
493
501
|
};
|
|
494
502
|
const getNestedRelation = (table, path) => {
|
|
495
|
-
let
|
|
496
|
-
let
|
|
497
|
-
for (const
|
|
498
|
-
|
|
499
|
-
if (!
|
|
500
|
-
|
|
503
|
+
let current = table;
|
|
504
|
+
let relation = null;
|
|
505
|
+
for (const name of path) {
|
|
506
|
+
relation = current.relations[name];
|
|
507
|
+
if (!relation) return null;
|
|
508
|
+
current = relation.foreignTable;
|
|
501
509
|
}
|
|
502
|
-
return
|
|
510
|
+
return relation;
|
|
503
511
|
};
|
|
504
512
|
for (const row of rawResults) {
|
|
505
|
-
const
|
|
513
|
+
const getVal = (logicalKey) => {
|
|
514
|
+
const quoted = `"${logicalKey}"`;
|
|
515
|
+
return row[quoted] ?? row[logicalKey];
|
|
516
|
+
};
|
|
517
|
+
const mainTableKey = mainTablePks.map((pk) => getVal(`${this._table._.name}.${pk}`) ?? getVal(pk)).join("_");
|
|
506
518
|
if (!groupedResults.has(mainTableKey)) {
|
|
507
519
|
groupedResults.set(mainTableKey, {});
|
|
508
520
|
}
|
|
509
521
|
const result = groupedResults.get(mainTableKey);
|
|
510
522
|
const relations2 = {};
|
|
511
523
|
for (const [key, value] of Object.entries(row)) {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
524
|
+
const normKey = normalizeRowKey(key);
|
|
525
|
+
if (!normKey.includes(".")) {
|
|
526
|
+
const mainDbToTs = getDbNameToTsName(this._table);
|
|
527
|
+
const tsName = mainDbToTs[normKey] ?? normKey;
|
|
528
|
+
const column = this._table._.columns[tsName];
|
|
529
|
+
result[tsName] = column ? deserializeValue(value, column) : value;
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
const dotIndex = normKey.indexOf(".");
|
|
533
|
+
const tableAlias = normKey.slice(0, dotIndex);
|
|
534
|
+
const columnName = normKey.slice(dotIndex + 1);
|
|
535
|
+
if (tableAlias === this._table._.name) {
|
|
536
|
+
const mainDbToTs = getDbNameToTsName(this._table);
|
|
537
|
+
const tsName = mainDbToTs[columnName] ?? columnName;
|
|
538
|
+
const column = this._table._.columns[tsName];
|
|
539
|
+
result[tsName] = column ? deserializeValue(value, column) : value;
|
|
540
|
+
} else {
|
|
541
|
+
if (tableAlias.endsWith("_jn")) continue;
|
|
542
|
+
const path = parseRelationPath(tableAlias, this._table._.name);
|
|
543
|
+
if (path.length > 0) {
|
|
544
|
+
const relationConfig = getNestedRelation(this._table, path);
|
|
545
|
+
const foreignTable = relationConfig?.foreignTable;
|
|
546
|
+
const foreignDbToTs = foreignTable ? getDbNameToTsName(foreignTable) : {};
|
|
547
|
+
const tsName = foreignDbToTs[columnName] ?? columnName;
|
|
548
|
+
const col = foreignTable?._.columns?.[tsName];
|
|
549
|
+
setNestedValue(relations2, path, tsName, col ? deserializeValue(value, col) : value);
|
|
517
550
|
} else {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
const relationConfig = getNestedRelation(this.table, relationPath);
|
|
521
|
-
const column = relationConfig?.foreignTable?._.columns?.[columnName];
|
|
522
|
-
const deserializedValue = column ? deserializeValue(value, column) : value;
|
|
523
|
-
setNestedValue(relations2, relationPath, deserializedValue, columnName);
|
|
524
|
-
} else {
|
|
525
|
-
if (!result[tableAlias]) result[tableAlias] = {};
|
|
526
|
-
result[tableAlias][columnName] = value;
|
|
527
|
-
}
|
|
551
|
+
if (!result[tableAlias]) result[tableAlias] = {};
|
|
552
|
+
result[tableAlias][columnName] = value;
|
|
528
553
|
}
|
|
529
|
-
} else {
|
|
530
|
-
const column = this.table._.columns[key];
|
|
531
|
-
result[key] = column ? deserializeValue(value, column) : value;
|
|
532
554
|
}
|
|
533
555
|
}
|
|
534
|
-
const attachRelations = (target,
|
|
535
|
-
for (const [relName,
|
|
536
|
-
const
|
|
537
|
-
const relationConfig = getNestedRelation(table, currentPath);
|
|
556
|
+
const attachRelations = (target, relData, table) => {
|
|
557
|
+
for (const [relName, data] of Object.entries(relData)) {
|
|
558
|
+
const relationConfig = table.relations[relName];
|
|
538
559
|
if (!relationConfig) continue;
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
}
|
|
548
|
-
if (relationConfig.type === "many" || relationConfig.type === "manyToMany") {
|
|
549
|
-
if (!target[relName]) target[relName] = [];
|
|
550
|
-
const directData = {};
|
|
551
|
-
const nestedData = {};
|
|
552
|
-
if (typeof relData === "object" && relData !== null) {
|
|
553
|
-
for (const [k, v] of Object.entries(relData)) {
|
|
554
|
-
if (typeof v === "object" && v !== null) {
|
|
555
|
-
nestedData[k] = v;
|
|
556
|
-
} else {
|
|
557
|
-
directData[k] = v;
|
|
558
|
-
}
|
|
560
|
+
const directData = {};
|
|
561
|
+
const nestedData = {};
|
|
562
|
+
if (typeof data === "object" && data !== null) {
|
|
563
|
+
for (const [k, v] of Object.entries(data)) {
|
|
564
|
+
if (typeof v === "object" && v !== null) {
|
|
565
|
+
nestedData[k] = v;
|
|
566
|
+
} else {
|
|
567
|
+
directData[k] = v;
|
|
559
568
|
}
|
|
560
569
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
)
|
|
570
|
+
}
|
|
571
|
+
const hasData = Object.values(directData).some(
|
|
572
|
+
(v) => v !== null && v !== void 0 && v !== ""
|
|
573
|
+
);
|
|
574
|
+
if (relationConfig.type === "many") {
|
|
575
|
+
if (!target[relName]) target[relName] = [];
|
|
564
576
|
if (hasData) {
|
|
565
|
-
const
|
|
566
|
-
const
|
|
567
|
-
if (
|
|
577
|
+
const relPks = Object.values(relationConfig.foreignTable._.columns).filter((c) => c.options.primaryKey).map((c) => c._.name);
|
|
578
|
+
const key = relPks.map((pk) => directData[pk]).join("_");
|
|
579
|
+
if (relPks.length === 0 || !target[relName].some(
|
|
580
|
+
(r) => relPks.map((pk) => r[pk]).join("_") === key
|
|
581
|
+
)) {
|
|
568
582
|
const newItem = { ...directData };
|
|
569
583
|
if (Object.keys(nestedData).length > 0) {
|
|
570
|
-
attachRelations(newItem, nestedData, relationConfig.foreignTable
|
|
584
|
+
attachRelations(newItem, nestedData, relationConfig.foreignTable);
|
|
571
585
|
}
|
|
572
586
|
target[relName].push(newItem);
|
|
573
587
|
}
|
|
574
588
|
}
|
|
575
589
|
} else {
|
|
576
|
-
const directData = {};
|
|
577
|
-
const nestedData = {};
|
|
578
|
-
if (typeof relData === "object" && relData !== null) {
|
|
579
|
-
for (const [k, v] of Object.entries(relData)) {
|
|
580
|
-
if (typeof v === "object" && v !== null) {
|
|
581
|
-
nestedData[k] = v;
|
|
582
|
-
} else {
|
|
583
|
-
directData[k] = v;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
const hasData = Object.values(directData).some(
|
|
588
|
-
(v) => v !== null && v !== void 0 && v !== ""
|
|
589
|
-
);
|
|
590
590
|
if (hasData || Object.keys(nestedData).length > 0) {
|
|
591
591
|
target[relName] = { ...directData };
|
|
592
592
|
if (Object.keys(nestedData).length > 0) {
|
|
593
|
-
attachRelations(
|
|
593
|
+
attachRelations(
|
|
594
|
+
target[relName],
|
|
595
|
+
nestedData,
|
|
596
|
+
relationConfig.foreignTable
|
|
597
|
+
);
|
|
594
598
|
}
|
|
595
599
|
}
|
|
596
600
|
}
|
|
597
601
|
}
|
|
598
602
|
};
|
|
599
|
-
attachRelations(result, relations2, this.
|
|
603
|
+
attachRelations(result, relations2, this._table);
|
|
600
604
|
}
|
|
601
605
|
return Array.from(groupedResults.values());
|
|
602
606
|
}
|
|
603
|
-
// Update the return type signatures
|
|
604
607
|
async all() {
|
|
605
608
|
return this.execute();
|
|
606
609
|
}
|
|
@@ -609,61 +612,32 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
|
609
612
|
const result = await this.execute();
|
|
610
613
|
return result[0];
|
|
611
614
|
}
|
|
615
|
+
async first() {
|
|
616
|
+
return this.get();
|
|
617
|
+
}
|
|
612
618
|
async exists() {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const whereIndex = this.query.indexOf(" WHERE ");
|
|
617
|
-
let fromPart = this.query;
|
|
618
|
-
let wherePart = "";
|
|
619
|
-
if (whereIndex !== -1) {
|
|
620
|
-
fromPart = this.query.substring(0, whereIndex);
|
|
621
|
-
wherePart = this.query.substring(whereIndex);
|
|
622
|
-
}
|
|
623
|
-
const query = `SELECT 1 ${fromPart}${joinSql}${wherePart} LIMIT 1`;
|
|
624
|
-
const params = [...joinParams, ...this.params];
|
|
625
|
-
this.selectedColumns = originalColumns;
|
|
626
|
-
const result = await this.db.select(query, params);
|
|
627
|
-
return result.length > 0;
|
|
619
|
+
this.applyIncludes();
|
|
620
|
+
const compiledResult = await this._builder.clearSelect().select(sql2.raw("1").as("__exists__")).limit(1).execute();
|
|
621
|
+
return compiledResult.length > 0;
|
|
628
622
|
}
|
|
629
623
|
async count() {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
const
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
let wherePart = "";
|
|
636
|
-
if (whereIndex !== -1) {
|
|
637
|
-
fromPart = this.query.substring(0, whereIndex);
|
|
638
|
-
wherePart = this.query.substring(whereIndex);
|
|
639
|
-
}
|
|
640
|
-
const query = `SELECT COUNT(*) as count ${fromPart}${joinSql}${wherePart}`;
|
|
641
|
-
const params = [...joinParams, ...this.params];
|
|
642
|
-
this.selectedColumns = originalColumns;
|
|
643
|
-
const result = await this.db.select(query, params);
|
|
644
|
-
return result[0]?.count || 0;
|
|
645
|
-
}
|
|
646
|
-
async first() {
|
|
647
|
-
return this.get();
|
|
624
|
+
this.applyIncludes();
|
|
625
|
+
const result = await this._builder.clearSelect().select(sql2`COUNT(*)`.as("count")).execute();
|
|
626
|
+
const row = result[0];
|
|
627
|
+
const val = row ? row['"count"'] ?? row.count : void 0;
|
|
628
|
+
return Number(val ?? 0);
|
|
648
629
|
}
|
|
649
630
|
async pluck(column) {
|
|
650
|
-
|
|
651
|
-
const
|
|
652
|
-
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
}
|
|
661
|
-
const query = `SELECT ${this.selectedColumns.join(", ")} ${fromPart}${joinSql}${wherePart}`;
|
|
662
|
-
const params = [...joinParams, ...this.params];
|
|
663
|
-
this.selectedColumns = originalColumns;
|
|
664
|
-
const results = await this.db.select(query, params);
|
|
665
|
-
const col = this.table._.columns[column];
|
|
666
|
-
return results.map((row) => col ? deserializeValue(row[columnName], col) : row[columnName]);
|
|
631
|
+
this.applyIncludes();
|
|
632
|
+
const col = this._table._.columns[column];
|
|
633
|
+
const alias2 = col._.name;
|
|
634
|
+
const results = await this._builder.clearSelect().select(
|
|
635
|
+
sql2.raw(`${this._table._.name}.${alias2}`).as(alias2)
|
|
636
|
+
).execute();
|
|
637
|
+
return results.map((row) => {
|
|
638
|
+
const val = row['"' + alias2 + '"'] ?? row[alias2];
|
|
639
|
+
return col ? deserializeValue(val, col) : val;
|
|
640
|
+
});
|
|
667
641
|
}
|
|
668
642
|
async paginate(page = 1, pageSize = 10) {
|
|
669
643
|
if (page < 1) page = 1;
|
|
@@ -683,16 +657,19 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
|
683
657
|
};
|
|
684
658
|
}
|
|
685
659
|
toSQL() {
|
|
686
|
-
|
|
687
|
-
const
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
660
|
+
this.applyIncludes();
|
|
661
|
+
const compiled = this._builder.compile();
|
|
662
|
+
return { sql: compiled.sql, params: [...compiled.parameters] };
|
|
663
|
+
}
|
|
664
|
+
toKyselyExpression() {
|
|
665
|
+
this.applyIncludes();
|
|
666
|
+
return this._builder;
|
|
693
667
|
}
|
|
694
668
|
};
|
|
695
669
|
|
|
670
|
+
// src/builders/update.ts
|
|
671
|
+
import { sql as sql3 } from "kysely";
|
|
672
|
+
|
|
696
673
|
// src/errors.ts
|
|
697
674
|
var TauriORMError = class extends Error {
|
|
698
675
|
constructor(message) {
|
|
@@ -761,414 +738,384 @@ var TableNotFoundError = class extends TauriORMError {
|
|
|
761
738
|
};
|
|
762
739
|
|
|
763
740
|
// src/builders/update.ts
|
|
764
|
-
var UpdateQueryBuilder = class
|
|
765
|
-
constructor(
|
|
766
|
-
|
|
767
|
-
this.
|
|
768
|
-
this.
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
741
|
+
var UpdateQueryBuilder = class {
|
|
742
|
+
constructor(kysely, table) {
|
|
743
|
+
this.kysely = kysely;
|
|
744
|
+
this._table = table;
|
|
745
|
+
this._builder = kysely.updateTable(table._.name);
|
|
746
|
+
}
|
|
747
|
+
_builder;
|
|
748
|
+
_table;
|
|
749
|
+
_updateData = {};
|
|
750
|
+
_returningColumns = [];
|
|
751
|
+
_hasWhereClause = false;
|
|
752
|
+
_allowGlobal = false;
|
|
753
|
+
_incrementDecrementOps = [];
|
|
775
754
|
set(data) {
|
|
776
|
-
this.
|
|
755
|
+
this._updateData = { ...this._updateData, ...data };
|
|
777
756
|
return this;
|
|
778
757
|
}
|
|
779
758
|
where(condition) {
|
|
780
|
-
this.
|
|
781
|
-
|
|
759
|
+
this._hasWhereClause = true;
|
|
760
|
+
this._builder = this._builder.where(condition);
|
|
761
|
+
return this;
|
|
782
762
|
}
|
|
783
763
|
increment(column, value = 1) {
|
|
784
|
-
const col = this.
|
|
785
|
-
if (!col)
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
this.incrementDecrementOps.push({ column: col._.name, op: "increment", value });
|
|
764
|
+
const col = this._table._.columns[column];
|
|
765
|
+
if (!col) throw new ColumnNotFoundError(String(column), this._table._.name);
|
|
766
|
+
this._incrementDecrementOps.push({ column: col._.name, op: "increment", value });
|
|
789
767
|
return this;
|
|
790
768
|
}
|
|
791
769
|
decrement(column, value = 1) {
|
|
792
|
-
const col = this.
|
|
793
|
-
if (!col)
|
|
794
|
-
|
|
795
|
-
}
|
|
796
|
-
this.incrementDecrementOps.push({ column: col._.name, op: "decrement", value });
|
|
770
|
+
const col = this._table._.columns[column];
|
|
771
|
+
if (!col) throw new ColumnNotFoundError(String(column), this._table._.name);
|
|
772
|
+
this._incrementDecrementOps.push({ column: col._.name, op: "decrement", value });
|
|
797
773
|
return this;
|
|
798
774
|
}
|
|
799
775
|
allowGlobalOperation() {
|
|
800
|
-
this.
|
|
776
|
+
this._allowGlobal = true;
|
|
801
777
|
return this;
|
|
802
778
|
}
|
|
803
779
|
returning(...columns) {
|
|
804
|
-
this.
|
|
780
|
+
this._returningColumns.push(...columns);
|
|
805
781
|
return this;
|
|
806
782
|
}
|
|
807
|
-
|
|
808
|
-
const
|
|
809
|
-
for (const [
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
783
|
+
mapReturningRows(rows) {
|
|
784
|
+
const dbNameToTs = {};
|
|
785
|
+
for (const [tsName, col] of Object.entries(this._table._.columns)) {
|
|
786
|
+
dbNameToTs[col._.name] = tsName;
|
|
787
|
+
}
|
|
788
|
+
const norm = (k) => k.startsWith('"') && k.endsWith('"') ? k.slice(1, -1) : k;
|
|
789
|
+
return rows.map((row) => {
|
|
790
|
+
const out = {};
|
|
791
|
+
for (const [dbKey, value] of Object.entries(row)) {
|
|
792
|
+
const logicalKey = norm(dbKey);
|
|
793
|
+
const tsName = dbNameToTs[logicalKey] ?? logicalKey;
|
|
794
|
+
const column = this._table._.columns[tsName];
|
|
795
|
+
out[tsName] = column ? deserializeValue(value, column) : value;
|
|
796
|
+
}
|
|
797
|
+
return out;
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
buildSetClause() {
|
|
801
|
+
const finalData = { ...this._updateData };
|
|
802
|
+
for (const [key, column] of Object.entries(this._table._.columns)) {
|
|
803
|
+
if (finalData[key] === void 0 && column.options.$onUpdateFn) {
|
|
804
|
+
;
|
|
805
|
+
finalData[key] = column.options.$onUpdateFn();
|
|
813
806
|
}
|
|
814
807
|
}
|
|
815
|
-
const
|
|
816
|
-
const whereParams = this.params;
|
|
817
|
-
let tablePart = baseQuery;
|
|
818
|
-
let whereClause = "";
|
|
819
|
-
const whereIndex = baseQuery.indexOf(" WHERE ");
|
|
820
|
-
if (whereIndex !== -1) {
|
|
821
|
-
tablePart = baseQuery.substring(0, whereIndex);
|
|
822
|
-
whereClause = baseQuery.substring(whereIndex);
|
|
823
|
-
}
|
|
824
|
-
const entries = Object.entries(finalUpdateData);
|
|
808
|
+
const entries = Object.entries(finalData);
|
|
825
809
|
const hasSetData = entries.length > 0;
|
|
826
|
-
const
|
|
827
|
-
if (!hasSetData && !
|
|
828
|
-
throw new UpdateValidationError(
|
|
810
|
+
const hasOps = this._incrementDecrementOps.length > 0;
|
|
811
|
+
if (!hasSetData && !hasOps) {
|
|
812
|
+
throw new UpdateValidationError(
|
|
813
|
+
"Cannot execute an update query without a .set(), .increment(), or .decrement() call."
|
|
814
|
+
);
|
|
829
815
|
}
|
|
830
|
-
const
|
|
831
|
-
const
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
if (!column) {
|
|
836
|
-
throw new ColumnNotFoundError(key, this.table._.name);
|
|
837
|
-
}
|
|
838
|
-
setClauses.push(`${column._.name} = ?`);
|
|
839
|
-
setParams.push(serializeValue(value, column));
|
|
840
|
-
}
|
|
816
|
+
const setMap = {};
|
|
817
|
+
for (const [key, value] of entries) {
|
|
818
|
+
const column = this._table._.columns[key];
|
|
819
|
+
if (!column) throw new ColumnNotFoundError(key, this._table._.name);
|
|
820
|
+
setMap[column._.name] = serializeValue(value, column);
|
|
841
821
|
}
|
|
842
|
-
for (const op of this.
|
|
822
|
+
for (const op of this._incrementDecrementOps) {
|
|
843
823
|
const sign = op.op === "increment" ? "+" : "-";
|
|
844
|
-
|
|
845
|
-
setParams.push(op.value);
|
|
824
|
+
setMap[op.column] = sql3.raw(`${op.column} ${sign} ${op.value}`);
|
|
846
825
|
}
|
|
847
|
-
|
|
848
|
-
const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
|
|
849
|
-
const params = [...setParams, ...whereParams];
|
|
850
|
-
return { sql: sql2, params };
|
|
826
|
+
return setMap;
|
|
851
827
|
}
|
|
852
828
|
async execute() {
|
|
853
|
-
if (!this.
|
|
854
|
-
throw new MissingWhereClauseError("UPDATE", this.
|
|
855
|
-
}
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
const
|
|
863
|
-
return
|
|
829
|
+
if (!this._hasWhereClause && !this._allowGlobal) {
|
|
830
|
+
throw new MissingWhereClauseError("UPDATE", this._table._.name);
|
|
831
|
+
}
|
|
832
|
+
const setMap = this.buildSetClause();
|
|
833
|
+
let builder = this._builder.set(setMap);
|
|
834
|
+
if (this._returningColumns.length > 0) {
|
|
835
|
+
const cols = this._returningColumns.map(
|
|
836
|
+
(k) => this._table._.columns[k]._.name
|
|
837
|
+
);
|
|
838
|
+
const rows = await builder.returning(cols).execute();
|
|
839
|
+
return this.mapReturningRows(rows);
|
|
864
840
|
}
|
|
841
|
+
const result = await builder.executeTakeFirst();
|
|
842
|
+
return [{ rowsAffected: Number(result?.numUpdatedRows ?? 0) }];
|
|
865
843
|
}
|
|
866
844
|
async returningAll() {
|
|
867
|
-
const
|
|
868
|
-
|
|
869
|
-
);
|
|
870
|
-
return this.returning(...allColumns).execute();
|
|
845
|
+
const allCols = Object.keys(this._table._.columns);
|
|
846
|
+
return this.returning(...allCols).execute();
|
|
871
847
|
}
|
|
872
848
|
async returningFirst() {
|
|
873
|
-
const
|
|
874
|
-
this.table._.columns
|
|
875
|
-
);
|
|
876
|
-
const results = await this.returning(...allColumns).execute();
|
|
849
|
+
const results = await this.returningAll();
|
|
877
850
|
return results[0];
|
|
878
851
|
}
|
|
879
852
|
toSQL() {
|
|
880
|
-
const
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
};
|
|
853
|
+
const setMap = this.buildSetClause();
|
|
854
|
+
let builder = this._builder.set(setMap);
|
|
855
|
+
if (this._returningColumns.length > 0) {
|
|
856
|
+
builder = builder.returning(
|
|
857
|
+
this._returningColumns.map((k) => this._table._.columns[k]._.name)
|
|
858
|
+
);
|
|
887
859
|
}
|
|
888
|
-
|
|
860
|
+
const compiled = builder.compile();
|
|
861
|
+
return { sql: compiled.sql, params: [...compiled.parameters] };
|
|
889
862
|
}
|
|
890
863
|
};
|
|
891
864
|
|
|
892
865
|
// src/builders/insert.ts
|
|
893
|
-
var InsertQueryBuilder = class
|
|
894
|
-
constructor(
|
|
895
|
-
|
|
896
|
-
this.
|
|
897
|
-
this.
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
866
|
+
var InsertQueryBuilder = class {
|
|
867
|
+
constructor(kysely, table) {
|
|
868
|
+
this.kysely = kysely;
|
|
869
|
+
this._table = table;
|
|
870
|
+
this._builder = kysely.insertInto(table._.name);
|
|
871
|
+
}
|
|
872
|
+
_builder;
|
|
873
|
+
_table;
|
|
874
|
+
_dataSets = [];
|
|
875
|
+
_returningColumns = [];
|
|
876
|
+
_onConflictAction = null;
|
|
877
|
+
_conflictTarget = [];
|
|
878
|
+
_updateSet = {};
|
|
904
879
|
values(data) {
|
|
905
|
-
const
|
|
906
|
-
this.
|
|
880
|
+
const arr = Array.isArray(data) ? data : [data];
|
|
881
|
+
this._dataSets.push(...arr);
|
|
907
882
|
return this;
|
|
908
883
|
}
|
|
909
884
|
returning(...columns) {
|
|
910
|
-
this.
|
|
885
|
+
this._returningColumns.push(...columns);
|
|
911
886
|
return this;
|
|
912
887
|
}
|
|
913
888
|
onConflictDoNothing(target) {
|
|
914
|
-
this.
|
|
889
|
+
this._onConflictAction = "nothing";
|
|
915
890
|
if (target) {
|
|
916
|
-
this.
|
|
891
|
+
this._conflictTarget = Array.isArray(target) ? target : [target];
|
|
917
892
|
}
|
|
918
893
|
return this;
|
|
919
894
|
}
|
|
920
895
|
onConflictDoUpdate(config) {
|
|
921
|
-
this.
|
|
922
|
-
this.
|
|
923
|
-
this.
|
|
896
|
+
this._onConflictAction = "update";
|
|
897
|
+
this._conflictTarget = Array.isArray(config.target) ? config.target : [config.target];
|
|
898
|
+
this._updateSet = config.set;
|
|
924
899
|
return this;
|
|
925
900
|
}
|
|
926
|
-
|
|
927
|
-
const
|
|
928
|
-
for (const [key, column] of Object.entries(this.
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
finalData[typedKey] = column.options.$defaultFn();
|
|
933
|
-
}
|
|
901
|
+
processDefaults(data) {
|
|
902
|
+
const out = { ...data };
|
|
903
|
+
for (const [key, column] of Object.entries(this._table._.columns)) {
|
|
904
|
+
if (out[key] === void 0 && column.options.$defaultFn) {
|
|
905
|
+
;
|
|
906
|
+
out[key] = column.options.$defaultFn();
|
|
934
907
|
}
|
|
935
908
|
}
|
|
936
|
-
return
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
clause += ` DO UPDATE SET ${setClause}`;
|
|
909
|
+
return out;
|
|
910
|
+
}
|
|
911
|
+
mapReturningRows(rows) {
|
|
912
|
+
const dbNameToTs = {};
|
|
913
|
+
for (const [tsName, col] of Object.entries(this._table._.columns)) {
|
|
914
|
+
dbNameToTs[col._.name] = tsName;
|
|
915
|
+
}
|
|
916
|
+
const norm = (k) => k.startsWith('"') && k.endsWith('"') ? k.slice(1, -1) : k;
|
|
917
|
+
return rows.map((row) => {
|
|
918
|
+
const out = {};
|
|
919
|
+
for (const [dbKey, value] of Object.entries(row)) {
|
|
920
|
+
const logicalKey = norm(dbKey);
|
|
921
|
+
const tsName = dbNameToTs[logicalKey] ?? logicalKey;
|
|
922
|
+
const column = this._table._.columns[tsName];
|
|
923
|
+
out[tsName] = column ? deserializeValue(value, column) : value;
|
|
952
924
|
}
|
|
925
|
+
return out;
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
serializeDataSet(data) {
|
|
929
|
+
const out = {};
|
|
930
|
+
for (const [key, value] of Object.entries(data)) {
|
|
931
|
+
const column = this._table._.columns[key];
|
|
932
|
+
out[column ? column._.name : key] = column ? serializeValue(value, column) : value;
|
|
953
933
|
}
|
|
954
|
-
return
|
|
934
|
+
return out;
|
|
955
935
|
}
|
|
956
936
|
async execute() {
|
|
957
|
-
if (this.
|
|
958
|
-
throw new InsertValidationError(
|
|
959
|
-
|
|
960
|
-
const processedDataSets = this.dataSets.map(
|
|
961
|
-
(data) => this.processDefaultValues(data)
|
|
962
|
-
);
|
|
963
|
-
const groups = /* @__PURE__ */ new Map();
|
|
964
|
-
for (const dataSet of processedDataSets) {
|
|
965
|
-
const keys = Object.keys(dataSet).sort().join(",");
|
|
966
|
-
if (!groups.has(keys)) {
|
|
967
|
-
groups.set(keys, []);
|
|
968
|
-
}
|
|
969
|
-
groups.get(keys).push(dataSet);
|
|
970
|
-
}
|
|
971
|
-
let results = [];
|
|
972
|
-
let lastInsertId;
|
|
973
|
-
let rowsAffected = 0;
|
|
974
|
-
for (const [_, dataSets] of groups) {
|
|
975
|
-
const columns = Object.keys(dataSets[0]);
|
|
976
|
-
const columnNames = columns.map(
|
|
977
|
-
(key) => this.table._.columns[key]._.name
|
|
978
|
-
);
|
|
979
|
-
const placeholders = `(${columns.map(() => "?").join(", ")})`;
|
|
980
|
-
const valuesSql = dataSets.map(() => placeholders).join(", ");
|
|
981
|
-
const conflictClause = this.buildConflictClause();
|
|
982
|
-
const finalQuery = `${this.query} (${columnNames.join(
|
|
983
|
-
", "
|
|
984
|
-
)}) VALUES ${valuesSql}${conflictClause}`;
|
|
985
|
-
const params = dataSets.flatMap(
|
|
986
|
-
(data) => columns.map((col) => {
|
|
987
|
-
const value = data[col] ?? null;
|
|
988
|
-
const column = this.table._.columns[col];
|
|
989
|
-
return column ? serializeValue(value, column) : value;
|
|
990
|
-
})
|
|
937
|
+
if (this._dataSets.length === 0) {
|
|
938
|
+
throw new InsertValidationError(
|
|
939
|
+
"No data provided for insert. Use .values() to provide data."
|
|
991
940
|
);
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
941
|
+
}
|
|
942
|
+
const processed = this._dataSets.map((d) => this.serializeDataSet(this.processDefaults(d)));
|
|
943
|
+
let builder = this._builder.values(processed.length === 1 ? processed[0] : processed);
|
|
944
|
+
if (this._onConflictAction === "nothing") {
|
|
945
|
+
if (this._conflictTarget.length > 0) {
|
|
946
|
+
const targetCols = this._conflictTarget.map((c) => c._.name);
|
|
947
|
+
builder = builder.onConflict(
|
|
948
|
+
(oc) => oc.columns(targetCols).doNothing()
|
|
998
949
|
);
|
|
999
|
-
params.push(...setValues);
|
|
1000
|
-
}
|
|
1001
|
-
if (this.returningColumns.length > 0) {
|
|
1002
|
-
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
1003
|
-
const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
|
|
1004
|
-
const rows = await this.db.select(queryWithReturning, params);
|
|
1005
|
-
results = results.concat(rows);
|
|
1006
950
|
} else {
|
|
1007
|
-
|
|
1008
|
-
lastInsertId = result.lastInsertId;
|
|
1009
|
-
rowsAffected += result.rowsAffected;
|
|
951
|
+
builder = builder.onConflict((oc) => oc.doNothing());
|
|
1010
952
|
}
|
|
953
|
+
} else if (this._onConflictAction === "update") {
|
|
954
|
+
const targetCols = this._conflictTarget.map((c) => c._.name);
|
|
955
|
+
const updateData = this.serializeDataSet(this._updateSet);
|
|
956
|
+
builder = builder.onConflict(
|
|
957
|
+
(oc) => oc.columns(targetCols).doUpdateSet(updateData)
|
|
958
|
+
);
|
|
1011
959
|
}
|
|
1012
|
-
if (this.
|
|
1013
|
-
|
|
960
|
+
if (this._returningColumns.length > 0) {
|
|
961
|
+
const cols = this._returningColumns.map(
|
|
962
|
+
(k) => this._table._.columns[k]._.name
|
|
963
|
+
);
|
|
964
|
+
const rows = await builder.returning(cols).execute();
|
|
965
|
+
return this.mapReturningRows(rows);
|
|
1014
966
|
}
|
|
1015
|
-
|
|
967
|
+
const result = await builder.executeTakeFirst();
|
|
968
|
+
return [
|
|
969
|
+
{
|
|
970
|
+
lastInsertId: Number(result?.insertId ?? 0),
|
|
971
|
+
rowsAffected: Number(result?.numInsertedOrUpdatedRows ?? 0)
|
|
972
|
+
}
|
|
973
|
+
];
|
|
1016
974
|
}
|
|
1017
975
|
async returningAll() {
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
);
|
|
1021
|
-
return this.returning(...allColumns).execute();
|
|
976
|
+
const allCols = Object.keys(this._table._.columns);
|
|
977
|
+
return this.returning(...allCols).execute();
|
|
1022
978
|
}
|
|
1023
979
|
async returningFirst() {
|
|
1024
|
-
const
|
|
1025
|
-
this.table._.columns
|
|
1026
|
-
);
|
|
1027
|
-
const results = await this.returning(...allColumns).execute();
|
|
980
|
+
const results = await this.returningAll();
|
|
1028
981
|
return results[0];
|
|
1029
982
|
}
|
|
1030
983
|
toSQL() {
|
|
1031
|
-
if (this.
|
|
1032
|
-
throw new InsertValidationError(
|
|
984
|
+
if (this._dataSets.length === 0) {
|
|
985
|
+
throw new InsertValidationError(
|
|
986
|
+
"No data provided for insert. Use .values() to provide data."
|
|
987
|
+
);
|
|
1033
988
|
}
|
|
1034
|
-
const
|
|
1035
|
-
|
|
1036
|
-
)
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
const params = processedDataSets.flatMap(
|
|
1049
|
-
(data) => columns.map((col) => {
|
|
1050
|
-
const value = data[col] ?? null;
|
|
1051
|
-
const column = this.table._.columns[col];
|
|
1052
|
-
return column ? serializeValue(value, column) : value;
|
|
1053
|
-
})
|
|
1054
|
-
);
|
|
1055
|
-
if (this.onConflictAction === "update") {
|
|
1056
|
-
const setValues = Object.entries(this.updateSet).map(
|
|
1057
|
-
([key, value]) => {
|
|
1058
|
-
const column = this.table._.columns[key];
|
|
1059
|
-
return column ? serializeValue(value, column) : value;
|
|
1060
|
-
}
|
|
989
|
+
const processed = this._dataSets.map((d) => this.serializeDataSet(this.processDefaults(d)));
|
|
990
|
+
let builder = this._builder.values(processed.length === 1 ? processed[0] : processed);
|
|
991
|
+
if (this._onConflictAction === "nothing") {
|
|
992
|
+
if (this._conflictTarget.length > 0) {
|
|
993
|
+
builder = builder.onConflict(
|
|
994
|
+
(oc) => oc.columns(this._conflictTarget.map((c) => c._.name)).doNothing()
|
|
995
|
+
);
|
|
996
|
+
} else {
|
|
997
|
+
builder = builder.onConflict((oc) => oc.doNothing());
|
|
998
|
+
}
|
|
999
|
+
} else if (this._onConflictAction === "update") {
|
|
1000
|
+
const updateData = this.serializeDataSet(this._updateSet);
|
|
1001
|
+
builder = builder.onConflict(
|
|
1002
|
+
(oc) => oc.columns(this._conflictTarget.map((c) => c._.name)).doUpdateSet(updateData)
|
|
1061
1003
|
);
|
|
1062
|
-
params.push(...setValues);
|
|
1063
1004
|
}
|
|
1064
|
-
if (this.
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
params
|
|
1069
|
-
};
|
|
1005
|
+
if (this._returningColumns.length > 0) {
|
|
1006
|
+
builder = builder.returning(
|
|
1007
|
+
this._returningColumns.map((k) => this._table._.columns[k]._.name)
|
|
1008
|
+
);
|
|
1070
1009
|
}
|
|
1071
|
-
|
|
1010
|
+
const compiled = builder.compile();
|
|
1011
|
+
return { sql: compiled.sql, params: [...compiled.parameters] };
|
|
1072
1012
|
}
|
|
1073
1013
|
};
|
|
1074
1014
|
|
|
1075
1015
|
// src/builders/delete.ts
|
|
1076
|
-
var DeleteQueryBuilder = class
|
|
1077
|
-
constructor(
|
|
1078
|
-
|
|
1079
|
-
this.
|
|
1080
|
-
this.
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1016
|
+
var DeleteQueryBuilder = class {
|
|
1017
|
+
constructor(kysely, table) {
|
|
1018
|
+
this.kysely = kysely;
|
|
1019
|
+
this._table = table;
|
|
1020
|
+
this._builder = kysely.deleteFrom(table._.name);
|
|
1021
|
+
}
|
|
1022
|
+
_builder;
|
|
1023
|
+
_table;
|
|
1024
|
+
_returningColumns = [];
|
|
1025
|
+
_hasWhereClause = false;
|
|
1026
|
+
_allowGlobal = false;
|
|
1027
|
+
mapReturningRows(rows) {
|
|
1028
|
+
const dbNameToTs = {};
|
|
1029
|
+
for (const [tsName, col] of Object.entries(this._table._.columns)) {
|
|
1030
|
+
dbNameToTs[col._.name] = tsName;
|
|
1031
|
+
}
|
|
1032
|
+
const norm = (k) => k.startsWith('"') && k.endsWith('"') ? k.slice(1, -1) : k;
|
|
1033
|
+
return rows.map((row) => {
|
|
1034
|
+
const out = {};
|
|
1035
|
+
for (const [dbKey, value] of Object.entries(row)) {
|
|
1036
|
+
const logicalKey = norm(dbKey);
|
|
1037
|
+
const tsName = dbNameToTs[logicalKey] ?? logicalKey;
|
|
1038
|
+
const column = this._table._.columns[tsName];
|
|
1039
|
+
out[tsName] = column ? deserializeValue(value, column) : value;
|
|
1040
|
+
}
|
|
1041
|
+
return out;
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1085
1044
|
where(condition) {
|
|
1086
|
-
this.
|
|
1087
|
-
|
|
1045
|
+
this._hasWhereClause = true;
|
|
1046
|
+
this._builder = this._builder.where(condition);
|
|
1047
|
+
return this;
|
|
1088
1048
|
}
|
|
1089
1049
|
allowGlobalOperation() {
|
|
1090
|
-
this.
|
|
1050
|
+
this._allowGlobal = true;
|
|
1091
1051
|
return this;
|
|
1092
1052
|
}
|
|
1093
1053
|
returning(...columns) {
|
|
1094
|
-
this.
|
|
1054
|
+
this._returningColumns.push(...columns);
|
|
1095
1055
|
return this;
|
|
1096
1056
|
}
|
|
1097
1057
|
async execute() {
|
|
1098
|
-
if (!this.
|
|
1099
|
-
throw new MissingWhereClauseError("DELETE", this.
|
|
1058
|
+
if (!this._hasWhereClause && !this._allowGlobal) {
|
|
1059
|
+
throw new MissingWhereClauseError("DELETE", this._table._.name);
|
|
1100
1060
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
const result = await this.db.execute(sql2, params);
|
|
1108
|
-
return [{ rowsAffected: result.rowsAffected }];
|
|
1061
|
+
if (this._returningColumns.length > 0) {
|
|
1062
|
+
const cols = this._returningColumns.map(
|
|
1063
|
+
(k) => this._table._.columns[k]._.name
|
|
1064
|
+
);
|
|
1065
|
+
const rows = await this._builder.returning(cols).execute();
|
|
1066
|
+
return this.mapReturningRows(rows);
|
|
1109
1067
|
}
|
|
1068
|
+
const result = await this._builder.executeTakeFirst();
|
|
1069
|
+
return [{ rowsAffected: Number(result?.numDeletedRows ?? 0) }];
|
|
1110
1070
|
}
|
|
1111
1071
|
async returningAll() {
|
|
1112
|
-
const
|
|
1113
|
-
return this.returning(...
|
|
1072
|
+
const allCols = Object.keys(this._table._.columns);
|
|
1073
|
+
return this.returning(...allCols).execute();
|
|
1114
1074
|
}
|
|
1115
1075
|
async returningFirst() {
|
|
1116
|
-
const
|
|
1117
|
-
const results = await this.returning(...allColumns).execute();
|
|
1076
|
+
const results = await this.returningAll();
|
|
1118
1077
|
return results[0];
|
|
1119
1078
|
}
|
|
1120
1079
|
toSQL() {
|
|
1121
|
-
|
|
1122
|
-
if (this.
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
params
|
|
1127
|
-
};
|
|
1080
|
+
let builder = this._builder;
|
|
1081
|
+
if (this._returningColumns.length > 0) {
|
|
1082
|
+
builder = builder.returning(
|
|
1083
|
+
this._returningColumns.map((k) => this._table._.columns[k]._.name)
|
|
1084
|
+
);
|
|
1128
1085
|
}
|
|
1129
|
-
|
|
1086
|
+
const compiled = builder.compile();
|
|
1087
|
+
return { sql: compiled.sql, params: [...compiled.parameters] };
|
|
1130
1088
|
}
|
|
1131
1089
|
};
|
|
1132
1090
|
|
|
1133
1091
|
// src/builders/with.ts
|
|
1134
1092
|
var WithQueryBuilder = class {
|
|
1135
|
-
constructor(
|
|
1136
|
-
this.
|
|
1093
|
+
constructor(kysely) {
|
|
1094
|
+
this.kysely = kysely;
|
|
1137
1095
|
}
|
|
1138
|
-
|
|
1096
|
+
_ctes = [];
|
|
1139
1097
|
with(alias2, query) {
|
|
1140
|
-
this.
|
|
1098
|
+
this._ctes.push({ alias: alias2, query: query.toKyselyExpression() });
|
|
1141
1099
|
return this;
|
|
1142
1100
|
}
|
|
1101
|
+
applyWith(builder) {
|
|
1102
|
+
let b = builder;
|
|
1103
|
+
for (const { alias: alias2, query } of this._ctes) {
|
|
1104
|
+
b = b.with(alias2, () => query);
|
|
1105
|
+
}
|
|
1106
|
+
return b;
|
|
1107
|
+
}
|
|
1143
1108
|
select(table, columns) {
|
|
1144
|
-
|
|
1145
|
-
this.applyWithClause(builder);
|
|
1146
|
-
return builder;
|
|
1109
|
+
return new SelectQueryBuilder(this.kysely, table, columns);
|
|
1147
1110
|
}
|
|
1148
1111
|
insert(table) {
|
|
1149
|
-
|
|
1150
|
-
this.applyWithClause(builder);
|
|
1151
|
-
return builder;
|
|
1112
|
+
return new InsertQueryBuilder(this.kysely, table);
|
|
1152
1113
|
}
|
|
1153
1114
|
update(table) {
|
|
1154
|
-
|
|
1155
|
-
this.applyWithClause(builder);
|
|
1156
|
-
return builder;
|
|
1115
|
+
return new UpdateQueryBuilder(this.kysely, table);
|
|
1157
1116
|
}
|
|
1158
1117
|
delete(table) {
|
|
1159
|
-
|
|
1160
|
-
this.applyWithClause(builder);
|
|
1161
|
-
return builder;
|
|
1162
|
-
}
|
|
1163
|
-
applyWithClause(builder) {
|
|
1164
|
-
if (this.ctes.length > 0) {
|
|
1165
|
-
const cteSql = this.ctes.map((cte) => `${cte.alias} AS (${cte.query})`).join(", ");
|
|
1166
|
-
builder["query"] = `WITH ${cteSql} ${builder["query"]}`;
|
|
1167
|
-
builder["params"] = [
|
|
1168
|
-
...this.ctes.flatMap((cte) => cte.params),
|
|
1169
|
-
...builder["params"]
|
|
1170
|
-
];
|
|
1171
|
-
}
|
|
1118
|
+
return new DeleteQueryBuilder(this.kysely, table);
|
|
1172
1119
|
}
|
|
1173
1120
|
};
|
|
1174
1121
|
|
|
@@ -1211,7 +1158,7 @@ var SQLiteColumn = class _SQLiteColumn {
|
|
|
1211
1158
|
unique() {
|
|
1212
1159
|
return new _SQLiteColumn(this._.name, this.type, { ...this.options, unique: true, mode: this._.mode });
|
|
1213
1160
|
}
|
|
1214
|
-
references(ref, column) {
|
|
1161
|
+
references(ref, column, options) {
|
|
1215
1162
|
const columnKey = typeof column === "string" ? column : column._.name;
|
|
1216
1163
|
const columnObj = typeof column === "string" ? ref._.columns[column] : column;
|
|
1217
1164
|
return new _SQLiteColumn(
|
|
@@ -1221,7 +1168,9 @@ var SQLiteColumn = class _SQLiteColumn {
|
|
|
1221
1168
|
...this.options,
|
|
1222
1169
|
references: {
|
|
1223
1170
|
table: ref,
|
|
1224
|
-
column: columnObj
|
|
1171
|
+
column: columnObj,
|
|
1172
|
+
onDelete: options?.onDelete,
|
|
1173
|
+
onUpdate: options?.onUpdate
|
|
1225
1174
|
},
|
|
1226
1175
|
mode: this._.mode
|
|
1227
1176
|
}
|
|
@@ -1250,39 +1199,14 @@ var Table = class {
|
|
|
1250
1199
|
var sqliteTable = (tableName, columns) => {
|
|
1251
1200
|
return new Table(tableName, columns);
|
|
1252
1201
|
};
|
|
1253
|
-
var asc = (column) => (
|
|
1254
|
-
|
|
1255
|
-
params: []
|
|
1256
|
-
});
|
|
1257
|
-
var desc = (column) => ({
|
|
1258
|
-
sql: `${column._.name} DESC`,
|
|
1259
|
-
params: []
|
|
1260
|
-
});
|
|
1261
|
-
var sql = (strings, ...values) => {
|
|
1262
|
-
const queryParts = [];
|
|
1263
|
-
const params = [];
|
|
1264
|
-
strings.forEach((str, i) => {
|
|
1265
|
-
queryParts.push(str);
|
|
1266
|
-
if (values[i] !== void 0) {
|
|
1267
|
-
if (typeof values[i] === "object" && values[i].sql) {
|
|
1268
|
-
queryParts.push(values[i].sql);
|
|
1269
|
-
params.push(...values[i].params);
|
|
1270
|
-
} else {
|
|
1271
|
-
queryParts.push("?");
|
|
1272
|
-
params.push(values[i]);
|
|
1273
|
-
}
|
|
1274
|
-
}
|
|
1275
|
-
});
|
|
1276
|
-
return {
|
|
1277
|
-
sql: queryParts.join(""),
|
|
1278
|
-
params
|
|
1279
|
-
};
|
|
1280
|
-
};
|
|
1202
|
+
var asc = (column) => kyselySql`${kyselySql.ref(column._.name)} ASC`;
|
|
1203
|
+
var desc = (column) => kyselySql`${kyselySql.ref(column._.name)} DESC`;
|
|
1281
1204
|
var TauriORM = class {
|
|
1282
1205
|
constructor(db, schema = void 0) {
|
|
1283
1206
|
this.db = db;
|
|
1207
|
+
this.kysely = new Kysely4({ dialect: new TauriDialect(db) });
|
|
1284
1208
|
if (schema) {
|
|
1285
|
-
for (const [
|
|
1209
|
+
for (const [, value] of Object.entries(schema)) {
|
|
1286
1210
|
if (value instanceof Table) {
|
|
1287
1211
|
this.tables.set(value._.name, value);
|
|
1288
1212
|
}
|
|
@@ -1290,24 +1214,31 @@ var TauriORM = class {
|
|
|
1290
1214
|
}
|
|
1291
1215
|
}
|
|
1292
1216
|
tables = /* @__PURE__ */ new Map();
|
|
1217
|
+
kysely;
|
|
1293
1218
|
buildColumnDefinition(col, forAlterTable = false) {
|
|
1294
|
-
let
|
|
1219
|
+
let sql6 = `${col._.name} ${col.type}`;
|
|
1295
1220
|
if (col.options.primaryKey && !forAlterTable) {
|
|
1296
|
-
|
|
1221
|
+
sql6 += " PRIMARY KEY";
|
|
1297
1222
|
if (col._.autoincrement) {
|
|
1298
|
-
|
|
1223
|
+
sql6 += " AUTOINCREMENT";
|
|
1299
1224
|
}
|
|
1300
1225
|
}
|
|
1301
|
-
if (col._.notNull)
|
|
1302
|
-
if (col.options.unique)
|
|
1226
|
+
if (col._.notNull) sql6 += " NOT NULL";
|
|
1227
|
+
if (col.options.unique) sql6 += " UNIQUE";
|
|
1303
1228
|
if (col.options.default !== void 0) {
|
|
1304
1229
|
const value = col.options.default;
|
|
1305
|
-
|
|
1230
|
+
sql6 += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
|
|
1306
1231
|
}
|
|
1307
1232
|
if (col.options.references) {
|
|
1308
|
-
|
|
1233
|
+
sql6 += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
|
|
1234
|
+
if (col.options.references.onDelete) {
|
|
1235
|
+
sql6 += ` ON DELETE ${col.options.references.onDelete.toUpperCase()}`;
|
|
1236
|
+
}
|
|
1237
|
+
if (col.options.references.onUpdate) {
|
|
1238
|
+
sql6 += ` ON UPDATE ${col.options.references.onUpdate.toUpperCase()}`;
|
|
1239
|
+
}
|
|
1309
1240
|
}
|
|
1310
|
-
return
|
|
1241
|
+
return sql6;
|
|
1311
1242
|
}
|
|
1312
1243
|
async checkMigration() {
|
|
1313
1244
|
const dbTables = await this.db.select(
|
|
@@ -1349,15 +1280,16 @@ var TauriORM = class {
|
|
|
1349
1280
|
const schemaColumns = table._.columns;
|
|
1350
1281
|
let needsRecreate = false;
|
|
1351
1282
|
for (const [colName, column] of Object.entries(schemaColumns)) {
|
|
1352
|
-
const
|
|
1283
|
+
const dbColName = column._.name;
|
|
1284
|
+
const existing = existingColumns.get(dbColName);
|
|
1353
1285
|
if (!existing) {
|
|
1354
1286
|
if (!this.canAddColumnWithAlter(column)) {
|
|
1355
1287
|
needsRecreate = true;
|
|
1356
1288
|
break;
|
|
1357
1289
|
}
|
|
1358
|
-
changes.columnsToAdd.push({ table: tableName, column:
|
|
1290
|
+
changes.columnsToAdd.push({ table: tableName, column: dbColName });
|
|
1359
1291
|
} else {
|
|
1360
|
-
const hasUniqueInDB = uniqueColumns.has(
|
|
1292
|
+
const hasUniqueInDB = uniqueColumns.has(dbColName);
|
|
1361
1293
|
const wantsUnique = !!column.options.unique;
|
|
1362
1294
|
if (hasUniqueInDB !== wantsUnique || this.hasColumnDefinitionChanged(column, existing)) {
|
|
1363
1295
|
needsRecreate = true;
|
|
@@ -1366,7 +1298,8 @@ var TauriORM = class {
|
|
|
1366
1298
|
}
|
|
1367
1299
|
}
|
|
1368
1300
|
for (const existingCol of existingColumns.keys()) {
|
|
1369
|
-
|
|
1301
|
+
const schemaHasCol = Object.values(schemaColumns).some((c) => c._.name === existingCol);
|
|
1302
|
+
if (!schemaHasCol) {
|
|
1370
1303
|
needsRecreate = true;
|
|
1371
1304
|
break;
|
|
1372
1305
|
}
|
|
@@ -1418,7 +1351,8 @@ var TauriORM = class {
|
|
|
1418
1351
|
let needsRecreate = false;
|
|
1419
1352
|
const columnsToAdd = [];
|
|
1420
1353
|
for (const [colName, column] of Object.entries(schemaColumns)) {
|
|
1421
|
-
const
|
|
1354
|
+
const dbColName = column._.name;
|
|
1355
|
+
const existing = existingColumns.get(dbColName);
|
|
1422
1356
|
if (!existing) {
|
|
1423
1357
|
if (this.canAddColumnWithAlter(column)) {
|
|
1424
1358
|
columnsToAdd.push(column);
|
|
@@ -1427,7 +1361,7 @@ var TauriORM = class {
|
|
|
1427
1361
|
break;
|
|
1428
1362
|
}
|
|
1429
1363
|
} else {
|
|
1430
|
-
const hasUniqueInDB = uniqueColumns.has(
|
|
1364
|
+
const hasUniqueInDB = uniqueColumns.has(dbColName);
|
|
1431
1365
|
const wantsUnique = !!column.options.unique;
|
|
1432
1366
|
if (hasUniqueInDB !== wantsUnique) {
|
|
1433
1367
|
needsRecreate = true;
|
|
@@ -1441,7 +1375,8 @@ var TauriORM = class {
|
|
|
1441
1375
|
}
|
|
1442
1376
|
if (options?.performDestructiveActions) {
|
|
1443
1377
|
for (const existingCol of existingColumns.keys()) {
|
|
1444
|
-
|
|
1378
|
+
const schemaHasCol = Object.values(schemaColumns).some((c) => c._.name === existingCol);
|
|
1379
|
+
if (!schemaHasCol) {
|
|
1445
1380
|
needsRecreate = true;
|
|
1446
1381
|
break;
|
|
1447
1382
|
}
|
|
@@ -1486,7 +1421,7 @@ var TauriORM = class {
|
|
|
1486
1421
|
await this.db.execute(`CREATE TABLE ${tempTableName} (${columnsSql})`);
|
|
1487
1422
|
const oldColumns = await this.db.select(`PRAGMA table_info('${tableName}')`);
|
|
1488
1423
|
const oldColumnNames = oldColumns.map((c) => c.name);
|
|
1489
|
-
const newColumnNames = Object.
|
|
1424
|
+
const newColumnNames = Object.values(table._.columns).map((c) => c._.name);
|
|
1490
1425
|
const commonColumns = oldColumnNames.filter((name) => newColumnNames.includes(name));
|
|
1491
1426
|
if (commonColumns.length > 0) {
|
|
1492
1427
|
const columnsList = commonColumns.join(", ");
|
|
@@ -1503,18 +1438,18 @@ var TauriORM = class {
|
|
|
1503
1438
|
console.warn(
|
|
1504
1439
|
`[Tauri-ORM] Table "${table._.name}" was not passed in the schema to the ORM constructor. Relations will not be available.`
|
|
1505
1440
|
);
|
|
1506
|
-
return new SelectQueryBuilder(this.
|
|
1441
|
+
return new SelectQueryBuilder(this.kysely, table, columns);
|
|
1507
1442
|
}
|
|
1508
|
-
return new SelectQueryBuilder(this.
|
|
1443
|
+
return new SelectQueryBuilder(this.kysely, internalTable, columns);
|
|
1509
1444
|
}
|
|
1510
1445
|
insert(table) {
|
|
1511
|
-
return new InsertQueryBuilder(this.
|
|
1446
|
+
return new InsertQueryBuilder(this.kysely, table);
|
|
1512
1447
|
}
|
|
1513
1448
|
update(table) {
|
|
1514
|
-
return new UpdateQueryBuilder(this.
|
|
1449
|
+
return new UpdateQueryBuilder(this.kysely, table);
|
|
1515
1450
|
}
|
|
1516
1451
|
delete(table) {
|
|
1517
|
-
return new DeleteQueryBuilder(this.
|
|
1452
|
+
return new DeleteQueryBuilder(this.kysely, table);
|
|
1518
1453
|
}
|
|
1519
1454
|
async upsert(table, data, conflictTarget) {
|
|
1520
1455
|
const columns = conflictTarget.map((col) => table._.columns[col]);
|
|
@@ -1524,7 +1459,7 @@ var TauriORM = class {
|
|
|
1524
1459
|
}).execute();
|
|
1525
1460
|
}
|
|
1526
1461
|
$with(alias2) {
|
|
1527
|
-
const withBuilder = new WithQueryBuilder(this.
|
|
1462
|
+
const withBuilder = new WithQueryBuilder(this.kysely);
|
|
1528
1463
|
return {
|
|
1529
1464
|
as: (query) => {
|
|
1530
1465
|
withBuilder.with(alias2, query);
|
|
@@ -1533,14 +1468,14 @@ var TauriORM = class {
|
|
|
1533
1468
|
};
|
|
1534
1469
|
}
|
|
1535
1470
|
async transaction(callback) {
|
|
1536
|
-
await this.db.execute("BEGIN
|
|
1471
|
+
await this.db.execute("BEGIN");
|
|
1537
1472
|
try {
|
|
1538
1473
|
const result = await callback(this);
|
|
1539
1474
|
await this.db.execute("COMMIT");
|
|
1540
1475
|
return result;
|
|
1541
|
-
} catch (
|
|
1476
|
+
} catch (e) {
|
|
1542
1477
|
await this.db.execute("ROLLBACK");
|
|
1543
|
-
throw
|
|
1478
|
+
throw e;
|
|
1544
1479
|
}
|
|
1545
1480
|
}
|
|
1546
1481
|
rollback() {
|
|
@@ -1592,7 +1527,9 @@ var TauriORM = class {
|
|
|
1592
1527
|
unique: !!col.options.unique,
|
|
1593
1528
|
dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null,
|
|
1594
1529
|
hasDefaultFn: col.options.$defaultFn !== void 0,
|
|
1595
|
-
hasOnUpdateFn: col.options.$onUpdateFn !== void 0
|
|
1530
|
+
hasOnUpdateFn: col.options.$onUpdateFn !== void 0,
|
|
1531
|
+
onDelete: col.options.references?.onDelete ?? null,
|
|
1532
|
+
onUpdate: col.options.references?.onUpdate ?? null
|
|
1596
1533
|
};
|
|
1597
1534
|
}
|
|
1598
1535
|
computeModelSignature() {
|
|
@@ -1656,11 +1593,6 @@ var OneRelation = class extends Relation {
|
|
|
1656
1593
|
}
|
|
1657
1594
|
};
|
|
1658
1595
|
var ManyRelation = class extends Relation {
|
|
1659
|
-
constructor(foreignTable) {
|
|
1660
|
-
super(foreignTable);
|
|
1661
|
-
}
|
|
1662
|
-
};
|
|
1663
|
-
var ManyToManyRelation = class extends Relation {
|
|
1664
1596
|
constructor(foreignTable, config) {
|
|
1665
1597
|
super(foreignTable);
|
|
1666
1598
|
this.config = config;
|
|
@@ -1673,9 +1605,6 @@ var relations = (table, relationsCallback) => {
|
|
|
1673
1605
|
},
|
|
1674
1606
|
many: (foreignTable) => {
|
|
1675
1607
|
return new ManyRelation(foreignTable);
|
|
1676
|
-
},
|
|
1677
|
-
manyToMany: (foreignTable, config) => {
|
|
1678
|
-
return new ManyToManyRelation(foreignTable, config);
|
|
1679
1608
|
}
|
|
1680
1609
|
});
|
|
1681
1610
|
for (const [name, relation] of Object.entries(builtRelations)) {
|
|
@@ -1684,21 +1613,15 @@ var relations = (table, relationsCallback) => {
|
|
|
1684
1613
|
type: "one",
|
|
1685
1614
|
foreignTable: relation.foreignTable,
|
|
1686
1615
|
fields: relation.config?.fields,
|
|
1687
|
-
references: relation.config?.references
|
|
1616
|
+
references: relation.config?.references,
|
|
1617
|
+
optional: relation.config?.optional,
|
|
1618
|
+
alias: relation.config?.alias
|
|
1688
1619
|
};
|
|
1689
1620
|
} else if (relation instanceof ManyRelation) {
|
|
1690
1621
|
table.relations[name] = {
|
|
1691
1622
|
type: "many",
|
|
1692
1623
|
foreignTable: relation.foreignTable
|
|
1693
1624
|
};
|
|
1694
|
-
} else if (relation instanceof ManyToManyRelation) {
|
|
1695
|
-
table.relations[name] = {
|
|
1696
|
-
type: "manyToMany",
|
|
1697
|
-
foreignTable: relation.foreignTable,
|
|
1698
|
-
junctionTable: relation.config.junctionTable,
|
|
1699
|
-
junctionFields: relation.config.junctionFields,
|
|
1700
|
-
junctionReferences: relation.config.junctionReferences
|
|
1701
|
-
};
|
|
1702
1625
|
}
|
|
1703
1626
|
}
|
|
1704
1627
|
return builtRelations;
|
|
@@ -1711,50 +1634,22 @@ var alias = (table, alias2) => {
|
|
|
1711
1634
|
};
|
|
1712
1635
|
|
|
1713
1636
|
// src/aggregates.ts
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
})
|
|
1718
|
-
var
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
})
|
|
1722
|
-
var
|
|
1723
|
-
sql: `SUM(${column._.name})`,
|
|
1724
|
-
params: []
|
|
1725
|
-
});
|
|
1726
|
-
var avg = (column) => ({
|
|
1727
|
-
sql: `AVG(${column._.name})`,
|
|
1728
|
-
params: []
|
|
1729
|
-
});
|
|
1730
|
-
var max = (column) => ({
|
|
1731
|
-
sql: `MAX(${column._.name})`,
|
|
1732
|
-
params: []
|
|
1733
|
-
});
|
|
1734
|
-
var min = (column) => ({
|
|
1735
|
-
sql: `MIN(${column._.name})`,
|
|
1736
|
-
params: []
|
|
1737
|
-
});
|
|
1738
|
-
var groupConcat = (column, separator = ",") => ({
|
|
1739
|
-
sql: `GROUP_CONCAT(${column._.name}, ?)`,
|
|
1740
|
-
params: [separator]
|
|
1741
|
-
});
|
|
1742
|
-
var as = (aggregate, alias2) => ({
|
|
1743
|
-
...aggregate,
|
|
1744
|
-
alias: alias2
|
|
1745
|
-
});
|
|
1637
|
+
import { sql as sql4 } from "kysely";
|
|
1638
|
+
var count = (column) => sql4`COUNT(${column ? sql4.ref(column._.name) : sql4.raw("*")})`;
|
|
1639
|
+
var countDistinct = (column) => sql4`COUNT(DISTINCT ${sql4.ref(column._.name)})`;
|
|
1640
|
+
var sum = (column) => sql4`SUM(${sql4.ref(column._.name)})`;
|
|
1641
|
+
var avg = (column) => sql4`AVG(${sql4.ref(column._.name)})`;
|
|
1642
|
+
var max = (column) => sql4`MAX(${sql4.ref(column._.name)})`;
|
|
1643
|
+
var min = (column) => sql4`MIN(${sql4.ref(column._.name)})`;
|
|
1644
|
+
var groupConcat = (column, separator = ",") => sql4`GROUP_CONCAT(${sql4.ref(column._.name)}, ${sql4.val(separator)})`;
|
|
1645
|
+
var as = (aggregate, alias2) => Object.assign(aggregate, { alias: alias2 });
|
|
1746
1646
|
|
|
1747
1647
|
// src/subquery.ts
|
|
1748
1648
|
var subquery = (query) => {
|
|
1749
|
-
|
|
1750
|
-
return {
|
|
1751
|
-
sql: `(${sql2})`,
|
|
1752
|
-
params,
|
|
1753
|
-
_isSubquery: true
|
|
1754
|
-
};
|
|
1649
|
+
return query.toKyselyExpression();
|
|
1755
1650
|
};
|
|
1756
1651
|
var scalarSubquery = (query) => {
|
|
1757
|
-
return
|
|
1652
|
+
return query.toKyselyExpression();
|
|
1758
1653
|
};
|
|
1759
1654
|
|
|
1760
1655
|
// src/column-helpers.ts
|
|
@@ -1773,14 +1668,135 @@ function numeric(name, config) {
|
|
|
1773
1668
|
return new SQLiteColumn(name, "NUMERIC", config);
|
|
1774
1669
|
}
|
|
1775
1670
|
var enumType = (name, values) => text(name, { enum: values });
|
|
1671
|
+
|
|
1672
|
+
// src/relations-v2.ts
|
|
1673
|
+
function extractTables(schema) {
|
|
1674
|
+
const tables = {};
|
|
1675
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
1676
|
+
const v = value;
|
|
1677
|
+
if (v && typeof v === "object" && v._?.name && v._?.columns && typeof v.relations === "object") {
|
|
1678
|
+
tables[key] = v;
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
return tables;
|
|
1682
|
+
}
|
|
1683
|
+
function through(column, junctionColumn, junctionTable) {
|
|
1684
|
+
return { column, junctionColumn, junctionTable };
|
|
1685
|
+
}
|
|
1686
|
+
function toArray(col) {
|
|
1687
|
+
return Array.isArray(col) ? col : [col];
|
|
1688
|
+
}
|
|
1689
|
+
function isThroughRef(v) {
|
|
1690
|
+
return v && typeof v === "object" && "column" in v && "junctionColumn" in v && "junctionTable" in v;
|
|
1691
|
+
}
|
|
1692
|
+
function buildTableRef(table) {
|
|
1693
|
+
return { ...table._.columns };
|
|
1694
|
+
}
|
|
1695
|
+
function buildR(tables) {
|
|
1696
|
+
const tableRefs = {};
|
|
1697
|
+
const oneFns = {};
|
|
1698
|
+
const manyFns = {};
|
|
1699
|
+
for (const [tableKey, table] of Object.entries(tables)) {
|
|
1700
|
+
tableRefs[tableKey] = buildTableRef(table);
|
|
1701
|
+
const foreignTable = table;
|
|
1702
|
+
oneFns[tableKey] = (opts) => {
|
|
1703
|
+
return new OneRelation(foreignTable, {
|
|
1704
|
+
fields: toArray(opts.from),
|
|
1705
|
+
references: toArray(opts.to),
|
|
1706
|
+
optional: opts.optional,
|
|
1707
|
+
alias: opts.alias
|
|
1708
|
+
});
|
|
1709
|
+
};
|
|
1710
|
+
manyFns[tableKey] = (opts) => {
|
|
1711
|
+
if (!opts?.from || !opts?.to) return new ManyRelation(foreignTable);
|
|
1712
|
+
if (isThroughRef(opts.from) && isThroughRef(opts.to)) {
|
|
1713
|
+
return new ManyRelation(foreignTable, {
|
|
1714
|
+
through: {
|
|
1715
|
+
junctionTable: opts.from.junctionTable,
|
|
1716
|
+
fromRef: { column: opts.from.column, junctionColumn: opts.from.junctionColumn },
|
|
1717
|
+
toRef: { column: opts.to.column, junctionColumn: opts.to.junctionColumn }
|
|
1718
|
+
},
|
|
1719
|
+
optional: opts.optional,
|
|
1720
|
+
alias: opts.alias,
|
|
1721
|
+
where: opts.where
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
return new ManyRelation(foreignTable, {
|
|
1725
|
+
from: toArray(opts.from),
|
|
1726
|
+
to: toArray(opts.to),
|
|
1727
|
+
optional: opts.optional,
|
|
1728
|
+
alias: opts.alias,
|
|
1729
|
+
where: opts.where
|
|
1730
|
+
});
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1733
|
+
return {
|
|
1734
|
+
...tableRefs,
|
|
1735
|
+
one: oneFns,
|
|
1736
|
+
many: manyFns
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
function applyRelationsToTables(tables, relationsResult) {
|
|
1740
|
+
for (const [tableKey, rels] of Object.entries(relationsResult)) {
|
|
1741
|
+
const table = tables[tableKey];
|
|
1742
|
+
if (!table) continue;
|
|
1743
|
+
for (const [relName, relation] of Object.entries(rels)) {
|
|
1744
|
+
if (relation instanceof OneRelation) {
|
|
1745
|
+
table.relations[relName] = {
|
|
1746
|
+
type: "one",
|
|
1747
|
+
foreignTable: relation.foreignTable,
|
|
1748
|
+
fields: relation.config?.fields,
|
|
1749
|
+
references: relation.config?.references,
|
|
1750
|
+
optional: relation.config?.optional,
|
|
1751
|
+
alias: relation.config?.alias
|
|
1752
|
+
};
|
|
1753
|
+
} else if (relation instanceof ManyRelation) {
|
|
1754
|
+
const config = relation.config;
|
|
1755
|
+
if (config?.through) {
|
|
1756
|
+
table.relations[relName] = {
|
|
1757
|
+
type: "many",
|
|
1758
|
+
foreignTable: relation.foreignTable,
|
|
1759
|
+
junctionTable: config.through.junctionTable,
|
|
1760
|
+
fromJunction: config.through.fromRef,
|
|
1761
|
+
toJunction: config.through.toRef,
|
|
1762
|
+
optional: config.optional,
|
|
1763
|
+
alias: config.alias,
|
|
1764
|
+
where: config.where
|
|
1765
|
+
};
|
|
1766
|
+
} else {
|
|
1767
|
+
table.relations[relName] = {
|
|
1768
|
+
type: "many",
|
|
1769
|
+
foreignTable: relation.foreignTable,
|
|
1770
|
+
fields: config ? config.to : void 0,
|
|
1771
|
+
references: config ? config.from : void 0,
|
|
1772
|
+
optional: config?.optional,
|
|
1773
|
+
alias: config?.alias,
|
|
1774
|
+
where: config?.where
|
|
1775
|
+
};
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
function defineRelations(schema, callback) {
|
|
1782
|
+
const tables = extractTables(schema);
|
|
1783
|
+
const r = buildR(tables);
|
|
1784
|
+
const result = callback(r);
|
|
1785
|
+
applyRelationsToTables(tables, result);
|
|
1786
|
+
return result;
|
|
1787
|
+
}
|
|
1788
|
+
function defineRelationsPart(schema, callback) {
|
|
1789
|
+
return defineRelations(schema, callback);
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
// src/index.ts
|
|
1793
|
+
import { sql as sql5 } from "kysely";
|
|
1776
1794
|
export {
|
|
1777
|
-
BaseQueryBuilder,
|
|
1778
1795
|
ColumnNotFoundError,
|
|
1779
1796
|
DeleteQueryBuilder,
|
|
1780
1797
|
InsertQueryBuilder,
|
|
1781
1798
|
InsertValidationError,
|
|
1782
1799
|
ManyRelation,
|
|
1783
|
-
ManyToManyRelation,
|
|
1784
1800
|
MigrationError,
|
|
1785
1801
|
MissingWhereClauseError,
|
|
1786
1802
|
OneRelation,
|
|
@@ -1791,6 +1807,7 @@ export {
|
|
|
1791
1807
|
SelectQueryBuilder,
|
|
1792
1808
|
Table,
|
|
1793
1809
|
TableNotFoundError,
|
|
1810
|
+
TauriDialect,
|
|
1794
1811
|
TauriORM,
|
|
1795
1812
|
TauriORMError,
|
|
1796
1813
|
UpdateQueryBuilder,
|
|
@@ -1808,6 +1825,8 @@ export {
|
|
|
1808
1825
|
contains,
|
|
1809
1826
|
count,
|
|
1810
1827
|
countDistinct,
|
|
1828
|
+
defineRelations,
|
|
1829
|
+
defineRelationsPart,
|
|
1811
1830
|
desc,
|
|
1812
1831
|
endsWith,
|
|
1813
1832
|
enumType,
|
|
@@ -1842,10 +1861,11 @@ export {
|
|
|
1842
1861
|
real,
|
|
1843
1862
|
relations,
|
|
1844
1863
|
scalarSubquery,
|
|
1845
|
-
sql,
|
|
1864
|
+
sql5 as sql,
|
|
1846
1865
|
sqliteTable,
|
|
1847
1866
|
startsWith,
|
|
1848
1867
|
subquery,
|
|
1849
1868
|
sum,
|
|
1850
|
-
text
|
|
1869
|
+
text,
|
|
1870
|
+
through
|
|
1851
1871
|
};
|