@type32/tauri-sqlite-orm 0.1.18-0 → 0.1.18-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/README.md +0 -156
- package/dist/index.d.mts +195 -73
- package/dist/index.d.ts +195 -73
- package/dist/index.js +663 -193
- package/dist/index.mjs +643 -190
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,483 @@
|
|
|
1
|
+
// src/builders/query-base.ts
|
|
2
|
+
var BaseQueryBuilder = class {
|
|
3
|
+
constructor(db) {
|
|
4
|
+
this.db = db;
|
|
5
|
+
}
|
|
6
|
+
query = "";
|
|
7
|
+
params = [];
|
|
8
|
+
where(condition) {
|
|
9
|
+
this.query += ` WHERE ${condition.sql}`;
|
|
10
|
+
this.params.push(...condition.params);
|
|
11
|
+
return this;
|
|
12
|
+
}
|
|
13
|
+
orderBy(column, direction = "ASC") {
|
|
14
|
+
if ("sql" in column) {
|
|
15
|
+
this.query += ` ORDER BY ${column.sql} ${direction}`;
|
|
16
|
+
this.params.push(...column.params);
|
|
17
|
+
} else {
|
|
18
|
+
this.query += ` ORDER BY ${column._.name} ${direction}`;
|
|
19
|
+
}
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
limit(count2) {
|
|
23
|
+
this.query += ` LIMIT ${count2}`;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
offset(count2) {
|
|
27
|
+
this.query += ` OFFSET ${count2}`;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
build() {
|
|
31
|
+
return {
|
|
32
|
+
sql: this.query,
|
|
33
|
+
params: this.params
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/operators.ts
|
|
39
|
+
var eq = (column, value) => ({
|
|
40
|
+
sql: `${column._.name} = ?`,
|
|
41
|
+
params: [value]
|
|
42
|
+
});
|
|
43
|
+
var and = (...conditions) => ({
|
|
44
|
+
sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
|
|
45
|
+
params: conditions.flatMap((c) => c.params)
|
|
46
|
+
});
|
|
47
|
+
var or = (...conditions) => ({
|
|
48
|
+
sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
|
|
49
|
+
params: conditions.flatMap((c) => c.params)
|
|
50
|
+
});
|
|
51
|
+
var not = (condition) => ({
|
|
52
|
+
sql: `NOT (${condition.sql})`,
|
|
53
|
+
params: condition.params
|
|
54
|
+
});
|
|
55
|
+
var gt = (column, value) => ({
|
|
56
|
+
sql: `${column._.name} > ?`,
|
|
57
|
+
params: [value]
|
|
58
|
+
});
|
|
59
|
+
var gte = (column, value) => ({
|
|
60
|
+
sql: `${column._.name} >= ?`,
|
|
61
|
+
params: [value]
|
|
62
|
+
});
|
|
63
|
+
var lt = (column, value) => ({
|
|
64
|
+
sql: `${column._.name} < ?`,
|
|
65
|
+
params: [value]
|
|
66
|
+
});
|
|
67
|
+
var lte = (column, value) => ({
|
|
68
|
+
sql: `${column._.name} <= ?`,
|
|
69
|
+
params: [value]
|
|
70
|
+
});
|
|
71
|
+
var like = (column, pattern) => ({
|
|
72
|
+
sql: `${column._.name} LIKE ?`,
|
|
73
|
+
params: [pattern]
|
|
74
|
+
});
|
|
75
|
+
var isNull = (column) => ({
|
|
76
|
+
sql: `${column._.name} IS NULL`,
|
|
77
|
+
params: []
|
|
78
|
+
});
|
|
79
|
+
var isNotNull = (column) => ({
|
|
80
|
+
sql: `${column._.name} IS NOT NULL`,
|
|
81
|
+
params: []
|
|
82
|
+
});
|
|
83
|
+
var inArray = (column, values) => ({
|
|
84
|
+
sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
|
|
85
|
+
params: values
|
|
86
|
+
});
|
|
87
|
+
var count = (column) => ({
|
|
88
|
+
sql: `COUNT(${column ? column._.name : "*"})`,
|
|
89
|
+
params: []
|
|
90
|
+
});
|
|
91
|
+
var countDistinct = (column) => ({
|
|
92
|
+
sql: `COUNT(DISTINCT ${column._.name})`,
|
|
93
|
+
params: []
|
|
94
|
+
});
|
|
95
|
+
var sum = (column) => ({
|
|
96
|
+
sql: `SUM(${column._.name})`,
|
|
97
|
+
params: []
|
|
98
|
+
});
|
|
99
|
+
var avg = (column) => ({
|
|
100
|
+
sql: `AVG(${column._.name})`,
|
|
101
|
+
params: []
|
|
102
|
+
});
|
|
103
|
+
var max = (column) => ({
|
|
104
|
+
sql: `MAX(${column._.name})`,
|
|
105
|
+
params: []
|
|
106
|
+
});
|
|
107
|
+
var min = (column) => ({
|
|
108
|
+
sql: `MIN(${column._.name})`,
|
|
109
|
+
params: []
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// src/builders/select.ts
|
|
113
|
+
var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
114
|
+
constructor(db, table, columns) {
|
|
115
|
+
super(db);
|
|
116
|
+
this.table = table;
|
|
117
|
+
this.columns = columns;
|
|
118
|
+
const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
|
|
119
|
+
this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
|
|
120
|
+
}
|
|
121
|
+
isDistinct = false;
|
|
122
|
+
groupByColumns = [];
|
|
123
|
+
havingCondition = null;
|
|
124
|
+
joins = [];
|
|
125
|
+
includeRelations = {};
|
|
126
|
+
distinct() {
|
|
127
|
+
this.isDistinct = true;
|
|
128
|
+
this.query = this.query.replace("SELECT", "SELECT DISTINCT");
|
|
129
|
+
return this;
|
|
130
|
+
}
|
|
131
|
+
groupBy(...columns) {
|
|
132
|
+
this.groupByColumns.push(...columns);
|
|
133
|
+
const columnNames = columns.map((col) => col._.name).join(", ");
|
|
134
|
+
this.query += ` GROUP BY ${columnNames}`;
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
having(condition) {
|
|
138
|
+
this.havingCondition = condition;
|
|
139
|
+
this.query += ` HAVING ${condition.sql}`;
|
|
140
|
+
this.params.push(...condition.params);
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
leftJoin(table, condition, alias2) {
|
|
144
|
+
this.joins.push({ type: "LEFT", table, condition, alias: alias2 });
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
innerJoin(table, condition, alias2) {
|
|
148
|
+
this.joins.push({ type: "INNER", table, condition, alias: alias2 });
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
include(relations2) {
|
|
152
|
+
this.includeRelations = { ...this.includeRelations, ...relations2 };
|
|
153
|
+
return this;
|
|
154
|
+
}
|
|
155
|
+
buildJoins() {
|
|
156
|
+
let sql2 = "";
|
|
157
|
+
const params = [];
|
|
158
|
+
for (const join of this.joins) {
|
|
159
|
+
const tableAlias = join.alias || join.table._.name;
|
|
160
|
+
sql2 += ` ${join.type} JOIN ${join.table._.name} ${tableAlias} ON ${join.condition.sql}`;
|
|
161
|
+
params.push(...join.condition.params);
|
|
162
|
+
}
|
|
163
|
+
for (const [relationName, include] of Object.entries(
|
|
164
|
+
this.includeRelations
|
|
165
|
+
)) {
|
|
166
|
+
if (!include) continue;
|
|
167
|
+
const relation = this.table.relations[relationName];
|
|
168
|
+
if (!relation) continue;
|
|
169
|
+
const foreignTable = relation.foreignTable;
|
|
170
|
+
const foreignAlias = `${this.table._.name}_${relationName}`;
|
|
171
|
+
if (relation.type === "one" && relation.fields && relation.references) {
|
|
172
|
+
const conditions = relation.fields.map(
|
|
173
|
+
(field, i) => eq(field, relation.references[i])
|
|
174
|
+
);
|
|
175
|
+
const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
|
|
176
|
+
sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
|
|
177
|
+
params.push(...condition.params);
|
|
178
|
+
} else if (relation.type === "many") {
|
|
179
|
+
const refRelation = Object.values(foreignTable.relations).find(
|
|
180
|
+
(r) => r.foreignTable === this.table
|
|
181
|
+
);
|
|
182
|
+
if (refRelation && refRelation.fields && refRelation.references) {
|
|
183
|
+
const conditions = refRelation.fields.map(
|
|
184
|
+
(field, i) => eq(field, refRelation.references[i])
|
|
185
|
+
);
|
|
186
|
+
const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
|
|
187
|
+
sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
|
|
188
|
+
params.push(...condition.params);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return { sql: sql2, params };
|
|
193
|
+
}
|
|
194
|
+
async execute() {
|
|
195
|
+
const { sql: joinSql, params: joinParams } = this.buildJoins();
|
|
196
|
+
this.query += joinSql;
|
|
197
|
+
this.params.push(...joinParams);
|
|
198
|
+
const { sql: sql2, params } = this.build();
|
|
199
|
+
return this.db.select(sql2, params);
|
|
200
|
+
}
|
|
201
|
+
async all() {
|
|
202
|
+
return this.execute();
|
|
203
|
+
}
|
|
204
|
+
async get() {
|
|
205
|
+
this.limit(1);
|
|
206
|
+
const result = await this.execute();
|
|
207
|
+
return result[0];
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// src/builders/update.ts
|
|
212
|
+
var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
213
|
+
constructor(db, table) {
|
|
214
|
+
super(db);
|
|
215
|
+
this.table = table;
|
|
216
|
+
this.query = `UPDATE ${table._.name}`;
|
|
217
|
+
}
|
|
218
|
+
updateData = {};
|
|
219
|
+
returningColumns = [];
|
|
220
|
+
set(data) {
|
|
221
|
+
this.updateData = { ...this.updateData, ...data };
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
returning(...columns) {
|
|
225
|
+
this.returningColumns.push(...columns);
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
228
|
+
buildUpdateClause() {
|
|
229
|
+
const finalUpdateData = { ...this.updateData };
|
|
230
|
+
for (const [key, column] of Object.entries(this.table._.columns)) {
|
|
231
|
+
const typedKey = key;
|
|
232
|
+
if (finalUpdateData[typedKey] === void 0 && column.options.$onUpdateFn) {
|
|
233
|
+
finalUpdateData[typedKey] = column.options.$onUpdateFn();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const baseQuery = this.query;
|
|
237
|
+
const whereParams = this.params;
|
|
238
|
+
let tablePart = baseQuery;
|
|
239
|
+
let whereClause = "";
|
|
240
|
+
const whereIndex = baseQuery.indexOf(" WHERE ");
|
|
241
|
+
if (whereIndex !== -1) {
|
|
242
|
+
tablePart = baseQuery.substring(0, whereIndex);
|
|
243
|
+
whereClause = baseQuery.substring(whereIndex);
|
|
244
|
+
}
|
|
245
|
+
const entries = Object.entries(finalUpdateData);
|
|
246
|
+
if (entries.length === 0) {
|
|
247
|
+
throw new Error("Cannot execute an update query without a .set() call.");
|
|
248
|
+
}
|
|
249
|
+
const setClause = entries.map(([key]) => {
|
|
250
|
+
const column = this.table._.columns[key];
|
|
251
|
+
if (!column) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
`Column ${key} does not exist on table ${this.table._.name}`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
return `${column._.name} = ?`;
|
|
257
|
+
}).join(", ");
|
|
258
|
+
const setParams = entries.map(([, value]) => value);
|
|
259
|
+
const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
|
|
260
|
+
const params = [...setParams, ...whereParams];
|
|
261
|
+
return { sql: sql2, params };
|
|
262
|
+
}
|
|
263
|
+
async execute() {
|
|
264
|
+
const { sql: updateSql, params } = this.buildUpdateClause();
|
|
265
|
+
if (this.returningColumns.length > 0) {
|
|
266
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
267
|
+
const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
|
|
268
|
+
return this.db.select(sqlWithReturning, params);
|
|
269
|
+
} else {
|
|
270
|
+
const result = await this.db.execute(updateSql, params);
|
|
271
|
+
return [{ rowsAffected: result.rowsAffected }];
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
async returningAll() {
|
|
275
|
+
const allColumns = Object.keys(
|
|
276
|
+
this.table._.columns
|
|
277
|
+
);
|
|
278
|
+
return this.returning(...allColumns).execute();
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
// src/builders/insert.ts
|
|
283
|
+
var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
284
|
+
constructor(db, table) {
|
|
285
|
+
super(db);
|
|
286
|
+
this.table = table;
|
|
287
|
+
this.query = `INSERT INTO ${table._.name}`;
|
|
288
|
+
}
|
|
289
|
+
dataSets = [];
|
|
290
|
+
returningColumns = [];
|
|
291
|
+
onConflictAction = null;
|
|
292
|
+
conflictTarget = [];
|
|
293
|
+
updateSet = {};
|
|
294
|
+
values(data) {
|
|
295
|
+
const dataArray = Array.isArray(data) ? data : [data];
|
|
296
|
+
this.dataSets.push(...dataArray);
|
|
297
|
+
return this;
|
|
298
|
+
}
|
|
299
|
+
returning(...columns) {
|
|
300
|
+
this.returningColumns.push(...columns);
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
onConflictDoNothing(target) {
|
|
304
|
+
this.onConflictAction = "nothing";
|
|
305
|
+
if (target) {
|
|
306
|
+
this.conflictTarget = Array.isArray(target) ? target : [target];
|
|
307
|
+
}
|
|
308
|
+
return this;
|
|
309
|
+
}
|
|
310
|
+
onConflictDoUpdate(config) {
|
|
311
|
+
this.onConflictAction = "update";
|
|
312
|
+
this.conflictTarget = Array.isArray(config.target) ? config.target : [config.target];
|
|
313
|
+
this.updateSet = config.set;
|
|
314
|
+
return this;
|
|
315
|
+
}
|
|
316
|
+
processDefaultValues(data) {
|
|
317
|
+
const finalData = { ...data };
|
|
318
|
+
for (const [key, column] of Object.entries(this.table._.columns)) {
|
|
319
|
+
const typedKey = key;
|
|
320
|
+
if (finalData[typedKey] === void 0) {
|
|
321
|
+
if (column.options.$defaultFn) {
|
|
322
|
+
finalData[typedKey] = column.options.$defaultFn();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return finalData;
|
|
327
|
+
}
|
|
328
|
+
buildConflictClause() {
|
|
329
|
+
if (!this.onConflictAction) return "";
|
|
330
|
+
let clause = " ON CONFLICT";
|
|
331
|
+
if (this.conflictTarget.length > 0) {
|
|
332
|
+
const targetNames = this.conflictTarget.map((col) => col._.name).join(", ");
|
|
333
|
+
clause += ` (${targetNames})`;
|
|
334
|
+
}
|
|
335
|
+
if (this.onConflictAction === "nothing") {
|
|
336
|
+
clause += " DO NOTHING";
|
|
337
|
+
} else if (this.onConflictAction === "update") {
|
|
338
|
+
const setEntries = Object.entries(this.updateSet);
|
|
339
|
+
if (setEntries.length > 0) {
|
|
340
|
+
const setClause = setEntries.map(([key]) => `${key} = ?`).join(", ");
|
|
341
|
+
clause += ` DO UPDATE SET ${setClause}`;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return clause;
|
|
345
|
+
}
|
|
346
|
+
async execute() {
|
|
347
|
+
if (this.dataSets.length === 0) {
|
|
348
|
+
throw new Error("No data provided for insert");
|
|
349
|
+
}
|
|
350
|
+
const processedDataSets = this.dataSets.map(
|
|
351
|
+
(data) => this.processDefaultValues(data)
|
|
352
|
+
);
|
|
353
|
+
const groups = /* @__PURE__ */ new Map();
|
|
354
|
+
for (const dataSet of processedDataSets) {
|
|
355
|
+
const keys = Object.keys(dataSet).sort().join(",");
|
|
356
|
+
if (!groups.has(keys)) {
|
|
357
|
+
groups.set(keys, []);
|
|
358
|
+
}
|
|
359
|
+
groups.get(keys).push(dataSet);
|
|
360
|
+
}
|
|
361
|
+
let results = [];
|
|
362
|
+
let lastInsertId;
|
|
363
|
+
let rowsAffected = 0;
|
|
364
|
+
for (const [_, dataSets] of groups) {
|
|
365
|
+
const columns = Object.keys(dataSets[0]);
|
|
366
|
+
const columnNames = columns.map(
|
|
367
|
+
(key) => this.table._.columns[key]._.name
|
|
368
|
+
);
|
|
369
|
+
const placeholders = `(${columns.map(() => "?").join(", ")})`;
|
|
370
|
+
const valuesSql = dataSets.map(() => placeholders).join(", ");
|
|
371
|
+
const conflictClause = this.buildConflictClause();
|
|
372
|
+
const finalQuery = `${this.query} (${columnNames.join(
|
|
373
|
+
", "
|
|
374
|
+
)}) VALUES ${valuesSql}${conflictClause}`;
|
|
375
|
+
const params = dataSets.flatMap(
|
|
376
|
+
(data) => columns.map((col) => data[col] ?? null)
|
|
377
|
+
);
|
|
378
|
+
if (this.onConflictAction === "update") {
|
|
379
|
+
const setValues = Object.entries(this.updateSet).map(
|
|
380
|
+
([, value]) => value
|
|
381
|
+
);
|
|
382
|
+
params.push(...setValues);
|
|
383
|
+
}
|
|
384
|
+
if (this.returningColumns.length > 0) {
|
|
385
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
386
|
+
const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
|
|
387
|
+
const rows = await this.db.select(queryWithReturning, params);
|
|
388
|
+
results = results.concat(rows);
|
|
389
|
+
} else {
|
|
390
|
+
const result = await this.db.execute(finalQuery, params);
|
|
391
|
+
lastInsertId = result.lastInsertId;
|
|
392
|
+
rowsAffected += result.rowsAffected;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (this.returningColumns.length > 0) {
|
|
396
|
+
return results;
|
|
397
|
+
}
|
|
398
|
+
return [{ lastInsertId, rowsAffected }];
|
|
399
|
+
}
|
|
400
|
+
async returningAll() {
|
|
401
|
+
const allColumns = Object.keys(
|
|
402
|
+
this.table._.columns
|
|
403
|
+
);
|
|
404
|
+
return this.returning(...allColumns).execute();
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
// src/builders/delete.ts
|
|
409
|
+
var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
410
|
+
constructor(db, table) {
|
|
411
|
+
super(db);
|
|
412
|
+
this.table = table;
|
|
413
|
+
this.query = `DELETE FROM ${table._.name}`;
|
|
414
|
+
}
|
|
415
|
+
returningColumns = [];
|
|
416
|
+
returning(...columns) {
|
|
417
|
+
this.returningColumns.push(...columns);
|
|
418
|
+
return this;
|
|
419
|
+
}
|
|
420
|
+
async execute() {
|
|
421
|
+
const { sql: sql2, params } = this.build();
|
|
422
|
+
if (this.returningColumns.length > 0) {
|
|
423
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
424
|
+
const sqlWithReturning = `${sql2} RETURNING ${returningNames}`;
|
|
425
|
+
return this.db.select(sqlWithReturning, params);
|
|
426
|
+
} else {
|
|
427
|
+
const result = await this.db.execute(sql2, params);
|
|
428
|
+
return [{ rowsAffected: result.rowsAffected }];
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
async returningAll() {
|
|
432
|
+
const allColumns = Object.keys(
|
|
433
|
+
this.table._.columns
|
|
434
|
+
);
|
|
435
|
+
return this.returning(...allColumns).execute();
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
// src/builders/with.ts
|
|
440
|
+
var WithQueryBuilder = class {
|
|
441
|
+
constructor(db) {
|
|
442
|
+
this.db = db;
|
|
443
|
+
}
|
|
444
|
+
ctes = [];
|
|
445
|
+
with(alias2, query) {
|
|
446
|
+
this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
|
|
447
|
+
return this;
|
|
448
|
+
}
|
|
449
|
+
select(table, columns) {
|
|
450
|
+
const builder = new SelectQueryBuilder(this.db, table, columns);
|
|
451
|
+
this.applyWithClause(builder);
|
|
452
|
+
return builder;
|
|
453
|
+
}
|
|
454
|
+
insert(table) {
|
|
455
|
+
const builder = new InsertQueryBuilder(this.db, table);
|
|
456
|
+
this.applyWithClause(builder);
|
|
457
|
+
return builder;
|
|
458
|
+
}
|
|
459
|
+
update(table) {
|
|
460
|
+
const builder = new UpdateQueryBuilder(this.db, table);
|
|
461
|
+
this.applyWithClause(builder);
|
|
462
|
+
return builder;
|
|
463
|
+
}
|
|
464
|
+
delete(table) {
|
|
465
|
+
const builder = new DeleteQueryBuilder(this.db, table);
|
|
466
|
+
this.applyWithClause(builder);
|
|
467
|
+
return builder;
|
|
468
|
+
}
|
|
469
|
+
applyWithClause(builder) {
|
|
470
|
+
if (this.ctes.length > 0) {
|
|
471
|
+
const cteSql = this.ctes.map((cte) => `${cte.alias} AS (${cte.query})`).join(", ");
|
|
472
|
+
builder["query"] = `WITH ${cteSql} ${builder["query"]}`;
|
|
473
|
+
builder["params"] = [
|
|
474
|
+
...this.ctes.flatMap((cte) => cte.params),
|
|
475
|
+
...builder["params"]
|
|
476
|
+
];
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
|
|
1
481
|
// src/orm.ts
|
|
2
482
|
var SQLiteColumn = class _SQLiteColumn {
|
|
3
483
|
constructor(name, type, options = {}, mode) {
|
|
@@ -41,7 +521,7 @@ var SQLiteColumn = class _SQLiteColumn {
|
|
|
41
521
|
return new _SQLiteColumn(
|
|
42
522
|
this._.name,
|
|
43
523
|
this.type,
|
|
44
|
-
{ ...this.options, primaryKey: true },
|
|
524
|
+
{ ...this.options, primaryKey: true, notNull: true },
|
|
45
525
|
this._.mode
|
|
46
526
|
);
|
|
47
527
|
}
|
|
@@ -83,14 +563,13 @@ var SQLiteColumn = class _SQLiteColumn {
|
|
|
83
563
|
this._.mode
|
|
84
564
|
);
|
|
85
565
|
}
|
|
566
|
+
as(alias2) {
|
|
567
|
+
return this;
|
|
568
|
+
}
|
|
86
569
|
};
|
|
87
|
-
var text = (name) => new SQLiteColumn(name, "TEXT");
|
|
88
|
-
var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
|
|
89
|
-
var real = (name) => new SQLiteColumn(name, "REAL");
|
|
90
|
-
var blob = (name) => new SQLiteColumn(name, "BLOB");
|
|
91
|
-
var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
|
|
92
570
|
var Table = class {
|
|
93
571
|
_;
|
|
572
|
+
relations = {};
|
|
94
573
|
constructor(name, columns) {
|
|
95
574
|
this._ = {
|
|
96
575
|
name,
|
|
@@ -101,194 +580,111 @@ var Table = class {
|
|
|
101
580
|
var sqliteTable = (tableName, columns) => {
|
|
102
581
|
return new Table(tableName, columns);
|
|
103
582
|
};
|
|
104
|
-
var
|
|
105
|
-
sql: `${column._.name}
|
|
106
|
-
params: [value]
|
|
107
|
-
});
|
|
108
|
-
var and = (...conditions) => ({
|
|
109
|
-
sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
|
|
110
|
-
params: conditions.flatMap((c) => c.params)
|
|
111
|
-
});
|
|
112
|
-
var or = (...conditions) => ({
|
|
113
|
-
sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
|
|
114
|
-
params: conditions.flatMap((c) => c.params)
|
|
115
|
-
});
|
|
116
|
-
var gt = (column, value) => ({
|
|
117
|
-
sql: `${column._.name} > ?`,
|
|
118
|
-
params: [value]
|
|
119
|
-
});
|
|
120
|
-
var gte = (column, value) => ({
|
|
121
|
-
sql: `${column._.name} >= ?`,
|
|
122
|
-
params: [value]
|
|
123
|
-
});
|
|
124
|
-
var lt = (column, value) => ({
|
|
125
|
-
sql: `${column._.name} < ?`,
|
|
126
|
-
params: [value]
|
|
127
|
-
});
|
|
128
|
-
var lte = (column, value) => ({
|
|
129
|
-
sql: `${column._.name} <= ?`,
|
|
130
|
-
params: [value]
|
|
131
|
-
});
|
|
132
|
-
var like = (column, pattern) => ({
|
|
133
|
-
sql: `${column._.name} LIKE ?`,
|
|
134
|
-
params: [pattern]
|
|
135
|
-
});
|
|
136
|
-
var isNull = (column) => ({
|
|
137
|
-
sql: `${column._.name} IS NULL`,
|
|
583
|
+
var asc = (column) => ({
|
|
584
|
+
sql: `${column._.name} ASC`,
|
|
138
585
|
params: []
|
|
139
586
|
});
|
|
140
|
-
var
|
|
141
|
-
sql: `${column._.name}
|
|
587
|
+
var desc = (column) => ({
|
|
588
|
+
sql: `${column._.name} DESC`,
|
|
142
589
|
params: []
|
|
143
590
|
});
|
|
144
|
-
var
|
|
145
|
-
|
|
146
|
-
params
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
return this;
|
|
158
|
-
}
|
|
159
|
-
orderBy(column, direction = "ASC") {
|
|
160
|
-
this.query += ` ORDER BY ${column._.name} ${direction}`;
|
|
161
|
-
return this;
|
|
162
|
-
}
|
|
163
|
-
limit(count) {
|
|
164
|
-
this.query += ` LIMIT ${count}`;
|
|
165
|
-
return this;
|
|
166
|
-
}
|
|
167
|
-
offset(count) {
|
|
168
|
-
this.query += ` OFFSET ${count}`;
|
|
169
|
-
return this;
|
|
170
|
-
}
|
|
171
|
-
build() {
|
|
172
|
-
return {
|
|
173
|
-
sql: this.query,
|
|
174
|
-
params: this.params
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
179
|
-
constructor(db, table, columns) {
|
|
180
|
-
super(db);
|
|
181
|
-
this.table = table;
|
|
182
|
-
this.columns = columns;
|
|
183
|
-
const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
|
|
184
|
-
this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
|
|
185
|
-
}
|
|
186
|
-
async execute() {
|
|
187
|
-
const { sql, params } = this.build();
|
|
188
|
-
return this.db.select(sql, ...params);
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
192
|
-
constructor(db, table) {
|
|
193
|
-
super(db);
|
|
194
|
-
this.table = table;
|
|
195
|
-
this.query = `INSERT INTO ${table._.name}`;
|
|
196
|
-
}
|
|
197
|
-
dataSets = [];
|
|
198
|
-
values(data) {
|
|
199
|
-
const dataArray = Array.isArray(data) ? data : [data];
|
|
200
|
-
this.dataSets.push(...dataArray);
|
|
201
|
-
return this;
|
|
202
|
-
}
|
|
203
|
-
async execute() {
|
|
204
|
-
if (this.dataSets.length === 0) {
|
|
205
|
-
throw new Error("No data provided for insert");
|
|
591
|
+
var sql = (strings, ...values) => {
|
|
592
|
+
const queryParts = [];
|
|
593
|
+
const params = [];
|
|
594
|
+
strings.forEach((str, i) => {
|
|
595
|
+
queryParts.push(str);
|
|
596
|
+
if (values[i] !== void 0) {
|
|
597
|
+
if (typeof values[i] === "object" && values[i].sql) {
|
|
598
|
+
queryParts.push(values[i].sql);
|
|
599
|
+
params.push(...values[i].params);
|
|
600
|
+
} else {
|
|
601
|
+
queryParts.push("?");
|
|
602
|
+
params.push(values[i]);
|
|
603
|
+
}
|
|
206
604
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
);
|
|
213
|
-
const placeholders = `(${columnNames.map(() => "?").join(", ")})`;
|
|
214
|
-
const valuesSql = this.dataSets.map(() => placeholders).join(", ");
|
|
215
|
-
this.query += ` (${columnNames.join(", ")}) VALUES ${valuesSql}`;
|
|
216
|
-
const params = this.dataSets.flatMap(
|
|
217
|
-
(data) => columns.map((col) => data[col])
|
|
218
|
-
);
|
|
219
|
-
const result = await this.db.execute(this.query, ...params);
|
|
220
|
-
return result.lastInsertId ?? 0;
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
224
|
-
constructor(db, table) {
|
|
225
|
-
super(db);
|
|
226
|
-
this.table = table;
|
|
227
|
-
this.query = `UPDATE ${table._.name}`;
|
|
228
|
-
}
|
|
229
|
-
updateData = {};
|
|
230
|
-
set(data) {
|
|
231
|
-
this.updateData = { ...this.updateData, ...data };
|
|
232
|
-
return this;
|
|
233
|
-
}
|
|
234
|
-
async execute() {
|
|
235
|
-
const entries = Object.entries(this.updateData);
|
|
236
|
-
const setClause = entries.map(([key]) => {
|
|
237
|
-
const column = this.table._.columns[key];
|
|
238
|
-
if (!column)
|
|
239
|
-
throw new Error(
|
|
240
|
-
`Column ${key} does not exist on table ${this.table._.name}`
|
|
241
|
-
);
|
|
242
|
-
return `${column._.name} = ?`;
|
|
243
|
-
}).join(", ");
|
|
244
|
-
this.query += ` SET ${setClause}`;
|
|
245
|
-
this.params.push(...entries.map(([, value]) => value));
|
|
246
|
-
const { sql, params } = this.build();
|
|
247
|
-
const result = await this.db.execute(sql, ...params);
|
|
248
|
-
return result.rowsAffected;
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
252
|
-
constructor(db, table) {
|
|
253
|
-
super(db);
|
|
254
|
-
this.table = table;
|
|
255
|
-
this.query = `DELETE FROM ${table._.name}`;
|
|
256
|
-
}
|
|
257
|
-
async execute() {
|
|
258
|
-
const { sql, params } = this.build();
|
|
259
|
-
const result = await this.db.execute(sql, ...params);
|
|
260
|
-
return result.rowsAffected;
|
|
261
|
-
}
|
|
605
|
+
});
|
|
606
|
+
return {
|
|
607
|
+
sql: queryParts.join(""),
|
|
608
|
+
params
|
|
609
|
+
};
|
|
262
610
|
};
|
|
263
611
|
var TauriORM = class {
|
|
264
612
|
constructor(db, schema = void 0) {
|
|
265
613
|
this.db = db;
|
|
266
614
|
if (schema) {
|
|
267
|
-
for (const
|
|
268
|
-
|
|
615
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
616
|
+
if (value instanceof Table) {
|
|
617
|
+
this.tables.set(value._.name, value);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
621
|
+
if (!(value instanceof Table) && typeof value === "object") {
|
|
622
|
+
const tableName = key.replace("Relations", "");
|
|
623
|
+
const table = Array.from(this.tables.values()).find(
|
|
624
|
+
(t) => t._.name === tableName
|
|
625
|
+
);
|
|
626
|
+
if (table) {
|
|
627
|
+
for (const [relName, rel] of Object.entries(value)) {
|
|
628
|
+
if (rel instanceof OneRelation) {
|
|
629
|
+
table.relations[relName] = {
|
|
630
|
+
type: "one",
|
|
631
|
+
foreignTable: rel.foreignTable,
|
|
632
|
+
fields: rel.config?.fields,
|
|
633
|
+
references: rel.config?.references
|
|
634
|
+
};
|
|
635
|
+
} else if (rel instanceof ManyRelation) {
|
|
636
|
+
table.relations[relName] = {
|
|
637
|
+
type: "many",
|
|
638
|
+
foreignTable: rel.foreignTable
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
269
644
|
}
|
|
270
645
|
}
|
|
271
646
|
}
|
|
272
647
|
tables = /* @__PURE__ */ new Map();
|
|
648
|
+
buildColumnDefinition(col, forAlterTable = false) {
|
|
649
|
+
let sql2 = `${col._.name} ${col.type}`;
|
|
650
|
+
if (col.options.primaryKey && !forAlterTable) {
|
|
651
|
+
sql2 += " PRIMARY KEY";
|
|
652
|
+
if (col._.autoincrement) {
|
|
653
|
+
sql2 += " AUTOINCREMENT";
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
if (col._.notNull) sql2 += " NOT NULL";
|
|
657
|
+
if (col.options.unique) sql2 += " UNIQUE";
|
|
658
|
+
if (col.options.default !== void 0) {
|
|
659
|
+
const value = col.options.default;
|
|
660
|
+
sql2 += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
|
|
661
|
+
}
|
|
662
|
+
if (col.options.references) {
|
|
663
|
+
sql2 += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
|
|
664
|
+
}
|
|
665
|
+
return sql2;
|
|
666
|
+
}
|
|
273
667
|
async migrate() {
|
|
274
668
|
for (const table of this.tables.values()) {
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
669
|
+
const existingTableInfo = await this.db.select(
|
|
670
|
+
`PRAGMA table_info('${table._.name}')`
|
|
671
|
+
);
|
|
672
|
+
if (existingTableInfo.length === 0) {
|
|
673
|
+
const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
|
|
674
|
+
const createSql = `CREATE TABLE ${table._.name} (${columnsSql})`;
|
|
675
|
+
await this.db.execute(createSql);
|
|
676
|
+
} else {
|
|
677
|
+
const existingColumnNames = new Set(
|
|
678
|
+
existingTableInfo.map((c) => c.name)
|
|
679
|
+
);
|
|
680
|
+
for (const column of Object.values(table._.columns)) {
|
|
681
|
+
if (!existingColumnNames.has(column._.name)) {
|
|
682
|
+
const columnSql = this.buildColumnDefinition(column, true);
|
|
683
|
+
const alterSql = `ALTER TABLE ${table._.name} ADD COLUMN ${columnSql}`;
|
|
684
|
+
await this.db.execute(alterSql);
|
|
685
|
+
}
|
|
287
686
|
}
|
|
288
|
-
|
|
289
|
-
}).join(", ");
|
|
290
|
-
const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
|
|
291
|
-
await this.db.execute(createSql);
|
|
687
|
+
}
|
|
292
688
|
}
|
|
293
689
|
}
|
|
294
690
|
select(table, columns) {
|
|
@@ -303,6 +699,15 @@ var TauriORM = class {
|
|
|
303
699
|
delete(table) {
|
|
304
700
|
return new DeleteQueryBuilder(this.db, table);
|
|
305
701
|
}
|
|
702
|
+
$with(alias2) {
|
|
703
|
+
const withBuilder = new WithQueryBuilder(this.db);
|
|
704
|
+
return {
|
|
705
|
+
as: (query) => {
|
|
706
|
+
withBuilder.with(alias2, query);
|
|
707
|
+
return withBuilder;
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
}
|
|
306
711
|
async transaction(callback) {
|
|
307
712
|
await this.db.execute("BEGIN TRANSACTION");
|
|
308
713
|
try {
|
|
@@ -314,6 +719,9 @@ var TauriORM = class {
|
|
|
314
719
|
throw error;
|
|
315
720
|
}
|
|
316
721
|
}
|
|
722
|
+
rollback() {
|
|
723
|
+
throw new Error("Transaction rolled back");
|
|
724
|
+
}
|
|
317
725
|
// --- Schema detection / signature ---
|
|
318
726
|
async ensureSchemaMeta() {
|
|
319
727
|
await this.db.execute(
|
|
@@ -342,7 +750,10 @@ var TauriORM = class {
|
|
|
342
750
|
pk: !!col.options.primaryKey,
|
|
343
751
|
ai: !!col._.autoincrement,
|
|
344
752
|
nn: !!col._.notNull,
|
|
345
|
-
|
|
753
|
+
unique: !!col.options.unique,
|
|
754
|
+
dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null,
|
|
755
|
+
hasDefaultFn: col.options.$defaultFn !== void 0,
|
|
756
|
+
hasOnUpdateFn: col.options.$onUpdateFn !== void 0
|
|
346
757
|
};
|
|
347
758
|
}
|
|
348
759
|
computeModelSignature() {
|
|
@@ -374,32 +785,70 @@ var TauriORM = class {
|
|
|
374
785
|
return false;
|
|
375
786
|
}
|
|
376
787
|
};
|
|
377
|
-
var
|
|
788
|
+
var Relation = class {
|
|
789
|
+
constructor(foreignTable) {
|
|
790
|
+
this.foreignTable = foreignTable;
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
var OneRelation = class extends Relation {
|
|
794
|
+
constructor(foreignTable, config) {
|
|
795
|
+
super(foreignTable);
|
|
796
|
+
this.config = config;
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
var ManyRelation = class extends Relation {
|
|
800
|
+
constructor(foreignTable) {
|
|
801
|
+
super(foreignTable);
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
var relations = (_table, relationsCallback) => {
|
|
378
805
|
return relationsCallback({
|
|
379
|
-
one: (
|
|
380
|
-
table
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
many: (table2) => ({
|
|
386
|
-
table: table2,
|
|
387
|
-
type: "many"
|
|
388
|
-
})
|
|
806
|
+
one: (table, config) => {
|
|
807
|
+
return new OneRelation(table, config);
|
|
808
|
+
},
|
|
809
|
+
many: (table) => {
|
|
810
|
+
return new ManyRelation(table);
|
|
811
|
+
}
|
|
389
812
|
});
|
|
390
813
|
};
|
|
814
|
+
var getTableColumns = (table) => {
|
|
815
|
+
return table._.columns;
|
|
816
|
+
};
|
|
817
|
+
var alias = (table, alias2) => {
|
|
818
|
+
return table;
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
// src/column-helpers.ts
|
|
822
|
+
var columnHelpers = (name) => new SQLiteColumn(name, "TEXT");
|
|
823
|
+
var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
|
|
824
|
+
var real = (name) => new SQLiteColumn(name, "REAL");
|
|
825
|
+
var blob = (name) => new SQLiteColumn(name, "BLOB");
|
|
826
|
+
var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
|
|
391
827
|
export {
|
|
828
|
+
BaseQueryBuilder,
|
|
392
829
|
DeleteQueryBuilder,
|
|
393
830
|
InsertQueryBuilder,
|
|
831
|
+
ManyRelation,
|
|
832
|
+
OneRelation,
|
|
833
|
+
Relation,
|
|
394
834
|
SQLiteColumn,
|
|
395
835
|
SelectQueryBuilder,
|
|
396
836
|
Table,
|
|
397
837
|
TauriORM,
|
|
398
838
|
UpdateQueryBuilder,
|
|
839
|
+
WithQueryBuilder,
|
|
840
|
+
alias,
|
|
399
841
|
and,
|
|
842
|
+
asc,
|
|
843
|
+
avg,
|
|
400
844
|
blob,
|
|
401
845
|
boolean,
|
|
846
|
+
columnHelpers,
|
|
847
|
+
count,
|
|
848
|
+
countDistinct,
|
|
849
|
+
desc,
|
|
402
850
|
eq,
|
|
851
|
+
getTableColumns,
|
|
403
852
|
gt,
|
|
404
853
|
gte,
|
|
405
854
|
inArray,
|
|
@@ -409,9 +858,13 @@ export {
|
|
|
409
858
|
like,
|
|
410
859
|
lt,
|
|
411
860
|
lte,
|
|
861
|
+
max,
|
|
862
|
+
min,
|
|
863
|
+
not,
|
|
412
864
|
or,
|
|
413
865
|
real,
|
|
414
866
|
relations,
|
|
867
|
+
sql,
|
|
415
868
|
sqliteTable,
|
|
416
|
-
|
|
869
|
+
sum
|
|
417
870
|
};
|