@type32/tauri-sqlite-orm 0.1.8 → 0.1.9
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 +111 -15
- package/dist/index.mjs +111 -15
- 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,7 +731,7 @@ var TauriORM = class {
|
|
|
721
731
|
return ret;
|
|
722
732
|
}
|
|
723
733
|
for (const data of this._rows) {
|
|
724
|
-
const finalData = {
|
|
734
|
+
const finalData = Object.assign({}, data);
|
|
725
735
|
const schema = this._table._schema;
|
|
726
736
|
for (const [key, col] of Object.entries(schema)) {
|
|
727
737
|
if (finalData[key] === void 0) {
|
|
@@ -1016,19 +1026,86 @@ var TauriORM = class {
|
|
|
1016
1026
|
}
|
|
1017
1027
|
return def;
|
|
1018
1028
|
});
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
)
|
|
1029
|
+
const tableConstraints = [];
|
|
1030
|
+
const constraints = table._constraints;
|
|
1031
|
+
if (constraints && constraints.length) {
|
|
1032
|
+
for (const spec of constraints) {
|
|
1033
|
+
if (spec.expr) {
|
|
1034
|
+
const name = spec.name;
|
|
1035
|
+
const expr = spec.expr.raw ?? spec.expr?.raw ?? String(spec.expr);
|
|
1036
|
+
tableConstraints.push(
|
|
1037
|
+
name ? `CONSTRAINT ${name} CHECK (${expr})` : `CHECK (${expr})`
|
|
1038
|
+
);
|
|
1039
|
+
continue;
|
|
1040
|
+
}
|
|
1041
|
+
if (spec.foreignColumns) {
|
|
1042
|
+
const name = spec.name;
|
|
1043
|
+
const cols = spec.columns.join(", ");
|
|
1044
|
+
const fTable = spec.foreignTable;
|
|
1045
|
+
const fCols = spec.foreignColumns.join(", ");
|
|
1046
|
+
let clause = `${name ? `CONSTRAINT ${name} ` : ""}FOREIGN KEY (${cols}) REFERENCES ${fTable} (${fCols})`;
|
|
1047
|
+
if (spec.onDelete)
|
|
1048
|
+
clause += ` ON DELETE ${String(
|
|
1049
|
+
spec.onDelete
|
|
1050
|
+
).toUpperCase()}`;
|
|
1051
|
+
if (spec.onUpdate)
|
|
1052
|
+
clause += ` ON UPDATE ${String(
|
|
1053
|
+
spec.onUpdate
|
|
1054
|
+
).toUpperCase()}`;
|
|
1055
|
+
tableConstraints.push(clause);
|
|
1056
|
+
continue;
|
|
1057
|
+
}
|
|
1058
|
+
if (spec.columns) {
|
|
1059
|
+
const cols = spec.columns.join(", ");
|
|
1060
|
+
const name = spec.name;
|
|
1061
|
+
const isPk = spec.kind === "primaryKey" || name && name.toLowerCase().includes("pk");
|
|
1062
|
+
if (isPk) {
|
|
1063
|
+
tableConstraints.push(
|
|
1064
|
+
name ? `CONSTRAINT ${name} PRIMARY KEY (${cols})` : `PRIMARY KEY (${cols})`
|
|
1065
|
+
);
|
|
1066
|
+
} else {
|
|
1067
|
+
tableConstraints.push(
|
|
1068
|
+
name ? `CONSTRAINT ${name} UNIQUE (${cols})` : `UNIQUE (${cols})`
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
continue;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
const parts = [...columnDefs, ...tableConstraints];
|
|
1076
|
+
return `CREATE TABLE IF NOT EXISTS ${tableName} (${parts.join(", ")});`;
|
|
1022
1077
|
}
|
|
1023
1078
|
async createTableIfNotExists(table) {
|
|
1024
1079
|
const sql2 = this.generateCreateTableSql(table);
|
|
1025
1080
|
await this.run(sql2);
|
|
1081
|
+
await this.createIndexesForTable(table);
|
|
1026
1082
|
}
|
|
1027
1083
|
async createTablesIfNotExist(tables) {
|
|
1028
1084
|
for (const t of tables) {
|
|
1029
1085
|
await this.createTableIfNotExists(t);
|
|
1030
1086
|
}
|
|
1031
1087
|
}
|
|
1088
|
+
generateCreateIndexSqls(table) {
|
|
1089
|
+
const tableName = table._tableName;
|
|
1090
|
+
const indexes = table._indexes || [];
|
|
1091
|
+
const stmts = [];
|
|
1092
|
+
for (const idx of indexes) {
|
|
1093
|
+
const unique2 = idx.unique ? "UNIQUE " : "";
|
|
1094
|
+
if (!idx.name) continue;
|
|
1095
|
+
const colList = Array.isArray(idx.columns) ? idx.columns : [];
|
|
1096
|
+
if (colList.length === 0) continue;
|
|
1097
|
+
const cols = `(${colList.join(", ")})`;
|
|
1098
|
+
const where = idx.where?.raw ? ` WHERE ${idx.where.raw}` : "";
|
|
1099
|
+
stmts.push(
|
|
1100
|
+
`CREATE ${unique2}INDEX IF NOT EXISTS ${idx.name} ON ${tableName} ${cols}${where};`
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
return stmts;
|
|
1104
|
+
}
|
|
1105
|
+
async createIndexesForTable(table) {
|
|
1106
|
+
const stmts = this.generateCreateIndexSqls(table);
|
|
1107
|
+
for (const s of stmts) await this.run(s);
|
|
1108
|
+
}
|
|
1032
1109
|
async ensureMigrationsTable() {
|
|
1033
1110
|
await this.run(
|
|
1034
1111
|
`CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)`
|
|
@@ -1053,20 +1130,23 @@ var TauriORM = class {
|
|
|
1053
1130
|
const track = options?.track ?? true;
|
|
1054
1131
|
if (track) {
|
|
1055
1132
|
await this.ensureMigrationsTable();
|
|
1133
|
+
}
|
|
1134
|
+
await this.forcePushForTables(tables, { preserveData: true });
|
|
1135
|
+
if (track) {
|
|
1056
1136
|
const name = options?.name ?? `init:${tables.map((t) => t._tableName).join(",")}`;
|
|
1057
1137
|
const already = await this.hasMigration(name);
|
|
1058
|
-
if (already)
|
|
1059
|
-
await this.createTablesIfNotExist(tables);
|
|
1060
|
-
await this.recordMigration(name);
|
|
1061
|
-
return;
|
|
1138
|
+
if (!already) await this.recordMigration(name);
|
|
1062
1139
|
}
|
|
1063
|
-
await this.createTablesIfNotExist(tables);
|
|
1064
1140
|
}
|
|
1065
1141
|
// Configure schema and relations, and generate db.query automatically
|
|
1066
1142
|
configure(tables, relDefs) {
|
|
1067
1143
|
this._tables = tables;
|
|
1068
1144
|
this._relations = relDefs ?? {};
|
|
1069
|
-
this.query = makeQueryAPI(
|
|
1145
|
+
this.query = makeQueryAPI(
|
|
1146
|
+
tables,
|
|
1147
|
+
this._relations ?? {},
|
|
1148
|
+
this.getDb.bind(this)
|
|
1149
|
+
);
|
|
1070
1150
|
return this;
|
|
1071
1151
|
}
|
|
1072
1152
|
// Convenience: migrate from configured tables
|
|
@@ -1074,6 +1154,7 @@ var TauriORM = class {
|
|
|
1074
1154
|
if (!this._tables)
|
|
1075
1155
|
throw new Error("No tables configured. Call db.configure({...}) first.");
|
|
1076
1156
|
await this.migrate(Object.values(this._tables), options);
|
|
1157
|
+
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
1077
1158
|
}
|
|
1078
1159
|
// --- Schema diff and CLI-like helpers ---
|
|
1079
1160
|
async diffSchema() {
|
|
@@ -1200,6 +1281,13 @@ var TauriORM = class {
|
|
|
1200
1281
|
entries.sort((a, b) => a.table.localeCompare(b.table));
|
|
1201
1282
|
return JSON.stringify(entries);
|
|
1202
1283
|
}
|
|
1284
|
+
getSchemaSignature() {
|
|
1285
|
+
return this.computeModelSignature();
|
|
1286
|
+
}
|
|
1287
|
+
async printSchemaDiff() {
|
|
1288
|
+
const diff = await this.diffSchema();
|
|
1289
|
+
console.log("Schema diff:", JSON.stringify(diff, null, 2));
|
|
1290
|
+
}
|
|
1203
1291
|
async isSchemaDirty() {
|
|
1204
1292
|
const sig = this.computeModelSignature();
|
|
1205
1293
|
const stored = await this.getSchemaMeta("schema_signature");
|
|
@@ -1209,7 +1297,9 @@ var TauriORM = class {
|
|
|
1209
1297
|
const status = await this.isSchemaDirty();
|
|
1210
1298
|
if (!this._tables) throw new Error("No tables configured.");
|
|
1211
1299
|
if (status.dirty) {
|
|
1212
|
-
await this.
|
|
1300
|
+
await this.forcePushForTables(Object.values(this._tables), {
|
|
1301
|
+
preserveData: true
|
|
1302
|
+
});
|
|
1213
1303
|
await this.setSchemaMeta(
|
|
1214
1304
|
"schema_signature",
|
|
1215
1305
|
this.computeModelSignature()
|
|
@@ -1250,13 +1340,17 @@ var TauriORM = class {
|
|
|
1250
1340
|
// Force push model to DB: add missing tables/columns, rebuild tables if incompatible
|
|
1251
1341
|
async forcePush(options) {
|
|
1252
1342
|
if (!this._tables) throw new Error("No tables configured.");
|
|
1343
|
+
await this.forcePushForTables(Object.values(this._tables), options);
|
|
1344
|
+
}
|
|
1345
|
+
async forcePushForTables(tables, options) {
|
|
1253
1346
|
const dbi = await this.getDb();
|
|
1254
1347
|
const preserve = options?.preserveData !== false;
|
|
1255
|
-
for (const tbl of
|
|
1348
|
+
for (const tbl of tables) {
|
|
1256
1349
|
const tableName = tbl._tableName;
|
|
1257
1350
|
const exists2 = await this.tableExists(tableName);
|
|
1258
1351
|
if (!exists2) {
|
|
1259
1352
|
await this.run(this.buildCreateTableSQL(tbl));
|
|
1353
|
+
await this.createIndexesForTable(tbl);
|
|
1260
1354
|
continue;
|
|
1261
1355
|
}
|
|
1262
1356
|
const existingCols = await dbi.select(
|
|
@@ -1301,6 +1395,7 @@ var TauriORM = class {
|
|
|
1301
1395
|
}
|
|
1302
1396
|
await this.run(`DROP TABLE ${tableName}`);
|
|
1303
1397
|
await this.run(`ALTER TABLE ${tmp} RENAME TO ${tableName}`);
|
|
1398
|
+
await this.createIndexesForTable(tbl);
|
|
1304
1399
|
} else {
|
|
1305
1400
|
for (const m of missing) {
|
|
1306
1401
|
let clause = `${m.name} ${m.type}`;
|
|
@@ -1311,6 +1406,7 @@ var TauriORM = class {
|
|
|
1311
1406
|
}
|
|
1312
1407
|
await this.run(`ALTER TABLE ${tableName} ADD COLUMN ${clause}`);
|
|
1313
1408
|
}
|
|
1409
|
+
await this.createIndexesForTable(tbl);
|
|
1314
1410
|
}
|
|
1315
1411
|
}
|
|
1316
1412
|
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,7 +653,7 @@ var TauriORM = class {
|
|
|
643
653
|
return ret;
|
|
644
654
|
}
|
|
645
655
|
for (const data of this._rows) {
|
|
646
|
-
const finalData = {
|
|
656
|
+
const finalData = Object.assign({}, data);
|
|
647
657
|
const schema = this._table._schema;
|
|
648
658
|
for (const [key, col] of Object.entries(schema)) {
|
|
649
659
|
if (finalData[key] === void 0) {
|
|
@@ -938,19 +948,86 @@ var TauriORM = class {
|
|
|
938
948
|
}
|
|
939
949
|
return def;
|
|
940
950
|
});
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
)
|
|
951
|
+
const tableConstraints = [];
|
|
952
|
+
const constraints = table._constraints;
|
|
953
|
+
if (constraints && constraints.length) {
|
|
954
|
+
for (const spec of constraints) {
|
|
955
|
+
if (spec.expr) {
|
|
956
|
+
const name = spec.name;
|
|
957
|
+
const expr = spec.expr.raw ?? spec.expr?.raw ?? String(spec.expr);
|
|
958
|
+
tableConstraints.push(
|
|
959
|
+
name ? `CONSTRAINT ${name} CHECK (${expr})` : `CHECK (${expr})`
|
|
960
|
+
);
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
if (spec.foreignColumns) {
|
|
964
|
+
const name = spec.name;
|
|
965
|
+
const cols = spec.columns.join(", ");
|
|
966
|
+
const fTable = spec.foreignTable;
|
|
967
|
+
const fCols = spec.foreignColumns.join(", ");
|
|
968
|
+
let clause = `${name ? `CONSTRAINT ${name} ` : ""}FOREIGN KEY (${cols}) REFERENCES ${fTable} (${fCols})`;
|
|
969
|
+
if (spec.onDelete)
|
|
970
|
+
clause += ` ON DELETE ${String(
|
|
971
|
+
spec.onDelete
|
|
972
|
+
).toUpperCase()}`;
|
|
973
|
+
if (spec.onUpdate)
|
|
974
|
+
clause += ` ON UPDATE ${String(
|
|
975
|
+
spec.onUpdate
|
|
976
|
+
).toUpperCase()}`;
|
|
977
|
+
tableConstraints.push(clause);
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
if (spec.columns) {
|
|
981
|
+
const cols = spec.columns.join(", ");
|
|
982
|
+
const name = spec.name;
|
|
983
|
+
const isPk = spec.kind === "primaryKey" || name && name.toLowerCase().includes("pk");
|
|
984
|
+
if (isPk) {
|
|
985
|
+
tableConstraints.push(
|
|
986
|
+
name ? `CONSTRAINT ${name} PRIMARY KEY (${cols})` : `PRIMARY KEY (${cols})`
|
|
987
|
+
);
|
|
988
|
+
} else {
|
|
989
|
+
tableConstraints.push(
|
|
990
|
+
name ? `CONSTRAINT ${name} UNIQUE (${cols})` : `UNIQUE (${cols})`
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
continue;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
const parts = [...columnDefs, ...tableConstraints];
|
|
998
|
+
return `CREATE TABLE IF NOT EXISTS ${tableName} (${parts.join(", ")});`;
|
|
944
999
|
}
|
|
945
1000
|
async createTableIfNotExists(table) {
|
|
946
1001
|
const sql2 = this.generateCreateTableSql(table);
|
|
947
1002
|
await this.run(sql2);
|
|
1003
|
+
await this.createIndexesForTable(table);
|
|
948
1004
|
}
|
|
949
1005
|
async createTablesIfNotExist(tables) {
|
|
950
1006
|
for (const t of tables) {
|
|
951
1007
|
await this.createTableIfNotExists(t);
|
|
952
1008
|
}
|
|
953
1009
|
}
|
|
1010
|
+
generateCreateIndexSqls(table) {
|
|
1011
|
+
const tableName = table._tableName;
|
|
1012
|
+
const indexes = table._indexes || [];
|
|
1013
|
+
const stmts = [];
|
|
1014
|
+
for (const idx of indexes) {
|
|
1015
|
+
const unique2 = idx.unique ? "UNIQUE " : "";
|
|
1016
|
+
if (!idx.name) continue;
|
|
1017
|
+
const colList = Array.isArray(idx.columns) ? idx.columns : [];
|
|
1018
|
+
if (colList.length === 0) continue;
|
|
1019
|
+
const cols = `(${colList.join(", ")})`;
|
|
1020
|
+
const where = idx.where?.raw ? ` WHERE ${idx.where.raw}` : "";
|
|
1021
|
+
stmts.push(
|
|
1022
|
+
`CREATE ${unique2}INDEX IF NOT EXISTS ${idx.name} ON ${tableName} ${cols}${where};`
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
return stmts;
|
|
1026
|
+
}
|
|
1027
|
+
async createIndexesForTable(table) {
|
|
1028
|
+
const stmts = this.generateCreateIndexSqls(table);
|
|
1029
|
+
for (const s of stmts) await this.run(s);
|
|
1030
|
+
}
|
|
954
1031
|
async ensureMigrationsTable() {
|
|
955
1032
|
await this.run(
|
|
956
1033
|
`CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)`
|
|
@@ -975,20 +1052,23 @@ var TauriORM = class {
|
|
|
975
1052
|
const track = options?.track ?? true;
|
|
976
1053
|
if (track) {
|
|
977
1054
|
await this.ensureMigrationsTable();
|
|
1055
|
+
}
|
|
1056
|
+
await this.forcePushForTables(tables, { preserveData: true });
|
|
1057
|
+
if (track) {
|
|
978
1058
|
const name = options?.name ?? `init:${tables.map((t) => t._tableName).join(",")}`;
|
|
979
1059
|
const already = await this.hasMigration(name);
|
|
980
|
-
if (already)
|
|
981
|
-
await this.createTablesIfNotExist(tables);
|
|
982
|
-
await this.recordMigration(name);
|
|
983
|
-
return;
|
|
1060
|
+
if (!already) await this.recordMigration(name);
|
|
984
1061
|
}
|
|
985
|
-
await this.createTablesIfNotExist(tables);
|
|
986
1062
|
}
|
|
987
1063
|
// Configure schema and relations, and generate db.query automatically
|
|
988
1064
|
configure(tables, relDefs) {
|
|
989
1065
|
this._tables = tables;
|
|
990
1066
|
this._relations = relDefs ?? {};
|
|
991
|
-
this.query = makeQueryAPI(
|
|
1067
|
+
this.query = makeQueryAPI(
|
|
1068
|
+
tables,
|
|
1069
|
+
this._relations ?? {},
|
|
1070
|
+
this.getDb.bind(this)
|
|
1071
|
+
);
|
|
992
1072
|
return this;
|
|
993
1073
|
}
|
|
994
1074
|
// Convenience: migrate from configured tables
|
|
@@ -996,6 +1076,7 @@ var TauriORM = class {
|
|
|
996
1076
|
if (!this._tables)
|
|
997
1077
|
throw new Error("No tables configured. Call db.configure({...}) first.");
|
|
998
1078
|
await this.migrate(Object.values(this._tables), options);
|
|
1079
|
+
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
999
1080
|
}
|
|
1000
1081
|
// --- Schema diff and CLI-like helpers ---
|
|
1001
1082
|
async diffSchema() {
|
|
@@ -1122,6 +1203,13 @@ var TauriORM = class {
|
|
|
1122
1203
|
entries.sort((a, b) => a.table.localeCompare(b.table));
|
|
1123
1204
|
return JSON.stringify(entries);
|
|
1124
1205
|
}
|
|
1206
|
+
getSchemaSignature() {
|
|
1207
|
+
return this.computeModelSignature();
|
|
1208
|
+
}
|
|
1209
|
+
async printSchemaDiff() {
|
|
1210
|
+
const diff = await this.diffSchema();
|
|
1211
|
+
console.log("Schema diff:", JSON.stringify(diff, null, 2));
|
|
1212
|
+
}
|
|
1125
1213
|
async isSchemaDirty() {
|
|
1126
1214
|
const sig = this.computeModelSignature();
|
|
1127
1215
|
const stored = await this.getSchemaMeta("schema_signature");
|
|
@@ -1131,7 +1219,9 @@ var TauriORM = class {
|
|
|
1131
1219
|
const status = await this.isSchemaDirty();
|
|
1132
1220
|
if (!this._tables) throw new Error("No tables configured.");
|
|
1133
1221
|
if (status.dirty) {
|
|
1134
|
-
await this.
|
|
1222
|
+
await this.forcePushForTables(Object.values(this._tables), {
|
|
1223
|
+
preserveData: true
|
|
1224
|
+
});
|
|
1135
1225
|
await this.setSchemaMeta(
|
|
1136
1226
|
"schema_signature",
|
|
1137
1227
|
this.computeModelSignature()
|
|
@@ -1172,13 +1262,17 @@ var TauriORM = class {
|
|
|
1172
1262
|
// Force push model to DB: add missing tables/columns, rebuild tables if incompatible
|
|
1173
1263
|
async forcePush(options) {
|
|
1174
1264
|
if (!this._tables) throw new Error("No tables configured.");
|
|
1265
|
+
await this.forcePushForTables(Object.values(this._tables), options);
|
|
1266
|
+
}
|
|
1267
|
+
async forcePushForTables(tables, options) {
|
|
1175
1268
|
const dbi = await this.getDb();
|
|
1176
1269
|
const preserve = options?.preserveData !== false;
|
|
1177
|
-
for (const tbl of
|
|
1270
|
+
for (const tbl of tables) {
|
|
1178
1271
|
const tableName = tbl._tableName;
|
|
1179
1272
|
const exists2 = await this.tableExists(tableName);
|
|
1180
1273
|
if (!exists2) {
|
|
1181
1274
|
await this.run(this.buildCreateTableSQL(tbl));
|
|
1275
|
+
await this.createIndexesForTable(tbl);
|
|
1182
1276
|
continue;
|
|
1183
1277
|
}
|
|
1184
1278
|
const existingCols = await dbi.select(
|
|
@@ -1223,6 +1317,7 @@ var TauriORM = class {
|
|
|
1223
1317
|
}
|
|
1224
1318
|
await this.run(`DROP TABLE ${tableName}`);
|
|
1225
1319
|
await this.run(`ALTER TABLE ${tmp} RENAME TO ${tableName}`);
|
|
1320
|
+
await this.createIndexesForTable(tbl);
|
|
1226
1321
|
} else {
|
|
1227
1322
|
for (const m of missing) {
|
|
1228
1323
|
let clause = `${m.name} ${m.type}`;
|
|
@@ -1233,6 +1328,7 @@ var TauriORM = class {
|
|
|
1233
1328
|
}
|
|
1234
1329
|
await this.run(`ALTER TABLE ${tableName} ADD COLUMN ${clause}`);
|
|
1235
1330
|
}
|
|
1331
|
+
await this.createIndexesForTable(tbl);
|
|
1236
1332
|
}
|
|
1237
1333
|
}
|
|
1238
1334
|
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|