@travetto/model-sql 6.0.0 → 6.0.1
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 +14 -14
- package/src/util.ts +9 -9
- package/support/test/query.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-sql",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "SQL backing for the travetto model module, with real-time modeling support for SQL schemas.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sql",
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
"directory": "module/model-sql"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@travetto/cli": "^6.0.
|
|
31
|
-
"@travetto/config": "^6.0.
|
|
32
|
-
"@travetto/context": "^6.0.
|
|
33
|
-
"@travetto/model": "^6.0.
|
|
34
|
-
"@travetto/model-query": "^6.0.
|
|
30
|
+
"@travetto/cli": "^6.0.1",
|
|
31
|
+
"@travetto/config": "^6.0.1",
|
|
32
|
+
"@travetto/context": "^6.0.1",
|
|
33
|
+
"@travetto/model": "^6.0.1",
|
|
34
|
+
"@travetto/model-query": "^6.0.1"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@travetto/test": "^6.0.
|
|
37
|
+
"@travetto/test": "^6.0.2"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@travetto/test": {
|
package/src/dialect/base.ts
CHANGED
|
@@ -286,7 +286,7 @@ export abstract class SQLDialect implements DialectState {
|
|
|
286
286
|
* Remove a sql column
|
|
287
287
|
*/
|
|
288
288
|
getDropColumnSQL(stack: VisitStack[]): string {
|
|
289
|
-
const field = stack
|
|
289
|
+
const field = stack.at(-1)!;
|
|
290
290
|
return `ALTER TABLE ${this.parentTable(stack)} DROP COLUMN ${this.ident(field.name)};`;
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -294,7 +294,7 @@ export abstract class SQLDialect implements DialectState {
|
|
|
294
294
|
* Add a sql column
|
|
295
295
|
*/
|
|
296
296
|
getAddColumnSQL(stack: VisitStack[]): string {
|
|
297
|
-
const field: FieldConfig = castTo(stack
|
|
297
|
+
const field: FieldConfig = castTo(stack.at(-1));
|
|
298
298
|
return `ALTER TABLE ${this.parentTable(stack)} ADD COLUMN ${this.getColumnDefinition(field)};`;
|
|
299
299
|
}
|
|
300
300
|
|
|
@@ -385,7 +385,7 @@ export abstract class SQLDialect implements DialectState {
|
|
|
385
385
|
*/
|
|
386
386
|
resolveName(stack: VisitStack[]): string {
|
|
387
387
|
const path = this.namespaceParent(stack);
|
|
388
|
-
const name = stack
|
|
388
|
+
const name = stack.at(-1)!.name;
|
|
389
389
|
const cache = this.getAliasCache(stack, this.namespace);
|
|
390
390
|
const base = cache.get(path)!;
|
|
391
391
|
return this.alias(name, base.alias);
|
|
@@ -630,7 +630,7 @@ ${this.getLimitSQL(cls, query)}`;
|
|
|
630
630
|
}
|
|
631
631
|
|
|
632
632
|
getCreateTableSQL(stack: VisitStack[]): string {
|
|
633
|
-
const config = stack
|
|
633
|
+
const config = stack.at(-1)!;
|
|
634
634
|
const parent = stack.length > 1;
|
|
635
635
|
const array = parent && config.array;
|
|
636
636
|
const fields = SchemaRegistry.has(config.type) ?
|
|
@@ -752,7 +752,7 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
|
|
|
752
752
|
* Get INSERT sql for a given instance and a specific stack location
|
|
753
753
|
*/
|
|
754
754
|
getInsertSQL(stack: VisitStack[], instances: InsertWrapper['records']): string | undefined {
|
|
755
|
-
const config = stack
|
|
755
|
+
const config = stack.at(-1)!;
|
|
756
756
|
const columns = SQLModelUtil.getFieldsByLocation(stack).local
|
|
757
757
|
.filter(x => !SchemaRegistry.has(x.type))
|
|
758
758
|
.toSorted((a, b) => a.name.localeCompare(b.name));
|
|
@@ -767,7 +767,7 @@ CREATE TABLE IF NOT EXISTS ${this.table(stack)} (
|
|
|
767
767
|
if (el.value === null || el.value === undefined) {
|
|
768
768
|
continue;
|
|
769
769
|
} else if (Array.isArray(el.value)) {
|
|
770
|
-
const name = el.stack
|
|
770
|
+
const name = el.stack.at(-1)!.name;
|
|
771
771
|
for (const sel of el.value) {
|
|
772
772
|
newInstances.push({
|
|
773
773
|
stack: el.stack,
|
|
@@ -836,7 +836,7 @@ ${matrix.map(row => `(${row.join(', ')})`).join(',\n')};`;
|
|
|
836
836
|
* Simple data base updates
|
|
837
837
|
*/
|
|
838
838
|
getUpdateSQL(stack: VisitStack[], data: Record<string, unknown>, where?: WhereClause<unknown>): string {
|
|
839
|
-
const { type } = stack
|
|
839
|
+
const { type } = stack.at(-1)!;
|
|
840
840
|
const { localMap } = SQLModelUtil.getFieldsByLocation(stack);
|
|
841
841
|
return `
|
|
842
842
|
UPDATE ${this.table(stack)} ${this.rootAlias}
|
|
@@ -849,7 +849,7 @@ SET
|
|
|
849
849
|
}
|
|
850
850
|
|
|
851
851
|
getDeleteSQL(stack: VisitStack[], where?: WhereClause<unknown>): string {
|
|
852
|
-
const { type } = stack
|
|
852
|
+
const { type } = stack.at(-1)!;
|
|
853
853
|
return `
|
|
854
854
|
DELETE
|
|
855
855
|
FROM ${this.table(stack)} ${this.rootAlias}
|
|
@@ -860,7 +860,7 @@ ${this.getWhereSQL(type, where)};`;
|
|
|
860
860
|
* Get elements by ids
|
|
861
861
|
*/
|
|
862
862
|
getSelectRowsByIdsSQL(stack: VisitStack[], ids: string[], select: FieldConfig[] = []): string {
|
|
863
|
-
const config = stack
|
|
863
|
+
const config = stack.at(-1)!;
|
|
864
864
|
const orderBy = !config.array ?
|
|
865
865
|
'' :
|
|
866
866
|
`ORDER BY ${this.rootAlias}.${this.idxField.name} ASC`;
|
|
@@ -889,7 +889,7 @@ ${this.getWhereSQL(cls, where!)}`;
|
|
|
889
889
|
const selectStack: (SelectClause<T> | undefined)[] = [];
|
|
890
890
|
|
|
891
891
|
const buildSet = (children: unknown[], field?: FieldConfig): Record<string, unknown> =>
|
|
892
|
-
SQLModelUtil.collectDependents(this, stack
|
|
892
|
+
SQLModelUtil.collectDependents(this, stack.at(-1)!, children, field);
|
|
893
893
|
|
|
894
894
|
await SQLModelUtil.visitSchema(SchemaRegistry.get(cls), {
|
|
895
895
|
onRoot: async (config) => {
|
|
@@ -899,9 +899,9 @@ ${this.getWhereSQL(cls, where!)}`;
|
|
|
899
899
|
await config.descend();
|
|
900
900
|
},
|
|
901
901
|
onSub: async ({ config, descend, fields, path }) => {
|
|
902
|
-
const top = stack
|
|
902
|
+
const top = stack.at(-1)!;
|
|
903
903
|
const ids = Object.keys(top);
|
|
904
|
-
const selectTop = selectStack
|
|
904
|
+
const selectTop = selectStack.at(-1)!;
|
|
905
905
|
const fieldKey = castKey<RetainFields<T>>(config.name);
|
|
906
906
|
const subSelectTop: SelectClause<T> | undefined = castTo(selectTop?.[fieldKey]);
|
|
907
907
|
|
|
@@ -937,7 +937,7 @@ ${this.getWhereSQL(cls, where!)}`;
|
|
|
937
937
|
}
|
|
938
938
|
},
|
|
939
939
|
onSimple: async ({ config, path }): Promise<void> => {
|
|
940
|
-
const top = stack
|
|
940
|
+
const top = stack.at(-1)!;
|
|
941
941
|
const ids = Object.keys(top);
|
|
942
942
|
if (ids.length) {
|
|
943
943
|
const { records: matching } = await this.executeSQL(this.getSelectRowsByIdsSQL(
|
|
@@ -956,7 +956,7 @@ ${this.getWhereSQL(cls, where!)}`;
|
|
|
956
956
|
* Delete all ids
|
|
957
957
|
*/
|
|
958
958
|
async deleteByIds(stack: VisitStack[], ids: string[]): Promise<number> {
|
|
959
|
-
return this.deleteAndGetCount<ModelType>(stack
|
|
959
|
+
return this.deleteAndGetCount<ModelType>(stack.at(-1)!.type, {
|
|
960
960
|
where: {
|
|
961
961
|
[stack.length === 1 ? this.idField.name : this.pathField.name]: {
|
|
962
962
|
$in: ids
|
package/src/util.ts
CHANGED
|
@@ -18,7 +18,7 @@ type FieldCacheEntry = {
|
|
|
18
18
|
*/
|
|
19
19
|
export class SQLModelUtil {
|
|
20
20
|
|
|
21
|
-
static
|
|
21
|
+
static #schemaFieldsCache = new Map<Class, FieldCacheEntry>();
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Creates a new visitation stack with the class as the root
|
|
@@ -53,11 +53,11 @@ export class SQLModelUtil {
|
|
|
53
53
|
* Get all available fields at current stack path
|
|
54
54
|
*/
|
|
55
55
|
static getFieldsByLocation(stack: VisitStack[]): FieldCacheEntry {
|
|
56
|
-
const top = stack
|
|
56
|
+
const top = stack.at(-1)!;
|
|
57
57
|
const cls = SchemaRegistry.get(top.type);
|
|
58
58
|
|
|
59
|
-
if (cls && this.
|
|
60
|
-
return this.
|
|
59
|
+
if (cls && this.#schemaFieldsCache.has(cls.class)) {
|
|
60
|
+
return this.#schemaFieldsCache.get(cls.class)!;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
if (!cls) { // If a simple type, it is it's own field
|
|
@@ -96,7 +96,7 @@ export class SQLModelUtil {
|
|
|
96
96
|
ret.local.reduce((acc, f) => (acc[f.name] = f) && acc, ret.localMap);
|
|
97
97
|
ret.foreign.reduce((acc, f) => (acc[f.name] = f) && acc, ret.foreignMap);
|
|
98
98
|
|
|
99
|
-
this.
|
|
99
|
+
this.#schemaFieldsCache.set(cls.class, ret);
|
|
100
100
|
|
|
101
101
|
return ret;
|
|
102
102
|
}
|
|
@@ -171,8 +171,8 @@ export class SQLModelUtil {
|
|
|
171
171
|
},
|
|
172
172
|
onSub: (config) => {
|
|
173
173
|
const { config: field } = config;
|
|
174
|
-
const topObj: Record<string, unknown> = castTo(pathObj
|
|
175
|
-
const top = config.path
|
|
174
|
+
const topObj: Record<string, unknown> = castTo(pathObj.at(-1));
|
|
175
|
+
const top = config.path.at(-1)!;
|
|
176
176
|
|
|
177
177
|
if (field.name in topObj) {
|
|
178
178
|
const value = topObj[field.name];
|
|
@@ -199,7 +199,7 @@ export class SQLModelUtil {
|
|
|
199
199
|
},
|
|
200
200
|
onSimple: (config) => {
|
|
201
201
|
const { config: field } = config;
|
|
202
|
-
const topObj: Record<string, unknown> = castTo(pathObj
|
|
202
|
+
const topObj: Record<string, unknown> = castTo(pathObj.at(-1));
|
|
203
203
|
const value = topObj[field.name];
|
|
204
204
|
return handler.onSimple({ ...config, value });
|
|
205
205
|
}
|
|
@@ -294,7 +294,7 @@ export class SQLModelUtil {
|
|
|
294
294
|
* Build table name via stack path
|
|
295
295
|
*/
|
|
296
296
|
static buildTable(list: VisitStack[]): string {
|
|
297
|
-
const top = list
|
|
297
|
+
const top = list.at(-1)!;
|
|
298
298
|
if (!top[TableSymbol]) {
|
|
299
299
|
top[TableSymbol] = list.map((el, i) => i === 0 ? ModelRegistry.getStore(el.type) : el.name).join('_');
|
|
300
300
|
}
|
package/support/test/query.ts
CHANGED
|
@@ -67,8 +67,8 @@ export abstract class BaseSQLTest extends BaseModelSuite<SQLModelService> {
|
|
|
67
67
|
|
|
68
68
|
const dct = await this.dialect;
|
|
69
69
|
dct.resolveName = (stack: VisitStack[]) => {
|
|
70
|
-
const field: FieldConfig = castTo(stack
|
|
71
|
-
const parent: FieldConfig = castTo(stack
|
|
70
|
+
const field: FieldConfig = castTo(stack.at(-1));
|
|
71
|
+
const parent: FieldConfig = castTo(stack.at(-2));
|
|
72
72
|
return `${field.owner ? field.owner.name : parent.name}.${field.name}`;
|
|
73
73
|
};
|
|
74
74
|
|
|
@@ -80,7 +80,7 @@ export abstract class BaseSQLTest extends BaseModelSuite<SQLModelService> {
|
|
|
80
80
|
async testRegEx() {
|
|
81
81
|
const dct = await this.dialect;
|
|
82
82
|
dct.resolveName = (stack: VisitStack[]) => {
|
|
83
|
-
const field: FieldConfig = castTo(stack
|
|
83
|
+
const field: FieldConfig = castTo(stack.at(-1));
|
|
84
84
|
return `${field.owner?.name}.${field.name}`;
|
|
85
85
|
};
|
|
86
86
|
|