@type32/tauri-sqlite-orm 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +1 -1
package/dist/index.js
CHANGED
|
@@ -31,37 +31,58 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
TauriORM: () => TauriORM,
|
|
34
|
+
and: () => and,
|
|
34
35
|
asc: () => asc,
|
|
36
|
+
between: () => between,
|
|
35
37
|
blob: () => blob,
|
|
36
38
|
boolean: () => boolean,
|
|
39
|
+
check: () => check,
|
|
37
40
|
defineTable: () => defineTable,
|
|
38
41
|
desc: () => desc,
|
|
39
42
|
eq: () => eq,
|
|
43
|
+
exists: () => exists,
|
|
44
|
+
foreignKey: () => foreignKey,
|
|
45
|
+
getQualifiedName: () => getQualifiedName,
|
|
40
46
|
gt: () => gt,
|
|
41
47
|
gte: () => gte,
|
|
48
|
+
ilike: () => ilike,
|
|
49
|
+
inArray: () => inArray,
|
|
42
50
|
increments: () => increments,
|
|
51
|
+
index: () => index,
|
|
43
52
|
integer: () => integer,
|
|
53
|
+
isNotNull: () => isNotNull,
|
|
54
|
+
isNull: () => isNull,
|
|
44
55
|
like: () => like,
|
|
45
56
|
lt: () => lt,
|
|
46
57
|
lte: () => lte,
|
|
47
58
|
makeQueryAPI: () => makeQueryAPI,
|
|
48
59
|
ne: () => ne,
|
|
60
|
+
not: () => not,
|
|
61
|
+
notBetween: () => notBetween,
|
|
62
|
+
notExists: () => notExists,
|
|
63
|
+
notIlike: () => notIlike,
|
|
64
|
+
notInArray: () => notInArray,
|
|
49
65
|
numeric: () => numeric,
|
|
66
|
+
or: () => or,
|
|
67
|
+
primaryKey: () => primaryKey,
|
|
68
|
+
raw: () => raw,
|
|
50
69
|
real: () => real,
|
|
51
70
|
relations: () => relations,
|
|
52
71
|
sql: () => sql,
|
|
53
72
|
text: () => text,
|
|
54
|
-
timestamp: () => timestamp
|
|
73
|
+
timestamp: () => timestamp,
|
|
74
|
+
unique: () => unique,
|
|
75
|
+
uniqueIndex: () => uniqueIndex
|
|
55
76
|
});
|
|
56
77
|
module.exports = __toCommonJS(index_exports);
|
|
57
78
|
|
|
58
79
|
// src/schema-builder.ts
|
|
59
80
|
function sql(strings, ...values) {
|
|
60
|
-
const
|
|
81
|
+
const raw2 = strings.reduce(
|
|
61
82
|
(acc, part, idx) => acc + part + (idx < values.length ? String(values[idx]) : ""),
|
|
62
83
|
""
|
|
63
84
|
);
|
|
64
|
-
return { raw };
|
|
85
|
+
return { raw: raw2 };
|
|
65
86
|
}
|
|
66
87
|
function createColumn(params) {
|
|
67
88
|
const col = { ...params };
|
|
@@ -188,7 +209,41 @@ function increments(name) {
|
|
|
188
209
|
autoIncrement: true
|
|
189
210
|
});
|
|
190
211
|
}
|
|
191
|
-
function
|
|
212
|
+
function unique(name) {
|
|
213
|
+
return {
|
|
214
|
+
on: (...cols) => ({ name, columns: cols.map((c) => c.name) })
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function primaryKey(opts) {
|
|
218
|
+
return { name: opts.name, columns: opts.columns.map((c) => c.name) };
|
|
219
|
+
}
|
|
220
|
+
function check(name, expr) {
|
|
221
|
+
return { name, expr };
|
|
222
|
+
}
|
|
223
|
+
function foreignKey(opts) {
|
|
224
|
+
const first = opts.columns[0];
|
|
225
|
+
return {
|
|
226
|
+
name: opts.name,
|
|
227
|
+
columns: opts.columns.map((c) => c.name),
|
|
228
|
+
foreignTable: first?.tableName || opts.foreignColumns[0]?.tableName || "",
|
|
229
|
+
foreignColumns: opts.foreignColumns.map((c) => c.name),
|
|
230
|
+
onDelete: opts.onDelete,
|
|
231
|
+
onUpdate: opts.onUpdate
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function index(name) {
|
|
235
|
+
return {
|
|
236
|
+
on: (...cols) => ({ name, columns: cols.map((c) => c.name) }),
|
|
237
|
+
where: (expr) => ({ name, columns: [], where: expr })
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function uniqueIndex(name) {
|
|
241
|
+
return {
|
|
242
|
+
on: (...cols) => ({ name, columns: cols.map((c) => c.name), unique: true }),
|
|
243
|
+
where: (expr) => ({ name, columns: [], unique: true, where: expr })
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function defineTable(tableName, schema, extras) {
|
|
192
247
|
const finalizedSchema = { ...schema };
|
|
193
248
|
for (const key of Object.keys(finalizedSchema)) {
|
|
194
249
|
const col = finalizedSchema[key];
|
|
@@ -198,6 +253,8 @@ function defineTable(tableName, schema) {
|
|
|
198
253
|
const table = {
|
|
199
254
|
_tableName: tableName,
|
|
200
255
|
_schema: finalizedSchema,
|
|
256
|
+
_constraints: [],
|
|
257
|
+
_indexes: [],
|
|
201
258
|
// The Drizzle-like type inference properties
|
|
202
259
|
$inferSelect: {},
|
|
203
260
|
$inferInsert: {}
|
|
@@ -206,6 +263,29 @@ function defineTable(tableName, schema) {
|
|
|
206
263
|
for (const [key, col] of Object.entries(finalizedSchema)) {
|
|
207
264
|
table[key] = col;
|
|
208
265
|
}
|
|
266
|
+
if (extras) {
|
|
267
|
+
const specs = extras(table) || [];
|
|
268
|
+
for (const s of specs) {
|
|
269
|
+
if (s.columns && s.unique !== void 0) {
|
|
270
|
+
table._indexes.push(s);
|
|
271
|
+
} else if (s.columns && s.foreignColumns) {
|
|
272
|
+
table._constraints.push(s);
|
|
273
|
+
} else if (s.columns && (s.name || s.name === void 0)) {
|
|
274
|
+
if (s.columns && s.name !== void 0 && s.columns.length > 0) {
|
|
275
|
+
const pk = s;
|
|
276
|
+
if (pk.columns.length > 1 || pk.name && pk.name.length > 0) {
|
|
277
|
+
table._constraints.push(s);
|
|
278
|
+
} else {
|
|
279
|
+
table._constraints.push(s);
|
|
280
|
+
}
|
|
281
|
+
} else {
|
|
282
|
+
table._constraints.push(s);
|
|
283
|
+
}
|
|
284
|
+
} else if (s.expr) {
|
|
285
|
+
table._constraints.push(s);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
209
289
|
return table;
|
|
210
290
|
}
|
|
211
291
|
|
|
@@ -213,6 +293,31 @@ function defineTable(tableName, schema) {
|
|
|
213
293
|
var import_plugin_sql = __toESM(require("@tauri-apps/plugin-sql"));
|
|
214
294
|
|
|
215
295
|
// src/sql-helpers.ts
|
|
296
|
+
function raw(strings, ...values) {
|
|
297
|
+
return {
|
|
298
|
+
toSQL: () => {
|
|
299
|
+
let clause = "";
|
|
300
|
+
const bindings = [];
|
|
301
|
+
for (let i = 0; i < strings.length; i++) {
|
|
302
|
+
clause += strings[i];
|
|
303
|
+
if (i < values.length) {
|
|
304
|
+
const v = values[i];
|
|
305
|
+
if (v && typeof v === "object" && typeof v.toSQL === "function") {
|
|
306
|
+
const s = v.toSQL();
|
|
307
|
+
clause += s.clause;
|
|
308
|
+
bindings.push(...s.bindings);
|
|
309
|
+
} else if (v && typeof v === "object" && "_dataType" in v) {
|
|
310
|
+
clause += getQualifiedName(v);
|
|
311
|
+
} else {
|
|
312
|
+
clause += "?";
|
|
313
|
+
bindings.push(v);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return { clause, bindings };
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
}
|
|
216
321
|
function isColumn(value) {
|
|
217
322
|
return typeof value === "object" && value !== null && "_dataType" in value;
|
|
218
323
|
}
|
|
@@ -238,6 +343,36 @@ function comparison(operator, column, value) {
|
|
|
238
343
|
}
|
|
239
344
|
};
|
|
240
345
|
}
|
|
346
|
+
var and = (...conditions) => ({
|
|
347
|
+
toSQL: () => {
|
|
348
|
+
const parts = [];
|
|
349
|
+
const bindings = [];
|
|
350
|
+
for (const c of conditions) {
|
|
351
|
+
const s = c.toSQL();
|
|
352
|
+
parts.push(`(${s.clause})`);
|
|
353
|
+
bindings.push(...s.bindings);
|
|
354
|
+
}
|
|
355
|
+
return { clause: parts.join(" AND "), bindings };
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
var or = (...conditions) => ({
|
|
359
|
+
toSQL: () => {
|
|
360
|
+
const parts = [];
|
|
361
|
+
const bindings = [];
|
|
362
|
+
for (const c of conditions) {
|
|
363
|
+
const s = c.toSQL();
|
|
364
|
+
parts.push(`(${s.clause})`);
|
|
365
|
+
bindings.push(...s.bindings);
|
|
366
|
+
}
|
|
367
|
+
return { clause: parts.join(" OR "), bindings };
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
var not = (condition) => ({
|
|
371
|
+
toSQL: () => {
|
|
372
|
+
const s = condition.toSQL();
|
|
373
|
+
return { clause: `NOT (${s.clause})`, bindings: s.bindings };
|
|
374
|
+
}
|
|
375
|
+
});
|
|
241
376
|
var eq = (column, value) => comparison("=", column, value);
|
|
242
377
|
var ne = (column, value) => comparison("!=", column, value);
|
|
243
378
|
var gt = (column, value) => comparison(">", column, value);
|
|
@@ -245,32 +380,154 @@ var gte = (column, value) => comparison(">=", column, value);
|
|
|
245
380
|
var lt = (column, value) => comparison("<", column, value);
|
|
246
381
|
var lte = (column, value) => comparison("<=", column, value);
|
|
247
382
|
var like = (column, value) => comparison("LIKE", column, value);
|
|
383
|
+
var ilike = (column, value) => ({
|
|
384
|
+
toSQL: () => {
|
|
385
|
+
const colExpr = `LOWER(${getQualifiedName(column)})`;
|
|
386
|
+
if (isColumn(value)) {
|
|
387
|
+
return {
|
|
388
|
+
clause: `${colExpr} LIKE LOWER(${getQualifiedName(value)})`,
|
|
389
|
+
bindings: []
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
return { clause: `${colExpr} LIKE LOWER(?)`, bindings: [value] };
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
var notIlike = (column, value) => ({
|
|
396
|
+
toSQL: () => {
|
|
397
|
+
const colExpr = `LOWER(${getQualifiedName(column)})`;
|
|
398
|
+
if (isColumn(value)) {
|
|
399
|
+
return {
|
|
400
|
+
clause: `${colExpr} NOT LIKE LOWER(${getQualifiedName(value)})`,
|
|
401
|
+
bindings: []
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
return { clause: `${colExpr} NOT LIKE LOWER(?)`, bindings: [value] };
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
var isNull = (column) => ({
|
|
408
|
+
toSQL: () => ({
|
|
409
|
+
clause: `${getQualifiedName(column)} IS NULL`,
|
|
410
|
+
bindings: []
|
|
411
|
+
})
|
|
412
|
+
});
|
|
413
|
+
var isNotNull = (column) => ({
|
|
414
|
+
toSQL: () => ({
|
|
415
|
+
clause: `${getQualifiedName(column)} IS NOT NULL`,
|
|
416
|
+
bindings: []
|
|
417
|
+
})
|
|
418
|
+
});
|
|
419
|
+
var between = (column, from, to) => ({
|
|
420
|
+
toSQL: () => {
|
|
421
|
+
const left = getQualifiedName(column);
|
|
422
|
+
const [fromClause, fromBindings] = isColumn(from) ? [getQualifiedName(from), []] : ["?", [from]];
|
|
423
|
+
const [toClause, toBindings] = isColumn(to) ? [getQualifiedName(to), []] : ["?", [to]];
|
|
424
|
+
return {
|
|
425
|
+
clause: `${left} BETWEEN ${fromClause} AND ${toClause}`,
|
|
426
|
+
bindings: [...fromBindings, ...toBindings]
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
var notBetween = (column, from, to) => ({
|
|
431
|
+
toSQL: () => {
|
|
432
|
+
const left = getQualifiedName(column);
|
|
433
|
+
const [fromClause, fromBindings] = isColumn(from) ? [getQualifiedName(from), []] : ["?", [from]];
|
|
434
|
+
const [toClause, toBindings] = isColumn(to) ? [getQualifiedName(to), []] : ["?", [to]];
|
|
435
|
+
return {
|
|
436
|
+
clause: `${left} NOT BETWEEN ${fromClause} AND ${toClause}`,
|
|
437
|
+
bindings: [...fromBindings, ...toBindings]
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
var inArray = (column, valuesOrQuery) => ({
|
|
442
|
+
toSQL: () => {
|
|
443
|
+
const left = getQualifiedName(column);
|
|
444
|
+
if (Array.isArray(valuesOrQuery)) {
|
|
445
|
+
const placeholders = valuesOrQuery.map(() => "?").join(", ");
|
|
446
|
+
return {
|
|
447
|
+
clause: `${left} IN (${placeholders})`,
|
|
448
|
+
bindings: valuesOrQuery
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
const sq = valuesOrQuery.toSQL ? valuesOrQuery.toSQL() : valuesOrQuery.toSQL();
|
|
452
|
+
return { clause: `${left} IN (${sq.clause})`, bindings: sq.bindings };
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
var notInArray = (column, valuesOrQuery) => ({
|
|
456
|
+
toSQL: () => {
|
|
457
|
+
const left = getQualifiedName(column);
|
|
458
|
+
if (Array.isArray(valuesOrQuery)) {
|
|
459
|
+
const placeholders = valuesOrQuery.map(() => "?").join(", ");
|
|
460
|
+
return {
|
|
461
|
+
clause: `${left} NOT IN (${placeholders})`,
|
|
462
|
+
bindings: valuesOrQuery
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
const sq = valuesOrQuery.toSQL ? valuesOrQuery.toSQL() : valuesOrQuery.toSQL();
|
|
466
|
+
return { clause: `${left} NOT IN (${sq.clause})`, bindings: sq.bindings };
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
var exists = (subquery) => ({
|
|
470
|
+
toSQL: () => {
|
|
471
|
+
const sq = subquery.toSQL ? subquery.toSQL() : subquery.toSQL();
|
|
472
|
+
return { clause: `EXISTS (${sq.clause})`, bindings: sq.bindings };
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
var notExists = (subquery) => ({
|
|
476
|
+
toSQL: () => {
|
|
477
|
+
const sq = subquery.toSQL ? subquery.toSQL() : subquery.toSQL();
|
|
478
|
+
return { clause: `NOT EXISTS (${sq.clause})`, bindings: sq.bindings };
|
|
479
|
+
}
|
|
480
|
+
});
|
|
248
481
|
var asc = (column) => `${getQualifiedName(column)} ASC`;
|
|
249
482
|
var desc = (column) => `${getQualifiedName(column)} DESC`;
|
|
250
483
|
|
|
251
484
|
// src/orm.ts
|
|
252
485
|
var SelectQueryBuilder = class {
|
|
253
486
|
_table = null;
|
|
254
|
-
_selectedColumns = [
|
|
487
|
+
_selectedColumns = [];
|
|
255
488
|
_joins = [];
|
|
256
489
|
_where = [];
|
|
257
490
|
_orderBy = [];
|
|
258
491
|
_limit = null;
|
|
259
492
|
_offset = null;
|
|
260
|
-
|
|
493
|
+
_groupBy = [];
|
|
494
|
+
_having = [];
|
|
495
|
+
_distinct = false;
|
|
261
496
|
_dbProvider;
|
|
262
497
|
constructor(dbProvider, fields) {
|
|
263
498
|
this._dbProvider = dbProvider;
|
|
264
499
|
if (fields) {
|
|
265
|
-
|
|
500
|
+
for (const [alias, col] of Object.entries(fields)) {
|
|
501
|
+
const sql2 = getQualifiedName(col);
|
|
502
|
+
this._selectedColumns.push({ sql: sql2, alias });
|
|
503
|
+
}
|
|
266
504
|
}
|
|
267
505
|
}
|
|
506
|
+
distinct() {
|
|
507
|
+
this._distinct = true;
|
|
508
|
+
return this;
|
|
509
|
+
}
|
|
510
|
+
select(fields) {
|
|
511
|
+
this._selectedColumns = [];
|
|
512
|
+
for (const [alias, expr] of Object.entries(fields)) {
|
|
513
|
+
if (typeof expr.toSQL === "function") {
|
|
514
|
+
const s = expr.toSQL();
|
|
515
|
+
this._selectedColumns.push({ sql: s.clause, alias });
|
|
516
|
+
} else {
|
|
517
|
+
this._selectedColumns.push({
|
|
518
|
+
sql: getQualifiedName(expr),
|
|
519
|
+
alias
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return this;
|
|
524
|
+
}
|
|
268
525
|
from(table) {
|
|
269
526
|
this._table = table;
|
|
270
527
|
return this;
|
|
271
528
|
}
|
|
272
529
|
where(...conditions) {
|
|
273
|
-
this._where.push(...conditions);
|
|
530
|
+
this._where.push(...conditions.filter(Boolean));
|
|
274
531
|
return this;
|
|
275
532
|
}
|
|
276
533
|
leftJoin(otherTable, on) {
|
|
@@ -279,8 +536,26 @@ var SelectQueryBuilder = class {
|
|
|
279
536
|
this._joins.push(joinClause);
|
|
280
537
|
return this;
|
|
281
538
|
}
|
|
539
|
+
groupBy(...exprs) {
|
|
540
|
+
for (const e of exprs) {
|
|
541
|
+
if (!e) continue;
|
|
542
|
+
if (typeof e === "string") this._groupBy.push(e);
|
|
543
|
+
else this._groupBy.push(getQualifiedName(e));
|
|
544
|
+
}
|
|
545
|
+
return this;
|
|
546
|
+
}
|
|
547
|
+
having(...conditions) {
|
|
548
|
+
this._having.push(...conditions);
|
|
549
|
+
return this;
|
|
550
|
+
}
|
|
282
551
|
orderBy(...clauses) {
|
|
283
|
-
|
|
552
|
+
for (const c of clauses) {
|
|
553
|
+
if (!c) continue;
|
|
554
|
+
if (typeof c === "string") this._orderBy.push(c);
|
|
555
|
+
else if (typeof c.toSQL === "function")
|
|
556
|
+
this._orderBy.push(c);
|
|
557
|
+
else this._orderBy.push(getQualifiedName(c));
|
|
558
|
+
}
|
|
284
559
|
return this;
|
|
285
560
|
}
|
|
286
561
|
limit(value) {
|
|
@@ -291,17 +566,15 @@ var SelectQueryBuilder = class {
|
|
|
291
566
|
this._offset = value;
|
|
292
567
|
return this;
|
|
293
568
|
}
|
|
294
|
-
// The final execution step
|
|
295
569
|
async execute() {
|
|
296
570
|
if (!this._table) {
|
|
297
571
|
throw new Error("Cannot execute select query without a 'from' table.");
|
|
298
572
|
}
|
|
299
573
|
const db = await this._dbProvider();
|
|
300
574
|
const bindings = [];
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
575
|
+
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(", ");
|
|
576
|
+
let query = `SELECT ${this._distinct ? "DISTINCT " : ""}${selectList} FROM ${this._table._tableName}`;
|
|
577
|
+
if (this._joins.length > 0) query += ` ${this._joins.join(" ")}`;
|
|
305
578
|
if (this._where.length > 0) {
|
|
306
579
|
const whereClauses = this._where.map((condition) => {
|
|
307
580
|
const sql2 = condition.toSQL();
|
|
@@ -310,22 +583,47 @@ var SelectQueryBuilder = class {
|
|
|
310
583
|
});
|
|
311
584
|
query += ` WHERE ${whereClauses.join(" AND ")}`;
|
|
312
585
|
}
|
|
586
|
+
if (this._groupBy.length > 0) {
|
|
587
|
+
query += ` GROUP BY ${this._groupBy.join(", ")}`;
|
|
588
|
+
}
|
|
589
|
+
if (this._having.length > 0) {
|
|
590
|
+
const havingClauses = this._having.map((h) => {
|
|
591
|
+
const sql2 = h.toSQL();
|
|
592
|
+
bindings.push(...sql2.bindings);
|
|
593
|
+
return `(${sql2.clause})`;
|
|
594
|
+
});
|
|
595
|
+
query += ` HAVING ${havingClauses.join(" AND ")}`;
|
|
596
|
+
}
|
|
313
597
|
if (this._orderBy.length > 0) {
|
|
314
|
-
|
|
598
|
+
const ordParts = [];
|
|
599
|
+
for (const ob of this._orderBy) {
|
|
600
|
+
if (typeof ob === "string") ordParts.push(ob);
|
|
601
|
+
else {
|
|
602
|
+
const s = ob.toSQL();
|
|
603
|
+
ordParts.push(s.clause);
|
|
604
|
+
bindings.push(...s.bindings);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
315
608
|
}
|
|
316
609
|
if (this._limit !== null) {
|
|
317
610
|
query += ` LIMIT ?`;
|
|
318
611
|
bindings.push(this._limit);
|
|
319
612
|
}
|
|
320
613
|
if (this._offset !== null) {
|
|
321
|
-
if (this._limit === null)
|
|
322
|
-
query += ` LIMIT -1`;
|
|
323
|
-
}
|
|
614
|
+
if (this._limit === null) query += ` LIMIT -1`;
|
|
324
615
|
query += ` OFFSET ?`;
|
|
325
616
|
bindings.push(this._offset);
|
|
326
617
|
}
|
|
327
618
|
return db.select(query, bindings);
|
|
328
619
|
}
|
|
620
|
+
async iterator() {
|
|
621
|
+
const rows = await this.execute();
|
|
622
|
+
async function* gen() {
|
|
623
|
+
for (const r of rows) yield r;
|
|
624
|
+
}
|
|
625
|
+
return gen();
|
|
626
|
+
}
|
|
329
627
|
};
|
|
330
628
|
var TauriORM = class {
|
|
331
629
|
// Soft relational query API: db.query.users.findMany({ with: { posts: true } })
|
|
@@ -346,18 +644,67 @@ var TauriORM = class {
|
|
|
346
644
|
select(fields) {
|
|
347
645
|
return new SelectQueryBuilder(this.getDb.bind(this), fields);
|
|
348
646
|
}
|
|
647
|
+
selectDistinct(fields) {
|
|
648
|
+
const qb = new SelectQueryBuilder(this.getDb.bind(this), fields);
|
|
649
|
+
qb.distinct();
|
|
650
|
+
return qb;
|
|
651
|
+
}
|
|
349
652
|
// --- Drizzle-style CRUD builders ---
|
|
350
653
|
insert(table) {
|
|
351
654
|
const self = this;
|
|
352
655
|
return new class InsertBuilder {
|
|
353
656
|
_table = table;
|
|
354
657
|
_rows = [];
|
|
658
|
+
_selectSql = null;
|
|
659
|
+
_conflict = null;
|
|
660
|
+
_returning = null;
|
|
355
661
|
values(rowOrRows) {
|
|
356
662
|
this._rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
|
|
357
663
|
return this;
|
|
358
664
|
}
|
|
665
|
+
select(qb) {
|
|
666
|
+
if (qb.toSQL) this._selectSql = qb.toSQL();
|
|
667
|
+
else this._selectSql = qb.toSQL();
|
|
668
|
+
return this;
|
|
669
|
+
}
|
|
670
|
+
returning(fields) {
|
|
671
|
+
this._returning = fields ?? {};
|
|
672
|
+
return this;
|
|
673
|
+
}
|
|
674
|
+
$returningId() {
|
|
675
|
+
this._returning = "__RETURNING_ID__";
|
|
676
|
+
return this;
|
|
677
|
+
}
|
|
678
|
+
onConflictDoNothing(opts) {
|
|
679
|
+
const target = opts?.target ? Array.isArray(opts.target) ? opts.target.map((c) => c.name) : opts.target.name : void 0;
|
|
680
|
+
this._conflict = {
|
|
681
|
+
kind: "doNothing",
|
|
682
|
+
target,
|
|
683
|
+
where: opts?.where
|
|
684
|
+
};
|
|
685
|
+
return this;
|
|
686
|
+
}
|
|
687
|
+
onConflictDoUpdate(opts) {
|
|
688
|
+
const target = Array.isArray(opts.target) ? opts.target.map((c) => c.name) : opts.target.name;
|
|
689
|
+
this._conflict = {
|
|
690
|
+
kind: "doUpdate",
|
|
691
|
+
target,
|
|
692
|
+
targetWhere: opts.targetWhere,
|
|
693
|
+
set: opts.set,
|
|
694
|
+
setWhere: opts.setWhere
|
|
695
|
+
};
|
|
696
|
+
return this;
|
|
697
|
+
}
|
|
359
698
|
async execute() {
|
|
360
699
|
const db = await self.getDb();
|
|
700
|
+
if (this._selectSql) {
|
|
701
|
+
const cols = Object.keys(this._table._schema);
|
|
702
|
+
let query = `INSERT INTO ${this._table._tableName} (${cols.join(", ")}) ${this._selectSql.clause}`;
|
|
703
|
+
const bindings = [...this._selectSql.bindings];
|
|
704
|
+
query += this._buildConflictClause();
|
|
705
|
+
const ret = await this._executeWithReturning(db, query, bindings);
|
|
706
|
+
return ret;
|
|
707
|
+
}
|
|
361
708
|
for (const data of this._rows) {
|
|
362
709
|
const finalData = { ...data };
|
|
363
710
|
const schema = this._table._schema;
|
|
@@ -373,11 +720,51 @@ var TauriORM = class {
|
|
|
373
720
|
const keys = Object.keys(finalData);
|
|
374
721
|
const values = Object.values(finalData);
|
|
375
722
|
const placeholders = values.map(() => "?").join(", ");
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
await
|
|
723
|
+
let query = `INSERT INTO ${this._table._tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
|
|
724
|
+
const bindings = [...values];
|
|
725
|
+
query += this._buildConflictClause();
|
|
726
|
+
const ret = await this._executeWithReturning(db, query, bindings);
|
|
727
|
+
if (ret !== void 0) return ret;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
_buildConflictClause() {
|
|
731
|
+
if (!this._conflict) return "";
|
|
732
|
+
if (this._conflict.kind === "doNothing") {
|
|
733
|
+
const tgt2 = this._conflict.target ? Array.isArray(this._conflict.target) ? `(${this._conflict.target.join(", ")})` : `(${this._conflict.target})` : "";
|
|
734
|
+
const where = this._conflict.where ? ` WHERE ${this._conflict.where.toSQL().clause}` : "";
|
|
735
|
+
return ` ON CONFLICT ${tgt2} DO NOTHING${where}`;
|
|
736
|
+
}
|
|
737
|
+
const c = this._conflict;
|
|
738
|
+
const tgt = Array.isArray(c.target) ? `(${c.target.join(", ")})` : `(${c.target})`;
|
|
739
|
+
const setKeys = Object.keys(c.set ?? {});
|
|
740
|
+
const setClause = setKeys.map((k) => {
|
|
741
|
+
const v = c.set[k];
|
|
742
|
+
return `${k} = ${typeof v === "object" && v && typeof v.toSQL === "function" ? v.toSQL().clause : "?"}`;
|
|
743
|
+
}).join(", ");
|
|
744
|
+
const targetWhere = c.targetWhere ? ` WHERE ${c.targetWhere.toSQL().clause}` : "";
|
|
745
|
+
const setWhere = c.setWhere ? ` WHERE ${c.setWhere.toSQL().clause}` : "";
|
|
746
|
+
return ` ON CONFLICT ${tgt}${targetWhere} DO UPDATE SET ${setClause}${setWhere}`;
|
|
747
|
+
}
|
|
748
|
+
async _executeWithReturning(db, query, bindings) {
|
|
749
|
+
if (this._returning === null) {
|
|
750
|
+
await db.execute(query, bindings);
|
|
751
|
+
return void 0;
|
|
380
752
|
}
|
|
753
|
+
if (this._returning === "__RETURNING_ID__") {
|
|
754
|
+
const rows = await db.select(`SELECT last_insert_rowid() as id`);
|
|
755
|
+
return rows.map((r) => ({ id: r.id }));
|
|
756
|
+
}
|
|
757
|
+
if (typeof this._returning === "object") {
|
|
758
|
+
const cols = Object.entries(
|
|
759
|
+
this._returning
|
|
760
|
+
).map(
|
|
761
|
+
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
762
|
+
).join(", ");
|
|
763
|
+
const retSql = `${query} RETURNING ${cols}`;
|
|
764
|
+
const res = await db.select(retSql, bindings);
|
|
765
|
+
return res;
|
|
766
|
+
}
|
|
767
|
+
return void 0;
|
|
381
768
|
}
|
|
382
769
|
}();
|
|
383
770
|
}
|
|
@@ -387,6 +774,10 @@ var TauriORM = class {
|
|
|
387
774
|
_table = table;
|
|
388
775
|
_data = null;
|
|
389
776
|
_where = null;
|
|
777
|
+
_orderBy = [];
|
|
778
|
+
_limit = null;
|
|
779
|
+
_from = null;
|
|
780
|
+
_returning = null;
|
|
390
781
|
set(data) {
|
|
391
782
|
this._data = data;
|
|
392
783
|
return this;
|
|
@@ -395,6 +786,28 @@ var TauriORM = class {
|
|
|
395
786
|
this._where = cond;
|
|
396
787
|
return this;
|
|
397
788
|
}
|
|
789
|
+
orderBy(...clauses) {
|
|
790
|
+
for (const c of clauses) {
|
|
791
|
+
if (!c) continue;
|
|
792
|
+
if (typeof c === "string") this._orderBy.push(c);
|
|
793
|
+
else if (typeof c.toSQL === "function")
|
|
794
|
+
this._orderBy.push(c);
|
|
795
|
+
else this._orderBy.push(getQualifiedName(c));
|
|
796
|
+
}
|
|
797
|
+
return this;
|
|
798
|
+
}
|
|
799
|
+
limit(n) {
|
|
800
|
+
this._limit = n;
|
|
801
|
+
return this;
|
|
802
|
+
}
|
|
803
|
+
from(tbl) {
|
|
804
|
+
this._from = tbl;
|
|
805
|
+
return this;
|
|
806
|
+
}
|
|
807
|
+
returning(fields) {
|
|
808
|
+
this._returning = fields ?? {};
|
|
809
|
+
return this;
|
|
810
|
+
}
|
|
398
811
|
async execute() {
|
|
399
812
|
if (!this._data)
|
|
400
813
|
throw new Error("Update requires set() before execute()");
|
|
@@ -406,10 +819,21 @@ var TauriORM = class {
|
|
|
406
819
|
dataToSet[key] = col.onUpdateFn();
|
|
407
820
|
}
|
|
408
821
|
}
|
|
409
|
-
const
|
|
410
|
-
const
|
|
411
|
-
const
|
|
412
|
-
|
|
822
|
+
const setParts = [];
|
|
823
|
+
const bindings = [];
|
|
824
|
+
for (const [k, v] of Object.entries(dataToSet)) {
|
|
825
|
+
if (v === void 0) continue;
|
|
826
|
+
if (v && typeof v === "object" && typeof v.toSQL === "function") {
|
|
827
|
+
const s = v.toSQL();
|
|
828
|
+
setParts.push(`${k} = ${s.clause}`);
|
|
829
|
+
bindings.push(...s.bindings);
|
|
830
|
+
} else {
|
|
831
|
+
setParts.push(`${k} = ?`);
|
|
832
|
+
bindings.push(v);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
let query = `UPDATE ${this._table._tableName} SET ${setParts.join(", ")}`;
|
|
836
|
+
if (this._from) query += ` FROM ${this._from._tableName}`;
|
|
413
837
|
if (this._where) {
|
|
414
838
|
if (typeof this._where.toSQL === "function") {
|
|
415
839
|
const sql2 = this._where.toSQL();
|
|
@@ -423,6 +847,31 @@ var TauriORM = class {
|
|
|
423
847
|
}
|
|
424
848
|
}
|
|
425
849
|
}
|
|
850
|
+
if (this._orderBy.length > 0) {
|
|
851
|
+
const ordParts = [];
|
|
852
|
+
for (const ob of this._orderBy) {
|
|
853
|
+
if (typeof ob === "string") ordParts.push(ob);
|
|
854
|
+
else {
|
|
855
|
+
const s = ob.toSQL();
|
|
856
|
+
ordParts.push(s.clause);
|
|
857
|
+
bindings.push(...s.bindings);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
861
|
+
}
|
|
862
|
+
if (this._limit !== null) {
|
|
863
|
+
query += ` LIMIT ?`;
|
|
864
|
+
bindings.push(this._limit);
|
|
865
|
+
}
|
|
866
|
+
if (this._returning) {
|
|
867
|
+
const cols = Object.entries(
|
|
868
|
+
this._returning
|
|
869
|
+
).map(
|
|
870
|
+
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
871
|
+
).join(", ");
|
|
872
|
+
const retSql = `${query} RETURNING ${cols}`;
|
|
873
|
+
return await db.select(retSql, bindings);
|
|
874
|
+
}
|
|
426
875
|
await db.execute(query, bindings);
|
|
427
876
|
}
|
|
428
877
|
}();
|
|
@@ -432,10 +881,31 @@ var TauriORM = class {
|
|
|
432
881
|
return new class DeleteBuilder {
|
|
433
882
|
_table = table;
|
|
434
883
|
_where = null;
|
|
884
|
+
_orderBy = [];
|
|
885
|
+
_limit = null;
|
|
886
|
+
_returning = null;
|
|
435
887
|
where(cond) {
|
|
436
888
|
this._where = cond;
|
|
437
889
|
return this;
|
|
438
890
|
}
|
|
891
|
+
orderBy(...clauses) {
|
|
892
|
+
for (const c of clauses) {
|
|
893
|
+
if (!c) continue;
|
|
894
|
+
if (typeof c === "string") this._orderBy.push(c);
|
|
895
|
+
else if (typeof c.toSQL === "function")
|
|
896
|
+
this._orderBy.push(c);
|
|
897
|
+
else this._orderBy.push(getQualifiedName(c));
|
|
898
|
+
}
|
|
899
|
+
return this;
|
|
900
|
+
}
|
|
901
|
+
limit(n) {
|
|
902
|
+
this._limit = n;
|
|
903
|
+
return this;
|
|
904
|
+
}
|
|
905
|
+
returning(fields) {
|
|
906
|
+
this._returning = fields ?? {};
|
|
907
|
+
return this;
|
|
908
|
+
}
|
|
439
909
|
async execute() {
|
|
440
910
|
const db = await self.getDb();
|
|
441
911
|
let query = `DELETE FROM ${this._table._tableName}`;
|
|
@@ -453,6 +923,31 @@ var TauriORM = class {
|
|
|
453
923
|
}
|
|
454
924
|
}
|
|
455
925
|
}
|
|
926
|
+
if (this._orderBy.length > 0) {
|
|
927
|
+
const ordParts = [];
|
|
928
|
+
for (const ob of this._orderBy) {
|
|
929
|
+
if (typeof ob === "string") ordParts.push(ob);
|
|
930
|
+
else {
|
|
931
|
+
const s = ob.toSQL();
|
|
932
|
+
ordParts.push(s.clause);
|
|
933
|
+
bindings.push(...s.bindings);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
937
|
+
}
|
|
938
|
+
if (this._limit !== null) {
|
|
939
|
+
query += ` LIMIT ?`;
|
|
940
|
+
bindings.push(this._limit);
|
|
941
|
+
}
|
|
942
|
+
if (this._returning) {
|
|
943
|
+
const cols = Object.entries(
|
|
944
|
+
this._returning
|
|
945
|
+
).map(
|
|
946
|
+
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
947
|
+
).join(", ");
|
|
948
|
+
const retSql = `${query} RETURNING ${cols}`;
|
|
949
|
+
return await db.select(retSql, bindings);
|
|
950
|
+
}
|
|
456
951
|
await db.execute(query, bindings);
|
|
457
952
|
}
|
|
458
953
|
}();
|
|
@@ -731,8 +1226,8 @@ var TauriORM = class {
|
|
|
731
1226
|
const preserve = options?.preserveData !== false;
|
|
732
1227
|
for (const tbl of Object.values(this._tables)) {
|
|
733
1228
|
const tableName = tbl._tableName;
|
|
734
|
-
const
|
|
735
|
-
if (!
|
|
1229
|
+
const exists2 = await this.tableExists(tableName);
|
|
1230
|
+
if (!exists2) {
|
|
736
1231
|
await this.run(this.buildCreateTableSQL(tbl));
|
|
737
1232
|
continue;
|
|
738
1233
|
}
|
|
@@ -969,10 +1464,10 @@ function makeQueryAPI(tables, relDefs, dbProvider) {
|
|
|
969
1464
|
const childPk = fkMap[relName].childPk;
|
|
970
1465
|
if (childPk) {
|
|
971
1466
|
if (!acc[relName]) acc[relName] = [];
|
|
972
|
-
const
|
|
1467
|
+
const exists2 = acc[relName].some(
|
|
973
1468
|
(r) => r[childPk.name] === childObj[childPk.name]
|
|
974
1469
|
);
|
|
975
|
-
if (!
|
|
1470
|
+
if (!exists2) acc[relName].push(childObj);
|
|
976
1471
|
} else {
|
|
977
1472
|
acc[relName].push(childObj);
|
|
978
1473
|
}
|
|
@@ -1102,25 +1597,46 @@ function makeQueryAPI(tables, relDefs, dbProvider) {
|
|
|
1102
1597
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1103
1598
|
0 && (module.exports = {
|
|
1104
1599
|
TauriORM,
|
|
1600
|
+
and,
|
|
1105
1601
|
asc,
|
|
1602
|
+
between,
|
|
1106
1603
|
blob,
|
|
1107
1604
|
boolean,
|
|
1605
|
+
check,
|
|
1108
1606
|
defineTable,
|
|
1109
1607
|
desc,
|
|
1110
1608
|
eq,
|
|
1609
|
+
exists,
|
|
1610
|
+
foreignKey,
|
|
1611
|
+
getQualifiedName,
|
|
1111
1612
|
gt,
|
|
1112
1613
|
gte,
|
|
1614
|
+
ilike,
|
|
1615
|
+
inArray,
|
|
1113
1616
|
increments,
|
|
1617
|
+
index,
|
|
1114
1618
|
integer,
|
|
1619
|
+
isNotNull,
|
|
1620
|
+
isNull,
|
|
1115
1621
|
like,
|
|
1116
1622
|
lt,
|
|
1117
1623
|
lte,
|
|
1118
1624
|
makeQueryAPI,
|
|
1119
1625
|
ne,
|
|
1626
|
+
not,
|
|
1627
|
+
notBetween,
|
|
1628
|
+
notExists,
|
|
1629
|
+
notIlike,
|
|
1630
|
+
notInArray,
|
|
1120
1631
|
numeric,
|
|
1632
|
+
or,
|
|
1633
|
+
primaryKey,
|
|
1634
|
+
raw,
|
|
1121
1635
|
real,
|
|
1122
1636
|
relations,
|
|
1123
1637
|
sql,
|
|
1124
1638
|
text,
|
|
1125
|
-
timestamp
|
|
1639
|
+
timestamp,
|
|
1640
|
+
unique,
|
|
1641
|
+
uniqueIndex
|
|
1126
1642
|
});
|