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

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/README.md CHANGED
@@ -134,7 +134,7 @@ import { eq } from "@type32/tauri-sqlite-orm";
134
134
  await db
135
135
  .update(users)
136
136
  .set({ email: "new.email@example.com" })
137
- .where(eq(users.id, 1));
137
+ .where(eq(users._.columns.id, 1));
138
138
  ```
139
139
 
140
140
  **DELETE**
@@ -143,7 +143,7 @@ await db
143
143
  import { eq } from "@type32/tauri-sqlite-orm";
144
144
 
145
145
  // Delete a user
146
- await db.delete(users).where(eq(users.id, 1));
146
+ await db.delete(users).where(eq(users._.columns.id, 1));
147
147
  ```
148
148
 
149
149
  ### Migrations
@@ -165,7 +165,7 @@ Run multiple database operations within a transaction to ensure atomicity.
165
165
  ```typescript
166
166
  await db.transaction(async (tx) => {
167
167
  await tx.insert(users).values({ name: "From Transaction" });
168
- await tx.delete(users).where(eq(users.id, 1));
168
+ await tx.delete(users).where(eq(users._.columns.id, 1));
169
169
  });
170
170
  ```
171
171
 
package/dist/index.d.mts CHANGED
@@ -117,6 +117,10 @@ declare class UpdateQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
117
117
  private updateData;
118
118
  constructor(db: Database, table: T);
119
119
  set(data: Partial<InferInsertModel<T>>): this;
120
+ build(): {
121
+ sql: string;
122
+ params: any[];
123
+ };
120
124
  execute(): Promise<number>;
121
125
  }
122
126
  declare class DeleteQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
@@ -128,6 +132,7 @@ declare class TauriORM {
128
132
  private db;
129
133
  private tables;
130
134
  constructor(db: Database, schema?: Record<string, AnyTable> | undefined);
135
+ private buildColumnDefinition;
131
136
  migrate(): Promise<void>;
132
137
  select<T extends AnyTable, C extends (keyof T["_"]["columns"])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
133
138
  insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
package/dist/index.d.ts CHANGED
@@ -117,6 +117,10 @@ declare class UpdateQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
117
117
  private updateData;
118
118
  constructor(db: Database, table: T);
119
119
  set(data: Partial<InferInsertModel<T>>): this;
120
+ build(): {
121
+ sql: string;
122
+ params: any[];
123
+ };
120
124
  execute(): Promise<number>;
121
125
  }
