@type32/tauri-sqlite-orm 0.1.17 → 0.1.18-0
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 +109 -190
- package/dist/index.d.mts +131 -431
- package/dist/index.d.ts +131 -431
- package/dist/index.js +308 -1681
- package/dist/index.mjs +298 -1643
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,1361 +1,404 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
10
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
9
|
};
|
|
12
|
-
var __copyProps = (to, from, except,
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
11
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
12
|
for (let key of __getOwnPropNames(from))
|
|
15
13
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
31
21
|
var index_exports = {};
|
|
32
22
|
__export(index_exports, {
|
|
23
|
+
DeleteQueryBuilder: () => DeleteQueryBuilder,
|
|
24
|
+
InsertQueryBuilder: () => InsertQueryBuilder,
|
|
25
|
+
SQLiteColumn: () => SQLiteColumn,
|
|
26
|
+
SelectQueryBuilder: () => SelectQueryBuilder,
|
|
27
|
+
Table: () => Table,
|
|
33
28
|
TauriORM: () => TauriORM,
|
|
29
|
+
UpdateQueryBuilder: () => UpdateQueryBuilder,
|
|
34
30
|
and: () => and,
|
|
35
|
-
asc: () => asc,
|
|
36
|
-
between: () => between,
|
|
37
31
|
blob: () => blob,
|
|
38
32
|
boolean: () => boolean,
|
|
39
|
-
check: () => check,
|
|
40
|
-
defineTable: () => defineTable,
|
|
41
|
-
desc: () => desc,
|
|
42
33
|
eq: () => eq,
|
|
43
|
-
exists: () => exists,
|
|
44
|
-
foreignKey: () => foreignKey,
|
|
45
|
-
getQualifiedName: () => getQualifiedName,
|
|
46
34
|
gt: () => gt,
|
|
47
35
|
gte: () => gte,
|
|
48
|
-
ilike: () => ilike,
|
|
49
36
|
inArray: () => inArray,
|
|
50
|
-
increments: () => increments,
|
|
51
|
-
index: () => index,
|
|
52
37
|
integer: () => integer,
|
|
53
38
|
isNotNull: () => isNotNull,
|
|
54
39
|
isNull: () => isNull,
|
|
55
40
|
like: () => like,
|
|
56
41
|
lt: () => lt,
|
|
57
42
|
lte: () => lte,
|
|
58
|
-
makeQueryAPI: () => makeQueryAPI,
|
|
59
|
-
ne: () => ne,
|
|
60
|
-
not: () => not,
|
|
61
|
-
notBetween: () => notBetween,
|
|
62
|
-
notExists: () => notExists,
|
|
63
|
-
notIlike: () => notIlike,
|
|
64
|
-
notInArray: () => notInArray,
|
|
65
|
-
numeric: () => numeric,
|
|
66
43
|
or: () => or,
|
|
67
|
-
primaryKey: () => primaryKey,
|
|
68
|
-
raw: () => raw,
|
|
69
44
|
real: () => real,
|
|
70
45
|
relations: () => relations,
|
|
71
|
-
|
|
72
|
-
text: () => text
|
|
73
|
-
timestamp: () => timestamp,
|
|
74
|
-
unique: () => unique,
|
|
75
|
-
uniqueIndex: () => uniqueIndex
|
|
46
|
+
sqliteTable: () => sqliteTable,
|
|
47
|
+
text: () => text
|
|
76
48
|
});
|
|
77
49
|
module.exports = __toCommonJS(index_exports);
|
|
78
50
|
|
|
79
|
-
// src/
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return { raw: raw2 };
|
|
86
|
-
}
|
|
87
|
-
function createColumn(params) {
|
|
88
|
-
const col = { ...params };
|
|
89
|
-
col.primaryKey = (opts) => {
|
|
90
|
-
col.isPrimaryKey = true;
|
|
91
|
-
if (opts?.autoIncrement) col.autoIncrement = true;
|
|
92
|
-
return col;
|
|
93
|
-
};
|
|
94
|
-
col.notNull = () => {
|
|
95
|
-
col.isNotNull = true;
|
|
96
|
-
return col;
|
|
97
|
-
};
|
|
98
|
-
col.default = (value) => {
|
|
99
|
-
col.defaultValue = value;
|
|
100
|
-
return col;
|
|
101
|
-
};
|
|
102
|
-
col.$type = () => col;
|
|
103
|
-
col.$defaultFn = (fn) => {
|
|
104
|
-
col.defaultFn = fn;
|
|
105
|
-
return col;
|
|
106
|
-
};
|
|
107
|
-
col.$default = (fn) => {
|
|
108
|
-
col.defaultFn = fn;
|
|
109
|
-
return col;
|
|
110
|
-
};
|
|
111
|
-
col.$onUpdate = (fn) => {
|
|
112
|
-
col.onUpdateFn = fn;
|
|
113
|
-
return col;
|
|
114
|
-
};
|
|
115
|
-
col.$onUpdateFn = (fn) => {
|
|
116
|
-
col.onUpdateFn = fn;
|
|
117
|
-
return col;
|
|
118
|
-
};
|
|
119
|
-
col.references = (target, actions) => {
|
|
120
|
-
const t = target();
|
|
121
|
-
col.references = {
|
|
122
|
-
table: t.tableName,
|
|
123
|
-
column: t.name,
|
|
124
|
-
onDelete: actions?.onDelete,
|
|
125
|
-
onUpdate: actions?.onUpdate
|
|
126
|
-
};
|
|
127
|
-
return col;
|
|
128
|
-
};
|
|
129
|
-
return col;
|
|
130
|
-
}
|
|
131
|
-
function text(nameOrConfig, maybeConfig) {
|
|
132
|
-
const name = typeof nameOrConfig === "string" ? nameOrConfig : "";
|
|
133
|
-
const config = typeof nameOrConfig === "string" ? maybeConfig : nameOrConfig;
|
|
134
|
-
const col = createColumn({
|
|
135
|
-
name,
|
|
136
|
-
type: "TEXT",
|
|
137
|
-
_dataType: ""
|
|
138
|
-
});
|
|
139
|
-
if (config?.enum) col.enumValues = config.enum;
|
|
140
|
-
if (config?.mode) col.mode = config.mode;
|
|
141
|
-
return col;
|
|
142
|
-
}
|
|
143
|
-
function integer(nameOrConfig, maybeConfig) {
|
|
144
|
-
const name = typeof nameOrConfig === "string" ? nameOrConfig : "";
|
|
145
|
-
const config = typeof nameOrConfig === "string" ? maybeConfig : nameOrConfig;
|
|
146
|
-
let dt = 0;
|
|
147
|
-
if (config?.mode === "boolean") dt = false;
|
|
148
|
-
if (config?.mode === "timestamp" || config?.mode === "timestamp_ms")
|
|
149
|
-
dt = /* @__PURE__ */ new Date();
|
|
150
|
-
const col = createColumn({
|
|
151
|
-
name,
|
|
152
|
-
type: "INTEGER",
|
|
153
|
-
mode: config?.mode ?? "number",
|
|
154
|
-
_dataType: dt
|
|
155
|
-
});
|
|
156
|
-
return col;
|
|
157
|
-
}
|
|
158
|
-
function real(name) {
|
|
159
|
-
return createColumn({
|
|
160
|
-
name: name ?? "",
|
|
161
|
-
type: "REAL",
|
|
162
|
-
_dataType: 0
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
function blob(nameOrConfig, maybeConfig) {
|
|
166
|
-
const name = typeof nameOrConfig === "string" ? nameOrConfig : "";
|
|
167
|
-
const config = typeof nameOrConfig === "string" ? maybeConfig : nameOrConfig;
|
|
168
|
-
let dt = new Uint8Array();
|
|
169
|
-
if (config?.mode === "bigint") dt = 0n;
|
|
170
|
-
if (config?.mode === "json") dt = void 0;
|
|
171
|
-
return createColumn({
|
|
172
|
-
name,
|
|
173
|
-
type: "BLOB",
|
|
174
|
-
mode: config?.mode,
|
|
175
|
-
_dataType: dt
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
function numeric(nameOrConfig, maybeConfig) {
|
|
179
|
-
const name = typeof nameOrConfig === "string" ? nameOrConfig : "";
|
|
180
|
-
const config = typeof nameOrConfig === "string" ? maybeConfig : nameOrConfig;
|
|
181
|
-
let dt = "";
|
|
182
|
-
if (config?.mode === "number") dt = 0;
|
|
183
|
-
if (config?.mode === "bigint") dt = 0n;
|
|
184
|
-
return createColumn({
|
|
185
|
-
name,
|
|
186
|
-
type: "NUMERIC",
|
|
187
|
-
mode: config?.mode,
|
|
188
|
-
_dataType: dt
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
function boolean(name) {
|
|
192
|
-
return createColumn({
|
|
193
|
-
name: name ?? "",
|
|
194
|
-
type: "INTEGER",
|
|
195
|
-
_dataType: false,
|
|
196
|
-
mode: "boolean"
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
function timestamp(name) {
|
|
200
|
-
return createColumn({
|
|
201
|
-
name: name ?? "",
|
|
202
|
-
type: "INTEGER",
|
|
203
|
-
_dataType: /* @__PURE__ */ new Date(),
|
|
204
|
-
mode: "timestamp"
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
function increments(name) {
|
|
208
|
-
return integer(name ?? "").primaryKey({
|
|
209
|
-
autoIncrement: true
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
function unique(name) {
|
|
213
|
-
return {
|
|
214
|
-
on: (...cols) => ({
|
|
215
|
-
name,
|
|
216
|
-
columns: cols.map((c) => c.name),
|
|
217
|
-
// runtime marker for DDL rendering
|
|
218
|
-
kind: "unique"
|
|
219
|
-
})
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
function primaryKey(opts) {
|
|
223
|
-
return {
|
|
224
|
-
name: opts.name,
|
|
225
|
-
columns: opts.columns.map((c) => c.name),
|
|
226
|
-
// runtime marker for DDL rendering
|
|
227
|
-
kind: "primaryKey"
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
function check(name, expr) {
|
|
231
|
-
return { name, expr };
|
|
232
|
-
}
|
|
233
|
-
function foreignKey(opts) {
|
|
234
|
-
const first = opts.columns[0];
|
|
235
|
-
return {
|
|
236
|
-
name: opts.name,
|
|
237
|
-
columns: opts.columns.map((c) => c.name),
|
|
238
|
-
foreignTable: first?.tableName || opts.foreignColumns[0]?.tableName || "",
|
|
239
|
-
foreignColumns: opts.foreignColumns.map((c) => c.name),
|
|
240
|
-
onDelete: opts.onDelete,
|
|
241
|
-
onUpdate: opts.onUpdate
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
function index(name) {
|
|
245
|
-
return {
|
|
246
|
-
on: (...cols) => ({
|
|
247
|
-
name,
|
|
248
|
-
columns: cols.map((c) => c.name)
|
|
249
|
-
}),
|
|
250
|
-
where: (expr) => ({ name, columns: [], where: expr })
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
function uniqueIndex(name) {
|
|
254
|
-
return {
|
|
255
|
-
on: (...cols) => ({
|
|
256
|
-
name,
|
|
257
|
-
columns: cols.map((c) => c.name),
|
|
258
|
-
unique: true
|
|
259
|
-
}),
|
|
260
|
-
where: (expr) => ({
|
|
51
|
+
// src/orm.ts
|
|
52
|
+
var SQLiteColumn = class _SQLiteColumn {
|
|
53
|
+
constructor(name, type, options = {}, mode) {
|
|
54
|
+
this.type = type;
|
|
55
|
+
this.options = options;
|
|
56
|
+
this._ = {
|
|
261
57
|
name,
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
function defineTable(tableName, schema, extras) {
|
|
269
|
-
const finalizedSchema = { ...schema };
|
|
270
|
-
for (const key of Object.keys(finalizedSchema)) {
|
|
271
|
-
const col = finalizedSchema[key];
|
|
272
|
-
if (!col.name || col.name === "") col.name = key;
|
|
273
|
-
col.tableName = tableName;
|
|
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
|
+
};
|
|
274
64
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
// omit PK columns
|
|
284
|
-
};
|
|
285
|
-
for (const [key, col] of Object.entries(finalizedSchema)) {
|
|
286
|
-
table[key] = col;
|
|
65
|
+
_;
|
|
66
|
+
notNull() {
|
|
67
|
+
return new _SQLiteColumn(
|
|
68
|
+
this._.name,
|
|
69
|
+
this.type,
|
|
70
|
+
{ ...this.options, notNull: true },
|
|
71
|
+
this._.mode
|
|
72
|
+
);
|
|
287
73
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
} else if (s.columns && (s.name || s.name === void 0)) {
|
|
296
|
-
if (s.columns && s.name !== void 0 && s.columns.length > 0) {
|
|
297
|
-
const pk = s;
|
|
298
|
-
if (pk.columns.length > 1 || pk.name && pk.name.length > 0) {
|
|
299
|
-
table._constraints.push(s);
|
|
300
|
-
} else {
|
|
301
|
-
table._constraints.push(s);
|
|
302
|
-
}
|
|
303
|
-
} else {
|
|
304
|
-
table._constraints.push(s);
|
|
305
|
-
}
|
|
306
|
-
} else if (s.expr) {
|
|
307
|
-
table._constraints.push(s);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
74
|
+
default(value) {
|
|
75
|
+
return new _SQLiteColumn(
|
|
76
|
+
this._.name,
|
|
77
|
+
this.type,
|
|
78
|
+
{ ...this.options, default: value },
|
|
79
|
+
this._.mode
|
|
80
|
+
);
|
|
310
81
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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
|
+
);
|
|
97
|
+
}
|
|
98
|
+
autoincrement() {
|
|
99
|
+
return new _SQLiteColumn(
|
|
100
|
+
this._.name,
|
|
101
|
+
this.type,
|
|
102
|
+
{ ...this.options, autoincrement: true },
|
|
103
|
+
this._.mode
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
unique() {
|
|
107
|
+
return new _SQLiteColumn(
|
|
108
|
+
this._.name,
|
|
109
|
+
this.type,
|
|
110
|
+
{ ...this.options, unique: true },
|
|
111
|
+
this._.mode
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
references(ref, column) {
|
|
115
|
+
return new _SQLiteColumn(
|
|
116
|
+
this._.name,
|
|
117
|
+
this.type,
|
|
118
|
+
{
|
|
119
|
+
...this.options,
|
|
120
|
+
references: {
|
|
121
|
+
table: ref,
|
|
122
|
+
column: ref._.columns[column]
|
|
337
123
|
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
function isColumn(value) {
|
|
344
|
-
return typeof value === "object" && value !== null && "_dataType" in value;
|
|
345
|
-
}
|
|
346
|
-
function getQualifiedName(column) {
|
|
347
|
-
if (column.tableName) return `${column.tableName}.${column.name}`;
|
|
348
|
-
return column.name;
|
|
349
|
-
}
|
|
350
|
-
function comparison(operator, column, value) {
|
|
351
|
-
return {
|
|
352
|
-
toSQL: () => {
|
|
353
|
-
if (isColumn(value)) {
|
|
354
|
-
return {
|
|
355
|
-
clause: `${getQualifiedName(column)} ${operator} ${getQualifiedName(
|
|
356
|
-
value
|
|
357
|
-
)}`,
|
|
358
|
-
bindings: []
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
return {
|
|
362
|
-
clause: `${getQualifiedName(column)} ${operator} ?`,
|
|
363
|
-
bindings: [value]
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
var and = (...conditions) => ({
|
|
369
|
-
toSQL: () => {
|
|
370
|
-
const parts = [];
|
|
371
|
-
const bindings = [];
|
|
372
|
-
for (const c of conditions) {
|
|
373
|
-
const s = c.toSQL();
|
|
374
|
-
parts.push(`(${s.clause})`);
|
|
375
|
-
bindings.push(...s.bindings);
|
|
376
|
-
}
|
|
377
|
-
return { clause: parts.join(" AND "), bindings };
|
|
124
|
+
},
|
|
125
|
+
this._.mode
|
|
126
|
+
);
|
|
378
127
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
parts.push(`(${s.clause})`);
|
|
387
|
-
bindings.push(...s.bindings);
|
|
388
|
-
}
|
|
389
|
-
return { clause: parts.join(" OR "), bindings };
|
|
128
|
+
$onUpdateFn(fn) {
|
|
129
|
+
return new _SQLiteColumn(
|
|
130
|
+
this._.name,
|
|
131
|
+
this.type,
|
|
132
|
+
{ ...this.options, $onUpdateFn: fn },
|
|
133
|
+
this._.mode
|
|
134
|
+
);
|
|
390
135
|
}
|
|
391
|
-
}
|
|
392
|
-
var
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
136
|
+
};
|
|
137
|
+
var text = (name) => new SQLiteColumn(name, "TEXT");
|
|
138
|
+
var integer = (name, config) => new SQLiteColumn(name, "INTEGER", {}, config?.mode || "default");
|
|
139
|
+
var real = (name) => new SQLiteColumn(name, "REAL");
|
|
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
|
|
148
|
+
};
|
|
396
149
|
}
|
|
150
|
+
};
|
|
151
|
+
var sqliteTable = (tableName, columns) => {
|
|
152
|
+
return new Table(tableName, columns);
|
|
153
|
+
};
|
|
154
|
+
var eq = (column, value) => ({
|
|
155
|
+
sql: `${column._.name} = ?`,
|
|
156
|
+
params: [value]
|
|
397
157
|
});
|
|
398
|
-
var
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
var gte = (column, value) => comparison(">=", column, value);
|
|
402
|
-
var lt = (column, value) => comparison("<", column, value);
|
|
403
|
-
var lte = (column, value) => comparison("<=", column, value);
|
|
404
|
-
var like = (column, value) => comparison("LIKE", column, value);
|
|
405
|
-
var ilike = (column, value) => ({
|
|
406
|
-
toSQL: () => {
|
|
407
|
-
const colExpr = `LOWER(${getQualifiedName(column)})`;
|
|
408
|
-
if (isColumn(value)) {
|
|
409
|
-
return {
|
|
410
|
-
clause: `${colExpr} LIKE LOWER(${getQualifiedName(value)})`,
|
|
411
|
-
bindings: []
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
return { clause: `${colExpr} LIKE LOWER(?)`, bindings: [value] };
|
|
415
|
-
}
|
|
158
|
+
var and = (...conditions) => ({
|
|
159
|
+
sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
|
|
160
|
+
params: conditions.flatMap((c) => c.params)
|
|
416
161
|
});
|
|
417
|
-
var
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (isColumn(value)) {
|
|
421
|
-
return {
|
|
422
|
-
clause: `${colExpr} NOT LIKE LOWER(${getQualifiedName(value)})`,
|
|
423
|
-
bindings: []
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
return { clause: `${colExpr} NOT LIKE LOWER(?)`, bindings: [value] };
|
|
427
|
-
}
|
|
162
|
+
var or = (...conditions) => ({
|
|
163
|
+
sql: conditions.map((c) => `(${c.sql})`).join(" OR "),
|
|
164
|
+
params: conditions.flatMap((c) => c.params)
|
|
428
165
|
});
|
|
429
|
-
var
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
bindings: []
|
|
433
|
-
})
|
|
166
|
+
var gt = (column, value) => ({
|
|
167
|
+
sql: `${column._.name} > ?`,
|
|
168
|
+
params: [value]
|
|
434
169
|
});
|
|
435
|
-
var
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
bindings: []
|
|
439
|
-
})
|
|
170
|
+
var gte = (column, value) => ({
|
|
171
|
+
sql: `${column._.name} >= ?`,
|
|
172
|
+
params: [value]
|
|
440
173
|
});
|
|
441
|
-
var
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
const [fromClause, fromBindings] = isColumn(from) ? [getQualifiedName(from), []] : ["?", [from]];
|
|
445
|
-
const [toClause, toBindings] = isColumn(to) ? [getQualifiedName(to), []] : ["?", [to]];
|
|
446
|
-
return {
|
|
447
|
-
clause: `${left} BETWEEN ${fromClause} AND ${toClause}`,
|
|
448
|
-
bindings: [...fromBindings, ...toBindings]
|
|
449
|
-
};
|
|
450
|
-
}
|
|
174
|
+
var lt = (column, value) => ({
|
|
175
|
+
sql: `${column._.name} < ?`,
|
|
176
|
+
params: [value]
|
|
451
177
|
});
|
|
452
|
-
var
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
const [fromClause, fromBindings] = isColumn(from) ? [getQualifiedName(from), []] : ["?", [from]];
|
|
456
|
-
const [toClause, toBindings] = isColumn(to) ? [getQualifiedName(to), []] : ["?", [to]];
|
|
457
|
-
return {
|
|
458
|
-
clause: `${left} NOT BETWEEN ${fromClause} AND ${toClause}`,
|
|
459
|
-
bindings: [...fromBindings, ...toBindings]
|
|
460
|
-
};
|
|
461
|
-
}
|
|
178
|
+
var lte = (column, value) => ({
|
|
179
|
+
sql: `${column._.name} <= ?`,
|
|
180
|
+
params: [value]
|
|
462
181
|
});
|
|
463
|
-
var
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if (Array.isArray(valuesOrQuery)) {
|
|
467
|
-
const placeholders = valuesOrQuery.map(() => "?").join(", ");
|
|
468
|
-
return {
|
|
469
|
-
clause: `${left} IN (${placeholders})`,
|
|
470
|
-
bindings: valuesOrQuery
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
const sq = valuesOrQuery.toSQL ? valuesOrQuery.toSQL() : valuesOrQuery.toSQL();
|
|
474
|
-
return { clause: `${left} IN (${sq.clause})`, bindings: sq.bindings };
|
|
475
|
-
}
|
|
182
|
+
var like = (column, pattern) => ({
|
|
183
|
+
sql: `${column._.name} LIKE ?`,
|
|
184
|
+
params: [pattern]
|
|
476
185
|
});
|
|
477
|
-
var
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
if (Array.isArray(valuesOrQuery)) {
|
|
481
|
-
const placeholders = valuesOrQuery.map(() => "?").join(", ");
|
|
482
|
-
return {
|
|
483
|
-
clause: `${left} NOT IN (${placeholders})`,
|
|
484
|
-
bindings: valuesOrQuery
|
|
485
|
-
};
|
|
486
|
-
}
|
|
487
|
-
const sq = valuesOrQuery.toSQL ? valuesOrQuery.toSQL() : valuesOrQuery.toSQL();
|
|
488
|
-
return { clause: `${left} NOT IN (${sq.clause})`, bindings: sq.bindings };
|
|
489
|
-
}
|
|
186
|
+
var isNull = (column) => ({
|
|
187
|
+
sql: `${column._.name} IS NULL`,
|
|
188
|
+
params: []
|
|
490
189
|
});
|
|
491
|
-
var
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
return { clause: `EXISTS (${sq.clause})`, bindings: sq.bindings };
|
|
495
|
-
}
|
|
190
|
+
var isNotNull = (column) => ({
|
|
191
|
+
sql: `${column._.name} IS NOT NULL`,
|
|
192
|
+
params: []
|
|
496
193
|
});
|
|
497
|
-
var
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
return { clause: `NOT EXISTS (${sq.clause})`, bindings: sq.bindings };
|
|
501
|
-
}
|
|
194
|
+
var inArray = (column, values) => ({
|
|
195
|
+
sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
|
|
196
|
+
params: values
|
|
502
197
|
});
|
|
503
|
-
var
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
_table = null;
|
|
513
|
-
_selectedColumns = [];
|
|
514
|
-
_joins = [];
|
|
515
|
-
_where = [];
|
|
516
|
-
_orderBy = [];
|
|
517
|
-
_limit = null;
|
|
518
|
-
_offset = null;
|
|
519
|
-
_groupBy = [];
|
|
520
|
-
_having = [];
|
|
521
|
-
_distinct = false;
|
|
522
|
-
_dbProvider;
|
|
523
|
-
constructor(dbProvider, fields) {
|
|
524
|
-
this._dbProvider = dbProvider;
|
|
525
|
-
if (fields) {
|
|
526
|
-
for (const [alias, col] of Object.entries(fields)) {
|
|
527
|
-
const sql2 = getQualifiedName(col);
|
|
528
|
-
this._selectedColumns.push({ sql: sql2, alias });
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
distinct() {
|
|
533
|
-
this._distinct = true;
|
|
534
|
-
return this;
|
|
535
|
-
}
|
|
536
|
-
select(fields) {
|
|
537
|
-
this._selectedColumns = [];
|
|
538
|
-
for (const [alias, expr] of Object.entries(fields)) {
|
|
539
|
-
if (typeof expr.toSQL === "function") {
|
|
540
|
-
const s = expr.toSQL();
|
|
541
|
-
this._selectedColumns.push({ sql: s.clause, alias });
|
|
542
|
-
} else {
|
|
543
|
-
this._selectedColumns.push({
|
|
544
|
-
sql: getQualifiedName(expr),
|
|
545
|
-
alias
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
}
|
|
198
|
+
var BaseQueryBuilder = class {
|
|
199
|
+
constructor(db) {
|
|
200
|
+
this.db = db;
|
|
201
|
+
}
|
|
202
|
+
query = "";
|
|
203
|
+
params = [];
|
|
204
|
+
where(condition) {
|
|
205
|
+
this.query += ` WHERE ${condition.sql}`;
|
|
206
|
+
this.params.push(...condition.params);
|
|
549
207
|
return this;
|
|
550
208
|
}
|
|
551
|
-
|
|
552
|
-
this.
|
|
209
|
+
orderBy(column, direction = "ASC") {
|
|
210
|
+
this.query += ` ORDER BY ${column._.name} ${direction}`;
|
|
553
211
|
return this;
|
|
554
212
|
}
|
|
555
|
-
|
|
556
|
-
this.
|
|
213
|
+
limit(count) {
|
|
214
|
+
this.query += ` LIMIT ${count}`;
|
|
557
215
|
return this;
|
|
558
216
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
const joinClause = `LEFT JOIN ${otherTable.tableName} ON ${onSql.clause}`;
|
|
562
|
-
this._joins.push(joinClause);
|
|
217
|
+
offset(count) {
|
|
218
|
+
this.query += ` OFFSET ${count}`;
|
|
563
219
|
return this;
|
|
564
220
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
return this;
|
|
572
|
-
}
|
|
573
|
-
having(...conditions) {
|
|
574
|
-
this._having.push(...conditions);
|
|
575
|
-
return this;
|
|
221
|
+
build() {
|
|
222
|
+
return {
|
|
223
|
+
sql: this.query,
|
|
224
|
+
params: this.params
|
|
225
|
+
};
|
|
576
226
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
}
|
|
585
|
-
return this;
|
|
227
|
+
};
|
|
228
|
+
var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
229
|
+
constructor(db, table, columns) {
|
|
230
|
+
super(db);
|
|
231
|
+
this.table = table;
|
|
232
|
+
this.columns = columns;
|
|
233
|
+
const columnNames = columns ? columns.map((c) => table._.columns[c]._.name) : ["*"];
|
|
234
|
+
this.query = `SELECT ${columnNames.join(", ")} FROM ${table._.name}`;
|
|
586
235
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
return this;
|
|
236
|
+
async execute() {
|
|
237
|
+
const { sql, params } = this.build();
|
|
238
|
+
return this.db.select(sql, ...params);
|
|
590
239
|
}
|
|
591
|
-
|
|
592
|
-
|
|
240
|
+
};
|
|
241
|
+
var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
242
|
+
constructor(db, table) {
|
|
243
|
+
super(db);
|
|
244
|
+
this.table = table;
|
|
245
|
+
this.query = `INSERT INTO ${table._.name}`;
|
|
246
|
+
}
|
|
247
|
+
dataSets = [];
|
|
248
|
+
values(data) {
|
|
249
|
+
const dataArray = Array.isArray(data) ? data : [data];
|
|
250
|
+
this.dataSets.push(...dataArray);
|
|
593
251
|
return this;
|
|
594
252
|
}
|
|
595
253
|
async execute() {
|
|
596
|
-
if (
|
|
597
|
-
throw new Error("
|
|
598
|
-
}
|
|
599
|
-
const db = await this._dbProvider();
|
|
600
|
-
const baseTableName = getTableName(this._table);
|
|
601
|
-
if (!baseTableName) {
|
|
602
|
-
throw new Error(
|
|
603
|
-
"Invalid table passed to select.from(): missing table name"
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
const bindings = [];
|
|
607
|
-
const selectList = this._selectedColumns.length > 0 ? this._selectedColumns.map((c) => c.alias ? `${c.sql} AS ${c.alias}` : c.sql).join(", ") : Object.values(this._table._schema).map((c) => `${baseTableName}.${c.name}`).join(", ");
|
|
608
|
-
let query = `SELECT ${this._distinct ? "DISTINCT " : ""}${selectList} FROM ${baseTableName}`;
|
|
609
|
-
if (this._joins.length > 0) query += ` ${this._joins.join(" ")}`;
|
|
610
|
-
if (this._where.length > 0) {
|
|
611
|
-
const whereClauses = this._where.map((condition) => {
|
|
612
|
-
const sql2 = condition.toSQL();
|
|
613
|
-
bindings.push(...sql2.bindings);
|
|
614
|
-
return `(${sql2.clause})`;
|
|
615
|
-
});
|
|
616
|
-
query += ` WHERE ${whereClauses.join(" AND ")}`;
|
|
617
|
-
}
|
|
618
|
-
if (this._groupBy.length > 0) {
|
|
619
|
-
query += ` GROUP BY ${this._groupBy.join(", ")}`;
|
|
620
|
-
}
|
|
621
|
-
if (this._having.length > 0) {
|
|
622
|
-
const havingClauses = this._having.map((h) => {
|
|
623
|
-
const sql2 = h.toSQL();
|
|
624
|
-
bindings.push(...sql2.bindings);
|
|
625
|
-
return `(${sql2.clause})`;
|
|
626
|
-
});
|
|
627
|
-
query += ` HAVING ${havingClauses.join(" AND ")}`;
|
|
628
|
-
}
|
|
629
|
-
if (this._orderBy.length > 0) {
|
|
630
|
-
const ordParts = [];
|
|
631
|
-
for (const ob of this._orderBy) {
|
|
632
|
-
if (typeof ob === "string") ordParts.push(ob);
|
|
633
|
-
else {
|
|
634
|
-
const s = ob.toSQL();
|
|
635
|
-
ordParts.push(s.clause);
|
|
636
|
-
bindings.push(...s.bindings);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
640
|
-
}
|
|
641
|
-
if (this._limit !== null) {
|
|
642
|
-
query += ` LIMIT ?`;
|
|
643
|
-
bindings.push(this._limit);
|
|
644
|
-
}
|
|
645
|
-
if (this._offset !== null) {
|
|
646
|
-
if (this._limit === null) query += ` LIMIT -1`;
|
|
647
|
-
query += ` OFFSET ?`;
|
|
648
|
-
bindings.push(this._offset);
|
|
649
|
-
}
|
|
650
|
-
return db.select(query, bindings);
|
|
651
|
-
}
|
|
652
|
-
async iterator() {
|
|
653
|
-
const rows = await this.execute();
|
|
654
|
-
async function* gen() {
|
|
655
|
-
for (const r of rows) yield r;
|
|
254
|
+
if (this.dataSets.length === 0) {
|
|
255
|
+
throw new Error("No data provided for insert");
|
|
656
256
|
}
|
|
657
|
-
|
|
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;
|
|
658
271
|
}
|
|
659
272
|
};
|
|
660
|
-
var
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
async getDb() {
|
|
673
|
-
return this._dbPromise;
|
|
674
|
-
}
|
|
675
|
-
// Deprecated: use configure()
|
|
676
|
-
configureQuery(tables, relations2) {
|
|
677
|
-
this.configure(tables, relations2);
|
|
678
|
-
}
|
|
679
|
-
select(fields) {
|
|
680
|
-
return new SelectQueryBuilder(this.getDb.bind(this), fields);
|
|
273
|
+
var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
274
|
+
constructor(db, table) {
|
|
275
|
+
super(db);
|
|
276
|
+
this.table = table;
|
|
277
|
+
this.query = `UPDATE ${table._.name}`;
|
|
278
|
+
}
|
|
279
|
+
updateData = {};
|
|
280
|
+
set(data) {
|
|
281
|
+
this.updateData = { ...this.updateData, ...data };
|
|
282
|
+
return this;
|
|
681
283
|
}
|
|
682
|
-
|
|
683
|
-
const
|
|
684
|
-
|
|
685
|
-
|
|
284
|
+
async execute() {
|
|
285
|
+
const entries = Object.entries(this.updateData);
|
|
286
|
+
const setClause = entries.map(([key]) => {
|
|
287
|
+
const column = this.table._.columns[key];
|
|
288
|
+
if (!column)
|
|
289
|
+
throw new Error(
|
|
290
|
+
`Column ${key} does not exist on table ${this.table._.name}`
|
|
291
|
+
);
|
|
292
|
+
return `${column._.name} = ?`;
|
|
293
|
+
}).join(", ");
|
|
294
|
+
this.query += ` SET ${setClause}`;
|
|
295
|
+
this.params.push(...entries.map(([, value]) => value));
|
|
296
|
+
const { sql, params } = this.build();
|
|
297
|
+
const result = await this.db.execute(sql, ...params);
|
|
298
|
+
return result.rowsAffected;
|
|
686
299
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
_selectSql = null;
|
|
694
|
-
_conflict = null;
|
|
695
|
-
_returning = null;
|
|
696
|
-
values(rowOrRows) {
|
|
697
|
-
this._rows = Array.isArray(rowOrRows) ? rowOrRows : [rowOrRows];
|
|
698
|
-
return this;
|
|
699
|
-
}
|
|
700
|
-
select(qb) {
|
|
701
|
-
if (qb.toSQL) this._selectSql = qb.toSQL();
|
|
702
|
-
else this._selectSql = qb.toSQL();
|
|
703
|
-
return this;
|
|
704
|
-
}
|
|
705
|
-
returning(fields) {
|
|
706
|
-
this._returning = fields ?? {};
|
|
707
|
-
return this;
|
|
708
|
-
}
|
|
709
|
-
$returningId() {
|
|
710
|
-
this._returning = "__RETURNING_ID__";
|
|
711
|
-
return this;
|
|
712
|
-
}
|
|
713
|
-
onConflictDoNothing(opts) {
|
|
714
|
-
const target = opts?.target ? Array.isArray(opts.target) ? opts.target.map((c) => c.name) : opts.target.name : void 0;
|
|
715
|
-
this._conflict = {
|
|
716
|
-
kind: "doNothing",
|
|
717
|
-
target,
|
|
718
|
-
where: opts?.where
|
|
719
|
-
};
|
|
720
|
-
return this;
|
|
721
|
-
}
|
|
722
|
-
onConflictDoUpdate(opts) {
|
|
723
|
-
const target = Array.isArray(opts.target) ? opts.target.map((c) => c.name) : opts.target.name;
|
|
724
|
-
this._conflict = {
|
|
725
|
-
kind: "doUpdate",
|
|
726
|
-
target,
|
|
727
|
-
targetWhere: opts.targetWhere,
|
|
728
|
-
set: opts.set,
|
|
729
|
-
setWhere: opts.setWhere
|
|
730
|
-
};
|
|
731
|
-
return this;
|
|
732
|
-
}
|
|
733
|
-
async execute() {
|
|
734
|
-
const db = await self.getDb();
|
|
735
|
-
const tableName = getTableName(this._table);
|
|
736
|
-
if (!tableName)
|
|
737
|
-
throw new Error(
|
|
738
|
-
"Invalid table passed to insert(): missing table name"
|
|
739
|
-
);
|
|
740
|
-
if (this._selectSql) {
|
|
741
|
-
const cols = Object.keys(this._table._schema);
|
|
742
|
-
let query = `INSERT INTO ${tableName} (${cols.join(", ")}) ${this._selectSql.clause}`;
|
|
743
|
-
const bindings = [...this._selectSql.bindings];
|
|
744
|
-
query += this._buildConflictClause();
|
|
745
|
-
const ret = await this._executeWithReturning(db, query, bindings);
|
|
746
|
-
return ret;
|
|
747
|
-
}
|
|
748
|
-
for (const data of this._rows) {
|
|
749
|
-
let coerceValue2 = function(col, value) {
|
|
750
|
-
if (col && col.mode === "boolean") {
|
|
751
|
-
return value ? 1 : 0;
|
|
752
|
-
}
|
|
753
|
-
if (value instanceof Date) {
|
|
754
|
-
if (col && col.mode === "timestamp_ms")
|
|
755
|
-
return value.getTime();
|
|
756
|
-
if (col && col.mode === "timestamp")
|
|
757
|
-
return Math.floor(value.getTime() / 1e3);
|
|
758
|
-
}
|
|
759
|
-
return value;
|
|
760
|
-
};
|
|
761
|
-
var coerceValue = coerceValue2;
|
|
762
|
-
const finalData = Object.assign({}, data);
|
|
763
|
-
const schema = this._table._schema;
|
|
764
|
-
for (const [key, col] of Object.entries(schema)) {
|
|
765
|
-
if (finalData[key] === void 0) {
|
|
766
|
-
if (col.defaultFn) {
|
|
767
|
-
finalData[key] = coerceValue2(col, col.defaultFn());
|
|
768
|
-
} else if (col.onUpdateFn && !this._rows.includes(data)) {
|
|
769
|
-
finalData[key] = coerceValue2(col, col.onUpdateFn());
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
const entries = Object.entries(finalData).filter(
|
|
774
|
-
([_, value]) => value !== void 0
|
|
775
|
-
);
|
|
776
|
-
const keys = entries.map(([k]) => {
|
|
777
|
-
const col = schema[k];
|
|
778
|
-
return col?.name ?? k;
|
|
779
|
-
});
|
|
780
|
-
const values = entries.map(([k, v]) => {
|
|
781
|
-
const col = schema[k];
|
|
782
|
-
return coerceValue2(col, v);
|
|
783
|
-
});
|
|
784
|
-
if (keys.length === 0) {
|
|
785
|
-
let query2 = `INSERT INTO ${tableName} DEFAULT VALUES`;
|
|
786
|
-
const bindings2 = [];
|
|
787
|
-
query2 += this._buildConflictClause();
|
|
788
|
-
const ret2 = await this._executeWithReturning(db, query2, bindings2);
|
|
789
|
-
if (ret2 !== void 0) return ret2;
|
|
790
|
-
continue;
|
|
791
|
-
}
|
|
792
|
-
const placeholders = values.map(() => "?").join(", ");
|
|
793
|
-
let query = `INSERT INTO ${tableName} (${keys.join(
|
|
794
|
-
", "
|
|
795
|
-
)}) VALUES (${placeholders})`;
|
|
796
|
-
const bindings = [...values];
|
|
797
|
-
query += this._buildConflictClause();
|
|
798
|
-
const ret = await this._executeWithReturning(db, query, bindings);
|
|
799
|
-
if (ret !== void 0) return ret;
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
_buildConflictClause() {
|
|
803
|
-
if (!this._conflict) return "";
|
|
804
|
-
if (this._conflict.kind === "doNothing") {
|
|
805
|
-
const tgt2 = this._conflict.target ? Array.isArray(this._conflict.target) ? `(${this._conflict.target.join(", ")})` : `(${this._conflict.target})` : "";
|
|
806
|
-
const where = this._conflict.where ? ` WHERE ${this._conflict.where.toSQL().clause}` : "";
|
|
807
|
-
return ` ON CONFLICT ${tgt2} DO NOTHING${where}`;
|
|
808
|
-
}
|
|
809
|
-
const c = this._conflict;
|
|
810
|
-
const tgt = Array.isArray(c.target) ? `(${c.target.join(", ")})` : `(${c.target})`;
|
|
811
|
-
const setKeys = Object.keys(c.set ?? {});
|
|
812
|
-
const setClause = setKeys.map((k) => {
|
|
813
|
-
const v = c.set[k];
|
|
814
|
-
return `${k} = ${typeof v === "object" && v && typeof v.toSQL === "function" ? v.toSQL().clause : "?"}`;
|
|
815
|
-
}).join(", ");
|
|
816
|
-
const targetWhere = c.targetWhere ? ` WHERE ${c.targetWhere.toSQL().clause}` : "";
|
|
817
|
-
const setWhere = c.setWhere ? ` WHERE ${c.setWhere.toSQL().clause}` : "";
|
|
818
|
-
return ` ON CONFLICT ${tgt}${targetWhere} DO UPDATE SET ${setClause}${setWhere}`;
|
|
819
|
-
}
|
|
820
|
-
async _executeWithReturning(db, query, bindings) {
|
|
821
|
-
if (this._returning === null) {
|
|
822
|
-
await db.execute(query, bindings);
|
|
823
|
-
return void 0;
|
|
824
|
-
}
|
|
825
|
-
if (this._returning === "__RETURNING_ID__") {
|
|
826
|
-
const rows = await db.select(`SELECT last_insert_rowid() as id`);
|
|
827
|
-
return rows.map((r) => ({ id: r.id }));
|
|
828
|
-
}
|
|
829
|
-
if (typeof this._returning === "object") {
|
|
830
|
-
const cols = Object.entries(
|
|
831
|
-
this._returning
|
|
832
|
-
).map(
|
|
833
|
-
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
834
|
-
).join(", ");
|
|
835
|
-
const retSql = `${query} RETURNING ${cols}`;
|
|
836
|
-
const res = await db.select(retSql, bindings);
|
|
837
|
-
return res;
|
|
838
|
-
}
|
|
839
|
-
return void 0;
|
|
840
|
-
}
|
|
841
|
-
}();
|
|
300
|
+
};
|
|
301
|
+
var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
302
|
+
constructor(db, table) {
|
|
303
|
+
super(db);
|
|
304
|
+
this.table = table;
|
|
305
|
+
this.query = `DELETE FROM ${table._.name}`;
|
|
842
306
|
}
|
|
843
|
-
|
|
844
|
-
const
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
_data = null;
|
|
848
|
-
_where = null;
|
|
849
|
-
_orderBy = [];
|
|
850
|
-
_limit = null;
|
|
851
|
-
_from = null;
|
|
852
|
-
_returning = null;
|
|
853
|
-
set(data) {
|
|
854
|
-
this._data = data;
|
|
855
|
-
return this;
|
|
856
|
-
}
|
|
857
|
-
where(cond) {
|
|
858
|
-
this._where = cond;
|
|
859
|
-
return this;
|
|
860
|
-
}
|
|
861
|
-
orderBy(...clauses) {
|
|
862
|
-
for (const c of clauses) {
|
|
863
|
-
if (!c) continue;
|
|
864
|
-
if (typeof c === "string") this._orderBy.push(c);
|
|
865
|
-
else if (typeof c.toSQL === "function")
|
|
866
|
-
this._orderBy.push(c);
|
|
867
|
-
else this._orderBy.push(getQualifiedName(c));
|
|
868
|
-
}
|
|
869
|
-
return this;
|
|
870
|
-
}
|
|
871
|
-
limit(n) {
|
|
872
|
-
this._limit = n;
|
|
873
|
-
return this;
|
|
874
|
-
}
|
|
875
|
-
from(tbl) {
|
|
876
|
-
this._from = tbl;
|
|
877
|
-
return this;
|
|
878
|
-
}
|
|
879
|
-
returning(fields) {
|
|
880
|
-
this._returning = fields ?? {};
|
|
881
|
-
return this;
|
|
882
|
-
}
|
|
883
|
-
async execute() {
|
|
884
|
-
if (!this._data)
|
|
885
|
-
throw new Error("Update requires set() before execute()");
|
|
886
|
-
const db = await self.getDb();
|
|
887
|
-
const tableName = getTableName(this._table);
|
|
888
|
-
if (!tableName)
|
|
889
|
-
throw new Error(
|
|
890
|
-
"Invalid table passed to update(): missing table name"
|
|
891
|
-
);
|
|
892
|
-
const schema = this._table._schema;
|
|
893
|
-
const dataToSet = { ...this._data };
|
|
894
|
-
for (const [key, col] of Object.entries(schema)) {
|
|
895
|
-
if (!(key in dataToSet) && col.onUpdateFn) {
|
|
896
|
-
const v = col.onUpdateFn();
|
|
897
|
-
if (col.mode === "boolean") dataToSet[key] = v ? 1 : 0;
|
|
898
|
-
else if (v instanceof Date) {
|
|
899
|
-
if (col.mode === "timestamp_ms")
|
|
900
|
-
dataToSet[key] = v.getTime();
|
|
901
|
-
else if (col.mode === "timestamp")
|
|
902
|
-
dataToSet[key] = Math.floor(v.getTime() / 1e3);
|
|
903
|
-
else dataToSet[key] = v;
|
|
904
|
-
} else dataToSet[key] = v;
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
const setParts = [];
|
|
908
|
-
const bindings = [];
|
|
909
|
-
for (const [k, v] of Object.entries(dataToSet)) {
|
|
910
|
-
if (v === void 0) continue;
|
|
911
|
-
if (v && typeof v === "object" && typeof v.toSQL === "function") {
|
|
912
|
-
const s = v.toSQL();
|
|
913
|
-
const colName = schema[k]?.name ?? k;
|
|
914
|
-
setParts.push(`${colName} = ${s.clause}`);
|
|
915
|
-
bindings.push(...s.bindings);
|
|
916
|
-
} else {
|
|
917
|
-
const colName = schema[k]?.name ?? k;
|
|
918
|
-
let val = v;
|
|
919
|
-
const col = schema[k];
|
|
920
|
-
if (col && col.mode === "boolean") val = v ? 1 : 0;
|
|
921
|
-
else if (v instanceof Date) {
|
|
922
|
-
if (col && col.mode === "timestamp_ms")
|
|
923
|
-
val = v.getTime();
|
|
924
|
-
else if (col && col.mode === "timestamp")
|
|
925
|
-
val = Math.floor(v.getTime() / 1e3);
|
|
926
|
-
}
|
|
927
|
-
setParts.push(`${colName} = ?`);
|
|
928
|
-
bindings.push(val);
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
let query = `UPDATE ${tableName} SET ${setParts.join(", ")}`;
|
|
932
|
-
if (this._from) query += ` FROM ${this._from.tableName}`;
|
|
933
|
-
if (this._where) {
|
|
934
|
-
if (typeof this._where.toSQL === "function") {
|
|
935
|
-
const sql2 = this._where.toSQL();
|
|
936
|
-
query += ` WHERE ${sql2.clause}`;
|
|
937
|
-
bindings.push(...sql2.bindings);
|
|
938
|
-
} else {
|
|
939
|
-
const entries = Object.entries(this._where);
|
|
940
|
-
if (entries.length > 0) {
|
|
941
|
-
query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
|
|
942
|
-
bindings.push(...entries.map(([, v]) => v));
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
if (this._orderBy.length > 0) {
|
|
947
|
-
const ordParts = [];
|
|
948
|
-
for (const ob of this._orderBy) {
|
|
949
|
-
if (typeof ob === "string") ordParts.push(ob);
|
|
950
|
-
else {
|
|
951
|
-
const s = ob.toSQL();
|
|
952
|
-
ordParts.push(s.clause);
|
|
953
|
-
bindings.push(...s.bindings);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
957
|
-
}
|
|
958
|
-
if (this._limit !== null) {
|
|
959
|
-
query += ` LIMIT ?`;
|
|
960
|
-
bindings.push(this._limit);
|
|
961
|
-
}
|
|
962
|
-
if (this._returning) {
|
|
963
|
-
const cols = Object.entries(
|
|
964
|
-
this._returning
|
|
965
|
-
).map(
|
|
966
|
-
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
967
|
-
).join(", ");
|
|
968
|
-
const retSql = `${query} RETURNING ${cols}`;
|
|
969
|
-
return await db.select(retSql, bindings);
|
|
970
|
-
}
|
|
971
|
-
await db.execute(query, bindings);
|
|
972
|
-
}
|
|
973
|
-
}();
|
|
307
|
+
async execute() {
|
|
308
|
+
const { sql, params } = this.build();
|
|
309
|
+
const result = await this.db.execute(sql, ...params);
|
|
310
|
+
return result.rowsAffected;
|
|
974
311
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
_returning = null;
|
|
983
|
-
where(cond) {
|
|
984
|
-
this._where = cond;
|
|
985
|
-
return this;
|
|
986
|
-
}
|
|
987
|
-
orderBy(...clauses) {
|
|
988
|
-
for (const c of clauses) {
|
|
989
|
-
if (!c) continue;
|
|
990
|
-
if (typeof c === "string") this._orderBy.push(c);
|
|
991
|
-
else if (typeof c.toSQL === "function")
|
|
992
|
-
this._orderBy.push(c);
|
|
993
|
-
else this._orderBy.push(getQualifiedName(c));
|
|
994
|
-
}
|
|
995
|
-
return this;
|
|
996
|
-
}
|
|
997
|
-
limit(n) {
|
|
998
|
-
this._limit = n;
|
|
999
|
-
return this;
|
|
1000
|
-
}
|
|
1001
|
-
returning(fields) {
|
|
1002
|
-
this._returning = fields ?? {};
|
|
1003
|
-
return this;
|
|
1004
|
-
}
|
|
1005
|
-
async execute() {
|
|
1006
|
-
const db = await self.getDb();
|
|
1007
|
-
const tableName = getTableName(this._table);
|
|
1008
|
-
if (!tableName)
|
|
1009
|
-
throw new Error(
|
|
1010
|
-
"Invalid table passed to delete(): missing table name"
|
|
1011
|
-
);
|
|
1012
|
-
let query = `DELETE FROM ${tableName}`;
|
|
1013
|
-
const bindings = [];
|
|
1014
|
-
if (this._where) {
|
|
1015
|
-
if (typeof this._where.toSQL === "function") {
|
|
1016
|
-
const sql2 = this._where.toSQL();
|
|
1017
|
-
query += ` WHERE ${sql2.clause}`;
|
|
1018
|
-
bindings.push(...sql2.bindings);
|
|
1019
|
-
} else {
|
|
1020
|
-
const entries = Object.entries(this._where);
|
|
1021
|
-
if (entries.length > 0) {
|
|
1022
|
-
const schema = this._table._schema;
|
|
1023
|
-
query += ` WHERE ${entries.map(([k]) => `${schema[k]?.name ?? k} = ?`).join(" AND ")}`;
|
|
1024
|
-
bindings.push(...entries.map(([, v]) => v));
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
if (this._orderBy.length > 0) {
|
|
1029
|
-
const ordParts = [];
|
|
1030
|
-
for (const ob of this._orderBy) {
|
|
1031
|
-
if (typeof ob === "string") ordParts.push(ob);
|
|
1032
|
-
else {
|
|
1033
|
-
const s = ob.toSQL();
|
|
1034
|
-
ordParts.push(s.clause);
|
|
1035
|
-
bindings.push(...s.bindings);
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
query += ` ORDER BY ${ordParts.join(", ")}`;
|
|
1039
|
-
}
|
|
1040
|
-
if (this._limit !== null) {
|
|
1041
|
-
query += ` LIMIT ?`;
|
|
1042
|
-
bindings.push(this._limit);
|
|
1043
|
-
}
|
|
1044
|
-
if (this._returning) {
|
|
1045
|
-
const cols = Object.entries(
|
|
1046
|
-
this._returning
|
|
1047
|
-
).map(
|
|
1048
|
-
([alias, col]) => `${col.tableName}.${col.name} AS ${alias}`
|
|
1049
|
-
).join(", ");
|
|
1050
|
-
const retSql = `${query} RETURNING ${cols}`;
|
|
1051
|
-
return await db.select(retSql, bindings);
|
|
1052
|
-
}
|
|
1053
|
-
await db.execute(query, bindings);
|
|
312
|
+
};
|
|
313
|
+
var TauriORM = class {
|
|
314
|
+
constructor(db, schema = void 0) {
|
|
315
|
+
this.db = db;
|
|
316
|
+
if (schema) {
|
|
317
|
+
for (const table of Object.values(schema)) {
|
|
318
|
+
this.tables.set(table._.name, table);
|
|
1054
319
|
}
|
|
1055
|
-
}();
|
|
1056
|
-
}
|
|
1057
|
-
// legacy direct methods removed in favor of builder APIs
|
|
1058
|
-
// legacy direct methods removed in favor of builder APIs
|
|
1059
|
-
// legacy direct methods removed in favor of builder APIs
|
|
1060
|
-
async run(query, bindings = []) {
|
|
1061
|
-
const db = await this.getDb();
|
|
1062
|
-
await db.execute(query, bindings);
|
|
1063
|
-
}
|
|
1064
|
-
// --- Migrations API ---
|
|
1065
|
-
formatDefaultValue(col) {
|
|
1066
|
-
const dv = col.defaultValue;
|
|
1067
|
-
if (dv === void 0) return null;
|
|
1068
|
-
if (dv && typeof dv === "object" && "raw" in dv) {
|
|
1069
|
-
return dv.raw;
|
|
1070
|
-
}
|
|
1071
|
-
if (dv instanceof Date) {
|
|
1072
|
-
const isMs = col.mode === "timestamp_ms";
|
|
1073
|
-
const num = isMs ? dv.getTime() : Math.floor(dv.getTime() / 1e3);
|
|
1074
|
-
return String(num);
|
|
1075
|
-
}
|
|
1076
|
-
if (col.mode === "boolean") {
|
|
1077
|
-
return String(dv ? 1 : 0);
|
|
1078
|
-
}
|
|
1079
|
-
if (typeof dv === "string") {
|
|
1080
|
-
return `'${dv.replace(/'/g, "''")}'`;
|
|
1081
320
|
}
|
|
1082
|
-
return String(dv);
|
|
1083
321
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
const formatted = this.formatDefaultValue(col);
|
|
1097
|
-
if (formatted !== null) def += ` DEFAULT ${formatted}`;
|
|
1098
|
-
}
|
|
1099
|
-
if (col.references && !col.isPrimaryKey) {
|
|
1100
|
-
def += ` REFERENCES ${col.references.table} (${col.references.column})`;
|
|
1101
|
-
if (col.references.onDelete)
|
|
1102
|
-
def += ` ON DELETE ${col.references.onDelete.toUpperCase()}`;
|
|
1103
|
-
if (col.references.onUpdate)
|
|
1104
|
-
def += ` ON UPDATE ${col.references.onUpdate.toUpperCase()}`;
|
|
1105
|
-
}
|
|
1106
|
-
return def;
|
|
1107
|
-
});
|
|
1108
|
-
const tableConstraints = [];
|
|
1109
|
-
const constraints = table._constraints;
|
|
1110
|
-
if (constraints && constraints.length) {
|
|
1111
|
-
for (const spec of constraints) {
|
|
1112
|
-
if (spec.expr) {
|
|
1113
|
-
const name = spec.name;
|
|
1114
|
-
const expr = spec.expr.raw ?? spec.expr?.raw ?? String(spec.expr);
|
|
1115
|
-
tableConstraints.push(
|
|
1116
|
-
name ? `CONSTRAINT ${name} CHECK (${expr})` : `CHECK (${expr})`
|
|
1117
|
-
);
|
|
1118
|
-
continue;
|
|
322
|
+
tables = /* @__PURE__ */ new Map();
|
|
323
|
+
async migrate() {
|
|
324
|
+
for (const table of this.tables.values()) {
|
|
325
|
+
const columnsSql = Object.entries(table._.columns).map(([name, col]) => {
|
|
326
|
+
let sql = `${col._.name} ${col.type}`;
|
|
327
|
+
if (col.options.primaryKey) sql += " PRIMARY KEY";
|
|
328
|
+
if (col._.autoincrement) sql += " AUTOINCREMENT";
|
|
329
|
+
if (col._.notNull) sql += " NOT NULL";
|
|
330
|
+
if (col.options.unique) sql += " UNIQUE";
|
|
331
|
+
if (col.options.default !== void 0) {
|
|
332
|
+
const value = col.options.default;
|
|
333
|
+
sql += ` DEFAULT ${typeof value === "string" ? `'${value}'` : value}`;
|
|
1119
334
|
}
|
|
1120
|
-
if (
|
|
1121
|
-
|
|
1122
|
-
const cols = spec.columns.join(", ");
|
|
1123
|
-
const fTable = spec.foreignTable;
|
|
1124
|
-
const fCols = spec.foreignColumns.join(", ");
|
|
1125
|
-
let clause = `${name ? `CONSTRAINT ${name} ` : ""}FOREIGN KEY (${cols}) REFERENCES ${fTable} (${fCols})`;
|
|
1126
|
-
if (spec.onDelete)
|
|
1127
|
-
clause += ` ON DELETE ${String(
|
|
1128
|
-
spec.onDelete
|
|
1129
|
-
).toUpperCase()}`;
|
|
1130
|
-
if (spec.onUpdate)
|
|
1131
|
-
clause += ` ON UPDATE ${String(
|
|
1132
|
-
spec.onUpdate
|
|
1133
|
-
).toUpperCase()}`;
|
|
1134
|
-
tableConstraints.push(clause);
|
|
1135
|
-
continue;
|
|
335
|
+
if (col.options.references) {
|
|
336
|
+
sql += ` REFERENCES ${col.options.references.table._.name}(${col.options.references.column._.name})`;
|
|
1136
337
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
if (isPk) {
|
|
1142
|
-
tableConstraints.push(
|
|
1143
|
-
name ? `CONSTRAINT ${name} PRIMARY KEY (${cols})` : `PRIMARY KEY (${cols})`
|
|
1144
|
-
);
|
|
1145
|
-
} else {
|
|
1146
|
-
tableConstraints.push(
|
|
1147
|
-
name ? `CONSTRAINT ${name} UNIQUE (${cols})` : `UNIQUE (${cols})`
|
|
1148
|
-
);
|
|
1149
|
-
}
|
|
1150
|
-
continue;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
338
|
+
return sql;
|
|
339
|
+
}).join(", ");
|
|
340
|
+
const createSql = `CREATE TABLE IF NOT EXISTS ${table._.name} (${columnsSql})`;
|
|
341
|
+
await this.db.execute(createSql);
|
|
1153
342
|
}
|
|
1154
|
-
const parts = [...columnDefs, ...tableConstraints];
|
|
1155
|
-
return `CREATE TABLE IF NOT EXISTS ${tableName} (${parts.join(", ")});`;
|
|
1156
343
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
await this.run(sql2);
|
|
1160
|
-
await this.createIndexesForTable(table);
|
|
1161
|
-
}
|
|
1162
|
-
async createTablesIfNotExist(tables) {
|
|
1163
|
-
for (const t of tables) {
|
|
1164
|
-
await this.createTableIfNotExists(t);
|
|
1165
|
-
}
|
|
344
|
+
select(table, columns) {
|
|
345
|
+
return new SelectQueryBuilder(this.db, table, columns);
|
|
1166
346
|
}
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
const indexes = table._indexes || [];
|
|
1170
|
-
const stmts = [];
|
|
1171
|
-
for (const idx of indexes) {
|
|
1172
|
-
const unique2 = idx.unique ? "UNIQUE " : "";
|
|
1173
|
-
if (!idx.name) continue;
|
|
1174
|
-
const colList = Array.isArray(idx.columns) ? idx.columns : [];
|
|
1175
|
-
if (colList.length === 0) continue;
|
|
1176
|
-
const cols = `(${colList.join(", ")})`;
|
|
1177
|
-
const where = idx.where?.raw ? ` WHERE ${idx.where.raw}` : "";
|
|
1178
|
-
stmts.push(
|
|
1179
|
-
`CREATE ${unique2}INDEX IF NOT EXISTS ${idx.name} ON ${tableName} ${cols}${where};`
|
|
1180
|
-
);
|
|
1181
|
-
}
|
|
1182
|
-
return stmts;
|
|
1183
|
-
}
|
|
1184
|
-
async createIndexesForTable(table) {
|
|
1185
|
-
const stmts = this.generateCreateIndexSqls(table);
|
|
1186
|
-
for (const s of stmts) await this.run(s);
|
|
1187
|
-
}
|
|
1188
|
-
async ensureMigrationsTable() {
|
|
1189
|
-
await this.run(
|
|
1190
|
-
`CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)`
|
|
1191
|
-
);
|
|
1192
|
-
}
|
|
1193
|
-
async hasMigration(name) {
|
|
1194
|
-
const db = await this.getDb();
|
|
1195
|
-
const rows = await db.select(
|
|
1196
|
-
`SELECT name FROM _migrations WHERE name = ?`,
|
|
1197
|
-
[name]
|
|
1198
|
-
);
|
|
1199
|
-
return Array.isArray(rows) && rows.length > 0;
|
|
1200
|
-
}
|
|
1201
|
-
async recordMigration(name) {
|
|
1202
|
-
const db = await this.getDb();
|
|
1203
|
-
await db.execute(
|
|
1204
|
-
`INSERT INTO _migrations (name, applied_at) VALUES (?, ?)`,
|
|
1205
|
-
[name, Date.now()]
|
|
1206
|
-
);
|
|
1207
|
-
}
|
|
1208
|
-
async migrate(tables, options) {
|
|
1209
|
-
const track = options?.track ?? true;
|
|
1210
|
-
if (track) {
|
|
1211
|
-
await this.ensureMigrationsTable();
|
|
1212
|
-
}
|
|
1213
|
-
await this.forcePushForTables(tables, { preserveData: true });
|
|
1214
|
-
if (track) {
|
|
1215
|
-
const name = options?.name ?? `init:${tables.map((t) => t.tableName).join(",")}`;
|
|
1216
|
-
const already = await this.hasMigration(name);
|
|
1217
|
-
if (!already) await this.recordMigration(name);
|
|
1218
|
-
}
|
|
347
|
+
insert(table) {
|
|
348
|
+
return new InsertQueryBuilder(this.db, table);
|
|
1219
349
|
}
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
this._tables = tables;
|
|
1223
|
-
this._relations = relDefs ?? {};
|
|
1224
|
-
this.query = makeQueryAPI(
|
|
1225
|
-
tables,
|
|
1226
|
-
this._relations ?? {},
|
|
1227
|
-
this.getDb.bind(this)
|
|
1228
|
-
);
|
|
1229
|
-
return this;
|
|
350
|
+
update(table) {
|
|
351
|
+
return new UpdateQueryBuilder(this.db, table);
|
|
1230
352
|
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
if (!this._tables)
|
|
1234
|
-
throw new Error("No tables configured. Call db.configure({...}) first.");
|
|
1235
|
-
await this.migrate(Object.values(this._tables), options);
|
|
1236
|
-
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
353
|
+
delete(table) {
|
|
354
|
+
return new DeleteQueryBuilder(this.db, table);
|
|
1237
355
|
}
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
)
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
);
|
|
1248
|
-
const existingNames = existing.map((r) => r.name);
|
|
1249
|
-
const extraTables = existingNames.filter(
|
|
1250
|
-
(n) => !configuredNames.includes(n)
|
|
1251
|
-
);
|
|
1252
|
-
const missingTables = configuredNames.filter(
|
|
1253
|
-
(n) => !existingNames.includes(n)
|
|
1254
|
-
);
|
|
1255
|
-
const tables = {};
|
|
1256
|
-
for (const tbl of Object.values(this._tables)) {
|
|
1257
|
-
const tableName = getTableName(tbl);
|
|
1258
|
-
if (!existingNames.includes(tableName)) {
|
|
1259
|
-
tables[tableName] = {
|
|
1260
|
-
missingColumns: Object.keys(tbl._schema),
|
|
1261
|
-
extraColumns: [],
|
|
1262
|
-
changedColumns: []
|
|
1263
|
-
};
|
|
1264
|
-
continue;
|
|
1265
|
-
}
|
|
1266
|
-
const cols = await dbi.select(`PRAGMA table_info('${tableName}')`);
|
|
1267
|
-
const colMap = new Map(cols.map((c) => [c.name, c]));
|
|
1268
|
-
const modelCols = Object.values(
|
|
1269
|
-
tbl._schema
|
|
1270
|
-
);
|
|
1271
|
-
const missingColumns = [];
|
|
1272
|
-
const extraColumns = [];
|
|
1273
|
-
const changedColumns = [];
|
|
1274
|
-
const modelNamesSet = new Set(modelCols.map((c) => c.name));
|
|
1275
|
-
for (const m of modelCols) {
|
|
1276
|
-
const info = colMap.get(m.name);
|
|
1277
|
-
if (!info) {
|
|
1278
|
-
missingColumns.push(m.name);
|
|
1279
|
-
continue;
|
|
1280
|
-
}
|
|
1281
|
-
const diffs = {};
|
|
1282
|
-
if ((info.type || "").toUpperCase() !== m.type.toUpperCase())
|
|
1283
|
-
diffs.type = true;
|
|
1284
|
-
if (!!info.pk !== !!m.isPrimaryKey) diffs.pk = true;
|
|
1285
|
-
if (!!info.notnull !== !!m.isNotNull) diffs.notNull = true;
|
|
1286
|
-
const modelDv = m.defaultValue && typeof m.defaultValue === "object" && m.defaultValue.raw ? m.defaultValue.raw : m.defaultValue ?? null;
|
|
1287
|
-
if ((info.dflt_value ?? null) !== modelDv)
|
|
1288
|
-
diffs.default = true;
|
|
1289
|
-
if (Object.keys(diffs).length)
|
|
1290
|
-
changedColumns.push({ name: m.name, diffs });
|
|
1291
|
-
}
|
|
1292
|
-
for (const c of cols)
|
|
1293
|
-
if (!modelNamesSet.has(c.name)) extraColumns.push(c.name);
|
|
1294
|
-
tables[tableName] = { missingColumns, extraColumns, changedColumns };
|
|
356
|
+
async transaction(callback) {
|
|
357
|
+
await this.db.execute("BEGIN TRANSACTION");
|
|
358
|
+
try {
|
|
359
|
+
const result = await callback(this);
|
|
360
|
+
await this.db.execute("COMMIT");
|
|
361
|
+
return result;
|
|
362
|
+
} catch (error) {
|
|
363
|
+
await this.db.execute("ROLLBACK");
|
|
364
|
+
throw error;
|
|
1295
365
|
}
|
|
1296
|
-
return { extraTables, missingTables, tables };
|
|
1297
|
-
}
|
|
1298
|
-
async generate() {
|
|
1299
|
-
if (!this._tables) throw new Error("No tables configured.");
|
|
1300
|
-
return {
|
|
1301
|
-
statements: Object.values(this._tables).map(
|
|
1302
|
-
(t) => this.buildCreateTableSQL(t)
|
|
1303
|
-
)
|
|
1304
|
-
};
|
|
1305
|
-
}
|
|
1306
|
-
async migrateCli(opts) {
|
|
1307
|
-
return this.migrateConfigured(opts);
|
|
1308
|
-
}
|
|
1309
|
-
async push(opts) {
|
|
1310
|
-
return this.forcePush(opts);
|
|
1311
|
-
}
|
|
1312
|
-
async pull() {
|
|
1313
|
-
return this.pullSchema();
|
|
1314
|
-
}
|
|
1315
|
-
async studio() {
|
|
1316
|
-
const dbi = await this.getDb();
|
|
1317
|
-
return { driver: "sqlite", path: dbi.path };
|
|
1318
366
|
}
|
|
1319
367
|
// --- Schema detection / signature ---
|
|
1320
368
|
async ensureSchemaMeta() {
|
|
1321
|
-
await this.
|
|
369
|
+
await this.db.execute(
|
|
1322
370
|
`CREATE TABLE IF NOT EXISTS _schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`
|
|
1323
371
|
);
|
|
1324
372
|
}
|
|
1325
373
|
async getSchemaMeta(key) {
|
|
1326
|
-
const dbi = await this.getDb();
|
|
1327
374
|
await this.ensureSchemaMeta();
|
|
1328
|
-
const rows = await
|
|
375
|
+
const rows = await this.db.select(
|
|
1329
376
|
`SELECT value FROM _schema_meta WHERE key = ?`,
|
|
1330
377
|
[key]
|
|
1331
378
|
);
|
|
1332
379
|
return rows?.[0]?.value ?? null;
|
|
1333
380
|
}
|
|
1334
381
|
async setSchemaMeta(key, value) {
|
|
1335
|
-
const dbi = await this.getDb();
|
|
1336
382
|
await this.ensureSchemaMeta();
|
|
1337
|
-
await
|
|
383
|
+
await this.db.execute(
|
|
1338
384
|
`INSERT INTO _schema_meta(key, value) VALUES(?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`,
|
|
1339
385
|
[key, value]
|
|
1340
386
|
);
|
|
1341
387
|
}
|
|
1342
388
|
normalizeColumn(col) {
|
|
1343
389
|
return {
|
|
1344
|
-
name: col.name,
|
|
390
|
+
name: col._.name,
|
|
1345
391
|
type: col.type,
|
|
1346
|
-
pk: !!col.
|
|
1347
|
-
ai: !!col.
|
|
1348
|
-
nn: !!col.
|
|
1349
|
-
dv: col.
|
|
392
|
+
pk: !!col.options.primaryKey,
|
|
393
|
+
ai: !!col._.autoincrement,
|
|
394
|
+
nn: !!col._.notNull,
|
|
395
|
+
dv: col.options.default && typeof col.options.default === "object" && col.options.default.raw ? { raw: col.options.default.raw } : col.options.default ?? null
|
|
1350
396
|
};
|
|
1351
397
|
}
|
|
1352
398
|
computeModelSignature() {
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
tbl._schema
|
|
1357
|
-
).map((c) => this.normalizeColumn(c)).sort((a, b) => a.name.localeCompare(b.name));
|
|
1358
|
-
return { table: tbl.tableName, columns: cols };
|
|
399
|
+
const entries = Array.from(this.tables.values()).map((tbl) => {
|
|
400
|
+
const cols = Object.values(tbl._.columns).map((c) => this.normalizeColumn(c)).sort((a, b) => a.name.localeCompare(b.name));
|
|
401
|
+
return { table: tbl._.name, columns: cols };
|
|
1359
402
|
});
|
|
1360
403
|
entries.sort((a, b) => a.table.localeCompare(b.table));
|
|
1361
404
|
return JSON.stringify(entries);
|
|
@@ -1363,22 +406,15 @@ var TauriORM = class {
|
|
|
1363
406
|
getSchemaSignature() {
|
|
1364
407
|
return this.computeModelSignature();
|
|
1365
408
|
}
|
|
1366
|
-
async printSchemaDiff() {
|
|
1367
|
-
const diff = await this.diffSchema();
|
|
1368
|
-
console.log("Schema diff:", JSON.stringify(diff, null, 2));
|
|
1369
|
-
}
|
|
1370
409
|
async isSchemaDirty() {
|
|
1371
410
|
const sig = this.computeModelSignature();
|
|
1372
411
|
const stored = await this.getSchemaMeta("schema_signature");
|
|
1373
412
|
return { dirty: sig !== stored, current: sig, stored };
|
|
1374
413
|
}
|
|
1375
|
-
async migrateIfDirty(
|
|
414
|
+
async migrateIfDirty() {
|
|
1376
415
|
const status = await this.isSchemaDirty();
|
|
1377
|
-
if (!this._tables) throw new Error("No tables configured.");
|
|
1378
416
|
if (status.dirty) {
|
|
1379
|
-
await this.
|
|
1380
|
-
preserveData: true
|
|
1381
|
-
});
|
|
417
|
+
await this.migrate();
|
|
1382
418
|
await this.setSchemaMeta(
|
|
1383
419
|
"schema_signature",
|
|
1384
420
|
this.computeModelSignature()
|
|
@@ -1387,455 +423,46 @@ var TauriORM = class {
|
|
|
1387
423
|
}
|
|
1388
424
|
return false;
|
|
1389
425
|
}
|
|
1390
|
-
// Pull current DB schema (minimal) for configured tables
|
|
1391
|
-
async pullSchema() {
|
|
1392
|
-
if (!this._tables) throw new Error("No tables configured.");
|
|
1393
|
-
const dbi = await this.getDb();
|
|
1394
|
-
const result = {};
|
|
1395
|
-
for (const tbl of Object.values(this._tables)) {
|
|
1396
|
-
const name = tbl.tableName;
|
|
1397
|
-
const cols = await dbi.select(`PRAGMA table_info('${name}')`);
|
|
1398
|
-
result[name] = cols.map((c) => ({
|
|
1399
|
-
name: c.name,
|
|
1400
|
-
type: c.type,
|
|
1401
|
-
notnull: !!c.notnull,
|
|
1402
|
-
pk: !!c.pk,
|
|
1403
|
-
dflt_value: c.dflt_value ?? null
|
|
1404
|
-
}));
|
|
1405
|
-
}
|
|
1406
|
-
return result;
|
|
1407
|
-
}
|
|
1408
|
-
buildCreateTableSQL(table) {
|
|
1409
|
-
return this.generateCreateTableSql(table);
|
|
1410
|
-
}
|
|
1411
|
-
async tableExists(name) {
|
|
1412
|
-
const dbi = await this.getDb();
|
|
1413
|
-
const rows = await dbi.select(
|
|
1414
|
-
`SELECT name FROM sqlite_master WHERE type='table' AND name = ?`,
|
|
1415
|
-
[name]
|
|
1416
|
-
);
|
|
1417
|
-
return rows.length > 0;
|
|
1418
|
-
}
|
|
1419
|
-
// Force push model to DB: add missing tables/columns, rebuild tables if incompatible
|
|
1420
|
-
async forcePush(options) {
|
|
1421
|
-
if (!this._tables) throw new Error("No tables configured.");
|
|
1422
|
-
await this.forcePushForTables(Object.values(this._tables), options);
|
|
1423
|
-
}
|
|
1424
|
-
async forcePushForTables(tables, options) {
|
|
1425
|
-
const dbi = await this.getDb();
|
|
1426
|
-
const preserve = options?.preserveData !== false;
|
|
1427
|
-
for (const tbl of tables) {
|
|
1428
|
-
const tableName = getTableName(tbl);
|
|
1429
|
-
const exists2 = await this.tableExists(tableName);
|
|
1430
|
-
if (!exists2) {
|
|
1431
|
-
await this.run(this.buildCreateTableSQL(tbl));
|
|
1432
|
-
await this.createIndexesForTable(tbl);
|
|
1433
|
-
continue;
|
|
1434
|
-
}
|
|
1435
|
-
const existingCols = await dbi.select(
|
|
1436
|
-
`PRAGMA table_info('${tableName}')`
|
|
1437
|
-
);
|
|
1438
|
-
const existingMap = new Map(existingCols.map((c) => [c.name, c]));
|
|
1439
|
-
const modelCols = Object.values(
|
|
1440
|
-
tbl._schema
|
|
1441
|
-
);
|
|
1442
|
-
const missing = [];
|
|
1443
|
-
let requiresRebuild = false;
|
|
1444
|
-
for (const m of modelCols) {
|
|
1445
|
-
const info = existingMap.get(m.name);
|
|
1446
|
-
if (!info) {
|
|
1447
|
-
missing.push(m);
|
|
1448
|
-
continue;
|
|
1449
|
-
}
|
|
1450
|
-
const typeDiff = (info.type || "").toUpperCase() !== m.type.toUpperCase();
|
|
1451
|
-
const pkDiff = !!info.pk !== !!m.isPrimaryKey;
|
|
1452
|
-
const nnDiff = !!info.notnull !== !!m.isNotNull;
|
|
1453
|
-
const modelDv = m.defaultValue && typeof m.defaultValue === "object" && m.defaultValue.raw ? m.defaultValue.raw : m.defaultValue ?? null;
|
|
1454
|
-
const defDiff = (info.dflt_value ?? null) !== modelDv;
|
|
1455
|
-
if (typeDiff || pkDiff || nnDiff && !modelDv || defDiff) {
|
|
1456
|
-
requiresRebuild = true;
|
|
1457
|
-
}
|
|
1458
|
-
}
|
|
1459
|
-
if (requiresRebuild) {
|
|
1460
|
-
const tmp = `_new_${tableName}`;
|
|
1461
|
-
await this.run(this.buildCreateTableSQL(tbl));
|
|
1462
|
-
await this.run(
|
|
1463
|
-
this.buildCreateTableSQL({ ...tbl, tableName: tmp })
|
|
1464
|
-
);
|
|
1465
|
-
const existingNames = existingCols.map((c) => c.name);
|
|
1466
|
-
const modelNames = modelCols.map((c) => c.name);
|
|
1467
|
-
const shared = existingNames.filter((n) => modelNames.includes(n));
|
|
1468
|
-
if (preserve && shared.length > 0) {
|
|
1469
|
-
await this.run(
|
|
1470
|
-
`INSERT INTO ${tmp} (${shared.join(", ")}) SELECT ${shared.join(
|
|
1471
|
-
", "
|
|
1472
|
-
)} FROM ${tableName}`
|
|
1473
|
-
);
|
|
1474
|
-
}
|
|
1475
|
-
await this.run(`DROP TABLE ${tableName}`);
|
|
1476
|
-
await this.run(`ALTER TABLE ${tmp} RENAME TO ${tableName}`);
|
|
1477
|
-
await this.createIndexesForTable(tbl);
|
|
1478
|
-
} else {
|
|
1479
|
-
for (const m of missing) {
|
|
1480
|
-
let clause = `${m.name} ${m.type}`;
|
|
1481
|
-
if (m.isNotNull) clause += " NOT NULL";
|
|
1482
|
-
if (m.defaultValue !== void 0) {
|
|
1483
|
-
const formatted = this.formatDefaultValue(m);
|
|
1484
|
-
if (formatted !== null) clause += ` DEFAULT ${formatted}`;
|
|
1485
|
-
}
|
|
1486
|
-
await this.run(`ALTER TABLE ${tableName} ADD COLUMN ${clause}`);
|
|
1487
|
-
}
|
|
1488
|
-
await this.createIndexesForTable(tbl);
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
1492
|
-
}
|
|
1493
426
|
};
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
one: (
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
if (rel && rel.kind === "one" && rel.cfg?.fields?.[0])
|
|
1509
|
-
return rel.cfg.fields[0];
|
|
1510
|
-
const basePk = getPrimaryKey(base);
|
|
1511
|
-
const guessNames = [
|
|
1512
|
-
`${base.tableName}_id`,
|
|
1513
|
-
`${base.tableName}Id`,
|
|
1514
|
-
`${basePk.name}`,
|
|
1515
|
-
`${base.tableName.slice(0, -1)}Id`
|
|
1516
|
-
];
|
|
1517
|
-
return childCols.find((c) => guessNames.includes(c.name)) || childCols.find((c) => /.*_id$/i.test(c.name)) || null;
|
|
1518
|
-
}
|
|
1519
|
-
function guessOneRelationJoin(base, rel) {
|
|
1520
|
-
const child = rel.table;
|
|
1521
|
-
const basePk = getPrimaryKey(base);
|
|
1522
|
-
const childCols = Object.values(child._schema);
|
|
1523
|
-
if (rel.cfg?.fields && rel.cfg?.references && rel.cfg.fields[0] && rel.cfg.references[0]) {
|
|
1524
|
-
const fk = rel.cfg.fields[0];
|
|
1525
|
-
const ref = rel.cfg.references[0];
|
|
1526
|
-
if (childCols.some((c) => c.name === fk.name)) {
|
|
1527
|
-
return { lhsTable: child, lhsCol: fk, rhsTable: base, rhsCol: ref };
|
|
1528
|
-
}
|
|
1529
|
-
const baseCols = Object.values(base._schema);
|
|
1530
|
-
if (baseCols.some((c) => c.name === fk.name)) {
|
|
1531
|
-
return { lhsTable: base, lhsCol: fk, rhsTable: child, rhsCol: ref };
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
const childFk = guessChildFk(child, base, rel);
|
|
1535
|
-
if (!childFk) return null;
|
|
1536
|
-
return { lhsTable: child, lhsCol: childFk, rhsTable: base, rhsCol: basePk };
|
|
1537
|
-
}
|
|
1538
|
-
function isFlatWith(spec) {
|
|
1539
|
-
return Object.values(spec).every((v) => typeof v === "boolean");
|
|
1540
|
-
}
|
|
1541
|
-
function makeQueryAPI(tables, relDefs, dbProvider) {
|
|
1542
|
-
const api = {};
|
|
1543
|
-
const tableKeyByName = {};
|
|
1544
|
-
for (const [k, t] of Object.entries(tables)) tableKeyByName[t.tableName] = k;
|
|
1545
|
-
for (const [tblKey, tbl] of Object.entries(tables)) {
|
|
1546
|
-
api[tblKey] = {
|
|
1547
|
-
async findMany(opts) {
|
|
1548
|
-
const base = tbl;
|
|
1549
|
-
const withSpec = opts?.with ?? {};
|
|
1550
|
-
const dbi = await dbProvider();
|
|
1551
|
-
const rels = relDefs[tblKey] ?? {};
|
|
1552
|
-
if (opts?.join && isFlatWith(withSpec)) {
|
|
1553
|
-
const baseCols = Object.values(base._schema);
|
|
1554
|
-
const basePk = baseCols.find((c) => c.isPrimaryKey) || baseCols.find((c) => c.name === "id") || baseCols[0];
|
|
1555
|
-
const selectParts = [];
|
|
1556
|
-
let baseSelected2;
|
|
1557
|
-
if (opts?.columns && !Array.isArray(opts.columns)) {
|
|
1558
|
-
baseSelected2 = Object.entries(opts.columns).filter(([, v]) => !!v).map(([k]) => k);
|
|
1559
|
-
} else if (Array.isArray(opts?.columns) && opts.columns.length > 0) {
|
|
1560
|
-
baseSelected2 = opts.columns;
|
|
1561
|
-
} else {
|
|
1562
|
-
baseSelected2 = baseCols.map((c) => c.name);
|
|
1563
|
-
}
|
|
1564
|
-
for (const name of baseSelected2)
|
|
1565
|
-
selectParts.push(`${base.tableName}.${name} AS __base_${name}`);
|
|
1566
|
-
const joins = [];
|
|
1567
|
-
const relColsMap = {};
|
|
1568
|
-
const fkMap = {};
|
|
1569
|
-
for (const [relName, enabled] of Object.entries(withSpec)) {
|
|
1570
|
-
if (!enabled) continue;
|
|
1571
|
-
const rel = rels[relName];
|
|
1572
|
-
if (!rel) continue;
|
|
1573
|
-
const child = rel.table;
|
|
1574
|
-
const childCols = Object.values(child._schema);
|
|
1575
|
-
const childPk = childCols.find((c) => c.isPrimaryKey) || childCols.find((c) => c.name === "id") || null;
|
|
1576
|
-
if (rel.kind === "one") {
|
|
1577
|
-
const mapping = guessOneRelationJoin(base, rel);
|
|
1578
|
-
if (!mapping) continue;
|
|
1579
|
-
if (mapping.lhsTable.tableName === child.tableName) {
|
|
1580
|
-
fkMap[relName] = { childFk: mapping.lhsCol, childPk };
|
|
1581
|
-
joins.push(
|
|
1582
|
-
`LEFT JOIN ${child.tableName} ON ${mapping.lhsTable.tableName}.${mapping.lhsCol.name} = ${mapping.rhsTable.tableName}.${mapping.rhsCol.name}`
|
|
1583
|
-
);
|
|
1584
|
-
} else {
|
|
1585
|
-
fkMap[relName] = { childFk: mapping.rhsCol, childPk };
|
|
1586
|
-
joins.push(
|
|
1587
|
-
`LEFT JOIN ${child.tableName} ON ${mapping.lhsTable.tableName}.${mapping.lhsCol.name} = ${mapping.rhsTable.tableName}.${mapping.rhsCol.name}`
|
|
1588
|
-
);
|
|
1589
|
-
}
|
|
1590
|
-
} else {
|
|
1591
|
-
const childFk = guessChildFk(child, base, rel);
|
|
1592
|
-
if (!childFk) continue;
|
|
1593
|
-
fkMap[relName] = { childFk, childPk };
|
|
1594
|
-
joins.push(
|
|
1595
|
-
`LEFT JOIN ${child.tableName} ON ${child.tableName}.${childFk.name} = ${base.tableName}.${basePk.name}`
|
|
1596
|
-
);
|
|
1597
|
-
}
|
|
1598
|
-
const selected = typeof enabled === "object" && enabled.columns?.length ? enabled.columns : childCols.map((c) => c.name);
|
|
1599
|
-
relColsMap[relName] = selected;
|
|
1600
|
-
for (const name of selected)
|
|
1601
|
-
selectParts.push(
|
|
1602
|
-
`${child.tableName}.${name} AS __rel_${relName}_${name}`
|
|
1603
|
-
);
|
|
1604
|
-
}
|
|
1605
|
-
let sqlText = `SELECT ${selectParts.join(", ")} FROM ${base.tableName}${joins.length ? " " + joins.join(" ") : ""}`;
|
|
1606
|
-
const bindings = [];
|
|
1607
|
-
if (opts?.where) {
|
|
1608
|
-
if (typeof opts.where === "function") {
|
|
1609
|
-
const w = opts.where(base, { eq, ne, gt, gte, lt, lte, like }).toSQL();
|
|
1610
|
-
sqlText += ` WHERE ${w.clause}`;
|
|
1611
|
-
bindings.push(...w.bindings);
|
|
1612
|
-
} else if (typeof opts.where.toSQL === "function") {
|
|
1613
|
-
const w = opts.where.toSQL();
|
|
1614
|
-
sqlText += ` WHERE ${w.clause}`;
|
|
1615
|
-
bindings.push(...w.bindings);
|
|
1616
|
-
} else {
|
|
1617
|
-
const entries = Object.entries(opts.where);
|
|
1618
|
-
if (entries.length > 0) {
|
|
1619
|
-
sqlText += ` WHERE ${entries.map(([k]) => `${base.tableName}.${k} = ?`).join(" AND ")}`;
|
|
1620
|
-
bindings.push(...entries.map(([, v]) => v));
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
|
-
const orderByClauses = typeof opts?.orderBy === "function" ? opts.orderBy(base, { asc, desc }) : opts?.orderBy;
|
|
1625
|
-
if (orderByClauses?.length)
|
|
1626
|
-
sqlText += ` ORDER BY ${orderByClauses.join(", ")}`;
|
|
1627
|
-
if (typeof opts?.limit === "number")
|
|
1628
|
-
sqlText += ` LIMIT ${opts.limit}`;
|
|
1629
|
-
if (typeof opts?.offset === "number")
|
|
1630
|
-
sqlText += ` OFFSET ${opts.offset}`;
|
|
1631
|
-
const rows = await dbi.select(sqlText, bindings);
|
|
1632
|
-
const groups = /* @__PURE__ */ new Map();
|
|
1633
|
-
for (const row of rows) {
|
|
1634
|
-
const baseObj = {};
|
|
1635
|
-
for (const name of baseSelected2)
|
|
1636
|
-
baseObj[name] = row[`__base_${name}`];
|
|
1637
|
-
const baseKey = baseObj[basePk.name];
|
|
1638
|
-
if (!groups.has(baseKey)) {
|
|
1639
|
-
const seed = { ...baseObj };
|
|
1640
|
-
for (const [relName, enabled] of Object.entries(withSpec)) {
|
|
1641
|
-
if (!enabled) continue;
|
|
1642
|
-
const rel = rels[relName];
|
|
1643
|
-
if (!rel) continue;
|
|
1644
|
-
seed[relName] = rel.kind === "many" ? [] : null;
|
|
1645
|
-
}
|
|
1646
|
-
groups.set(baseKey, seed);
|
|
1647
|
-
}
|
|
1648
|
-
const acc = groups.get(baseKey);
|
|
1649
|
-
for (const [relName, enabled] of Object.entries(withSpec)) {
|
|
1650
|
-
if (!enabled) continue;
|
|
1651
|
-
const rel = rels[relName];
|
|
1652
|
-
if (!rel) continue;
|
|
1653
|
-
const childCols = relColsMap[relName];
|
|
1654
|
-
const childObj = {};
|
|
1655
|
-
let allNull = true;
|
|
1656
|
-
for (const name of childCols) {
|
|
1657
|
-
const v = row[`__rel_${relName}_${name}`];
|
|
1658
|
-
childObj[name] = v;
|
|
1659
|
-
if (v !== null && v !== void 0) allNull = false;
|
|
1660
|
-
}
|
|
1661
|
-
if (allNull) continue;
|
|
1662
|
-
if (rel.kind === "many") {
|
|
1663
|
-
const childPk = fkMap[relName].childPk;
|
|
1664
|
-
if (childPk) {
|
|
1665
|
-
if (!acc[relName]) acc[relName] = [];
|
|
1666
|
-
const exists2 = acc[relName].some(
|
|
1667
|
-
(r) => r[childPk.name] === childObj[childPk.name]
|
|
1668
|
-
);
|
|
1669
|
-
if (!exists2) acc[relName].push(childObj);
|
|
1670
|
-
} else {
|
|
1671
|
-
acc[relName].push(childObj);
|
|
1672
|
-
}
|
|
1673
|
-
} else {
|
|
1674
|
-
acc[relName] = childObj;
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
|
-
return Array.from(groups.values());
|
|
1679
|
-
}
|
|
1680
|
-
let baseSelected;
|
|
1681
|
-
if (opts?.columns && !Array.isArray(opts.columns)) {
|
|
1682
|
-
baseSelected = Object.entries(opts.columns).filter(([, v]) => !!v).map(([k]) => k);
|
|
1683
|
-
} else if (Array.isArray(opts?.columns) && opts.columns.length > 0) {
|
|
1684
|
-
baseSelected = opts.columns;
|
|
1685
|
-
} else {
|
|
1686
|
-
baseSelected = Object.values(base._schema).map(
|
|
1687
|
-
(c) => c.name
|
|
1688
|
-
);
|
|
1689
|
-
}
|
|
1690
|
-
let baseSql = `SELECT ${baseSelected.join(", ")} FROM ${base.tableName}`;
|
|
1691
|
-
const baseBindings = [];
|
|
1692
|
-
if (opts?.where) {
|
|
1693
|
-
if (typeof opts.where === "function") {
|
|
1694
|
-
const w = opts.where(base, { eq, ne, gt, gte, lt, lte, like }).toSQL();
|
|
1695
|
-
baseSql += ` WHERE ${w.clause}`;
|
|
1696
|
-
baseBindings.push(...w.bindings);
|
|
1697
|
-
} else if (typeof opts.where.toSQL === "function") {
|
|
1698
|
-
const w = opts.where.toSQL();
|
|
1699
|
-
baseSql += ` WHERE ${w.clause}`;
|
|
1700
|
-
baseBindings.push(...w.bindings);
|
|
1701
|
-
} else {
|
|
1702
|
-
const entries = Object.entries(opts.where);
|
|
1703
|
-
if (entries.length > 0) {
|
|
1704
|
-
baseSql += ` WHERE ${entries.map(([k]) => `${k} = ?`).join(" AND ")}`;
|
|
1705
|
-
baseBindings.push(...entries.map(([, v]) => v));
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
const orderByClauses2 = typeof opts?.orderBy === "function" ? opts.orderBy(base, { asc, desc }) : opts?.orderBy;
|
|
1710
|
-
if (orderByClauses2?.length)
|
|
1711
|
-
baseSql += ` ORDER BY ${orderByClauses2.join(", ")}`;
|
|
1712
|
-
if (typeof opts?.limit === "number") baseSql += ` LIMIT ${opts.limit}`;
|
|
1713
|
-
if (typeof opts?.offset === "number")
|
|
1714
|
-
baseSql += ` OFFSET ${opts.offset}`;
|
|
1715
|
-
const baseRows = await dbi.select(baseSql, baseBindings);
|
|
1716
|
-
const result = baseRows.map((r) => ({ ...r }));
|
|
1717
|
-
async function loadRelationsFor(parents, parentTable, spec) {
|
|
1718
|
-
const parentPk = getPrimaryKey(parentTable);
|
|
1719
|
-
const parentIds = parents.map((p) => p[parentPk.name]);
|
|
1720
|
-
const relsMap = relDefs[Object.keys(tables).find(
|
|
1721
|
-
(k) => tables[k].tableName === parentTable.tableName
|
|
1722
|
-
)] || {};
|
|
1723
|
-
for (const [relName, v] of Object.entries(spec)) {
|
|
1724
|
-
const enabled = v;
|
|
1725
|
-
const rel = relsMap[relName];
|
|
1726
|
-
if (!rel) continue;
|
|
1727
|
-
const child = rel.table;
|
|
1728
|
-
const childCols = Object.values(child._schema);
|
|
1729
|
-
const selectCols = enabled?.columns && enabled.columns.length > 0 ? enabled.columns : childCols.map((c) => c.name);
|
|
1730
|
-
if (rel.kind === "many") {
|
|
1731
|
-
const fkCol = guessChildFk(child, parentTable, rel);
|
|
1732
|
-
if (!fkCol) continue;
|
|
1733
|
-
const sql2 = `SELECT ${selectCols.join(", ")} FROM ${child.tableName} WHERE ${fkCol.name} IN (${parentIds.map(() => "?").join(", ")})`;
|
|
1734
|
-
const rows = await dbi.select(sql2, parentIds);
|
|
1735
|
-
const buckets = /* @__PURE__ */ new Map();
|
|
1736
|
-
for (const r of rows) {
|
|
1737
|
-
const key = r[fkCol.name];
|
|
1738
|
-
if (!buckets.has(key)) buckets.set(key, []);
|
|
1739
|
-
buckets.get(key).push(r);
|
|
1740
|
-
}
|
|
1741
|
-
for (const p of parents)
|
|
1742
|
-
p[relName] = buckets.get(p[parentPk.name]) ?? [];
|
|
1743
|
-
if (enabled?.with) {
|
|
1744
|
-
const children = parents.flatMap(
|
|
1745
|
-
(p) => p[relName]
|
|
1746
|
-
);
|
|
1747
|
-
if (children.length > 0)
|
|
1748
|
-
await loadRelationsFor(children, child, enabled.with);
|
|
1749
|
-
}
|
|
1750
|
-
} else {
|
|
1751
|
-
const mapping = guessOneRelationJoin(parentTable, rel);
|
|
1752
|
-
if (!mapping) continue;
|
|
1753
|
-
if (mapping.lhsTable.tableName === child.tableName) {
|
|
1754
|
-
const sql2 = `SELECT ${selectCols.join(", ")} FROM ${child.tableName} WHERE ${mapping.lhsCol.name} IN (${parentIds.map(() => "?").join(", ")})`;
|
|
1755
|
-
const rows = await dbi.select(sql2, parentIds);
|
|
1756
|
-
const mapOne = /* @__PURE__ */ new Map();
|
|
1757
|
-
for (const r of rows) mapOne.set(r[mapping.lhsCol.name], r);
|
|
1758
|
-
for (const p of parents)
|
|
1759
|
-
p[relName] = mapOne.get(p[parentPk.name]) ?? null;
|
|
1760
|
-
} else {
|
|
1761
|
-
const parentFkName = mapping.lhsCol.name;
|
|
1762
|
-
const childPkName = mapping.rhsCol.name;
|
|
1763
|
-
const childIds = parents.map((p) => p[parentFkName]).filter((v2) => v2 !== void 0 && v2 !== null);
|
|
1764
|
-
if (childIds.length === 0) {
|
|
1765
|
-
for (const p of parents) p[relName] = null;
|
|
1766
|
-
} else {
|
|
1767
|
-
const sql2 = `SELECT ${selectCols.join(", ")} FROM ${child.tableName} WHERE ${childPkName} IN (${childIds.map(() => "?").join(", ")})`;
|
|
1768
|
-
const rows = await dbi.select(sql2, childIds);
|
|
1769
|
-
const mapOne = /* @__PURE__ */ new Map();
|
|
1770
|
-
for (const r of rows) mapOne.set(r[childPkName], r);
|
|
1771
|
-
for (const p of parents)
|
|
1772
|
-
p[relName] = mapOne.get(p[parentFkName]) ?? null;
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
if (enabled?.with) {
|
|
1776
|
-
const children = parents.map((p) => p[relName]).filter((x) => Boolean(x));
|
|
1777
|
-
if (children.length > 0)
|
|
1778
|
-
await loadRelationsFor(children, child, enabled.with);
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1782
|
-
}
|
|
1783
|
-
if (Object.keys(withSpec).length > 0) {
|
|
1784
|
-
await loadRelationsFor(result, base, withSpec);
|
|
1785
|
-
}
|
|
1786
|
-
return result;
|
|
1787
|
-
},
|
|
1788
|
-
async findFirst(opts) {
|
|
1789
|
-
const rows = await api[tblKey].findMany({ ...opts, limit: 1 });
|
|
1790
|
-
return rows?.[0] ?? null;
|
|
1791
|
-
}
|
|
1792
|
-
};
|
|
1793
|
-
}
|
|
1794
|
-
return api;
|
|
1795
|
-
}
|
|
427
|
+
var relations = (table, relationsCallback) => {
|
|
428
|
+
return relationsCallback({
|
|
429
|
+
one: (table2, config) => ({
|
|
430
|
+
table: table2,
|
|
431
|
+
type: "one",
|
|
432
|
+
foreignKey: config.fields[0],
|
|
433
|
+
localKey: config.references[0]
|
|
434
|
+
}),
|
|
435
|
+
many: (table2) => ({
|
|
436
|
+
table: table2,
|
|
437
|
+
type: "many"
|
|
438
|
+
})
|
|
439
|
+
});
|
|
440
|
+
};
|
|
1796
441
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1797
442
|
0 && (module.exports = {
|
|
443
|
+
DeleteQueryBuilder,
|
|
444
|
+
InsertQueryBuilder,
|
|
445
|
+
SQLiteColumn,
|
|
446
|
+
SelectQueryBuilder,
|
|
447
|
+
Table,
|
|
1798
448
|
TauriORM,
|
|
449
|
+
UpdateQueryBuilder,
|
|
1799
450
|
and,
|
|
1800
|
-
asc,
|
|
1801
|
-
between,
|
|
1802
451
|
blob,
|
|
1803
452
|
boolean,
|
|
1804
|
-
check,
|
|
1805
|
-
defineTable,
|
|
1806
|
-
desc,
|
|
1807
453
|
eq,
|
|
1808
|
-
exists,
|
|
1809
|
-
foreignKey,
|
|
1810
|
-
getQualifiedName,
|
|
1811
454
|
gt,
|
|
1812
455
|
gte,
|
|
1813
|
-
ilike,
|
|
1814
456
|
inArray,
|
|
1815
|
-
increments,
|
|
1816
|
-
index,
|
|
1817
457
|
integer,
|
|
1818
458
|
isNotNull,
|
|
1819
459
|
isNull,
|
|
1820
460
|
like,
|
|
1821
461
|
lt,
|
|
1822
462
|
lte,
|
|
1823
|
-
makeQueryAPI,
|
|
1824
|
-
ne,
|
|
1825
|
-
not,
|
|
1826
|
-
notBetween,
|
|
1827
|
-
notExists,
|
|
1828
|
-
notIlike,
|
|
1829
|
-
notInArray,
|
|
1830
|
-
numeric,
|
|
1831
463
|
or,
|
|
1832
|
-
primaryKey,
|
|
1833
|
-
raw,
|
|
1834
464
|
real,
|
|
1835
465
|
relations,
|
|
1836
|
-
|
|
1837
|
-
text
|
|
1838
|
-
timestamp,
|
|
1839
|
-
unique,
|
|
1840
|
-
uniqueIndex
|
|
466
|
+
sqliteTable,
|
|
467
|
+
text
|
|
1841
468
|
});
|