@type32/tauri-sqlite-orm 0.1.18-2 → 0.1.18-21
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 +232 -90
- package/dist/index.d.ts +232 -90
- package/dist/index.js +806 -206
- package/dist/index.mjs +785 -204
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,11 +7,11 @@ var __export = (target, all) => {
|
|
|
7
7
|
for (var name in all)
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
|
-
var __copyProps = (to, from, except,
|
|
10
|
+
var __copyProps = (to, from, except, desc2) => {
|
|
11
11
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
12
|
for (let key of __getOwnPropNames(from))
|
|
13
13
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
|
|
15
15
|
}
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
@@ -20,17 +20,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
BaseQueryBuilder: () => BaseQueryBuilder,
|
|
23
24
|
DeleteQueryBuilder: () => DeleteQueryBuilder,
|
|
24
25
|
InsertQueryBuilder: () => InsertQueryBuilder,
|
|
26
|
+
ManyRelation: () => ManyRelation,
|
|
27
|
+
OneRelation: () => OneRelation,
|
|
28
|
+
Relation: () => Relation,
|
|
25
29
|
SQLiteColumn: () => SQLiteColumn,
|
|
26
30
|
SelectQueryBuilder: () => SelectQueryBuilder,
|
|
27
31
|
Table: () => Table,
|
|
28
32
|
TauriORM: () => TauriORM,
|
|
29
33
|
UpdateQueryBuilder: () => UpdateQueryBuilder,
|
|
34
|
+
WithQueryBuilder: () => WithQueryBuilder,
|
|
35
|
+
alias: () => alias,
|
|
30
36
|
and: () => and,
|
|
37
|
+
asc: () => asc,
|
|
38
|
+
avg: () => avg,
|
|
31
39
|
blob: () => blob,
|
|
32
40
|
boolean: () => boolean,
|
|
41
|
+
count: () => count,
|
|
42
|
+
countDistinct: () => countDistinct,
|
|
43
|
+
desc: () => desc,
|
|
44
|
+
enumType: () => enumType,
|
|
33
45
|
eq: () => eq,
|
|
46
|
+
getTableColumns: () => getTableColumns,
|
|
34
47
|
gt: () => gt,
|
|
35
48
|
gte: () => gte,
|
|
36
49
|
inArray: () => inArray,
|
|
@@ -40,121 +53,65 @@ __export(index_exports, {
|
|
|
40
53
|
like: () => like,
|
|
41
54
|
lt: () => lt,
|
|
42
55
|
lte: () => lte,
|
|
56
|
+
max: () => max,
|
|
57
|
+
min: () => min,
|
|
58
|
+
not: () => not,
|
|
59
|
+
numeric: () => numeric,
|
|
43
60
|
or: () => or,
|
|
44
61
|
real: () => real,
|
|
45
62
|
relations: () => relations,
|
|
63
|
+
sql: () => sql,
|
|
46
64
|
sqliteTable: () => sqliteTable,
|
|
65
|
+
sum: () => sum,
|
|
47
66
|
text: () => text
|
|
48
67
|
});
|
|
49
68
|
module.exports = __toCommonJS(index_exports);
|
|
50
69
|
|
|
51
|
-
// src/
|
|
52
|
-
var
|
|
53
|
-
constructor(
|
|
54
|
-
this.
|
|
55
|
-
this.options = options;
|
|
56
|
-
this._ = {
|
|
57
|
-
name,
|
|
58
|
-
dataType: type,
|
|
59
|
-
mode: mode || "default",
|
|
60
|
-
notNull: options.notNull ?? false,
|
|
61
|
-
hasDefault: options.default !== void 0 || options.$defaultFn !== void 0,
|
|
62
|
-
autoincrement: options.autoincrement ?? false
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
_;
|
|
66
|
-
notNull() {
|
|
67
|
-
return new _SQLiteColumn(
|
|
68
|
-
this._.name,
|
|
69
|
-
this.type,
|
|
70
|
-
{ ...this.options, notNull: true },
|
|
71
|
-
this._.mode
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
default(value) {
|
|
75
|
-
return new _SQLiteColumn(
|
|
76
|
-
this._.name,
|
|
77
|
-
this.type,
|
|
78
|
-
{ ...this.options, default: value },
|
|
79
|
-
this._.mode
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
$defaultFn(fn) {
|
|
83
|
-
return new _SQLiteColumn(
|
|
84
|
-
this._.name,
|
|
85
|
-
this.type,
|
|
86
|
-
{ ...this.options, $defaultFn: fn },
|
|
87
|
-
this._.mode
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
primaryKey() {
|
|
91
|
-
return new _SQLiteColumn(
|
|
92
|
-
this._.name,
|
|
93
|
-
this.type,
|
|
94
|
-
{ ...this.options, primaryKey: true },
|
|
95
|
-
this._.mode
|
|
96
|
-
);
|
|
70
|
+
// src/builders/query-base.ts
|
|
71
|
+
var BaseQueryBuilder = class {
|
|
72
|
+
constructor(db) {
|
|
73
|
+
this.db = db;
|
|
97
74
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
);
|
|
75
|
+
query = "";
|
|
76
|
+
params = [];
|
|
77
|
+
where(condition) {
|
|
78
|
+
this.query += ` WHERE ${condition.sql}`;
|
|
79
|
+
this.params.push(...condition.params);
|
|
80
|
+
return this;
|
|
105
81
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.
|
|
109
|
-
this.
|
|
110
|
-
|
|
111
|
-
this._.
|
|
112
|
-
|
|
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;
|
|
113
90
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.type,
|
|
118
|
-
{
|
|
119
|
-
...this.options,
|
|
120
|
-
references: {
|
|
121
|
-
table: ref,
|
|
122
|
-
column: ref._.columns[column]
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
this._.mode
|
|
126
|
-
);
|
|
91
|
+
limit(count2) {
|
|
92
|
+
this.query += ` LIMIT ${count2}`;
|
|
93
|
+
return this;
|
|
127
94
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this.type,
|
|
132
|
-
{ ...this.options, $onUpdateFn: fn },
|
|
133
|
-
this._.mode
|
|
134
|
-
);
|
|
95
|
+
offset(count2) {
|
|
96
|
+
this.query += ` OFFSET ${count2}`;
|
|
97
|
+
return this;
|
|
135
98
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
var blob = (name) => new SQLiteColumn(name, "BLOB");
|
|
141
|
-
var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
|
|
142
|
-
var Table = class {
|
|
143
|
-
_;
|
|
144
|
-
constructor(name, columns) {
|
|
145
|
-
this._ = {
|
|
146
|
-
name,
|
|
147
|
-
columns
|
|
99
|
+
build() {
|
|
100
|
+
return {
|
|
101
|
+
sql: this.query,
|
|
102
|
+
params: this.params
|
|
148
103
|
};
|
|
149
104
|
}
|
|
150
105
|
};
|
|
151
|
-
|
|
152
|
-
|
|
106
|
+
|
|
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
|
+
};
|
|
153
114
|
};
|
|
154
|
-
var eq = (column, value) => ({
|
|
155
|
-
sql: `${column._.name} = ?`,
|
|
156
|
-
params: [value]
|
|
157
|
-
});
|
|
158
115
|
var and = (...conditions) => ({
|
|
159
116
|
sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
|
|
160
117
|
params: conditions.flatMap((c) => c.params)
|
|
@@ -163,6 +120,10 @@ var or = (...conditions) => ({
|
|
|
163
120
|
sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
|
|
164
121
|
params: conditions.flatMap((c) => c.params)
|
|
165
122
|
});
|
|
123
|
+
var not = (condition) => ({
|
|
124
|
+
sql: `NOT (${condition.sql})`,
|
|
125
|
+
params: condition.params
|
|
126
|
+
});
|
|
166
127
|
var gt = (column, value) => ({
|
|
167
128
|
sql: `${column._.name} > ?`,
|
|
168
129
|
params: [value]
|
|
@@ -195,81 +156,241 @@ var inArray = (column, values) => ({
|
|
|
195
156
|
sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
|
|
196
157
|
params: values
|
|
197
158
|
});
|
|
198
|
-
var
|
|
199
|
-
|
|
200
|
-
|
|
159
|
+
var count = (column) => ({
|
|
160
|
+
sql: `COUNT(${column ? column._.name : "*"})`,
|
|
161
|
+
params: []
|
|
162
|
+
});
|
|
163
|
+
var countDistinct = (column) => ({
|
|
164
|
+
sql: `COUNT(DISTINCT ${column._.name})`,
|
|
165
|
+
params: []
|
|
166
|
+
});
|
|
167
|
+
var sum = (column) => ({
|
|
168
|
+
sql: `SUM(${column._.name})`,
|
|
169
|
+
params: []
|
|
170
|
+
});
|
|
171
|
+
var avg = (column) => ({
|
|
172
|
+
sql: `AVG(${column._.name})`,
|
|
173
|
+
params: []
|
|
174
|
+
});
|
|
175
|
+
var max = (column) => ({
|
|
176
|
+
sql: `MAX(${column._.name})`,
|
|
177
|
+
params: []
|
|
178
|
+
});
|
|
179
|
+
var min = (column) => ({
|
|
180
|
+
sql: `MIN(${column._.name})`,
|
|
181
|
+
params: []
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// src/builders/select.ts
|
|
185
|
+
var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
186
|
+
constructor(db, table, columns) {
|
|
187
|
+
super(db);
|
|
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}`;
|
|
201
196
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
197
|
+
isDistinct = false;
|
|
198
|
+
groupByColumns = [];
|
|
199
|
+
havingCondition = null;
|
|
200
|
+
joins = [];
|
|
201
|
+
includeRelations = {};
|
|
202
|
+
selectedTableAlias;
|
|
203
|
+
selectedColumns = [];
|
|
204
|
+
distinct() {
|
|
205
|
+
this.isDistinct = true;
|
|
207
206
|
return this;
|
|
208
207
|
}
|
|
209
|
-
|
|
210
|
-
this.
|
|
208
|
+
groupBy(...columns) {
|
|
209
|
+
this.groupByColumns.push(...columns);
|
|
210
|
+
const columnNames = columns.map((col) => `${this.selectedTableAlias}.${col._.name}`).join(", ");
|
|
211
|
+
this.query += ` GROUP BY ${columnNames}`;
|
|
211
212
|
return this;
|
|
212
213
|
}
|
|
213
|
-
|
|
214
|
-
this.
|
|
214
|
+
having(condition) {
|
|
215
|
+
this.havingCondition = condition;
|
|
216
|
+
this.query += ` HAVING ${condition.sql}`;
|
|
217
|
+
this.params.push(...condition.params);
|
|
215
218
|
return this;
|
|
216
219
|
}
|
|
217
|
-
|
|
218
|
-
this.
|
|
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);
|
|
219
226
|
return this;
|
|
220
227
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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);
|
|
234
|
+
return this;
|
|
226
235
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const
|
|
234
|
-
|
|
236
|
+
include(relations2) {
|
|
237
|
+
this.includeRelations = { ...this.includeRelations, ...relations2 };
|
|
238
|
+
return this;
|
|
239
|
+
}
|
|
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);
|
|
246
|
+
}
|
|
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
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return { sql: sql2, params };
|
|
235
295
|
}
|
|
296
|
+
// Enhanced execute method that handles relation data mapping
|
|
236
297
|
async execute() {
|
|
237
|
-
const { sql, params } = this.
|
|
238
|
-
|
|
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);
|
|
309
|
+
}
|
|
310
|
+
const hasJoins = this.joins.length > 0;
|
|
311
|
+
if (hasJoins) {
|
|
312
|
+
return rawResults;
|
|
313
|
+
}
|
|
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
|
+
});
|
|
239
326
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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;
|
|
332
|
+
}
|
|
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
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return Array.from(groupedResults.values());
|
|
246
381
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
this.dataSets.push(...dataArray);
|
|
251
|
-
return this;
|
|
382
|
+
// Update the return type signatures
|
|
383
|
+
async all() {
|
|
384
|
+
return this.execute();
|
|
252
385
|
}
|
|
253
|
-
async
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const columns = Object.keys(
|
|
258
|
-
this.dataSets[0]
|
|
259
|
-
);
|
|
260
|
-
const columnNames = columns.map(
|
|
261
|
-
(c) => this.table._.columns[c]._.name
|
|
262
|
-
);
|
|
263
|
-
const placeholders = `(${columnNames.map(() => "?").join(", ")})`;
|
|
264
|
-
const valuesSql = this.dataSets.map(() => placeholders).join(", ");
|
|
265
|
-
this.query += ` (${columnNames.join(", ")}) VALUES ${valuesSql}`;
|
|
266
|
-
const params = this.dataSets.flatMap(
|
|
267
|
-
(data) => columns.map((col) => data[col])
|
|
268
|
-
);
|
|
269
|
-
const result = await this.db.execute(this.query, params);
|
|
270
|
-
return result.lastInsertId ?? 0;
|
|
386
|
+
async get() {
|
|
387
|
+
this.limit(1);
|
|
388
|
+
const result = await this.execute();
|
|
389
|
+
return result[0];
|
|
271
390
|
}
|
|
272
391
|
};
|
|
392
|
+
|
|
393
|
+
// src/builders/update.ts
|
|
273
394
|
var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
274
395
|
constructor(db, table) {
|
|
275
396
|
super(db);
|
|
@@ -277,11 +398,23 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
|
277
398
|
this.query = `UPDATE ${table._.name}`;
|
|
278
399
|
}
|
|
279
400
|
updateData = {};
|
|
401
|
+
returningColumns = [];
|
|
280
402
|
set(data) {
|
|
281
403
|
this.updateData = { ...this.updateData, ...data };
|
|
282
404
|
return this;
|
|
283
405
|
}
|
|
284
|
-
|
|
406
|
+
returning(...columns) {
|
|
407
|
+
this.returningColumns.push(...columns);
|
|
408
|
+
return this;
|
|
409
|
+
}
|
|
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
|
+
}
|
|
285
418
|
const baseQuery = this.query;
|
|
286
419
|
const whereParams = this.params;
|
|
287
420
|
let tablePart = baseQuery;
|
|
@@ -291,7 +424,7 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
|
291
424
|
tablePart = baseQuery.substring(0, whereIndex);
|
|
292
425
|
whereClause = baseQuery.substring(whereIndex);
|
|
293
426
|
}
|
|
294
|
-
const entries = Object.entries(
|
|
427
|
+
const entries = Object.entries(finalUpdateData);
|
|
295
428
|
if (entries.length === 0) {
|
|
296
429
|
throw new Error("Cannot execute an update query without a .set() call.");
|
|
297
430
|
}
|
|
@@ -305,61 +438,416 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
|
305
438
|
return `${column._.name} = ?`;
|
|
306
439
|
}).join(", ");
|
|
307
440
|
const setParams = entries.map(([, value]) => value);
|
|
308
|
-
const
|
|
441
|
+
const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
|
|
309
442
|
const params = [...setParams, ...whereParams];
|
|
310
|
-
return { sql, params };
|
|
443
|
+
return { sql: sql2, params };
|
|
311
444
|
}
|
|
312
445
|
async execute() {
|
|
313
|
-
const { sql, params } = this.
|
|
314
|
-
|
|
315
|
-
|
|
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
|
|
459
|
+
);
|
|
460
|
+
return this.returning(...allColumns).execute();
|
|
316
461
|
}
|
|
317
462
|
};
|
|
463
|
+
|
|
464
|
+
// src/builders/insert.ts
|
|
465
|
+
var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
466
|
+
constructor(db, table) {
|
|
467
|
+
super(db);
|
|
468
|
+
this.table = table;
|
|
469
|
+
this.query = `INSERT INTO ${table._.name}`;
|
|
470
|
+
}
|
|
471
|
+
dataSets = [];
|
|
472
|
+
returningColumns = [];
|
|
473
|
+
onConflictAction = null;
|
|
474
|
+
conflictTarget = [];
|
|
475
|
+
updateSet = {};
|
|
476
|
+
values(data) {
|
|
477
|
+
const dataArray = Array.isArray(data) ? data : [data];
|
|
478
|
+
this.dataSets.push(...dataArray);
|
|
479
|
+
return this;
|
|
480
|
+
}
|
|
481
|
+
returning(...columns) {
|
|
482
|
+
this.returningColumns.push(...columns);
|
|
483
|
+
return this;
|
|
484
|
+
}
|
|
485
|
+
onConflictDoNothing(target) {
|
|
486
|
+
this.onConflictAction = "nothing";
|
|
487
|
+
if (target) {
|
|
488
|
+
this.conflictTarget = Array.isArray(target) ? target : [target];
|
|
489
|
+
}
|
|
490
|
+
return this;
|
|
491
|
+
}
|
|
492
|
+
onConflictDoUpdate(config) {
|
|
493
|
+
this.onConflictAction = "update";
|
|
494
|
+
this.conflictTarget = Array.isArray(config.target) ? config.target : [config.target];
|
|
495
|
+
this.updateSet = config.set;
|
|
496
|
+
return this;
|
|
497
|
+
}
|
|
498
|
+
processDefaultValues(data) {
|
|
499
|
+
const finalData = { ...data };
|
|
500
|
+
for (const [key, column] of Object.entries(this.table._.columns)) {
|
|
501
|
+
const typedKey = key;
|
|
502
|
+
if (finalData[typedKey] === void 0) {
|
|
503
|
+
if (column.options.$defaultFn) {
|
|
504
|
+
finalData[typedKey] = column.options.$defaultFn();
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return finalData;
|
|
509
|
+
}
|
|
510
|
+
buildConflictClause() {
|
|
511
|
+
if (!this.onConflictAction) return "";
|
|
512
|
+
let clause = " ON CONFLICT";
|
|
513
|
+
if (this.conflictTarget.length > 0) {
|
|
514
|
+
const targetNames = this.conflictTarget.map((col) => col._.name).join(", ");
|
|
515
|
+
clause += ` (${targetNames})`;
|
|
516
|
+
}
|
|
517
|
+
if (this.onConflictAction === "nothing") {
|
|
518
|
+
clause += " DO NOTHING";
|
|
519
|
+
} else if (this.onConflictAction === "update") {
|
|
520
|
+
const setEntries = Object.entries(this.updateSet);
|
|
521
|
+
if (setEntries.length > 0) {
|
|
522
|
+
const setClause = setEntries.map(([key]) => `${key} = ?`).join(", ");
|
|
523
|
+
clause += ` DO UPDATE SET ${setClause}`;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return clause;
|
|
527
|
+
}
|
|
528
|
+
async execute() {
|
|
529
|
+
if (this.dataSets.length === 0) {
|
|
530
|
+
throw new Error("No data provided for insert");
|
|
531
|
+
}
|
|
532
|
+
const processedDataSets = this.dataSets.map(
|
|
533
|
+
(data) => this.processDefaultValues(data)
|
|
534
|
+
);
|
|
535
|
+
const groups = /* @__PURE__ */ new Map();
|
|
536
|
+
for (const dataSet of processedDataSets) {
|
|
537
|
+
const keys = Object.keys(dataSet).sort().join(",");
|
|
538
|
+
if (!groups.has(keys)) {
|
|
539
|
+
groups.set(keys, []);
|
|
540
|
+
}
|
|
541
|
+
groups.get(keys).push(dataSet);
|
|
542
|
+
}
|
|
543
|
+
let results = [];
|
|
544
|
+
let lastInsertId;
|
|
545
|
+
let rowsAffected = 0;
|
|
546
|
+
for (const [_, dataSets] of groups) {
|
|
547
|
+
const columns = Object.keys(dataSets[0]);
|
|
548
|
+
const columnNames = columns.map(
|
|
549
|
+
(key) => this.table._.columns[key]._.name
|
|
550
|
+
);
|
|
551
|
+
const placeholders = `(${columns.map(() => "?").join(", ")})`;
|
|
552
|
+
const valuesSql = dataSets.map(() => placeholders).join(", ");
|
|
553
|
+
const conflictClause = this.buildConflictClause();
|
|
554
|
+
const finalQuery = `${this.query} (${columnNames.join(
|
|
555
|
+
", "
|
|
556
|
+
)}) VALUES ${valuesSql}${conflictClause}`;
|
|
557
|
+
const params = dataSets.flatMap(
|
|
558
|
+
(data) => columns.map((col) => data[col] ?? null)
|
|
559
|
+
);
|
|
560
|
+
if (this.onConflictAction === "update") {
|
|
561
|
+
const setValues = Object.entries(this.updateSet).map(
|
|
562
|
+
([, value]) => value
|
|
563
|
+
);
|
|
564
|
+
params.push(...setValues);
|
|
565
|
+
}
|
|
566
|
+
if (this.returningColumns.length > 0) {
|
|
567
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
568
|
+
const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
|
|
569
|
+
const rows = await this.db.select(queryWithReturning, params);
|
|
570
|
+
results = results.concat(rows);
|
|
571
|
+
} else {
|
|
572
|
+
const result = await this.db.execute(finalQuery, params);
|
|
573
|
+
lastInsertId = result.lastInsertId;
|
|
574
|
+
rowsAffected += result.rowsAffected;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (this.returningColumns.length > 0) {
|
|
578
|
+
return results;
|
|
579
|
+
}
|
|
580
|
+
return [{ lastInsertId, rowsAffected }];
|
|
581
|
+
}
|
|
582
|
+
async returningAll() {
|
|
583
|
+
const allColumns = Object.keys(
|
|
584
|
+
this.table._.columns
|
|
585
|
+
);
|
|
586
|
+
return this.returning(...allColumns).execute();
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
// src/builders/delete.ts
|
|
318
591
|
var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
319
592
|
constructor(db, table) {
|
|
320
593
|
super(db);
|
|
321
594
|
this.table = table;
|
|
322
595
|
this.query = `DELETE FROM ${table._.name}`;
|
|
323
596
|
}
|
|
597
|
+
returningColumns = [];
|
|
598
|
+
returning(...columns) {
|
|
599
|
+
this.returningColumns.push(...columns);
|
|
600
|
+
return this;
|
|
601
|
+
}
|
|
324
602
|
async execute() {
|
|
325
|
-
const { sql, params } = this.build();
|
|
326
|
-
|
|
327
|
-
|
|
603
|
+
const { sql: sql2, params } = this.build();
|
|
604
|
+
if (this.returningColumns.length > 0) {
|
|
605
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
606
|
+
const sqlWithReturning = `${sql2} RETURNING ${returningNames}`;
|
|
607
|
+
return this.db.select(sqlWithReturning, params);
|
|
608
|
+
} else {
|
|
609
|
+
const result = await this.db.execute(sql2, params);
|
|
610
|
+
return [{ rowsAffected: result.rowsAffected }];
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
async returningAll() {
|
|
614
|
+
const allColumns = Object.keys(this.table._.columns);
|
|
615
|
+
return this.returning(...allColumns).execute();
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
// src/builders/with.ts
|
|
620
|
+
var WithQueryBuilder = class {
|
|
621
|
+
constructor(db) {
|
|
622
|
+
this.db = db;
|
|
623
|
+
}
|
|
624
|
+
ctes = [];
|
|
625
|
+
with(alias2, query) {
|
|
626
|
+
this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
|
|
627
|
+
return this;
|
|
628
|
+
}
|
|
629
|
+
select(table, columns) {
|
|
630
|
+
const builder = new SelectQueryBuilder(this.db, table, columns);
|
|
631
|
+
this.applyWithClause(builder);
|
|
632
|
+
return builder;
|
|
633
|
+
}
|
|
634
|
+
insert(table) {
|
|
635
|
+
const builder = new InsertQueryBuilder(this.db, table);
|
|
636
|
+
this.applyWithClause(builder);
|
|
637
|
+
return builder;
|
|
638
|
+
}
|
|
639
|
+
update(table) {
|
|
640
|
+
const builder = new UpdateQueryBuilder(this.db, table);
|
|
641
|
+
this.applyWithClause(builder);
|
|
642
|
+
return builder;
|
|
643
|
+
}
|
|
644
|
+
delete(table) {
|
|
645
|
+
const builder = new DeleteQueryBuilder(this.db, table);
|
|
646
|
+
this.applyWithClause(builder);
|
|
647
|
+
return builder;
|
|
648
|
+
}
|
|
649
|
+
applyWithClause(builder) {
|
|
650
|
+
if (this.ctes.length > 0) {
|
|
651
|
+
const cteSql = this.ctes.map((cte) => `${cte.alias} AS (${cte.query})`).join(", ");
|
|
652
|
+
builder["query"] = `WITH ${cteSql} ${builder["query"]}`;
|
|
653
|
+
builder["params"] = [
|
|
654
|
+
...this.ctes.flatMap((cte) => cte.params),
|
|
655
|
+
...builder["params"]
|
|
656
|
+
];
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
|
|
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
|
+
};
|
|
328
733
|
}
|
|
329
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
|
+
};
|
|
330
766
|
var TauriORM = class {
|
|
331
767
|
constructor(db, schema = void 0) {
|
|
332
768
|
this.db = db;
|
|
333
769
|
if (schema) {
|
|
334
|
-
for (const
|
|
335
|
-
|
|
770
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
771
|
+
if (value instanceof Table) {
|
|
772
|
+
this.tables.set(value._.name, value);
|
|
773
|
+
}
|
|
336
774
|
}
|
|
337
775
|
}
|
|
338
776
|
}
|
|
339
777
|
tables = /* @__PURE__ */ new Map();
|
|
340
|
-
|
|
778
|
+
buildColumnDefinition(col, forAlterTable = false) {
|
|
779
|
+
let sql2 = `${col._.name} ${col.type}`;
|
|
780
|
+
if (col.options.primaryKey && !forAlterTable) {
|
|
781
|
+
sql2 += " PRIMARY KEY";
|
|
782
|
+
if (col._.autoincrement) {
|
|
783
|
+
sql2 += " AUTOINCREMENT";
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (col._.notNull) sql2 += " NOT NULL";
|
|
787
|
+
if (col.options.unique) sql2 += " UNIQUE";
|
|
788
|
+
if (col.options.default !== void 0) {
|
|
789
|
+
const value = col.options.default;
|
|
790
|
+
sql2 += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
|
|
791
|
+
}
|
|
792
|
+
if (col.options.references) {
|
|
793
|
+
sql2 += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
|
|
794
|
+
}
|
|
795
|
+
return sql2;
|
|
796
|
+
}
|
|
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()));
|
|
341
803
|
for (const table of this.tables.values()) {
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
804
|
+
const tableName = table._.name;
|
|
805
|
+
const tableExists = dbTableNames.has(tableName);
|
|
806
|
+
if (!tableExists) {
|
|
807
|
+
const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
|
|
808
|
+
const createSql = `CREATE TABLE ${tableName}
|
|
809
|
+
(
|
|
810
|
+
${columnsSql}
|
|
811
|
+
)`;
|
|
812
|
+
await this.db.execute(createSql);
|
|
813
|
+
} else {
|
|
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));
|
|
817
|
+
for (const column of Object.values(table._.columns)) {
|
|
818
|
+
if (!existingColumnNames.has(column._.name)) {
|
|
819
|
+
const columnSql = this.buildColumnDefinition(column, true);
|
|
820
|
+
const alterSql = `ALTER TABLE ${tableName}
|
|
821
|
+
ADD COLUMN ${columnSql}`;
|
|
822
|
+
await this.db.execute(alterSql);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
if (options?.performDestructiveActions) {
|
|
826
|
+
for (const colName of existingColumnNames) {
|
|
827
|
+
if (!schemaColumnNames.has(colName)) {
|
|
828
|
+
await this.dropColumn(tableName, colName);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
351
831
|
}
|
|
352
|
-
|
|
353
|
-
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
if (options?.performDestructiveActions) {
|
|
835
|
+
for (const tableName of dbTableNames) {
|
|
836
|
+
if (!schemaTableNames.has(tableName)) {
|
|
837
|
+
await this.dropTable(tableName);
|
|
354
838
|
}
|
|
355
|
-
|
|
356
|
-
}).join(", ");
|
|
357
|
-
const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
|
|
358
|
-
await this.db.execute(createSql);
|
|
839
|
+
}
|
|
359
840
|
}
|
|
360
841
|
}
|
|
361
842
|
select(table, columns) {
|
|
362
|
-
|
|
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);
|
|
363
851
|
}
|
|
364
852
|
insert(table) {
|
|
365
853
|
return new InsertQueryBuilder(this.db, table);
|
|
@@ -370,6 +858,15 @@ var TauriORM = class {
|
|
|
370
858
|
delete(table) {
|
|
371
859
|
return new DeleteQueryBuilder(this.db, table);
|
|
372
860
|
}
|
|
861
|
+
$with(alias2) {
|
|
862
|
+
const withBuilder = new WithQueryBuilder(this.db);
|
|
863
|
+
return {
|
|
864
|
+
as: (query) => {
|
|
865
|
+
withBuilder.with(alias2, query);
|
|
866
|
+
return withBuilder;
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
}
|
|
373
870
|
async transaction(callback) {
|
|
374
871
|
await this.db.execute("BEGIN TRANSACTION");
|
|
375
872
|
try {
|
|
@@ -381,16 +878,31 @@ var TauriORM = class {
|
|
|
381
878
|
throw error;
|
|
382
879
|
}
|
|
383
880
|
}
|
|
881
|
+
rollback() {
|
|
882
|
+
throw new Error("Transaction rolled back");
|
|
883
|
+
}
|
|
384
884
|
// --- Schema detection / signature ---
|
|
385
885
|
async ensureSchemaMeta() {
|
|
386
886
|
await this.db.execute(
|
|
387
|
-
`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
|
+
)`
|
|
388
898
|
);
|
|
389
899
|
}
|
|
390
900
|
async getSchemaMeta(key) {
|
|
391
901
|
await this.ensureSchemaMeta();
|
|
392
902
|
const rows = await this.db.select(
|
|
393
|
-
`SELECT value
|
|
903
|
+
`SELECT value
|
|
904
|
+
FROM _schema_meta
|
|
905
|
+
WHERE key = ?`,
|
|
394
906
|
[key]
|
|
395
907
|
);
|
|
396
908
|
return rows?.[0]?.value ?? null;
|
|
@@ -398,7 +910,10 @@ var TauriORM = class {
|
|
|
398
910
|
async setSchemaMeta(key, value) {
|
|
399
911
|
await this.ensureSchemaMeta();
|
|
400
912
|
await this.db.execute(
|
|
401
|
-
`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`,
|
|
402
917
|
[key, value]
|
|
403
918
|
);
|
|
404
919
|
}
|
|
@@ -409,7 +924,10 @@ var TauriORM = class {
|
|
|
409
924
|
pk: !!col.options.primaryKey,
|
|
410
925
|
ai: !!col._.autoincrement,
|
|
411
926
|
nn: !!col._.notNull,
|
|
412
|
-
|
|
927
|
+
unique: !!col.options.unique,
|
|
928
|
+
dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null,
|
|
929
|
+
hasDefaultFn: col.options.$defaultFn !== void 0,
|
|
930
|
+
hasOnUpdateFn: col.options.$onUpdateFn !== void 0
|
|
413
931
|
};
|
|
414
932
|
}
|
|
415
933
|
computeModelSignature() {
|
|
@@ -432,42 +950,118 @@ var TauriORM = class {
|
|
|
432
950
|
const status = await this.isSchemaDirty();
|
|
433
951
|
if (status.dirty) {
|
|
434
952
|
await this.migrate();
|
|
435
|
-
await this.setSchemaMeta(
|
|
436
|
-
"schema_signature",
|
|
437
|
-
this.computeModelSignature()
|
|
438
|
-
);
|
|
953
|
+
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
439
954
|
return true;
|
|
440
955
|
}
|
|
441
956
|
return false;
|
|
442
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
|
+
}
|
|
981
|
+
};
|
|
982
|
+
var Relation = class {
|
|
983
|
+
constructor(foreignTable) {
|
|
984
|
+
this.foreignTable = foreignTable;
|
|
985
|
+
}
|
|
986
|
+
};
|
|
987
|
+
var OneRelation = class extends Relation {
|
|
988
|
+
constructor(foreignTable, config) {
|
|
989
|
+
super(foreignTable);
|
|
990
|
+
this.config = config;
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
var ManyRelation = class extends Relation {
|
|
994
|
+
constructor(foreignTable) {
|
|
995
|
+
super(foreignTable);
|
|
996
|
+
}
|
|
443
997
|
};
|
|
444
998
|
var relations = (table, relationsCallback) => {
|
|
445
|
-
|
|
446
|
-
one: (
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
many: (table2) => ({
|
|
453
|
-
table: table2,
|
|
454
|
-
type: "many"
|
|
455
|
-
})
|
|
999
|
+
const builtRelations = relationsCallback({
|
|
1000
|
+
one: (foreignTable, config) => {
|
|
1001
|
+
return new OneRelation(foreignTable, config);
|
|
1002
|
+
},
|
|
1003
|
+
many: (foreignTable) => {
|
|
1004
|
+
return new ManyRelation(foreignTable);
|
|
1005
|
+
}
|
|
456
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;
|
|
457
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 });
|
|
458
1039
|
// Annotate the CommonJS export names for ESM import in node:
|
|
459
1040
|
0 && (module.exports = {
|
|
1041
|
+
BaseQueryBuilder,
|
|
460
1042
|
DeleteQueryBuilder,
|
|
461
1043
|
InsertQueryBuilder,
|
|
1044
|
+
ManyRelation,
|
|
1045
|
+
OneRelation,
|
|
1046
|
+
Relation,
|
|
462
1047
|
SQLiteColumn,
|
|
463
1048
|
SelectQueryBuilder,
|
|
464
1049
|
Table,
|
|
465
1050
|
TauriORM,
|
|
466
1051
|
UpdateQueryBuilder,
|
|
1052
|
+
WithQueryBuilder,
|
|
1053
|
+
alias,
|
|
467
1054
|
and,
|
|
1055
|
+
asc,
|
|
1056
|
+
avg,
|
|
468
1057
|
blob,
|
|
469
1058
|
boolean,
|
|
1059
|
+
count,
|
|
1060
|
+
countDistinct,
|
|
1061
|
+
desc,
|
|
1062
|
+
enumType,
|
|
470
1063
|
eq,
|
|
1064
|
+
getTableColumns,
|
|
471
1065
|
gt,
|
|
472
1066
|
gte,
|
|
473
1067
|
inArray,
|
|
@@ -477,9 +1071,15 @@ var relations = (table, relationsCallback) => {
|
|
|
477
1071
|
like,
|
|
478
1072
|
lt,
|
|
479
1073
|
lte,
|
|
1074
|
+
max,
|
|
1075
|
+
min,
|
|
1076
|
+
not,
|
|
1077
|
+
numeric,
|
|
480
1078
|
or,
|
|
481
1079
|
real,
|
|
482
1080
|
relations,
|
|
1081
|
+
sql,
|
|
483
1082
|
sqliteTable,
|
|
1083
|
+
sum,
|
|
484
1084
|
text
|
|
485
1085
|
});
|