@type32/tauri-sqlite-orm 0.1.18-9 → 0.1.19
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 +176 -160
- package/dist/index.d.ts +176 -160
- package/dist/index.js +516 -394
- package/dist/index.mjs +516 -395
- package/package.json +5 -4
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -63
- package/dist/cli.mjs +0 -62
package/dist/index.js
CHANGED
|
@@ -27,7 +27,6 @@ __export(index_exports, {
|
|
|
27
27
|
OneRelation: () => OneRelation,
|
|
28
28
|
Relation: () => Relation,
|
|
29
29
|
SQLiteColumn: () => SQLiteColumn,
|
|
30
|
-
SelectBuilder: () => SelectBuilder,
|
|
31
30
|
SelectQueryBuilder: () => SelectQueryBuilder,
|
|
32
31
|
Table: () => Table,
|
|
33
32
|
TauriORM: () => TauriORM,
|
|
@@ -42,6 +41,7 @@ __export(index_exports, {
|
|
|
42
41
|
count: () => count,
|
|
43
42
|
countDistinct: () => countDistinct,
|
|
44
43
|
desc: () => desc,
|
|
44
|
+
enumType: () => enumType,
|
|
45
45
|
eq: () => eq,
|
|
46
46
|
getTableColumns: () => getTableColumns,
|
|
47
47
|
gt: () => gt,
|
|
@@ -56,6 +56,7 @@ __export(index_exports, {
|
|
|
56
56
|
max: () => max,
|
|
57
57
|
min: () => min,
|
|
58
58
|
not: () => not,
|
|
59
|
+
numeric: () => numeric,
|
|
59
60
|
or: () => or,
|
|
60
61
|
real: () => real,
|
|
61
62
|
relations: () => relations,
|
|
@@ -66,129 +67,51 @@ __export(index_exports, {
|
|
|
66
67
|
});
|
|
67
68
|
module.exports = __toCommonJS(index_exports);
|
|
68
69
|
|
|
69
|
-
// src/
|
|
70
|
-
var
|
|
71
|
-
constructor(
|
|
72
|
-
this.
|
|
73
|
-
this.options = options;
|
|
74
|
-
this._ = {
|
|
75
|
-
name,
|
|
76
|
-
dataType: type,
|
|
77
|
-
mode: mode || "default",
|
|
78
|
-
notNull: options.notNull ?? false,
|
|
79
|
-
hasDefault: options.default !== void 0 || options.$defaultFn !== void 0,
|
|
80
|
-
autoincrement: options.autoincrement ?? false,
|
|
81
|
-
table: void 0
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
_;
|
|
85
|
-
notNull() {
|
|
86
|
-
return new _SQLiteColumn(
|
|
87
|
-
this._.name,
|
|
88
|
-
this.type,
|
|
89
|
-
{ ...this.options, notNull: true },
|
|
90
|
-
this._.mode
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
default(value) {
|
|
94
|
-
return new _SQLiteColumn(
|
|
95
|
-
this._.name,
|
|
96
|
-
this.type,
|
|
97
|
-
{ ...this.options, default: value },
|
|
98
|
-
this._.mode
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
$defaultFn(fn) {
|
|
102
|
-
return new _SQLiteColumn(
|
|
103
|
-
this._.name,
|
|
104
|
-
this.type,
|
|
105
|
-
{ ...this.options, $defaultFn: fn },
|
|
106
|
-
this._.mode
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
primaryKey() {
|
|
110
|
-
return new _SQLiteColumn(
|
|
111
|
-
this._.name,
|
|
112
|
-
this.type,
|
|
113
|
-
{ ...this.options, primaryKey: true, notNull: true },
|
|
114
|
-
this._.mode
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
autoincrement() {
|
|
118
|
-
return new _SQLiteColumn(
|
|
119
|
-
this._.name,
|
|
120
|
-
this.type,
|
|
121
|
-
{ ...this.options, autoincrement: true },
|
|
122
|
-
this._.mode
|
|
123
|
-
);
|
|
70
|
+
// src/builders/query-base.ts
|
|
71
|
+
var BaseQueryBuilder = class {
|
|
72
|
+
constructor(db) {
|
|
73
|
+
this.db = db;
|
|
124
74
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
);
|
|
75
|
+
query = "";
|
|
76
|
+
params = [];
|
|
77
|
+
where(condition) {
|
|
78
|
+
this.query += ` WHERE ${condition.sql}`;
|
|
79
|
+
this.params.push(...condition.params);
|
|
80
|
+
return this;
|
|
132
81
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
this.
|
|
136
|
-
this.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
column: ref._.columns[column]
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
this._.mode
|
|
145
|
-
);
|
|
82
|
+
orderBy(column, direction = "ASC") {
|
|
83
|
+
if ("sql" in column) {
|
|
84
|
+
this.query += ` ORDER BY ${column.sql} ${direction}`;
|
|
85
|
+
this.params.push(...column.params);
|
|
86
|
+
} else {
|
|
87
|
+
this.query += ` ORDER BY ${column._.name} ${direction}`;
|
|
88
|
+
}
|
|
89
|
+
return this;
|
|
146
90
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
this.type,
|
|
151
|
-
{ ...this.options, $onUpdateFn: fn },
|
|
152
|
-
this._.mode
|
|
153
|
-
);
|
|
91
|
+
limit(count2) {
|
|
92
|
+
this.query += ` LIMIT ${count2}`;
|
|
93
|
+
return this;
|
|
154
94
|
}
|
|
155
|
-
|
|
95
|
+
offset(count2) {
|
|
96
|
+
this.query += ` OFFSET ${count2}`;
|
|
156
97
|
return this;
|
|
157
98
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
var blob = (name) => new SQLiteColumn(name, "BLOB");
|
|
163
|
-
var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
|
|
164
|
-
var Table = class {
|
|
165
|
-
_;
|
|
166
|
-
constructor(name, columns) {
|
|
167
|
-
this._ = {
|
|
168
|
-
name,
|
|
169
|
-
columns
|
|
99
|
+
build() {
|
|
100
|
+
return {
|
|
101
|
+
sql: this.query,
|
|
102
|
+
params: this.params
|
|
170
103
|
};
|
|
171
104
|
}
|
|
172
105
|
};
|
|
173
|
-
var sqliteTable = (tableName, columns) => {
|
|
174
|
-
const table = new Table(tableName, columns);
|
|
175
|
-
for (const col of Object.values(columns)) {
|
|
176
|
-
col._.table = table;
|
|
177
|
-
}
|
|
178
|
-
return table;
|
|
179
|
-
};
|
|
180
|
-
var getTableColumns = (table) => {
|
|
181
|
-
return table._.columns;
|
|
182
|
-
};
|
|
183
|
-
var alias = (table, alias2) => {
|
|
184
|
-
return table;
|
|
185
|
-
};
|
|
186
106
|
|
|
187
|
-
// src/
|
|
188
|
-
var eq = (column, value) =>
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
107
|
+
// src/operators.ts
|
|
108
|
+
var eq = (column, value, tableAlias) => {
|
|
109
|
+
const columnName = tableAlias ? `${tableAlias}.${column._.name}` : column._.name;
|
|
110
|
+
return {
|
|
111
|
+
sql: `${columnName} = ?`,
|
|
112
|
+
params: [value]
|
|
113
|
+
};
|
|
114
|
+
};
|
|
192
115
|
var and = (...conditions) => ({
|
|
193
116
|
sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
|
|
194
117
|
params: conditions.flatMap((c) => c.params)
|
|
@@ -233,14 +156,6 @@ var inArray = (column, values) => ({
|
|
|
233
156
|
sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
|
|
234
157
|
params: values
|
|
235
158
|
});
|
|
236
|
-
var asc = (column) => ({
|
|
237
|
-
sql: `${column._.name} ASC`,
|
|
238
|
-
params: []
|
|
239
|
-
});
|
|
240
|
-
var desc = (column) => ({
|
|
241
|
-
sql: `${column._.name} DESC`,
|
|
242
|
-
params: []
|
|
243
|
-
});
|
|
244
159
|
var count = (column) => ({
|
|
245
160
|
sql: `COUNT(${column ? column._.name : "*"})`,
|
|
246
161
|
params: []
|
|
@@ -265,170 +180,206 @@ var min = (column) => ({
|
|
|
265
180
|
sql: `MIN(${column._.name})`,
|
|
266
181
|
params: []
|
|
267
182
|
});
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
const params = [];
|
|
271
|
-
strings.forEach((str, i) => {
|
|
272
|
-
queryParts.push(str);
|
|
273
|
-
if (values[i] !== void 0) {
|
|
274
|
-
if (typeof values[i] === "object" && values[i].sql) {
|
|
275
|
-
queryParts.push(values[i].sql);
|
|
276
|
-
params.push(...values[i].params);
|
|
277
|
-
} else {
|
|
278
|
-
queryParts.push("?");
|
|
279
|
-
params.push(values[i]);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
return {
|
|
284
|
-
sql: queryParts.join(""),
|
|
285
|
-
params
|
|
286
|
-
};
|
|
287
|
-
};
|
|
288
|
-
var BaseQueryBuilder = class {
|
|
289
|
-
constructor(db) {
|
|
290
|
-
this.db = db;
|
|
291
|
-
}
|
|
292
|
-
query = "";
|
|
293
|
-
params = [];
|
|
294
|
-
build() {
|
|
295
|
-
return {
|
|
296
|
-
sql: this.query,
|
|
297
|
-
params: this.params
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
};
|
|
183
|
+
|
|
184
|
+
// src/builders/select.ts
|
|
301
185
|
var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
302
|
-
constructor(db, table,
|
|
186
|
+
constructor(db, table, columns) {
|
|
303
187
|
super(db);
|
|
304
|
-
this.
|
|
305
|
-
this.
|
|
306
|
-
this.
|
|
307
|
-
|
|
188
|
+
this.table = table;
|
|
189
|
+
this.columns = columns;
|
|
190
|
+
this.selectedTableAlias = table._.name;
|
|
191
|
+
const selected = columns ? columns.map((c) => this.table._.columns[c]) : Object.values(this.table._.columns);
|
|
192
|
+
this.selectedColumns = selected.map(
|
|
193
|
+
(col) => `${this.selectedTableAlias}.${col._.name} AS "${this.selectedTableAlias}.${col._.name}"`
|
|
194
|
+
);
|
|
195
|
+
this.query = `FROM ${table._.name} ${this.selectedTableAlias}`;
|
|
308
196
|
}
|
|
309
197
|
isDistinct = false;
|
|
310
198
|
groupByColumns = [];
|
|
311
|
-
havingCondition;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
offsetCount;
|
|
317
|
-
whereCondition;
|
|
318
|
-
where(condition) {
|
|
319
|
-
this.whereCondition = condition;
|
|
320
|
-
return this;
|
|
321
|
-
}
|
|
322
|
-
leftJoin(table, on) {
|
|
323
|
-
this.joinClauses.push({ type: "LEFT JOIN", table, on });
|
|
324
|
-
return this;
|
|
325
|
-
}
|
|
326
|
-
innerJoin(table, on) {
|
|
327
|
-
this.joinClauses.push({ type: "INNER JOIN", table, on });
|
|
328
|
-
return this;
|
|
329
|
-
}
|
|
330
|
-
rightJoin(table, on) {
|
|
331
|
-
this.joinClauses.push({ type: "RIGHT JOIN", table, on });
|
|
332
|
-
return this;
|
|
333
|
-
}
|
|
334
|
-
fullJoin(table, on) {
|
|
335
|
-
this.joinClauses.push({ type: "FULL JOIN", table, on });
|
|
336
|
-
return this;
|
|
337
|
-
}
|
|
199
|
+
havingCondition = null;
|
|
200
|
+
joins = [];
|
|
201
|
+
includeRelations = {};
|
|
202
|
+
selectedTableAlias;
|
|
203
|
+
selectedColumns = [];
|
|
338
204
|
distinct() {
|
|
339
205
|
this.isDistinct = true;
|
|
340
206
|
return this;
|
|
341
207
|
}
|
|
342
208
|
groupBy(...columns) {
|
|
343
209
|
this.groupByColumns.push(...columns);
|
|
210
|
+
const columnNames = columns.map((col) => `${this.selectedTableAlias}.${col._.name}`).join(", ");
|
|
211
|
+
this.query += ` GROUP BY ${columnNames}`;
|
|
344
212
|
return this;
|
|
345
213
|
}
|
|
346
214
|
having(condition) {
|
|
347
215
|
this.havingCondition = condition;
|
|
216
|
+
this.query += ` HAVING ${condition.sql}`;
|
|
217
|
+
this.params.push(...condition.params);
|
|
348
218
|
return this;
|
|
349
219
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
} else {
|
|
357
|
-
this.orderByClauses.push({
|
|
358
|
-
sql: `${column._.name} ${direction}`,
|
|
359
|
-
params: []
|
|
360
|
-
});
|
|
361
|
-
}
|
|
220
|
+
leftJoin(table, condition, alias2) {
|
|
221
|
+
this.joins.push({ type: "LEFT", table, condition, alias: alias2 });
|
|
222
|
+
const aliasedColumns = Object.values(table._.columns).map(
|
|
223
|
+
(col) => `${alias2}.${col._.name} AS "${alias2}.${col._.name}"`
|
|
224
|
+
);
|
|
225
|
+
this.selectedColumns.push(...aliasedColumns);
|
|
362
226
|
return this;
|
|
363
227
|
}
|
|
364
|
-
|
|
365
|
-
this.
|
|
228
|
+
innerJoin(table, condition, alias2) {
|
|
229
|
+
this.joins.push({ type: "INNER", table, condition, alias: alias2 });
|
|
230
|
+
const aliasedColumns = Object.values(table._.columns).map(
|
|
231
|
+
(col) => `${alias2}.${col._.name} AS "${alias2}.${col._.name}"`
|
|
232
|
+
);
|
|
233
|
+
this.selectedColumns.push(...aliasedColumns);
|
|
366
234
|
return this;
|
|
367
235
|
}
|
|
368
|
-
|
|
369
|
-
this.
|
|
236
|
+
include(relations2) {
|
|
237
|
+
this.includeRelations = { ...this.includeRelations, ...relations2 };
|
|
370
238
|
return this;
|
|
371
239
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
} else {
|
|
379
|
-
columnsClause = selectionEntries.map(([alias2, col]) => {
|
|
380
|
-
if (col instanceof SQLiteColumn) {
|
|
381
|
-
return `${col._.table._.name}.${col._.name} AS "${alias2}"`;
|
|
382
|
-
} else {
|
|
383
|
-
selectParams.push(...col.params);
|
|
384
|
-
return `(${col.sql}) AS "${alias2}"`;
|
|
385
|
-
}
|
|
386
|
-
}).join(", ");
|
|
387
|
-
}
|
|
388
|
-
let query = `SELECT ${this.isDistinct ? "DISTINCT " : ""}${columnsClause} FROM ${this.fromTable._.name}`;
|
|
389
|
-
const queryParams = [...selectParams];
|
|
390
|
-
if (this.joinClauses.length > 0) {
|
|
391
|
-
const joins = this.joinClauses.map((j) => {
|
|
392
|
-
queryParams.push(...j.on.params);
|
|
393
|
-
return `${j.type} ${j.table._.name} ON ${j.on.sql}`;
|
|
394
|
-
});
|
|
395
|
-
query += ` ${joins.join(" ")}`;
|
|
240
|
+
buildJoins() {
|
|
241
|
+
let sql2 = "";
|
|
242
|
+
const params = [];
|
|
243
|
+
for (const join of this.joins) {
|
|
244
|
+
sql2 += ` ${join.type} JOIN ${join.table._.name} ${join.alias} ON ${join.condition.sql}`;
|
|
245
|
+
params.push(...join.condition.params);
|
|
396
246
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
247
|
+
for (const [relationName, include] of Object.entries(this.includeRelations)) {
|
|
248
|
+
if (!include) continue;
|
|
249
|
+
const relation = this.table.relations[relationName];
|
|
250
|
+
if (!relation) {
|
|
251
|
+
console.warn(
|
|
252
|
+
`[Tauri-ORM] Relation "${relationName}" not found on table "${this.table._.name}". Skipping include.`
|
|
253
|
+
);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
const foreignTable = relation.foreignTable;
|
|
257
|
+
const foreignAlias = `${this.selectedTableAlias}_${relationName}`;
|
|
258
|
+
const aliasedColumns = Object.values(foreignTable._.columns).map(
|
|
259
|
+
(col) => `${foreignAlias}.${col._.name} AS "${foreignAlias}.${col._.name}"`
|
|
260
|
+
);
|
|
261
|
+
this.selectedColumns.push(...aliasedColumns);
|
|
262
|
+
if (relation.type === "one" && relation.fields && relation.references) {
|
|
263
|
+
const conditions = relation.fields.map((field, i) => {
|
|
264
|
+
const localColumn = `${this.selectedTableAlias}.${field._.name}`;
|
|
265
|
+
const foreignColumn = `${foreignAlias}.${relation.references[i]._.name}`;
|
|
266
|
+
return {
|
|
267
|
+
sql: `${localColumn} = ${foreignColumn}`,
|
|
268
|
+
params: []
|
|
269
|
+
};
|
|
270
|
+
});
|
|
271
|
+
const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
|
|
272
|
+
sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
|
|
273
|
+
params.push(...condition.params);
|
|
274
|
+
} else if (relation.type === "many") {
|
|
275
|
+
const refRelation = Object.entries(foreignTable.relations).find(
|
|
276
|
+
([_, r]) => r.foreignTable === this.table
|
|
277
|
+
);
|
|
278
|
+
if (refRelation && refRelation[1].fields && refRelation[1].references) {
|
|
279
|
+
const [_, relationConfig] = refRelation;
|
|
280
|
+
const conditions = relationConfig.fields.map((field, i) => {
|
|
281
|
+
const localColumn = `${foreignAlias}.${field._.name}`;
|
|
282
|
+
const foreignColumn = `${this.selectedTableAlias}.${relationConfig.references[i]._.name}`;
|
|
283
|
+
return {
|
|
284
|
+
sql: `${localColumn} = ${foreignColumn}`,
|
|
285
|
+
params: []
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
|
|
289
|
+
sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
|
|
290
|
+
params.push(...condition.params);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
404
293
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
294
|
+
return { sql: sql2, params };
|
|
295
|
+
}
|
|
296
|
+
// Enhanced execute method that handles relation data mapping
|
|
297
|
+
async execute() {
|
|
298
|
+
const { sql: joinSql, params: joinParams } = this.buildJoins();
|
|
299
|
+
const distinct = this.isDistinct ? "DISTINCT " : "";
|
|
300
|
+
this.query = `SELECT ${distinct}${this.selectedColumns.join(", ")} ${this.query}`;
|
|
301
|
+
this.query += joinSql;
|
|
302
|
+
this.params.push(...joinParams);
|
|
303
|
+
const { sql: sql2, params } = this.build();
|
|
304
|
+
console.log("Executing SQL:", sql2, "with params:", params);
|
|
305
|
+
const rawResults = await this.db.select(sql2, params);
|
|
306
|
+
const hasIncludes = Object.values(this.includeRelations).some((i) => i);
|
|
307
|
+
if (hasIncludes) {
|
|
308
|
+
return this.processRelationResults(rawResults);
|
|
408
309
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
queryParams.push(...this.orderByClauses.flatMap((c) => c.params));
|
|
310
|
+
const hasJoins = this.joins.length > 0;
|
|
311
|
+
if (hasJoins) {
|
|
312
|
+
return rawResults;
|
|
413
313
|
}
|
|
414
|
-
|
|
415
|
-
|
|
314
|
+
const prefix = `${this.selectedTableAlias}.`;
|
|
315
|
+
return rawResults.map((row) => {
|
|
316
|
+
const newRow = {};
|
|
317
|
+
for (const key in row) {
|
|
318
|
+
if (key.startsWith(prefix)) {
|
|
319
|
+
newRow[key.substring(prefix.length)] = row[key];
|
|
320
|
+
} else {
|
|
321
|
+
newRow[key] = row[key];
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return newRow;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
processRelationResults(rawResults) {
|
|
328
|
+
if (!rawResults.length) return [];
|
|
329
|
+
const mainTablePks = Object.values(this.table._.columns).filter((c) => c.options.primaryKey).map((c) => c._.name);
|
|
330
|
+
if (mainTablePks.length === 0) {
|
|
331
|
+
return rawResults;
|
|
416
332
|
}
|
|
417
|
-
|
|
418
|
-
|
|
333
|
+
const groupedResults = /* @__PURE__ */ new Map();
|
|
334
|
+
for (const row of rawResults) {
|
|
335
|
+
const mainTableKey = mainTablePks.map((pk) => row[`${this.selectedTableAlias}.${pk}`] ?? row[pk]).join("_");
|
|
336
|
+
if (!groupedResults.has(mainTableKey)) {
|
|
337
|
+
groupedResults.set(mainTableKey, {});
|
|
338
|
+
}
|
|
339
|
+
const result = groupedResults.get(mainTableKey);
|
|
340
|
+
const relations2 = {};
|
|
341
|
+
for (const [key, value] of Object.entries(row)) {
|
|
342
|
+
if (key.includes(".")) {
|
|
343
|
+
const [tableAlias, columnName] = key.split(".");
|
|
344
|
+
if (tableAlias === this.selectedTableAlias) {
|
|
345
|
+
result[columnName] = value;
|
|
346
|
+
} else {
|
|
347
|
+
const parts = tableAlias.split("_");
|
|
348
|
+
if (parts.length >= 2 && parts[0] === this.selectedTableAlias) {
|
|
349
|
+
const relationName = parts.slice(1).join("_");
|
|
350
|
+
if (!relations2[relationName]) relations2[relationName] = {};
|
|
351
|
+
relations2[relationName][columnName] = value;
|
|
352
|
+
} else {
|
|
353
|
+
if (!result[tableAlias]) result[tableAlias] = {};
|
|
354
|
+
result[tableAlias][columnName] = value;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
} else {
|
|
358
|
+
result[key] = value;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
for (const [relName, relData] of Object.entries(relations2)) {
|
|
362
|
+
const relationConfig = this.table.relations[relName];
|
|
363
|
+
if (!relationConfig) continue;
|
|
364
|
+
const hasData = Object.values(relData).some(
|
|
365
|
+
(v) => v !== null && v !== void 0 && v !== ""
|
|
366
|
+
);
|
|
367
|
+
if (!hasData) continue;
|
|
368
|
+
if (relationConfig.type === "many") {
|
|
369
|
+
if (!result[relName]) result[relName] = [];
|
|
370
|
+
const relatedPks = Object.values(relationConfig.foreignTable._.columns).filter((c) => c.options.primaryKey).map((c) => c._.name);
|
|
371
|
+
const relDataKey = relatedPks.map((pk) => relData[pk]).join("_");
|
|
372
|
+
if (relatedPks.length === 0 || !result[relName].some((r) => relatedPks.map((pk) => r[pk]).join("_") === relDataKey)) {
|
|
373
|
+
result[relName].push(relData);
|
|
374
|
+
}
|
|
375
|
+
} else {
|
|
376
|
+
result[relName] = relData;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
419
379
|
}
|
|
420
|
-
return
|
|
421
|
-
sql: query,
|
|
422
|
-
params: queryParams
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
|
-
build() {
|
|
426
|
-
return this.buildSelectQuery();
|
|
427
|
-
}
|
|
428
|
-
async execute() {
|
|
429
|
-
const { sql: sql2, params } = this.buildSelectQuery();
|
|
430
|
-
return this.db.select(sql2, params);
|
|
380
|
+
return Array.from(groupedResults.values());
|
|
431
381
|
}
|
|
382
|
+
// Update the return type signatures
|
|
432
383
|
async all() {
|
|
433
384
|
return this.execute();
|
|
434
385
|
}
|
|
@@ -438,19 +389,79 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
|
438
389
|
return result[0];
|
|
439
390
|
}
|
|
440
391
|
};
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
392
|
+
|
|
393
|
+
// src/builders/update.ts
|
|
394
|
+
var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
395
|
+
constructor(db, table) {
|
|
396
|
+
super(db);
|
|
397
|
+
this.table = table;
|
|
398
|
+
this.query = `UPDATE ${table._.name}`;
|
|
399
|
+
}
|
|
400
|
+
updateData = {};
|
|
401
|
+
returningColumns = [];
|
|
402
|
+
set(data) {
|
|
403
|
+
this.updateData = { ...this.updateData, ...data };
|
|
404
|
+
return this;
|
|
405
|
+
}
|
|
406
|
+
returning(...columns) {
|
|
407
|
+
this.returningColumns.push(...columns);
|
|
408
|
+
return this;
|
|
445
409
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
410
|
+
buildUpdateClause() {
|
|
411
|
+
const finalUpdateData = { ...this.updateData };
|
|
412
|
+
for (const [key, column] of Object.entries(this.table._.columns)) {
|
|
413
|
+
const typedKey = key;
|
|
414
|
+
if (finalUpdateData[typedKey] === void 0 && column.options.$onUpdateFn) {
|
|
415
|
+
finalUpdateData[typedKey] = column.options.$onUpdateFn();
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
const baseQuery = this.query;
|
|
419
|
+
const whereParams = this.params;
|
|
420
|
+
let tablePart = baseQuery;
|
|
421
|
+
let whereClause = "";
|
|
422
|
+
const whereIndex = baseQuery.indexOf(" WHERE ");
|
|
423
|
+
if (whereIndex !== -1) {
|
|
424
|
+
tablePart = baseQuery.substring(0, whereIndex);
|
|
425
|
+
whereClause = baseQuery.substring(whereIndex);
|
|
426
|
+
}
|
|
427
|
+
const entries = Object.entries(finalUpdateData);
|
|
428
|
+
if (entries.length === 0) {
|
|
429
|
+
throw new Error("Cannot execute an update query without a .set() call.");
|
|
430
|
+
}
|
|
431
|
+
const setClause = entries.map(([key]) => {
|
|
432
|
+
const column = this.table._.columns[key];
|
|
433
|
+
if (!column) {
|
|
434
|
+
throw new Error(
|
|
435
|
+
`Column ${key} does not exist on table ${this.table._.name}`
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
return `${column._.name} = ?`;
|
|
439
|
+
}).join(", ");
|
|
440
|
+
const setParams = entries.map(([, value]) => value);
|
|
441
|
+
const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
|
|
442
|
+
const params = [...setParams, ...whereParams];
|
|
443
|
+
return { sql: sql2, params };
|
|
444
|
+
}
|
|
445
|
+
async execute() {
|
|
446
|
+
const { sql: updateSql, params } = this.buildUpdateClause();
|
|
447
|
+
if (this.returningColumns.length > 0) {
|
|
448
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
449
|
+
const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
|
|
450
|
+
return this.db.select(sqlWithReturning, params);
|
|
451
|
+
} else {
|
|
452
|
+
const result = await this.db.execute(updateSql, params);
|
|
453
|
+
return [{ rowsAffected: result.rowsAffected }];
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
async returningAll() {
|
|
457
|
+
const allColumns = Object.keys(
|
|
458
|
+
this.table._.columns
|
|
451
459
|
);
|
|
460
|
+
return this.returning(...allColumns).execute();
|
|
452
461
|
}
|
|
453
462
|
};
|
|
463
|
+
|
|
464
|
+
// src/builders/insert.ts
|
|
454
465
|
var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
455
466
|
constructor(db, table) {
|
|
456
467
|
super(db);
|
|
@@ -468,13 +479,7 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
|
468
479
|
return this;
|
|
469
480
|
}
|
|
470
481
|
returning(...columns) {
|
|
471
|
-
|
|
472
|
-
if (typeof col === "string") {
|
|
473
|
-
this.returningColumns.push(this.table._.columns[col]);
|
|
474
|
-
} else {
|
|
475
|
-
this.returningColumns.push(col);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
482
|
+
this.returningColumns.push(...columns);
|
|
478
483
|
return this;
|
|
479
484
|
}
|
|
480
485
|
onConflictDoNothing(target) {
|
|
@@ -559,7 +564,7 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
|
559
564
|
params.push(...setValues);
|
|
560
565
|
}
|
|
561
566
|
if (this.returningColumns.length > 0) {
|
|
562
|
-
const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
|
|
567
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
563
568
|
const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
|
|
564
569
|
const rows = await this.db.select(queryWithReturning, params);
|
|
565
570
|
results = results.concat(rows);
|
|
@@ -581,81 +586,8 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
|
581
586
|
return this.returning(...allColumns).execute();
|
|
582
587
|
}
|
|
583
588
|
};
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
super(db);
|
|
587
|
-
this.table = table;
|
|
588
|
-
this.query = `UPDATE ${table._.name}`;
|
|
589
|
-
}
|
|
590
|
-
updateData = {};
|
|
591
|
-
returningColumns = [];
|
|
592
|
-
set(data) {
|
|
593
|
-
this.updateData = { ...this.updateData, ...data };
|
|
594
|
-
return this;
|
|
595
|
-
}
|
|
596
|
-
returning(...columns) {
|
|
597
|
-
for (const col of columns) {
|
|
598
|
-
if (typeof col === "string") {
|
|
599
|
-
this.returningColumns.push(this.table._.columns[col]);
|
|
600
|
-
} else {
|
|
601
|
-
this.returningColumns.push(col);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
return this;
|
|
605
|
-
}
|
|
606
|
-
buildUpdateClause() {
|
|
607
|
-
const finalUpdateData = { ...this.updateData };
|
|
608
|
-
for (const [key, column] of Object.entries(this.table._.columns)) {
|
|
609
|
-
const typedKey = key;
|
|
610
|
-
if (finalUpdateData[typedKey] === void 0 && column.options.$onUpdateFn) {
|
|
611
|
-
finalUpdateData[typedKey] = column.options.$onUpdateFn();
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
const baseQuery = this.query;
|
|
615
|
-
const whereParams = this.params;
|
|
616
|
-
let tablePart = baseQuery;
|
|
617
|
-
let whereClause = "";
|
|
618
|
-
const whereIndex = baseQuery.indexOf(" WHERE ");
|
|
619
|
-
if (whereIndex !== -1) {
|
|
620
|
-
tablePart = baseQuery.substring(0, whereIndex);
|
|
621
|
-
whereClause = baseQuery.substring(whereIndex);
|
|
622
|
-
}
|
|
623
|
-
const entries = Object.entries(finalUpdateData);
|
|
624
|
-
if (entries.length === 0) {
|
|
625
|
-
throw new Error("Cannot execute an update query without a .set() call.");
|
|
626
|
-
}
|
|
627
|
-
const setClause = entries.map(([key]) => {
|
|
628
|
-
const column = this.table._.columns[key];
|
|
629
|
-
if (!column) {
|
|
630
|
-
throw new Error(
|
|
631
|
-
`Column ${key} does not exist on table ${this.table._.name}`
|
|
632
|
-
);
|
|
633
|
-
}
|
|
634
|
-
return `${column._.name} = ?`;
|
|
635
|
-
}).join(", ");
|
|
636
|
-
const setParams = entries.map(([, value]) => value);
|
|
637
|
-
const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
|
|
638
|
-
const params = [...setParams, ...whereParams];
|
|
639
|
-
return { sql: sql2, params };
|
|
640
|
-
}
|
|
641
|
-
async execute() {
|
|
642
|
-
const { sql: updateSql, params } = this.buildUpdateClause();
|
|
643
|
-
if (this.returningColumns.length > 0) {
|
|
644
|
-
const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
|
|
645
|
-
const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
|
|
646
|
-
return this.db.select(sqlWithReturning, params);
|
|
647
|
-
} else {
|
|
648
|
-
const result = await this.db.execute(updateSql, params);
|
|
649
|
-
return [{ rowsAffected: result.rowsAffected }];
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
async returningAll() {
|
|
653
|
-
const allColumns = Object.keys(
|
|
654
|
-
this.table._.columns
|
|
655
|
-
);
|
|
656
|
-
return this.returning(...allColumns).execute();
|
|
657
|
-
}
|
|
658
|
-
};
|
|
589
|
+
|
|
590
|
+
// src/builders/delete.ts
|
|
659
591
|
var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
660
592
|
constructor(db, table) {
|
|
661
593
|
super(db);
|
|
@@ -664,19 +596,13 @@ var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
|
664
596
|
}
|
|
665
597
|
returningColumns = [];
|
|
666
598
|
returning(...columns) {
|
|
667
|
-
|
|
668
|
-
if (typeof col === "string") {
|
|
669
|
-
this.returningColumns.push(this.table._.columns[col]);
|
|
670
|
-
} else {
|
|
671
|
-
this.returningColumns.push(col);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
599
|
+
this.returningColumns.push(...columns);
|
|
674
600
|
return this;
|
|
675
601
|
}
|
|
676
602
|
async execute() {
|
|
677
603
|
const { sql: sql2, params } = this.build();
|
|
678
604
|
if (this.returningColumns.length > 0) {
|
|
679
|
-
const returningNames = this.returningColumns.map((col) => col._.name).join(", ");
|
|
605
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
680
606
|
const sqlWithReturning = `${sql2} RETURNING ${returningNames}`;
|
|
681
607
|
return this.db.select(sqlWithReturning, params);
|
|
682
608
|
} else {
|
|
@@ -685,12 +611,12 @@ var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
|
685
611
|
}
|
|
686
612
|
}
|
|
687
613
|
async returningAll() {
|
|
688
|
-
const allColumns = Object.keys(
|
|
689
|
-
this.table._.columns
|
|
690
|
-
);
|
|
614
|
+
const allColumns = Object.keys(this.table._.columns);
|
|
691
615
|
return this.returning(...allColumns).execute();
|
|
692
616
|
}
|
|
693
617
|
};
|
|
618
|
+
|
|
619
|
+
// src/builders/with.ts
|
|
694
620
|
var WithQueryBuilder = class {
|
|
695
621
|
constructor(db) {
|
|
696
622
|
this.db = db;
|
|
@@ -700,12 +626,8 @@ var WithQueryBuilder = class {
|
|
|
700
626
|
this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
|
|
701
627
|
return this;
|
|
702
628
|
}
|
|
703
|
-
select(table,
|
|
704
|
-
const builder = new SelectQueryBuilder(
|
|
705
|
-
this.db,
|
|
706
|
-
table,
|
|
707
|
-
selection
|
|
708
|
-
);
|
|
629
|
+
select(table, columns) {
|
|
630
|
+
const builder = new SelectQueryBuilder(this.db, table, columns);
|
|
709
631
|
this.applyWithClause(builder);
|
|
710
632
|
return builder;
|
|
711
633
|
}
|
|
@@ -737,13 +659,117 @@ var WithQueryBuilder = class {
|
|
|
737
659
|
};
|
|
738
660
|
|
|
739
661
|
// src/orm.ts
|
|
662
|
+
var SQLiteColumn = class _SQLiteColumn {
|
|
663
|
+
constructor(name, type, options = {}, mode) {
|
|
664
|
+
this.type = type;
|
|
665
|
+
this.options = options;
|
|
666
|
+
this._ = {
|
|
667
|
+
name,
|
|
668
|
+
dataType: type,
|
|
669
|
+
mode: mode || "default",
|
|
670
|
+
notNull: options.notNull ?? false,
|
|
671
|
+
hasDefault: options.default !== void 0 || options.$defaultFn !== void 0,
|
|
672
|
+
autoincrement: options.autoincrement ?? false,
|
|
673
|
+
enum: options.enum,
|
|
674
|
+
customType: void 0
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
_;
|
|
678
|
+
notNull() {
|
|
679
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, notNull: true }, this._.mode);
|
|
680
|
+
}
|
|
681
|
+
default(value) {
|
|
682
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, default: value }, this._.mode);
|
|
683
|
+
}
|
|
684
|
+
$defaultFn(fn) {
|
|
685
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, $defaultFn: fn }, this._.mode);
|
|
686
|
+
}
|
|
687
|
+
primaryKey() {
|
|
688
|
+
return new _SQLiteColumn(
|
|
689
|
+
this._.name,
|
|
690
|
+
this.type,
|
|
691
|
+
{ ...this.options, primaryKey: true, notNull: true },
|
|
692
|
+
this._.mode
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
autoincrement() {
|
|
696
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, autoincrement: true }, this._.mode);
|
|
697
|
+
}
|
|
698
|
+
unique() {
|
|
699
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, unique: true }, this._.mode);
|
|
700
|
+
}
|
|
701
|
+
references(ref, column) {
|
|
702
|
+
return new _SQLiteColumn(
|
|
703
|
+
this._.name,
|
|
704
|
+
this.type,
|
|
705
|
+
{
|
|
706
|
+
...this.options,
|
|
707
|
+
references: {
|
|
708
|
+
table: ref,
|
|
709
|
+
column: ref._.columns[column]
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
this._.mode
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
$onUpdateFn(fn) {
|
|
716
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, $onUpdateFn: fn }, this._.mode);
|
|
717
|
+
}
|
|
718
|
+
$type() {
|
|
719
|
+
return this;
|
|
720
|
+
}
|
|
721
|
+
as(alias2) {
|
|
722
|
+
return this;
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
var Table = class {
|
|
726
|
+
_;
|
|
727
|
+
relations = {};
|
|
728
|
+
constructor(name, columns) {
|
|
729
|
+
this._ = {
|
|
730
|
+
name,
|
|
731
|
+
columns
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
var sqliteTable = (tableName, columns) => {
|
|
736
|
+
return new Table(tableName, columns);
|
|
737
|
+
};
|
|
738
|
+
var asc = (column) => ({
|
|
739
|
+
sql: `${column._.name} ASC`,
|
|
740
|
+
params: []
|
|
741
|
+
});
|
|
742
|
+
var desc = (column) => ({
|
|
743
|
+
sql: `${column._.name} DESC`,
|
|
744
|
+
params: []
|
|
745
|
+
});
|
|
746
|
+
var sql = (strings, ...values) => {
|
|
747
|
+
const queryParts = [];
|
|
748
|
+
const params = [];
|
|
749
|
+
strings.forEach((str, i) => {
|
|
750
|
+
queryParts.push(str);
|
|
751
|
+
if (values[i] !== void 0) {
|
|
752
|
+
if (typeof values[i] === "object" && values[i].sql) {
|
|
753
|
+
queryParts.push(values[i].sql);
|
|
754
|
+
params.push(...values[i].params);
|
|
755
|
+
} else {
|
|
756
|
+
queryParts.push("?");
|
|
757
|
+
params.push(values[i]);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
return {
|
|
762
|
+
sql: queryParts.join(""),
|
|
763
|
+
params
|
|
764
|
+
};
|
|
765
|
+
};
|
|
740
766
|
var TauriORM = class {
|
|
741
767
|
constructor(db, schema = void 0) {
|
|
742
768
|
this.db = db;
|
|
743
769
|
if (schema) {
|
|
744
|
-
for (const
|
|
745
|
-
if (
|
|
746
|
-
this.tables.set(
|
|
770
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
771
|
+
if (value instanceof Table) {
|
|
772
|
+
this.tables.set(value._.name, value);
|
|
747
773
|
}
|
|
748
774
|
}
|
|
749
775
|
}
|
|
@@ -768,31 +794,60 @@ var TauriORM = class {
|
|
|
768
794
|
}
|
|
769
795
|
return sql2;
|
|
770
796
|
}
|
|
771
|
-
async migrate() {
|
|
797
|
+
async migrate(options) {
|
|
798
|
+
const dbTables = await this.db.select(
|
|
799
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'`
|
|
800
|
+
);
|
|
801
|
+
const dbTableNames = new Set(dbTables.map((t) => t.name));
|
|
802
|
+
const schemaTableNames = new Set(Array.from(this.tables.keys()));
|
|
772
803
|
for (const table of this.tables.values()) {
|
|
773
|
-
const
|
|
774
|
-
|
|
775
|
-
)
|
|
776
|
-
if (existingTableInfo.length === 0) {
|
|
804
|
+
const tableName = table._.name;
|
|
805
|
+
const tableExists = dbTableNames.has(tableName);
|
|
806
|
+
if (!tableExists) {
|
|
777
807
|
const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
|
|
778
|
-
const createSql = `CREATE TABLE ${
|
|
808
|
+
const createSql = `CREATE TABLE ${tableName}
|
|
809
|
+
(
|
|
810
|
+
${columnsSql}
|
|
811
|
+
)`;
|
|
779
812
|
await this.db.execute(createSql);
|
|
780
813
|
} else {
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
);
|
|
814
|
+
const existingTableInfo = await this.db.select(`PRAGMA table_info('${tableName}')`);
|
|
815
|
+
const existingColumnNames = new Set(existingTableInfo.map((c) => c.name));
|
|
816
|
+
const schemaColumnNames = new Set(Object.keys(table._.columns));
|
|
784
817
|
for (const column of Object.values(table._.columns)) {
|
|
785
818
|
if (!existingColumnNames.has(column._.name)) {
|
|
786
819
|
const columnSql = this.buildColumnDefinition(column, true);
|
|
787
|
-
const alterSql = `ALTER TABLE ${
|
|
820
|
+
const alterSql = `ALTER TABLE ${tableName}
|
|
821
|
+
ADD COLUMN ${columnSql}`;
|
|
788
822
|
await this.db.execute(alterSql);
|
|
789
823
|
}
|
|
790
824
|
}
|
|
825
|
+
if (options?.performDestructiveActions) {
|
|
826
|
+
for (const colName of existingColumnNames) {
|
|
827
|
+
if (!schemaColumnNames.has(colName)) {
|
|
828
|
+
await this.dropColumn(tableName, colName);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
if (options?.performDestructiveActions) {
|
|
835
|
+
for (const tableName of dbTableNames) {
|
|
836
|
+
if (!schemaTableNames.has(tableName)) {
|
|
837
|
+
await this.dropTable(tableName);
|
|
838
|
+
}
|
|
791
839
|
}
|
|
792
840
|
}
|
|
793
841
|
}
|
|
794
|
-
select(
|
|
795
|
-
|
|
842
|
+
select(table, columns) {
|
|
843
|
+
const internalTable = this.tables.get(table._.name);
|
|
844
|
+
if (!internalTable) {
|
|
845
|
+
console.warn(
|
|
846
|
+
`[Tauri-ORM] Table "${table._.name}" was not passed in the schema to the ORM constructor. Relations will not be available.`
|
|
847
|
+
);
|
|
848
|
+
return new SelectQueryBuilder(this.db, table, columns);
|
|
849
|
+
}
|
|
850
|
+
return new SelectQueryBuilder(this.db, internalTable, columns);
|
|
796
851
|
}
|
|
797
852
|
insert(table) {
|
|
798
853
|
return new InsertQueryBuilder(this.db, table);
|
|
@@ -829,13 +884,25 @@ var TauriORM = class {
|
|
|
829
884
|
// --- Schema detection / signature ---
|
|
830
885
|
async ensureSchemaMeta() {
|
|
831
886
|
await this.db.execute(
|
|
832
|
-
`CREATE TABLE IF NOT EXISTS _schema_meta
|
|
887
|
+
`CREATE TABLE IF NOT EXISTS _schema_meta
|
|
888
|
+
(
|
|
889
|
+
key
|
|
890
|
+
TEXT
|
|
891
|
+
PRIMARY
|
|
892
|
+
KEY,
|
|
893
|
+
value
|
|
894
|
+
TEXT
|
|
895
|
+
NOT
|
|
896
|
+
NULL
|
|
897
|
+
)`
|
|
833
898
|
);
|
|
834
899
|
}
|
|
835
900
|
async getSchemaMeta(key) {
|
|
836
901
|
await this.ensureSchemaMeta();
|
|
837
902
|
const rows = await this.db.select(
|
|
838
|
-
`SELECT value
|
|
903
|
+
`SELECT value
|
|
904
|
+
FROM _schema_meta
|
|
905
|
+
WHERE key = ?`,
|
|
839
906
|
[key]
|
|
840
907
|
);
|
|
841
908
|
return rows?.[0]?.value ?? null;
|
|
@@ -843,7 +910,10 @@ var TauriORM = class {
|
|
|
843
910
|
async setSchemaMeta(key, value) {
|
|
844
911
|
await this.ensureSchemaMeta();
|
|
845
912
|
await this.db.execute(
|
|
846
|
-
`INSERT INTO _schema_meta(key, value)
|
|
913
|
+
`INSERT INTO _schema_meta(key, value)
|
|
914
|
+
VALUES (?, ?) ON CONFLICT(key) DO
|
|
915
|
+
UPDATE
|
|
916
|
+
SET value = excluded.value`,
|
|
847
917
|
[key, value]
|
|
848
918
|
);
|
|
849
919
|
}
|
|
@@ -880,14 +950,34 @@ var TauriORM = class {
|
|
|
880
950
|
const status = await this.isSchemaDirty();
|
|
881
951
|
if (status.dirty) {
|
|
882
952
|
await this.migrate();
|
|
883
|
-
await this.setSchemaMeta(
|
|
884
|
-
"schema_signature",
|
|
885
|
-
this.computeModelSignature()
|
|
886
|
-
);
|
|
953
|
+
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
887
954
|
return true;
|
|
888
955
|
}
|
|
889
956
|
return false;
|
|
890
957
|
}
|
|
958
|
+
async doesTableExist(tableName) {
|
|
959
|
+
const result = await this.db.select(
|
|
960
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
|
|
961
|
+
[tableName]
|
|
962
|
+
);
|
|
963
|
+
return result.length > 0;
|
|
964
|
+
}
|
|
965
|
+
async dropTable(tableName) {
|
|
966
|
+
await this.db.execute(`DROP TABLE IF EXISTS ${tableName}`);
|
|
967
|
+
}
|
|
968
|
+
async doesColumnExist(tableName, columnName) {
|
|
969
|
+
const result = await this.db.select(`PRAGMA table_info('${tableName}')`);
|
|
970
|
+
return result.some((col) => col.name === columnName);
|
|
971
|
+
}
|
|
972
|
+
async renameTable(from, to) {
|
|
973
|
+
await this.db.execute(`ALTER TABLE ${from} RENAME TO ${to}`);
|
|
974
|
+
}
|
|
975
|
+
async dropColumn(tableName, columnName) {
|
|
976
|
+
await this.db.execute(`ALTER TABLE ${tableName} DROP COLUMN ${columnName}`);
|
|
977
|
+
}
|
|
978
|
+
async renameColumn(tableName, from, to) {
|
|
979
|
+
await this.db.execute(`ALTER TABLE ${tableName} RENAME COLUMN ${from} TO ${to}`);
|
|
980
|
+
}
|
|
891
981
|
};
|
|
892
982
|
var Relation = class {
|
|
893
983
|
constructor(foreignTable) {
|
|
@@ -905,16 +995,47 @@ var ManyRelation = class extends Relation {
|
|
|
905
995
|
super(foreignTable);
|
|
906
996
|
}
|
|
907
997
|
};
|
|
908
|
-
var relations = (
|
|
909
|
-
|
|
910
|
-
one: (
|
|
911
|
-
return new OneRelation(
|
|
998
|
+
var relations = (table, relationsCallback) => {
|
|
999
|
+
const builtRelations = relationsCallback({
|
|
1000
|
+
one: (foreignTable, config) => {
|
|
1001
|
+
return new OneRelation(foreignTable, config);
|
|
912
1002
|
},
|
|
913
|
-
many: (
|
|
914
|
-
return new ManyRelation(
|
|
1003
|
+
many: (foreignTable) => {
|
|
1004
|
+
return new ManyRelation(foreignTable);
|
|
915
1005
|
}
|
|
916
1006
|
});
|
|
1007
|
+
for (const [name, relation] of Object.entries(builtRelations)) {
|
|
1008
|
+
if (relation instanceof OneRelation) {
|
|
1009
|
+
table.relations[name] = {
|
|
1010
|
+
type: "one",
|
|
1011
|
+
foreignTable: relation.foreignTable,
|
|
1012
|
+
fields: relation.config?.fields,
|
|
1013
|
+
references: relation.config?.references
|
|
1014
|
+
};
|
|
1015
|
+
} else if (relation instanceof ManyRelation) {
|
|
1016
|
+
table.relations[name] = {
|
|
1017
|
+
type: "many",
|
|
1018
|
+
foreignTable: relation.foreignTable
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
return builtRelations;
|
|
1023
|
+
};
|
|
1024
|
+
var getTableColumns = (table) => {
|
|
1025
|
+
return table._.columns;
|
|
917
1026
|
};
|
|
1027
|
+
var alias = (table, alias2) => {
|
|
1028
|
+
return table;
|
|
1029
|
+
};
|
|
1030
|
+
|
|
1031
|
+
// src/column-helpers.ts
|
|
1032
|
+
var text = (name, config) => new SQLiteColumn(name, "TEXT", config, config?.mode);
|
|
1033
|
+
var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
|
|
1034
|
+
var real = (name) => new SQLiteColumn(name, "REAL");
|
|
1035
|
+
var blob = (name, config) => new SQLiteColumn(name, "BLOB", {}, config?.mode);
|
|
1036
|
+
var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
|
|
1037
|
+
var numeric = (name, config) => new SQLiteColumn(name, "NUMERIC", {}, config?.mode);
|
|
1038
|
+
var enumType = (name, values) => text(name, { enum: values });
|
|
918
1039
|
// Annotate the CommonJS export names for ESM import in node:
|
|
919
1040
|
0 && (module.exports = {
|
|
920
1041
|
BaseQueryBuilder,
|
|
@@ -924,7 +1045,6 @@ var relations = (_table, relationsCallback) => {
|
|
|
924
1045
|
OneRelation,
|
|
925
1046
|
Relation,
|
|
926
1047
|
SQLiteColumn,
|
|
927
|
-
SelectBuilder,
|
|
928
1048
|
SelectQueryBuilder,
|
|
929
1049
|
Table,
|
|
930
1050
|
TauriORM,
|
|
@@ -939,6 +1059,7 @@ var relations = (_table, relationsCallback) => {
|
|
|
939
1059
|
count,
|
|
940
1060
|
countDistinct,
|
|
941
1061
|
desc,
|
|
1062
|
+
enumType,
|
|
942
1063
|
eq,
|
|
943
1064
|
getTableColumns,
|
|
944
1065
|
gt,
|
|
@@ -953,6 +1074,7 @@ var relations = (_table, relationsCallback) => {
|
|
|
953
1074
|
max,
|
|
954
1075
|
min,
|
|
955
1076
|
not,
|
|
1077
|
+
numeric,
|
|
956
1078
|
or,
|
|
957
1079
|
real,
|
|
958
1080
|
relations,
|