122
126
  declare class DeleteQueryBuilder<T extends AnyTable> extends BaseQueryBuilder {
@@ -128,6 +132,7 @@ declare class TauriORM {
128
132
  private db;
129
133
  private tables;
130
134
  constructor(db: Database, schema?: Record<string, AnyTable> | undefined);
135
+ private buildColumnDefinition;
131
136
  migrate(): Promise<void>;
132
137
  select<T extends AnyTable, C extends (keyof T["_"]["columns"])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
133
138
  insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
package/dist/index.js CHANGED
@@ -281,18 +281,35 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
281
281
  this.updateData = { ...this.updateData, ...data };
282
282
  return this;
283
283
  }
284
- async execute() {
284
+ build() {
285
+ const baseQuery = this.query;
286
+ const whereParams = this.params;
287
+ let tablePart = baseQuery;
288
+ let whereClause = "";
289
+ const whereIndex = baseQuery.indexOf(" WHERE ");
290
+ if (whereIndex !== -1) {
291
+ tablePart = baseQuery.substring(0, whereIndex);
292
+ whereClause = baseQuery.substring(whereIndex);
293
+ }
285
294
  const entries = Object.entries(this.updateData);
295
+ if (entries.length === 0) {
296
+ throw new Error("Cannot execute an update query without a .set() call.");
297
+ }
286
298
  const setClause = entries.map(([key]) => {
287
299
  const column = this.table._.columns[key];
288
- if (!column)
300
+ if (!column) {
289
301
  throw new Error(
290
302
  `Column ${key} does not exist on table ${this.table._.name}`
291
303
  );
304
+ }
292
305
  return `${column._.name} = ?`;
293
306
  }).join(", ");
294
- this.query += ` SET ${setClause}`;
295
- this.params.push(...entries.map(([, value]) => value));
307
+ const setParams = entries.map(([, value]) => value);
308
+ const sql = `${tablePart} SET ${setClause}${whereClause}`;
309
+ const params = [...setParams, ...whereParams];
310
+ return { sql, params };
311
+ }
312
+ async execute() {
296
313
  const { sql, params } = this.build();
297
314
  const result = await this.db.execute(sql, params);
298
315
  return result.rowsAffected;
@@ -320,25 +337,46 @@ var TauriORM = class {
320
337
  }
321
338
  }
322
339
  tables = /* @__PURE__ */ new Map();
340
+ buildColumnDefinition(col, forAlterTable = false) {
341
+ let sql = `${col._.name} ${col.type}`;
342
+ if (col.options.primaryKey && !forAlterTable) {
343
+ sql += " PRIMARY KEY";
344
+ if (col._.autoincrement) {
345
+ sql += " AUTOINCREMENT";
346
+ }
347
+ }
348
+ if (col._.notNull) sql += " NOT NULL";
349
+ if (col.options.unique) sql += " UNIQUE";
350
+ if (col.options.default !== void 0) {
351
+ const value = col.options.default;
352
+ sql += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
353
+ }
354
+ if (col.options.references) {
355
+ sql += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
356
+ }
357
+ return sql;
358
+ }
323
359
  async migrate() {
324
360
  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})`;
361
+ const existingTableInfo = await this.db.select(
362
+ `PRAGMA table_info('${table._.name}')`
363
+ );
364
+ if (existingTableInfo.length === 0) {
365
+ const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
366
+ const createSql = `CREATE TABLE ${table._.name} (${columnsSql})`;
367
+ await this.db.execute(createSql);
368
+ } else {
369
+ const existingColumnNames = new Set(
370
+ existingTableInfo.map((c) => c.name)
371
+ );
372
+ for (const column of Object.values(table._.columns)) {
373
+ if (!existingColumnNames.has(column._.name)) {
374
+ const columnSql = this.buildColumnDefinition(column, true);
375
+ const alterSql = `ALTER TABLE ${table._.name} ADD COLUMN ${columnSql}`;
376
+ await this.db.execute(alterSql);
377
+ }
337
378
  }
338
- return sql;
339
- }).join(", ");
340
- const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
341
- await this.db.execute(createSql);
379
+ }
342
380
  }
343
381
  }
344
382
  select(table, columns) {
@@ -392,7 +430,10 @@ var TauriORM = class {
392
430
  pk: !!col.options.primaryKey,
393
431
  ai: !!col._.autoincrement,
394
432
  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
433
+ unique: !!col.options.unique,
434
+ dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null,
435
+ hasDefaultFn: col.options.$defaultFn !== void 0,
436
+ hasOnUpdateFn: col.options.$onUpdateFn !== void 0
396
437
  };
397
438
  }
398
439
  computeModelSignature() {
package/dist/index.mjs CHANGED
@@ -231,18 +231,35 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
231
231
  this.updateData = { ...this.updateData, ...data };
232
232
  return this;
233
233
  }
234
- async execute() {
234
+ build() {
235
+ const baseQuery = this.query;
236
+ const whereParams = this.params;
237
+ let tablePart = baseQuery;
238
+ let whereClause = "";
239
+ const whereIndex = baseQuery.indexOf(" WHERE ");
240
+ if (whereIndex !== -1) {
241
+ tablePart = baseQuery.substring(0, whereIndex);
242
+ whereClause = baseQuery.substring(whereIndex);
243
+ }
235
244
  const entries = Object.entries(this.updateData);
245
+ if (entries.length === 0) {
246
+ throw new Error("Cannot execute an update query without a .set() call.");
247
+ }
236
248
  const setClause = entries.map(([key]) => {
237
249
  const column = this.table._.columns[key];
238
- if (!column)
250
+ if (!column) {
239
251
  throw new Error(
240
252
  `Column ${key} does not exist on table ${this.table._.name}`
241
253
  );
254
+ }
242
255
  return `${column._.name} = ?`;
243
256
  }).join(", ");
244
- this.query += ` SET ${setClause}`;
245
- this.params.push(...entries.map(([, value]) => value));
257
+ const setParams = entries.map(([, value]) => value);
258
+ const sql = `${tablePart} SET ${setClause}${whereClause}`;
259
+ const params = [...setParams, ...whereParams];
260
+ return { sql, params };
261
+ }
262
+ async execute() {
246
263
  const { sql, params } = this.build();
247
264
  const result = await this.db.execute(sql, params);
248
265
  return result.rowsAffected;
@@ -270,25 +287,46 @@ var TauriORM = class {
270
287
  }
271
288
  }
272
289
  tables = /* @__PURE__ */ new Map();
290
+ buildColumnDefinition(col, forAlterTable = false) {
291
+ let sql = `${col._.name} ${col.type}`;
292
+ if (col.options.primaryKey && !forAlterTable) {
293
+ sql += " PRIMARY KEY";
294
+ if (col._.autoincrement) {
295
+ sql += " AUTOINCREMENT";
296
+ }
297
+ }
298
+ if (col._.notNull) sql += " NOT NULL";
299
+ if (col.options.unique) sql += " UNIQUE";
300
+ if (col.options.default !== void 0) {
301
+ const value = col.options.default;
302
+ sql += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
303
+ }
304
+ if (col.options.references) {
305
+ sql += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
306
+ }
307
+ return sql;
308
+ }
273
309
  async migrate() {
274
310
  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})`;
311
+ const existingTableInfo = await this.db.select(
312
+ `PRAGMA table_info('${table._.name}')`
313
+ );
314
+ if (existingTableInfo.length === 0) {
315
+ const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
316
+ const createSql = `CREATE TABLE ${table._.name} (${columnsSql})`;
317
+ await this.db.execute(createSql);
318
+ } else {
319
+ const existingColumnNames = new Set(
320
+ existingTableInfo.map((c) => c.name)
321
+ );
322
+ for (const column of Object.values(table._.columns)) {
323
+ if (!existingColumnNames.has(column._.name)) {
324
+ const columnSql = this.buildColumnDefinition(column, true);
325
+ const alterSql = `ALTER TABLE ${table._.name} ADD COLUMN ${columnSql}`;
326
+ await this.db.execute(alterSql);
327
+ }
287
328
  }
288
- return sql;
289
- }).join(", ");
290
- const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
291
- await this.db.execute(createSql);
329
+ }
292
330
  }
293
331
  }
294
332
  select(table, columns) {
@@ -342,7 +380,10 @@ var TauriORM = class {
342
380
  pk: !!col.options.primaryKey,
343
381
  ai: !!col._.autoincrement,
344
382
  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
383
+ unique: !!col.options.unique,
384
+ dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null,
385
+ hasDefaultFn: col.options.$defaultFn !== void 0,
386
+ hasOnUpdateFn: col.options.$onUpdateFn !== void 0
346
387
  };
347
388
  }
348
389
  computeModelSignature() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@type32/tauri-sqlite-orm",
3
- "version": "0.1.18-1",
3
+ "version": "0.1.18-3",
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",