@type32/tauri-sqlite-orm 0.1.18-8 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +165 -117
- package/dist/index.d.ts +165 -117
- package/dist/index.js +516 -269
- package/dist/index.mjs +513 -269
- package/package.json +5 -4
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -63
- package/dist/cli.mjs +0 -62
package/dist/index.mjs
CHANGED
|
@@ -1,113 +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, notNull: true },
|
|
45
|
-
this._.mode
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
autoincrement() {
|
|
49
|
-
return new _SQLiteColumn(
|
|
50
|
-
this._.name,
|
|
51
|
-
this.type,
|
|
52
|
-
{ ...this.options, autoincrement: true },
|
|
53
|
-
this._.mode
|
|
54
|
-
);
|
|
1
|
+
// src/builders/query-base.ts
|
|
2
|
+
var BaseQueryBuilder = class {
|
|
3
|
+
constructor(db) {
|
|
4
|
+
this.db = db;
|
|
55
5
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
);
|
|
6
|
+
query = "";
|
|
7
|
+
params = [];
|
|
8
|
+
where(condition) {
|
|
9
|
+
this.query += ` WHERE ${condition.sql}`;
|
|
10
|
+
this.params.push(...condition.params);
|
|
11
|
+
return this;
|
|
63
12
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
column: ref._.columns[column]
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
this._.mode
|
|
76
|
-
);
|
|
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;
|
|
77
21
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this.type,
|
|
82
|
-
{ ...this.options, $onUpdateFn: fn },
|
|
83
|
-
this._.mode
|
|
84
|
-
);
|
|
22
|
+
limit(count2) {
|
|
23
|
+
this.query += ` LIMIT ${count2}`;
|
|
24
|
+
return this;
|
|
85
25
|
}
|
|
86
|
-
|
|
26
|
+
offset(count2) {
|
|
27
|
+
this.query += ` OFFSET ${count2}`;
|
|
87
28
|
return this;
|
|
88
29
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
var blob = (name) => new SQLiteColumn(name, "BLOB");
|
|
94
|
-
var boolean = (name) => new SQLiteColumn(name, "BOOLEAN");
|
|
95
|
-
var Table = class {
|
|
96
|
-
_;
|
|
97
|
-
constructor(name, columns) {
|
|
98
|
-
this._ = {
|
|
99
|
-
name,
|
|
100
|
-
columns
|
|
30
|
+
build() {
|
|
31
|
+
return {
|
|
32
|
+
sql: this.query,
|
|
33
|
+
params: this.params
|
|
101
34
|
};
|
|
102
35
|
}
|
|
103
36
|
};
|
|
104
|
-
|
|
105
|
-
|
|
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
|
+
};
|
|
106
45
|
};
|
|
107
|
-
var eq = (column, value) => ({
|
|
108
|
-
sql: `${column._.name} = ?`,
|
|
109
|
-
params: [value]
|
|
110
|
-
});
|
|
111
46
|
var and = (...conditions) => ({
|
|
112
47
|
sql: conditions.map((c) => `(${c.sql})`).join(" AND "),
|
|
113
48
|
params: conditions.flatMap((c) => c.params)
|
|
@@ -152,14 +87,6 @@ var inArray = (column, values) => ({
|
|
|
152
87
|
sql: `${column._.name} IN (${values.map(() => "?").join(",")})`,
|
|
153
88
|
params: values
|
|
154
89
|
});
|
|
155
|
-
var asc = (column) => ({
|
|
156
|
-
sql: `${column._.name} ASC`,
|
|
157
|
-
params: []
|
|
158
|
-
});
|
|
159
|
-
var desc = (column) => ({
|
|
160
|
-
sql: `${column._.name} DESC`,
|
|
161
|
-
params: []
|
|
162
|
-
});
|
|
163
90
|
var count = (column) => ({
|
|
164
91
|
sql: `COUNT(${column ? column._.name : "*"})`,
|
|
165
92
|
params: []
|
|
@@ -184,80 +111,34 @@ var min = (column) => ({
|
|
|
184
111
|
sql: `MIN(${column._.name})`,
|
|
185
112
|
params: []
|
|
186
113
|
});
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const params = [];
|
|
190
|
-
strings.forEach((str, i) => {
|
|
191
|
-
queryParts.push(str);
|
|
192
|
-
if (values[i] !== void 0) {
|
|
193
|
-
if (typeof values[i] === "object" && values[i].sql) {
|
|
194
|
-
queryParts.push(values[i].sql);
|
|
195
|
-
params.push(...values[i].params);
|
|
196
|
-
} else {
|
|
197
|
-
queryParts.push("?");
|
|
198
|
-
params.push(values[i]);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
return {
|
|
203
|
-
sql: queryParts.join(""),
|
|
204
|
-
params
|
|
205
|
-
};
|
|
206
|
-
};
|
|
207
|
-
var BaseQueryBuilder = class {
|
|
208
|
-
constructor(db) {
|
|
209
|
-
this.db = db;
|
|
210
|
-
}
|
|
211
|
-
query = "";
|
|
212
|
-
params = [];
|
|
213
|
-
where(condition) {
|
|
214
|
-
this.query += ` WHERE ${condition.sql}`;
|
|
215
|
-
this.params.push(...condition.params);
|
|
216
|
-
return this;
|
|
217
|
-
}
|
|
218
|
-
orderBy(column, direction = "ASC") {
|
|
219
|
-
if ("sql" in column) {
|
|
220
|
-
this.query += ` ORDER BY ${column.sql} ${direction}`;
|
|
221
|
-
this.params.push(...column.params);
|
|
222
|
-
} else {
|
|
223
|
-
this.query += ` ORDER BY ${column._.name} ${direction}`;
|
|
224
|
-
}
|
|
225
|
-
return this;
|
|
226
|
-
}
|
|
227
|
-
limit(count2) {
|
|
228
|
-
this.query += ` LIMIT ${count2}`;
|
|
229
|
-
return this;
|
|
230
|
-
}
|
|
231
|
-
offset(count2) {
|
|
232
|
-
this.query += ` OFFSET ${count2}`;
|
|
233
|
-
return this;
|
|
234
|
-
}
|
|
235
|
-
build() {
|
|
236
|
-
return {
|
|
237
|
-
sql: this.query,
|
|
238
|
-
params: this.params
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
};
|
|
114
|
+
|
|
115
|
+
// src/builders/select.ts
|
|
242
116
|
var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
243
117
|
constructor(db, table, columns) {
|
|
244
118
|
super(db);
|
|
245
119
|
this.table = table;
|
|
246
120
|
this.columns = columns;
|
|
247
|
-
|
|
248
|
-
|
|
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}`;
|
|
249
127
|
}
|
|
250
128
|
isDistinct = false;
|
|
251
129
|
groupByColumns = [];
|
|
252
130
|
havingCondition = null;
|
|
131
|
+
joins = [];
|
|
132
|
+
includeRelations = {};
|
|
133
|
+
selectedTableAlias;
|
|
134
|
+
selectedColumns = [];
|
|
253
135
|
distinct() {
|
|
254
136
|
this.isDistinct = true;
|
|
255
|
-
this.query = this.query.replace("SELECT", "SELECT DISTINCT");
|
|
256
137
|
return this;
|
|
257
138
|
}
|
|
258
139
|
groupBy(...columns) {
|
|
259
140
|
this.groupByColumns.push(...columns);
|
|
260
|
-
const columnNames = columns.map((col) => col._.name).join(", ");
|
|
141
|
+
const columnNames = columns.map((col) => `${this.selectedTableAlias}.${col._.name}`).join(", ");
|
|
261
142
|
this.query += ` GROUP BY ${columnNames}`;
|
|
262
143
|
return this;
|
|
263
144
|
}
|
|
@@ -267,10 +148,169 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
|
267
148
|
this.params.push(...condition.params);
|
|
268
149
|
return this;
|
|
269
150
|
}
|
|
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);
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
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);
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
include(relations2) {
|
|
168
|
+
this.includeRelations = { ...this.includeRelations, ...relations2 };
|
|
169
|
+
return this;
|
|
170
|
+
}
|
|
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 };
|
|
226
|
+
}
|
|
227
|
+
// Enhanced execute method that handles relation data mapping
|
|
270
228
|
async execute() {
|
|
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);
|
|
271
234
|
const { sql: sql2, params } = this.build();
|
|
272
|
-
|
|
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
|
+
});
|
|
273
257
|
}
|
|
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());
|
|
312
|
+
}
|
|
313
|
+
// Update the return type signatures
|
|
274
314
|
async all() {
|
|
275
315
|
return this.execute();
|
|
276
316
|
}
|
|
@@ -280,6 +320,79 @@ var SelectQueryBuilder = class extends BaseQueryBuilder {
|
|
|
280
320
|
return result[0];
|
|
281
321
|
}
|
|
282
322
|
};
|
|
323
|
+
|
|
324
|
+
// src/builders/update.ts
|
|
325
|
+
var UpdateQueryBuilder = class extends BaseQueryBuilder {
|
|
326
|
+
constructor(db, table) {
|
|
327
|
+
super(db);
|
|
328
|
+
this.table = table;
|
|
329
|
+
this.query = `UPDATE ${table._.name}`;
|
|
330
|
+
}
|
|
331
|
+
updateData = {};
|
|
332
|
+
returningColumns = [];
|
|
333
|
+
set(data) {
|
|
334
|
+
this.updateData = { ...this.updateData, ...data };
|
|
335
|
+
return this;
|
|
336
|
+
}
|
|
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
|
+
}
|
|
349
|
+
const baseQuery = this.query;
|
|
350
|
+
const whereParams = this.params;
|
|
351
|
+
let tablePart = baseQuery;
|
|
352
|
+
let whereClause = "";
|
|
353
|
+
const whereIndex = baseQuery.indexOf(" WHERE ");
|
|
354
|
+
if (whereIndex !== -1) {
|
|
355
|
+
tablePart = baseQuery.substring(0, whereIndex);
|
|
356
|
+
whereClause = baseQuery.substring(whereIndex);
|
|
357
|
+
}
|
|
358
|
+
const entries = Object.entries(finalUpdateData);
|
|
359
|
+
if (entries.length === 0) {
|
|
360
|
+
throw new Error("Cannot execute an update query without a .set() call.");
|
|
361
|
+
}
|
|
362
|
+
const setClause = entries.map(([key]) => {
|
|
363
|
+
const column = this.table._.columns[key];
|
|
364
|
+
if (!column) {
|
|
365
|
+
throw new Error(
|
|
366
|
+
`Column ${key} does not exist on table ${this.table._.name}`
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
return `${column._.name} = ?`;
|
|
370
|
+
}).join(", ");
|
|
371
|
+
const setParams = entries.map(([, value]) => value);
|
|
372
|
+
const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
|
|
373
|
+
const params = [...setParams, ...whereParams];
|
|
374
|
+
return { sql: sql2, params };
|
|
375
|
+
}
|
|
376
|
+
async execute() {
|
|
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();
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// src/builders/insert.ts
|
|
283
396
|
var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
284
397
|
constructor(db, table) {
|
|
285
398
|
super(db);
|
|
@@ -297,7 +410,7 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
|
297
410
|
return this;
|
|
298
411
|
}
|
|
299
412
|
returning(...columns) {
|
|
300
|
-
this.returningColumns
|
|
413
|
+
this.returningColumns.push(...columns);
|
|
301
414
|
return this;
|
|
302
415
|
}
|
|
303
416
|
onConflictDoNothing(target) {
|
|
@@ -404,75 +517,8 @@ var InsertQueryBuilder = class extends BaseQueryBuilder {
|
|
|
404
517
|
return this.returning(...allColumns).execute();
|
|
405
518
|
}
|
|
406
519
|
};
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
super(db);
|
|
410
|
-
this.table = table;
|
|
411
|
-
this.query = `UPDATE ${table._.name}`;
|
|
412
|
-
}
|
|
413
|
-
updateData = {};
|
|
414
|
-
returningColumns = [];
|
|
415
|
-
set(data) {
|
|
416
|
-
this.updateData = { ...this.updateData, ...data };
|
|
417
|
-
return this;
|
|
418
|
-
}
|
|
419
|
-
returning(...columns) {
|
|
420
|
-
this.returningColumns = columns;
|
|
421
|
-
return this;
|
|
422
|
-
}
|
|
423
|
-
buildUpdateClause() {
|
|
424
|
-
const finalUpdateData = { ...this.updateData };
|
|
425
|
-
for (const [key, column] of Object.entries(this.table._.columns)) {
|
|
426
|
-
const typedKey = key;
|
|
427
|
-
if (finalUpdateData[typedKey] === void 0 && column.options.$onUpdateFn) {
|
|
428
|
-
finalUpdateData[typedKey] = column.options.$onUpdateFn();
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
const baseQuery = this.query;
|
|
432
|
-
const whereParams = this.params;
|
|
433
|
-
let tablePart = baseQuery;
|
|
434
|
-
let whereClause = "";
|
|
435
|
-
const whereIndex = baseQuery.indexOf(" WHERE ");
|
|
436
|
-
if (whereIndex !== -1) {
|
|
437
|
-
tablePart = baseQuery.substring(0, whereIndex);
|
|
438
|
-
whereClause = baseQuery.substring(whereIndex);
|
|
439
|
-
}
|
|
440
|
-
const entries = Object.entries(finalUpdateData);
|
|
441
|
-
if (entries.length === 0) {
|
|
442
|
-
throw new Error("Cannot execute an update query without a .set() call.");
|
|
443
|
-
}
|
|
444
|
-
const setClause = entries.map(([key]) => {
|
|
445
|
-
const column = this.table._.columns[key];
|
|
446
|
-
if (!column) {
|
|
447
|
-
throw new Error(
|
|
448
|
-
`Column ${key} does not exist on table ${this.table._.name}`
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
return `${column._.name} = ?`;
|
|
452
|
-
}).join(", ");
|
|
453
|
-
const setParams = entries.map(([, value]) => value);
|
|
454
|
-
const sql2 = `${tablePart} SET ${setClause}${whereClause}`;
|
|
455
|
-
const params = [...setParams, ...whereParams];
|
|
456
|
-
return { sql: sql2, params };
|
|
457
|
-
}
|
|
458
|
-
async execute() {
|
|
459
|
-
const { sql: updateSql, params } = this.buildUpdateClause();
|
|
460
|
-
if (this.returningColumns.length > 0) {
|
|
461
|
-
const returningNames = this.returningColumns.map((col) => this.table._.columns[col]._.name).join(", ");
|
|
462
|
-
const sqlWithReturning = `${updateSql} RETURNING ${returningNames}`;
|
|
463
|
-
return this.db.select(sqlWithReturning, params);
|
|
464
|
-
} else {
|
|
465
|
-
const result = await this.db.execute(updateSql, params);
|
|
466
|
-
return [{ rowsAffected: result.rowsAffected }];
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
async returningAll() {
|
|
470
|
-
const allColumns = Object.keys(
|
|
471
|
-
this.table._.columns
|
|
472
|
-
);
|
|
473
|
-
return this.returning(...allColumns).execute();
|
|
474
|
-
}
|
|
475
|
-
};
|
|
520
|
+
|
|
521
|
+
// src/builders/delete.ts
|
|
476
522
|
var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
477
523
|
constructor(db, table) {
|
|
478
524
|
super(db);
|
|
@@ -481,7 +527,7 @@ var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
|
481
527
|
}
|
|
482
528
|
returningColumns = [];
|
|
483
529
|
returning(...columns) {
|
|
484
|
-
this.returningColumns
|
|
530
|
+
this.returningColumns.push(...columns);
|
|
485
531
|
return this;
|
|
486
532
|
}
|
|
487
533
|
async execute() {
|
|
@@ -496,12 +542,12 @@ var DeleteQueryBuilder = class extends BaseQueryBuilder {
|
|
|
496
542
|
}
|
|
497
543
|
}
|
|
498
544
|
async returningAll() {
|
|
499
|
-
const allColumns = Object.keys(
|
|
500
|
-
this.table._.columns
|
|
501
|
-
);
|
|
545
|
+
const allColumns = Object.keys(this.table._.columns);
|
|
502
546
|
return this.returning(...allColumns).execute();
|
|
503
547
|
}
|
|
504
548
|
};
|
|
549
|
+
|
|
550
|
+
// src/builders/with.ts
|
|
505
551
|
var WithQueryBuilder = class {
|
|
506
552
|
constructor(db) {
|
|
507
553
|
this.db = db;
|
|
@@ -542,13 +588,119 @@ var WithQueryBuilder = class {
|
|
|
542
588
|
}
|
|
543
589
|
}
|
|
544
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
|
+
};
|
|
545
697
|
var TauriORM = class {
|
|
546
698
|
constructor(db, schema = void 0) {
|
|
547
699
|
this.db = db;
|
|
548
700
|
if (schema) {
|
|
549
|
-
for (const
|
|
550
|
-
if (
|
|
551
|
-
this.tables.set(
|
|
701
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
702
|
+
if (value instanceof Table) {
|
|
703
|
+
this.tables.set(value._.name, value);
|
|
552
704
|
}
|
|
553
705
|
}
|
|
554
706
|
}
|
|
@@ -573,31 +725,60 @@ var TauriORM = class {
|
|
|
573
725
|
}
|
|
574
726
|
return sql2;
|
|
575
727
|
}
|
|
576
|
-
async migrate() {
|
|
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()));
|
|
577
734
|
for (const table of this.tables.values()) {
|
|
578
|
-
const
|
|
579
|
-
|
|
580
|
-
)
|
|
581
|
-
if (existingTableInfo.length === 0) {
|
|
735
|
+
const tableName = table._.name;
|
|
736
|
+
const tableExists = dbTableNames.has(tableName);
|
|
737
|
+
if (!tableExists) {
|
|
582
738
|
const columnsSql = Object.values(table._.columns).map((col) => this.buildColumnDefinition(col)).join(", ");
|
|
583
|
-
const createSql = `CREATE TABLE ${
|
|
739
|
+
const createSql = `CREATE TABLE ${tableName}
|
|
740
|
+
(
|
|
741
|
+
${columnsSql}
|
|
742
|
+
)`;
|
|
584
743
|
await this.db.execute(createSql);
|
|
585
744
|
} else {
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
);
|
|
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));
|
|
589
748
|
for (const column of Object.values(table._.columns)) {
|
|
590
749
|
if (!existingColumnNames.has(column._.name)) {
|
|
591
750
|
const columnSql = this.buildColumnDefinition(column, true);
|
|
592
|
-
const alterSql = `ALTER TABLE ${
|
|
751
|
+
const alterSql = `ALTER TABLE ${tableName}
|
|
752
|
+
ADD COLUMN ${columnSql}`;
|
|
593
753
|
await this.db.execute(alterSql);
|
|
594
754
|
}
|
|
595
755
|
}
|
|
756
|
+
if (options?.performDestructiveActions) {
|
|
757
|
+
for (const colName of existingColumnNames) {
|
|
758
|
+
if (!schemaColumnNames.has(colName)) {
|
|
759
|
+
await this.dropColumn(tableName, colName);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (options?.performDestructiveActions) {
|
|
766
|
+
for (const tableName of dbTableNames) {
|
|
767
|
+
if (!schemaTableNames.has(tableName)) {
|
|
768
|
+
await this.dropTable(tableName);
|
|
769
|
+
}
|
|
596
770
|
}
|
|
597
771
|
}
|
|
598
772
|
}
|
|
599
773
|
select(table, columns) {
|
|
600
|
-
|
|
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);
|
|
601
782
|
}
|
|
602
783
|
insert(table) {
|
|
603
784
|
return new InsertQueryBuilder(this.db, table);
|
|
@@ -634,13 +815,25 @@ var TauriORM = class {
|
|
|
634
815
|
// --- Schema detection / signature ---
|
|
635
816
|
async ensureSchemaMeta() {
|
|
636
817
|
await this.db.execute(
|
|
637
|
-
`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
|
+
)`
|
|
638
829
|
);
|
|
639
830
|
}
|
|
640
831
|
async getSchemaMeta(key) {
|
|
641
832
|
await this.ensureSchemaMeta();
|
|
642
833
|
const rows = await this.db.select(
|
|
643
|
-
`SELECT value
|
|
834
|
+
`SELECT value
|
|
835
|
+
FROM _schema_meta
|
|
836
|
+
WHERE key = ?`,
|
|
644
837
|
[key]
|
|
645
838
|
);
|
|
646
839
|
return rows?.[0]?.value ?? null;
|
|
@@ -648,7 +841,10 @@ var TauriORM = class {
|
|
|
648
841
|
async setSchemaMeta(key, value) {
|
|
649
842
|
await this.ensureSchemaMeta();
|
|
650
843
|
await this.db.execute(
|
|
651
|
-
`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`,
|
|
652
848
|
[key, value]
|
|
653
849
|
);
|
|
654
850
|
}
|
|
@@ -685,14 +881,34 @@ var TauriORM = class {
|
|
|
685
881
|
const status = await this.isSchemaDirty();
|
|
686
882
|
if (status.dirty) {
|
|
687
883
|
await this.migrate();
|
|
688
|
-
await this.setSchemaMeta(
|
|
689
|
-
"schema_signature",
|
|
690
|
-
this.computeModelSignature()
|
|
691
|
-
);
|
|
884
|
+
await this.setSchemaMeta("schema_signature", this.computeModelSignature());
|
|
692
885
|
return true;
|
|
693
886
|
}
|
|
694
887
|
return false;
|
|
695
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
|
+
}
|
|
696
912
|
};
|
|
697
913
|
var Relation = class {
|
|
698
914
|
constructor(foreignTable) {
|
|
@@ -710,15 +926,31 @@ var ManyRelation = class extends Relation {
|
|
|
710
926
|
super(foreignTable);
|
|
711
927
|
}
|
|
712
928
|
};
|
|
713
|
-
var relations = (
|
|
714
|
-
|
|
715
|
-
one: (
|
|
716
|
-
return new OneRelation(
|
|
929
|
+
var relations = (table, relationsCallback) => {
|
|
930
|
+
const builtRelations = relationsCallback({
|
|
931
|
+
one: (foreignTable, config) => {
|
|
932
|
+
return new OneRelation(foreignTable, config);
|
|
717
933
|
},
|
|
718
|
-
many: (
|
|
719
|
-
return new ManyRelation(
|
|
934
|
+
many: (foreignTable) => {
|
|
935
|
+
return new ManyRelation(foreignTable);
|
|
720
936
|
}
|
|
721
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;
|
|
722
954
|
};
|
|
723
955
|
var getTableColumns = (table) => {
|
|
724
956
|
return table._.columns;
|
|
@@ -726,7 +958,17 @@ var getTableColumns = (table) => {
|
|
|
726
958
|
var alias = (table, alias2) => {
|
|
727
959
|
return table;
|
|
728
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 });
|
|
729
970
|
export {
|
|
971
|
+
BaseQueryBuilder,
|
|
730
972
|
DeleteQueryBuilder,
|
|
731
973
|
InsertQueryBuilder,
|
|
732
974
|
ManyRelation,
|
|
@@ -747,6 +989,7 @@ export {
|
|
|
747
989
|
count,
|
|
748
990
|
countDistinct,
|
|
749
991
|
desc,
|
|
992
|
+
enumType,
|
|
750
993
|
eq,
|
|
751
994
|
getTableColumns,
|
|
752
995
|
gt,
|
|
@@ -761,6 +1004,7 @@ export {
|
|
|
761
1004
|
max,
|
|
762
1005
|
min,
|
|
763
1006
|
not,
|
|
1007
|
+
numeric,
|
|
764
1008
|
or,
|
|
765
1009
|
real,
|
|
766
1010
|
relations,
|