@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.mjs CHANGED
@@ -1,3 +1,483 @@
1
+ // src/builders/query-base.ts
2
+ var BaseQueryBuilder = class {
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ query = "";
7
+ params = [];
8
+ where(condition) {
9
+ this.query += ` WHERE ${condition.sql}`;
10
+ this.params.push(...condition.params);
11
+ return this;
12
+ }
13
+ orderBy(column, direction = "ASC") {
14
+ if ("sql" in column) {
15
+ this.query += ` ORDER BY ${column.sql} ${direction}`;
16
+ this.params.push(...column.params);
17
+ } else {
18
+ this.query += ` ORDER BY ${column._.name} ${direction}`;
19
+ }
20
+ return this;
21
+ }
22
+ limit(count2) {
23
+ this.query += ` LIMIT ${count2}`;
24
+ return this;
25
+ }
26
+ offset(count2) {
27
+ this.query += ` OFFSET ${count2}`;
28
+ return this;
29
+ }
30
+ build() {
31
+ return {
32
+ sql: this.query,
33
+ params: this.params
34
+ };
35
+ }
36
+ };
37
+
38
+ // src/operators.ts
39
+ var eq = (column, value) => ({
40
+ sql: `${column._.name} = ?`,
41
+ params: [value]
42
+ });
43
+ var and = (...conditions) => ({
44
+ sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
45
+ params: conditions.flatMap((c) => c.params)
46
+ });
47
+ var or = (...conditions) => ({
48
+ sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
49
+ params: conditions.flatMap((c) => c.params)
50
+ });
51
+ var not = (condition) => ({
52
+ sql: `NOT (${condition.sql})`,
53
+ params: condition.params
54
+ });
55
+ var gt = (column, value) => ({
56
+ sql: `${column._.name} > ?`,
57
+ params: [value]
58
+ });
59
+ var gte = (column, value) => ({
60
+ sql: `${column._.name} >= ?`,
61
+ params: [value]
62
+ });
63
+ var lt = (column, value) => ({
64
+ sql: `${column._.name} < ?`,
65
+ params: [value]
66
+ });
67
+ var lte = (column, value) => ({
68
+ sql: `${column._.name} <= ?`,
69
+ params: [value]
70
+ });
71
+ var like = (column, pattern) => ({
72
+ sql: `${column._.name} LIKE ?`,
73
+ params: [pattern]
74
+ });
75
+ var isNull = (column) => ({
76
+ sql: `${column._.name} IS NULL`,
77
+ params: []
78
+ });
79
+ var isNotNull = (column) => ({
80
+ sql: `${column._.name} IS NOT NULL`,
81
+ params: []
82
+ });
83
+ var inArray = (column, values) => ({
84
+ sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
85
+ params: values
86
+ });
87
+ var count = (column) => ({
88
+ sql: `COUNT(${column ? column._.name : "*"})`,
89
+ params: []
90
+ });
91
+ var countDistinct = (column) => ({
92
+ sql: `COUNT(DISTINCT ${column._.name})`,
93
+ params: []
94
+ });
95
+ var sum = (column) => ({
96
+ sql: `SUM(${column._.name})`,
97
+ params: []
98
+ });
99
+ var avg = (column) => ({
100
+ sql: `AVG(${column._.name})`,
101
+ params: []
102
+ });
103
+ var max = (column) => ({
104
+ sql: `MAX(${column._.name})`,
105
+ params: []
106
+ });
107
+ var min = (column) => ({
108
+ sql: `MIN(${column._.name})`,
109
+ params: []
110
+ });
111
+
112
+ // src/builders/select.ts
113
+ var SelectQueryBuilder = class extends BaseQueryBuilder {
114
+ constructor(db, table, columns) {
115
+ super(db);
116
+ this.table = table;
117
+ this.columns = columns;
118
+ const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
119
+ this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
120
+ }
121
+ isDistinct = false;
122
+ groupByColumns = [];
123
+ havingCondition = null;
124
+ joins = [];
125
+ includeRelations = {};
126
+ distinct() {
127
+ this.isDistinct = true;
128
+ this.query = this.query.replace("SELECT", "SELECT DISTINCT");
129
+ return this;
130
+ }
131
+ groupBy(...columns) {
132
+ this.groupByColumns.push(...columns);
133
+ const columnNames = columns.map((col) => col._.name).join(", ");
134
+ this.query += ` GROUP BY ${columnNames}`;
135
+ return this;
136
+ }
137
+ having(condition) {
138
+ this.havingCondition = condition;
139
+ this.query += ` HAVING ${condition.sql}`;
140
+ this.params.push(...condition.params);
141
+ return this;
142
+ }
143
+ leftJoin(table, condition, alias2) {
144
+ this.joins.push({ type: "LEFT", table, condition, alias: alias2 });
145
+ return this;
146
+ }
147
+ innerJoin(table, condition, alias2) {
148
+ this.joins.push({ type: "INNER", table, condition, alias: alias2 });
149
+ return this;
150
+ }
151
+ include(relations2) {
152
+ this.includeRelations = { ...this.includeRelations, ...relations2 };
153
+ return this;
154
+ }
155
+ buildJoins() {
156
+ let sql2 = "";
157
+ const params = [];
158
+ for (const join of this.joins) {
159
+ const tableAlias = join.alias || join.table._.name;
160
+ sql2 += ` ${join.type} JOIN ${join.table._.name} ${tableAlias} ON ${join.condition.sql}`;
161
+ params.push(...join.condition.params);
162
+ }
163
+ for (const [relationName, include] of Object.entries(
164
+ this.includeRelations
165
+ )) {
166
+ if (!include) continue;
167
+ const relation = this.table.relations[relationName];
168
+ if (!relation) continue;
169
+ const foreignTable = relation.foreignTable;
170
+ const foreignAlias = `${this.table._.name}_${relationName}`;
171
+ if (relation.type === "one" && relation.fields && relation.references) {
172
+ const conditions = relation.fields.map(
173
+ (field, i) => eq(field, relation.references[i])
174
+ );
175
+ const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
176
+ sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
177
+ params.push(...condition.params);
178
+ } else if (relation.type === "many") {
179
+ const refRelation = Object.values(foreignTable.relations).find(
180
+ (r) => r.foreignTable === this.table
181
+ );
182
+ if (refRelation && refRelation.fields && refRelation.references) {
183
+ const conditions = refRelation.fields.map(
184
+ (field, i) => eq(field, refRelation.references[i])
185
+ );
186
+ const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
187
+ sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
188
+ params.push(...condition.params);
189
+ }
190
+ }
191
+ }
192
+ return { sql: sql2, params };
193
+ }
194
+ async execute() {
195
+ const { sql: joinSql, params: joinParams } = this.buildJoins();
196
+ this.query += joinSql;
197
+ this.params.push(...joinParams);
198
+ const { sql: sql2, params } = this.build();
199
+ return this.db.select(sql2, params);
200
+ }
201
+ async all() {
202
+ return this.execute();
203
+ }
204
+ async get() {
205
+ this.limit(1);
206
+ const result = await this.execute();
207
+ return result[0];
208
+ }
209
+ };
210
+
211
+ // src/builders/update.ts
212
+ var UpdateQueryBuilder = class extends BaseQueryBuilder {
213
+ constructor(db, table) {
214
+ super(db);
215
+ this.table = table;
216
+ this.query = `UPDATE ${table._.name}`;
217
+ }
218
+ updateData = {};
219
+ returningColumns = [];
220
+ set(data) {
221
+ this.updateData = { ...this.updateData, ...data };
222
+ return this;
223
+ }
224
+ returning(...columns) {
225
+ this.returningColumns.push(...columns);
226
+ return this;
227
+ }
228
+ buildUpdateClause() {
229
+ const finalUpdateData = { ...this.updateData };
230
+ for (const [key, column] of Object.entries(this.table._.columns)) {
231
+ const typedKey = key;
232
+ if (finalUpdateData[typedKey] === void 0 && column.options.$onUpdateFn) {
233
+ finalUpdateData[typedKey] = column.options.$onUpdateFn();
234
+ }
235
+ }
236
+ const baseQuery = this.query;
237
+ const whereParams = this.params;
238
+ let tablePart = baseQuery;
239
+ let whereClause = "";
240
+ const whereIndex = baseQuery.indexOf(" WHERE ");
241
+ if (whereIndex !== -1) {
242
+ tablePart = baseQuery.substring(0, whereIndex);
243
+ whereClause = baseQuery.substring(whereIndex);
244
+ }
245
+ const entries = Object.entries(finalUpdateData);
246
+ if (entries.length === 0) {
247
+ throw new Error("Cannot execute an update query without a .set() call.");
248
+ }
249
+ const setClause = entries.map(([key]) => {
250
+ const column = this.table._.columns[key];
251
+ if (!column) {
252
+ throw new Error(
253
+ `Column ${key} does not exist on table ${this.table._.name}`
254
+ );
255
+ }
256
+ return `${column._.name} = ?`;
257
+ }).join(", ");
258
+ const setParams = entries.map(([, value]) => value);
259
+ const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
260
+ const params = [...setParams, ...whereParams];
261
+ return { sql: sql2, params };
262
+ }
263
+ async execute() {
264
+ const { sql: updateSql, params } = this.buildUpdateClause();
265
+ if (this.returningColumns.length > 0) {
266
+ const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
267
+ const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
268
+ return this.db.select(sqlWithReturning, params);
269
+ } else {
270
+ const result = await this.db.execute(updateSql, params);
271
+ return [{ rowsAffected: result.rowsAffected }];
272
+ }
273
+ }
274
+ async returningAll() {
275
+ const allColumns = Object.keys(
276
+ this.table._.columns
277
+ );
278
+ return this.returning(...allColumns).execute();
279
+ }
280
+ };
281
+
282
+ // src/builders/insert.ts
283
+ var InsertQueryBuilder = class extends BaseQueryBuilder {
284
+ constructor(db, table) {
285
+ super(db);
286
+ this.table = table;
287
+ this.query = `INSERT INTO ${table._.name}`;
288
+ }
289
+ dataSets = [];
290
+ returningColumns = [];
291
+ onConflictAction = null;
292
+ conflictTarget = [];
293
+ updateSet = {};
294
+ values(data) {
295
+ const dataArray = Array.isArray(data) ? data : [data];
296
+ this.dataSets.push(...dataArray);
297
+ return this;
298
+ }
299
+ returning(...columns) {
300
+ this.returningColumns.push(...columns);
301
+ return this;
302
+ }
303
+ onConflictDoNothing(target) {
304
+ this.onConflictAction = "nothing";
305
+ if (target) {
306
+ this.conflictTarget = Array.isArray(target) ? target : [target];
307
+ }
308
+ return this;
309
+ }
310
+ onConflictDoUpdate(config) {
311
+ this.onConflictAction = "update";
312
+ this.conflictTarget = Array.isArray(config.target) ? config.target : [config.target];
313
+ this.updateSet = config.set;
314
+ return this;
315
+ }
316
+ processDefaultValues(data) {
317
+ const finalData = { ...data };
318
+ for (const [key, column] of Object.entries(this.table._.columns)) {
319
+ const typedKey = key;
320
+ if (finalData[typedKey] === void 0) {
321
+ if (column.options.$defaultFn) {
322
+ finalData[typedKey] = column.options.$defaultFn();
323
+ }
324
+ }
325
+ }
326
+ return finalData;
327
+ }
328
+ buildConflictClause() {
329
+ if (!this.onConflictAction) return "";
330
+ let clause = " ON CONFLICT";
331
+ if (this.conflictTarget.length > 0) {
332
+ const targetNames = this.conflictTarget.map((col) => col._.name).join(", ");
333
+ clause += ` (${targetNames})`;
334
+ }
335
+ if (this.onConflictAction === "nothing") {
336
+ clause += " DO NOTHING";
337
+ } else if (this.onConflictAction === "update") {
338
+ const setEntries = Object.entries(this.updateSet);
339
+ if (setEntries.length > 0) {
340
+ const setClause = setEntries.map(([key]) => `${key} = ?`).join(", ");
341
+ clause += ` DO UPDATE SET ${setClause}`;
342
+ }
343
+ }
344
+ return clause;
345
+ }
346
+ async execute() {
347
+ if (this.dataSets.length === 0) {
348
+ throw new Error("No data provided for insert");
349
+ }
350
+ const processedDataSets = this.dataSets.map(
351
+ (data) => this.processDefaultValues(data)
352
+ );
353
+ const groups = /* @__PURE__ */ new Map();
354
+ for (const dataSet of processedDataSets) {
355
+ const keys = Object.keys(dataSet).sort().join(",");
356
+ if (!groups.has(keys)) {
357
+ groups.set(keys, []);
358
+ }
359
+ groups.get(keys).push(dataSet);
360
+ }
361
+ let results = [];
362
+ let lastInsertId;
363
+ let rowsAffected = 0;
364
+ for (const [_, dataSets] of groups) {
365
+ const columns = Object.keys(dataSets[0]);
366
+ const columnNames = columns.map(
367
+ (key) => this.table._.columns[key]._.name
368
+ );
369
+ const placeholders = `(${columns.map(() => "?").join(", ")})`;
370
+ const valuesSql = dataSets.map(() => placeholders).join(", ");
371
+ const conflictClause = this.buildConflictClause();
372
+ const finalQuery = `${this.query} (${columnNames.join(
373
+ ", "
374
+ )}) VALUES ${valuesSql}${conflictClause}`;
375
+ const params = dataSets.flatMap(
376
+ (data) => columns.map((col) => data[col] ?? null)
377
+ );
378
+ if (this.onConflictAction === "update") {
379
+ const setValues = Object.entries(this.updateSet).map(
380
+ ([, value]) => value
381
+ );
382
+ params.push(...setValues);
383
+ }
384
+ if (this.returningColumns.length > 0) {
385
+ const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
386
+ const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
387
+ const rows = await this.db.select(queryWithReturning, params);
388
+ results = results.concat(rows);
389
+ } else {
390
+ const result = await this.db.execute(finalQuery, params);
391
+ lastInsertId = result.lastInsertId;
392
+ rowsAffected += result.rowsAffected;
393
+ }
394
+ }
395
+ if (this.returningColumns.length > 0) {
396
+ return results;
397
+ }
398
+ return [{ lastInsertId, rowsAffected }];
399
+ }
400
+ async returningAll() {
401
+ const allColumns = Object.keys(
402
+ this.table._.columns
403
+ );
404
+ return this.returning(...allColumns).execute();
405
+ }
406
+ };
407
+
408
+ // src/builders/delete.ts
409
+ var DeleteQueryBuilder = class extends BaseQueryBuilder {
410
+ constructor(db, table) {
411
+ super(db);
412
+ this.table = table;
413
+ this.query = `DELETE FROM ${table._.name}`;
414
+ }
415
+ returningColumns = [];
416
+ returning(...columns) {
417
+ this.returningColumns.push(...columns);
418
+ return this;
419
+ }
420
+ async execute() {
421
+ const { sql: sql2, params } = this.build();
422
+ if (this.returningColumns.length > 0) {
423
+ const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
424
+ const sqlWithReturning = `${sql2} RETURNING ${returningNames}`;
425
+ return this.db.select(sqlWithReturning, params);
426
+ } else {
427
+ const result = await this.db.execute(sql2, params);
428
+ return [{ rowsAffected: result.rowsAffected }];
429
+ }
430
+ }
431
+ async returningAll() {
432
+ const allColumns = Object.keys(
433
+ this.table._.columns
434
+ );
435
+ return this.returning(...allColumns).execute();
436
+ }
437
+ };
438
+
439
+ // src/builders/with.ts
440
+ var WithQueryBuilder = class {
441
+ constructor(db) {
442
+ this.db = db;
443
+ }
444
+ ctes = [];
445
+ with(alias2, query) {
446
+ this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
447
+ return this;
448
+ }
449
+ select(table, columns) {
450
+ const builder = new SelectQueryBuilder(this.db, table, columns);
451
+ this.applyWithClause(builder);
452
+ return builder;
453
+ }
454
+ insert(table) {
455
+ const builder = new InsertQueryBuilder(this.db, table);
456
+ this.applyWithClause(builder);
457
+ return builder;
458
+ }
459
+ update(table) {
460
+ const builder = new UpdateQueryBuilder(this.db, table);
461
+ this.applyWithClause(builder);
462
+ return builder;
463
+ }
464
+ delete(table) {
465
+ const builder = new DeleteQueryBuilder(this.db, table);
466
+ this.applyWithClause(builder);
467
+ return builder;
468
+ }
469
+ applyWithClause(builder) {
470
+ if (this.ctes.length > 0) {
471
+ const cteSql = this.ctes.map((cte) => `${cte.alias} AS (${cte.query})`).join(", ");
472
+ builder["query"] = `WITH ${cteSql} ${builder["query"]}`;
473
+ builder["params"] = [
474
+ ...this.ctes.flatMap((cte) => cte.params),
475
+ ...builder["params"]
476
+ ];
477
+ }
478
+ }
479
+ };
480
+
1
481
  // src/orm.ts
