@type32/tauri-sqlite-orm 0.1.8 → 0.1.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 +39 -15
- package/dist/index.d.ts +39 -15
- package/dist/index.js +150 -25
- package/dist/index.mjs +150 -25
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -188,6 +188,12 @@ declare const notExists: (subquery: SQL | {
|
|
|
188
188
|
declare const asc: (column: Column) => string;
|
|
189
189
|
declare const desc: (column: Column) => string;
|
|
190
190
|
|
|
191
|
+
type InferInsert<T> = T extends {
|
|
192
|
+
$inferInsert: infer I;
|
|
193
|
+
} ? I : never;
|
|
194
|
+
type InferSelect<T> = T extends {
|
|
195
|
+
$inferSelect: infer S;
|
|
196
|
+
} ? S : never;
|
|
191
197
|
declare class SelectQueryBuilder<T> {
|
|
192
198
|
private _table;
|
|
193
199
|
private _selectedColumns;
|
|
@@ -222,11 +228,17 @@ declare class TauriORM {
|
|
|
222
228
|
constructor(dbUri: string);
|
|
223
229
|
private getDb;
|
|
224
230
|
configureQuery(tables: Record<string, Table<any>>, relations: Record<string, Record<string, RelationConfig>>): void;
|
|
225
|
-
select<
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
231
|
+
select<TFields extends Record<string, Column<any>>>(fields: TFields): SelectQueryBuilder<{
|
|
232
|
+
[K in keyof TFields]: TFields[K]["_dataType"];
|
|
233
|
+
}>;
|
|
234
|
+
select<T = any>(fields?: undefined): SelectQueryBuilder<T>;
|
|
235
|
+
selectDistinct<TFields extends Record<string, Column<any>>>(fields: TFields): SelectQueryBuilder<{
|
|
236
|
+
[K in keyof TFields]: TFields[K]["_dataType"];
|
|
237
|
+
}>;
|
|
238
|
+
selectDistinct<T = any>(fields?: undefined): SelectQueryBuilder<T>;
|
|
239
|
+
insert<TTable extends Table<any>>(table: TTable): {
|
|
240
|
+
_table: TTable;
|
|
241
|
+
_rows: Array<InferInsert<TTable>>;
|
|
230
242
|
_selectSql: {
|
|
231
243
|
clause: string;
|
|
232
244
|
bindings: any[];
|
|
@@ -243,7 +255,7 @@ declare class TauriORM {
|
|
|
243
255
|
setWhere?: SQL;
|
|
244
256
|
};
|
|
245
257
|
_returning: null | "__RETURNING_ID__" | Record<string, Column<any>>;
|
|
246
|
-
values(rowOrRows:
|
|
258
|
+
values(rowOrRows: InferInsert<TTable> | Array<InferInsert<TTable>>): /*elided*/ any;
|
|
247
259
|
select(qb: {
|
|
248
260
|
toSQL?: () => {
|
|
249
261
|
clause: string;
|
|
@@ -266,15 +278,15 @@ declare class TauriORM {
|
|
|
266
278
|
_buildConflictClause(): string;
|
|
267
279
|
_executeWithReturning(db: any, query: string, bindings: any[]): Promise<any>;
|
|
268
280
|
};
|
|
269
|
-
update(table:
|
|
270
|
-
_table:
|
|
271
|
-
_data:
|
|
281
|
+
update<TTable extends Table<any>>(table: TTable): {
|
|
282
|
+
_table: TTable;
|
|
283
|
+
_data: Partial<InferInsert<TTable>> | null;
|
|
272
284
|
_where: Record<string, any> | SQL | null;
|
|
273
285
|
_orderBy: Array<string | SQL>;
|
|
274
286
|
_limit: number | null;
|
|
275
287
|
_from: Table<any> | null;
|
|
276
288
|
_returning: null | Record<string, Column<any>>;
|
|
277
|
-
set(data:
|
|
289
|
+
set(data: Partial<InferInsert<TTable>>): /*elided*/ any;
|
|
278
290
|
where(cond: Record<string, any> | SQL): /*elided*/ any;
|
|
279
291
|
orderBy(...clauses: (string | Column<any> | SQL)[]): /*elided*/ any;
|
|
280
292
|
limit(n: number): /*elided*/ any;
|
|
@@ -282,13 +294,13 @@ declare class TauriORM {
|
|
|
282
294
|
returning(fields?: Record<string, Column<any>>): any;
|
|
283
295
|
execute(): Promise<unknown>;
|
|
284
296
|
};
|
|
285
|
-
delete(table:
|
|
286
|
-
_table:
|
|
287
|
-
_where:
|
|
297
|
+
delete<TTable extends Table<any>>(table: TTable): {
|
|
298
|
+
_table: TTable;
|
|
299
|
+
_where: Partial<InferInsert<TTable>> | SQL | null;
|
|
288
300
|
_orderBy: Array<string | SQL>;
|
|
289
301
|
_limit: number | null;
|
|
290
302
|
_returning: null | Record<string, Column<any>>;
|
|
291
|
-
where(cond:
|
|
303
|
+
where(cond: Partial<InferInsert<TTable>> | SQL): /*elided*/ any;
|
|
292
304
|
orderBy(...clauses: (string | Column<any> | SQL)[]): /*elided*/ any;
|
|
293
305
|
limit(n: number): /*elided*/ any;
|
|
294
306
|
returning(fields?: Record<string, Column<any>>): any;
|
|
@@ -299,6 +311,8 @@ declare class TauriORM {
|
|
|
299
311
|
private generateCreateTableSql;
|
|
300
312
|
createTableIfNotExists(table: Table<any>): Promise<void>;
|
|
301
313
|
createTablesIfNotExist(tables: Table<any>[]): Promise<void>;
|
|
314
|
+
private generateCreateIndexSqls;
|
|
315
|
+
private createIndexesForTable;
|
|
302
316
|
private ensureMigrationsTable;
|
|
303
317
|
private hasMigration;
|
|
304
318
|
private recordMigration;
|
|
@@ -306,7 +320,14 @@ declare class TauriORM {
|
|
|
306
320
|
name?: string;
|
|
307
321
|
track?: boolean;
|
|
308
322
|
}): Promise<void>;
|
|
309
|
-
configure
|
|
323
|
+
configure<TTables extends Record<string, Table<any>>, TRelDefs extends Record<string, Record<string, RelationConfig>> = Record<string, Record<string, RelationConfig>>>(tables: TTables, relDefs?: TRelDefs): this & {
|
|
324
|
+
query: {
|
|
325
|
+
[K in keyof TTables]: {
|
|
326
|
+
findMany: (opts?: any) => Promise<Array<InferSelect<TTables[K]>>>;
|
|
327
|
+
findFirst: (opts?: any) => Promise<InferSelect<TTables[K]> | null>;
|
|
328
|
+
};
|
|
329
|
+
};
|
|
330
|
+
};
|
|
310
331
|
migrateConfigured(options?: {
|
|
311
332
|
name?: string;
|
|
312
333
|
track?: boolean;
|
|
@@ -349,6 +370,8 @@ declare class TauriORM {
|
|
|
349
370
|
private setSchemaMeta;
|
|
350
371
|
private normalizeColumn;
|
|
351
372
|
private computeModelSignature;
|
|
373
|
+
getSchemaSignature(): string;
|
|
374
|
+
printSchemaDiff(): Promise<void>;
|
|
352
375
|
isSchemaDirty(): Promise<{
|
|
353
376
|
dirty: boolean;
|
|
354
377
|
current: string;
|
|
@@ -365,6 +388,7 @@ declare class TauriORM {
|
|
|
365
388
|
dropExtraColumns?: boolean;
|
|
366
389
|
preserveData?: boolean;
|
|
367
390
|
}): Promise<void>;
|
|
391
|
+
private forcePushForTables;
|
|
368
392
|
}
|
|
369
393
|
type OneConfig = {
|
|
370
394
|
fields?: Column[];
|
package/dist/index.d.ts
CHANGED
|
@@ -188,6 +188,12 @@ declare const notExists: (subquery: SQL | {
|
|
|
188
188
|
declare const asc: (column: Column) => string;
|
|
189
189
|
declare const desc: (column: Column) => string;
|
|
190
190
|
|
|
191
|
+
type InferInsert<T> = T extends {
|
|
192
|
+
$inferInsert: infer I;
|
|
193
|
+
} ? I : never;
|
|
194
|
+
type InferSelect<T> = T extends {
|
|
195
|
+
$inferSelect: infer S;
|
|
196
|
+
} ? S : never;
|
|
191
197
|
declare class SelectQueryBuilder<T> {
|
|
192
198
|
private _table;
|
|
193
199
|
private _selectedColumns;
|
|
@@ -222,11 +228,17 @@ declare class TauriORM {
|
|
|
222
228
|
constructor(dbUri: string);
|
|
223
229
|
private getDb;
|
|
224
230
|
configureQuery(tables: Record<string, Table<any>>, relations: Record<string, Record<string, RelationConfig>>): void;
|
|
225
|
-
select<
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
231
|
+
select<TFields extends Record<string, Column<any>>>(fields: TFields): SelectQueryBuilder<{
|
|
232
|
+
[K in keyof TFields]: TFields[K]["_dataType"];
|
|
233
|
+
}>;
|
|
234
|
+
select<T = any>(fields?: undefined): SelectQueryBuilder<T>;
|
|
235
|
+
selectDistinct<TFields extends Record<string, Column<any>>>(fields: TFields): SelectQueryBuilder<{
|
|
236
|
+
[K in keyof TFields]: TFields[K]["_dataType"];
|
|
237
|
+
}>;
|
|
238
|
+
selectDistinct<T = any>(fields?: undefined): SelectQueryBuilder<T>;
|
|
239
|
+
insert<TTable extends Table<any>>(table: TTable): {
|
|
240
|
+
_table: TTable;
|
|
241
|
+
_rows: Array<InferInsert<TTable>>;
|
|
230
242
|
_selectSql: {
|
|
231
243
|
clause: string;
|
|
232
244
|
bindings: any[];
|
|
@@ -243,7 +255,7 @@ declare class TauriORM {
|
|
|
243
255
|
setWhere?: SQL;
|
|
244
256
|
};
|
|
245
257
|
_returning: null | "__RETURNING_ID__" | Record<string, Column<any>>;
|
|
246
|
-
values(rowOrRows:
|
|
258
|
+
values(rowOrRows: InferInsert<TTable> | Array<InferInsert<TTable>>): /*elided*/ any;
|
|
247
259
|
select(qb: {
|
|
248
260
|
toSQL?: () => {
|
|
249
261
|
clause: string;
|
|
@@ -266,15 +278,15 @@ declare class TauriORM {
|
|
|
266
278
|
_buildConflictClause(): string;
|
|
267
279
|
_executeWithReturning(db: any, query: string, bindings: any[]): Promise<any>;
|
|
268
280
|
};
|
|
269
|
-
update(table:
|
|
270
|
-
_table:
|
|
271
|
-
_data:
|
|
281
|
+
update<TTable extends Table<any>>(table: TTable): {
|
|
282
|
+
_table: TTable;
|
|
283
|
+
_data: Partial<InferInsert<TTable>> | null;
|
|
272
284
|
_where: Record<string, any> | SQL | null;
|
|
273
285
|
_orderBy: Array<string | SQL>;
|
|
274
286
|
_limit: number | null;
|
|
275
287
|
_from: Table<any> | null;
|
|
276
288
|
_returning: null | Record<string, Column<any>>;
|
|
277
|
-
set(data:
|
|
289
|
+
set(data: Partial<InferInsert<TTable>>): /*elided*/ any;
|
|
278
290
|
where(cond: Record<string, any> | SQL): /*elided*/ any;
|
|
279
291
|
orderBy(...clauses: (string | Column<any> | SQL)[]): /*elided*/ any;
|
|
280
292
|
limit(n: number): /*elided*/ any;
|
|
@@ -282,13 +294,13 @@ declare class TauriORM {
|
|
|
282
294
|
returning(fields?: Record<string, Column<any>>): any;
|
|
283
295
|
execute(): Promise<unknown>;
|
|
284
296
|
};
|
|
285
|
-
delete(table:
|
|
286
|
-
_table:
|
|
287
|
-
_where:
|
|
297
|
+
delete<TTable extends Table<any>>(table: TTable): {
|
|
298
|
+
_table: TTable;
|
|
299
|
+
_where: Partial<InferInsert<TTable>> | SQL | null;
|
|
288
300
|
_orderBy: Array<string | SQL>;
|
|
289
301
|
_limit: number | null;
|
|
290
302
|
_returning: null | Record<string, Column<any>>;
|
|
291
|
-
where(cond:
|
|
303
|
+
where(cond: Partial<InferInsert<TTable>> | SQL): /*elided*/ any;
|
|
292
304
|
orderBy(...clauses: (string | Column<any> | SQL)[]): /*elided*/ any;
|
|
293
305
|
limit(n: number): /*elided*/ any;
|
|
294
306
|
returning(fields?: Record<string, Column<any>>): any;
|
|
@@ -299,6 +311,8 @@ declare class TauriORM {
|
|
|
299
311
|
private generateCreateTableSql;
|
|
300
312
|
createTableIfNotExists(table: Table<any>): Promise<void>;
|
|
301
313
|
createTablesIfNotExist(tables: Table<any>[]): Promise<void>;
|
|
314
|
+
private generateCreateIndexSqls;
|
|
315
|
+
private createIndexesForTable;
|
|
302
316
|
private ensureMigrationsTable;
|
|
303
317
|
private hasMigration;
|
|
304
318
|
private recordMigration;
|
|
@@ -306,7 +320,14 @@ declare class TauriORM {
|
|
|
306
320
|
name?: string;
|
|
307
321
|
track?: boolean;
|
|
308
322
|
}): Promise<void>;
|
|
309
|
-
configure
|
|
323
|
+
configure<TTables extends Record<string, Table<any>>, TRelDefs extends Record<string, Record<string, RelationConfig>> = Record<string, Record<string, RelationConfig>>>(tables: TTables, relDefs?: TRelDefs): this & {
|
|
324
|
+
query: {
|
|
325
|
+
[K in keyof TTables]: {
|
|
326
|
+
findMany: (opts?: any) => Promise<Array<InferSelect<TTables[K]>>>;
|
|
327
|
+
findFirst: (opts?: any) => Promise<InferSelect<TTables[K]> | null>;
|
|
328
|
+
};
|
|
329
|
+
};
|
|
330
|
+
};
|
|
310
331
|
migrateConfigured(options?: {
|
|
311
332
|
name?: string;
|
|
312
333
|
track?: boolean;
|
|
@@ -349,6 +370,8 @@ declare class TauriORM {
|
|
|
349
370
|
private setSchemaMeta;
|
|
350
371
|
private normalizeColumn;
|
|
351
372
|
private computeModelSignature;
|
|
373
|
+
getSchemaSignature(): string;
|
|
374
|
+
printSchemaDiff(): Promise<void>;
|
|
352
375
|
isSchemaDirty(): Promise<{
|
|
353
376
|
dirty: boolean;
|
|
354
377
|
current: string;
|
|
@@ -365,6 +388,7 @@ declare class TauriORM {
|
|
|
365
388
|
dropExtraColumns?: boolean;
|
|
366
389
|
preserveData?: boolean;
|
|
367
390
|
}): Promise<void>;
|
|
391
|
+
private forcePushForTables;
|
|
368
392
|
}
|
|
369
393
|
type OneConfig = {
|
|
370
394
|
fields?: Column[];
|
package/dist/index.js
CHANGED
|
@@ -213,12 +213,19 @@ function unique(name) {
|
|
|
213
213
|
return {
|
|
214
214
|
on: (...cols) => ({
|
|
215
215
|
name,
|
|
216
|
-
columns: cols.map((c) => c.name)
|
|
216
|
+
columns: cols.map((c) => c.name),
|
|
217
|
+
// runtime marker for DDL rendering
|
|
218
|
+
kind: "unique"
|
|
217
219
|
})
|
|
218
220
|
};
|
|
219
221
|
}
|
|
220
222
|
function primaryKey(opts) {
|
|
221
|
-
return {
|
|
223
|
+
return {
|
|
224
|
+
name: opts.name,
|
|
225
|
+
columns: opts.columns.map((c) => c.name),
|
|
226
|
+
// runtime marker for DDL rendering
|
|
227
|
+
kind: "primaryKey"
|
|
228
|
+
};
|
|
222
229
|
}
|
|
223
230
|
function check(name, expr) {
|
|
224
231
|
return { name, expr };
|
|
@@ -647,7 +654,10 @@ var TauriORM = class {
|
|
|
647
654
|
_relations = null;
|
|
648
655
|
_dbPromise;
|
|
649
656
|
constructor(dbUri) {
|
|
650
|
-
this._dbPromise = import_plugin_sql.default.load(dbUri)
|
|
657
|
+
this._dbPromise = import_plugin_sql.default.load(dbUri).then(async (db) => {
|
|
658
|
+
await db.execute("PRAGMA foreign_keys = ON");
|
|
659
|
+
return db;
|
|
660
|
+
});
|
|
651
661
|
}
|
|
652
662
|
async getDb() {
|
|
653
663
|
return this._dbPromise;
|
|
@@ -721,19 +731,32 @@ var TauriORM = class {
|
|
|
721
731
|
return ret;
|
|
722
732
|
}
|
|
723
733
|
for (const data of this._rows) {
|
|
724
|
-
|
|
734
|
+
let coerceValue2 = function(col, value) {
|
|
735
|
+
if (col && col.mode === "boolean") {
|
|
736
|
+
return value ? 1 : 0;
|
|
737
|
+
}
|
|
738
|
+
if (value instanceof Date) {
|
|
739
|
+
if (col && col.mode === "timestamp_ms") return value.getTime();
|
|
740
|
+
if (col && col.mode === "timestamp")
|
|
741
|
+
return Math.floor(value.getTime() / 1e3);
|
|
742
|
+
}
|
|
743
|
+
return value;
|
|
744
|
+
};
|
|
745
|
+
var coerceValue = coerceValue2;
|
|
746
|
+
const finalData = Object.assign({}, data);
|
|
725
747
|
const schema = this._table._schema;
|
|
726
748
|
for (const [key, col] of Object.entries(schema)) {
|
|
727
749
|
if (finalData[key] === void 0) {
|
|
728
750
|
if (col.defaultFn) {
|
|
729
|
-
finalData[key] = col.defaultFn();
|
|
751
|
+
finalData[key] = coerceValue2(col, col.defaultFn());
|
|
730
752
|
} else if (col.onUpdateFn) {
|
|
731
|
-
finalData[key] = col.onUpdateFn();
|
|
753
|
+
finalData[key] = coerceValue2(col, col.onUpdateFn());
|
|
732
754
|
}
|
|
733
755
|
}
|
|
734
756
|
}
|
|
735
|
-
const
|
|
736
|
-
const
|
|
757
|
+
const entries = Object.entries(finalData);
|
|
758
|
+
const keys = entries.map(([k]) => schema[k]?.name ?? k);
|
|
759
|
+
const values = entries.map(([k, v]) => coerceValue2(schema[k], v));
|
|
737
760
|
const placeholders = values.map(() => "?").join(", ");
|
|
738
761
|
let query = `INSERT INTO ${this._table._tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
|
|
739
762
|
const bindings = [...values];
|
|
@@ -831,7 +854,13 @@ var TauriORM = class {
|
|
|
831
854
|
const dataToSet = { ...this._data };
|
|
832
855
|
for (const [key, col] of Object.entries(schema)) {
|
|
833
856
|
if (!(key in dataToSet) && col.onUpdateFn) {
|
|
834
|
-
|
|
857
|
+
const v = col.onUpdateFn();
|
|
858
|
+
if (col.mode === "boolean") dataToSet[key] = v ? 1 : 0;
|
|
859
|
+
else if (v instanceof Date) {
|
|
860
|
+
if (col.mode === "timestamp_ms") dataToSet[key] = v.getTime();
|
|
861
|
+
else if (col.mode === "timestamp") dataToSet[key] = Math.floor(v.getTime() / 1e3);
|
|
862
|
+
else dataToSet[key] = v;
|
|
863
|
+
} else dataToSet[key] = v;
|
|
835
864
|
}
|
|
836
865
|
}
|
|
837
866
|
const setParts = [];
|
|
@@ -840,11 +869,20 @@ var TauriORM = class {
|
|
|
840
869
|
if (v === void 0) continue;
|
|
841
870
|
if (v && typeof v === "object" && typeof v.toSQL === "function") {
|
|
842
871
|
const s = v.toSQL();
|
|
843
|
-
|
|
872
|
+
const colName = schema[k]?.name ?? k;
|
|
873
|
+
setParts.push(`${colName} = ${s.clause}`);
|
|
844
874
|
bindings.push(...s.bindings);
|
|
845
875
|
} else {
|
|
846
|
-
|
|
847
|
-
|
|
876
|
+
const colName = schema[k]?.name ?? k;
|
|
877
|
+
let val = v;
|
|
878
|
+
const col = schema[k];
|
|
879
|
+
if (col && col.mode === "boolean") val = v ? 1 : 0;
|
|
880
|
+
else if (v instanceof Date) {
|
|
881
|
+
if (col && col.mode === "timestamp_ms") val = v.getTime();
|
|
882
|
+
else if (col && col.mode === "timestamp") val = Math.floor(v.getTime() / 1e3);
|
|
883
|
+
}
|
|
884
|
+
setParts.push(`${colName} = ?`);
|
|
885
|
+
bindings.push(val);
|
|
848
886
|
}
|
|
849
887
|
}
|
|
850
888
|
let query = `UPDATE ${this._table._tableName} SET ${setParts.join(", ")}`;
|
|
@@ -857,7 +895,7 @@ var TauriORM = class {
|
|
|
857
895
|
} else {
|
|
858
896
|
const entries = Object.entries(this._where);
|
|
859
897
|
if (entries.length > 0) {
|
|
860
|
-
query += ` WHERE ${entries.map(([k]) => `${k} = ?`).join(" AND ")}`;
|
|
898
|
+
query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
|
|
861
899
|
bindings.push(...entries.map(([, v]) => v));
|
|
862
900
|
}
|
|
863
901
|
}
|
|
@@ -933,7 +971,8 @@ var TauriORM = class {
|
|
|
933
971
|
} else {
|
|
934
972
|
const entries = Object.entries(this._where);
|
|
935
973
|
if (entries.length > 0) {
|
|
936
|
-
|
|
974
|
+
const schema = this._table._schema;
|
|
975
|
+
query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
|
|
937
976
|
bindings.push(...entries.map(([, v]) => v));
|
|
938
977
|
}
|
|
939
978
|
}
|
|
@@ -1016,19 +1055,86 @@ var TauriORM = class {
|
|
|
1016
1055
|
}
|
|
1017
1056
|
return def;
|
|
1018
1057
|
});
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
)
|
|
1058
|
+
const tableConstraints = [];
|
|
1059
|
+
const constraints = table._constraints;
|
|
1060
|
+
if (constraints && constraints.length) {
|
|
1061
|
+
for (const spec of constraints) {
|
|
1062
|
+
if (spec.expr) {
|
|
1063
|
+
const name = spec.name;
|
|
1064
|
+
const expr = spec.expr.raw ?? spec.expr?.raw ?? String(spec.expr);
|
|
1065
|
+
tableConstraints.push(
|
|
1066
|
+
name ? `CONSTRAINT ${name} CHECK (${expr})` : `CHECK (${expr})`
|
|
1067
|
+
);
|
|
1068
|
+
continue;
|
|
1069
|
+
}
|
|
1070
|
+
if (spec.foreignColumns) {
|
|
1071
|
+
const name = spec.name;
|
|
1072
|
+
const cols = spec.columns.join(", ");
|
|
1073
|
+
const fTable = spec.foreignTable;
|
|
1074
|
+
const fCols = spec.foreignColumns.join(", ");
|
|
1075
|
+
let clause = `${name ? `CONSTRAINT ${name} ` : ""}FOREIGN KEY (${cols}) REFERENCES ${fTable} (${fCols})`;
|
|
1076
|
+
if (spec.onDelete)
|
|
1077
|
+
clause += ` ON DELETE ${String(
|
|
1078
|
+
spec.onDelete
|
|
1079
|
+
).toUpperCase()}`;
|
|
1080
|
+
if (spec.onUpdate)
|
|
1081
|
+
clause += ` ON UPDATE ${String(
|
|
1082
|
+
spec.onUpdate
|
|
1083
|
+
).toUpperCase()}`;
|
|
1084
|
+
tableConstraints.push(clause);
|
|
1085
|
+
continue;
|
|
1086
|
+
}
|
|
1087
|
+
if (spec.columns) {
|
|
1088
|
+
const cols = spec.columns.join(", ");
|
|
1089
|
+
const name = spec.name;
|
|
1090
|
+
const isPk = spec.kind === "primaryKey" || name && name.toLowerCase().includes("pk");
|
|
1091
|
+
if (isPk) {
|
|
1092
|
+
tableConstraints.push(
|
|
1093
|
+
name ? `CONSTRAINT ${name} PRIMARY KEY (${cols})` : `PRIMARY KEY (${cols})`
|
|
1094
|
+
);
|
|
1095
|
+
} else {
|
|
1096
|
+
tableConstraints.push(
|
|
1097
|
+
name ? `CONSTRAINT ${name} UNIQUE (${cols})` : `UNIQUE (${cols})`
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
const parts = [...columnDefs, ...tableConstraints];
|
|
1105
|
+
return `CREATE TABLE IF NOT EXISTS ${tableName} (${parts.join(", ")});`;
|
|
1022
1106
|
}
|
|
1023
1107
|
async createTableIfNotExists(table) {
|
|
1024
1108
|
const sql2 = this.generateCreateTableSql(table);
|
|
1025
1109
|
await this.run(sql2);
|
|
1110
|
+
await this.createIndexesForTable(table);
|
|
1026
1111
|
}
|
|
1027
1112
|
async createTablesIfNotExist(tables) {
|
|
1028
1113
|
for (const t of tables) {
|
|
1029
1114
|
await this.createTableIfNotExists(t);
|
|
1030
1115
|
}
|
|
1031
1116
|
}
|
|
1117
|
+
generateCreateIndexSqls(table) {
|
|
1118
|
+
const tableName = table._tableName;
|
|
1119
|
+
const indexes = table._indexes || [];
|
|
1120
|
+
const stmts = [];
|
|
1121
|
+
for (const idx of indexes) {
|
|
1122
|
+
const unique2 = idx.unique ? "UNIQUE " : "";
|
|
1123
|
+
if (!idx.name) continue;
|
|
1124
|
+
const colList = Array.isArray(idx.columns) ? idx.columns : [];
|
|
1125
|
+
if (colList.length === 0) continue;
|
|
1126
|
+
const cols = `(${colList.join(", ")})`;
|
|
1127
|
+
const where = idx.where?.raw ? ` WHERE ${idx.where.raw}` : "";
|
|
1128
|
+
stmts.push(
|
|
1129
|
+
`CREATE ${unique2}INDEX IF NOT EXISTS ${idx.name} ON ${tableName} ${cols}${where};`
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
return stmts;
|
|
1133
|
+
}
|
|
1134
|
+
async createIndexesForTable(table) {
|
|
1135
|
+
const stmts = this.generateCreateIndexSqls(table);
|
|
1136
|
+
for (const s of stmts) await this.run(s);
|
|
1137
|
+
}
|
|
1032
1138
|
async ensureMigrationsTable() {
|
|
1033
1139
|
await this.run(
|
|
1034
1140
|
`CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)`
|
|
@@ -1053,20 +1159,23 @@ var TauriORM = class {
|
|
|
1053
1159
|
const track = options?.track ?? true;
|
|
1054
1160
|
if (track) {
|
|
1055
1161
|
await this.ensureMigrationsTable();
|
|
1162
|
+
}
|
|
1163
|
+
await this.forcePushForTables(tables, { preserveData: true });
|
|
1164
|
+
if (track) {
|
|
1056
1165
|
const name = options?.name ?? `init:${tables.map((t) => t._tableName).join(",")}`;
|
|
1057
1166
|
const already = await this.hasMigration(name);
|
|
1058
|
-
if (already)
|
|
1059
|
-
await this.createTablesIfNotExist(tables);
|
|
1060
|
-
await this.recordMigration(name);
|
|
1061
|
-
return;
|
|
1167
|
+
if (!already) await this.recordMigration(name);
|
|
1062
1168
|
}
|
|
1063
|
-
await this.createTablesIfNotExist(tables);
|
|
1064
1169
|
}
|
|
1065
1170
|
// Configure schema and relations, and generate db.query automatically
|
|
1066
1171
|
configure(tables, relDefs) {
|
|
1067
1172
|
this._tables = tables;
|
|
1068
1173
|
this._relations = relDefs ?? {};
|
|
1069
|
-
this.query = makeQueryAPI(
|
|
1174
|
+
this.query = makeQueryAPI(
|
|
1175
|
+
tables,
|
|
1176
|
+
this._relations ?? {},
|
|
1177
|
+
this.getDb.bind(this)
|
|
1178
|
+
);
|
|
1070
1179
|
return this;
|
|
1071
1180
|
}
|
|
1072
1181
|
// Convenience: migrate from configured tables
|
|
@@ -1074,6 +1183,7 @@ var TauriORM = class {
|
|
|
1074
1183
|
if (!this._tables)
|
|
1075
1184
|
throw new Error("No tables configured. Call db.configure({...}) first.");
|
|
1076
1185
|
await this.migrate(Object.values(this._tables), options);
|
|
1186
|
+
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
1077
1187
|
}
|
|
1078
1188
|
// --- Schema diff and CLI-like helpers ---
|
|
1079
1189
|
async diffSchema() {
|
|
@@ -1200,6 +1310,13 @@ var TauriORM = class {
|
|
|
1200
1310
|
entries.sort((a, b) => a.table.localeCompare(b.table));
|
|
1201
1311
|
return JSON.stringify(entries);
|
|
1202
1312
|
}
|
|
1313
|
+
getSchemaSignature() {
|
|
1314
|
+
return this.computeModelSignature();
|
|
1315
|
+
}
|
|
1316
|
+
async printSchemaDiff() {
|
|
1317
|
+
const diff = await this.diffSchema();
|
|
1318
|
+
console.log("Schema diff:", JSON.stringify(diff, null, 2));
|
|
1319
|
+
}
|
|
1203
1320
|
async isSchemaDirty() {
|
|
1204
1321
|
const sig = this.computeModelSignature();
|
|
1205
1322
|
const stored = await this.getSchemaMeta("schema_signature");
|
|
@@ -1209,7 +1326,9 @@ var TauriORM = class {
|
|
|
1209
1326
|
const status = await this.isSchemaDirty();
|
|
1210
1327
|
if (!this._tables) throw new Error("No tables configured.");
|
|
1211
1328
|
if (status.dirty) {
|
|
1212
|
-
await this.
|
|
1329
|
+
await this.forcePushForTables(Object.values(this._tables), {
|
|
1330
|
+
preserveData: true
|
|
1331
|
+
});
|
|
1213
1332
|
await this.setSchemaMeta(
|
|
1214
1333
|
"schema_signature",
|
|
1215
1334
|
this.computeModelSignature()
|
|
@@ -1250,13 +1369,17 @@ var TauriORM = class {
|
|
|
1250
1369
|
// Force push model to DB: add missing tables/columns, rebuild tables if incompatible
|
|
1251
1370
|
async forcePush(options) {
|
|
1252
1371
|
if (!this._tables) throw new Error("No tables configured.");
|
|
1372
|
+
await this.forcePushForTables(Object.values(this._tables), options);
|
|
1373
|
+
}
|
|
1374
|
+
async forcePushForTables(tables, options) {
|
|
1253
1375
|
const dbi = await this.getDb();
|
|
1254
1376
|
const preserve = options?.preserveData !== false;
|
|
1255
|
-
for (const tbl of
|
|
1377
|
+
for (const tbl of tables) {
|
|
1256
1378
|
const tableName = tbl._tableName;
|
|
1257
1379
|
const exists2 = await this.tableExists(tableName);
|
|
1258
1380
|
if (!exists2) {
|
|
1259
1381
|
await this.run(this.buildCreateTableSQL(tbl));
|
|
1382
|
+
await this.createIndexesForTable(tbl);
|
|
1260
1383
|
continue;
|
|
1261
1384
|
}
|
|
1262
1385
|
const existingCols = await dbi.select(
|
|
@@ -1301,6 +1424,7 @@ var TauriORM = class {
|
|
|
1301
1424
|
}
|
|
1302
1425
|
await this.run(`DROP TABLE ${tableName}`);
|
|
1303
1426
|
await this.run(`ALTER TABLE ${tmp} RENAME TO ${tableName}`);
|
|
1427
|
+
await this.createIndexesForTable(tbl);
|
|
1304
1428
|
} else {
|
|
1305
1429
|
for (const m of missing) {
|
|
1306
1430
|
let clause = `${m.name} ${m.type}`;
|
|
@@ -1311,6 +1435,7 @@ var TauriORM = class {
|
|
|
1311
1435
|
}
|
|
1312
1436
|
await this.run(`ALTER TABLE ${tableName} ADD COLUMN ${clause}`);
|
|
1313
1437
|
}
|
|
1438
|
+
await this.createIndexesForTable(tbl);
|
|
1314
1439
|
}
|
|
1315
1440
|
}
|
|
1316
1441
|
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
package/dist/index.mjs
CHANGED
|
@@ -135,12 +135,19 @@ function unique(name) {
|
|
|
135
135
|
return {
|
|
136
136
|
on: (...cols) => ({
|
|
137
137
|
name,
|
|
138
|
-
columns: cols.map((c) => c.name)
|
|
138
|
+
columns: cols.map((c) => c.name),
|
|
139
|
+
// runtime marker for DDL rendering
|
|
140
|
+
kind: "unique"
|
|
139
141
|
})
|
|
140
142
|
};
|
|
141
143
|
}
|
|
142
144
|
function primaryKey(opts) {
|
|
143
|
-
return {
|
|
145
|
+
return {
|
|
146
|
+
name: opts.name,
|
|
147
|
+
columns: opts.columns.map((c) => c.name),
|
|
148
|
+
// runtime marker for DDL rendering
|
|
149
|
+
kind: "primaryKey"
|
|
150
|
+
};
|
|
144
151
|
}
|
|
145
152
|
function check(name, expr) {
|
|
146
153
|
return { name, expr };
|
|
@@ -569,7 +576,10 @@ var TauriORM = class {
|
|
|
569
576
|
_relations = null;
|
|
570
577
|
_dbPromise;
|
|
571
578
|
constructor(dbUri) {
|
|
572
|
-
this._dbPromise = Database.load(dbUri)
|
|
579
|
+
this._dbPromise = Database.load(dbUri).then(async (db) => {
|
|
580
|
+
await db.execute("PRAGMA foreign_keys = ON");
|
|
581
|
+
return db;
|
|
582
|
+
});
|
|
573
583
|
}
|
|
574
584
|
async getDb() {
|
|
575
585
|
return this._dbPromise;
|
|
@@ -643,19 +653,32 @@ var TauriORM = class {
|
|
|
643
653
|
return ret;
|
|
644
654
|
}
|
|
645
655
|
for (const data of this._rows) {
|
|
646
|
-
|
|
656
|
+
let coerceValue2 = function(col, value) {
|
|
657
|
+
if (col && col.mode === "boolean") {
|
|
658
|
+
return value ? 1 : 0;
|
|
659
|
+
}
|
|
660
|
+
if (value instanceof Date) {
|
|
661
|
+
if (col && col.mode === "timestamp_ms") return value.getTime();
|
|
662
|
+
if (col && col.mode === "timestamp")
|
|
663
|
+
return Math.floor(value.getTime() / 1e3);
|
|
664
|
+
}
|
|
665
|
+
return value;
|
|
666
|
+
};
|
|
667
|
+
var coerceValue = coerceValue2;
|
|
668
|
+
const finalData = Object.assign({}, data);
|
|
647
669
|
const schema = this._table._schema;
|
|
648
670
|
for (const [key, col] of Object.entries(schema)) {
|
|
649
671
|
if (finalData[key] === void 0) {
|
|
650
672
|
if (col.defaultFn) {
|
|
651
|
-
finalData[key] = col.defaultFn();
|
|
673
|
+
finalData[key] = coerceValue2(col, col.defaultFn());
|
|
652
674
|
} else if (col.onUpdateFn) {
|
|
653
|
-
finalData[key] = col.onUpdateFn();
|
|
675
|
+
finalData[key] = coerceValue2(col, col.onUpdateFn());
|
|
654
676
|
}
|
|
655
677
|
}
|
|
656
678
|
}
|
|
657
|
-
const
|
|
658
|
-
const
|
|
679
|
+
const entries = Object.entries(finalData);
|
|
680
|
+
const keys = entries.map(([k]) => schema[k]?.name ?? k);
|
|
681
|
+
const values = entries.map(([k, v]) => coerceValue2(schema[k], v));
|
|
659
682
|
const placeholders = values.map(() => "?").join(", ");
|
|
660
683
|
let query = `INSERT INTO ${this._table._tableName} (${keys.join(", ")}) VALUES (${placeholders})`;
|
|
661
684
|
const bindings = [...values];
|
|
@@ -753,7 +776,13 @@ var TauriORM = class {
|
|
|
753
776
|
const dataToSet = { ...this._data };
|
|
754
777
|
for (const [key, col] of Object.entries(schema)) {
|
|
755
778
|
if (!(key in dataToSet) && col.onUpdateFn) {
|
|
756
|
-
|
|
779
|
+
const v = col.onUpdateFn();
|
|
780
|
+
if (col.mode === "boolean") dataToSet[key] = v ? 1 : 0;
|
|
781
|
+
else if (v instanceof Date) {
|
|
782
|
+
if (col.mode === "timestamp_ms") dataToSet[key] = v.getTime();
|
|
783
|
+
else if (col.mode === "timestamp") dataToSet[key] = Math.floor(v.getTime() / 1e3);
|
|
784
|
+
else dataToSet[key] = v;
|
|
785
|
+
} else dataToSet[key] = v;
|
|
757
786
|
}
|
|
758
787
|
}
|
|
759
788
|
const setParts = [];
|
|
@@ -762,11 +791,20 @@ var TauriORM = class {
|
|
|
762
791
|
if (v === void 0) continue;
|
|
763
792
|
if (v && typeof v === "object" && typeof v.toSQL === "function") {
|
|
764
793
|
const s = v.toSQL();
|
|
765
|
-
|
|
794
|
+
const colName = schema[k]?.name ?? k;
|
|
795
|
+
setParts.push(`${colName} = ${s.clause}`);
|
|
766
796
|
bindings.push(...s.bindings);
|
|
767
797
|
} else {
|
|
768
|
-
|
|
769
|
-
|
|
798
|
+
const colName = schema[k]?.name ?? k;
|
|
799
|
+
let val = v;
|
|
800
|
+
const col = schema[k];
|
|
801
|
+
if (col && col.mode === "boolean") val = v ? 1 : 0;
|
|
802
|
+
else if (v instanceof Date) {
|
|
803
|
+
if (col && col.mode === "timestamp_ms") val = v.getTime();
|
|
804
|
+
else if (col && col.mode === "timestamp") val = Math.floor(v.getTime() / 1e3);
|
|
805
|
+
}
|
|
806
|
+
setParts.push(`${colName} = ?`);
|
|
807
|
+
bindings.push(val);
|
|
770
808
|
}
|
|
771
809
|
}
|
|
772
810
|
let query = `UPDATE ${this._table._tableName} SET ${setParts.join(", ")}`;
|
|
@@ -779,7 +817,7 @@ var TauriORM = class {
|
|
|
779
817
|
} else {
|
|
780
818
|
const entries = Object.entries(this._where);
|
|
781
819
|
if (entries.length > 0) {
|
|
782
|
-
query += ` WHERE ${entries.map(([k]) => `${k} = ?`).join(" AND ")}`;
|
|
820
|
+
query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
|
|
783
821
|
bindings.push(...entries.map(([, v]) => v));
|
|
784
822
|
}
|
|
785
823
|
}
|
|
@@ -855,7 +893,8 @@ var TauriORM = class {
|
|
|
855
893
|
} else {
|
|
856
894
|
const entries = Object.entries(this._where);
|
|
857
895
|
if (entries.length > 0) {
|
|
858
|
-
|
|
896
|
+
const schema = this._table._schema;
|
|
897
|
+
query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
|
|
859
898
|
bindings.push(...entries.map(([, v]) => v));
|
|
860
899
|
}
|
|
861
900
|
}
|
|
@@ -938,19 +977,86 @@ var TauriORM = class {
|
|
|
938
977
|
}
|
|
939
978
|
return def;
|
|
940
979
|
});
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
)
|
|
980
|
+
const tableConstraints = [];
|
|
981
|
+
const constraints = table._constraints;
|
|
982
|
+
if (constraints && constraints.length) {
|
|
983
|
+
for (const spec of constraints) {
|
|
984
|
+
if (spec.expr) {
|
|
985
|
+
const name = spec.name;
|
|
986
|
+
const expr = spec.expr.raw ?? spec.expr?.raw ?? String(spec.expr);
|
|
987
|
+
tableConstraints.push(
|
|
988
|
+
name ? `CONSTRAINT ${name} CHECK (${expr})` : `CHECK (${expr})`
|
|
989
|
+
);
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
if (spec.foreignColumns) {
|
|
993
|
+
const name = spec.name;
|
|
994
|
+
const cols = spec.columns.join(", ");
|
|
995
|
+
const fTable = spec.foreignTable;
|
|
996
|
+
const fCols = spec.foreignColumns.join(", ");
|
|
997
|
+
let clause = `${name ? `CONSTRAINT ${name} ` : ""}FOREIGN KEY (${cols}) REFERENCES ${fTable} (${fCols})`;
|
|
998
|
+
if (spec.onDelete)
|
|
999
|
+
clause += ` ON DELETE ${String(
|
|
1000
|
+
spec.onDelete
|
|
1001
|
+
).toUpperCase()}`;
|
|
1002
|
+
if (spec.onUpdate)
|
|
1003
|
+
clause += ` ON UPDATE ${String(
|
|
1004
|
+
spec.onUpdate
|
|
1005
|
+
).toUpperCase()}`;
|
|
1006
|
+
tableConstraints.push(clause);
|
|
1007
|
+
continue;
|
|
1008
|
+
}
|
|
1009
|
+
if (spec.columns) {
|
|
1010
|
+
const cols = spec.columns.join(", ");
|
|
1011
|
+
const name = spec.name;
|
|
1012
|
+
const isPk = spec.kind === "primaryKey" || name && name.toLowerCase().includes("pk");
|
|
1013
|
+
if (isPk) {
|
|
1014
|
+
tableConstraints.push(
|
|
1015
|
+
name ? `CONSTRAINT ${name} PRIMARY KEY (${cols})` : `PRIMARY KEY (${cols})`
|
|
1016
|
+
);
|
|
1017
|
+
} else {
|
|
1018
|
+
tableConstraints.push(
|
|
1019
|
+
name ? `CONSTRAINT ${name} UNIQUE (${cols})` : `UNIQUE (${cols})`
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
continue;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
const parts = [...columnDefs, ...tableConstraints];
|
|
1027
|
+
return `CREATE TABLE IF NOT EXISTS ${tableName} (${parts.join(", ")});`;
|
|
944
1028
|
}
|
|
945
1029
|
async createTableIfNotExists(table) {
|
|
946
1030
|
const sql2 = this.generateCreateTableSql(table);
|
|
947
1031
|
await this.run(sql2);
|
|
1032
|
+
await this.createIndexesForTable(table);
|
|
948
1033
|
}
|
|
949
1034
|
async createTablesIfNotExist(tables) {
|
|
950
1035
|
for (const t of tables) {
|
|
951
1036
|
await this.createTableIfNotExists(t);
|
|
952
1037
|
}
|
|
953
1038
|
}
|
|
1039
|
+
generateCreateIndexSqls(table) {
|
|
1040
|
+
const tableName = table._tableName;
|
|
1041
|
+
const indexes = table._indexes || [];
|
|
1042
|
+
const stmts = [];
|
|
1043
|
+
for (const idx of indexes) {
|
|
1044
|
+
const unique2 = idx.unique ? "UNIQUE " : "";
|
|
1045
|
+
if (!idx.name) continue;
|
|
1046
|
+
const colList = Array.isArray(idx.columns) ? idx.columns : [];
|
|
1047
|
+
if (colList.length === 0) continue;
|
|
1048
|
+
const cols = `(${colList.join(", ")})`;
|
|
1049
|
+
const where = idx.where?.raw ? ` WHERE ${idx.where.raw}` : "";
|
|
1050
|
+
stmts.push(
|
|
1051
|
+
`CREATE ${unique2}INDEX IF NOT EXISTS ${idx.name} ON ${tableName} ${cols}${where};`
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
return stmts;
|
|
1055
|
+
}
|
|
1056
|
+
async createIndexesForTable(table) {
|
|
1057
|
+
const stmts = this.generateCreateIndexSqls(table);
|
|
1058
|
+
for (const s of stmts) await this.run(s);
|
|
1059
|
+
}
|
|
954
1060
|
async ensureMigrationsTable() {
|
|
955
1061
|
await this.run(
|
|
956
1062
|
`CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)`
|
|
@@ -975,20 +1081,23 @@ var TauriORM = class {
|
|
|
975
1081
|
const track = options?.track ?? true;
|
|
976
1082
|
if (track) {
|
|
977
1083
|
await this.ensureMigrationsTable();
|
|
1084
|
+
}
|
|
1085
|
+
await this.forcePushForTables(tables, { preserveData: true });
|
|
1086
|
+
if (track) {
|
|
978
1087
|
const name = options?.name ?? `init:${tables.map((t) => t._tableName).join(",")}`;
|
|
979
1088
|
const already = await this.hasMigration(name);
|
|
980
|
-
if (already)
|
|
981
|
-
await this.createTablesIfNotExist(tables);
|
|
982
|
-
await this.recordMigration(name);
|
|
983
|
-
return;
|
|
1089
|
+
if (!already) await this.recordMigration(name);
|
|
984
1090
|
}
|
|
985
|
-
await this.createTablesIfNotExist(tables);
|
|
986
1091
|
}
|
|
987
1092
|
// Configure schema and relations, and generate db.query automatically
|
|
988
1093
|
configure(tables, relDefs) {
|
|
989
1094
|
this._tables = tables;
|
|
990
1095
|
this._relations = relDefs ?? {};
|
|
991
|
-
this.query = makeQueryAPI(
|
|
1096
|
+
this.query = makeQueryAPI(
|
|
1097
|
+
tables,
|
|
1098
|
+
this._relations ?? {},
|
|
1099
|
+
this.getDb.bind(this)
|
|
1100
|
+
);
|
|
992
1101
|
return this;
|
|
993
1102
|
}
|
|
994
1103
|
// Convenience: migrate from configured tables
|
|
@@ -996,6 +1105,7 @@ var TauriORM = class {
|
|
|
996
1105
|
if (!this._tables)
|
|
997
1106
|
throw new Error("No tables configured. Call db.configure({...}) first.");
|
|
998
1107
|
await this.migrate(Object.values(this._tables), options);
|
|
1108
|
+
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
999
1109
|
}
|
|
1000
1110
|
// --- Schema diff and CLI-like helpers ---
|
|
1001
1111
|
async diffSchema() {
|
|
@@ -1122,6 +1232,13 @@ var TauriORM = class {
|
|
|
1122
1232
|
entries.sort((a, b) => a.table.localeCompare(b.table));
|
|
1123
1233
|
return JSON.stringify(entries);
|
|
1124
1234
|
}
|
|
1235
|
+
getSchemaSignature() {
|
|
1236
|
+
return this.computeModelSignature();
|
|
1237
|
+
}
|
|
1238
|
+
async printSchemaDiff() {
|
|
1239
|
+
const diff = await this.diffSchema();
|
|
1240
|
+
console.log("Schema diff:", JSON.stringify(diff, null, 2));
|
|
1241
|
+
}
|
|
1125
1242
|
async isSchemaDirty() {
|
|
1126
1243
|
const sig = this.computeModelSignature();
|
|
1127
1244
|
const stored = await this.getSchemaMeta("schema_signature");
|
|
@@ -1131,7 +1248,9 @@ var TauriORM = class {
|
|
|
1131
1248
|
const status = await this.isSchemaDirty();
|
|
1132
1249
|
if (!this._tables) throw new Error("No tables configured.");
|
|
1133
1250
|
if (status.dirty) {
|
|
1134
|
-
await this.
|
|
1251
|
+
await this.forcePushForTables(Object.values(this._tables), {
|
|
1252
|
+
preserveData: true
|
|
1253
|
+
});
|
|
1135
1254
|
await this.setSchemaMeta(
|
|
1136
1255
|
"schema_signature",
|
|
1137
1256
|
this.computeModelSignature()
|
|
@@ -1172,13 +1291,17 @@ var TauriORM = class {
|
|
|
1172
1291
|
// Force push model to DB: add missing tables/columns, rebuild tables if incompatible
|
|
1173
1292
|
async forcePush(options) {
|
|
1174
1293
|
if (!this._tables) throw new Error("No tables configured.");
|
|
1294
|
+
await this.forcePushForTables(Object.values(this._tables), options);
|
|
1295
|
+
}
|
|
1296
|
+
async forcePushForTables(tables, options) {
|
|
1175
1297
|
const dbi = await this.getDb();
|
|
1176
1298
|
const preserve = options?.preserveData !== false;
|
|
1177
|
-
for (const tbl of
|
|
1299
|
+
for (const tbl of tables) {
|
|
1178
1300
|
const tableName = tbl._tableName;
|
|
1179
1301
|
const exists2 = await this.tableExists(tableName);
|
|
1180
1302
|
if (!exists2) {
|
|
1181
1303
|
await this.run(this.buildCreateTableSQL(tbl));
|
|
1304
|
+
await this.createIndexesForTable(tbl);
|
|
1182
1305
|
continue;
|
|
1183
1306
|
}
|
|
1184
1307
|
const existingCols = await dbi.select(
|
|
@@ -1223,6 +1346,7 @@ var TauriORM = class {
|
|
|
1223
1346
|
}
|
|
1224
1347
|
await this.run(`DROP TABLE ${tableName}`);
|
|
1225
1348
|
await this.run(`ALTER TABLE ${tmp} RENAME TO ${tableName}`);
|
|
1349
|
+
await this.createIndexesForTable(tbl);
|
|
1226
1350
|
} else {
|
|
1227
1351
|
for (const m of missing) {
|
|
1228
1352
|
let clause = `${m.name} ${m.type}`;
|
|
@@ -1233,6 +1357,7 @@ var TauriORM = class {
|
|
|
1233
1357
|
}
|
|
1234
1358
|
await this.run(`ALTER TABLE ${tableName} ADD COLUMN ${clause}`);
|
|
1235
1359
|
}
|
|
1360
|
+
await this.createIndexesForTable(tbl);
|
|
1236
1361
|
}
|
|
1237
1362
|
}
|
|
1238
1363
|
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|