@type32/tauri-sqlite-orm 0.1.18-4 → 0.1.18-6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -83,6 +83,9 @@ var SQLiteColumn = class _SQLiteColumn {
83
83
  this._.mode
84
84
  );
85
85
  }
86
+ as(alias2) {
87
+ return this;
88
+ }
86
89
  };
87
90
  var text = (name) => new SQLiteColumn(name, "TEXT");
88
91
  var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
@@ -113,6 +116,10 @@ var or = (...conditions) => ({
113
116
  sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
114
117
  params: conditions.flatMap((c) => c.params)
115
118
  });
119
+ var not = (condition) => ({
120
+ sql: `NOT (${condition.sql})`,
121
+ params: condition.params
122
+ });
116
123
  var gt = (column, value) => ({
117
124
  sql: `${column._.name} > ?`,
118
125
  params: [value]
@@ -145,6 +152,58 @@ var inArray = (column, values) => ({
145
152
  sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
146
153
  params: values
147
154
  });
155
+ var asc = (column) => ({
156
+ sql: `${column._.name} ASC`,
157
+ params: []
158
+ });
159
+ var desc = (column) => ({
160
+ sql: `${column._.name} DESC`,
161
+ params: []
162
+ });
163
+ var count = (column) => ({
164
+ sql: `COUNT(${column ? column._.name : "*"})`,
165
+ params: []
166
+ });
167
+ var countDistinct = (column) => ({
168
+ sql: `COUNT(DISTINCT ${column._.name})`,
169
+ params: []
170
+ });
171
+ var sum = (column) => ({
172
+ sql: `SUM(${column._.name})`,
173
+ params: []
174
+ });
175
+ var avg = (column) => ({
176
+ sql: `AVG(${column._.name})`,
177
+ params: []
178
+ });
179
+ var max = (column) => ({
180
+ sql: `MAX(${column._.name})`,
181
+ params: []
182
+ });
183
+ var min = (column) => ({
184
+ sql: `MIN(${column._.name})`,
185
+ params: []
186
+ });
187
+ var sql = (strings, ...values) => {
188
+ const queryParts = [];
189
+ const params = [];
190
+ strings.forEach((str, i) => {
191
+ queryParts.push(str);
192
+ if (values[i] !== void 0) {
193
+ if (typeof values[i] === "object" && values[i].sql) {
194
+ queryParts.push(values[i].sql);
195
+ params.push(...values[i].params);
196
+ } else {
197
+ queryParts.push("?");
198
+ params.push(values[i]);
199
+ }
200
+ }
201
+ });
202
+ return {
203
+ sql: queryParts.join(""),
204
+ params
205
+ };
206
+ };
148
207
  var BaseQueryBuilder = class {
149
208
  constructor(db) {
150
209
  this.db = db;
@@ -157,15 +216,20 @@ var BaseQueryBuilder = class {
157
216
  return this;
158
217
  }
159
218
  orderBy(column, direction = "ASC") {
160
- this.query += ` ORDER BY ${column._.name} ${direction}`;
219
+ if ("sql" in column) {
220
+ this.query += ` ORDER BY ${column.sql} ${direction}`;
221
+ this.params.push(...column.params);
222
+ } else {
223
+ this.query += ` ORDER BY ${column._.name} ${direction}`;
224
+ }
161
225
  return this;
162
226
  }
163
- limit(count) {
164
- this.query += ` LIMIT ${count}`;
227
+ limit(count2) {
228
+ this.query += ` LIMIT ${count2}`;
165
229
  return this;
166
230
  }
167
- offset(count) {
168
- this.query += ` OFFSET ${count}`;
231
+ offset(count2) {
232
+ this.query += ` OFFSET ${count2}`;
169
233
  return this;
170
234
  }
171
235
  build() {
@@ -183,9 +247,37 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
183
247
  const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
184
248
  this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
185
249
  }
250
+ isDistinct = false;
251
+ groupByColumns = [];
252
+ havingCondition = null;
253
+ distinct() {
254
+ this.isDistinct = true;
255
+ this.query = this.query.replace("SELECT", "SELECT DISTINCT");
256
+ return this;
257
+ }
258
+ groupBy(...columns) {
259
+ this.groupByColumns.push(...columns);
260
+ const columnNames = columns.map((col) => col._.name).join(", ");
261
+ this.query += ` GROUP BY ${columnNames}`;
262
+ return this;
263
+ }
264
+ having(condition) {
265
+ this.havingCondition = condition;
266
+ this.query += ` HAVING ${condition.sql}`;
267
+ this.params.push(...condition.params);
268
+ return this;
269
+ }
186
270
  async execute() {
187
- const { sql, params } = this.build();
188
- return this.db.select(sql, params);
271
+ const { sql: sql2, params } = this.build();
272
+ return this.db.select(sql2, params);
273
+ }
274
+ async all() {
275
+ return this.execute();
276
+ }
277
+ async get() {
278
+ this.limit(1);
279
+ const result = await this.execute();
280
+ return result[0];
189
281
  }
190
282
  };
191
283
  var InsertQueryBuilder = class extends BaseQueryBuilder {
@@ -195,46 +287,121 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
195
287
  this.query = `INSERT INTO ${table._.name}`;
196
288
  }
197
289
  dataSets = [];
290
+ returningColumns = [];
291
+ onConflictAction = null;
292
+ conflictTarget = [];
293
+ updateSet = {};
198
294
  values(data) {
199
295
  const dataArray = Array.isArray(data) ? data : [data];
200
296
  this.dataSets.push(...dataArray);
201
297
  return this;
202
298
  }
299
+ returning(...columns) {
300
+ this.returningColumns = 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
+ }
203
346
  async execute() {
204
347
  if (this.dataSets.length === 0) {
205
348
  throw new Error("No data provided for insert");
206
349
  }
207
- const processedDataSets = this.dataSets.map((dataSet) => {
208
- const finalData = { ...dataSet };
209
- for (const [key, column] of Object.entries(this.table._.columns)) {
210
- if (finalData[key] === void 0) {
211
- if (column.options.$defaultFn) {
212
- finalData[key] = column.options.$defaultFn();
213
- }
214
- }
215
- }
216
- return finalData;
217
- });
218
- const allKeys = /* @__PURE__ */ new Set();
350
+ const processedDataSets = this.dataSets.map(
351
+ (data) => this.processDefaultValues(data)
352
+ );
353
+ const groups = /* @__PURE__ */ new Map();
219
354
  for (const dataSet of processedDataSets) {
220
- for (const key of Object.keys(dataSet)) {
221
- allKeys.add(key);
355
+ const keys = Object.keys(dataSet).sort().join(",");
356
+ if (!groups.has(keys)) {
357
+ groups.set(keys, []);
222
358
  }
359
+ groups.get(keys).push(dataSet);
223
360
  }
224
- const columns = Array.from(allKeys);
225
- const columnNames = columns.map(
226
- (key) => this.table._.columns[key]._.name
227
- );
228
- const placeholders = `(${columns.map(() => "?").join(", ")})`;
229
- const valuesSql = processedDataSets.map(() => placeholders).join(", ");
230
- const finalQuery = `${this.query} (${columnNames.join(
231
- ", "
232
- )}) VALUES ${valuesSql}`;
233
- const params = processedDataSets.flatMap(
234
- (data) => columns.map((col) => data[col] ?? null)
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
235
403
  );
236
- const result = await this.db.execute(finalQuery, params);
237
- return result.lastInsertId ?? 0;
404
+ return this.returning(...allColumns).execute();
238
405
  }
239
406
  };
240
407
  var UpdateQueryBuilder = class extends BaseQueryBuilder {
@@ -244,15 +411,21 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
244
411
  this.query = `UPDATE ${table._.name}`;
245
412
  }
246
413
  updateData = {};
414
+ returningColumns = [];
247
415
  set(data) {
248
416
  this.updateData = { ...this.updateData, ...data };
249
417
  return this;
250
418
  }
251
- build() {
419
+ returning(...columns) {
420
+ this.returningColumns = columns;
421
+ return this;
422
+ }
423
+ buildUpdateClause() {
252
424
  const finalUpdateData = { ...this.updateData };
253
425
  for (const [key, column] of Object.entries(this.table._.columns)) {
254
- if (finalUpdateData[key] === void 0 && column.options.$onUpdateFn) {
255
- finalUpdateData[key] = column.options.$onUpdateFn();
426
+ const typedKey = key;
427
+ if (finalUpdateData[typedKey] === void 0 && column.options.$onUpdateFn) {
428
+ finalUpdateData[typedKey] = column.options.$onUpdateFn();
256
429
  }
257
430
  }
258
431
  const baseQuery = this.query;
@@ -278,14 +451,26 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
278
451
  return `${column._.name} = ?`;
279
452
  }).join(", ");
280
453
  const setParams = entries.map(([, value]) => value);
281
- const sql = `${tablePart} SET ${setClause}${whereClause}`;
454
+ const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
282
455
  const params = [...setParams, ...whereParams];
283
- return { sql, params };
456
+ return { sql: sql2, params };
284
457
  }
285
458
  async execute() {
286
- const { sql, params } = this.build();
287
- const result = await this.db.execute(sql, params);
288
- return result.rowsAffected;
459
+ const { sql: updateSql, params } = this.buildUpdateClause();
460
+ if (this.returningColumns.length > 0) {
461
+ const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
462
+ const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
463
+ return this.db.select(sqlWithReturning, params);
464
+ } else {
465
+ const result = await this.db.execute(updateSql, params);
466
+ return [{ rowsAffected: result.rowsAffected }];
467
+ }
468
+ }
469
+ async returningAll() {
470
+ const allColumns = Object.keys(
471
+ this.table._.columns
472
+ );
473
+ return this.returning(...allColumns).execute();
289
474
  }
290
475
  };
291
476
  var DeleteQueryBuilder = class extends BaseQueryBuilder {
@@ -294,10 +479,67 @@ var DeleteQueryBuilder = class extends BaseQueryBuilder {
294
479
  this.table = table;
295
480
  this.query = `DELETE FROM ${table._.name}`;
296
481
  }
482
+ returningColumns = [];
483
+ returning(...columns) {
484
+ this.returningColumns = columns;
485
+ return this;
486
+ }
297
487
  async execute() {
298
- const { sql, params } = this.build();
299
- const result = await this.db.execute(sql, params);
300
- return result.rowsAffected;
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
+ var WithQueryBuilder = class {
506
+ constructor(db) {
507
+ this.db = db;
508
+ }
509
+ ctes = [];
510
+ with(alias2, query) {
511
+ this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
512
+ return this;
513
+ }
514
+ select(table, columns) {
515
+ const builder = new SelectQueryBuilder(this.db, table, columns);
516
+ this.applyWithClause(builder);
517
+ return builder;
518
+ }
519
+ insert(table) {
520
+ const builder = new InsertQueryBuilder(this.db, table);
521
+ this.applyWithClause(builder);
522
+ return builder;
523
+ }
524
+ update(table) {
525
+ const builder = new UpdateQueryBuilder(this.db, table);
526
+ this.applyWithClause(builder);
527
+ return builder;
528
+ }
529
+ delete(table) {
530
+ const builder = new DeleteQueryBuilder(this.db, table);
531
+ this.applyWithClause(builder);
532
+ return builder;
533
+ }
534
+ applyWithClause(builder) {
535
+ if (this.ctes.length > 0) {
536
+ const cteSql = this.ctes.map((cte) => `${cte.alias} AS (${cte.query})`).join(", ");
537
+ builder["query"] = `WITH ${cteSql} ${builder["query"]}`;
538
+ builder["params"] = [
539
+ ...this.ctes.flatMap((cte) => cte.params),
540
+ ...builder["params"]
541
+ ];
542
+ }
301
543
  }
302
544
  };
303
545
  var TauriORM = class {
@@ -311,23 +553,23 @@ var TauriORM = class {
311
553
  }
312
554
  tables = /* @__PURE__ */ new Map();
313
555
  buildColumnDefinition(col, forAlterTable = false) {
314
- let sql = `${col._.name} ${col.type}`;
556
+ let sql2 = `${col._.name} ${col.type}`;
315
557
  if (col.options.primaryKey && !forAlterTable) {
316
- sql += " PRIMARY KEY";
558
+ sql2 += " PRIMARY KEY";
317
559
  if (col._.autoincrement) {
318
- sql += " AUTOINCREMENT";
560
+ sql2 += " AUTOINCREMENT";
319
561
  }
320
562
  }
321
- if (col._.notNull) sql += " NOT NULL";
322
- if (col.options.unique) sql += " UNIQUE";
563
+ if (col._.notNull) sql2 += " NOT NULL";
564
+ if (col.options.unique) sql2 += " UNIQUE";
323
565
  if (col.options.default !== void 0) {
324
566
  const value = col.options.default;
325
- sql += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
567
+ sql2 += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
326
568
  }
327
569
  if (col.options.references) {
328
- sql += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
570
+ sql2 += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
329
571
  }
330
- return sql;
572
+ return sql2;
331
573
  }
332
574
  async migrate() {
333
575
  for (const table of this.tables.values()) {
@@ -364,6 +606,15 @@ var TauriORM = class {
364
606
  delete(table) {
365
607
  return new DeleteQueryBuilder(this.db, table);
366
608
  }
609
+ $with(alias2) {
610
+ const withBuilder = new WithQueryBuilder(this.db);
611
+ return {
612
+ as: (query) => {
613
+ withBuilder.with(alias2, query);
614
+ return withBuilder;
615
+ }
616
+ };
617
+ }
367
618
  async transaction(callback) {
368
619
  await this.db.execute("BEGIN TRANSACTION");
369
620
  try {
@@ -375,6 +626,9 @@ var TauriORM = class {
375
626
  throw error;
376
627
  }
377
628
  }
629
+ rollback() {
630
+ throw new Error("Transaction rolled back");
631
+ }
378
632
  // --- Schema detection / signature ---
379
633
  async ensureSchemaMeta() {
380
634
  await this.db.execute(
@@ -452,6 +706,12 @@ var relations = (table, relationsCallback) => {
452
706
  })
453
707
  });
454
708
  };
709
+ var getTableColumns = (table) => {
710
+ return table._.columns;
711
+ };
712
+ var alias = (table, alias2) => {
713
+ return table;
714
+ };
455
715
  export {
456
716
  DeleteQueryBuilder,
457
717
  InsertQueryBuilder,
@@ -460,10 +720,18 @@ export {
460
720
  Table,
461
721
  TauriORM,
462
722
  UpdateQueryBuilder,
723
+ WithQueryBuilder,
724
+ alias,
463
725
  and,
726
+ asc,
727
+ avg,
464
728
  blob,
465
729
  boolean,
730
+ count,
731
+ countDistinct,
732
+ desc,
466
733
  eq,
734
+ getTableColumns,
467
735
  gt,
468
736
  gte,
469
737
  inArray,
@@ -473,9 +741,14 @@ export {
473
741
  like,
474
742
  lt,
475
743
  lte,
744
+ max,
745
+ min,
746
+ not,
476
747
  or,
477
748
  real,
478
749
  relations,
750
+ sql,
479
751
  sqliteTable,
752
+ sum,
480
753
  text
481
754
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@type32/tauri-sqlite-orm",
3
- "version": "0.1.18-4",
3
+ "version": "0.1.18-6",
4
4
  "description": "A Drizzle-like ORM for Tauri v2's SQL JS API plugin.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",