2
482
  var SQLiteColumn = class _SQLiteColumn {
3
483
  constructor(name, type, options = {}, mode) {
@@ -41,7 +521,7 @@ var SQLiteColumn = class _SQLiteColumn {
41
521
  return new _SQLiteColumn(
42
522
  this._.name,
43
523
  this.type,
44
- { ...this.options, primaryKey: true },
524
+ { ...this.options, primaryKey: true, notNull: true },
45
525
  this._.mode
46
526
  );
47
527
  }
@@ -83,14 +563,13 @@ var SQLiteColumn = class _SQLiteColumn {
83
563
  this._.mode
84
564
  );
85
565
  }
566
+ as(alias2) {
567
+ return this;
568
+ }
86
569
  };
87
- var text = (name) => new SQLiteColumn(name, "TEXT");
88
- var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
89
- var real = (name) => new SQLiteColumn(name, "REAL");
90
- var blob = (name) => new SQLiteColumn(name, "BLOB");
91
- var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
92
570
  var Table = class {
93
571
  _;
572
+ relations = {};
94
573
  constructor(name, columns) {
95
574
  this._ = {
96
575
  name,
@@ -101,194 +580,111 @@ var Table = class {
101
580
  var sqliteTable = (tableName, columns) => {
102
581
  return new Table(tableName, columns);
103
582
  };
104
- var eq = (column, value) => ({
105
- sql: `${column._.name} = ?`,
106
- params: [value]
107
- });
108
- var and = (...conditions) => ({
109
- sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
110
- params: conditions.flatMap((c) => c.params)
111
- });
112
- var or = (...conditions) => ({
113
- sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
114
- params: conditions.flatMap((c) => c.params)
115
- });
116
- var gt = (column, value) => ({
117
- sql: `${column._.name} > ?`,
118
- params: [value]
119
- });
120
- var gte = (column, value) => ({
121
- sql: `${column._.name} >= ?`,
122
- params: [value]
123
- });
124
- var lt = (column, value) => ({
125
- sql: `${column._.name} < ?`,
126
- params: [value]
127
- });
128
- var lte = (column, value) => ({
129
- sql: `${column._.name} <= ?`,
130
- params: [value]
131
- });
132
- var like = (column, pattern) => ({
133
- sql: `${column._.name} LIKE ?`,
134
- params: [pattern]
135
- });
136
- var isNull = (column) => ({
137
- sql: `${column._.name} IS NULL`,
583
+ var asc = (column) => ({
584
+ sql: `${column._.name} ASC`,
138
585
  params: []
139
586
  });
140
- var isNotNull = (column) => ({
141
- sql: `${column._.name} IS NOT NULL`,
587
+ var desc = (column) => ({
588
+ sql: `${column._.name} DESC`,
142
589
  params: []
143
590
  });
144
- var inArray = (column, values) => ({
145
- sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
146
- params: values
147
- });
148
- var BaseQueryBuilder = class {
149
- constructor(db) {
150
- this.db = db;
151
- }
152
- query = "";
153
- params = [];
154
- where(condition) {
155
- this.query += ` WHERE ${condition.sql}`;
156
- this.params.push(...condition.params);
157
- return this;
158
- }
159
- orderBy(column, direction = "ASC") {
160
- this.query += ` ORDER BY ${column._.name} ${direction}`;
161
- return this;
162
- }
163
- limit(count) {
164
- this.query += ` LIMIT ${count}`;
165
- return this;
166
- }
167
- offset(count) {
168
- this.query += ` OFFSET ${count}`;
169
- return this;
170
- }
171
- build() {
172
- return {
173
- sql: this.query,
174
- params: this.params
175
- };
176
- }
177
- };
178
- var SelectQueryBuilder = class extends BaseQueryBuilder {
179
- constructor(db, table, columns) {
180
- super(db);
181
- this.table = table;
182
- this.columns = columns;
183
- const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
184
- this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
185
- }
186
- async execute() {
187
- const { sql, params } = this.build();
188
- return this.db.select(sql, params);
189
- }
190
- };
191
- var InsertQueryBuilder = class extends BaseQueryBuilder {
192
- constructor(db, table) {
193
- super(db);
194
- this.table = table;
195
- this.query = `INSERT INTO ${table._.name}`;
196
- }
197
- dataSets = [];
198
- values(data) {
199
- const dataArray = Array.isArray(data) ? data : [data];
200
- this.dataSets.push(...dataArray);
201
- return this;
202
- }
203
- async execute() {
204
- if (this.dataSets.length === 0) {
205
- throw new Error("No data provided for insert");
591
+ var sql = (strings, ...values) => {
592
+ const queryParts = [];
593
+ const params = [];
594
+ strings.forEach((str, i) => {
595
+ queryParts.push(str);
596
+ if (values[i] !== void 0) {
597
+ if (typeof values[i] === "object" && values[i].sql) {
598
+ queryParts.push(values[i].sql);
599
+ params.push(...values[i].params);
600
+ } else {
601
+ queryParts.push("?");
602
+ params.push(values[i]);
603
+ }
206
604
  }
207
- const columns = Object.keys(
208
- this.dataSets[0]
209
- );
210
- const columnNames = columns.map(
211
- (c) => this.table._.columns[c]._.name
212
- );
213
- const placeholders = `(${columnNames.map(() => "?").join(", ")})`;
214
- const valuesSql = this.dataSets.map(() => placeholders).join(", ");
215
- this.query += ` (${columnNames.join(", ")}) VALUES ${valuesSql}`;
216
- const params = this.dataSets.flatMap(
217
- (data) => columns.map((col) => data[col])
218
- );
219
- const result = await this.db.execute(this.query, params);
220
- return result.lastInsertId ?? 0;
221
- }
222
- };
223
- var UpdateQueryBuilder = class extends BaseQueryBuilder {
224
- constructor(db, table) {
225
- super(db);
226
- this.table = table;
227
- this.query = `UPDATE ${table._.name}`;
228
- }
229
- updateData = {};
230
- set(data) {
231
- this.updateData = { ...this.updateData, ...data };
232
- return this;
233
- }
234
- async execute() {
235
- const entries = Object.entries(this.updateData);
236
- const setClause = entries.map(([key]) => {
237
- const column = this.table._.columns[key];
238
- if (!column)
239
- throw new Error(
240
- `Column ${key} does not exist on table ${this.table._.name}`
241
- );
242
- return `${column._.name} = ?`;
243
- }).join(", ");
244
- this.query += ` SET ${setClause}`;
245
- this.params.push(...entries.map(([, value]) => value));
246
- const { sql, params } = this.build();
247
- const result = await this.db.execute(sql, params);
248
- return result.rowsAffected;
249
- }
250
- };
251
- var DeleteQueryBuilder = class extends BaseQueryBuilder {
252
- constructor(db, table) {
253
- super(db);
254
- this.table = table;
255
- this.query = `DELETE FROM ${table._.name}`;
256
- }
257
- async execute() {
258
- const { sql, params } = this.build();
259
- const result = await this.db.execute(sql, params);
260
- return result.rowsAffected;
261
- }
605
+ });
606
+ return {
607
+ sql: queryParts.join(""),
608
+ params
609
+ };
262
610
  };
263
611
  var TauriORM = class {
264
612
  constructor(db, schema = void 0) {
265
613
  this.db = db;
266
614
  if (schema) {
267
- for (const table of Object.values(schema)) {
268
- this.tables.set(table._.name, table);
615
+ for (const [key, value] of Object.entries(schema)) {
616
+ if (value instanceof Table) {
617
+ this.tables.set(value._.name, value);
618
+ }
619
+ }
620
+ for (const [key, value] of Object.entries(schema)) {
621
+ if (!(value instanceof Table) && typeof value === "object") {
622
+ const tableName = key.replace("Relations", "");
623
+ const table = Array.from(this.tables.values()).find(
624
+ (t) => t._.name === tableName
625
+ );
626
+ if (table) {
627
+ for (const [relName, rel] of Object.entries(value)) {
628
+ if (rel instanceof OneRelation) {
629
+ table.relations[relName] = {
630
+ type: "one",
631
+ foreignTable: rel.foreignTable,
632
+ fields: rel.config?.fields,
633
+ references: rel.config?.references
634
+ };
635
+ } else if (rel instanceof ManyRelation) {
636
+ table.relations[relName] = {
637
+ type: "many",
638
+ foreignTable: rel.foreignTable
639
+ };
640
+ }
641
+ }
642
+ }
643
+ }
269
644
  }
270
645
  }
271
646
  }
272
647
  tables = /* @__PURE__ */ new Map();
648
+ buildColumnDefinition(col, forAlterTable = false) {
649
+ let sql2 = `${col._.name} ${col.type}`;
650
+ if (col.options.primaryKey && !forAlterTable) {
651
+ sql2 += " PRIMARY KEY";
652
+ if (col._.autoincrement) {
653
+ sql2 += " AUTOINCREMENT";
654
+ }
655
+ }
656
+ if (col._.notNull) sql2 += " NOT NULL";
657
+ if (col.options.unique) sql2 += " UNIQUE";
658
+ if (col.options.default !== void 0) {
659
+ const value = col.options.default;
660
+ sql2 += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
661
+ }
662
+ if (col.options.references) {
663
+ sql2 += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
664
+ }
665
+ return sql2;
666
+ }
273
667
  async migrate() {
274
668
  for (const table of this.tables.values()) {
275
- const columnsSql = Object.entries(table._.columns).map(([name, col]) => {
276
- let sql = `${col._.name} ${col.type}`;
277
- if (col.options.primaryKey) sql += " PRIMARY KEY";
278
- if (col._.autoincrement) sql += " AUTOINCREMENT";
279
- if (col._.notNull) sql += " NOT NULL";
280
- if (col.options.unique) sql += " UNIQUE";
281
- if (col.options.default !== void 0) {
282
- const value = col.options.default;
283
- sql += ` DEFAULT ${typeof value === "string" ? `'${value}'` : value}`;
284
- }
285
- if (col.options.references) {
286
- sql += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
669
+ const existingTableInfo = await this.db.select(
670
+ `PRAGMA table_info('${table._.name}')`
671
+ );
672
+ if (existingTableInfo.length === 0) {
673
+ const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
674
+ const createSql = `CREATE TABLE ${table._.name} (${columnsSql})`;
675
+ await this.db.execute(createSql);
676
+ } else {
677
+ const existingColumnNames = new Set(
678
+ existingTableInfo.map((c) => c.name)
679
+ );
680
+ for (const column of Object.values(table._.columns)) {
681
+ if (!existingColumnNames.has(column._.name)) {
682
+ const columnSql = this.buildColumnDefinition(column, true);
683
+ const alterSql = `ALTER TABLE ${table._.name} ADD COLUMN ${columnSql}`;
684
+ await this.db.execute(alterSql);
685
+ }
287
686
  }
288
- return sql;
289
- }).join(", ");
290
- const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
291
- await this.db.execute(createSql);
687
+ }
292
688
  }
293
689
  }
294
690
  select(table, columns) {
@@ -303,6 +699,15 @@ var TauriORM = class {
303
699
  delete(table) {
304
700
  return new DeleteQueryBuilder(this.db, table);
305
701
  }
702
+ $with(alias2) {
703
+ const withBuilder = new WithQueryBuilder(this.db);
704
+ return {
705
+ as: (query) => {
706
+ withBuilder.with(alias2, query);
707
+ return withBuilder;
708
+ }
709
+ };
710
+ }
306
711
  async transaction(callback) {
307
712
  await this.db.execute("BEGIN TRANSACTION");
308
713
  try {
@@ -314,6 +719,9 @@ var TauriORM = class {
314
719
  throw error;
315
720
  }
316
721
  }
722
+ rollback() {
723
+ throw new Error("Transaction rolled back");
724
+ }
317
725
  // --- Schema detection / signature ---
318
726
  async ensureSchemaMeta() {
319
727
  await this.db.execute(
@@ -342,7 +750,10 @@ var TauriORM = class {
342
750
  pk: !!col.options.primaryKey,
343
751
  ai: !!col._.autoincrement,
344
752
  nn: !!col._.notNull,
345
- dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null
753
+ unique: !!col.options.unique,
754
+ dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null,
755
+ hasDefaultFn: col.options.$defaultFn !== void 0,
756
+ hasOnUpdateFn: col.options.$onUpdateFn !== void 0
346
757
  };
347
758
  }
348
759
  computeModelSignature() {
@@ -374,32 +785,70 @@ var TauriORM = class {
374
785
  return false;
375
786
  }
376
787
  };
377
- var relations = (table, relationsCallback) => {
788
+ var Relation = class {
789
+ constructor(foreignTable) {
790
+ this.foreignTable = foreignTable;
791
+ }
792
+ };
793
+ var OneRelation = class extends Relation {
794
+ constructor(foreignTable, config) {
795
+ super(foreignTable);
796
+ this.config = config;
797
+ }
798
+ };
799
+ var ManyRelation = class extends Relation {
800
+ constructor(foreignTable) {
801
+ super(foreignTable);
802
+ }
803
+ };
804
+ var relations = (_table, relationsCallback) => {
378
805
  return relationsCallback({
379
- one: (table2, config) => ({
380
- table: table2,
381
- type: "one",
382
- foreignKey: config.fields[0],
383
- localKey: config.references[0]
384
- }),
385
- many: (table2) => ({
386
- table: table2,
387
- type: "many"
388
- })
806
+ one: (table, config) => {
807
+ return new OneRelation(table, config);
808
+ },
809
+ many: (table) => {
810
+ return new ManyRelation(table);
811
+ }
389
812
  });
390
813
  };
814
+ var getTableColumns = (table) => {
815
+ return table._.columns;
816
+ };
817
+ var alias = (table, alias2) => {
818
+ return table;
819
+ };
820
+
821
+ // src/column-helpers.ts
822
+ var columnHelpers = (name) => new SQLiteColumn(name, "TEXT");
823
+ var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
824
+ var real = (name) => new SQLiteColumn(name, "REAL");
825
+ var blob = (name) => new SQLiteColumn(name, "BLOB");
826
+ var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
391
827
  export {
828
+ BaseQueryBuilder,
392
829
  DeleteQueryBuilder,
393
830
  InsertQueryBuilder,
831
+ ManyRelation,
832
+ OneRelation,
833
+ Relation,
394
834
  SQLiteColumn,
395
835
  SelectQueryBuilder,
396
836
  Table,
397
837
  TauriORM,
398
838
  UpdateQueryBuilder,
839
+ WithQueryBuilder,
840
+ alias,
399
841
  and,
842
+ asc,
843
+ avg,
400
844
  blob,
401
845
  boolean,
846
+ columnHelpers,
847
+ count,
848
+ countDistinct,
849
+ desc,
402
850
  eq,
851
+ getTableColumns,
403
852
  gt,
404
853
  gte,
405
854
  inArray,
@@ -409,9 +858,13 @@ export {
409
858
  like,
410
859
  lt,
411
860
  lte,
861
+ max,
862
+ min,
863
+ not,
412
864
  or,
413
865
  real,
414
866
  relations,
867
+ sql,
415
868
  sqliteTable,
416
- text
869
+ sum
417
870
  };