@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.mjs
CHANGED
|
@@ -1,110 +1,48 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
var
|
|
3
|
-
constructor(
|
|
4
|
-
this.
|
|
5
|
-
this.options = options;
|
|
6
|
-
this._ = {
|
|
7
|
-
name,
|
|
8
|
-
dataType: type,
|
|
9
|
-
mode: mode || "default",
|
|
10
|
-
notNull: options.notNull ?? false,
|
|
11
|
-
hasDefault: options.default !== void 0 || options.$defaultFn !== void 0,
|
|
12
|
-
autoincrement: options.autoincrement ?? false
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
_;
|
|
16
|
-
notNull() {
|
|
17
|
-
return new _SQLiteColumn(
|
|
18
|
-
this._.name,
|
|
19
|
-
this.type,
|
|
20
|
-
{ ...this.options, notNull: true },
|
|
21
|
-
this._.mode
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
default(value) {
|
|
25
|
-
return new _SQLiteColumn(
|
|
26
|
-
this._.name,
|
|
27
|
-
this.type,
|
|
28
|
-
{ ...this.options, default: value },
|
|
29
|
-
this._.mode
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
$defaultFn(fn) {
|
|
33
|
-
return new _SQLiteColumn(
|
|
34
|
-
this._.name,
|
|
35
|
-
this.type,
|
|
36
|
-
{ ...this.options, $defaultFn: fn },
|
|
37
|
-
this._.mode
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
primaryKey() {
|
|
41
|
-
return new _SQLiteColumn(
|
|
42
|
-
this._.name,
|
|
43
|
-
this.type,
|
|
44
|
-
{ ...this.options, primaryKey: true },
|
|
45
|
-
this._.mode
|
|
46
|
-
);
|
|
1
|
+
// src/builders/query-base.ts
|
|
2
|
+
var BaseQueryBuilder = class {
|
|
3
|
+
constructor(db) {
|
|
4
|
+
this.db = db;
|
|
47
5
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
6
|
+
query = "";
|
|
7
|
+
params = [];
|
|
8
|
+
where(condition) {
|
|
9
|
+
this.query += ` WHERE ${condition.sql}`;
|
|
10
|
+
this.params.push(...condition.params);
|
|
11
|
+
return this;
|
|
55
12
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
this.
|
|
59
|
-
this.
|
|
60
|
-
|
|
61
|
-
this._.
|
|
62
|
-
|
|
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;
|
|
63
21
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.type,
|
|
68
|
-
{
|
|
69
|
-
...this.options,
|
|
70
|
-
references: {
|
|
71
|
-
table: ref,
|
|
72
|
-
column: ref._.columns[column]
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
this._.mode
|
|
76
|
-
);
|
|
22
|
+
limit(count2) {
|
|
23
|
+
this.query += ` LIMIT ${count2}`;
|
|
24
|
+
return this;
|
|
77
25
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.type,
|
|
82
|
-
{ ...this.options, $onUpdateFn: fn },
|
|
83
|
-
this._.mode
|
|
84
|
-
);
|
|
26
|
+
offset(count2) {
|
|
27
|
+
this.query += ` OFFSET ${count2}`;
|
|
28
|
+
return this;
|
|
85
29
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
var blob = (name) => new SQLiteColumn(name, "BLOB");
|
|
91
|
-
var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
|
|
92
|
-
var Table = class {
|
|
93
|
-
_;
|
|
94
|
-
constructor(name, columns) {
|
|
95
|
-
this._ = {
|
|
96
|
-
name,
|
|
97
|
-
columns
|
|
30
|
+
build() {
|
|
31
|
+
return {
|
|
32
|
+
sql: this.query,
|
|
33
|
+
params: this.params
|
|
98
34
|
};
|
|
99
35
|
}
|
|
100
36
|
};
|
|
101
|
-
|
|
102
|
-
|
|
37
|
+
|
|
38
|
+
// src/operators.ts
|
|
39
|
+
var eq = (column, value, tableAlias) => {
|
|
40
|
+
const columnName = tableAlias ? `${tableAlias}.${column._.name}` : column._.name;
|
|
41
|
+
return {
|
|
42
|
+
sql: `${columnName} = ?`,
|
|
43
|
+
params: [value]
|
|
44
|
+
};
|
|
103
45
|
};
|
|
104
|
-
var eq = (column, value) => ({
|
|
105
|
-
sql: `${column._.name} = ?`,
|
|
106
|
-
params: [value]
|
|
107
|
-
});
|
|
108
46
|
var and = (...conditions) => ({
|
|
109
47
|
sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
|
|
110
48
|
params: conditions.flatMap((c) => c.params)
|
|
@@ -113,6 +51,10 @@ var or = (...conditions) => ({
|
|
|
113
51
|
sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
|
|
114
52
|
params: conditions.flatMap((c) => c.params)
|
|
115
53
|
});
|
|
54
|
+
var not = (condition) => ({
|
|
55
|
+
sql: `NOT (${condition.sql})`,
|
|
56
|
+
params: condition.params
|
|
57
|
+
});
|
|
116
58
|
var gt = (column, value) => ({
|
|
117
59
|
sql: `${column._.name} > ?`,
|
|
118
60
|
params: [value]
|
|
@@ -145,81 +87,241 @@ var inArray = (column, values) => ({
|
|
|
145
87
|
sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
|
|
146
88
|
params: values
|
|
147
89
|
});
|
|
148
|
-
var
|
|
149
|
-
|
|
150
|
-
|
|
90
|
+
var count = (column) => ({
|
|
91
|
+
sql: `COUNT(${column ? column._.name : "*"})`,
|
|
92
|
+
params: []
|
|
93
|
+
});
|
|
94
|
+
var countDistinct = (column) => ({
|
|
95
|
+
sql: `COUNT(DISTINCT ${column._.name})`,
|
|
96
|
+
params: []
|
|
97
|
+
});
|
|
98
|
+
var sum = (column) => ({
|
|
99
|
+
sql: `SUM(${column._.name})`,
|
|
100
|
+
params: []
|
|
101
|
+
});
|
|
102
|
+
var avg = (column) => ({
|
|
103
|
+
sql: `AVG(${column._.name})`,
|
|
104
|
+
params: []
|
|
105
|
+
});
|
|
106
|
+
var max = (column) => ({
|
|
107
|
+
sql: `MAX(${column._.name})`,
|
|
108
|
+
params: []
|
|
109
|
+
});
|
|
110
|
+
var min = (column) => ({
|
|
111
|
+
sql: `MIN(${column._.name})`,
|
|
112
|
+
params: []
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// src/builders/select.ts
|
|
116
|
+
var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
117
|
+
constructor(db, table, columns) {
|
|
118
|
+
super(db);
|
|
119
|
+
this.table = table;
|
|
120
|
+
this.columns = columns;
|
|
121
|
+
this.selectedTableAlias = table._.name;
|
|
122
|
+
const selected = columns ? columns.map((c) => this.table._.columns[c]) : Object.values(this.table._.columns);
|
|
123
|
+
this.selectedColumns = selected.map(
|
|
124
|
+
(col) => `${this.selectedTableAlias}.${col._.name} AS "${this.selectedTableAlias}.${col._.name}"`
|
|
125
|
+
);
|
|
126
|
+
this.query = `FROM ${table._.name} ${this.selectedTableAlias}`;
|
|
127
|
+
}
|
|
128
|
+
isDistinct = false;
|
|
129
|
+
groupByColumns = [];
|
|
130
|
+
havingCondition = null;
|
|
131
|
+
joins = [];
|
|
132
|
+
includeRelations = {};
|
|
133
|
+
selectedTableAlias;
|
|
134
|
+
selectedColumns = [];
|
|
135
|
+
distinct() {
|
|
136
|
+
this.isDistinct = true;
|
|
137
|
+
return this;
|
|
151
138
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
this.query += `
|
|
156
|
-
this.params.push(...condition.params);
|
|
139
|
+
groupBy(...columns) {
|
|
140
|
+
this.groupByColumns.push(...columns);
|
|
141
|
+
const columnNames = columns.map((col) => `${this.selectedTableAlias}.${col._.name}`).join(", ");
|
|
142
|
+
this.query += ` GROUP BY ${columnNames}`;
|
|
157
143
|
return this;
|
|
158
144
|
}
|
|
159
|
-
|
|
160
|
-
this.
|
|
145
|
+
having(condition) {
|
|
146
|
+
this.havingCondition = condition;
|
|
147
|
+
this.query += ` HAVING ${condition.sql}`;
|
|
148
|
+
this.params.push(...condition.params);
|
|
161
149
|
return this;
|
|
162
150
|
}
|
|
163
|
-
|
|
164
|
-
this.
|
|
151
|
+
leftJoin(table, condition, alias2) {
|
|
152
|
+
this.joins.push({ type: "LEFT", table, condition, alias: alias2 });
|
|
153
|
+
const aliasedColumns = Object.values(table._.columns).map(
|
|
154
|
+
(col) => `${alias2}.${col._.name} AS "${alias2}.${col._.name}"`
|
|
155
|
+
);
|
|
156
|
+
this.selectedColumns.push(...aliasedColumns);
|
|
165
157
|
return this;
|
|
166
158
|
}
|
|
167
|
-
|
|
168
|
-
this.
|
|
159
|
+
innerJoin(table, condition, alias2) {
|
|
160
|
+
this.joins.push({ type: "INNER", table, condition, alias: alias2 });
|
|
161
|
+
const aliasedColumns = Object.values(table._.columns).map(
|
|
162
|
+
(col) => `${alias2}.${col._.name} AS "${alias2}.${col._.name}"`
|
|
163
|
+
);
|
|
164
|
+
this.selectedColumns.push(...aliasedColumns);
|
|
169
165
|
return this;
|
|
170
166
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
params: this.params
|
|
175
|
-
};
|
|
167
|
+
include(relations2) {
|
|
168
|
+
this.includeRelations = { ...this.includeRelations, ...relations2 };
|
|
169
|
+
return this;
|
|
176
170
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
171
|
+
buildJoins() {
|
|
172
|
+
let sql2 = "";
|
|
173
|
+
const params = [];
|
|
174
|
+
for (const join of this.joins) {
|
|
175
|
+
sql2 += ` ${join.type} JOIN ${join.table._.name} ${join.alias} ON ${join.condition.sql}`;
|
|
176
|
+
params.push(...join.condition.params);
|
|
177
|
+
}
|
|
178
|
+
for (const [relationName, include] of Object.entries(this.includeRelations)) {
|
|
179
|
+
if (!include) continue;
|
|
180
|
+
const relation = this.table.relations[relationName];
|
|
181
|
+
if (!relation) {
|
|
182
|
+
console.warn(
|
|
183
|
+
`[Tauri-ORM] Relation "${relationName}" not found on table "${this.table._.name}". Skipping include.`
|
|
184
|
+
);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const foreignTable = relation.foreignTable;
|
|
188
|
+
const foreignAlias = `${this.selectedTableAlias}_${relationName}`;
|
|
189
|
+
const aliasedColumns = Object.values(foreignTable._.columns).map(
|
|
190
|
+
(col) => `${foreignAlias}.${col._.name} AS "${foreignAlias}.${col._.name}"`
|
|
191
|
+
);
|
|
192
|
+
this.selectedColumns.push(...aliasedColumns);
|
|
193
|
+
if (relation.type === "one" && relation.fields && relation.references) {
|
|
194
|
+
const conditions = relation.fields.map((field, i) => {
|
|
195
|
+
const localColumn = `${this.selectedTableAlias}.${field._.name}`;
|
|
196
|
+
const foreignColumn = `${foreignAlias}.${relation.references[i]._.name}`;
|
|
197
|
+
return {
|
|
198
|
+
sql: `${localColumn} = ${foreignColumn}`,
|
|
199
|
+
params: []
|
|
200
|
+
};
|
|
201
|
+
});
|
|
202
|
+
const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
|
|
203
|
+
sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
|
|
204
|
+
params.push(...condition.params);
|
|
205
|
+
} else if (relation.type === "many") {
|
|
206
|
+
const refRelation = Object.entries(foreignTable.relations).find(
|
|
207
|
+
([_, r]) => r.foreignTable === this.table
|
|
208
|
+
);
|
|
209
|
+
if (refRelation && refRelation[1].fields && refRelation[1].references) {
|
|
210
|
+
const [_, relationConfig] = refRelation;
|
|
211
|
+
const conditions = relationConfig.fields.map((field, i) => {
|
|
212
|
+
const localColumn = `${foreignAlias}.${field._.name}`;
|
|
213
|
+
const foreignColumn = `${this.selectedTableAlias}.${relationConfig.references[i]._.name}`;
|
|
214
|
+
return {
|
|
215
|
+
sql: `${localColumn} = ${foreignColumn}`,
|
|
216
|
+
params: []
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
const condition = conditions.length > 1 ? and(...conditions) : conditions[0];
|
|
220
|
+
sql2 += ` LEFT JOIN ${foreignTable._.name} ${foreignAlias} ON ${condition.sql}`;
|
|
221
|
+
params.push(...condition.params);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return { sql: sql2, params };
|
|
185
226
|
}
|
|
227
|
+
// Enhanced execute method that handles relation data mapping
|
|
186
228
|
async execute() {
|
|
187
|
-
const { sql, params } = this.
|
|
188
|
-
|
|
229
|
+
const { sql: joinSql, params: joinParams } = this.buildJoins();
|
|
230
|
+
const distinct = this.isDistinct ? "DISTINCT " : "";
|
|
231
|
+
this.query = `SELECT ${distinct}${this.selectedColumns.join(", ")} ${this.query}`;
|
|
232
|
+
this.query += joinSql;
|
|
233
|
+
this.params.push(...joinParams);
|
|
234
|
+
const { sql: sql2, params } = this.build();
|
|
235
|
+
console.log("Executing SQL:", sql2, "with params:", params);
|
|
236
|
+
const rawResults = await this.db.select(sql2, params);
|
|
237
|
+
const hasIncludes = Object.values(this.includeRelations).some((i) => i);
|
|
238
|
+
if (hasIncludes) {
|
|
239
|
+
return this.processRelationResults(rawResults);
|
|
240
|
+
}
|
|
241
|
+
const hasJoins = this.joins.length > 0;
|
|
242
|
+
if (hasJoins) {
|
|
243
|
+
return rawResults;
|
|
244
|
+
}
|
|
245
|
+
const prefix = `${this.selectedTableAlias}.`;
|
|
246
|
+
return rawResults.map((row) => {
|
|
247
|
+
const newRow = {};
|
|
248
|
+
for (const key in row) {
|
|
249
|
+
if (key.startsWith(prefix)) {
|
|
250
|
+
newRow[key.substring(prefix.length)] = row[key];
|
|
251
|
+
} else {
|
|
252
|
+
newRow[key] = row[key];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return newRow;
|
|
256
|
+
});
|
|
189
257
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
258
|
+
processRelationResults(rawResults) {
|
|
259
|
+
if (!rawResults.length) return [];
|
|
260
|
+
const mainTablePks = Object.values(this.table._.columns).filter((c) => c.options.primaryKey).map((c) => c._.name);
|
|
261
|
+
if (mainTablePks.length === 0) {
|
|
262
|
+
return rawResults;
|
|
263
|
+
}
|
|
264
|
+
const groupedResults = /* @__PURE__ */ new Map();
|
|
265
|
+
for (const row of rawResults) {
|
|
266
|
+
const mainTableKey = mainTablePks.map((pk) => row[`${this.selectedTableAlias}.${pk}`] ?? row[pk]).join("_");
|
|
267
|
+
if (!groupedResults.has(mainTableKey)) {
|
|
268
|
+
groupedResults.set(mainTableKey, {});
|
|
269
|
+
}
|
|
270
|
+
const result = groupedResults.get(mainTableKey);
|
|
271
|
+
const relations2 = {};
|
|
272
|
+
for (const [key, value] of Object.entries(row)) {
|
|
273
|
+
if (key.includes(".")) {
|
|
274
|
+
const [tableAlias, columnName] = key.split(".");
|
|
275
|
+
if (tableAlias === this.selectedTableAlias) {
|
|
276
|
+
result[columnName] = value;
|
|
277
|
+
} else {
|
|
278
|
+
const parts = tableAlias.split("_");
|
|
279
|
+
if (parts.length >= 2 && parts[0] === this.selectedTableAlias) {
|
|
280
|
+
const relationName = parts.slice(1).join("_");
|
|
281
|
+
if (!relations2[relationName]) relations2[relationName] = {};
|
|
282
|
+
relations2[relationName][columnName] = value;
|
|
283
|
+
} else {
|
|
284
|
+
if (!result[tableAlias]) result[tableAlias] = {};
|
|
285
|
+
result[tableAlias][columnName] = value;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
result[key] = value;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
for (const [relName, relData] of Object.entries(relations2)) {
|
|
293
|
+
const relationConfig = this.table.relations[relName];
|
|
294
|
+
if (!relationConfig) continue;
|
|
295
|
+
const hasData = Object.values(relData).some(
|
|
296
|
+
(v) => v !== null && v !== void 0 && v !== ""
|
|
297
|
+
);
|
|
298
|
+
if (!hasData) continue;
|
|
299
|
+
if (relationConfig.type === "many") {
|
|
300
|
+
if (!result[relName]) result[relName] = [];
|
|
301
|
+
const relatedPks = Object.values(relationConfig.foreignTable._.columns).filter((c) => c.options.primaryKey).map((c) => c._.name);
|
|
302
|
+
const relDataKey = relatedPks.map((pk) => relData[pk]).join("_");
|
|
303
|
+
if (relatedPks.length === 0 || !result[relName].some((r) => relatedPks.map((pk) => r[pk]).join("_") === relDataKey)) {
|
|
304
|
+
result[relName].push(relData);
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
result[relName] = relData;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return Array.from(groupedResults.values());
|
|
196
312
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
this.dataSets.push(...dataArray);
|
|
201
|
-
return this;
|
|
313
|
+
// Update the return type signatures
|
|
314
|
+
async all() {
|
|
315
|
+
return this.execute();
|
|
202
316
|
}
|
|
203
|
-
async
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const columns = Object.keys(
|
|
208
|
-
this.dataSets[0]
|
|
209
|
-
);
|
|
210
|
-
const columnNames = columns.map(
|
|
211
|
-
(c) => this.table._.columns[c]._.name
|
|
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;
|
|
317
|
+
async get() {
|
|
318
|
+
this.limit(1);
|
|
319
|
+
const result = await this.execute();
|
|
320
|
+
return result[0];
|
|
221
321
|
}
|
|
222
322
|
};
|
|
323
|
+
|
|
324
|
+
// src/builders/update.ts
|
|
223
325
|
var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
224
326
|
constructor(db, table) {
|
|
225
327
|
super(db);
|
|
@@ -227,11 +329,23 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
|
227
329
|
this.query = `UPDATE ${table._.name}`;
|
|
228
330
|
}
|
|
229
331
|
updateData = {};
|
|
332
|
+
returningColumns = [];
|
|
230
333
|
set(data) {
|
|
231
334
|
this.updateData = { ...this.updateData, ...data };
|
|
232
335
|
return this;
|
|
233
336
|
}
|
|
234
|
-
|
|
337
|
+
returning(...columns) {
|
|
338
|
+
this.returningColumns.push(...columns);
|
|
339
|
+
return this;
|
|
340
|
+
}
|
|
341
|
+
buildUpdateClause() {
|
|
342
|
+
const finalUpdateData = { ...this.updateData };
|
|
343
|
+
for (const [key, column] of Object.entries(this.table._.columns)) {
|
|
344
|
+
const typedKey = key;
|
|
345
|
+
if (finalUpdateData[typedKey] === void 0 && column.options.$onUpdateFn) {
|
|
346
|
+
finalUpdateData[typedKey] = column.options.$onUpdateFn();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
235
349
|
const baseQuery = this.query;
|
|
236
350
|
const whereParams = this.params;
|
|
237
351
|
let tablePart = baseQuery;
|
|
@@ -241,7 +355,7 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
|
241
355
|
tablePart = baseQuery.substring(0, whereIndex);
|
|
242
356
|
whereClause = baseQuery.substring(whereIndex);
|
|
243
357
|
}
|
|
244
|
-
const entries = Object.entries(
|
|
358
|
+
const entries = Object.entries(finalUpdateData);
|
|
245
359
|
if (entries.length === 0) {
|
|
246
360
|
throw new Error("Cannot execute an update query without a .set() call.");
|
|
247
361
|
}
|
|
@@ -255,61 +369,416 @@ var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
|
255
369
|
return `${column._.name} = ?`;
|
|
256
370
|
}).join(", ");
|
|
257
371
|
const setParams = entries.map(([, value]) => value);
|
|
258
|
-
const
|
|
372
|
+
const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
|
|
259
373
|
const params = [...setParams, ...whereParams];
|
|
260
|
-
return { sql, params };
|
|
374
|
+
return { sql: sql2, params };
|
|
261
375
|
}
|
|
262
376
|
async execute() {
|
|
263
|
-
const { sql, params } = this.
|
|
264
|
-
|
|
265
|
-
|
|
377
|
+
const { sql: updateSql, params } = this.buildUpdateClause();
|
|
378
|
+
if (this.returningColumns.length > 0) {
|
|
379
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
380
|
+
const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
|
|
381
|
+
return this.db.select(sqlWithReturning, params);
|
|
382
|
+
} else {
|
|
383
|
+
const result = await this.db.execute(updateSql, params);
|
|
384
|
+
return [{ rowsAffected: result.rowsAffected }];
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
async returningAll() {
|
|
388
|
+
const allColumns = Object.keys(
|
|
389
|
+
this.table._.columns
|
|
390
|
+
);
|
|
391
|
+
return this.returning(...allColumns).execute();
|
|
266
392
|
}
|
|
267
393
|
};
|
|
394
|
+
|
|
395
|
+
// src/builders/insert.ts
|
|
396
|
+
var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
397
|
+
constructor(db, table) {
|
|
398
|
+
super(db);
|
|
399
|
+
this.table = table;
|
|
400
|
+
this.query = `INSERT INTO ${table._.name}`;
|
|
401
|
+
}
|
|
402
|
+
dataSets = [];
|
|
403
|
+
returningColumns = [];
|
|
404
|
+
onConflictAction = null;
|
|
405
|
+
conflictTarget = [];
|
|
406
|
+
updateSet = {};
|
|
407
|
+
values(data) {
|
|
408
|
+
const dataArray = Array.isArray(data) ? data : [data];
|
|
409
|
+
this.dataSets.push(...dataArray);
|
|
410
|
+
return this;
|
|
411
|
+
}
|
|
412
|
+
returning(...columns) {
|
|
413
|
+
this.returningColumns.push(...columns);
|
|
414
|
+
return this;
|
|
415
|
+
}
|
|
416
|
+
onConflictDoNothing(target) {
|
|
417
|
+
this.onConflictAction = "nothing";
|
|
418
|
+
if (target) {
|
|
419
|
+
this.conflictTarget = Array.isArray(target) ? target : [target];
|
|
420
|
+
}
|
|
421
|
+
return this;
|
|
422
|
+
}
|
|
423
|
+
onConflictDoUpdate(config) {
|
|
424
|
+
this.onConflictAction = "update";
|
|
425
|
+
this.conflictTarget = Array.isArray(config.target) ? config.target : [config.target];
|
|
426
|
+
this.updateSet = config.set;
|
|
427
|
+
return this;
|
|
428
|
+
}
|
|
429
|
+
processDefaultValues(data) {
|
|
430
|
+
const finalData = { ...data };
|
|
431
|
+
for (const [key, column] of Object.entries(this.table._.columns)) {
|
|
432
|
+
const typedKey = key;
|
|
433
|
+
if (finalData[typedKey] === void 0) {
|
|
434
|
+
if (column.options.$defaultFn) {
|
|
435
|
+
finalData[typedKey] = column.options.$defaultFn();
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return finalData;
|
|
440
|
+
}
|
|
441
|
+
buildConflictClause() {
|
|
442
|
+
if (!this.onConflictAction) return "";
|
|
443
|
+
let clause = " ON CONFLICT";
|
|
444
|
+
if (this.conflictTarget.length > 0) {
|
|
445
|
+
const targetNames = this.conflictTarget.map((col) => col._.name).join(", ");
|
|
446
|
+
clause += ` (${targetNames})`;
|
|
447
|
+
}
|
|
448
|
+
if (this.onConflictAction === "nothing") {
|
|
449
|
+
clause += " DO NOTHING";
|
|
450
|
+
} else if (this.onConflictAction === "update") {
|
|
451
|
+
const setEntries = Object.entries(this.updateSet);
|
|
452
|
+
if (setEntries.length > 0) {
|
|
453
|
+
const setClause = setEntries.map(([key]) => `${key} = ?`).join(", ");
|
|
454
|
+
clause += ` DO UPDATE SET ${setClause}`;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return clause;
|
|
458
|
+
}
|
|
459
|
+
async execute() {
|
|
460
|
+
if (this.dataSets.length === 0) {
|
|
461
|
+
throw new Error("No data provided for insert");
|
|
462
|
+
}
|
|
463
|
+
const processedDataSets = this.dataSets.map(
|
|
464
|
+
(data) => this.processDefaultValues(data)
|
|
465
|
+
);
|
|
466
|
+
const groups = /* @__PURE__ */ new Map();
|
|
467
|
+
for (const dataSet of processedDataSets) {
|
|
468
|
+
const keys = Object.keys(dataSet).sort().join(",");
|
|
469
|
+
if (!groups.has(keys)) {
|
|
470
|
+
groups.set(keys, []);
|
|
471
|
+
}
|
|
472
|
+
groups.get(keys).push(dataSet);
|
|
473
|
+
}
|
|
474
|
+
let results = [];
|
|
475
|
+
let lastInsertId;
|
|
476
|
+
let rowsAffected = 0;
|
|
477
|
+
for (const [_, dataSets] of groups) {
|
|
478
|
+
const columns = Object.keys(dataSets[0]);
|
|
479
|
+
const columnNames = columns.map(
|
|
480
|
+
(key) => this.table._.columns[key]._.name
|
|
481
|
+
);
|
|
482
|
+
const placeholders = `(${columns.map(() => "?").join(", ")})`;
|
|
483
|
+
const valuesSql = dataSets.map(() => placeholders).join(", ");
|
|
484
|
+
const conflictClause = this.buildConflictClause();
|
|
485
|
+
const finalQuery = `${this.query} (${columnNames.join(
|
|
486
|
+
", "
|
|
487
|
+
)}) VALUES ${valuesSql}${conflictClause}`;
|
|
488
|
+
const params = dataSets.flatMap(
|
|
489
|
+
(data) => columns.map((col) => data[col] ?? null)
|
|
490
|
+
);
|
|
491
|
+
if (this.onConflictAction === "update") {
|
|
492
|
+
const setValues = Object.entries(this.updateSet).map(
|
|
493
|
+
([, value]) => value
|
|
494
|
+
);
|
|
495
|
+
params.push(...setValues);
|
|
496
|
+
}
|
|
497
|
+
if (this.returningColumns.length > 0) {
|
|
498
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
499
|
+
const queryWithReturning = `${finalQuery} RETURNING ${returningNames}`;
|
|
500
|
+
const rows = await this.db.select(queryWithReturning, params);
|
|
501
|
+
results = results.concat(rows);
|
|
502
|
+
} else {
|
|
503
|
+
const result = await this.db.execute(finalQuery, params);
|
|
504
|
+
lastInsertId = result.lastInsertId;
|
|
505
|
+
rowsAffected += result.rowsAffected;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (this.returningColumns.length > 0) {
|
|
509
|
+
return results;
|
|
510
|
+
}
|
|
511
|
+
return [{ lastInsertId, rowsAffected }];
|
|
512
|
+
}
|
|
513
|
+
async returningAll() {
|
|
514
|
+
const allColumns = Object.keys(
|
|
515
|
+
this.table._.columns
|
|
516
|
+
);
|
|
517
|
+
return this.returning(...allColumns).execute();
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
// src/builders/delete.ts
|
|
268
522
|
var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
269
523
|
constructor(db, table) {
|
|
270
524
|
super(db);
|
|
271
525
|
this.table = table;
|
|
272
526
|
this.query = `DELETE FROM ${table._.name}`;
|
|
273
527
|
}
|
|
528
|
+
returningColumns = [];
|
|
529
|
+
returning(...columns) {
|
|
530
|
+
this.returningColumns.push(...columns);
|
|
531
|
+
return this;
|
|
532
|
+
}
|
|
274
533
|
async execute() {
|
|
275
|
-
const { sql, params } = this.build();
|
|
276
|
-
|
|
277
|
-
|
|
534
|
+
const { sql: sql2, params } = this.build();
|
|
535
|
+
if (this.returningColumns.length > 0) {
|
|
536
|
+
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
537
|
+
const sqlWithReturning = `${sql2} RETURNING ${returningNames}`;
|
|
538
|
+
return this.db.select(sqlWithReturning, params);
|
|
539
|
+
} else {
|
|
540
|
+
const result = await this.db.execute(sql2, params);
|
|
541
|
+
return [{ rowsAffected: result.rowsAffected }];
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
async returningAll() {
|
|
545
|
+
const allColumns = Object.keys(this.table._.columns);
|
|
546
|
+
return this.returning(...allColumns).execute();
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
// src/builders/with.ts
|
|
551
|
+
var WithQueryBuilder = class {
|
|
552
|
+
constructor(db) {
|
|
553
|
+
this.db = db;
|
|
554
|
+
}
|
|
555
|
+
ctes = [];
|
|
556
|
+
with(alias2, query) {
|
|
557
|
+
this.ctes.push({ alias: alias2, query: query.sql, params: query.params });
|
|
558
|
+
return this;
|
|
559
|
+
}
|
|
560
|
+
select(table, columns) {
|
|
561
|
+
const builder = new SelectQueryBuilder(this.db, table, columns);
|
|
562
|
+
this.applyWithClause(builder);
|
|
563
|
+
return builder;
|
|
564
|
+
}
|
|
565
|
+
insert(table) {
|
|
566
|
+
const builder = new InsertQueryBuilder(this.db, table);
|
|
567
|
+
this.applyWithClause(builder);
|
|
568
|
+
return builder;
|
|
569
|
+
}
|
|
570
|
+
update(table) {
|
|
571
|
+
const builder = new UpdateQueryBuilder(this.db, table);
|
|
572
|
+
this.applyWithClause(builder);
|
|
573
|
+
return builder;
|
|
574
|
+
}
|
|
575
|
+
delete(table) {
|
|
576
|
+
const builder = new DeleteQueryBuilder(this.db, table);
|
|
577
|
+
this.applyWithClause(builder);
|
|
578
|
+
return builder;
|
|
579
|
+
}
|
|
580
|
+
applyWithClause(builder) {
|
|
581
|
+
if (this.ctes.length > 0) {
|
|
582
|
+
const cteSql = this.ctes.map((cte) => `${cte.alias} AS (${cte.query})`).join(", ");
|
|
583
|
+
builder["query"] = `WITH ${cteSql} ${builder["query"]}`;
|
|
584
|
+
builder["params"] = [
|
|
585
|
+
...this.ctes.flatMap((cte) => cte.params),
|
|
586
|
+
...builder["params"]
|
|
587
|
+
];
|
|
588
|
+
}
|
|
278
589
|
}
|
|
279
590
|
};
|
|
591
|
+
|
|
592
|
+
// src/orm.ts
|
|
593
|
+
var SQLiteColumn = class _SQLiteColumn {
|
|
594
|
+
constructor(name, type, options = {}, mode) {
|
|
595
|
+
this.type = type;
|
|
596
|
+
this.options = options;
|
|
597
|
+
this._ = {
|
|
598
|
+
name,
|
|
599
|
+
dataType: type,
|
|
600
|
+
mode: mode || "default",
|
|
601
|
+
notNull: options.notNull ?? false,
|
|
602
|
+
hasDefault: options.default !== void 0 || options.$defaultFn !== void 0,
|
|
603
|
+
autoincrement: options.autoincrement ?? false,
|
|
604
|
+
enum: options.enum,
|
|
605
|
+
customType: void 0
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
_;
|
|
609
|
+
notNull() {
|
|
610
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, notNull: true }, this._.mode);
|
|
611
|
+
}
|
|
612
|
+
default(value) {
|
|
613
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, default: value }, this._.mode);
|
|
614
|
+
}
|
|
615
|
+
$defaultFn(fn) {
|
|
616
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, $defaultFn: fn }, this._.mode);
|
|
617
|
+
}
|
|
618
|
+
primaryKey() {
|
|
619
|
+
return new _SQLiteColumn(
|
|
620
|
+
this._.name,
|
|
621
|
+
this.type,
|
|
622
|
+
{ ...this.options, primaryKey: true, notNull: true },
|
|
623
|
+
this._.mode
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
autoincrement() {
|
|
627
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, autoincrement: true }, this._.mode);
|
|
628
|
+
}
|
|
629
|
+
unique() {
|
|
630
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, unique: true }, this._.mode);
|
|
631
|
+
}
|
|
632
|
+
references(ref, column) {
|
|
633
|
+
return new _SQLiteColumn(
|
|
634
|
+
this._.name,
|
|
635
|
+
this.type,
|
|
636
|
+
{
|
|
637
|
+
...this.options,
|
|
638
|
+
references: {
|
|
639
|
+
table: ref,
|
|
640
|
+
column: ref._.columns[column]
|
|
641
|
+
}
|
|
642
|
+
},
|
|
643
|
+
this._.mode
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
$onUpdateFn(fn) {
|
|
647
|
+
return new _SQLiteColumn(this._.name, this.type, { ...this.options, $onUpdateFn: fn }, this._.mode);
|
|
648
|
+
}
|
|
649
|
+
$type() {
|
|
650
|
+
return this;
|
|
651
|
+
}
|
|
652
|
+
as(alias2) {
|
|
653
|
+
return this;
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
var Table = class {
|
|
657
|
+
_;
|
|
658
|
+
relations = {};
|
|
659
|
+
constructor(name, columns) {
|
|
660
|
+
this._ = {
|
|
661
|
+
name,
|
|
662
|
+
columns
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
var sqliteTable = (tableName, columns) => {
|
|
667
|
+
return new Table(tableName, columns);
|
|
668
|
+
};
|
|
669
|
+
var asc = (column) => ({
|
|
670
|
+
sql: `${column._.name} ASC`,
|
|
671
|
+
params: []
|
|
672
|
+
});
|
|
673
|
+
var desc = (column) => ({
|
|
674
|
+
sql: `${column._.name} DESC`,
|
|
675
|
+
params: []
|
|
676
|
+
});
|
|
677
|
+
var sql = (strings, ...values) => {
|
|
678
|
+
const queryParts = [];
|
|
679
|
+
const params = [];
|
|
680
|
+
strings.forEach((str, i) => {
|
|
681
|
+
queryParts.push(str);
|
|
682
|
+
if (values[i] !== void 0) {
|
|
683
|
+
if (typeof values[i] === "object" && values[i].sql) {
|
|
684
|
+
queryParts.push(values[i].sql);
|
|
685
|
+
params.push(...values[i].params);
|
|
686
|
+
} else {
|
|
687
|
+
queryParts.push("?");
|
|
688
|
+
params.push(values[i]);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
return {
|
|
693
|
+
sql: queryParts.join(""),
|
|
694
|
+
params
|
|
695
|
+
};
|
|
696
|
+
};
|
|
280
697
|
var TauriORM = class {
|
|
281
698
|
constructor(db, schema = void 0) {
|
|
282
699
|
this.db = db;
|
|
283
700
|
if (schema) {
|
|
284
|
-
for (const
|
|
285
|
-
|
|
701
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
702
|
+
if (value instanceof Table) {
|
|
703
|
+
this.tables.set(value._.name, value);
|
|
704
|
+
}
|
|
286
705
|
}
|
|
287
706
|
}
|
|
288
707
|
}
|
|
289
708
|
tables = /* @__PURE__ */ new Map();
|
|
290
|
-
|
|
709
|
+
buildColumnDefinition(col, forAlterTable = false) {
|
|
710
|
+
let sql2 = `${col._.name} ${col.type}`;
|
|
711
|
+
if (col.options.primaryKey && !forAlterTable) {
|
|
712
|
+
sql2 += " PRIMARY KEY";
|
|
713
|
+
if (col._.autoincrement) {
|
|
714
|
+
sql2 += " AUTOINCREMENT";
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
if (col._.notNull) sql2 += " NOT NULL";
|
|
718
|
+
if (col.options.unique) sql2 += " UNIQUE";
|
|
719
|
+
if (col.options.default !== void 0) {
|
|
720
|
+
const value = col.options.default;
|
|
721
|
+
sql2 += ` DEFAULT ${typeof value === "string" ? `'${value.replace(/'/g, "''")}'` : value}`;
|
|
722
|
+
}
|
|
723
|
+
if (col.options.references) {
|
|
724
|
+
sql2 += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
|
|
725
|
+
}
|
|
726
|
+
return sql2;
|
|
727
|
+
}
|
|
728
|
+
async migrate(options) {
|
|
729
|
+
const dbTables = await this.db.select(
|
|
730
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'`
|
|
731
|
+
);
|
|
732
|
+
const dbTableNames = new Set(dbTables.map((t) => t.name));
|
|
733
|
+
const schemaTableNames = new Set(Array.from(this.tables.keys()));
|
|
291
734
|
for (const table of this.tables.values()) {
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
735
|
+
const tableName = table._.name;
|
|
736
|
+
const tableExists = dbTableNames.has(tableName);
|
|
737
|
+
if (!tableExists) {
|
|
738
|
+
const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
|
|
739
|
+
const createSql = `CREATE TABLE ${tableName}
|
|
740
|
+
(
|
|
741
|
+
${columnsSql}
|
|
742
|
+
)`;
|
|
743
|
+
await this.db.execute(createSql);
|
|
744
|
+
} else {
|
|
745
|
+
const existingTableInfo = await this.db.select(`PRAGMA table_info('${tableName}')`);
|
|
746
|
+
const existingColumnNames = new Set(existingTableInfo.map((c) => c.name));
|
|
747
|
+
const schemaColumnNames = new Set(Object.keys(table._.columns));
|
|
748
|
+
for (const column of Object.values(table._.columns)) {
|
|
749
|
+
if (!existingColumnNames.has(column._.name)) {
|
|
750
|
+
const columnSql = this.buildColumnDefinition(column, true);
|
|
751
|
+
const alterSql = `ALTER TABLE ${tableName}
|
|
752
|
+
ADD COLUMN ${columnSql}`;
|
|
753
|
+
await this.db.execute(alterSql);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
if (options?.performDestructiveActions) {
|
|
757
|
+
for (const colName of existingColumnNames) {
|
|
758
|
+
if (!schemaColumnNames.has(colName)) {
|
|
759
|
+
await this.dropColumn(tableName, colName);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
301
762
|
}
|
|
302
|
-
|
|
303
|
-
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (options?.performDestructiveActions) {
|
|
766
|
+
for (const tableName of dbTableNames) {
|
|
767
|
+
if (!schemaTableNames.has(tableName)) {
|
|
768
|
+
await this.dropTable(tableName);
|
|
304
769
|
}
|
|
305
|
-
|
|
306
|
-
}).join(", ");
|
|
307
|
-
const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
|
|
308
|
-
await this.db.execute(createSql);
|
|
770
|
+
}
|
|
309
771
|
}
|
|
310
772
|
}
|
|
311
773
|
select(table, columns) {
|
|
312
|
-
|
|
774
|
+
const internalTable = this.tables.get(table._.name);
|
|
775
|
+
if (!internalTable) {
|
|
776
|
+
console.warn(
|
|
777
|
+
`[Tauri-ORM] Table "${table._.name}" was not passed in the schema to the ORM constructor. Relations will not be available.`
|
|
778
|
+
);
|
|
779
|
+
return new SelectQueryBuilder(this.db, table, columns);
|
|
780
|
+
}
|
|
781
|
+
return new SelectQueryBuilder(this.db, internalTable, columns);
|
|
313
782
|
}
|
|
314
783
|
insert(table) {
|
|
315
784
|
return new InsertQueryBuilder(this.db, table);
|
|
@@ -320,6 +789,15 @@ var TauriORM = class {
|
|
|
320
789
|
delete(table) {
|
|
321
790
|
return new DeleteQueryBuilder(this.db, table);
|
|
322
791
|
}
|
|
792
|
+
$with(alias2) {
|
|
793
|
+
const withBuilder = new WithQueryBuilder(this.db);
|
|
794
|
+
return {
|
|
795
|
+
as: (query) => {
|
|
796
|
+
withBuilder.with(alias2, query);
|
|
797
|
+
return withBuilder;
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
}
|
|
323
801
|
async transaction(callback) {
|
|
324
802
|
await this.db.execute("BEGIN TRANSACTION");
|
|
325
803
|
try {
|
|
@@ -331,16 +809,31 @@ var TauriORM = class {
|
|
|
331
809
|
throw error;
|
|
332
810
|
}
|
|
333
811
|
}
|
|
812
|
+
rollback() {
|
|
813
|
+
throw new Error("Transaction rolled back");
|
|
814
|
+
}
|
|
334
815
|
// --- Schema detection / signature ---
|
|
335
816
|
async ensureSchemaMeta() {
|
|
336
817
|
await this.db.execute(
|
|
337
|
-
`CREATE TABLE IF NOT EXISTS _schema_meta
|
|
818
|
+
`CREATE TABLE IF NOT EXISTS _schema_meta
|
|
819
|
+
(
|
|
820
|
+
key
|
|
821
|
+
TEXT
|
|
822
|
+
PRIMARY
|
|
823
|
+
KEY,
|
|
824
|
+
value
|
|
825
|
+
TEXT
|
|
826
|
+
NOT
|
|
827
|
+
NULL
|
|
828
|
+
)`
|
|
338
829
|
);
|
|
339
830
|
}
|
|
340
831
|
async getSchemaMeta(key) {
|
|
341
832
|
await this.ensureSchemaMeta();
|
|
342
833
|
const rows = await this.db.select(
|
|
343
|
-
`SELECT value
|
|
834
|
+
`SELECT value
|
|
835
|
+
FROM _schema_meta
|
|
836
|
+
WHERE key = ?`,
|
|
344
837
|
[key]
|
|
345
838
|
);
|
|
346
839
|
return rows?.[0]?.value ?? null;
|
|
@@ -348,7 +841,10 @@ var TauriORM = class {
|
|
|
348
841
|
async setSchemaMeta(key, value) {
|
|
349
842
|
await this.ensureSchemaMeta();
|
|
350
843
|
await this.db.execute(
|
|
351
|
-
`INSERT INTO _schema_meta(key, value)
|
|
844
|
+
`INSERT INTO _schema_meta(key, value)
|
|
845
|
+
VALUES (?, ?) ON CONFLICT(key) DO
|
|
846
|
+
UPDATE
|
|
847
|
+
SET value = excluded.value`,
|
|
352
848
|
[key, value]
|
|
353
849
|
);
|
|
354
850
|
}
|
|
@@ -359,7 +855,10 @@ var TauriORM = class {
|
|
|
359
855
|
pk: !!col.options.primaryKey,
|
|
360
856
|
ai: !!col._.autoincrement,
|
|
361
857
|
nn: !!col._.notNull,
|
|
362
|
-
|
|
858
|
+
unique: !!col.options.unique,
|
|
859
|
+
dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null,
|
|
860
|
+
hasDefaultFn: col.options.$defaultFn !== void 0,
|
|
861
|
+
hasOnUpdateFn: col.options.$onUpdateFn !== void 0
|
|
363
862
|
};
|
|
364
863
|
}
|
|
365
864
|
computeModelSignature() {
|
|
@@ -382,41 +881,117 @@ var TauriORM = class {
|
|
|
382
881
|
const status = await this.isSchemaDirty();
|
|
383
882
|
if (status.dirty) {
|
|
384
883
|
await this.migrate();
|
|
385
|
-
await this.setSchemaMeta(
|
|
386
|
-
"schema_signature",
|
|
387
|
-
this.computeModelSignature()
|
|
388
|
-
);
|
|
884
|
+
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
389
885
|
return true;
|
|
390
886
|
}
|
|
391
887
|
return false;
|
|
392
888
|
}
|
|
889
|
+
async doesTableExist(tableName) {
|
|
890
|
+
const result = await this.db.select(
|
|
891
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
|
|
892
|
+
[tableName]
|
|
893
|
+
);
|
|
894
|
+
return result.length > 0;
|
|
895
|
+
}
|
|
896
|
+
async dropTable(tableName) {
|
|
897
|
+
await this.db.execute(`DROP TABLE IF EXISTS ${tableName}`);
|
|
898
|
+
}
|
|
899
|
+
async doesColumnExist(tableName, columnName) {
|
|
900
|
+
const result = await this.db.select(`PRAGMA table_info('${tableName}')`);
|
|
901
|
+
return result.some((col) => col.name === columnName);
|
|
902
|
+
}
|
|
903
|
+
async renameTable(from, to) {
|
|
904
|
+
await this.db.execute(`ALTER TABLE ${from} RENAME TO ${to}`);
|
|
905
|
+
}
|
|
906
|
+
async dropColumn(tableName, columnName) {
|
|
907
|
+
await this.db.execute(`ALTER TABLE ${tableName} DROP COLUMN ${columnName}`);
|
|
908
|
+
}
|
|
909
|
+
async renameColumn(tableName, from, to) {
|
|
910
|
+
await this.db.execute(`ALTER TABLE ${tableName} RENAME COLUMN ${from} TO ${to}`);
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
var Relation = class {
|
|
914
|
+
constructor(foreignTable) {
|
|
915
|
+
this.foreignTable = foreignTable;
|
|
916
|
+
}
|
|
917
|
+
};
|
|
918
|
+
var OneRelation = class extends Relation {
|
|
919
|
+
constructor(foreignTable, config) {
|
|
920
|
+
super(foreignTable);
|
|
921
|
+
this.config = config;
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
var ManyRelation = class extends Relation {
|
|
925
|
+
constructor(foreignTable) {
|
|
926
|
+
super(foreignTable);
|
|
927
|
+
}
|
|
393
928
|
};
|
|
394
929
|
var relations = (table, relationsCallback) => {
|
|
395
|
-
|
|
396
|
-
one: (
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
many: (table2) => ({
|
|
403
|
-
table: table2,
|
|
404
|
-
type: "many"
|
|
405
|
-
})
|
|
930
|
+
const builtRelations = relationsCallback({
|
|
931
|
+
one: (foreignTable, config) => {
|
|
932
|
+
return new OneRelation(foreignTable, config);
|
|
933
|
+
},
|
|
934
|
+
many: (foreignTable) => {
|
|
935
|
+
return new ManyRelation(foreignTable);
|
|
936
|
+
}
|
|
406
937
|
});
|
|
938
|
+
for (const [name, relation] of Object.entries(builtRelations)) {
|
|
939
|
+
if (relation instanceof OneRelation) {
|
|
940
|
+
table.relations[name] = {
|
|
941
|
+
type: "one",
|
|
942
|
+
foreignTable: relation.foreignTable,
|
|
943
|
+
fields: relation.config?.fields,
|
|
944
|
+
references: relation.config?.references
|
|
945
|
+
};
|
|
946
|
+
} else if (relation instanceof ManyRelation) {
|
|
947
|
+
table.relations[name] = {
|
|
948
|
+
type: "many",
|
|
949
|
+
foreignTable: relation.foreignTable
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
return builtRelations;
|
|
407
954
|
};
|
|
955
|
+
var getTableColumns = (table) => {
|
|
956
|
+
return table._.columns;
|
|
957
|
+
};
|
|
958
|
+
var alias = (table, alias2) => {
|
|
959
|
+
return table;
|
|
960
|
+
};
|
|
961
|
+
|
|
962
|
+
// src/column-helpers.ts
|
|
963
|
+
var text = (name, config) => new SQLiteColumn(name, "TEXT", config, config?.mode);
|
|
964
|
+
var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
|
|
965
|
+
var real = (name) => new SQLiteColumn(name, "REAL");
|
|
966
|
+
var blob = (name, config) => new SQLiteColumn(name, "BLOB", {}, config?.mode);
|
|
967
|
+
var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
|
|
968
|
+
var numeric = (name, config) => new SQLiteColumn(name, "NUMERIC", {}, config?.mode);
|
|
969
|
+
var enumType = (name, values) => text(name, { enum: values });
|
|
408
970
|
export {
|
|
971
|
+
BaseQueryBuilder,
|
|
409
972
|
DeleteQueryBuilder,
|
|
410
973
|
InsertQueryBuilder,
|
|
974
|
+
ManyRelation,
|
|
975
|
+
OneRelation,
|
|
976
|
+
Relation,
|
|
411
977
|
SQLiteColumn,
|
|
412
978
|
SelectQueryBuilder,
|
|
413
979
|
Table,
|
|
414
980
|
TauriORM,
|
|
415
981
|
UpdateQueryBuilder,
|
|
982
|
+
WithQueryBuilder,
|
|
983
|
+
alias,
|
|
416
984
|
and,
|
|
985
|
+
asc,
|
|
986
|
+
avg,
|
|
417
987
|
blob,
|
|
418
988
|
boolean,
|
|
989
|
+
count,
|
|
990
|
+
countDistinct,
|
|
991
|
+
desc,
|
|
992
|
+
enumType,
|
|
419
993
|
eq,
|
|
994
|
+
getTableColumns,
|
|
420
995
|
gt,
|
|
421
996
|
gte,
|
|
422
997
|
inArray,
|
|
@@ -426,9 +1001,15 @@ export {
|
|
|
426
1001
|
like,
|
|
427
1002
|
lt,
|
|
428
1003
|
lte,
|
|
1004
|
+
max,
|
|
1005
|
+
min,
|
|
1006
|
+
not,
|
|
1007
|
+
numeric,
|
|
429
1008
|
or,
|
|
430
1009
|
real,
|
|
431
1010
|
relations,
|
|
1011
|
+
sql,
|
|
432
1012
|
sqliteTable,
|
|
1013
|
+
sum,
|
|
433
1014
|
text
|
|
434
1015
|
};
|