@type32/tauri-sqlite-orm 0.1.16 → 0.1.18-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,1345 +1,404 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
10
8
  __defProp(target, name, { get: all[name], enumerable: true });
11
9
  };
12
- var __copyProps = (to, from, except, desc2) => {
10
+ var __copyProps = (to, from, except, desc) => {
13
11
  if (from && typeof from === "object" || typeof from === "function") {
14
12
  for (let key of __getOwnPropNames(from))
15
13
  if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
31
21
  var index_exports = {};
32
22
  __export(index_exports, {
23
+ DeleteQueryBuilder: () => DeleteQueryBuilder,
24
+ InsertQueryBuilder: () => InsertQueryBuilder,
25
+ SQLiteColumn: () => SQLiteColumn,
26
+ SelectQueryBuilder: () => SelectQueryBuilder,
27
+ Table: () => Table,
33
28
  TauriORM: () => TauriORM,
29
+ UpdateQueryBuilder: () => UpdateQueryBuilder,
34
30
  and: () => and,
35
- asc: () => asc,
36
- between: () => between,
37
31
  blob: () => blob,
38
32
  boolean: () => boolean,
39
- check: () => check,
40
- defineTable: () => defineTable,
41
- desc: () => desc,
42
33
  eq: () => eq,
43
- exists: () => exists,
44
- foreignKey: () => foreignKey,
45
- getQualifiedName: () => getQualifiedName,
46
34
  gt: () => gt,
47
35
  gte: () => gte,
48
- ilike: () => ilike,
49
36
  inArray: () => inArray,
50
- increments: () => increments,
51
- index: () => index,
52
37
  integer: () => integer,
53
38
  isNotNull: () => isNotNull,
54
39
  isNull: () => isNull,
55
40
  like: () => like,
56
41
  lt: () => lt,
57
42
  lte: () => lte,
58
- makeQueryAPI: () => makeQueryAPI,
59
- ne: () => ne,
60
- not: () => not,
61
- notBetween: () => notBetween,
62
- notExists: () => notExists,
63
- notIlike: () => notIlike,
64
- notInArray: () => notInArray,
65
- numeric: () => numeric,
66
43
  or: () => or,
67
- primaryKey: () => primaryKey,
68
- raw: () => raw,
69
44
  real: () => real,
70
45
  relations: () => relations,
71
- sql: () => sql,
72
- text: () => text,
73
- timestamp: () => timestamp,
74
- unique: () => unique,
75
- uniqueIndex: () => uniqueIndex
46
+ sqliteTable: () => sqliteTable,
47
+ text: () => text
76
48
  });
77
49
  module.exports = __toCommonJS(index_exports);
78
50
 
79
- // src/schema-builder.ts
80
- function sql(strings, ...values) {
81
- const raw2 = strings.reduce(
82
- (acc, part, idx) => acc + part + (idx < values.length ? String(values[idx]) : ""),
83
- ""
84
- );
85
- return { raw: raw2 };
86
- }
87
- function createColumn(params) {
88
- const col = { ...params };
89
- col.primaryKey = (opts) => {
90
- col.isPrimaryKey = true;
91
- if (opts?.autoIncrement) col.autoIncrement = true;
92
- return col;
93
- };
94
- col.notNull = () => {
95
- col.isNotNull = true;
96
- return col;
97
- };
98
- col.default = (value) => {
99
- col.defaultValue = value;
100
- return col;
101
- };
102
- col.$type = () => col;
103
- col.$defaultFn = (fn) => {
104
- col.defaultFn = fn;
105
- return col;
106
- };
107
- col.$default = (fn) => {
108
- col.defaultFn = fn;
109
- return col;
110
- };
111
- col.$onUpdate = (fn) => {
112
- col.onUpdateFn = fn;
113
- return col;
114
- };
115
- col.$onUpdateFn = (fn) => {
116
- col.onUpdateFn = fn;
117
- return col;
118
- };
119
- col.references = (target, actions) => {
120
- const t = target();
121
- col.references = {
122
- table: t.tableName,
123
- column: t.name,
124
- onDelete: actions?.onDelete,
125
- onUpdate: actions?.onUpdate
126
- };
127
- return col;
128
- };
129
- return col;
130
- }
131
- function text(nameOrConfig, maybeConfig) {
132
- const name = typeof nameOrConfig === "string" ? nameOrConfig : "";
133
- const config = typeof nameOrConfig === "string" ? maybeConfig : nameOrConfig;
134
- const col = createColumn({
135
- name,
136
- type: "TEXT",
137
- _dataType: ""
138
- });
139
- if (config?.enum) col.enumValues = config.enum;
140
- if (config?.mode) col.mode = config.mode;
141
- return col;
142
- }
143
- function integer(nameOrConfig, maybeConfig) {
144
- const name = typeof nameOrConfig === "string" ? nameOrConfig : "";
145
- const config = typeof nameOrConfig === "string" ? maybeConfig : nameOrConfig;
146
- let dt = 0;
147
- if (config?.mode === "boolean") dt = false;
148
- if (config?.mode === "timestamp" || config?.mode === "timestamp_ms")
149
- dt = /* @__PURE__ */ new Date();
150
- const col = createColumn({
151
- name,
152
- type: "INTEGER",
153
- mode: config?.mode ?? "number",
154
- _dataType: dt
155
- });
156
- return col;
157
- }
158
- function real(name) {
159
- return createColumn({
160
- name: name ?? "",
161
- type: "REAL",
162
- _dataType: 0
163
- });
164
- }
165
- function blob(nameOrConfig, maybeConfig) {
166
- const name = typeof nameOrConfig === "string" ? nameOrConfig : "";
167
- const config = typeof nameOrConfig === "string" ? maybeConfig : nameOrConfig;
168
- let dt = new Uint8Array();
169
- if (config?.mode === "bigint") dt = 0n;
170
- if (config?.mode === "json") dt = void 0;
171
- return createColumn({
172
- name,
173
- type: "BLOB",
174
- mode: config?.mode,
175
- _dataType: dt
176
- });
177
- }
178
- function numeric(nameOrConfig, maybeConfig) {
179
- const name = typeof nameOrConfig === "string" ? nameOrConfig : "";
180
- const config = typeof nameOrConfig === "string" ? maybeConfig : nameOrConfig;
181
- let dt = "";
182
- if (config?.mode === "number") dt = 0;
183
- if (config?.mode === "bigint") dt = 0n;
184
- return createColumn({
185
- name,
186
- type: "NUMERIC",
187
- mode: config?.mode,
188
- _dataType: dt
189
- });
190
- }
191
- function boolean(name) {
192
- return createColumn({
193
- name: name ?? "",
194
- type: "INTEGER",
195
- _dataType: false,
196
- mode: "boolean"
197
- });
198
- }
199
- function timestamp(name) {
200
- return createColumn({
201
- name: name ?? "",
202
- type: "INTEGER",
203
- _dataType: /* @__PURE__ */ new Date(),
204
- mode: "timestamp"
205
- });
206
- }
207
- function increments(name) {
208
- return integer(name ?? "").primaryKey({
209
- autoIncrement: true
210
- });
211
- }
212
- function unique(name) {
213
- return {
214
- on: (...cols) => ({
215
- name,
216
- columns: cols.map((c) => c.name),
217
- // runtime marker for DDL rendering
218
- kind: "unique"
219
- })
220
- };
221
- }
222
- function primaryKey(opts) {
223
- return {
224
- name: opts.name,
225
- columns: opts.columns.map((c) => c.name),
226
- // runtime marker for DDL rendering
227
- kind: "primaryKey"
228
- };
229
- }
230
- function check(name, expr) {
231
- return { name, expr };
232
- }
233
- function foreignKey(opts) {
234
- const first = opts.columns[0];
235
- return {
236
- name: opts.name,
237
- columns: opts.columns.map((c) => c.name),
238
- foreignTable: first?.tableName || opts.foreignColumns[0]?.tableName || "",
239
- foreignColumns: opts.foreignColumns.map((c) => c.name),
240
- onDelete: opts.onDelete,
241
- onUpdate: opts.onUpdate
242
- };
243
- }
244
- function index(name) {
245
- return {
246
- on: (...cols) => ({
247
- name,
248
- columns: cols.map((c) => c.name)
249
- }),
250
- where: (expr) => ({ name, columns: [], where: expr })
251
- };
252
- }
253
- function uniqueIndex(name) {
254
- return {
255
- on: (...cols) => ({
256
- name,
257
- columns: cols.map((c) => c.name),
258
- unique: true
259
- }),
260
- where: (expr) => ({
51
+ // src/orm.ts
52
+ var SQLiteColumn = class _SQLiteColumn {
53
+ constructor(name, type, options = {}, mode) {
54
+ this.type = type;
55
+ this.options = options;
56
+ this._ = {
261
57
  name,
262
- columns: [],
263
- unique: true,
264
- where: expr
265
- })
266
- };
267
- }
268
- function defineTable(tableName, schema, extras) {
269
- const finalizedSchema = { ...schema };
270
- for (const key of Object.keys(finalizedSchema)) {
271
- const col = finalizedSchema[key];
272
- if (!col.name || col.name === "") col.name = key;
273
- col.tableName = tableName;
58
+ dataType: type,
59
+ mode: mode || "default",
60
+ notNull: options.notNull ?? false,
61
+ hasDefault: options.default !== void 0 || options.$defaultFn !== void 0,
62
+ autoincrement: options.autoincrement ?? false
63
+ };
274
64
  }
275
- const table = {
276
- tableName,
277
- _schema: finalizedSchema,
278
- _constraints: [],
279
- _indexes: [],
280
- // The Drizzle-like type inference properties
281
- $inferSelect: {},
282
- $inferInsert: {}
283
- // omit PK columns
284
- };
285
- for (const [key, col] of Object.entries(finalizedSchema)) {
286
- table[key] = col;
65
+ _;
66
+ notNull() {
67
+ return new _SQLiteColumn(
68
+ this._.name,
69
+ this.type,
70
+ { ...this.options, notNull: true },
71
+ this._.mode
72
+ );
287
73
  }
288
- if (extras) {
289
- const specs = extras(table) || [];
290
- for (const s of specs) {
291
- if (s.columns && s.unique !== void 0) {
292
- table._indexes.push(s);
293
- } else if (s.columns && s.foreignColumns) {
294
- table._constraints.push(s);
295
- } else if (s.columns && (s.name || s.name === void 0)) {
296
- if (s.columns && s.name !== void 0 && s.columns.length > 0) {
297
- const pk = s;
298
- if (pk.columns.length > 1 || pk.name && pk.name.length > 0) {
299
- table._constraints.push(s);
300
- } else {
301
- table._constraints.push(s);
302
- }
303
- } else {
304
- table._constraints.push(s);
305
- }
306
- } else if (s.expr) {
307
- table._constraints.push(s);
308
- }
309
- }
74
+ default(value) {
75
+ return new _SQLiteColumn(
76
+ this._.name,
77
+ this.type,
78
+ { ...this.options, default: value },
79
+ this._.mode
80
+ );
310
81
  }
311
- return table;
312
- }
313
-
314
- // src/orm.ts
315
- var import_plugin_sql = __toESM(require("@tauri-apps/plugin-sql"));
316
-
317
- // src/sql-helpers.ts
318
- function raw(strings, ...values) {
319
- return {
320
- toSQL: () => {
321
- let clause = "";
322
- const bindings = [];
323
- for (let i = 0; i < strings.length; i++) {
324
- clause += strings[i];
325
- if (i < values.length) {
326
- const v = values[i];
327
- if (v && typeof v === "object" && typeof v.toSQL === "function") {
328
- const s = v.toSQL();
329
- clause += s.clause;
330
- bindings.push(...s.bindings);
331
- } else if (v && typeof v === "object" && "_dataType" in v) {
332
- clause += getQualifiedName(v);
333
- } else {
334
- clause += "?";
335
- bindings.push(v);
336
- }
82
+ $defaultFn(fn) {
83
+ return new _SQLiteColumn(
84
+ this._.name,
85
+ this.type,
86
+ { ...this.options, $defaultFn: fn },
87
+ this._.mode
88
+ );
89
+ }
90
+ primaryKey() {
91
+ return new _SQLiteColumn(
92
+ this._.name,
93
+ this.type,
94
+ { ...this.options, primaryKey: true },
95
+ this._.mode
96
+ );
97
+ }
98
+ autoincrement() {
99
+ return new _SQLiteColumn(
100
+ this._.name,
101
+ this.type,
102
+ { ...this.options, autoincrement: true },
103
+ this._.mode
104
+ );
105
+ }
106
+ unique() {
107
+ return new _SQLiteColumn(
108
+ this._.name,
109
+ this.type,
110
+ { ...this.options, unique: true },
111
+ this._.mode
112
+ );
113
+ }
114
+ references(ref, column) {
115
+ return new _SQLiteColumn(
116
+ this._.name,
117
+ this.type,
118
+ {
119
+ ...this.options,
120
+ references: {
121
+ table: ref,
122
+ column: ref._.columns[column]
337
123
  }
338
- }
339
- return { clause, bindings };
340
- }
341
- };
342
- }
343
- function isColumn(value) {
344
- return typeof value === "object" && value !== null && "_dataType" in value;
345
- }
346
- function getQualifiedName(column) {
347
- if (column.tableName) return `${column.tableName}.${column.name}`;
348
- return column.name;
349
- }
350
- function comparison(operator, column, value) {
351
- return {
352
- toSQL: () => {
353
- if (isColumn(value)) {
354
- return {
355
- clause: `${getQualifiedName(column)} ${operator} ${getQualifiedName(
356
- value
357
- )}`,
358
- bindings: []
359
- };
360
- }
361
- return {
362
- clause: `${getQualifiedName(column)} ${operator} ?`,
363
- bindings: [value]
364
- };
365
- }
366
- };
367
- }
368
- var and = (...conditions) => ({
369
- toSQL: () => {
370
- const parts = [];
371
- const bindings = [];
372
- for (const c of conditions) {
373
- const s = c.toSQL();
374
- parts.push(`(${s.clause})`);
375
- bindings.push(...s.bindings);
376
- }
377
- return { clause: parts.join(" AND "), bindings };
124
+ },
125
+ this._.mode
126
+ );
378
127
  }
379
- });
380
- var or = (...conditions) => ({
381
- toSQL: () => {
382
- const parts = [];
383
- const bindings = [];
384
- for (const c of conditions) {
385
- const s = c.toSQL();
386
- parts.push(`(${s.clause})`);
387
- bindings.push(...s.bindings);
388
- }
389
- return { clause: parts.join(" OR "), bindings };
128
+ $onUpdateFn(fn) {
129
+ return new _SQLiteColumn(
130
+ this._.name,
131
+ this.type,
132
+ { ...this.options, $onUpdateFn: fn },
133
+ this._.mode
134
+ );
390
135
  }
391
- });
392
- var not = (condition) => ({
393
- toSQL: () => {
394
- const s = condition.toSQL();
395
- return { clause: `NOT (${s.clause})`, bindings: s.bindings };
136
+ };
137
+ var text = (name) => new SQLiteColumn(name, "TEXT");
138
+ var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
139
+ var real = (name) => new SQLiteColumn(name, "REAL");
140
+ var blob = (name) => new SQLiteColumn(name, "BLOB");
141
+ var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
142
+ var Table = class {
143
+ _;
144
+ constructor(name, columns) {
145
+ this._ = {
146
+ name,
147
+ columns
148
+ };
396
149
  }
150
+ };
151
+ var sqliteTable = (tableName, columns) => {
152
+ return new Table(tableName, columns);
153
+ };
154
+ var eq = (column, value) => ({
155
+ sql: `${column._.name} = ?`,
156
+ params: [value]
397
157
  });
398
- var eq = (column, value) => comparison("=", column, value);
399
- var ne = (column, value) => comparison("!=", column, value);
400
- var gt = (column, value) => comparison(">", column, value);
401
- var gte = (column, value) => comparison(">=", column, value);
402
- var lt = (column, value) => comparison("<", column, value);
403
- var lte = (column, value) => comparison("<=", column, value);
404
- var like = (column, value) => comparison("LIKE", column, value);
405
- var ilike = (column, value) => ({
406
- toSQL: () => {
407
- const colExpr = `LOWER(${getQualifiedName(column)})`;
408
- if (isColumn(value)) {
409
- return {
410
- clause: `${colExpr} LIKE LOWER(${getQualifiedName(value)})`,
411
- bindings: []
412
- };
413
- }
414
- return { clause: `${colExpr} LIKE LOWER(?)`, bindings: [value] };
415
- }
158
+ var and = (...conditions) => ({
159
+ sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
160
+ params: conditions.flatMap((c) => c.params)
416
161
  });
417
- var notIlike = (column, value) => ({
418
- toSQL: () => {
419
- const colExpr = `LOWER(${getQualifiedName(column)})`;
420
- if (isColumn(value)) {
421
- return {
422
- clause: `${colExpr} NOT LIKE LOWER(${getQualifiedName(value)})`,
423
- bindings: []
424
- };
425
- }
426
- return { clause: `${colExpr} NOT LIKE LOWER(?)`, bindings: [value] };
427
- }
162
+ var or = (...conditions) => ({
163
+ sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
164
+ params: conditions.flatMap((c) => c.params)
428
165
  });
429
- var isNull = (column) => ({
430
- toSQL: () => ({
431
- clause: `${getQualifiedName(column)} IS NULL`,
432
- bindings: []
433
- })
166
+ var gt = (column, value) => ({
167
+ sql: `${column._.name} > ?`,
168
+ params: [value]
434
169
  });
435
- var isNotNull = (column) => ({
436
- toSQL: () => ({
437
- clause: `${getQualifiedName(column)} IS NOT NULL`,
438
- bindings: []
439
- })
170
+ var gte = (column, value) => ({
171
+ sql: `${column._.name} >= ?`,
172
+ params: [value]
440
173
  });
441
- var between = (column, from, to) => ({
442
- toSQL: () => {
443
- const left = getQualifiedName(column);
444
- const [fromClause, fromBindings] = isColumn(from) ? [getQualifiedName(from), []] : ["?", [from]];
445
- const [toClause, toBindings] = isColumn(to) ? [getQualifiedName(to), []] : ["?", [to]];
446
- return {
447
- clause: `${left} BETWEEN ${fromClause} AND ${toClause}`,
448
- bindings: [...fromBindings, ...toBindings]
449
- };
450
- }
174
+ var lt = (column, value) => ({
175
+ sql: `${column._.name} < ?`,
176
+ params: [value]
451
177
  });
452
- var notBetween = (column, from, to) => ({
453
- toSQL: () => {
454
- const left = getQualifiedName(column);
455
- const [fromClause, fromBindings] = isColumn(from) ? [getQualifiedName(from), []] : ["?", [from]];
456
- const [toClause, toBindings] = isColumn(to) ? [getQualifiedName(to), []] : ["?", [to]];
457
- return {
458
- clause: `${left} NOT BETWEEN ${fromClause} AND ${toClause}`,
459
- bindings: [...fromBindings, ...toBindings]
460
- };
461
- }
178
+ var lte = (column, value) => ({
179
+ sql: `${column._.name} <= ?`,
180
+ params: [value]
462
181
  });
463
- var inArray = (column, valuesOrQuery) => ({
464
- toSQL: () => {
465
- const left = getQualifiedName(column);
466
- if (Array.isArray(valuesOrQuery)) {
467
- const placeholders = valuesOrQuery.map(() => "?").join(", ");
468
- return {
469
- clause: `${left} IN (${placeholders})`,
470
- bindings: valuesOrQuery
471
- };
472
- }
473
- const sq = valuesOrQuery.toSQL ? valuesOrQuery.toSQL() : valuesOrQuery.toSQL();
474
- return { clause: `${left} IN (${sq.clause})`, bindings: sq.bindings };
475
- }
182
+ var like = (column, pattern) => ({
183
+ sql: `${column._.name} LIKE ?`,
184
+ params: [pattern]
476
185
  });
477
- var notInArray = (column, valuesOrQuery) => ({
478
- toSQL: () => {
479
- const left = getQualifiedName(column);
480
- if (Array.isArray(valuesOrQuery)) {
481
- const placeholders = valuesOrQuery.map(() => "?").join(", ");
482
- return {
483
- clause: `${left} NOT IN (${placeholders})`,
484
- bindings: valuesOrQuery
485
- };
486
- }
487
- const sq = valuesOrQuery.toSQL ? valuesOrQuery.toSQL() : valuesOrQuery.toSQL();
488
- return { clause: `${left} NOT IN (${sq.clause})`, bindings: sq.bindings };
489
- }
186
+ var isNull = (column) => ({
187
+ sql: `${column._.name} IS NULL`,
188
+ params: []
490
189
  });
491
- var exists = (subquery) => ({
492
- toSQL: () => {
493
- const sq = subquery.toSQL ? subquery.toSQL() : subquery.toSQL();
494
- return { clause: `EXISTS (${sq.clause})`, bindings: sq.bindings };
495
- }
190
+ var isNotNull = (column) => ({
191
+ sql: `${column._.name} IS NOT NULL`,
192
+ params: []
496
193
  });
497
- var notExists = (subquery) => ({
498
- toSQL: () => {
499
- const sq = subquery.toSQL ? subquery.toSQL() : subquery.toSQL();
500
- return { clause: `NOT EXISTS (${sq.clause})`, bindings: sq.bindings };
501
- }
194
+ var inArray = (column, values) => ({
195
+ sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
196
+ params: values
502
197
  });
503
- var asc = (column) => `${getQualifiedName(column)} ASC`;
504
- var desc = (column) => `${getQualifiedName(column)} DESC`;
505
-
506
- // src/orm.ts
507
- function getTableName(table) {
508
- const anyTable = table;
509
- return anyTable._tableName || anyTable.tableName || anyTable.name || "";
510
- }
511
- var SelectQueryBuilder = class {
512
- _table = null;
513
- _selectedColumns = [];
514
- _joins = [];
515
- _where = [];
516
- _orderBy = [];
517
- _limit = null;
518
- _offset = null;
519
- _groupBy = [];
520
- _having = [];
521
- _distinct = false;
522
- _dbProvider;
523
- constructor(dbProvider, fields) {
524
- this._dbProvider = dbProvider;
525
- if (fields) {
526
- for (const [alias, col] of Object.entries(fields)) {
527
- const sql2 = getQualifiedName(col);
528
- this._selectedColumns.push({ sql: sql2, alias });
529
- }
530
- }
531
- }
532
- distinct() {
533
- this._distinct = true;
534
- return this;
535
- }
536
- select(fields) {
537
- this._selectedColumns = [];
538
- for (const [alias, expr] of Object.entries(fields)) {
539
- if (typeof expr.toSQL === "function") {
540
- const s = expr.toSQL();
541
- this._selectedColumns.push({ sql: s.clause, alias });
542
- } else {
543
- this._selectedColumns.push({
544
- sql: getQualifiedName(expr),
545
- alias
546
- });
547
- }
548
- }
198
+ var BaseQueryBuilder = class {
199
+ constructor(db) {
200
+ this.db = db;
201
+ }
202
+ query = "";
203
+ params = [];
204
+ where(condition) {
205
+ this.query += ` WHERE ${condition.sql}`;
206
+ this.params.push(...condition.params);
549
207
  return this;
550
208
  }
551
- from(table) {
552
- this._table = table;
209
+ orderBy(column, direction = "ASC") {
210
+ this.query += ` ORDER BY ${column._.name} ${direction}`;
553
211
  return this;
554
212
  }
555
- where(...conditions) {
556
- this._where.push(...conditions.filter(Boolean));
213
+ limit(count) {
214
+ this.query += ` LIMIT ${count}`;
557
215
  return this;
558
216
  }
559
- leftJoin(otherTable, on) {
560
- const onSql = on.toSQL();
561
- const joinClause = `LEFT JOIN ${otherTable._tableName} ON ${onSql.clause}`;
562
- this._joins.push(joinClause);
217
+ offset(count) {
218
+ this.query += ` OFFSET ${count}`;
563
219
  return this;
564
220
  }
565
- groupBy(...exprs) {
566
- for (const e of exprs) {
567
- if (!e) continue;
568
- if (typeof e === "string") this._groupBy.push(e);
569
- else this._groupBy.push(getQualifiedName(e));
570
- }
571
- return this;
572
- }
573
- having(...conditions) {
574
- this._having.push(...conditions);
575
- return this;
221
+ build() {
222
+ return {
223
+ sql: this.query,
224
+ params: this.params
225
+ };
576
226
  }
577
- orderBy(...clauses) {
578
- for (const c of clauses) {
579
- if (!c) continue;
580
- if (typeof c === "string") this._orderBy.push(c);
581
- else if (typeof c.toSQL === "function")
582
- this._orderBy.push(c);
583
- else this._orderBy.push(getQualifiedName(c));
584
- }
585
- return this;
227
+ };
228
+ var SelectQueryBuilder = class extends BaseQueryBuilder {
229
+ constructor(db, table, columns) {
230
+ super(db);
231
+ this.table = table;
232
+ this.columns = columns;
233
+ const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
234
+ this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
586
235
  }
587
- limit(value) {
588
- this._limit = value;
589
- return this;
236
+ async execute() {
237
+ const { sql, params } = this.build();
238
+ return this.db.select(sql, ...params);
590
239
  }
591
- offset(value) {
592
- this._offset = value;
240
+ };
241
+ var InsertQueryBuilder = class extends BaseQueryBuilder {
242
+ constructor(db, table) {
243
+ super(db);
244
+ this.table = table;
245
+ this.query = `INSERT INTO ${table._.name}`;
246
+ }
247
+ dataSets = [];
248
+ values(data) {
249
+ const dataArray = Array.isArray(data) ? data : [data];
250
+ this.dataSets.push(...dataArray);
593
251
  return this;
594
252
  }
595
253
  async execute() {
596
- if (!this._table) {
597
- throw new Error("Cannot execute select query without a 'from' table.");
598
- }
599
- const db = await this._dbProvider();
600
- const baseTableName = getTableName(this._table);
601
- if (!baseTableName) {
602
- throw new Error(
603
- "Invalid table passed to select.from(): missing table name"
604
- );
605
- }
606
- const bindings = [];
607
- 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) => `${baseTableName}.${c.name}`).join(", ");
608
- let query = `SELECT ${this._distinct ? "DISTINCT " : ""}${selectList} FROM ${baseTableName}`;
609
- if (this._joins.length > 0) query += ` ${this._joins.join(" ")}`;
610
- if (this._where.length > 0) {
611
- const whereClauses = this._where.map((condition) => {
612
- const sql2 = condition.toSQL();
613
- bindings.push(...sql2.bindings);
614
- return `(${sql2.clause})`;
615
- });
616
- query += ` WHERE ${whereClauses.join(" AND ")}`;
617
- }
618
- if (this._groupBy.length > 0) {
619
- query += ` GROUP BY ${this._groupBy.join(", ")}`;
620
- }
621
- if (this._having.length > 0) {
622
- const havingClauses = this._having.map((h) => {
623
- const sql2 = h.toSQL();
624
- bindings.push(...sql2.bindings);
625
- return `(${sql2.clause})`;
626
- });
627
- query += ` HAVING ${havingClauses.join(" AND ")}`;
628
- }
629
- if (this._orderBy.length > 0) {
630
- const ordParts = [];
631
- for (const ob of this._orderBy) {
632
- if (typeof ob === "string") ordParts.push(ob);
633
- else {
634
- const s = ob.toSQL();
635
- ordParts.push(s.clause);
636
- bindings.push(...s.bindings);
637
- }
638
- }
639
- query += ` ORDER BY ${ordParts.join(", ")}`;
640
- }
641
- if (this._limit !== null) {
642
- query += ` LIMIT ?`;
643
- bindings.push(this._limit);
644
- }
645
- if (this._offset !== null) {
646
- if (this._limit === null) query += ` LIMIT -1`;
647
- query += ` OFFSET ?`;
648
- bindings.push(this._offset);
649
- }
650
- return db.select(query, bindings);
651
- }
652
- async iterator() {
653
- const rows = await this.execute();
654
- async function* gen() {
655
- for (const r of rows) yield r;
254
+ if (this.dataSets.length === 0) {
255
+ throw new Error("No data provided for insert");
656
256
  }
657
- return gen();
257
+ const columns = Object.keys(
258
+ this.dataSets[0]
259
+ );
260
+ const columnNames = columns.map(
261
+ (c) => this.table._.columns[c]._.name
262
+ );
263
+ const placeholders = `(${columnNames.map(() => "?").join(", ")})`;
264
+ const valuesSql = this.dataSets.map(() => placeholders).join(", ");
265
+ this.query += ` (${columnNames.join(", ")}) VALUES ${valuesSql}`;
266
+ const params = this.dataSets.flatMap(
267
+ (data) => columns.map((col) => data[col])
268
+ );
269
+ const result = await this.db.execute(this.query, ...params);
270
+ return result.lastInsertId ?? 0;
658
271
  }
659
272
  };
660
- var TauriORM = class {
661
- // Soft relational query API: db.query.users.findMany({ with: { posts: true } })
662
- query = {};
663
- _tables = null;
664
- _relations = null;
665
- _dbPromise;
666
- constructor(dbUri) {
667
- this._dbPromise = import_plugin_sql.default.load(dbUri).then(async (db) => {
668
- await db.execute("PRAGMA foreign_keys = ON");
669
- return db;
670
- });
671
- }
672
- async getDb() {
673
- return this._dbPromise;
674
- }
675
- // Deprecated: use configure()
676
- configureQuery(tables, relations2) {
677
- this.configure(tables, relations2);
678
- }
679
- select(fields) {
680
- return new SelectQueryBuilder(this.getDb.bind(this), fields);
273
+ var UpdateQueryBuilder = class extends BaseQueryBuilder {
274
+ constructor(db, table) {
275
+ super(db);
276
+ this.table = table;
277
+ this.query = `UPDATE ${table._.name}`;
278
+ }
279
+ updateData = {};
280
+ set(data) {
281
+ this.updateData = { ...this.updateData, ...data };
282
+ return this;
681
283
  }
682
- selectDistinct(fields) {
683
- const qb = new SelectQueryBuilder(this.getDb.bind(this), fields);
684
- qb.distinct();
685
- return qb;
284
+ async execute() {
285
+ const entries = Object.entries(this.updateData);
286
+ const setClause = entries.map(([key]) => {
287
+ const column = this.table._.columns[key];
288
+ if (!column)
289
+ throw new Error(
290
+ `Column ${key} does not exist on table ${this.table._.name}`
291
+ );
292
+ return `${column._.name} = ?`;
293
+ }).join(", ");
294
+ this.query += ` SET ${setClause}`;
295
+ this.params.push(...entries.map(([, value]) => value));
296
+ const { sql, params } = this.build();
297
+ const result = await this.db.execute(sql, ...params);
298
+ return result.rowsAffected;
686
299
  }
687
- // --- Drizzle-style CRUD builders ---
688
- insert(table) {
689
- const self = this;
690
- return new class InsertBuilder {
691
- _table = table;
692
- _rows = [];
693
- _selectSql = null;
694
- _conflict = null;
695
- _returning = null;
696
- values(rowOrRows) {
697
- this._rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
698
- return this;
699
- }
700
- select(qb) {
701
- if (qb.toSQL) this._selectSql = qb.toSQL();
702
- else this._selectSql = qb.toSQL();
703
- return this;
704
- }
705
- returning(fields) {
706
- this._returning = fields ?? {};
707
- return this;
708
- }
709
- $returningId() {
710
- this._returning = "__RETURNING_ID__";
711
- return this;
712
- }
713
- onConflictDoNothing(opts) {
714
- const target = opts?.target ? Array.isArray(opts.target) ? opts.target.map((c) => c.name) : opts.target.name : void 0;
715
- this._conflict = {
716
- kind: "doNothing",
717
- target,
718
- where: opts?.where
719
- };
720
- return this;
721
- }
722
- onConflictDoUpdate(opts) {
723
- const target = Array.isArray(opts.target) ? opts.target.map((c) => c.name) : opts.target.name;
724
- this._conflict = {
725
- kind: "doUpdate",
726
- target,
727
- targetWhere: opts.targetWhere,
728
- set: opts.set,
729
- setWhere: opts.setWhere
730
- };
731
- return this;
732
- }
733
- async execute() {
734
- const db = await self.getDb();
735
- const tableName = getTableName(this._table);
736
- if (!tableName)
737
- throw new Error(
738
- "Invalid table passed to insert(): missing table name"
739
- );
740
- if (this._selectSql) {
741
- const cols = Object.keys(this._table._schema);
742
- let query = `INSERT INTO ${tableName} (${cols.join(", ")}) ${this._selectSql.clause}`;
743
- const bindings = [...this._selectSql.bindings];
744
- query += this._buildConflictClause();
745
- const ret = await this._executeWithReturning(db, query, bindings);
746
- return ret;
747
- }
748
- for (const data of this._rows) {
749
- let coerceValue2 = function(col, value) {
750
- if (col && col.mode === "boolean") {
751
- return value ? 1 : 0;
752
- }
753
- if (value instanceof Date) {
754
- if (col && col.mode === "timestamp_ms")
755
- return value.getTime();
756
- if (col && col.mode === "timestamp")
757
- return Math.floor(value.getTime() / 1e3);
758
- }
759
- return value;
760
- };
761
- var coerceValue = coerceValue2;
762
- const finalData = Object.assign({}, data);
763
- const schema = this._table._schema;
764
- for (const [key, col] of Object.entries(schema)) {
765
- if (finalData[key] === void 0) {
766
- if (col.defaultFn) {
767
- finalData[key] = coerceValue2(col, col.defaultFn());
768
- } else if (col.onUpdateFn) {
769
- finalData[key] = coerceValue2(col, col.onUpdateFn());
770
- }
771
- }
772
- }
773
- const entries = Object.entries(finalData);
774
- const keys = entries.map(([k]) => schema[k]?.name ?? k);
775
- const values = entries.map(([k, v]) => coerceValue2(schema[k], v));
776
- const placeholders = values.map(() => "?").join(", ");
777
- let query = `INSERT INTO ${tableName} (${keys.join(
778
- ", "
779
- )}) VALUES (${placeholders})`;
780
- const bindings = [...values];
781
- query += this._buildConflictClause();
782
- const ret = await this._executeWithReturning(db, query, bindings);
783
- if (ret !== void 0) return ret;
784
- }
785
- }
786
- _buildConflictClause() {
787
- if (!this._conflict) return "";
788
- if (this._conflict.kind === "doNothing") {
789
- const tgt2 = this._conflict.target ? Array.isArray(this._conflict.target) ? `(${this._conflict.target.join(", ")})` : `(${this._conflict.target})` : "";
790
- const where = this._conflict.where ? ` WHERE ${this._conflict.where.toSQL().clause}` : "";
791
- return ` ON CONFLICT ${tgt2} DO NOTHING${where}`;
792
- }
793
- const c = this._conflict;
794
- const tgt = Array.isArray(c.target) ? `(${c.target.join(", ")})` : `(${c.target})`;
795
- const setKeys = Object.keys(c.set ?? {});
796
- const setClause = setKeys.map((k) => {
797
- const v = c.set[k];
798
- return `${k} = ${typeof v === "object" && v && typeof v.toSQL === "function" ? v.toSQL().clause : "?"}`;
799
- }).join(", ");
800
- const targetWhere = c.targetWhere ? ` WHERE ${c.targetWhere.toSQL().clause}` : "";
801
- const setWhere = c.setWhere ? ` WHERE ${c.setWhere.toSQL().clause}` : "";
802
- return ` ON CONFLICT ${tgt}${targetWhere} DO UPDATE SET ${setClause}${setWhere}`;
803
- }
804
- async _executeWithReturning(db, query, bindings) {
805
- if (this._returning === null) {
806
- await db.execute(query, bindings);
807
- return void 0;
808
- }
809
- if (this._returning === "__RETURNING_ID__") {
810
- const rows = await db.select(`SELECT last_insert_rowid() as id`);
811
- return rows.map((r) => ({ id: r.id }));
812
- }
813
- if (typeof this._returning === "object") {
814
- const cols = Object.entries(
815
- this._returning
816
- ).map(
817
- ([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
818
- ).join(", ");
819
- const retSql = `${query} RETURNING ${cols}`;
820
- const res = await db.select(retSql, bindings);
821
- return res;
822
- }
823
- return void 0;
824
- }
825
- }();
300
+ };
301
+ var DeleteQueryBuilder = class extends BaseQueryBuilder {
302
+ constructor(db, table) {
303
+ super(db);
304
+ this.table = table;
305
+ this.query = `DELETE FROM ${table._.name}`;
826
306
  }
827
- update(table) {
828
- const self = this;
829
- return new class UpdateBuilder {
830
- _table = table;
831
- _data = null;
832
- _where = null;
833
- _orderBy = [];
834
- _limit = null;
835
- _from = null;
836
- _returning = null;
837
- set(data) {
838
- this._data = data;
839
- return this;
840
- }
841
- where(cond) {
842
- this._where = cond;
843
- return this;
844
- }
845
- orderBy(...clauses) {
846
- for (const c of clauses) {
847
- if (!c) continue;
848
- if (typeof c === "string") this._orderBy.push(c);
849
- else if (typeof c.toSQL === "function")
850
- this._orderBy.push(c);
851
- else this._orderBy.push(getQualifiedName(c));
852
- }
853
- return this;
854
- }
855
- limit(n) {
856
- this._limit = n;
857
- return this;
858
- }
859
- from(tbl) {
860
- this._from = tbl;
861
- return this;
862
- }
863
- returning(fields) {
864
- this._returning = fields ?? {};
865
- return this;
866
- }
867
- async execute() {
868
- if (!this._data)
869
- throw new Error("Update requires set() before execute()");
870
- const db = await self.getDb();
871
- const tableName = getTableName(this._table);
872
- if (!tableName)
873
- throw new Error(
874
- "Invalid table passed to update(): missing table name"
875
- );
876
- const schema = this._table._schema;
877
- const dataToSet = { ...this._data };
878
- for (const [key, col] of Object.entries(schema)) {
879
- if (!(key in dataToSet) && col.onUpdateFn) {
880
- const v = col.onUpdateFn();
881
- if (col.mode === "boolean") dataToSet[key] = v ? 1 : 0;
882
- else if (v instanceof Date) {
883
- if (col.mode === "timestamp_ms")
884
- dataToSet[key] = v.getTime();
885
- else if (col.mode === "timestamp")
886
- dataToSet[key] = Math.floor(v.getTime() / 1e3);
887
- else dataToSet[key] = v;
888
- } else dataToSet[key] = v;
889
- }
890
- }
891
- const setParts = [];
892
- const bindings = [];
893
- for (const [k, v] of Object.entries(dataToSet)) {
894
- if (v === void 0) continue;
895
- if (v && typeof v === "object" && typeof v.toSQL === "function") {
896
- const s = v.toSQL();
897
- const colName = schema[k]?.name ?? k;
898
- setParts.push(`${colName} = ${s.clause}`);
899
- bindings.push(...s.bindings);
900
- } else {
901
- const colName = schema[k]?.name ?? k;
902
- let val = v;
903
- const col = schema[k];
904
- if (col && col.mode === "boolean") val = v ? 1 : 0;
905
- else if (v instanceof Date) {
906
- if (col && col.mode === "timestamp_ms")
907
- val = v.getTime();
908
- else if (col && col.mode === "timestamp")
909
- val = Math.floor(v.getTime() / 1e3);
910
- }
911
- setParts.push(`${colName} = ?`);
912
- bindings.push(val);
913
- }
914
- }
915
- let query = `UPDATE ${tableName} SET ${setParts.join(", ")}`;
916
- if (this._from) query += ` FROM ${this._from._tableName}`;
917
- if (this._where) {
918
- if (typeof this._where.toSQL === "function") {
919
- const sql2 = this._where.toSQL();
920
- query += ` WHERE ${sql2.clause}`;
921
- bindings.push(...sql2.bindings);
922
- } else {
923
- const entries = Object.entries(this._where);
924
- if (entries.length > 0) {
925
- query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
926
- bindings.push(...entries.map(([, v]) => v));
927
- }
928
- }
929
- }
930
- if (this._orderBy.length > 0) {
931
- const ordParts = [];
932
- for (const ob of this._orderBy) {
933
- if (typeof ob === "string") ordParts.push(ob);
934
- else {
935
- const s = ob.toSQL();
936
- ordParts.push(s.clause);
937
- bindings.push(...s.bindings);
938
- }
939
- }
940
- query += ` ORDER BY ${ordParts.join(", ")}`;
941
- }
942
- if (this._limit !== null) {
943
- query += ` LIMIT ?`;
944
- bindings.push(this._limit);
945
- }
946
- if (this._returning) {
947
- const cols = Object.entries(
948
- this._returning
949
- ).map(
950
- ([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
951
- ).join(", ");
952
- const retSql = `${query} RETURNING ${cols}`;
953
- return await db.select(retSql, bindings);
954
- }
955
- await db.execute(query, bindings);
956
- }
957
- }();
307
+ async execute() {
308
+ const { sql, params } = this.build();
309
+ const result = await this.db.execute(sql, ...params);
310
+ return result.rowsAffected;
958
311
  }
959
- delete(table) {
960
- const self = this;
961
- return new class DeleteBuilder {
962
- _table = table;
963
- _where = null;
964
- _orderBy = [];
965
- _limit = null;
966
- _returning = null;
967
- where(cond) {
968
- this._where = cond;
969
- return this;
970
- }
971
- orderBy(...clauses) {
972
- for (const c of clauses) {
973
- if (!c) continue;
974
- if (typeof c === "string") this._orderBy.push(c);
975
- else if (typeof c.toSQL === "function")
976
- this._orderBy.push(c);
977
- else this._orderBy.push(getQualifiedName(c));
978
- }
979
- return this;
980
- }
981
- limit(n) {
982
- this._limit = n;
983
- return this;
984
- }
985
- returning(fields) {
986
- this._returning = fields ?? {};
987
- return this;
988
- }
989
- async execute() {
990
- const db = await self.getDb();
991
- const tableName = getTableName(this._table);
992
- if (!tableName)
993
- throw new Error(
994
- "Invalid table passed to delete(): missing table name"
995
- );
996
- let query = `DELETE FROM ${tableName}`;
997
- const bindings = [];
998
- if (this._where) {
999
- if (typeof this._where.toSQL === "function") {
1000
- const sql2 = this._where.toSQL();
1001
- query += ` WHERE ${sql2.clause}`;
1002
- bindings.push(...sql2.bindings);
1003
- } else {
1004
- const entries = Object.entries(this._where);
1005
- if (entries.length > 0) {
1006
- const schema = this._table._schema;
1007
- query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
1008
- bindings.push(...entries.map(([, v]) => v));
1009
- }
1010
- }
1011
- }
1012
- if (this._orderBy.length > 0) {
1013
- const ordParts = [];
1014
- for (const ob of this._orderBy) {
1015
- if (typeof ob === "string") ordParts.push(ob);
1016
- else {
1017
- const s = ob.toSQL();
1018
- ordParts.push(s.clause);
1019
- bindings.push(...s.bindings);
1020
- }
1021
- }
1022
- query += ` ORDER BY ${ordParts.join(", ")}`;
1023
- }
1024
- if (this._limit !== null) {
1025
- query += ` LIMIT ?`;
1026
- bindings.push(this._limit);
1027
- }
1028
- if (this._returning) {
1029
- const cols = Object.entries(
1030
- this._returning
1031
- ).map(
1032
- ([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
1033
- ).join(", ");
1034
- const retSql = `${query} RETURNING ${cols}`;
1035
- return await db.select(retSql, bindings);
1036
- }
1037
- await db.execute(query, bindings);
312
+ };
313
+ var TauriORM = class {
314
+ constructor(db, schema = void 0) {
315
+ this.db = db;
316
+ if (schema) {
317
+ for (const table of Object.values(schema)) {
318
+ this.tables.set(table._.name, table);
1038
319
  }
1039
- }();
1040
- }
1041
- // legacy direct methods removed in favor of builder APIs
1042
- // legacy direct methods removed in favor of builder APIs
1043
- // legacy direct methods removed in favor of builder APIs
1044
- async run(query, bindings = []) {
1045
- const db = await this.getDb();
1046
- await db.execute(query, bindings);
1047
- }
1048
- // --- Migrations API ---
1049
- formatDefaultValue(col) {
1050
- const dv = col.defaultValue;
1051
- if (dv === void 0) return null;
1052
- if (dv && typeof dv === "object" && "raw" in dv) {
1053
- return dv.raw;
1054
- }
1055
- if (dv instanceof Date) {
1056
- const isMs = col.mode === "timestamp_ms";
1057
- const num = isMs ? dv.getTime() : Math.floor(dv.getTime() / 1e3);
1058
- return String(num);
1059
- }
1060
- if (col.mode === "boolean") {
1061
- return String(dv ? 1 : 0);
1062
- }
1063
- if (typeof dv === "string") {
1064
- return `'${dv.replace(/'/g, "''")}'`;
1065
320
  }
1066
- return String(dv);
1067
321
  }
1068
- generateCreateTableSql(table) {
1069
- const tableName = getTableName(table);
1070
- if (!tableName)
1071
- throw new Error("Invalid table passed to DDL: missing table name");
1072
- const columns = Object.values(table._schema);
1073
- const columnDefs = columns.map((col) => {
1074
- let def = `${col.name} ${col.type}`;
1075
- if (col.isPrimaryKey) {
1076
- def += col.autoIncrement ? " PRIMARY KEY AUTOINCREMENT" : " PRIMARY KEY";
1077
- }
1078
- if (col.isNotNull) def += " NOT NULL";
1079
- if (col.defaultValue !== void 0) {
1080
- const formatted = this.formatDefaultValue(col);
1081
- if (formatted !== null) def += ` DEFAULT ${formatted}`;
1082
- }
1083
- if (col.references && !col.isPrimaryKey) {
1084
- def += ` REFERENCES ${col.references.table} (${col.references.column})`;
1085
- if (col.references.onDelete)
1086
- def += ` ON DELETE ${col.references.onDelete.toUpperCase()}`;
1087
- if (col.references.onUpdate)
1088
- def += ` ON UPDATE ${col.references.onUpdate.toUpperCase()}`;
1089
- }
1090
- return def;
1091
- });
1092
- const tableConstraints = [];
1093
- const constraints = table._constraints;
1094
- if (constraints && constraints.length) {
1095
- for (const spec of constraints) {
1096
- if (spec.expr) {
1097
- const name = spec.name;
1098
- const expr = spec.expr.raw ?? spec.expr?.raw ?? String(spec.expr);
1099
- tableConstraints.push(
1100
- name ? `CONSTRAINT ${name} CHECK (${expr})` : `CHECK (${expr})`
1101
- );
1102
- continue;
322
+ tables = /* @__PURE__ */ new Map();
323
+ async migrate() {
324
+ for (const table of this.tables.values()) {
325
+ const columnsSql = Object.entries(table._.columns).map(([name, col]) => {
326
+ let sql = `${col._.name} ${col.type}`;
327
+ if (col.options.primaryKey) sql += " PRIMARY KEY";
328
+ if (col._.autoincrement) sql += " AUTOINCREMENT";
329
+ if (col._.notNull) sql += " NOT NULL";
330
+ if (col.options.unique) sql += " UNIQUE";
331
+ if (col.options.default !== void 0) {
332
+ const value = col.options.default;
333
+ sql += ` DEFAULT ${typeof value === "string" ? `'${value}'` : value}`;
1103
334
  }
1104
- if (spec.foreignColumns) {
1105
- const name = spec.name;
1106
- const cols = spec.columns.join(", ");
1107
- const fTable = spec.foreignTable;
1108
- const fCols = spec.foreignColumns.join(", ");
1109
- let clause = `${name ? `CONSTRAINT ${name} ` : ""}FOREIGN KEY (${cols}) REFERENCES ${fTable} (${fCols})`;
1110
- if (spec.onDelete)
1111
- clause += ` ON DELETE ${String(
1112
- spec.onDelete
1113
- ).toUpperCase()}`;
1114
- if (spec.onUpdate)
1115
- clause += ` ON UPDATE ${String(
1116
- spec.onUpdate
1117
- ).toUpperCase()}`;
1118
- tableConstraints.push(clause);
1119
- continue;
335
+ if (col.options.references) {
336
+ sql += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
1120
337
  }
1121
- if (spec.columns) {
1122
- const cols = spec.columns.join(", ");
1123
- const name = spec.name;
1124
- const isPk = spec.kind === "primaryKey" || name && name.toLowerCase().includes("pk");
1125
- if (isPk) {
1126
- tableConstraints.push(
1127
- name ? `CONSTRAINT ${name} PRIMARY KEY (${cols})` : `PRIMARY KEY (${cols})`
1128
- );
1129
- } else {
1130
- tableConstraints.push(
1131
- name ? `CONSTRAINT ${name} UNIQUE (${cols})` : `UNIQUE (${cols})`
1132
- );
1133
- }
1134
- continue;
1135
- }
1136
- }
338
+ return sql;
339
+ }).join(", ");
340
+ const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
341
+ await this.db.execute(createSql);
1137
342
  }
1138
- const parts = [...columnDefs, ...tableConstraints];
1139
- return `CREATE TABLE IF NOT EXISTS ${tableName} (${parts.join(", ")});`;
1140
343
  }
1141
- async createTableIfNotExists(table) {
1142
- const sql2 = this.generateCreateTableSql(table);
1143
- await this.run(sql2);
1144
- await this.createIndexesForTable(table);
1145
- }
1146
- async createTablesIfNotExist(tables) {
1147
- for (const t of tables) {
1148
- await this.createTableIfNotExists(t);
1149
- }
344
+ select(table, columns) {
345
+ return new SelectQueryBuilder(this.db, table, columns);
1150
346
  }
1151
- generateCreateIndexSqls(table) {
1152
- const tableName = table._tableName;
1153
- const indexes = table._indexes || [];
1154
- const stmts = [];
1155
- for (const idx of indexes) {
1156
- const unique2 = idx.unique ? "UNIQUE " : "";
1157
- if (!idx.name) continue;
1158
- const colList = Array.isArray(idx.columns) ? idx.columns : [];
1159
- if (colList.length === 0) continue;
1160
- const cols = `(${colList.join(", ")})`;
1161
- const where = idx.where?.raw ? ` WHERE ${idx.where.raw}` : "";
1162
- stmts.push(
1163
- `CREATE ${unique2}INDEX IF NOT EXISTS ${idx.name} ON ${tableName} ${cols}${where};`
1164
- );
1165
- }
1166
- return stmts;
1167
- }
1168
- async createIndexesForTable(table) {
1169
- const stmts = this.generateCreateIndexSqls(table);
1170
- for (const s of stmts) await this.run(s);
1171
- }
1172
- async ensureMigrationsTable() {
1173
- await this.run(
1174
- `CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)`
1175
- );
1176
- }
1177
- async hasMigration(name) {
1178
- const db = await this.getDb();
1179
- const rows = await db.select(
1180
- `SELECT name FROM _migrations WHERE name = ?`,
1181
- [name]
1182
- );
1183
- return Array.isArray(rows) && rows.length > 0;
1184
- }
1185
- async recordMigration(name) {
1186
- const db = await this.getDb();
1187
- await db.execute(
1188
- `INSERT INTO _migrations (name, applied_at) VALUES (?, ?)`,
1189
- [name, Date.now()]
1190
- );
1191
- }
1192
- async migrate(tables, options) {
1193
- const track = options?.track ?? true;
1194
- if (track) {
1195
- await this.ensureMigrationsTable();
1196
- }
1197
- await this.forcePushForTables(tables, { preserveData: true });
1198
- if (track) {
1199
- const name = options?.name ?? `init:${tables.map((t) => t._tableName).join(",")}`;
1200
- const already = await this.hasMigration(name);
1201
- if (!already) await this.recordMigration(name);
1202
- }
347
+ insert(table) {
348
+ return new InsertQueryBuilder(this.db, table);
1203
349
  }
1204
- // Configure schema and relations, and generate db.query automatically
1205
- configure(tables, relDefs) {
1206
- this._tables = tables;
1207
- this._relations = relDefs ?? {};
1208
- this.query = makeQueryAPI(
1209
- tables,
1210
- this._relations ?? {},
1211
- this.getDb.bind(this)
1212
- );
1213
- return this;
350
+ update(table) {
351
+ return new UpdateQueryBuilder(this.db, table);
1214
352
  }
1215
- // Convenience: migrate from configured tables
1216
- async migrateConfigured(options) {
1217
- if (!this._tables)
1218
- throw new Error("No tables configured. Call db.configure({...}) first.");
1219
- await this.migrate(Object.values(this._tables), options);
1220
- await this.setSchemaMeta("schema_signature", this.computeModelSignature());
353
+ delete(table) {
354
+ return new DeleteQueryBuilder(this.db, table);
1221
355
  }
1222
- // --- Schema diff and CLI-like helpers ---
1223
- async diffSchema() {
1224
- if (!this._tables) throw new Error("No tables configured.");
1225
- const dbi = await this.getDb();
1226
- const configuredNames = Object.values(this._tables).map(
1227
- (t) => getTableName(t)
1228
- );
1229
- const existing = await dbi.select(
1230
- `SELECT name FROM sqlite_master WHERE type='table'`
1231
- );
1232
- const existingNames = existing.map((r) => r.name);
1233
- const extraTables = existingNames.filter(
1234
- (n) => !configuredNames.includes(n)
1235
- );
1236
- const missingTables = configuredNames.filter(
1237
- (n) => !existingNames.includes(n)
1238
- );
1239
- const tables = {};
1240
- for (const tbl of Object.values(this._tables)) {
1241
- const tableName = getTableName(tbl);
1242
- if (!existingNames.includes(tableName)) {
1243
- tables[tableName] = {
1244
- missingColumns: Object.keys(tbl._schema),
1245
- extraColumns: [],
1246
- changedColumns: []
1247
- };
1248
- continue;
1249
- }
1250
- const cols = await dbi.select(`PRAGMA table_info('${tableName}')`);
1251
- const colMap = new Map(cols.map((c) => [c.name, c]));
1252
- const modelCols = Object.values(
1253
- tbl._schema
1254
- );
1255
- const missingColumns = [];
1256
- const extraColumns = [];
1257
- const changedColumns = [];
1258
- const modelNamesSet = new Set(modelCols.map((c) => c.name));
1259
- for (const m of modelCols) {
1260
- const info = colMap.get(m.name);
1261
- if (!info) {
1262
- missingColumns.push(m.name);
1263
- continue;
1264
- }
1265
- const diffs = {};
1266
- if ((info.type || "").toUpperCase() !== m.type.toUpperCase())
1267
- diffs.type = true;
1268
- if (!!info.pk !== !!m.isPrimaryKey) diffs.pk = true;
1269
- if (!!info.notnull !== !!m.isNotNull) diffs.notNull = true;
1270
- const modelDv = m.defaultValue && typeof m.defaultValue === "object" && m.defaultValue.raw ? m.defaultValue.raw : m.defaultValue ?? null;
1271
- if ((info.dflt_value ?? null) !== modelDv)
1272
- diffs.default = true;
1273
- if (Object.keys(diffs).length)
1274
- changedColumns.push({ name: m.name, diffs });
1275
- }
1276
- for (const c of cols)
1277
- if (!modelNamesSet.has(c.name)) extraColumns.push(c.name);
1278
- tables[tableName] = { missingColumns, extraColumns, changedColumns };
356
+ async transaction(callback) {
357
+ await this.db.execute("BEGIN TRANSACTION");
358
+ try {
359
+ const result = await callback(this);
360
+ await this.db.execute("COMMIT");
361
+ return result;
362
+ } catch (error) {
363
+ await this.db.execute("ROLLBACK");
364
+ throw error;
1279
365
  }
1280
- return { extraTables, missingTables, tables };
1281
- }
1282
- async generate() {
1283
- if (!this._tables) throw new Error("No tables configured.");
1284
- return {
1285
- statements: Object.values(this._tables).map(
1286
- (t) => this.buildCreateTableSQL(t)
1287
- )
1288
- };
1289
- }
1290
- async migrateCli(opts) {
1291
- return this.migrateConfigured(opts);
1292
- }
1293
- async push(opts) {
1294
- return this.forcePush(opts);
1295
- }
1296
- async pull() {
1297
- return this.pullSchema();
1298
- }
1299
- async studio() {
1300
- const dbi = await this.getDb();
1301
- return { driver: "sqlite", path: dbi.path };
1302
366
  }
1303
367
  // --- Schema detection / signature ---
1304
368
  async ensureSchemaMeta() {
1305
- await this.run(
369
+ await this.db.execute(
1306
370
  `CREATE TABLE IF NOT EXISTS _schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`
1307
371
  );
1308
372
  }
1309
373
  async getSchemaMeta(key) {
1310
- const dbi = await this.getDb();
1311
374
  await this.ensureSchemaMeta();
1312
- const rows = await dbi.select(
375
+ const rows = await this.db.select(
1313
376
  `SELECT value FROM _schema_meta WHERE key = ?`,
1314
377
  [key]
1315
378
  );
1316
379
  return rows?.[0]?.value ?? null;
1317
380
  }
1318
381
  async setSchemaMeta(key, value) {
1319
- const dbi = await this.getDb();
1320
382
  await this.ensureSchemaMeta();
1321
- await dbi.execute(
383
+ await this.db.execute(
1322
384
  `INSERT INTO _schema_meta(key, value) VALUES(?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`,
1323
385
  [key, value]
1324
386
  );
1325
387
  }
1326
388
  normalizeColumn(col) {
1327
389
  return {
1328
- name: col.name,
390
+ name: col._.name,
1329
391
  type: col.type,
1330
- pk: !!col.isPrimaryKey,
1331
- ai: !!col.autoIncrement,
1332
- nn: !!col.isNotNull,
1333
- dv: col.defaultValue && typeof col.defaultValue === "object" && col.defaultValue.raw ? { raw: col.defaultValue.raw } : col.defaultValue ?? null
392
+ pk: !!col.options.primaryKey,
393
+ ai: !!col._.autoincrement,
394
+ nn: !!col._.notNull,
395
+ dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null
1334
396
  };
1335
397
  }
1336
398
  computeModelSignature() {
1337
- if (!this._tables) return "";
1338
- const entries = Object.entries(this._tables).map(([k, tbl]) => {
1339
- const cols = Object.values(
1340
- tbl._schema
1341
- ).map((c) => this.normalizeColumn(c)).sort((a, b) => a.name.localeCompare(b.name));
1342
- return { table: tbl._tableName, columns: cols };
399
+ const entries = Array.from(this.tables.values()).map((tbl) => {
400
+ const cols = Object.values(tbl._.columns).map((c) => this.normalizeColumn(c)).sort((a, b) => a.name.localeCompare(b.name));
401
+ return { table: tbl._.name, columns: cols };
1343
402
  });
1344
403
  entries.sort((a, b) => a.table.localeCompare(b.table));
1345
404
  return JSON.stringify(entries);
@@ -1347,22 +406,15 @@ var TauriORM = class {
1347
406
  getSchemaSignature() {
1348
407
  return this.computeModelSignature();
1349
408
  }
1350
- async printSchemaDiff() {
1351
- const diff = await this.diffSchema();
1352
- console.log("Schema diff:", JSON.stringify(diff, null, 2));
1353
- }
1354
409
  async isSchemaDirty() {
1355
410
  const sig = this.computeModelSignature();
1356
411
  const stored = await this.getSchemaMeta("schema_signature");
1357
412
  return { dirty: sig !== stored, current: sig, stored };
1358
413
  }
1359
- async migrateIfDirty(options) {
414
+ async migrateIfDirty() {
1360
415
  const status = await this.isSchemaDirty();
1361
- if (!this._tables) throw new Error("No tables configured.");
1362
416
  if (status.dirty) {
1363
- await this.forcePushForTables(Object.values(this._tables), {
1364
- preserveData: true
1365
- });
417
+ await this.migrate();
1366
418
  await this.setSchemaMeta(
1367
419
  "schema_signature",
1368
420
  this.computeModelSignature()
@@ -1371,455 +423,46 @@ var TauriORM = class {
1371
423
  }
1372
424
  return false;
1373
425
  }
1374
- // Pull current DB schema (minimal) for configured tables
1375
- async pullSchema() {
1376
- if (!this._tables) throw new Error("No tables configured.");
1377
- const dbi = await this.getDb();
1378
- const result = {};
1379
- for (const tbl of Object.values(this._tables)) {
1380
- const name = tbl._tableName;
1381
- const cols = await dbi.select(`PRAGMA table_info('${name}')`);
1382
- result[name] = cols.map((c) => ({
1383
- name: c.name,
1384
- type: c.type,
1385
- notnull: !!c.notnull,
1386
- pk: !!c.pk,
1387
- dflt_value: c.dflt_value ?? null
1388
- }));
1389
- }
1390
- return result;
1391
- }
1392
- buildCreateTableSQL(table) {
1393
- return this.generateCreateTableSql(table);
1394
- }
1395
- async tableExists(name) {
1396
- const dbi = await this.getDb();
1397
- const rows = await dbi.select(
1398
- `SELECT name FROM sqlite_master WHERE type='table' AND name = ?`,
1399
- [name]
1400
- );
1401
- return rows.length > 0;
1402
- }
1403
- // Force push model to DB: add missing tables/columns, rebuild tables if incompatible
1404
- async forcePush(options) {
1405
- if (!this._tables) throw new Error("No tables configured.");
1406
- await this.forcePushForTables(Object.values(this._tables), options);
1407
- }
1408
- async forcePushForTables(tables, options) {
1409
- const dbi = await this.getDb();
1410
- const preserve = options?.preserveData !== false;
1411
- for (const tbl of tables) {
1412
- const tableName = getTableName(tbl);
1413
- const exists2 = await this.tableExists(tableName);
1414
- if (!exists2) {
1415
- await this.run(this.buildCreateTableSQL(tbl));
1416
- await this.createIndexesForTable(tbl);
1417
- continue;
1418
- }
1419
- const existingCols = await dbi.select(
1420
- `PRAGMA table_info('${tableName}')`
1421
- );
1422
- const existingMap = new Map(existingCols.map((c) => [c.name, c]));
1423
- const modelCols = Object.values(
1424
- tbl._schema
1425
- );
1426
- const missing = [];
1427
- let requiresRebuild = false;
1428
- for (const m of modelCols) {
1429
- const info = existingMap.get(m.name);
1430
- if (!info) {
1431
- missing.push(m);
1432
- continue;
1433
- }
1434
- const typeDiff = (info.type || "").toUpperCase() !== m.type.toUpperCase();
1435
- const pkDiff = !!info.pk !== !!m.isPrimaryKey;
1436
- const nnDiff = !!info.notnull !== !!m.isNotNull;
1437
- const modelDv = m.defaultValue && typeof m.defaultValue === "object" && m.defaultValue.raw ? m.defaultValue.raw : m.defaultValue ?? null;
1438
- const defDiff = (info.dflt_value ?? null) !== modelDv;
1439
- if (typeDiff || pkDiff || nnDiff && !modelDv || defDiff) {
1440
- requiresRebuild = true;
1441
- }
1442
- }
1443
- if (requiresRebuild) {
1444
- const tmp = `_new_${tableName}`;
1445
- await this.run(this.buildCreateTableSQL(tbl));
1446
- await this.run(
1447
- this.buildCreateTableSQL({ ...tbl, _tableName: tmp })
1448
- );
1449
- const existingNames = existingCols.map((c) => c.name);
1450
- const modelNames = modelCols.map((c) => c.name);
1451
- const shared = existingNames.filter((n) => modelNames.includes(n));
1452
- if (preserve && shared.length > 0) {
1453
- await this.run(
1454
- `INSERT INTO ${tmp} (${shared.join(", ")}) SELECT ${shared.join(
1455
- ", "
1456
- )} FROM ${tableName}`
1457
- );
1458
- }
1459
- await this.run(`DROP TABLE ${tableName}`);
1460
- await this.run(`ALTER TABLE ${tmp} RENAME TO ${tableName}`);
1461
- await this.createIndexesForTable(tbl);
1462
- } else {
1463
- for (const m of missing) {
1464
- let clause = `${m.name} ${m.type}`;
1465
- if (m.isNotNull) clause += " NOT NULL";
1466
- if (m.defaultValue !== void 0) {
1467
- const formatted = this.formatDefaultValue(m);
1468
- if (formatted !== null) clause += ` DEFAULT ${formatted}`;
1469
- }
1470
- await this.run(`ALTER TABLE ${tableName} ADD COLUMN ${clause}`);
1471
- }
1472
- await this.createIndexesForTable(tbl);
1473
- }
1474
- }
1475
- await this.setSchemaMeta("schema_signature", this.computeModelSignature());
1476
- }
1477
426
  };
1478
- function relations(baseTable, builder) {
1479
- const ctx = {
1480
- one: (table, cfg) => ({ kind: "one", table, cfg }),
1481
- many: (table, cfg) => ({ kind: "many", table, cfg })
1482
- };
1483
- const rels = builder(ctx);
1484
- return rels;
1485
- }
1486
- function getPrimaryKey(table) {
1487
- const cols = Object.values(table._schema);
1488
- return cols.find((c) => c.isPrimaryKey) || cols.find((c) => c.name === "id") || cols[0];
1489
- }
1490
- function guessChildFk(child, base, rel) {
1491
- const childCols = Object.values(child._schema);
1492
- if (rel && rel.kind === "one" && rel.cfg?.fields?.[0])
1493
- return rel.cfg.fields[0];
1494
- const basePk = getPrimaryKey(base);
1495
- const guessNames = [
1496
- `${base._tableName}_id`,
1497
- `${base._tableName}Id`,
1498
- `${basePk.name}`,
1499
- `${base._tableName.slice(0, -1)}Id`
1500
- ];
1501
- return childCols.find((c) => guessNames.includes(c.name)) || childCols.find((c) => /.*_id$/i.test(c.name)) || null;
1502
- }
1503
- function guessOneRelationJoin(base, rel) {
1504
- const child = rel.table;
1505
- const basePk = getPrimaryKey(base);
1506
- const childCols = Object.values(child._schema);
1507
- if (rel.cfg?.fields && rel.cfg?.references && rel.cfg.fields[0] && rel.cfg.references[0]) {
1508
- const fk = rel.cfg.fields[0];
1509
- const ref = rel.cfg.references[0];
1510
- if (childCols.some((c) => c.name === fk.name)) {
1511
- return { lhsTable: child, lhsCol: fk, rhsTable: base, rhsCol: ref };
1512
- }
1513
- const baseCols = Object.values(base._schema);
1514
- if (baseCols.some((c) => c.name === fk.name)) {
1515
- return { lhsTable: base, lhsCol: fk, rhsTable: child, rhsCol: ref };
1516
- }
1517
- }
1518
- const childFk = guessChildFk(child, base, rel);
1519
- if (!childFk) return null;
1520
- return { lhsTable: child, lhsCol: childFk, rhsTable: base, rhsCol: basePk };
1521
- }
1522
- function isFlatWith(spec) {
1523
- return Object.values(spec).every((v) => typeof v === "boolean");
1524
- }
1525
- function makeQueryAPI(tables, relDefs, dbProvider) {
1526
- const api = {};
1527
- const tableKeyByName = {};
1528
- for (const [k, t] of Object.entries(tables)) tableKeyByName[t._tableName] = k;
1529
- for (const [tblKey, tbl] of Object.entries(tables)) {
1530
- api[tblKey] = {
1531
- async findMany(opts) {
1532
- const base = tbl;
1533
- const withSpec = opts?.with ?? {};
1534
- const dbi = await dbProvider();
1535
- const rels = relDefs[tblKey] ?? {};
1536
- if (opts?.join && isFlatWith(withSpec)) {
1537
- const baseCols = Object.values(base._schema);
1538
- const basePk = baseCols.find((c) => c.isPrimaryKey) || baseCols.find((c) => c.name === "id") || baseCols[0];
1539
- const selectParts = [];
1540
- let baseSelected2;
1541
- if (opts?.columns && !Array.isArray(opts.columns)) {
1542
- baseSelected2 = Object.entries(opts.columns).filter(([, v]) => !!v).map(([k]) => k);
1543
- } else if (Array.isArray(opts?.columns) && opts.columns.length > 0) {
1544
- baseSelected2 = opts.columns;
1545
- } else {
1546
- baseSelected2 = baseCols.map((c) => c.name);
1547
- }
1548
- for (const name of baseSelected2)
1549
- selectParts.push(`${base._tableName}.${name} AS __base_${name}`);
1550
- const joins = [];
1551
- const relColsMap = {};
1552
- const fkMap = {};
1553
- for (const [relName, enabled] of Object.entries(withSpec)) {
1554
- if (!enabled) continue;
1555
- const rel = rels[relName];
1556
- if (!rel) continue;
1557
- const child = rel.table;
1558
- const childCols = Object.values(child._schema);
1559
- const childPk = childCols.find((c) => c.isPrimaryKey) || childCols.find((c) => c.name === "id") || null;
1560
- if (rel.kind === "one") {
1561
- const mapping = guessOneRelationJoin(base, rel);
1562
- if (!mapping) continue;
1563
- if (mapping.lhsTable._tableName === child._tableName) {
1564
- fkMap[relName] = { childFk: mapping.lhsCol, childPk };
1565
- joins.push(
1566
- `LEFT JOIN ${child._tableName} ON ${mapping.lhsTable._tableName}.${mapping.lhsCol.name} = ${mapping.rhsTable._tableName}.${mapping.rhsCol.name}`
1567
- );
1568
- } else {
1569
- fkMap[relName] = { childFk: mapping.rhsCol, childPk };
1570
- joins.push(
1571
- `LEFT JOIN ${child._tableName} ON ${mapping.lhsTable._tableName}.${mapping.lhsCol.name} = ${mapping.rhsTable._tableName}.${mapping.rhsCol.name}`
1572
- );
1573
- }
1574
- } else {
1575
- const childFk = guessChildFk(child, base, rel);
1576
- if (!childFk) continue;
1577
- fkMap[relName] = { childFk, childPk };
1578
- joins.push(
1579
- `LEFT JOIN ${child._tableName} ON ${child._tableName}.${childFk.name} = ${base._tableName}.${basePk.name}`
1580
- );
1581
- }
1582
- const selected = typeof enabled === "object" && enabled.columns?.length ? enabled.columns : childCols.map((c) => c.name);
1583
- relColsMap[relName] = selected;
1584
- for (const name of selected)
1585
- selectParts.push(
1586
- `${child._tableName}.${name} AS __rel_${relName}_${name}`
1587
- );
1588
- }
1589
- let sqlText = `SELECT ${selectParts.join(", ")} FROM ${base._tableName}${joins.length ? " " + joins.join(" ") : ""}`;
1590
- const bindings = [];
1591
- if (opts?.where) {
1592
- if (typeof opts.where === "function") {
1593
- const w = opts.where(base, { eq, ne, gt, gte, lt, lte, like }).toSQL();
1594
- sqlText += ` WHERE ${w.clause}`;
1595
- bindings.push(...w.bindings);
1596
- } else if (typeof opts.where.toSQL === "function") {
1597
- const w = opts.where.toSQL();
1598
- sqlText += ` WHERE ${w.clause}`;
1599
- bindings.push(...w.bindings);
1600
- } else {
1601
- const entries = Object.entries(opts.where);
1602
- if (entries.length > 0) {
1603
- sqlText += ` WHERE ${entries.map(([k]) => `${base._tableName}.${k} = ?`).join(" AND ")}`;
1604
- bindings.push(...entries.map(([, v]) => v));
1605
- }
1606
- }
1607
- }
1608
- const orderByClauses = typeof opts?.orderBy === "function" ? opts.orderBy(base, { asc, desc }) : opts?.orderBy;
1609
- if (orderByClauses?.length)
1610
- sqlText += ` ORDER BY ${orderByClauses.join(", ")}`;
1611
- if (typeof opts?.limit === "number")
1612
- sqlText += ` LIMIT ${opts.limit}`;
1613
- if (typeof opts?.offset === "number")
1614
- sqlText += ` OFFSET ${opts.offset}`;
1615
- const rows = await dbi.select(sqlText, bindings);
1616
- const groups = /* @__PURE__ */ new Map();
1617
- for (const row of rows) {
1618
- const baseObj = {};
1619
- for (const name of baseSelected2)
1620
- baseObj[name] = row[`__base_${name}`];
1621
- const baseKey = baseObj[basePk.name];
1622
- if (!groups.has(baseKey)) {
1623
- const seed = { ...baseObj };
1624
- for (const [relName, enabled] of Object.entries(withSpec)) {
1625
- if (!enabled) continue;
1626
- const rel = rels[relName];
1627
- if (!rel) continue;
1628
- seed[relName] = rel.kind === "many" ? [] : null;
1629
- }
1630
- groups.set(baseKey, seed);
1631
- }
1632
- const acc = groups.get(baseKey);
1633
- for (const [relName, enabled] of Object.entries(withSpec)) {
1634
- if (!enabled) continue;
1635
- const rel = rels[relName];
1636
- if (!rel) continue;
1637
- const childCols = relColsMap[relName];
1638
- const childObj = {};
1639
- let allNull = true;
1640
- for (const name of childCols) {
1641
- const v = row[`__rel_${relName}_${name}`];
1642
- childObj[name] = v;
1643
- if (v !== null && v !== void 0) allNull = false;
1644
- }
1645
- if (allNull) continue;
1646
- if (rel.kind === "many") {
1647
- const childPk = fkMap[relName].childPk;
1648
- if (childPk) {
1649
- if (!acc[relName]) acc[relName] = [];
1650
- const exists2 = acc[relName].some(
1651
- (r) => r[childPk.name] === childObj[childPk.name]
1652
- );
1653
- if (!exists2) acc[relName].push(childObj);
1654
- } else {
1655
- acc[relName].push(childObj);
1656
- }
1657
- } else {
1658
- acc[relName] = childObj;
1659
- }
1660
- }
1661
- }
1662
- return Array.from(groups.values());
1663
- }
1664
- let baseSelected;
1665
- if (opts?.columns && !Array.isArray(opts.columns)) {
1666
- baseSelected = Object.entries(opts.columns).filter(([, v]) => !!v).map(([k]) => k);
1667
- } else if (Array.isArray(opts?.columns) && opts.columns.length > 0) {
1668
- baseSelected = opts.columns;
1669
- } else {
1670
- baseSelected = Object.values(base._schema).map(
1671
- (c) => c.name
1672
- );
1673
- }
1674
- let baseSql = `SELECT ${baseSelected.join(", ")} FROM ${base._tableName}`;
1675
- const baseBindings = [];
1676
- if (opts?.where) {
1677
- if (typeof opts.where === "function") {
1678
- const w = opts.where(base, { eq, ne, gt, gte, lt, lte, like }).toSQL();
1679
- baseSql += ` WHERE ${w.clause}`;
1680
- baseBindings.push(...w.bindings);
1681
- } else if (typeof opts.where.toSQL === "function") {
1682
- const w = opts.where.toSQL();
1683
- baseSql += ` WHERE ${w.clause}`;
1684
- baseBindings.push(...w.bindings);
1685
- } else {
1686
- const entries = Object.entries(opts.where);
1687
- if (entries.length > 0) {
1688
- baseSql += ` WHERE ${entries.map(([k]) => `${k} = ?`).join(" AND ")}`;
1689
- baseBindings.push(...entries.map(([, v]) => v));
1690
- }
1691
- }
1692
- }
1693
- const orderByClauses2 = typeof opts?.orderBy === "function" ? opts.orderBy(base, { asc, desc }) : opts?.orderBy;
1694
- if (orderByClauses2?.length)
1695
- baseSql += ` ORDER BY ${orderByClauses2.join(", ")}`;
1696
- if (typeof opts?.limit === "number") baseSql += ` LIMIT ${opts.limit}`;
1697
- if (typeof opts?.offset === "number")
1698
- baseSql += ` OFFSET ${opts.offset}`;
1699
- const baseRows = await dbi.select(baseSql, baseBindings);
1700
- const result = baseRows.map((r) => ({ ...r }));
1701
- async function loadRelationsFor(parents, parentTable, spec) {
1702
- const parentPk = getPrimaryKey(parentTable);
1703
- const parentIds = parents.map((p) => p[parentPk.name]);
1704
- const relsMap = relDefs[Object.keys(tables).find(
1705
- (k) => tables[k]._tableName === parentTable._tableName
1706
- )] || {};
1707
- for (const [relName, v] of Object.entries(spec)) {
1708
- const enabled = v;
1709
- const rel = relsMap[relName];
1710
- if (!rel) continue;
1711
- const child = rel.table;
1712
- const childCols = Object.values(child._schema);
1713
- const selectCols = enabled?.columns && enabled.columns.length > 0 ? enabled.columns : childCols.map((c) => c.name);
1714
- if (rel.kind === "many") {
1715
- const fkCol = guessChildFk(child, parentTable, rel);
1716
- if (!fkCol) continue;
1717
- const sql2 = `SELECT ${selectCols.join(", ")} FROM ${child._tableName} WHERE ${fkCol.name} IN (${parentIds.map(() => "?").join(", ")})`;
1718
- const rows = await dbi.select(sql2, parentIds);
1719
- const buckets = /* @__PURE__ */ new Map();
1720
- for (const r of rows) {
1721
- const key = r[fkCol.name];
1722
- if (!buckets.has(key)) buckets.set(key, []);
1723
- buckets.get(key).push(r);
1724
- }
1725
- for (const p of parents)
1726
- p[relName] = buckets.get(p[parentPk.name]) ?? [];
1727
- if (enabled?.with) {
1728
- const children = parents.flatMap(
1729
- (p) => p[relName]
1730
- );
1731
- if (children.length > 0)
1732
- await loadRelationsFor(children, child, enabled.with);
1733
- }
1734
- } else {
1735
- const mapping = guessOneRelationJoin(parentTable, rel);
1736
- if (!mapping) continue;
1737
- if (mapping.lhsTable._tableName === child._tableName) {
1738
- const sql2 = `SELECT ${selectCols.join(", ")} FROM ${child._tableName} WHERE ${mapping.lhsCol.name} IN (${parentIds.map(() => "?").join(", ")})`;
1739
- const rows = await dbi.select(sql2, parentIds);
1740
- const mapOne = /* @__PURE__ */ new Map();
1741
- for (const r of rows) mapOne.set(r[mapping.lhsCol.name], r);
1742
- for (const p of parents)
1743
- p[relName] = mapOne.get(p[parentPk.name]) ?? null;
1744
- } else {
1745
- const parentFkName = mapping.lhsCol.name;
1746
- const childPkName = mapping.rhsCol.name;
1747
- const childIds = parents.map((p) => p[parentFkName]).filter((v2) => v2 !== void 0 && v2 !== null);
1748
- if (childIds.length === 0) {
1749
- for (const p of parents) p[relName] = null;
1750
- } else {
1751
- const sql2 = `SELECT ${selectCols.join(", ")} FROM ${child._tableName} WHERE ${childPkName} IN (${childIds.map(() => "?").join(", ")})`;
1752
- const rows = await dbi.select(sql2, childIds);
1753
- const mapOne = /* @__PURE__ */ new Map();
1754
- for (const r of rows) mapOne.set(r[childPkName], r);
1755
- for (const p of parents)
1756
- p[relName] = mapOne.get(p[parentFkName]) ?? null;
1757
- }
1758
- }
1759
- if (enabled?.with) {
1760
- const children = parents.map((p) => p[relName]).filter((x) => Boolean(x));
1761
- if (children.length > 0)
1762
- await loadRelationsFor(children, child, enabled.with);
1763
- }
1764
- }
1765
- }
1766
- }
1767
- if (Object.keys(withSpec).length > 0) {
1768
- await loadRelationsFor(result, base, withSpec);
1769
- }
1770
- return result;
1771
- },
1772
- async findFirst(opts) {
1773
- const rows = await api[tblKey].findMany({ ...opts, limit: 1 });
1774
- return rows?.[0] ?? null;
1775
- }
1776
- };
1777
- }
1778
- return api;
1779
- }
427
+ var relations = (table, relationsCallback) => {
428
+ return relationsCallback({
429
+ one: (table2, config) => ({
430
+ table: table2,
431
+ type: "one",
432
+ foreignKey: config.fields[0],
433
+ localKey: config.references[0]
434
+ }),
435
+ many: (table2) => ({
436
+ table: table2,
437
+ type: "many"
438
+ })
439
+ });
440
+ };
1780
441
  // Annotate the CommonJS export names for ESM import in node:
1781
442
  0 && (module.exports = {
443
+ DeleteQueryBuilder,
444
+ InsertQueryBuilder,
445
+ SQLiteColumn,
446
+ SelectQueryBuilder,
447
+ Table,
1782
448
  TauriORM,
449
+ UpdateQueryBuilder,
1783
450
  and,
1784
- asc,
1785
- between,
1786
451
  blob,
1787
452
  boolean,
1788
- check,
1789
- defineTable,
1790
- desc,
1791
453
  eq,
1792
- exists,
1793
- foreignKey,
1794
- getQualifiedName,
1795
454
  gt,
1796
455
  gte,
1797
- ilike,
1798
456
  inArray,
1799
- increments,
1800
- index,
1801
457
  integer,
1802
458
  isNotNull,
1803
459
  isNull,
1804
460
  like,
1805
461
  lt,
1806
462
  lte,
1807
- makeQueryAPI,
1808
- ne,
1809
- not,
1810
- notBetween,
1811
- notExists,
1812
- notIlike,
1813
- notInArray,
1814
- numeric,
1815
463
  or,
1816
- primaryKey,
1817
- raw,
1818
464
  real,
1819
465
  relations,
1820
- sql,
1821
- text,
1822
- timestamp,
1823
- unique,
1824
- uniqueIndex
466
+ sqliteTable,
467
+ text
1825
468
  });