@type32/tauri-sqlite-orm 0.1.18-1 → 0.1.18-10

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
@@ -7,11 +7,11 @@ var __export = (target, all) => {
7
7
  for (var name in all)
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
- var __copyProps = (to, from, except, desc) => {
10
+ var __copyProps = (to, from, except, desc2) => {
11
11
  if (from && typeof from === "object" || typeof from === "function") {
12
12
  for (let key of __getOwnPropNames(from))
13
13
  if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
15
15
  }
16
16
  return to;
17
17
  };
@@ -20,17 +20,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ BaseQueryBuilder: () => BaseQueryBuilder,
23
24
  DeleteQueryBuilder: () => DeleteQueryBuilder,
24
25
  InsertQueryBuilder: () => InsertQueryBuilder,
26
+ ManyRelation: () => ManyRelation,
27
+ OneRelation: () => OneRelation,
28
+ Relation: () => Relation,
25
29
  SQLiteColumn: () => SQLiteColumn,
26
30
  SelectQueryBuilder: () => SelectQueryBuilder,
27
31
  Table: () => Table,
28
32
  TauriORM: () => TauriORM,
29
33
  UpdateQueryBuilder: () => UpdateQueryBuilder,
34
+ WithQueryBuilder: () => WithQueryBuilder,
35
+ alias: () => alias,
30
36
  and: () => and,
37
+ asc: () => asc,
38
+ avg: () => avg,
31
39
  blob: () => blob,
32
40
  boolean: () => boolean,
41
+ columnHelpers: () => columnHelpers,
42
+ count: () => count,
43
+ countDistinct: () => countDistinct,
44
+ desc: () => desc,
33
45
  eq: () => eq,
46
+ getTableColumns: () => getTableColumns,
34
47
  gt: () => gt,
35
48
  gte: () => gte,
36
49
  inArray: () => inArray,
@@ -40,14 +53,498 @@ __export(index_exports, {
40
53
  like: () => like,
41
54
  lt: () => lt,
42
55
  lte: () => lte,
56
+ max: () => max,
57
+ min: () => min,
58
+ not: () => not,
43
59
  or: () => or,
44
60
  real: () => real,
45
61
  relations: () => relations,
62
+ sql: () => sql,
46
63
  sqliteTable: () => sqliteTable,
47
- text: () => text
64
+ sum: () => sum
48
65
  });
49
66
  module.exports = __toCommonJS(index_exports);
50
67
 
68
+ // src/builders/query-base.ts
69
+ var BaseQueryBuilder = class {
70
+ constructor(db) {
71
+ this.db = db;
72
+ }
73
+ query = "";
74
+ params = [];
75
+ where(condition) {
76
+ this.query += ` WHERE ${condition.sql}`;
77
+ this.params.push(...condition.params);
78
+ return this;
79
+ }
80
+ orderBy(column, direction = "ASC") {
81
+ if ("sql" in column) {
82
+ this.query += ` ORDER BY ${column.sql} ${direction}`;
83
+ this.params.push(...column.params);
84
+ } else {
85
+ this.query += ` ORDER BY ${column._.name} ${direction}`;
86
+ }
87
+ return this;
88
+ }
89
+ limit(count2) {
90
+ this.query += ` LIMIT ${count2}`;
91
+ return this;
92
+ }
93
+ offset(count2) {
94
+ this.query += ` OFFSET ${count2}`;
95
+ return this;
96
+ }
97
+ build() {
98
+ return {
99
+ sql: this.query,
100
+ params: this.params
101
+ };
102
+ }
103
+ };
104
+
105
+ // src/operators.ts
106
+ var eq = (column, value) => ({
107
+ sql: `${column._.name} = ?`,
108
+ params: [value]
109
+ });
110
+ var and = (...conditions) => ({
111
+ sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
112
+ params: conditions.flatMap((c) => c.params)
113
+ });
114
+ var or = (...conditions) => ({
115
+ sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
116
+ params: conditions.flatMap((c) => c.params)
117
+ });
118
+ var not = (condition) => ({
119
+ sql: `NOT (${condition.sql})`,
120
+ params: condition.params
121
+ });
122
+ var gt = (column, value) => ({
123
+ sql: `${column._.name} > ?`,
124
+ params: [value]
125
+ });
126
+ var gte = (column, value) => ({
127
+ sql: `${column._.name} >= ?`,
128
+ params: [value]
129
+ });
130
+ var lt = (column, value) => ({
131
+ sql: `${column._.name} < ?`,
132
+ params: [value]
133
+ });
134
+ var lte = (column, value) => ({
135
+ sql: `${column._.name} <= ?`,
136
+ params: [value]
137
+ });
138
+ var like = (column, pattern) => ({
139
+ sql: `${column._.name} LIKE ?`,
140
+ params: [pattern]
141
+ });
142
+ var isNull = (column) => ({
143
+ sql: `${column._.name} IS NULL`,
144
+ params: []
145
+ });
146
+ var isNotNull = (column) => ({
147
+ sql: `${column._.name} IS NOT NULL`,
148
+ params: []
149
+ });
150
+ var inArray = (column, values) => ({
151
+ sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
152
+ params: values
153
+ });
154
+ var count = (column) => ({
155
+ sql: `COUNT(${column ? column._.name : "*"})`,
156
+ params: []
157
+ });
158
+ var countDistinct = (column) => ({
159
+ sql: `COUNT(DISTINCT ${column._.name})`,
160
+ params: []
161
+ });
162
+ var sum = (column) => ({
163
+ sql: `SUM(${column._.name})`,
164
+ params: []
165
+ });
166
+ var avg = (column) => ({
167
+ sql: `AVG(${column._.name})`,
168
+ params: []
169
+ });
170
+ var max = (column) => ({
171
+ sql: `MAX(${column._.name})`,
172
+ params: []
173
+ });
174
+ var min = (column) => ({
175
+ sql: `MIN(${column._.name})`,
176
+ params: []
177
+ });
178
+
179
+ // src/builders/select.ts
180
+ var SelectQueryBuilder = class extends BaseQueryBuilder {
181
+ constructor(db, table, columns) {
182
+ super(db);
183
+ this.table = table;
184
+ this.columns = columns;
185
+ const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
186
+ this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
187
+ }
188
+ isDistinct = false;
189
+ groupByColumns = [];
190
+ havingCondition = null;
191
+ joins = [];
192
+ includeRelations = {};
193
+ distinct() {
194
+ this.isDistinct = true;
195
+ this.query = this.query.replace("SELECT", "SELECT DISTINCT");
196
+ return this;
197
+ }
198
+ groupBy(...columns) {
199
+ this.groupByColumns.push(...columns);
200
+ const columnNames = columns.map((col) => col._.name).join(", ");
201
+ this.query += ` GROUP BY ${columnNames}`;
202
+ return this;
203
+ }
204
+ having(condition) {
205
+ this.havingCondition = condition;
206
+ this.query += ` HAVING ${condition.sql}`;
207
+ this.params.push(...condition.params);
208
+ return this;
209
+ }
210
+ leftJoin(table, condition, alias2) {
211
+ this.joins.push({ type: "LEFT", table, condition, alias: alias2 });
212
+ return this;
213
+ }
214
+ innerJoin(table, condition, alias2) {
215
+ this.joins.push({ type: "INNER", table, condition, alias: alias2 });
216
+ return this;
217
+ }
218
+ include(relations2) {
219
+ this.includeRelations = { ...this.includeRelations, ...relations2 };
220
+ return this;
221
+ }
222
+ buildJoins() {
223
+ let sql2 = "";
224
+ const params = [];
225
+ for (const join of this.joins) {
226
+ const tableAlias = join.alias || join.table._.name;
227
+ sql2 += ` ${join.type} JOIN ${join.table._.name} ${tableAlias} ON ${join.condition.sql}`;
228
+ params.push(...join.condition.params);
229
+ }
230
+ for (const [relationName, include] of Object.entries(
231
+ this.includeRelations
232
+ )) {
233
+ if (!include) continue;
234
+ const relation = this.table.relations[relationName];
235
+ if (!relation) continue;
236
+ const foreignTable = relation.foreignTable;
237
+ const foreignAlias = `${this.table._.name}_${relationName}`;
238
+ if (relation.type === "one" && relation.fields && relation.references) {
239
+ const conditions = relation.fields.map(
240
+ (field, i) => eq(field, relation.references[i])
241
+ );
242
+ const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
243
+ sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
244
+ params.push(...condition.params);
245
+ } else if (relation.type === "many") {
246
+ const refRelation = Object.values(foreignTable.relations).find(
247
+ (r) => r.foreignTable === this.table
248
+ );
249
+ if (refRelation && refRelation.fields && refRelation.references) {
250
+ const conditions = refRelation.fields.map(
251
+ (field, i) => eq(field, refRelation.references[i])
252
+ );
253
+ const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
254
+ sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
255
+ params.push(...condition.params);
256
+ }
257
+ }
258
+ }
259
+ return { sql: sql2, params };
260
+ }
261
+ async execute() {
262
+ const { sql: joinSql, params: joinParams } = this.buildJoins();
263
+ this.query += joinSql;
264
+ this.params.push(...joinParams);
265
+ const { sql: sql2, params } = this.build();
266
+ return this.db.select(sql2, params);
267
+ }
268
+ async all() {
269
+ return this.execute();
270
+ }
271
+ async get() {
272
+ this.limit(1);
273
+ const result = await this.execute();
274
+ return result[0];
275
+ }
276
+ };
277
+
278
+ // src/builders/update.ts
279
+ var UpdateQueryBuilder = class extends BaseQueryBuilder {
280
+ constructor(db, table) {
281
+ super(db);
282
+ this.table = table;
283
+ this.query = `UPDATE ${table._.name}`;
284
+ }
285
+ updateData = {};
286
+ returningColumns = [];
287
+ set(data) {
288
+ this.updateData = { ...this.updateData, ...data };
289
+ return this;
290
+ }
291
+ returning(...columns) {
292
+ this.returningColumns.push(...columns);
293
+ return this;
294
+ }
295
+ buildUpdateClause() {
296
+ const finalUpdateData = { ...this.updateData };
297
+ for (const [key, column] of Object.entries(this.table._.columns)) {
298
+ const typedKey = key;
299
+ if (finalUpdateData[typedKey] === void 0 && column.options.$onUpdateFn) {
300
+ finalUpdateData[typedKey] = column.options.$onUpdateFn();
301
+ }
302
+ }
303
+ const baseQuery = this.query;
304
+ const whereParams = this.params;
305
+ let tablePart = baseQuery;
306
+ let whereClause = "";
307
+ const whereIndex = baseQuery.indexOf(" WHERE ");
308
+ if (whereIndex !== -1) {
309
+ tablePart = baseQuery.substring(0, whereIndex);
310
+ whereClause = baseQuery.substring(whereIndex);
311
+ }
312
+ const entries = Object.entries(finalUpdateData);
313
+ if (entries.length === 0) {
314
+ throw new Error("Cannot execute an update query without a .set() call.");
315
+ }
316
+ const setClause = entries.map(([key]) => {
317
+ const column = this.table._.columns[key];
318
+ if (!column) {
319
+ throw new Error(
320
+ `Column ${key} does not exist on table ${this.table._.name}`
321
+ );
322
+ }
323
+ return `${column._.name} = ?`;
324
+ }).join(", ");
325
+ const setParams = entries.map(([, value]) => value);
326
+ const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
327
+ const params = [...setParams, ...whereParams];
328
+ return { sql: sql2, params };
329
+ }
330
+ async execute() {
331
+ const { sql: updateSql, params } = this.buildUpdateClause();
332
+ if (this.returningColumns.length > 0) {
333
+ const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
334
+ const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
335
+ return this.db.select(sqlWithReturning, params);
336
+ } else {
337
+ const result = await this.db.execute(updateSql, params);
338
+ return [{ rowsAffected: result.rowsAffected }];
339
+ }
340
+ }
341
+ async returningAll() {
342
+ const allColumns = Object.keys(
343
+ this.table._.columns
344
+ );
345
+ return this.returning(...allColumns).execute();
346
+ }
347
+ };
348
+
349
+ // src/builders/insert.ts
350
+ var InsertQueryBuilder = class extends BaseQueryBuilder {
351
+ constructor(db, table) {
352
+ super(db);
353
+ this.table = table;
354
+ this.query = `INSERT INTO ${table._.name}`;
355
+ }
356
+ dataSets = [];
357
+ returningColumns = [];
358
+ onConflictAction = null;
359
+ conflictTarget = [];
360
+ updateSet = {};
361
+ values(data) {
362
+ const dataArray = Array.isArray(data) ? data : [data];
363
+ this.dataSets.push(...dataArray);
364
+ return this;
365
+ }
366
+ returning(...columns) {
367
+ this.returningColumns.push(...columns);
368
+ return this;
369
+ }
370
+ onConflictDoNothing(target) {
371
+ this.onConflictAction = "nothing";
372
+ if (target) {
373
+ this.conflictTarget = Array.isArray(target) ? target : [target];
374
+ }
375
+ return this;
376
+ }
377
+ onConflictDoUpdate(config) {
378
+ this.onConflictAction = "update";
379
+ this.conflictTarget = Array.isArray(config.target) ? config.target : [config.target];
380
+ this.updateSet = config.set;
381
+ return this;
382
+ }
383
+ processDefaultValues(data) {
384
+ const finalData = { ...data };
385
+ for (const [key, column] of Object.entries(this.table._.columns)) {
386
+ const typedKey = key;
387
+ if (finalData[typedKey] === void 0) {
388
+ if (column.options.$defaultFn) {
389
+ finalData[typedKey] = column.options.$defaultFn();
390
+ }
391
+ }
392
+ }
393
+ return finalData;
394
+ }
395
+ buildConflictClause() {
396
+ if (!this.onConflictAction) return "";
397
+ let clause = " ON CONFLICT";
398
+ if (this.conflictTarget.length > 0) {
399
+ const targetNames = this.conflictTarget.map((col) => col._.name).join(", ");
400
+ clause += ` (${targetNames})`;
401
+ }
402
+ if (this.onConflictAction === "nothing") {
403
+ clause += " DO NOTHING";
404
+ } else if (this.onConflictAction === "update") {
405
+ const setEntries = Object.entries(this.updateSet);
406
+ if (setEntries.length > 0) {
407
+ const setClause = setEntries.map(([key]) => `${key} = ?`).join(", ");
408
+ clause += ` DO UPDATE SET ${setClause}`;
409
+ }
410
+ }
411
+ return clause;
412
+ }
413
+ async execute() {
414
+ if (this.dataSets.length === 0) {
415
+ throw new Error("No data provided for insert");
416
+ }
417
+ const processedDataSets = this.dataSets.map(
418
+ (data) => this.processDefaultValues(data)
419
+ );
420
+ const groups = /* @__PURE__ */ new Map();
421
+ for (const dataSet of processedDataSets) {
422
+ const keys = Object.keys(dataSet).sort().join(",");
423
+ if (!groups.has(keys)) {
424
+ groups.set(keys, []);
425
+ }
426
+ groups.get(keys).push(dataSet);
427
+ }
428
+ let results = [];
429
+ let lastInsertId;
430
+ let rowsAffected = 0;
431
+ for (const [_, dataSets] of groups) {
432
+ const columns = Object.keys(dataSets[0]);
433
+ const columnNames = columns.map(
434
+ (key) => this.table._.columns[key]._.name
435
+ );
436
+ const placeholders = `(${columns.map(() => "?").join(", ")})`;
437
+ const valuesSql = dataSets.map(() => placeholders).join(", ");
438
+ const conflictClause = this.buildConflictClause();
439
+ const finalQuery = `${this.query} (${columnNames.join(
440
+ ", "
441
+ )}) VALUES ${valuesSql}${conflictClause}`;
442
+ const params = dataSets.flatMap(
443
+ (data) => columns.map((col) => data[col] ?? null)
444
+ );
445
+ if (this.onConflictAction === "update") {
446
+ const setValues = Object.entries(this.updateSet).map(
447
+ ([, value]) => value
448
+ );
449
+ params.push(...setValues);
450
+ }
451
+ if (this.returningColumns.length > 0) {
452
+ const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
453
+ const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
454
+ const rows = await this.db.select(queryWithReturning, params);
455
+ results = results.concat(rows);
456
+ } else {
457
+ const result = await this.db.execute(finalQuery, params);
458
+ lastInsertId = result.lastInsertId;
459
+ rowsAffected += result.rowsAffected;
460
+ }
461
+ }
462
+ if (this.returningColumns.length > 0) {
463
+ return results;
464
+ }
465
+ return [{ lastInsertId, rowsAffected }];
466
+ }
467
+ async returningAll() {
468
+ const allColumns = Object.keys(
469
+ this.table._.columns
470
+ );
471
+ return this.returning(...allColumns).execute();
472
+ }
473
+ };
474
+
475
+ // src/builders/delete.ts
476
+ var DeleteQueryBuilder = class extends BaseQueryBuilder {
477
+ constructor(db, table) {
478
+ super(db);
479
+ this.table = table;
480
+ this.query = `DELETE FROM ${table._.name}`;
481
+ }
482
+ returningColumns = [];
483
+ returning(...columns) {
484
+ this.returningColumns.push(...columns);
485
+ return this;
486
+ }
487
+ async execute() {
488
+ const { sql: sql2, params } = this.build();
489
+ if (this.returningColumns.length > 0) {
490
+ const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
491
+ const sqlWithReturning = `${sql2} RETURNING ${returningNames}`;
492
+ return this.db.select(sqlWithReturning, params);
493
+ } else {
494
+ const result = await this.db.execute(sql2, params);
495
+ return [{ rowsAffected: result.rowsAffected }];
496
+ }
497
+ }
498
+ async returningAll() {
499
+ const allColumns = Object.keys(
500
+ this.table._.columns
501
+ );
502
+ return this.returning(...allColumns).execute();
503
+ }
504
+ };
505
+
506
+ // src/builders/with.ts
507
+ var WithQueryBuilder = class {
508
+ constructor(db) {
509
+ this.db = db;
510
+ }
511
+ ctes = [];
512
+ with(alias2, query) {
513
+ this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
514
+ return this;
515
+ }
516
+ select(table, columns) {
517
+ const builder = new SelectQueryBuilder(this.db, table, columns);
518
+ this.applyWithClause(builder);
519
+ return builder;
520
+ }
521
+ insert(table) {
522
+ const builder = new InsertQueryBuilder(this.db, table);
523
+ this.applyWithClause(builder);
524
+ return builder;
525
+ }
526
+ update(table) {
527
+ const builder = new UpdateQueryBuilder(this.db, table);
528
+ this.applyWithClause(builder);
529
+ return builder;
530
+ }
531
+ delete(table) {
532
+ const builder = new DeleteQueryBuilder(this.db, table);
533
+ this.applyWithClause(builder);
534
+ return builder;
535
+ }
536
+ applyWithClause(builder) {
537
+ if (this.ctes.length > 0) {
538
+ const cteSql = this.ctes.map((cte) => `${cte.alias} AS (${cte.query})`).join(", ");
539
+ builder["query"] = `WITH ${cteSql} ${builder["query"]}`;
540
+ builder["params"] = [
541
+ ...this.ctes.flatMap((cte) => cte.params),
542
+ ...builder["params"]
543
+ ];
544
+ }
545
+ }
546
+ };
547
+
51
548
  // src/orm.ts
52
549
  var SQLiteColumn = class _SQLiteColumn {
53
550
  constructor(name, type, options = {}, mode) {
@@ -91,7 +588,7 @@ var SQLiteColumn = class _SQLiteColumn {
91
588
  return new _SQLiteColumn(
92
589
  this._.name,
93
590
  this.type,
94
- { ...this.options, primaryKey: true },
591
+ { ...this.options, primaryKey: true, notNull: true },
95
592
  this._.mode
96
593
  );
97
594
  }
@@ -133,14 +630,13 @@ var SQLiteColumn = class _SQLiteColumn {
133
630
  this._.mode
134
631
  );
135
632
  }
633
+ as(alias2) {
634
+ return this;
635
+ }
136
636
  };
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
637
  var Table = class {
143
638
  _;
639
+ relations = {};
144
640
  constructor(name, columns) {
145
641
  this._ = {
146
642
  name,
@@ -151,194 +647,111 @@ var Table = class {
151
647
  var sqliteTable = (tableName, columns) => {
152
648
  return new Table(tableName, columns);
153
649
  };
154
- var eq = (column, value) => ({
155
- sql: `${column._.name} = ?`,
156
- params: [value]
157
- });
158
- var and = (...conditions) => ({
159
- sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
160
- params: conditions.flatMap((c) => c.params)
161
- });
162
- var or = (...conditions) => ({
163
- sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
164
- params: conditions.flatMap((c) => c.params)
165
- });
166
- var gt = (column, value) => ({
167
- sql: `${column._.name} > ?`,
168
- params: [value]
169
- });
170
- var gte = (column, value) => ({
171
- sql: `${column._.name} >= ?`,
172
- params: [value]
173
- });
174
- var lt = (column, value) => ({
175
- sql: `${column._.name} < ?`,
176
- params: [value]
177
- });
178
- var lte = (column, value) => ({
179
- sql: `${column._.name} <= ?`,
180
- params: [value]
181
- });
182
- var like = (column, pattern) => ({
183
- sql: `${column._.name} LIKE ?`,
184
- params: [pattern]
185
- });
186
- var isNull = (column) => ({
187
- sql: `${column._.name} IS NULL`,
650
+ var asc = (column) => ({
651
+ sql: `${column._.name} ASC`,
188
652
  params: []
189
653
  });
190
- var isNotNull = (column) => ({
191
- sql: `${column._.name} IS NOT NULL`,
654
+ var desc = (column) => ({
655
+ sql: `${column._.name} DESC`,
192
656
  params: []
193
657
  });
194
- var inArray = (column, values) => ({
195
- sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
196
- params: values
197
- });
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);
207
- return this;
208
- }
209
- orderBy(column, direction = "ASC") {
210
- this.query += ` ORDER BY ${column._.name} ${direction}`;
211
- return this;
212
- }
213
- limit(count) {
214
- this.query += ` LIMIT ${count}`;
215
- return this;
216
- }
217
- offset(count) {
218
- this.query += ` OFFSET ${count}`;
219
- return this;
220
- }
221
- build() {
222
- return {
223
- sql: this.query,
224
- params: this.params
225
- };
226
- }
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}`;
235
- }
236
- async execute() {
237
- const { sql, params } = this.build();
238
- return this.db.select(sql, params);
239
- }
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);
251
- return this;
252
- }
253
- async execute() {
254
- if (this.dataSets.length === 0) {
255
- throw new Error("No data provided for insert");
658
+ var sql = (strings, ...values) => {
659
+ const queryParts = [];
660
+ const params = [];
661
+ strings.forEach((str, i) => {
662
+ queryParts.push(str);
663
+ if (values[i] !== void 0) {
664
+ if (typeof values[i] === "object" && values[i].sql) {
665
+ queryParts.push(values[i].sql);
666
+ params.push(...values[i].params);
667
+ } else {
668
+ queryParts.push("?");
669
+ params.push(values[i]);
670
+ }
256
671
  }
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;
271
- }
272
- };
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;
283
- }
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;
299
- }
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}`;
306
- }
307
- async execute() {
308
- const { sql, params } = this.build();
309
- const result = await this.db.execute(sql, params);
310
- return result.rowsAffected;
311
- }
672
+ });
673
+ return {
674
+ sql: queryParts.join(""),
675
+ params
676
+ };
312
677
  };
313
678
  var TauriORM = class {
314
679
  constructor(db, schema = void 0) {
315
680
  this.db = db;
316
681
  if (schema) {
317
- for (const table of Object.values(schema)) {
318
- this.tables.set(table._.name, table);
682
+ for (const [key, value] of Object.entries(schema)) {
683
+ if (value instanceof Table) {
684
+ this.tables.set(value._.name, value);
685
+ }
686
+ }
687
+ for (const [key, value] of Object.entries(schema)) {
688
+ if (!(value instanceof Table) && typeof value === "object") {
689
+ const tableName = key.replace("Relations", "");
690
+ const table = Array.from(this.tables.values()).find(
691
+ (t) => t._.name === tableName
692
+ );
693
+ if (table) {
694
+ for (const [relName, rel] of Object.entries(value)) {
695
+ if (rel instanceof OneRelation) {
696
+ table.relations[relName] = {
697
+ type: "one",
698
+ foreignTable: rel.foreignTable,
699
+ fields: rel.config?.fields,
700
+ references: rel.config?.references
701
+ };
702
+ } else if (rel instanceof ManyRelation) {
703
+ table.relations[relName] = {
704
+ type: "many",
705
+ foreignTable: rel.foreignTable
706
+ };
707
+ }
708
+ }
709
+ }
710
+ }
319
711
  }
320
712
  }
321
713
  }
322
714
  tables = /* @__PURE__ */ new Map();
715
+ buildColumnDefinition(col, forAlterTable = false) {
716
+ let sql2 = `${col._.name} ${col.type}`;
717
+ if (col.options.primaryKey && !forAlterTable) {
718
+ sql2 += " PRIMARY KEY";
719
+ if (col._.autoincrement) {
720
+ sql2 += " AUTOINCREMENT";
721
+ }
722
+ }
723
+ if (col._.notNull) sql2 += " NOT NULL";
724
+ if (col.options.unique) sql2 += " UNIQUE";
725
+ if (col.options.default !== void 0) {
726
+ const value = col.options.default;
727
+ sql2 += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
728
+ }
729
+ if (col.options.references) {
730
+ sql2 += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
731
+ }
732
+ return sql2;
733
+ }
323
734
  async migrate() {
324
735
  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}`;
334
- }
335
- if (col.options.references) {
336
- sql += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
736
+ const existingTableInfo = await this.db.select(
737
+ `PRAGMA table_info('${table._.name}')`
738
+ );
739
+ if (existingTableInfo.length === 0) {
740
+ const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
741
+ const createSql = `CREATE TABLE ${table._.name} (${columnsSql})`;
742
+ await this.db.execute(createSql);
743
+ } else {
744
+ const existingColumnNames = new Set(
745
+ existingTableInfo.map((c) => c.name)
746
+ );
747
+ for (const column of Object.values(table._.columns)) {
748
+ if (!existingColumnNames.has(column._.name)) {
749
+ const columnSql = this.buildColumnDefinition(column, true);
750
+ const alterSql = `ALTER TABLE ${table._.name} ADD COLUMN ${columnSql}`;
751
+ await this.db.execute(alterSql);
752
+ }
337
753
  }
338
- return sql;
339
- }).join(", ");
340
- const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
341
- await this.db.execute(createSql);
754
+ }
342
755
  }
343
756
  }
344
757
  select(table, columns) {
@@ -353,6 +766,15 @@ var TauriORM = class {
353
766
  delete(table) {
354
767
  return new DeleteQueryBuilder(this.db, table);
355
768
  }
769
+ $with(alias2) {
770
+ const withBuilder = new WithQueryBuilder(this.db);
771
+ return {
772
+ as: (query) => {
773
+ withBuilder.with(alias2, query);
774
+ return withBuilder;
775
+ }
776
+ };
777
+ }
356
778
  async transaction(callback) {
357
779
  await this.db.execute("BEGIN TRANSACTION");
358
780
  try {
@@ -364,6 +786,9 @@ var TauriORM = class {
364
786
  throw error;
365
787
  }
366
788
  }
789
+ rollback() {
790
+ throw new Error("Transaction rolled back");
791
+ }
367
792
  // --- Schema detection / signature ---
368
793
  async ensureSchemaMeta() {
369
794
  await this.db.execute(
@@ -392,7 +817,10 @@ var TauriORM = class {
392
817
  pk: !!col.options.primaryKey,
393
818
  ai: !!col._.autoincrement,
394
819
  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
820
+ unique: !!col.options.unique,
821
+ dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null,
822
+ hasDefaultFn: col.options.$defaultFn !== void 0,
823
+ hasOnUpdateFn: col.options.$onUpdateFn !== void 0
396
824
  };
397
825
  }
398
826
  computeModelSignature() {
@@ -424,33 +852,71 @@ var TauriORM = class {
424
852
  return false;
425
853
  }
426
854
  };
427
- var relations = (table, relationsCallback) => {
855
+ var Relation = class {
856
+ constructor(foreignTable) {
857
+ this.foreignTable = foreignTable;
858
+ }
859
+ };
860
+ var OneRelation = class extends Relation {
861
+ constructor(foreignTable, config) {
862
+ super(foreignTable);
863
+ this.config = config;
864
+ }
865
+ };
866
+ var ManyRelation = class extends Relation {
867
+ constructor(foreignTable) {
868
+ super(foreignTable);
869
+ }
870
+ };
871
+ var relations = (_table, relationsCallback) => {
428
872
  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
- })
873
+ one: (table, config) => {
874
+ return new OneRelation(table, config);
875
+ },
876
+ many: (table) => {
877
+ return new ManyRelation(table);
878
+ }
439
879
  });
440
880
  };
881
+ var getTableColumns = (table) => {
882
+ return table._.columns;
883
+ };
884
+ var alias = (table, alias2) => {
885
+ return table;
886
+ };
887
+
888
+ // src/column-helpers.ts
889
+ var columnHelpers = (name) => new SQLiteColumn(name, "TEXT");
890
+ var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
891
+ var real = (name) => new SQLiteColumn(name, "REAL");
892
+ var blob = (name) => new SQLiteColumn(name, "BLOB");
893
+ var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
441
894
  // Annotate the CommonJS export names for ESM import in node:
442
895
  0 && (module.exports = {
896
+ BaseQueryBuilder,
443
897
  DeleteQueryBuilder,
444
898
  InsertQueryBuilder,
899
+ ManyRelation,
900
+ OneRelation,
901
+ Relation,
445
902
  SQLiteColumn,
446
903
  SelectQueryBuilder,
447
904
  Table,
448
905
  TauriORM,
449
906
  UpdateQueryBuilder,
907
+ WithQueryBuilder,
908
+ alias,
450
909
  and,
910
+ asc,
911
+ avg,
451
912
  blob,
452
913
  boolean,
914
+ columnHelpers,
915
+ count,
916
+ countDistinct,
917
+ desc,
453
918
  eq,
919
+ getTableColumns,
454
920
  gt,
455
921
  gte,
456
922
  inArray,
@@ -460,9 +926,13 @@ var relations = (table, relationsCallback) => {
460
926
  like,
461
927
  lt,
462
928
  lte,
929
+ max,
930
+ min,
931
+ not,
463
932
  or,
464
933
  real,
465
934
  relations,
935
+ sql,
466
936
  sqliteTable,
467
- text
937
+ sum
468
938
  });