@travetto/model-sql 7.1.3 → 8.0.0-alpha.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/package.json +7 -7
- package/src/dialect/base.ts +22 -20
- package/src/service.ts +1 -2
- package/src/table-manager.ts +3 -1
- package/src/util.ts +1 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-sql",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0-alpha.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "SQL backing for the travetto model module, with real-time modeling support for SQL schemas.",
|
|
6
6
|
"keywords": [
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
"directory": "module/model-sql"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@travetto/config": "^
|
|
32
|
-
"@travetto/context": "^
|
|
33
|
-
"@travetto/model": "^
|
|
34
|
-
"@travetto/model-query": "^
|
|
31
|
+
"@travetto/config": "^8.0.0-alpha.0",
|
|
32
|
+
"@travetto/context": "^8.0.0-alpha.0",
|
|
33
|
+
"@travetto/model": "^8.0.0-alpha.0",
|
|
34
|
+
"@travetto/model-query": "^8.0.0-alpha.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@travetto/cli": "^
|
|
38
|
-
"@travetto/test": "^
|
|
37
|
+
"@travetto/cli": "^8.0.0-alpha.0",
|
|
38
|
+
"@travetto/test": "^8.0.0-alpha.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependenciesMeta": {
|
|
41
41
|
"@travetto/cli": {
|
package/src/dialect/base.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @stylistic/indent */
|
|
2
|
-
import { DataUtil, type SchemaFieldConfig,
|
|
3
|
-
import { type Class,
|
|
2
|
+
import { DataUtil, type SchemaFieldConfig, SchemaRegistryIndex, type Point } from '@travetto/schema';
|
|
3
|
+
import { type Class, RuntimeError, TypedObject, TimeUtil, castTo, castKey, toConcrete, JSONUtil } from '@travetto/runtime';
|
|
4
4
|
import { type SelectClause, type Query, type SortClause, type WhereClause, type RetainQueryPrimitiveFields, ModelQueryUtil } from '@travetto/model-query';
|
|
5
5
|
import type { BulkResponse, IndexConfig, ModelType } from '@travetto/model';
|
|
6
6
|
|
|
@@ -22,11 +22,6 @@ export type SQLTableDescription = {
|
|
|
22
22
|
indices: { name: string, columns: { name: string, desc: boolean }[], is_unique: boolean }[];
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
@Schema()
|
|
26
|
-
class Total {
|
|
27
|
-
total: number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
25
|
function makeField(name: string, type: Class, required: boolean, extra: Partial<SchemaFieldConfig>): SchemaFieldConfig {
|
|
31
26
|
return {
|
|
32
27
|
name,
|
|
@@ -212,6 +207,8 @@ export abstract class SQLDialect implements DialectState {
|
|
|
212
207
|
}
|
|
213
208
|
} else if (config.type === Boolean) {
|
|
214
209
|
return `${value ? 'TRUE' : 'FALSE'}`;
|
|
210
|
+
} else if (config.type === castTo(BigInt)) {
|
|
211
|
+
return value.toString();
|
|
215
212
|
} else if (config.type === Number) {
|
|
216
213
|
return `${value}`;
|
|
217
214
|
} else if (config.type === Date) {
|
|
@@ -223,9 +220,9 @@ export abstract class SQLDialect implements DialectState {
|
|
|
223
220
|
} else if (config.type === PointConcrete && Array.isArray(value)) {
|
|
224
221
|
return `point(${value[0]},${value[1]})`;
|
|
225
222
|
} else if (config.type === Object) {
|
|
226
|
-
return this.quote(
|
|
223
|
+
return this.quote(JSONUtil.toUTF8(value).replaceAll("'", "''"));
|
|
227
224
|
}
|
|
228
|
-
throw new
|
|
225
|
+
throw new RuntimeError(`Unknown value type for field ${config.name}, ${value}`, { category: 'data' });
|
|
229
226
|
}
|
|
230
227
|
|
|
231
228
|
/**
|
|
@@ -234,7 +231,9 @@ export abstract class SQLDialect implements DialectState {
|
|
|
234
231
|
getColumnType(config: SchemaFieldConfig): string {
|
|
235
232
|
let type: string = '';
|
|
236
233
|
|
|
237
|
-
if (config.type ===
|
|
234
|
+
if (config.type === castTo(BigInt)) {
|
|
235
|
+
type = this.COLUMN_TYPES.BIGINT;
|
|
236
|
+
} else if (config.type === Number) {
|
|
238
237
|
type = this.COLUMN_TYPES.INT;
|
|
239
238
|
if (config.precision) {
|
|
240
239
|
const [digits, decimals] = config.precision;
|
|
@@ -290,18 +289,21 @@ export abstract class SQLDialect implements DialectState {
|
|
|
290
289
|
/**
|
|
291
290
|
* Delete query and return count removed
|
|
292
291
|
*/
|
|
293
|
-
async deleteAndGetCount<T>(cls: Class<T>, query: Query<T>): Promise<number> {
|
|
292
|
+
async deleteAndGetCount<T extends ModelType>(cls: Class<T>, query: Query<T>): Promise<number> {
|
|
294
293
|
const { count } = await this.executeSQL<T>(this.getDeleteSQL(SQLModelUtil.classToStack(cls), query.where));
|
|
295
|
-
return count;
|
|
294
|
+
return DataUtil.coerceType(count, Number);
|
|
296
295
|
}
|
|
297
296
|
|
|
298
297
|
/**
|
|
299
298
|
* Get the count for a given query
|
|
300
299
|
*/
|
|
301
|
-
async getCountForQuery<T>(cls: Class<T>, query: Query<T>): Promise<number> {
|
|
302
|
-
const { records } = await this.executeSQL<{ total: number }>(
|
|
303
|
-
|
|
304
|
-
|
|
300
|
+
async getCountForQuery<T extends ModelType>(cls: Class<T>, query: Query<T>): Promise<number> {
|
|
301
|
+
const { records } = await this.executeSQL<{ total: number }>(
|
|
302
|
+
this.getQueryCountSQL(cls,
|
|
303
|
+
ModelQueryUtil.getWhereClause(cls, query.where)
|
|
304
|
+
)
|
|
305
|
+
);
|
|
306
|
+
return DataUtil.coerceType(records[0].total, Number);
|
|
305
307
|
}
|
|
306
308
|
|
|
307
309
|
/**
|
|
@@ -449,13 +451,13 @@ export abstract class SQLDialect implements DialectState {
|
|
|
449
451
|
|
|
450
452
|
switch (subKey) {
|
|
451
453
|
case '$nin': case '$in': {
|
|
452
|
-
const arr = (Array.isArray(value) ? value : [value]).map(
|
|
454
|
+
const arr = (Array.isArray(value) ? value : [value]).map(resolve);
|
|
453
455
|
items.push(`${sPath} ${SQL_OPS[subKey]} (${arr.join(',')})`);
|
|
454
456
|
break;
|
|
455
457
|
}
|
|
456
458
|
case '$all': {
|
|
457
459
|
const set = new Set();
|
|
458
|
-
const arr = [value].flat().filter(item => !set.has(item) && !!set.add(item)).map(
|
|
460
|
+
const arr = [value].flat().filter(item => !set.has(item) && !!set.add(item)).map(resolve);
|
|
459
461
|
const valueTable = this.parentTable(sStack);
|
|
460
462
|
const alias = `_all_${sStack.length}`;
|
|
461
463
|
const pPath = this.identifier(this.parentPathField.name);
|
|
@@ -660,9 +662,9 @@ ${this.getLimitSQL(cls, query)}`;
|
|
|
660
662
|
(array ? [castTo<SchemaFieldConfig>(config)] : []);
|
|
661
663
|
|
|
662
664
|
if (!parent) {
|
|
663
|
-
|
|
665
|
+
const idField = fields.find(field => field.name === this.idField.name);
|
|
664
666
|
if (!idField) {
|
|
665
|
-
fields.push(
|
|
667
|
+
fields.push(this.idField);
|
|
666
668
|
}
|
|
667
669
|
}
|
|
668
670
|
|
package/src/service.ts
CHANGED
|
@@ -253,8 +253,7 @@ export class SQLModelService implements
|
|
|
253
253
|
@Connected()
|
|
254
254
|
async queryCount<T extends ModelType>(cls: Class<T>, query: ModelQuery<T>): Promise<number> {
|
|
255
255
|
await QueryVerifier.verify(cls, query);
|
|
256
|
-
|
|
257
|
-
return +records[0].total;
|
|
256
|
+
return this.#dialect.getCountForQuery(cls, query);
|
|
258
257
|
}
|
|
259
258
|
|
|
260
259
|
@Connected()
|
package/src/table-manager.ts
CHANGED
|
@@ -130,7 +130,9 @@ export class TableManager {
|
|
|
130
130
|
|
|
131
131
|
const sqlCommands = await this.getUpsertTablesSQL(cls);
|
|
132
132
|
for (const key of ['dropIndex', 'table', 'createIndex'] as const) {
|
|
133
|
-
|
|
133
|
+
for (const command of sqlCommands[key]) {
|
|
134
|
+
await this.#exec(command);
|
|
135
|
+
}
|
|
134
136
|
}
|
|
135
137
|
}
|
|
136
138
|
|
package/src/util.ts
CHANGED
|
@@ -318,15 +318,13 @@ export class SQLModelUtil {
|
|
|
318
318
|
(wrappers[key] ??= { stack, records: [] }).records.push({ stack, value });
|
|
319
319
|
};
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
items.map(item =>
|
|
322
322
|
this.visitSchemaInstance(cls, item, {
|
|
323
323
|
onRoot: ({ path, value }) => track(path, value),
|
|
324
324
|
onSub: ({ path, value }) => track(path, value),
|
|
325
325
|
onSimple: ({ path, value }) => track(path, value)
|
|
326
326
|
}));
|
|
327
327
|
|
|
328
|
-
await Promise.all(all);
|
|
329
|
-
|
|
330
328
|
const result = [...Object.values(wrappers)].toSorted((a, b) => a.stack.length - b.stack.length);
|
|
331
329
|
return result;
|
|
332
330
|
}
|