@type32/tauri-sqlite-orm 0.2.8 → 0.2.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.d.mts CHANGED
@@ -289,6 +289,9 @@ declare class TauriORM {
289
289
  migrate(options?: {
290
290
  performDestructiveActions?: boolean;
291
291
  }): Promise<void>;
292
+ private canAddColumnWithAlter;
293
+ private hasColumnDefinitionChanged;
294
+ private recreateTable;
292
295
  select<T extends AnyTable, C extends (keyof T['_']['columns'])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
293
296
  insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
294
297
  update<T extends AnyTable>(table: T): UpdateQueryBuilder<T>;
@@ -405,22 +408,26 @@ declare const as: <T>(aggregate: SQLAggregate<T>, alias: string) => SQLAggregate
405
408
  declare const subquery: <T extends AnyTable>(query: SelectQueryBuilder<T, any>) => SQLSubquery;
406
409
  declare const scalarSubquery: <T extends AnyTable>(query: SelectQueryBuilder<T, any>) => SQLSubquery;
407
410
 
408
- declare const text: <TName extends string, TMode extends "default" | "json" = "default", TEnum extends readonly string[] = never>(name: TName, config?: {
409
- mode?: TMode;
410
- enum?: TEnum;
411
- }) => SQLiteColumn<TName, "TEXT", TMode, false, false, false, TEnum, never>;
412
- declare const integer: <TName extends string, TMode extends Mode = "default">(name: TName, config?: {
413
- mode?: TMode;
414
- }) => SQLiteColumn<TName, "INTEGER", TMode, false, false, false, never, never>;
411
+ declare function text<TName extends string>(name: TName): SQLiteColumn<TName, 'TEXT', 'default', false, false, false, never, never>;
412
+ declare function text<TName extends string, const TConfig extends {
413
+ mode?: 'default' | 'json';
414
+ enum?: readonly string[];
415
+ }>(name: TName, config: TConfig): SQLiteColumn<TName, 'TEXT', TConfig['mode'] extends 'json' ? 'json' : 'default', false, false, false, TConfig['enum'] extends readonly string[] ? TConfig['enum'] : never, never>;
416
+ declare function integer<TName extends string>(name: TName): SQLiteColumn<TName, 'INTEGER', 'default', false, false, false, never, never>;
417
+ declare function integer<TName extends string, const TConfig extends {
418
+ mode: Mode;
419
+ }>(name: TName, config: TConfig): SQLiteColumn<TName, 'INTEGER', TConfig['mode'], false, false, false, never, never>;
415
420
  declare const real: <TName extends string>(name: TName) => SQLiteColumn<TName, "REAL", "default", false, false, false, never, never>;
416
- declare const blob: <TName extends string, TMode extends "json" | "bigint" | "default" = "default">(name: TName, config?: {
417
- mode?: TMode;
418
- }) => SQLiteColumn<TName, "BLOB", TMode, false, false, false, never, never>;
421
+ declare function blob<TName extends string>(name: TName): SQLiteColumn<TName, 'BLOB', 'default', false, false, false, never, never>;
422
+ declare function blob<TName extends string, const TConfig extends {
423
+ mode: 'json' | 'bigint' | 'default';
424
+ }>(name: TName, config: TConfig): SQLiteColumn<TName, 'BLOB', TConfig['mode'], false, false, false, never, never>;
419
425
  declare const boolean: <TName extends string>(name: TName) => SQLiteColumn<TName, "BOOLEAN", "default", false, false, false, never, never>;
420
- declare const numeric: <TName extends string, TMode extends "bigint" | "default" = "default">(name: TName, config?: {
421
- mode?: TMode;
422
- }) => SQLiteColumn<TName, "NUMERIC", TMode, false, false, false, never, never>;
423
- declare const enumType: <TName extends string, TValues extends readonly [string, ...string[]]>(name: TName, values: TValues) => SQLiteColumn<TName, "TEXT", "default", false, false, false, TValues, never>;
426
+ declare function numeric<TName extends string>(name: TName): SQLiteColumn<TName, 'NUMERIC', 'default', false, false, false, never, never>;
427
+ declare function numeric<TName extends string, const TConfig extends {
428
+ mode: 'bigint' | 'default';
429
+ }>(name: TName, config: TConfig): SQLiteColumn<TName, 'NUMERIC', TConfig['mode'], false, false, false, never, never>;
430
+ declare const enumType: <TName extends string, TValues extends readonly [string, ...string[]]>(name: TName, values: TValues) => SQLiteColumn<TName, "TEXT", "default", false, false, false, TValues extends readonly string[] ? TValues : never, never>;
424
431
 
425
432
  declare class TauriORMError extends Error {
426
433
  constructor(message: string);
package/dist/index.d.ts CHANGED
@@ -289,6 +289,9 @@ declare class TauriORM {
289
289
  migrate(options?: {
290
290
  performDestructiveActions?: boolean;
291
291
  }): Promise<void>;
292
+ private canAddColumnWithAlter;
293
+ private hasColumnDefinitionChanged;
294
+ private recreateTable;
292
295
  select<T extends AnyTable, C extends (keyof T['_']['columns'])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
293
296
  insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
294
297
  update<T extends AnyTable>(table: T): UpdateQueryBuilder<T>;
@@ -405,22 +408,26 @@ declare const as: <T>(aggregate: SQLAggregate<T>, alias: string) => SQLAggregate
405
408
  declare const subquery: <T extends AnyTable>(query: SelectQueryBuilder<T, any>) => SQLSubquery;
406
409
  declare const scalarSubquery: <T extends AnyTable>(query: SelectQueryBuilder<T, any>) => SQLSubquery;
407
410
 
408
- declare const text: <TName extends string, TMode extends "default" | "json" = "default", TEnum extends readonly string[] = never>(name: TName, config?: {
409
- mode?: TMode;
410
- enum?: TEnum;
411
- }) => SQLiteColumn<TName, "TEXT", TMode, false, false, false, TEnum, never>;
412
- declare const integer: <TName extends string, TMode extends Mode = "default">(name: TName, config?: {
413
- mode?: TMode;
414
- }) => SQLiteColumn<TName, "INTEGER", TMode, false, false, false, never, never>;
411
+ declare function text<TName extends string>(name: TName): SQLiteColumn<TName, 'TEXT', 'default', false, false, false, never, never>;
412
+ declare function text<TName extends string, const TConfig extends {
413
+ mode?: 'default' | 'json';
414
+ enum?: readonly string[];
415
+ }>(name: TName, config: TConfig): SQLiteColumn<TName, 'TEXT', TConfig['mode'] extends 'json' ? 'json' : 'default', false, false, false, TConfig['enum'] extends readonly string[] ? TConfig['enum'] : never, never>;
416
+ declare function integer<TName extends string>(name: TName): SQLiteColumn<TName, 'INTEGER', 'default', false, false, false, never, never>;
417
+ declare function integer<TName extends string, const TConfig extends {
418
+ mode: Mode;
419
+ }>(name: TName, config: TConfig): SQLiteColumn<TName, 'INTEGER', TConfig['mode'], false, false, false, never, never>;
415
420
  declare const real: <TName extends string>(name: TName) => SQLiteColumn<TName, "REAL", "default", false, false, false, never, never>;
416
- declare const blob: <TName extends string, TMode extends "json" | "bigint" | "default" = "default">(name: TName, config?: {
417
- mode?: TMode;
418
- }) => SQLiteColumn<TName, "BLOB", TMode, false, false, false, never, never>;
421
+ declare function blob<TName extends string>(name: TName): SQLiteColumn<TName, 'BLOB', 'default', false, false, false, never, never>;
422
+ declare function blob<TName extends string, const TConfig extends {
423
+ mode: 'json' | 'bigint' | 'default';
424
+ }>(name: TName, config: TConfig): SQLiteColumn<TName, 'BLOB', TConfig['mode'], false, false, false, never, never>;
419
425
  declare const boolean: <TName extends string>(name: TName) => SQLiteColumn<TName, "BOOLEAN", "default", false, false, false, never, never>;
420
- declare const numeric: <TName extends string, TMode extends "bigint" | "default" = "default">(name: TName, config?: {
421
- mode?: TMode;
422
- }) => SQLiteColumn<TName, "NUMERIC", TMode, false, false, false, never, never>;
423
- declare const enumType: <TName extends string, TValues extends readonly [string, ...string[]]>(name: TName, values: TValues) => SQLiteColumn<TName, "TEXT", "default", false, false, false, TValues, never>;
426
+ declare function numeric<TName extends string>(name: TName): SQLiteColumn<TName, 'NUMERIC', 'default', false, false, false, never, never>;
427
+ declare function numeric<TName extends string, const TConfig extends {
428
+ mode: 'bigint' | 'default';
429
+ }>(name: TName, config: TConfig): SQLiteColumn<TName, 'NUMERIC', TConfig['mode'], false, false, false, never, never>;
430
+ declare const enumType: <TName extends string, TValues extends readonly [string, ...string[]]>(name: TName, values: TValues) => SQLiteColumn<TName, "TEXT", "default", false, false, false, TValues extends readonly string[] ? TValues : never, never>;
424
431
 
425
432
  declare class TauriORMError extends Error {
426
433
  constructor(message: string);
package/dist/index.js CHANGED
@@ -1269,30 +1269,62 @@ var TauriORM = class {
1269
1269
  const tableExists = dbTableNames.has(tableName);
1270
1270
  if (!tableExists) {
1271
1271
  const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
1272
- const createSql = `CREATE TABLE ${tableName}
1273
- (
1274
- ${columnsSql}
1275
- )`;
1272
+ const createSql = `CREATE TABLE ${tableName} (${columnsSql})`;
1276
1273
  await this.db.execute(createSql);
1277
1274
  } else {
1278
1275
  const existingTableInfo = await this.db.select(`PRAGMA table_info('${tableName}')`);
1279
- const existingColumnNames = new Set(existingTableInfo.map((c) => c.name));
1280
- const schemaColumnNames = new Set(Object.keys(table._.columns));
1281
- for (const column of Object.values(table._.columns)) {
1282
- if (!existingColumnNames.has(column._.name)) {
1283
- const columnSql = this.buildColumnDefinition(column, true);
1284
- const alterSql = `ALTER TABLE ${tableName}
1285
- ADD COLUMN ${columnSql}`;
1286
- await this.db.execute(alterSql);
1276
+ const existingIndexes = await this.db.select(`PRAGMA index_list('${tableName}')`);
1277
+ const uniqueColumns = /* @__PURE__ */ new Set();
1278
+ for (const index of existingIndexes) {
1279
+ if (index.unique === 1 && index.origin === "u") {
1280
+ const indexInfo = await this.db.select(`PRAGMA index_info('${index.name}')`);
1281
+ if (indexInfo.length === 1) {
1282
+ uniqueColumns.add(indexInfo[0].name);
1283
+ }
1284
+ }
1285
+ }
1286
+ const existingColumns = new Map(existingTableInfo.map((c) => [c.name, c]));
1287
+ const schemaColumns = table._.columns;
1288
+ let needsRecreate = false;
1289
+ const columnsToAdd = [];
1290
+ for (const [colName, column] of Object.entries(schemaColumns)) {
1291
+ const existing = existingColumns.get(colName);
1292
+ if (!existing) {
1293
+ if (this.canAddColumnWithAlter(column)) {
1294
+ columnsToAdd.push(column);
1295
+ } else {
1296
+ needsRecreate = true;
1297
+ break;
1298
+ }
1299
+ } else {
1300
+ const hasUniqueInDB = uniqueColumns.has(colName);
1301
+ const wantsUnique = !!column.options.unique;
1302
+ if (hasUniqueInDB !== wantsUnique) {
1303
+ needsRecreate = true;
1304
+ break;
1305
+ }
1306
+ if (this.hasColumnDefinitionChanged(column, existing)) {
1307
+ needsRecreate = true;
1308
+ break;
1309
+ }
1287
1310
  }
1288
1311
  }
1289
1312
  if (options?.performDestructiveActions) {
1290
- for (const colName of existingColumnNames) {
1291
- if (!schemaColumnNames.has(colName)) {
1292
- await this.dropColumn(tableName, colName);
1313
+ for (const existingCol of existingColumns.keys()) {
1314
+ if (!schemaColumns[existingCol]) {
1315
+ needsRecreate = true;
1316
+ break;
1293
1317
  }
1294
1318
  }
1295
1319
  }
1320
+ if (needsRecreate) {
1321
+ await this.recreateTable(tableName, table);
1322
+ } else if (columnsToAdd.length > 0) {
1323
+ for (const column of columnsToAdd) {
1324
+ const columnSql = this.buildColumnDefinition(column, true);
1325
+ await this.db.execute(`ALTER TABLE ${tableName} ADD COLUMN ${columnSql}`);
1326
+ }
1327
+ }
1296
1328
  }
1297
1329
  }
1298
1330
  if (options?.performDestructiveActions) {
@@ -1303,6 +1335,38 @@ var TauriORM = class {
1303
1335
  }
1304
1336
  }
1305
1337
  }
1338
+ canAddColumnWithAlter(column) {
1339
+ if (column.options.primaryKey) return false;
1340
+ if (column.options.unique) return false;
1341
+ if (column._.notNull && column.options.default === void 0 && !column.options.$defaultFn) return false;
1342
+ return true;
1343
+ }
1344
+ hasColumnDefinitionChanged(column, existing) {
1345
+ if (column.type.toUpperCase() !== existing.type.toUpperCase()) return true;
1346
+ if (column._.notNull !== (existing.notnull === 1)) return true;
1347
+ if (!!column.options.primaryKey !== (existing.pk === 1)) return true;
1348
+ const hasDefault = column.options.default !== void 0;
1349
+ const existingHasDefault = existing.dflt_value !== null;
1350
+ if (hasDefault !== existingHasDefault) return true;
1351
+ return false;
1352
+ }
1353
+ async recreateTable(tableName, table) {
1354
+ const tempTableName = `${tableName}_new_${Date.now()}`;
1355
+ const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
1356
+ await this.db.execute(`CREATE TABLE ${tempTableName} (${columnsSql})`);
1357
+ const oldColumns = await this.db.select(`PRAGMA table_info('${tableName}')`);
1358
+ const oldColumnNames = oldColumns.map((c) => c.name);
1359
+ const newColumnNames = Object.keys(table._.columns);
1360
+ const commonColumns = oldColumnNames.filter((name) => newColumnNames.includes(name));
1361
+ if (commonColumns.length > 0) {
1362
+ const columnsList = commonColumns.join(", ");
1363
+ await this.db.execute(
1364
+ `INSERT INTO ${tempTableName} (${columnsList}) SELECT ${columnsList} FROM ${tableName}`
1365
+ );
1366
+ }
1367
+ await this.db.execute(`DROP TABLE ${tableName}`);
1368
+ await this.db.execute(`ALTER TABLE ${tempTableName} RENAME TO ${tableName}`);
1369
+ }
1306
1370
  select(table, columns) {
1307
1371
  const internalTable = this.tables.get(table._.name);
1308
1372
  if (!internalTable) {
@@ -1564,12 +1628,20 @@ var scalarSubquery = (query) => {
1564
1628
  };
1565
1629
 
1566
1630
  // src/column-helpers.ts
1567
- var text = (name, config) => new SQLiteColumn(name, "TEXT", config);
1568
- var integer = (name, config) => new SQLiteColumn(name, "INTEGER", config);
1631
+ function text(name, config) {
1632
+ return new SQLiteColumn(name, "TEXT", config);
1633
+ }
1634
+ function integer(name, config) {
1635
+ return new SQLiteColumn(name, "INTEGER", config);
1636
+ }
1569
1637
  var real = (name) => new SQLiteColumn(name, "REAL");
1570
- var blob = (name, config) => new SQLiteColumn(name, "BLOB", config);
1638
+ function blob(name, config) {
1639
+ return new SQLiteColumn(name, "BLOB", config);
1640
+ }
1571
1641
  var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
1572
- var numeric = (name, config) => new SQLiteColumn(name, "NUMERIC", config);
1642
+ function numeric(name, config) {
1643
+ return new SQLiteColumn(name, "NUMERIC", config);
1644
+ }
1573
1645
  var enumType = (name, values) => text(name, { enum: values });
1574
1646
  // Annotate the CommonJS export names for ESM import in node:
1575
1647
  0 && (module.exports = {
package/dist/index.mjs CHANGED
@@ -1170,30 +1170,62 @@ var TauriORM = class {
1170
1170
  const tableExists = dbTableNames.has(tableName);
1171
1171
  if (!tableExists) {
1172
1172
  const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
1173
- const createSql = `CREATE TABLE ${tableName}
1174
- (
1175
- ${columnsSql}
1176
- )`;
1173
+ const createSql = `CREATE TABLE ${tableName} (${columnsSql})`;
1177
1174
  await this.db.execute(createSql);
1178
1175
  } else {
1179
1176
  const existingTableInfo = await this.db.select(`PRAGMA table_info('${tableName}')`);
1180
- const existingColumnNames = new Set(existingTableInfo.map((c) => c.name));
1181
- const schemaColumnNames = new Set(Object.keys(table._.columns));
1182
- for (const column of Object.values(table._.columns)) {
1183
- if (!existingColumnNames.has(column._.name)) {
1184
- const columnSql = this.buildColumnDefinition(column, true);
1185
- const alterSql = `ALTER TABLE ${tableName}
1186
- ADD COLUMN ${columnSql}`;
1187
- await this.db.execute(alterSql);
1177
+ const existingIndexes = await this.db.select(`PRAGMA index_list('${tableName}')`);
1178
+ const uniqueColumns = /* @__PURE__ */ new Set();
1179
+ for (const index of existingIndexes) {
1180
+ if (index.unique === 1 && index.origin === "u") {
1181
+ const indexInfo = await this.db.select(`PRAGMA index_info('${index.name}')`);
1182
+ if (indexInfo.length === 1) {
1183
+ uniqueColumns.add(indexInfo[0].name);
1184
+ }
1185
+ }
1186
+ }
1187
+ const existingColumns = new Map(existingTableInfo.map((c) => [c.name, c]));
1188
+ const schemaColumns = table._.columns;
1189
+ let needsRecreate = false;
1190
+ const columnsToAdd = [];
1191
+ for (const [colName, column] of Object.entries(schemaColumns)) {
1192
+ const existing = existingColumns.get(colName);
1193
+ if (!existing) {
1194
+ if (this.canAddColumnWithAlter(column)) {
1195
+ columnsToAdd.push(column);
1196
+ } else {
1197
+ needsRecreate = true;
1198
+ break;
1199
+ }
1200
+ } else {
1201
+ const hasUniqueInDB = uniqueColumns.has(colName);
1202
+ const wantsUnique = !!column.options.unique;
1203
+ if (hasUniqueInDB !== wantsUnique) {
1204
+ needsRecreate = true;
1205
+ break;
1206
+ }
1207
+ if (this.hasColumnDefinitionChanged(column, existing)) {
1208
+ needsRecreate = true;
1209
+ break;
1210
+ }
1188
1211
  }
1189
1212
  }
1190
1213
  if (options?.performDestructiveActions) {
1191
- for (const colName of existingColumnNames) {
1192
- if (!schemaColumnNames.has(colName)) {
1193
- await this.dropColumn(tableName, colName);
1214
+ for (const existingCol of existingColumns.keys()) {
1215
+ if (!schemaColumns[existingCol]) {
1216
+ needsRecreate = true;
1217
+ break;
1194
1218
  }
1195
1219
  }
1196
1220
  }
1221
+ if (needsRecreate) {
1222
+ await this.recreateTable(tableName, table);
1223
+ } else if (columnsToAdd.length > 0) {
1224
+ for (const column of columnsToAdd) {
1225
+ const columnSql = this.buildColumnDefinition(column, true);
1226
+ await this.db.execute(`ALTER TABLE ${tableName} ADD COLUMN ${columnSql}`);
1227
+ }
1228
+ }
1197
1229
  }
1198
1230
  }
1199
1231
  if (options?.performDestructiveActions) {
@@ -1204,6 +1236,38 @@ var TauriORM = class {
1204
1236
  }
1205
1237
  }
1206
1238
  }
1239
+ canAddColumnWithAlter(column) {
1240
+ if (column.options.primaryKey) return false;
1241
+ if (column.options.unique) return false;
1242
+ if (column._.notNull && column.options.default === void 0 && !column.options.$defaultFn) return false;
1243
+ return true;
1244
+ }
1245
+ hasColumnDefinitionChanged(column, existing) {
1246
+ if (column.type.toUpperCase() !== existing.type.toUpperCase()) return true;
1247
+ if (column._.notNull !== (existing.notnull === 1)) return true;
1248
+ if (!!column.options.primaryKey !== (existing.pk === 1)) return true;
1249
+ const hasDefault = column.options.default !== void 0;
1250
+ const existingHasDefault = existing.dflt_value !== null;
1251
+ if (hasDefault !== existingHasDefault) return true;
1252
+ return false;
1253
+ }
1254
+ async recreateTable(tableName, table) {
1255
+ const tempTableName = `${tableName}_new_${Date.now()}`;
1256
+ const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
1257
+ await this.db.execute(`CREATE TABLE ${tempTableName} (${columnsSql})`);
1258
+ const oldColumns = await this.db.select(`PRAGMA table_info('${tableName}')`);
1259
+ const oldColumnNames = oldColumns.map((c) => c.name);
1260
+ const newColumnNames = Object.keys(table._.columns);
1261
+ const commonColumns = oldColumnNames.filter((name) => newColumnNames.includes(name));
1262
+ if (commonColumns.length > 0) {
1263
+ const columnsList = commonColumns.join(", ");
1264
+ await this.db.execute(
1265
+ `INSERT INTO ${tempTableName} (${columnsList}) SELECT ${columnsList} FROM ${tableName}`
1266
+ );
1267
+ }
1268
+ await this.db.execute(`DROP TABLE ${tableName}`);
1269
+ await this.db.execute(`ALTER TABLE ${tempTableName} RENAME TO ${tableName}`);
1270
+ }
1207
1271
  select(table, columns) {
1208
1272
  const internalTable = this.tables.get(table._.name);
1209
1273
  if (!internalTable) {
@@ -1465,12 +1529,20 @@ var scalarSubquery = (query) => {
1465
1529
  };
1466
1530
 
1467
1531
  // src/column-helpers.ts
1468
- var text = (name, config) => new SQLiteColumn(name, "TEXT", config);
1469
- var integer = (name, config) => new SQLiteColumn(name, "INTEGER", config);
1532
+ function text(name, config) {
1533
+ return new SQLiteColumn(name, "TEXT", config);
1534
+ }
1535
+ function integer(name, config) {
1536
+ return new SQLiteColumn(name, "INTEGER", config);
1537
+ }
1470
1538
  var real = (name) => new SQLiteColumn(name, "REAL");
1471
- var blob = (name, config) => new SQLiteColumn(name, "BLOB", config);
1539
+ function blob(name, config) {
1540
+ return new SQLiteColumn(name, "BLOB", config);
1541
+ }
1472
1542
  var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
1473
- var numeric = (name, config) => new SQLiteColumn(name, "NUMERIC", config);
1543
+ function numeric(name, config) {
1544
+ return new SQLiteColumn(name, "NUMERIC", config);
1545
+ }
1474
1546
  var enumType = (name, values) => text(name, { enum: values });
1475
1547
  export {
1476
1548
  BaseQueryBuilder,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@type32/tauri-sqlite-orm",
3
- "version": "0.2.8",
3
+ "version": "0.2.10",
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",