@type32/tauri-sqlite-orm 0.1.4 → 0.1.6
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 -6
- package/dist/index.d.mts +152 -8
- package/dist/index.d.ts +152 -8
- package/dist/index.js +547 -31
- package/dist/index.mjs +525 -30
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/schema-builder.ts
|
|
2
2
|
function sql(strings, ...values) {
|
|
3
|
-
const
|
|
3
|
+
const raw2 = strings.reduce(
|
|
4
4
|
(acc, part, idx) => acc + part + (idx < values.length ? String(values[idx]) : ""),
|
|
5
5
|
""
|
|
6
6
|
);
|
|
7
|
-
return { raw };
|
|
7
|
+
return { raw: raw2 };
|
|
8
8
|
}
|
|
9
9
|
function createColumn(params) {
|
|
10
10
|
const col = { ...params };
|
|
@@ -131,7 +131,41 @@ function increments(name) {
|
|
|
131
131
|
autoIncrement: true
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
|
-
function
|
|
134
|
+
function unique(name) {
|
|
135
|
+
return {
|
|
136
|
+
on: (...cols) => ({ name, columns: cols.map((c) => c.name) })
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function primaryKey(opts) {
|
|
140
|
+
return { name: opts.name, columns: opts.columns.map((c) => c.name) };
|
|
141
|
+
}
|
|
142
|
+
function check(name, expr) {
|
|
143
|
+
return { name, expr };
|
|
144
|
+
}
|
|
145
|
+
function foreignKey(opts) {
|
|
146
|
+
const first = opts.columns[0];
|
|
147
|
+
return {
|
|
148
|
+
name: opts.name,
|
|
149
|
+
columns: opts.columns.map((c) => c.name),
|
|
150
|
+
foreignTable: first?.tableName || opts.foreignColumns[0]?.tableName || "",
|
|
151
|
+
foreignColumns: opts.foreignColumns.map((c) => c.name),
|
|
152
|
+
onDelete: opts.onDelete,
|
|
153
|
+
onUpdate: opts.onUpdate
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function index(name) {
|
|
157
|
+
return {
|
|
158
|
+
on: (...cols) => ({ name, columns: cols.map((c) => c.name) }),
|
|
159
|
+
where: (expr) => ({ name, columns: [], where: expr })
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function uniqueIndex(name) {
|
|
163
|
+
return {
|
|
164
|
+
on: (...cols) => ({ name, columns: cols.map((c) => c.name), unique: true }),
|
|
165
|
+
where: (expr) => ({ name, columns: [], unique: true, where: expr })
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function defineTable(tableName, schema, extras) {
|
|
135
169
|
const finalizedSchema = { ...schema };
|
|
136
170
|
for (const key of Object.keys(finalizedSchema)) {
|
|
137
171
|
const col = finalizedSchema[key];
|
|
@@ -141,6 +175,8 @@ function defineTable(tableName, schema) {
|
|
|
141
175
|
const table = {
|
|
142
176
|
_tableName: tableName,
|
|
143
177
|
_schema: finalizedSchema,
|
|
178
|
+
_constraints: [],
|
|
179
|
+
_indexes: [],
|
|
144
180
|
// The Drizzle-like type inference properties
|
|
145
181
|
$inferSelect: {},
|
|
146
182
|
$inferInsert: {}
|
|
@@ -149,6 +185,29 @@ function defineTable(tableName, schema) {
|
|
|
149
185
|
for (const [key, col] of Object.entries(finalizedSchema)) {
|
|
150
186
|
table[key] = col;
|
|
151
187
|
}
|
|
188
|
+
if (extras) {
|
|
189
|
+
const specs = extras(table) || [];
|
|
190
|
+
for (const s of specs) {
|
|
191
|
+
if (s.columns && s.unique !== void 0) {
|
|
192
|
+
table._indexes.push(s);
|
|
193
|
+
} else if (s.columns && s.foreignColumns) {
|
|
194
|
+
table._constraints.push(s);
|
|
195
|
+
} else if (s.columns && (s.name || s.name === void 0)) {
|
|
196
|
+
if (s.columns && s.name !== void 0 && s.columns.length > 0) {
|
|
197
|
+
const pk = s;
|
|
198
|
+
if (pk.columns.length > 1 || pk.name && pk.name.length > 0) {
|
|
199
|
+
table._constraints.push(s);
|
|
200
|
+
} else {
|
|
201
|
+
table._constraints.push(s);
|
|
202
|
+
}
|
|
203
|
+
} else {
|
|
204
|
+
table._constraints.push(s);
|
|
205
|
+
}
|
|
206
|
+
} else if (s.expr) {
|
|
207
|
+
table._constraints.push(s);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
152
211
|
return table;
|
|
153
212
|
}
|
|
154
213
|
|
|
@@ -156,6 +215,31 @@ function defineTable(tableName, schema) {
|
|
|
156
215
|
import Database from "@tauri-apps/plugin-sql";
|
|
157
216
|
|
|
158
217
|
// src/sql-helpers.ts
|
|
218
|
+
function raw(strings, ...values) {
|
|
219
|
+
return {
|
|
220
|
+
toSQL: () => {
|
|
221
|
+
let clause = "";
|
|
222
|
+
const bindings = [];
|
|
223
|
+
for (let i = 0; i < strings.length; i++) {
|
|
224
|
+
clause += strings[i];
|
|
225
|
+
if (i < values.length) {
|
|
226
|
+
const v = values[i];
|
|
227
|
+
if (v && typeof v === "object" && typeof v.toSQL === "function") {
|
|
228
|
+
const s = v.toSQL();
|
|
229
|
+
clause += s.clause;
|
|
230
|
+
bindings.push(...s.bindings);
|
|
231
|
+
} else if (v && typeof v === "object" && "_dataType" in v) {
|
|
232
|
+
clause += getQualifiedName(v);
|
|
233
|
+
} else {
|
|
234
|
+
clause += "?";
|
|
235
|
+
bindings.push(v);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return { clause, bindings };
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
159
243
|
function isColumn(value) {
|
|
160
244
|
return typeof value === "object" && value !== null && "_dataType" in value;
|
|
161
245
|
}
|
|
@@ -181,6 +265,36 @@ function comparison(operator, column, value) {
|
|
|
181
265
|
}
|
|
182
266
|
};
|
|
183
267
|
}
|
|
268
|
+
var and = (...conditions) => ({
|
|
269
|
+
toSQL: () => {
|
|
270
|
+
const parts = [];
|
|
271
|
+
const bindings = [];
|
|
272
|
+
for (const c of conditions) {
|
|
273
|
+
const s = c.toSQL();
|
|
274
|
+
parts.push(`(${s.clause})`);
|
|
275
|
+
bindings.push(...s.bindings);
|
|
276
|
+
}
|
|
277
|
+
return { clause: parts.join(" AND "), bindings };
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
var or = (...conditions) => ({
|
|
281
|
+
toSQL: () => {
|
|
282
|
+
const parts = [];
|
|
283
|
+
const bindings = [];
|
|
284
|
+
for (const c of conditions) {
|
|
285
|
+
const s = c.toSQL();
|
|
286
|
+
parts.push(`(${s.clause})`);
|
|
287
|
+
bindings.push(...s.bindings);
|
|
288
|
+
}
|
|
289
|
+
return { clause: parts.join(" OR "), bindings };
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
var not = (condition) => ({
|
|
293
|
+
toSQL: () => {
|
|
294
|
+
const s = condition.toSQL();
|
|
295
|
+
return { clause: `NOT (${s.clause})`, bindings: s.bindings };
|
|
296
|
+
}
|
|
297
|
+
});
|
|
184
298
|
var eq = (column, value) => comparison("=", column, value);
|
|
185
299
|
var ne = (column, value) => comparison("!=", column, value);
|
|
186
300
|
var gt = (column, value) => comparison(">", column, value);
|
|
@@ -188,32 +302,154 @@ var gte = (column, value) => comparison(">=", column, value);
|
|
|
188
302
|
var lt = (column, value) => comparison("<", column, value);
|
|
189
303
|
var lte = (column, value) => comparison("<=", column, value);
|
|
190
304
|
var like = (column, value) => comparison("LIKE", column, value);
|
|
305
|
+
var ilike = (column, value) => ({
|
|
306
|
+
toSQL: () => {
|
|
307
|
+
const colExpr = `LOWER(${getQualifiedName(column)})`;
|
|
308
|
+
if (isColumn(value)) {
|
|
309
|
+
return {
|
|
310
|
+
clause: `${colExpr} LIKE LOWER(${getQualifiedName(value)})`,
|
|
311
|
+
bindings: []
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
return { clause: `${colExpr} LIKE LOWER(?)`, bindings: [value] };
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
var notIlike = (column, value) => ({
|
|
318
|
+
toSQL: () => {
|
|
319
|
+
const colExpr = `LOWER(${getQualifiedName(column)})`;
|
|
320
|
+
if (isColumn(value)) {
|
|
321
|
+
return {
|
|
322
|
+
clause: `${colExpr} NOT LIKE LOWER(${getQualifiedName(value)})`,
|
|
323
|
+
bindings: []
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
return { clause: `${colExpr} NOT LIKE LOWER(?)`, bindings: [value] };
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
var isNull = (column) => ({
|
|
330
|
+
toSQL: () => ({
|
|
331
|
+
clause: `${getQualifiedName(column)} IS NULL`,
|
|
332
|
+
bindings: []
|
|
333
|
+
})
|
|
334
|
+
});
|
|
335
|
+
var isNotNull = (column) => ({
|
|
336
|
+
toSQL: () => ({
|
|
337
|
+
clause: `${getQualifiedName(column)} IS NOT NULL`,
|
|
338
|
+
bindings: []
|
|
339
|
+
})
|
|
340
|
+
});
|
|
341
|
+
var between = (column, from, to) => ({
|
|
342
|
+
toSQL: () => {
|
|
343
|
+
const left = getQualifiedName(column);
|
|
344
|
+
const [fromClause, fromBindings] = isColumn(from) ? [getQualifiedName(from), []] : ["?", [from]];
|
|
345
|
+
const [toClause, toBindings] = isColumn(to) ? [getQualifiedName(to), []] : ["?", [to]];
|
|
346
|
+
return {
|
|
347
|
+
clause: `${left} BETWEEN ${fromClause} AND ${toClause}`,
|
|
348
|
+
bindings: [...fromBindings, ...toBindings]
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
var notBetween = (column, from, to) => ({
|
|
353
|
+
toSQL: () => {
|
|
354
|
+
const left = getQualifiedName(column);
|
|
355
|
+
const [fromClause, fromBindings] = isColumn(from) ? [getQualifiedName(from), []] : ["?", [from]];
|
|
356
|
+
const [toClause, toBindings] = isColumn(to) ? [getQualifiedName(to), []] : ["?", [to]];
|
|
357
|
+
return {
|
|
358
|
+
clause: `${left} NOT BETWEEN ${fromClause} AND ${toClause}`,
|
|
359
|
+
bindings: [...fromBindings, ...toBindings]
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
var inArray = (column, valuesOrQuery) => ({
|
|
364
|
+
toSQL: () => {
|
|
365
|
+
const left = getQualifiedName(column);
|
|
366
|
+
if (Array.isArray(valuesOrQuery)) {
|
|
367
|
+
const placeholders = valuesOrQuery.map(() => "?").join(", ");
|
|
368
|
+
return {
|
|
369
|
+
clause: `${left} IN (${placeholders})`,
|
|
370
|
+
bindings: valuesOrQuery
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
const sq = valuesOrQuery.toSQL ? valuesOrQuery.toSQL() : valuesOrQuery.toSQL();
|
|
374
|
+
return { clause: `${left} IN (${sq.clause})`, bindings: sq.bindings };
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
var notInArray = (column, valuesOrQuery) => ({
|
|
378
|
+
toSQL: () => {
|
|
379
|
+
const left = getQualifiedName(column);
|
|
380
|
+
if (Array.isArray(valuesOrQuery)) {
|
|
381
|
+
const placeholders = valuesOrQuery.map(() => "?").join(", ");
|
|
382
|
+
return {
|
|
383
|
+
clause: `${left} NOT IN (${placeholders})`,
|
|
384
|
+
bindings: valuesOrQuery
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
const sq = valuesOrQuery.toSQL ? valuesOrQuery.toSQL() : valuesOrQuery.toSQL();
|
|
388
|
+
return { clause: `${left} NOT IN (${sq.clause})`, bindings: sq.bindings };
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
var exists = (subquery) => ({
|
|
392
|
+
toSQL: () => {
|
|
393
|
+
const sq = subquery.toSQL ? subquery.toSQL() : subquery.toSQL();
|
|
394
|
+
return { clause: `EXISTS (${sq.clause})`, bindings: sq.bindings };
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
var notExists = (subquery) => ({
|
|
398
|
+
toSQL: () => {
|
|
399
|
+
const sq = subquery.toSQL ? subquery.toSQL() : subquery.toSQL();
|
|
400
|
+
return { clause: `NOT EXISTS (${sq.clause})`, bindings: sq.bindings };
|
|
401
|
+
}
|
|
402
|
+
});
|
|
191
403
|
var asc = (column) => `${getQualifiedName(column)} ASC`;
|
|
192
404
|
var desc = (column) => `${getQualifiedName(column)} DESC`;
|
|
193
405
|
|
|
194
406
|
// src/orm.ts
|
|
195
407
|
var SelectQueryBuilder = class {
|
|
196
408
|
_table = null;
|
|
197
|
-
_selectedColumns = [
|
|
409
|
+
_selectedColumns = [];
|
|
198
410
|
_joins = [];
|
|
199
411
|
_where = [];
|
|
200
412
|
_orderBy = [];
|
|
201
413
|
_limit = null;
|
|
202
414
|
_offset = null;
|
|
203
|
-
|
|
415
|
+
_groupBy = [];
|
|
416
|
+
_having = [];
|
|
417
|
+
_distinct = false;
|
|
204
418
|
_dbProvider;
|
|
205
419
|
constructor(dbProvider, fields) {
|
|
206
420
|
this._dbProvider = dbProvider;
|
|
207
421
|
if (fields) {
|
|
208
|
-
|
|
422
|
+
for (const [alias, col] of Object.entries(fields)) {
|
|
423
|
+
const sql2 = getQualifiedName(col);
|
|
424
|
+
this._selectedColumns.push({ sql: sql2, alias });
|
|
425
|
+
}
|
|
209
426
|
}
|
|
210
427
|
}
|
|
428
|
+
distinct() {
|
|
429
|
+
this._distinct = true;
|
|
430
|
+
return this;
|
|
431
|
+
}
|
|
432
|
+
select(fields) {
|
|
433
|
+
this._selectedColumns = [];
|
|
434
|
+
for (const [alias, expr] of Object.entries(fields)) {
|
|
435
|
+
if (typeof expr.toSQL === "function") {
|
|
436
|
+
const s = expr.toSQL();
|
|
437
|
+
this._selectedColumns.push({ sql: s.clause, alias });
|
|
438
|
+
} else {
|
|
439
|
+
this._selectedColumns.push({
|
|
440
|
+
sql: getQualifiedName(expr),
|
|
441
|
+
alias
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return this;
|
|
446
|
+
}
|
|
211
447
|
from(table) {
|
|
212
448
|
this._table = table;
|
|
213
449
|
return this;
|
|
214
450
|
}
|
|
215
451
|
where(...conditions) {
|
|
216
|
-
this._where.push(...conditions);
|
|
452
|
+
this._where.push(...conditions.filter(Boolean));
|
|
217
453
|
return this;
|
|
218
454
|
}
|
|
219
455
|
leftJoin(otherTable, on) {
|
|
@@ -222,8 +458,26 @@ var SelectQueryBuilder = class {
|
|
|
222
458
|
this._joins.push(joinClause);
|
|
223
459
|
return this;
|
|
224
460
|
}
|
|
461
|
+
groupBy(...exprs) {
|
|
462
|
+
for (const e of exprs) {
|
|
463
|
+
if (!e) continue;
|
|
464
|
+
if (typeof e === "string") this._groupBy.push(e);
|
|
465
|
+
else this._groupBy.push(getQualifiedName(e));
|
|
466
|
+
}
|
|
467
|
+
return this;
|
|
468
|
+
}
|
|
469
|
+
having(...conditions) {
|
|
470
|
+
this._having.push(...conditions);
|
|
471
|
+
return this;
|
|
472
|
+
}
|
|
225
473
|
orderBy(...clauses) {
|
|
226
|
-
|
|
474
|
+
for (const c of clauses) {
|
|
475
|
+
if (!c) continue;
|
|
476
|
+
if (typeof c === "string") this._orderBy.push(c);
|
|
477
|
+
else if (typeof c.toSQL === "function")
|
|
478
|
+
this._orderBy.push(c);
|
|
479
|
+
else this._orderBy.push(getQualifiedName(c));
|
|
480
|
+
}
|
|
227
481
|
return this;
|
|
228
482
|
}
|
|
229
483
|
limit(value) {
|
|
@@ -234,17 +488,15 @@ var SelectQueryBuilder = class {
|
|
|
234
488
|
this._offset = value;
|
|
235
489
|
return this;
|
|
236
490
|
}
|
|
237
|
-
// The final execution step
|
|
238
491
|
async execute() {
|
|
239
492
|
if (!this._table) {
|
|
240
493
|
throw new Error("Cannot execute select query without a 'from' table.");
|
|
241
494
|
}
|
|
242
495
|
const db = await this._dbProvider();
|
|
243
496
|
const bindings = [];
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
497
|
+
const selectList = this._selectedColumns.length > 0 ? this._selectedColumns.map((c) => c.alias ? `${c.sql} AS ${c.alias}` : c.sql).join(", ") : Object.values(this._table._schema).map((c) => `${this._table._tableName}.${c.name}`).join(", ");
|
|
498
|
+
let query = `SELECT ${this._distinct ? "DISTINCT " : ""}${selectList} FROM ${this._table._tableName}`;
|
|
499
|
+
if (this._joins.length > 0) query += ` ${this._joins.join(" ")}`;
|
|
248
500
|
if (this._where.length > 0) {
|
|
249
501
|
const whereClauses = this._where.map((condition) => {
|
|
250
502
|
const sql2 = condition.toSQL();
|
|
@@ -253,22 +505,47 @@ var SelectQueryBuilder = class {
|
|
|
253
505
|
});
|
|
254
506
|
query += ` WHERE ${whereClauses.join(" AND ")}`;
|
|
255
507
|
}
|
|
508
|
+
if (this._groupBy.length > 0) {
|
|
509
|
+
query += ` GROUP BY ${this._groupBy.join(", ")}`;
|
|
510
|
+
}
|
|
511
|
+
if (this._having.length > 0) {
|
|
512
|
+
const havingClauses = this._having.map((h) => {
|
|
513
|
+
const sql2 = h.toSQL();
|
|
514
|
+
bindings.push(...sql2.bindings);
|
|
515
|
+
return `(${sql2.clause})`;
|
|
516
|
+
});
|
|
517
|
+
query += ` HAVING ${havingClauses.join(" AND ")}`;
|
|
518
|
+
}
|
|
256
519
|
if (this._orderBy.length > 0) {
|
|
257
|
-
|
|
520
|
+
const ordParts = [];
|
|
521
|
+
for (const ob of this._orderBy) {
|
|
522
|
+
if (typeof ob === "string") ordParts.push(ob);
|
|
523
|
+
else {
|
|
524
|
+
const s = ob.toSQL();
|
|
525
|
+
ordParts.push(s.clause);
|
|
526
|
+
bindings.push(...s.bindings);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
258
530
|
}
|
|
259
531
|
if (this._limit !== null) {
|
|
260
532
|
query += ` LIMIT ?`;
|
|
261
533
|
bindings.push(this._limit);
|
|
262
534
|
}
|
|
263
535
|
if (this._offset !== null) {
|
|
264
|
-
if (this._limit === null)
|
|
265
|
-
query += ` LIMIT -1`;
|
|
266
|
-
}
|
|
536
|
+
if (this._limit === null) query += ` LIMIT -1`;
|
|
267
537
|
query += ` OFFSET ?`;
|
|
268
538
|
bindings.push(this._offset);
|
|
269
539
|
}
|
|
270
540
|
return db.select(query, bindings);
|
|
271
541
|
}
|
|
542
|
+
async iterator() {
|
|
543
|
+
const rows = await this.execute();
|
|
544
|
+
async function* gen() {
|
|
545
|
+
for (const r of rows) yield r;
|
|
546
|
+
}
|
|
547
|
+
return gen();
|
|
548
|
+
}
|
|
272
549
|
};
|
|
273
550
|
var TauriORM = class {
|
|
274
551
|
// Soft relational query API: db.query.users.findMany({ with: { posts: true } })
|
|
@@ -289,18 +566,67 @@ var TauriORM = class {
|
|
|
289
566
|
select(fields) {
|
|
290
567
|
return new SelectQueryBuilder(this.getDb.bind(this), fields);
|
|
291
568
|
}
|
|
569
|
+
selectDistinct(fields) {
|
|
570
|
+
const qb = new SelectQueryBuilder(this.getDb.bind(this), fields);
|
|
571
|
+
qb.distinct();
|
|
572
|
+
return qb;
|
|
573
|
+
}
|
|
292
574
|
// --- Drizzle-style CRUD builders ---
|
|
293
575
|
insert(table) {
|
|
294
576
|
const self = this;
|
|
295
577
|
return new class InsertBuilder {
|
|
296
578
|
_table = table;
|
|
297
579
|
_rows = [];
|
|
580
|
+
_selectSql = null;
|
|
581
|
+
_conflict = null;
|
|
582
|
+
_returning = null;
|
|
298
583
|
values(rowOrRows) {
|
|
299
584
|
this._rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
|
|
300
585
|
return this;
|
|
301
586
|
}
|
|
587
|
+
select(qb) {
|
|
588
|
+
if (qb.toSQL) this._selectSql = qb.toSQL();
|
|
589
|
+
else this._selectSql = qb.toSQL();
|
|
590
|
+
return this;
|
|
591
|
+
}
|
|
592
|
+
returning(fields) {
|
|
593
|
+
this._returning = fields ?? {};
|
|
594
|
+
return this;
|
|
595
|
+
}
|
|
596
|
+
$returningId() {
|
|
597
|
+
this._returning = "__RETURNING_ID__";
|
|
598
|
+
return this;
|
|
599
|
+
}
|
|
600
|
+
onConflictDoNothing(opts) {
|
|
601
|
+
const target = opts?.target ? Array.isArray(opts.target) ? opts.target.map((c) => c.name) : opts.target.name : void 0;
|
|
602
|
+
this._conflict = {
|
|
603
|
+
kind: "doNothing",
|
|
604
|
+
target,
|
|
605
|
+
where: opts?.where
|
|
606
|
+
};
|
|
607
|
+
return this;
|
|
608
|
+
}
|
|
609
|
+
onConflictDoUpdate(opts) {
|
|
610
|
+
const target = Array.isArray(opts.target) ? opts.target.map((c) => c.name) : opts.target.name;
|
|
611
|
+
this._conflict = {
|
|
612
|
+
kind: "doUpdate",
|
|
613
|
+
target,
|
|
614
|
+
targetWhere: opts.targetWhere,
|
|
615
|
+
set: opts.set,
|
|
616
|
+
setWhere: opts.setWhere
|
|
617
|
+
};
|
|
618
|
+
return this;
|
|
619
|
+
}
|
|
302
620
|
async execute() {
|
|
303
621
|
const db = await self.getDb();
|
|
622
|
+
if (this._selectSql) {
|
|
623
|
+
const cols = Object.keys(this._table._schema);
|
|
624
|
+
let query = `INSERT INTO ${this._table._tableName} (${cols.join(", ")}) ${this._selectSql.clause}`;
|
|
625
|
+
const bindings = [...this._selectSql.bindings];
|
|
626
|
+
query += this._buildConflictClause();
|
|
627
|
+
const ret = await this._executeWithReturning(db, query, bindings);
|
|
628
|
+
return ret;
|
|
629
|
+
}
|
|
304
630
|
for (const data of this._rows) {
|
|
305
631
|
const finalData = { ...data };
|
|
306
632
|
const schema = this._table._schema;
|
|
@@ -316,11 +642,51 @@ var TauriORM = class {
|
|
|
316
642
|
const keys = Object.keys(finalData);
|
|
317
643
|
const values = Object.values(finalData);
|
|
318
644
|
const placeholders = values.map(() => "?").join(", ");
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
await
|
|
645
|
+
let query = `INSERT INTO ${this._table._tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
|
|
646
|
+
const bindings = [...values];
|
|
647
|
+
query += this._buildConflictClause();
|
|
648
|
+
const ret = await this._executeWithReturning(db, query, bindings);
|
|
649
|
+
if (ret !== void 0) return ret;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
_buildConflictClause() {
|
|
653
|
+
if (!this._conflict) return "";
|
|
654
|
+
if (this._conflict.kind === "doNothing") {
|
|
655
|
+
const tgt2 = this._conflict.target ? Array.isArray(this._conflict.target) ? `(${this._conflict.target.join(", ")})` : `(${this._conflict.target})` : "";
|
|
656
|
+
const where = this._conflict.where ? ` WHERE ${this._conflict.where.toSQL().clause}` : "";
|
|
657
|
+
return ` ON CONFLICT ${tgt2} DO NOTHING${where}`;
|
|
323
658
|
}
|
|
659
|
+
const c = this._conflict;
|
|
660
|
+
const tgt = Array.isArray(c.target) ? `(${c.target.join(", ")})` : `(${c.target})`;
|
|
661
|
+
const setKeys = Object.keys(c.set ?? {});
|
|
662
|
+
const setClause = setKeys.map((k) => {
|
|
663
|
+
const v = c.set[k];
|
|
664
|
+
return `${k} = ${typeof v === "object" && v && typeof v.toSQL === "function" ? v.toSQL().clause : "?"}`;
|
|
665
|
+
}).join(", ");
|
|
666
|
+
const targetWhere = c.targetWhere ? ` WHERE ${c.targetWhere.toSQL().clause}` : "";
|
|
667
|
+
const setWhere = c.setWhere ? ` WHERE ${c.setWhere.toSQL().clause}` : "";
|
|
668
|
+
return ` ON CONFLICT ${tgt}${targetWhere} DO UPDATE SET ${setClause}${setWhere}`;
|
|
669
|
+
}
|
|
670
|
+
async _executeWithReturning(db, query, bindings) {
|
|
671
|
+
if (this._returning === null) {
|
|
672
|
+
await db.execute(query, bindings);
|
|
673
|
+
return void 0;
|
|
674
|
+
}
|
|
675
|
+
if (this._returning === "__RETURNING_ID__") {
|
|
676
|
+
const rows = await db.select(`SELECT last_insert_rowid() as id`);
|
|
677
|
+
return rows.map((r) => ({ id: r.id }));
|
|
678
|
+
}
|
|
679
|
+
if (typeof this._returning === "object") {
|
|
680
|
+
const cols = Object.entries(
|
|
681
|
+
this._returning
|
|
682
|
+
).map(
|
|
683
|
+
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
684
|
+
).join(", ");
|
|
685
|
+
const retSql = `${query} RETURNING ${cols}`;
|
|
686
|
+
const res = await db.select(retSql, bindings);
|
|
687
|
+
return res;
|
|
688
|
+
}
|
|
689
|
+
return void 0;
|
|
324
690
|
}
|
|
325
691
|
}();
|
|
326
692
|
}
|
|
@@ -330,6 +696,10 @@ var TauriORM = class {
|
|
|
330
696
|
_table = table;
|
|
331
697
|
_data = null;
|
|
332
698
|
_where = null;
|
|
699
|
+
_orderBy = [];
|
|
700
|
+
_limit = null;
|
|
701
|
+
_from = null;
|
|
702
|
+
_returning = null;
|
|
333
703
|
set(data) {
|
|
334
704
|
this._data = data;
|
|
335
705
|
return this;
|
|
@@ -338,6 +708,28 @@ var TauriORM = class {
|
|
|
338
708
|
this._where = cond;
|
|
339
709
|
return this;
|
|
340
710
|
}
|
|
711
|
+
orderBy(...clauses) {
|
|
712
|
+
for (const c of clauses) {
|
|
713
|
+
if (!c) continue;
|
|
714
|
+
if (typeof c === "string") this._orderBy.push(c);
|
|
715
|
+
else if (typeof c.toSQL === "function")
|
|
716
|
+
this._orderBy.push(c);
|
|
717
|
+
else this._orderBy.push(getQualifiedName(c));
|
|
718
|
+
}
|
|
719
|
+
return this;
|
|
720
|
+
}
|
|
721
|
+
limit(n) {
|
|
722
|
+
this._limit = n;
|
|
723
|
+
return this;
|
|
724
|
+
}
|
|
725
|
+
from(tbl) {
|
|
726
|
+
this._from = tbl;
|
|
727
|
+
return this;
|
|
728
|
+
}
|
|
729
|
+
returning(fields) {
|
|
730
|
+
this._returning = fields ?? {};
|
|
731
|
+
return this;
|
|
732
|
+
}
|
|
341
733
|
async execute() {
|
|
342
734
|
if (!this._data)
|
|
343
735
|
throw new Error("Update requires set() before execute()");
|
|
@@ -349,10 +741,21 @@ var TauriORM = class {
|
|
|
349
741
|
dataToSet[key] = col.onUpdateFn();
|
|
350
742
|
}
|
|
351
743
|
}
|
|
352
|
-
const
|
|
353
|
-
const
|
|
354
|
-
const
|
|
355
|
-
|
|
744
|
+
const setParts = [];
|
|
745
|
+
const bindings = [];
|
|
746
|
+
for (const [k, v] of Object.entries(dataToSet)) {
|
|
747
|
+
if (v === void 0) continue;
|
|
748
|
+
if (v && typeof v === "object" && typeof v.toSQL === "function") {
|
|
749
|
+
const s = v.toSQL();
|
|
750
|
+
setParts.push(`${k} = ${s.clause}`);
|
|
751
|
+
bindings.push(...s.bindings);
|
|
752
|
+
} else {
|
|
753
|
+
setParts.push(`${k} = ?`);
|
|
754
|
+
bindings.push(v);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
let query = `UPDATE ${this._table._tableName} SET ${setParts.join(", ")}`;
|
|
758
|
+
if (this._from) query += ` FROM ${this._from._tableName}`;
|
|
356
759
|
if (this._where) {
|
|
357
760
|
if (typeof this._where.toSQL === "function") {
|
|
358
761
|
const sql2 = this._where.toSQL();
|
|
@@ -366,6 +769,31 @@ var TauriORM = class {
|
|
|
366
769
|
}
|
|
367
770
|
}
|
|
368
771
|
}
|
|
772
|
+
if (this._orderBy.length > 0) {
|
|
773
|
+
const ordParts = [];
|
|
774
|
+
for (const ob of this._orderBy) {
|
|
775
|
+
if (typeof ob === "string") ordParts.push(ob);
|
|
776
|
+
else {
|
|
777
|
+
const s = ob.toSQL();
|
|
778
|
+
ordParts.push(s.clause);
|
|
779
|
+
bindings.push(...s.bindings);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
783
|
+
}
|
|
784
|
+
if (this._limit !== null) {
|
|
785
|
+
query += ` LIMIT ?`;
|
|
786
|
+
bindings.push(this._limit);
|
|
787
|
+
}
|
|
788
|
+
if (this._returning) {
|
|
789
|
+
const cols = Object.entries(
|
|
790
|
+
this._returning
|
|
791
|
+
).map(
|
|
792
|
+
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
793
|
+
).join(", ");
|
|
794
|
+
const retSql = `${query} RETURNING ${cols}`;
|
|
795
|
+
return await db.select(retSql, bindings);
|
|
796
|
+
}
|
|
369
797
|
await db.execute(query, bindings);
|
|
370
798
|
}
|
|
371
799
|
}();
|
|
@@ -375,10 +803,31 @@ var TauriORM = class {
|
|
|
375
803
|
return new class DeleteBuilder {
|
|
376
804
|
_table = table;
|
|
377
805
|
_where = null;
|
|
806
|
+
_orderBy = [];
|
|
807
|
+
_limit = null;
|
|
808
|
+
_returning = null;
|
|
378
809
|
where(cond) {
|
|
379
810
|
this._where = cond;
|
|
380
811
|
return this;
|
|
381
812
|
}
|
|
813
|
+
orderBy(...clauses) {
|
|
814
|
+
for (const c of clauses) {
|
|
815
|
+
if (!c) continue;
|
|
816
|
+
if (typeof c === "string") this._orderBy.push(c);
|
|
817
|
+
else if (typeof c.toSQL === "function")
|
|
818
|
+
this._orderBy.push(c);
|
|
819
|
+
else this._orderBy.push(getQualifiedName(c));
|
|
820
|
+
}
|
|
821
|
+
return this;
|
|
822
|
+
}
|
|
823
|
+
limit(n) {
|
|
824
|
+
this._limit = n;
|
|
825
|
+
return this;
|
|
826
|
+
}
|
|
827
|
+
returning(fields) {
|
|
828
|
+
this._returning = fields ?? {};
|
|
829
|
+
return this;
|
|
830
|
+
}
|
|
382
831
|
async execute() {
|
|
383
832
|
const db = await self.getDb();
|
|
384
833
|
let query = `DELETE FROM ${this._table._tableName}`;
|
|
@@ -396,6 +845,31 @@ var TauriORM = class {
|
|
|
396
845
|
}
|
|
397
846
|
}
|
|
398
847
|
}
|
|
848
|
+
if (this._orderBy.length > 0) {
|
|
849
|
+
const ordParts = [];
|
|
850
|
+
for (const ob of this._orderBy) {
|
|
851
|
+
if (typeof ob === "string") ordParts.push(ob);
|
|
852
|
+
else {
|
|
853
|
+
const s = ob.toSQL();
|
|
854
|
+
ordParts.push(s.clause);
|
|
855
|
+
bindings.push(...s.bindings);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
859
|
+
}
|
|
860
|
+
if (this._limit !== null) {
|
|
861
|
+
query += ` LIMIT ?`;
|
|
862
|
+
bindings.push(this._limit);
|
|
863
|
+
}
|
|
864
|
+
if (this._returning) {
|
|
865
|
+
const cols = Object.entries(
|
|
866
|
+
this._returning
|
|
867
|
+
).map(
|
|
868
|
+
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
869
|
+
).join(", ");
|
|
870
|
+
const retSql = `${query} RETURNING ${cols}`;
|
|
871
|
+
return await db.select(retSql, bindings);
|
|
872
|
+
}
|
|
399
873
|
await db.execute(query, bindings);
|
|
400
874
|
}
|
|
401
875
|
}();
|
|
@@ -674,8 +1148,8 @@ var TauriORM = class {
|
|
|
674
1148
|
const preserve = options?.preserveData !== false;
|
|
675
1149
|
for (const tbl of Object.values(this._tables)) {
|
|
676
1150
|
const tableName = tbl._tableName;
|
|
677
|
-
const
|
|
678
|
-
if (!
|
|
1151
|
+
const exists2 = await this.tableExists(tableName);
|
|
1152
|
+
if (!exists2) {
|
|
679
1153
|
await this.run(this.buildCreateTableSQL(tbl));
|
|
680
1154
|
continue;
|
|
681
1155
|
}
|
|
@@ -912,10 +1386,10 @@ function makeQueryAPI(tables, relDefs, dbProvider) {
|
|
|
912
1386
|
const childPk = fkMap[relName].childPk;
|
|
913
1387
|
if (childPk) {
|
|
914
1388
|
if (!acc[relName]) acc[relName] = [];
|
|
915
|
-
const
|
|
1389
|
+
const exists2 = acc[relName].some(
|
|
916
1390
|
(r) => r[childPk.name] === childObj[childPk.name]
|
|
917
1391
|
);
|
|
918
|
-
if (!
|
|
1392
|
+
if (!exists2) acc[relName].push(childObj);
|
|
919
1393
|
} else {
|
|
920
1394
|
acc[relName].push(childObj);
|
|
921
1395
|
}
|
|
@@ -1044,25 +1518,46 @@ function makeQueryAPI(tables, relDefs, dbProvider) {
|
|
|
1044
1518
|
}
|
|
1045
1519
|
export {
|
|
1046
1520
|
TauriORM,
|
|
1521
|
+
and,
|
|
1047
1522
|
asc,
|
|
1523
|
+
between,
|
|
1048
1524
|
blob,
|
|
1049
1525
|
boolean,
|
|
1526
|
+
check,
|
|
1050
1527
|
defineTable,
|
|
1051
1528
|
desc,
|
|
1052
1529
|
eq,
|
|
1530
|
+
exists,
|
|
1531
|
+
foreignKey,
|
|
1532
|
+
getQualifiedName,
|
|
1053
1533
|
gt,
|
|
1054
1534
|
gte,
|
|
1535
|
+
ilike,
|
|
1536
|
+
inArray,
|
|
1055
1537
|
increments,
|
|
1538
|
+
index,
|
|
1056
1539
|
integer,
|
|
1540
|
+
isNotNull,
|
|
1541
|
+
isNull,
|
|
1057
1542
|
like,
|
|
1058
1543
|
lt,
|
|
1059
1544
|
lte,
|
|
1060
1545
|
makeQueryAPI,
|
|
1061
1546
|
ne,
|
|
1547
|
+
not,
|
|
1548
|
+
notBetween,
|
|
1549
|
+
notExists,
|
|
1550
|
+
notIlike,
|
|
1551
|
+
notInArray,
|
|
1062
1552
|
numeric,
|
|
1553
|
+
or,
|
|
1554
|
+
primaryKey,
|
|
1555
|
+
raw,
|
|
1063
1556
|
real,
|
|
1064
1557
|
relations,
|
|
1065
1558
|
sql,
|
|
1066
1559
|
text,
|
|
1067
|
-
timestamp
|
|
1560
|
+
timestamp,
|
|
1561
|
+
unique,
|
|
1562
|
+
uniqueIndex
|
|
1068
1563
|
};
|