@deterministic-code/datasources 0.1.10 → 0.1.12
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/BatchCommandIBulkWriteStrategy.d.ts +1 -0
- package/dist/BatchCommandIBulkWriteStrategy.js +12 -4
- package/dist/CRUDRepository.d.ts +2 -0
- package/dist/CRUDRepository.js +15 -5
- package/dist/CRUDRepositoryBuilder.d.ts +4 -0
- package/dist/CRUDRepositoryBuilder.js +9 -0
- package/dist/CRUDRepositoryOptions.d.ts +2 -0
- package/dist/NestedSelectBuilder.d.ts +6 -0
- package/dist/NestedSelectBuilder.js +63 -0
- package/dist/NestedSelectBuilderOptions.d.ts +5 -0
- package/dist/NestedSelectBuilderOptions.js +1 -0
- package/dist/NestedSelectRelation.d.ts +9 -0
- package/dist/NestedSelectRelation.js +1 -0
- package/dist/NestedSelectRelationKind.d.ts +1 -0
- package/dist/NestedSelectRelationKind.js +1 -0
- package/dist/NestedSelectStatement.d.ts +10 -0
- package/dist/NestedSelectStatement.js +1 -0
- package/dist/NestedSelectType.d.ts +7 -0
- package/dist/NestedSelectType.js +1 -0
- package/dist/RepositoryBuilderOptionsFactory.d.ts +8 -0
- package/dist/RepositoryBuilderOptionsFactory.js +12 -0
- package/dist/SelectFieldAliases.d.ts +14 -0
- package/dist/SelectFieldAliases.js +62 -0
- package/dist/StatementMappers.d.ts +1 -0
- package/dist/StatementMappers.js +21 -28
- package/dist/index.d.ts +9 -2
- package/dist/index.js +3 -1
- package/dist/statements/Aggregate.d.ts +4 -4
- package/dist/statements/Aggregate.js +5 -5
- package/dist/statements/CreateNestedReadStoredProcedureStatement.d.ts +14 -0
- package/dist/statements/CreateNestedReadStoredProcedureStatement.js +37 -0
- package/dist/statements/CreateNestedReadStoredProcedureStatementTextRenderer.d.ts +4 -0
- package/dist/statements/CreateNestedReadStoredProcedureStatementTextRenderer.js +5 -0
- package/dist/statements/ICreateNestedReadStoredProcedureStatement.d.ts +8 -0
- package/dist/statements/ICreateNestedReadStoredProcedureStatement.js +1 -0
- package/dist/statements/IStatementVisitor.d.ts +2 -0
- package/dist/statements/NestedWhereArgument.d.ts +5 -0
- package/dist/statements/NestedWhereArgument.js +1 -0
- package/dist/statements/SelectStatement.d.ts +1 -0
- package/dist/statements/SelectStatement.js +2 -0
- package/dist/statements/SelectStatementOptions.d.ts +1 -0
- package/dist/statements/SelectStatementTextRenderer.js +6 -1
- package/dist/statements/StatementRenderer.d.ts +3 -0
- package/dist/statements/StatementRenderer.js +5 -0
- package/dist/statements/Where.js +1 -0
- package/dist/statements/index.d.ts +4 -0
- package/dist/statements/index.js +2 -0
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ const empty = () => ({ result: null, rowsAffected: 0 });
|
|
|
9
9
|
const budget = 8000;
|
|
10
10
|
const maxRows = 250;
|
|
11
11
|
const assigned = (value) => value !== null && value !== "" && value !== 0 && value !== 0n;
|
|
12
|
+
const listed = (list, col, fallback) => list === undefined ? fallback : list.includes(col);
|
|
12
13
|
const columnsOf = (rows) => {
|
|
13
14
|
const seen = new Set();
|
|
14
15
|
const columns = [];
|
|
@@ -83,12 +84,12 @@ export class BatchCommandIBulkWriteStrategy {
|
|
|
83
84
|
};
|
|
84
85
|
mappedInsert = (item) => {
|
|
85
86
|
const record = this.reverse(item);
|
|
86
|
-
const statement = this.statements().insert(this.fields(record, (col) => !this.ids.includes(col) || assigned(record[col] ?? null)));
|
|
87
|
+
const statement = this.statements().insert(this.fields(record, (col) => listed(this.options.createProperties, col, !this.ids.includes(col) || assigned(record[col] ?? null))));
|
|
87
88
|
return { table: statement.table, fields: statement.fields };
|
|
88
89
|
};
|
|
89
90
|
mappedUpdate = (item) => {
|
|
90
91
|
const record = this.reverse(item);
|
|
91
|
-
const fields = this.fields(record, (col) => !this.ids.includes(col));
|
|
92
|
+
const fields = this.fields(record, (col) => listed(this.options.updateProperties, col, !this.ids.includes(col)));
|
|
92
93
|
if (fields.length === 0)
|
|
93
94
|
throw new DatasourceError("Update requires at least one non-Id field");
|
|
94
95
|
const statement = this.statements().update(fields, this.idsWhere(record), (name, value) => this.cell(name, value, true));
|
|
@@ -101,7 +102,7 @@ export class BatchCommandIBulkWriteStrategy {
|
|
|
101
102
|
};
|
|
102
103
|
updateCommand = (item, byWhere) => {
|
|
103
104
|
const record = this.reverse(item);
|
|
104
|
-
const fields = this.fields(record, (col) => !this.ids.includes(col));
|
|
105
|
+
const fields = this.fields(record, (col) => listed(this.options.updateProperties, col, !this.ids.includes(col)));
|
|
105
106
|
if (fields.length === 0)
|
|
106
107
|
throw new DatasourceError("Update requires at least one non-Id field");
|
|
107
108
|
const statement = this.statements().update(fields, byWhere ?? this.idsWhere(record), (name, value) => this.cell(name, value, byWhere === undefined));
|
|
@@ -127,8 +128,15 @@ export class BatchCommandIBulkWriteStrategy {
|
|
|
127
128
|
const row = objects.reverseConvert(item);
|
|
128
129
|
return this.options.rowConverter ? this.options.rowConverter.reverseConvert(row) : row;
|
|
129
130
|
};
|
|
131
|
+
writable = (key) => {
|
|
132
|
+
const columns = this.statements().readColumns;
|
|
133
|
+
const map = this.options.propertyMappings;
|
|
134
|
+
return (columns.length === 0 ||
|
|
135
|
+
columns.includes(key) ||
|
|
136
|
+
(map !== undefined && columns.some((name) => map.map(name) === key)));
|
|
137
|
+
};
|
|
130
138
|
fields = (record, include) => Object.entries(record)
|
|
131
|
-
.filter(([key, value]) => include(key) && value !== null && value !== undefined)
|
|
139
|
+
.filter(([key, value]) => include(key) && this.writable(key) && value !== null && value !== undefined)
|
|
132
140
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
133
141
|
.map(([name, value]) => ({ name, value: this.cell(name, value, true) }));
|
|
134
142
|
cell = (property, value, fieldsApplied) => fieldsApplied
|
package/dist/CRUDRepository.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ import type { IReadonlyEnrichmentStrategy } from "./IReadonlyEnrichmentStrategy.
|
|
|
12
12
|
import type { IReadonlyRepository } from "./IReadonlyRepository.js";
|
|
13
13
|
export declare class CRUDRepository<T = Cells> extends ReadonlyRepository<T> implements ICRUDRepository<T> {
|
|
14
14
|
readonly ids: readonly string[];
|
|
15
|
+
private readonly createProperties?;
|
|
16
|
+
private readonly updateProperties?;
|
|
15
17
|
private readonly crudStatements;
|
|
16
18
|
private readonly tree;
|
|
17
19
|
private readonly write;
|
package/dist/CRUDRepository.js
CHANGED
|
@@ -11,8 +11,14 @@ import { UnitOfWorkTransaction } from "./UnitOfWorkTransaction.js";
|
|
|
11
11
|
import { RepositoryTree } from "./RepositoryTree.js";
|
|
12
12
|
import { RepositoryTreeNode } from "./RepositoryTreeNode.js";
|
|
13
13
|
const assigned = (value) => value !== null && value !== "" && value !== 0 && value !== 0n;
|
|
14
|
-
const
|
|
15
|
-
|
|
14
|
+
const listed = (list, col, fallback) => list === undefined ? fallback : list.includes(col);
|
|
15
|
+
const writable = (key, columns, column) => columns.length === 0 || columns.includes(key) || columns.some((name) => column(name) === key);
|
|
16
|
+
const fieldsOf = (record, include, cell, enrichmentInto, columns, column) => Object.entries(record)
|
|
17
|
+
.filter(([key, value]) => include(key) &&
|
|
18
|
+
writable(key, columns, column) &&
|
|
19
|
+
!enrichmentInto(key) &&
|
|
20
|
+
value !== null &&
|
|
21
|
+
value !== undefined)
|
|
16
22
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
17
23
|
.map(([name, value]) => ({ name, value: cell(name, value, true) }));
|
|
18
24
|
const isCells = (id) => typeof id === "object" && id !== null;
|
|
@@ -29,6 +35,8 @@ const identified = (row, column) => {
|
|
|
29
35
|
const scalarOf = (value) => value === undefined || value === null || typeof value === "object" ? undefined : value;
|
|
30
36
|
export class CRUDRepository extends ReadonlyRepository {
|
|
31
37
|
ids;
|
|
38
|
+
createProperties;
|
|
39
|
+
updateProperties;
|
|
32
40
|
crudStatements;
|
|
33
41
|
tree;
|
|
34
42
|
write;
|
|
@@ -40,6 +48,8 @@ export class CRUDRepository extends ReadonlyRepository {
|
|
|
40
48
|
const opened = repositoryParts(typeOrConnection, options);
|
|
41
49
|
super(opened.built);
|
|
42
50
|
this.ids = opened.built.ids;
|
|
51
|
+
this.createProperties = options.createProperties;
|
|
52
|
+
this.updateProperties = options.updateProperties;
|
|
43
53
|
this.crudStatements = opened.statements;
|
|
44
54
|
this.tree = new RepositoryTree(new RepositoryTreeNode(this, ""));
|
|
45
55
|
this.write = options.write ?? new DefaultWriteEnrichmentStrategy();
|
|
@@ -101,7 +111,7 @@ export class CRUDRepository extends ReadonlyRepository {
|
|
|
101
111
|
readSingleById = async (id) => this.readSingle(this.byId(id));
|
|
102
112
|
insert = async (item) => {
|
|
103
113
|
const record = this.reverseConvert(item);
|
|
104
|
-
const fields = fieldsOf(record, (col) => !this.ids.includes(col) || assigned(record[col] ?? null), this.cell, this.enrichmentInto);
|
|
114
|
+
const fields = fieldsOf(record, (col) => listed(this.createProperties, col, !this.ids.includes(col) || assigned(record[col] ?? null)), this.cell, this.enrichmentInto, this.crudStatements.readColumns, this.column);
|
|
105
115
|
const statement = this.crudStatements.insert(fields);
|
|
106
116
|
const response = await execute(this.command(), statement, statement.fields);
|
|
107
117
|
if (this.ids.length === 1 && !fields.some((field) => field.name === this.ids[0]))
|
|
@@ -136,7 +146,7 @@ export class CRUDRepository extends ReadonlyRepository {
|
|
|
136
146
|
idValue = (item) => scalarOf(item[this.ids[0]]);
|
|
137
147
|
save = async (item, byWhere) => {
|
|
138
148
|
const record = this.reverseConvert(item);
|
|
139
|
-
const fields = fieldsOf(record, (col) => !this.ids.includes(col), this.cell, this.enrichmentInto);
|
|
149
|
+
const fields = fieldsOf(record, (col) => listed(this.updateProperties, col, !this.ids.includes(col)), this.cell, this.enrichmentInto, this.crudStatements.readColumns, this.column);
|
|
140
150
|
if (fields.length === 0)
|
|
141
151
|
throw new DatasourceError("Update requires at least one non-Id field");
|
|
142
152
|
const statement = this.crudStatements.update(fields, byWhere ?? this.idWhere(record), (name, value) => this.cell(name, value, byWhere === undefined));
|
|
@@ -149,7 +159,7 @@ export class CRUDRepository extends ReadonlyRepository {
|
|
|
149
159
|
const parameters = listed.length
|
|
150
160
|
? listed
|
|
151
161
|
: DefaultStatementTextRenderer.instance.render(statement).includes("$")
|
|
152
|
-
? fieldsOf(record, () => true, this.cell, this.enrichmentInto)
|
|
162
|
+
? fieldsOf(record, () => true, this.cell, this.enrichmentInto, this.crudStatements.readColumns, this.column)
|
|
153
163
|
: [];
|
|
154
164
|
return execute(this.command(), statement, parameters);
|
|
155
165
|
};
|
|
@@ -12,7 +12,11 @@ export declare const repositoryParts: <T>(typeOrConnection: Constructable<T> | I
|
|
|
12
12
|
statements: CRUDRepositoryStatements;
|
|
13
13
|
};
|
|
14
14
|
export declare class CRUDRepositoryBuilder<T = object> extends ReadonlyRepositoryBuilder<T> {
|
|
15
|
+
private readonly factory;
|
|
15
16
|
crudStatements?: CRUDRepositoryStatements;
|
|
17
|
+
add(options: CRUDRepositoryOptions<T>): this;
|
|
18
|
+
add(dialect: string, options: CRUDRepositoryOptions<T>): this;
|
|
19
|
+
for: (connection: IConnection) => CRUDRepositoryOptions<T>;
|
|
16
20
|
protected ids: (options: ReadonlyRepositoryMappingOptions<T>) => string[];
|
|
17
21
|
protected statements: (table: string, columns: string[]) => ReadonlyRepositoryStatements;
|
|
18
22
|
build: (connection: IConnection, options: CRUDRepositoryOptions<T>) => CRUDRepository<T>;
|
|
@@ -3,6 +3,7 @@ import { CRUDRepository } from "./CRUDRepository.js";
|
|
|
3
3
|
import { CRUDRepositoryStatements } from "./CRUDRepositoryStatements.js";
|
|
4
4
|
import { ReadonlyRepositoryBuilder } from "./ReadonlyRepositoryBuilder.js";
|
|
5
5
|
import { ReadonlyRepositoryStatements } from "./ReadonlyRepositoryStatements.js";
|
|
6
|
+
import { RepositoryBuilderOptionsFactory } from "./RepositoryBuilderOptionsFactory.js";
|
|
6
7
|
const isCrud = (options) => "ids" in options || "write" in options;
|
|
7
8
|
const withIds = (options) => "ids" in options
|
|
8
9
|
? options
|
|
@@ -18,7 +19,15 @@ export const repositoryParts = (typeOrConnection, connectionOrOptions) => {
|
|
|
18
19
|
return { built, statements: builder.crudStatements };
|
|
19
20
|
};
|
|
20
21
|
export class CRUDRepositoryBuilder extends ReadonlyRepositoryBuilder {
|
|
22
|
+
factory = new RepositoryBuilderOptionsFactory();
|
|
21
23
|
crudStatements;
|
|
24
|
+
add(dialectOrOptions, options) {
|
|
25
|
+
typeof dialectOrOptions === "string"
|
|
26
|
+
? this.factory.add(dialectOrOptions, options)
|
|
27
|
+
: this.factory.add(dialectOrOptions);
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
for = (connection) => this.factory.for(connection.provider);
|
|
22
31
|
ids = (options) => isCrud(options)
|
|
23
32
|
? (options.ids ?? (options.type ? defaultId(fieldNamesOf(options.type)) : ["id"]))
|
|
24
33
|
: [];
|
|
@@ -3,5 +3,7 @@ import type { Cells } from "./converters/Cell.js";
|
|
|
3
3
|
import type { IWriteEnrichmentStrategy } from "./IWriteEnrichmentStrategy.js";
|
|
4
4
|
export type CRUDRepositoryOptions<T = Cells> = ReadonlyRepositoryMappingOptions<T> & {
|
|
5
5
|
ids?: string[];
|
|
6
|
+
createProperties?: string[];
|
|
7
|
+
updateProperties?: string[];
|
|
6
8
|
write?: IWriteEnrichmentStrategy<T>;
|
|
7
9
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NestedSelectBuilderOptions } from "./NestedSelectBuilderOptions.js";
|
|
2
|
+
import type { NestedSelectStatement } from "./NestedSelectStatement.js";
|
|
3
|
+
import type { NestedSelectType } from "./NestedSelectType.js";
|
|
4
|
+
export declare class NestedSelectBuilder {
|
|
5
|
+
build(root: NestedSelectType, options?: NestedSelectBuilderOptions): NestedSelectStatement;
|
|
6
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { selectFieldAliases } from "./SelectFieldAliases.js";
|
|
2
|
+
import { Join } from "./statements/Join.js";
|
|
3
|
+
import { SelectStatement } from "./statements/SelectStatement.js";
|
|
4
|
+
export class NestedSelectBuilder {
|
|
5
|
+
build(root, options) {
|
|
6
|
+
const stopAt = options?.stopAt ?? [];
|
|
7
|
+
const fields = [];
|
|
8
|
+
const joins = [];
|
|
9
|
+
walk(root, root.name, root.name, "", stopAt, false, fields, joins);
|
|
10
|
+
const aliases = selectFieldAliases(root.name, fields);
|
|
11
|
+
const byPath = Object.fromEntries(fields.map((field, i) => [field, aliases[i]]));
|
|
12
|
+
return {
|
|
13
|
+
select: new SelectStatement({
|
|
14
|
+
table: root.name,
|
|
15
|
+
fields,
|
|
16
|
+
joins,
|
|
17
|
+
where: options?.where,
|
|
18
|
+
}),
|
|
19
|
+
map: mapOf(root, root.name, "", stopAt, byPath),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const walk = (type, fieldPrefix, joinEntity, stopPrefix, stopAt, outer, fields, joins) => {
|
|
24
|
+
for (const property of type.properties)
|
|
25
|
+
fields.push(`${fieldPrefix}.${property}`);
|
|
26
|
+
for (const relation of type.relations) {
|
|
27
|
+
const path = stopPrefix.length === 0 ? relation.name : `${stopPrefix}.${relation.name}`;
|
|
28
|
+
if (stopped(stopAt, path))
|
|
29
|
+
continue;
|
|
30
|
+
const list = relation.kind === "list";
|
|
31
|
+
joins.push(list || outer
|
|
32
|
+
? Join.left(relation.target.name, `${joinEntity}.${relation.from}`, `${relation.target.name}.${relation.to}`)
|
|
33
|
+
: Join.inner(relation.target.name, `${joinEntity}.${relation.from}`, `${relation.target.name}.${relation.to}`));
|
|
34
|
+
walk(relation.target, `${fieldPrefix}.${relation.target.name}`, relation.target.name, path, stopAt, outer || list, fields, joins);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const mapOf = (type, fieldPrefix, stopPrefix, stopAt, aliases) => ({
|
|
38
|
+
key: aliases[`${fieldPrefix}.${type.key}`],
|
|
39
|
+
fields: fieldsOf(type, fieldPrefix, stopPrefix, stopAt, aliases),
|
|
40
|
+
});
|
|
41
|
+
const fieldsOf = (type, fieldPrefix, stopPrefix, stopAt, aliases) => {
|
|
42
|
+
const fields = {};
|
|
43
|
+
for (const property of type.properties) {
|
|
44
|
+
const alias = aliases[`${fieldPrefix}.${property}`];
|
|
45
|
+
fields[alias] = alias;
|
|
46
|
+
}
|
|
47
|
+
for (const relation of type.relations) {
|
|
48
|
+
const path = stopPrefix.length === 0 ? relation.name : `${stopPrefix}.${relation.name}`;
|
|
49
|
+
if (stopped(stopAt, path))
|
|
50
|
+
continue;
|
|
51
|
+
const childPrefix = `${fieldPrefix}.${relation.target.name}`;
|
|
52
|
+
if (relation.kind === "list") {
|
|
53
|
+
fields[relation.name] = {
|
|
54
|
+
key: aliases[`${childPrefix}.${relation.target.key}`],
|
|
55
|
+
fields: fieldsOf(relation.target, childPrefix, path, stopAt, aliases),
|
|
56
|
+
};
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
Object.assign(fields, fieldsOf(relation.target, childPrefix, path, stopAt, aliases));
|
|
60
|
+
}
|
|
61
|
+
return fields;
|
|
62
|
+
};
|
|
63
|
+
const stopped = (stopAt, path) => stopAt.some((item) => item === path || path.startsWith(`${item}.`));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NestedSelectRelationKind } from "./NestedSelectRelationKind.js";
|
|
2
|
+
import type { NestedSelectType } from "./NestedSelectType.js";
|
|
3
|
+
export type NestedSelectRelation = {
|
|
4
|
+
name: string;
|
|
5
|
+
kind: NestedSelectRelationKind;
|
|
6
|
+
from: string;
|
|
7
|
+
to: string;
|
|
8
|
+
target: NestedSelectType;
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type NestedSelectRelationKind = "object" | "list";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TypeMapGroup } from "./mappers/TypeMapGroup.js";
|
|
2
|
+
import type { SelectStatement } from "./statements/SelectStatement.js";
|
|
3
|
+
export type NestedSelectMapField = string | TypeMapGroup<Record<string, string>>;
|
|
4
|
+
export type NestedSelectStatement = {
|
|
5
|
+
select: SelectStatement;
|
|
6
|
+
map: {
|
|
7
|
+
key: string;
|
|
8
|
+
fields: Record<string, NestedSelectMapField>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CRUDRepositoryOptions } from "./CRUDRepositoryOptions.js";
|
|
2
|
+
export declare class RepositoryBuilderOptionsFactory<T = object> {
|
|
3
|
+
private fallback?;
|
|
4
|
+
private readonly items;
|
|
5
|
+
add(options: CRUDRepositoryOptions<T>): this;
|
|
6
|
+
add(dialect: string, options: CRUDRepositoryOptions<T>): this;
|
|
7
|
+
for: (provider: string) => CRUDRepositoryOptions<T>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DatasourceError } from "./DatasourceError.js";
|
|
2
|
+
export class RepositoryBuilderOptionsFactory {
|
|
3
|
+
fallback;
|
|
4
|
+
items = new Map();
|
|
5
|
+
add(dialectOrOptions, options) {
|
|
6
|
+
typeof dialectOrOptions === "string"
|
|
7
|
+
? this.items.set(dialectOrOptions, options)
|
|
8
|
+
: (this.fallback = dialectOrOptions);
|
|
9
|
+
return this;
|
|
10
|
+
}
|
|
11
|
+
for = (provider) => this.items.get(provider) ?? this.fallback ?? (() => { throw new DatasourceError("repository options required"); })();
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type PathParts = {
|
|
2
|
+
owner: string;
|
|
3
|
+
last: string;
|
|
4
|
+
root: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare const selectFieldAliases: (table: string, fields: readonly string[], aliases?: readonly (string | undefined)[]) => (string | undefined)[];
|
|
7
|
+
export declare const applySelectFieldAlias: (field: string, alias?: string) => string;
|
|
8
|
+
export declare const pathOf: (field: string, table: string) => PathParts | undefined;
|
|
9
|
+
export declare const functionOf: (field: string) => {
|
|
10
|
+
name: string;
|
|
11
|
+
inner: string;
|
|
12
|
+
} | undefined;
|
|
13
|
+
export declare const asIndexOf: (field: string) => number;
|
|
14
|
+
export declare const segments: (name: string) => string[];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const selectFieldAliases = (table, fields, aliases = []) => {
|
|
2
|
+
const result = fields.map(() => undefined);
|
|
3
|
+
const used = new Set();
|
|
4
|
+
for (const [i] of fields.entries()) {
|
|
5
|
+
const alias = aliases[i];
|
|
6
|
+
if (alias !== undefined) {
|
|
7
|
+
result[i] = alias;
|
|
8
|
+
used.add(alias);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
for (const [i, field] of fields.entries()) {
|
|
12
|
+
const path = pathOf(field, table);
|
|
13
|
+
if (result[i] === undefined && path?.root) {
|
|
14
|
+
result[i] = path.last;
|
|
15
|
+
used.add(path.last);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
for (const [i, field] of fields.entries()) {
|
|
19
|
+
const path = pathOf(field, table);
|
|
20
|
+
if (result[i] === undefined && path && !path.root) {
|
|
21
|
+
const alias = used.has(path.last) ? `${path.owner}${path.last}` : path.last;
|
|
22
|
+
result[i] = alias;
|
|
23
|
+
used.add(alias);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
export const applySelectFieldAlias = (field, alias) => alias === undefined ? field : `${field} AS ${alias}`;
|
|
29
|
+
export const pathOf = (field, table) => {
|
|
30
|
+
if (asIndexOf(field) >= 0 || field.includes("("))
|
|
31
|
+
return undefined;
|
|
32
|
+
const parts = segments(field);
|
|
33
|
+
if (parts.length < 2)
|
|
34
|
+
return undefined;
|
|
35
|
+
return {
|
|
36
|
+
owner: parts[parts.length - 2],
|
|
37
|
+
last: parts[parts.length - 1],
|
|
38
|
+
root: parts.length === 2 && parts[0] === table,
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export const functionOf = (field) => {
|
|
42
|
+
const open = field.indexOf("(");
|
|
43
|
+
return open <= 0 || !field.endsWith(")")
|
|
44
|
+
? undefined
|
|
45
|
+
: { name: field.slice(0, open).trim(), inner: field.slice(open + 1, -1).trim() };
|
|
46
|
+
};
|
|
47
|
+
export const asIndexOf = (field) => field.toUpperCase().indexOf(" AS ");
|
|
48
|
+
export const segments = (name) => {
|
|
49
|
+
const parts = [];
|
|
50
|
+
let quoted = false;
|
|
51
|
+
let start = 0;
|
|
52
|
+
for (let i = 0; i < name.length; i++) {
|
|
53
|
+
if (name[i] === '"')
|
|
54
|
+
quoted = !quoted;
|
|
55
|
+
if (name[i] === "." && !quoted) {
|
|
56
|
+
parts.push(name.slice(start, i));
|
|
57
|
+
start = i + 1;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
parts.push(name.slice(start));
|
|
61
|
+
return parts;
|
|
62
|
+
};
|
|
@@ -12,5 +12,6 @@ export declare class StatementMappers implements IMapper<string, string> {
|
|
|
12
12
|
property: (key: string) => string;
|
|
13
13
|
apply: (query: IStatement | undefined, cell: (property: string, value: Cell) => Cell) => IStatement | undefined;
|
|
14
14
|
applyWhere: (where: IWhere | undefined, cell: (property: string, value: Cell) => Cell) => IWhere | undefined;
|
|
15
|
+
private mapSelectFields;
|
|
15
16
|
private mapSelectField;
|
|
16
17
|
}
|
package/dist/StatementMappers.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { DatasourceError } from "./DatasourceError.js";
|
|
2
|
+
import { applySelectFieldAlias, asIndexOf, functionOf, segments, selectFieldAliases } from "./SelectFieldAliases.js";
|
|
1
3
|
import { DeleteStatement } from "./statements/DeleteStatement.js";
|
|
2
4
|
import { InsertStatement } from "./statements/InsertStatement.js";
|
|
3
5
|
import { SelectInsertedIdStatement } from "./statements/SelectInsertedIdStatement.js";
|
|
@@ -12,25 +14,25 @@ export class StatementMappers {
|
|
|
12
14
|
this.propertyMappers = propertyMappers;
|
|
13
15
|
}
|
|
14
16
|
map = (property) => {
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
17
|
+
const parts = segments(property);
|
|
18
|
+
if (parts.length < 2)
|
|
17
19
|
return this.propertyMappers.map(property);
|
|
18
|
-
const qualifier =
|
|
19
|
-
const name =
|
|
20
|
+
const qualifier = parts[parts.length - 2];
|
|
21
|
+
const name = parts[parts.length - 1];
|
|
20
22
|
const mapped = this.propertyMappers.map(name);
|
|
21
23
|
if (mapped !== name && mapped.includes("."))
|
|
22
24
|
return mapped;
|
|
23
25
|
const table = this.entityMappers.map(qualifier);
|
|
24
|
-
return table === qualifier && mapped === name ?
|
|
26
|
+
return table === qualifier && mapped === name ? `${qualifier}.${name}` : `${table}.${mapped}`;
|
|
25
27
|
};
|
|
26
28
|
reverseMap = (key) => {
|
|
27
29
|
const reversed = this.propertyMappers.reverseMap(key);
|
|
28
30
|
if (reversed !== key && this.propertyMappers.map(reversed) === key)
|
|
29
31
|
return reversed;
|
|
30
|
-
const
|
|
31
|
-
if (
|
|
32
|
+
const parts = segments(key);
|
|
33
|
+
if (parts.length < 2)
|
|
32
34
|
return reversed;
|
|
33
|
-
const column =
|
|
35
|
+
const column = parts[parts.length - 1];
|
|
34
36
|
const name = this.propertyMappers.reverseMap(column);
|
|
35
37
|
return name !== column && this.propertyMappers.map(name) === column ? name : reversed;
|
|
36
38
|
};
|
|
@@ -41,7 +43,7 @@ export class StatementMappers {
|
|
|
41
43
|
return new SelectStatement({
|
|
42
44
|
distinct: query.distinct,
|
|
43
45
|
table: this.entityMappers.map(query.table),
|
|
44
|
-
fields: query.fields.
|
|
46
|
+
fields: this.mapSelectFields(query.table, query.fields, query.aliases),
|
|
45
47
|
where: query.where instanceof Where ? this.applyWhere(query.where, cell) : query.where,
|
|
46
48
|
joins: query.joins.map((join) => ({
|
|
47
49
|
kind: join.kind,
|
|
@@ -65,24 +67,15 @@ export class StatementMappers {
|
|
|
65
67
|
return query;
|
|
66
68
|
};
|
|
67
69
|
applyWhere = (where, cell) => where instanceof Where ? where.map(this.column, cell) : where;
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
mapSelectFields = (table, fields, aliases) => {
|
|
71
|
+
const lookup = selectFieldAliases(table, fields, aliases);
|
|
72
|
+
return fields.map((field, i) => this.mapSelectField(field, lookup[i]));
|
|
73
|
+
};
|
|
74
|
+
mapSelectField = (field, alias) => {
|
|
75
|
+
if (asIndexOf(field) >= 0)
|
|
76
|
+
throw new DatasourceError(`Select field "${field}" must be a path`);
|
|
77
|
+
const functionCall = functionOf(field);
|
|
78
|
+
const mapped = functionCall === undefined ? this.map(field) : `${functionCall.name}(${this.map(functionCall.inner)})`;
|
|
79
|
+
return applySelectFieldAlias(mapped, alias);
|
|
76
80
|
};
|
|
77
81
|
}
|
|
78
|
-
const lastDot = (name) => {
|
|
79
|
-
let quoted = false;
|
|
80
|
-
let dot = -1;
|
|
81
|
-
for (let i = 0; i < name.length; i++) {
|
|
82
|
-
if (name[i] === '"')
|
|
83
|
-
quoted = !quoted;
|
|
84
|
-
if (name[i] === "." && !quoted)
|
|
85
|
-
dot = i;
|
|
86
|
-
}
|
|
87
|
-
return dot;
|
|
88
|
-
};
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type { DatasourceOptions } from "./DatasourceOptions.js";
|
|
|
10
10
|
export { DatasourceFactory } from "./DatasourceFactory.js";
|
|
11
11
|
export { ProviderCatalog } from "./ProviderCatalog.js";
|
|
12
12
|
export { DriverLoader } from "./DriverLoader.js";
|
|
13
|
-
export type { ICreateTableStatement, ICreateIndexStatement, IDropTableStatement, IAlterTableStatement, AlterAction, IDropIndexStatement, IDropTriggerStatement, ICreateTriggerStatement, IIdentityInsertStatement, ICreateCreateStoredProcedureStatement, ICreateReadStoredProcedureStatement, ICreateUpdateStoredProcedureStatement, ICreateDeleteStoredProcedureStatement, ICreateBulkCreateStoredProcedureStatement, ICreateBulkUpdateStoredProcedureStatement, ICreateBulkDeleteStoredProcedureStatement, IDropRoutineStatement, RoutineParameter, IDeleteStatement, IExpression, IBulkDeleteStatement, IBulkInsertStatement, IBulkUpdateStatement, IInsertStatement, ISelectStatement, IStatement, IStatementVisitor, ICondition, IConditionVisitor, IExecuteStoredProcedureStatement, IReturnStatement, ITableConstraint, TableConstraintKind, IUpdateStatement, IWhere, } from "./statements/index.js";
|
|
13
|
+
export type { ICreateTableStatement, ICreateIndexStatement, IDropTableStatement, IAlterTableStatement, AlterAction, IDropIndexStatement, IDropTriggerStatement, ICreateTriggerStatement, IIdentityInsertStatement, ICreateCreateStoredProcedureStatement, ICreateReadStoredProcedureStatement, ICreateNestedReadStoredProcedureStatement, NestedWhereArgument, ICreateUpdateStoredProcedureStatement, ICreateDeleteStoredProcedureStatement, ICreateBulkCreateStoredProcedureStatement, ICreateBulkUpdateStoredProcedureStatement, ICreateBulkDeleteStoredProcedureStatement, IDropRoutineStatement, RoutineParameter, IDeleteStatement, IExpression, IBulkDeleteStatement, IBulkInsertStatement, IBulkUpdateStatement, IInsertStatement, ISelectStatement, IStatement, IStatementVisitor, ICondition, IConditionVisitor, IExecuteStoredProcedureStatement, IReturnStatement, ITableConstraint, TableConstraintKind, IUpdateStatement, IWhere, } from "./statements/index.js";
|
|
14
14
|
export type { IReader } from "./IReader.js";
|
|
15
15
|
export type { IRepository } from "./IRepository.js";
|
|
16
16
|
export type { IReadonlyRepository } from "./IReadonlyRepository.js";
|
|
@@ -52,7 +52,14 @@ export { RepositoryTreeNode } from "./RepositoryTreeNode.js";
|
|
|
52
52
|
export { CRUDRepository } from "./CRUDRepository.js";
|
|
53
53
|
export { ReadonlyRepositoryBuilder } from "./ReadonlyRepositoryBuilder.js";
|
|
54
54
|
export { CRUDRepositoryBuilder } from "./CRUDRepositoryBuilder.js";
|
|
55
|
+
export { RepositoryBuilderOptionsFactory } from "./RepositoryBuilderOptionsFactory.js";
|
|
55
56
|
export { StatementMappers } from "./StatementMappers.js";
|
|
57
|
+
export { NestedSelectBuilder } from "./NestedSelectBuilder.js";
|
|
58
|
+
export type { NestedSelectBuilderOptions } from "./NestedSelectBuilderOptions.js";
|
|
59
|
+
export type { NestedSelectRelation } from "./NestedSelectRelation.js";
|
|
60
|
+
export type { NestedSelectRelationKind } from "./NestedSelectRelationKind.js";
|
|
61
|
+
export type { NestedSelectStatement } from "./NestedSelectStatement.js";
|
|
62
|
+
export type { NestedSelectType } from "./NestedSelectType.js";
|
|
56
63
|
export { ReadonlyRepositoryStatements } from "./ReadonlyRepositoryStatements.js";
|
|
57
64
|
export { CRUDRepositoryStatements } from "./CRUDRepositoryStatements.js";
|
|
58
65
|
export type { BuiltRepository } from "./BuiltRepository.js";
|
|
@@ -67,7 +74,7 @@ export { UnitOfWorkTransaction } from "./UnitOfWorkTransaction.js";
|
|
|
67
74
|
export { IsolationLevel } from "./IsolationLevel.js";
|
|
68
75
|
export type { IsolationLevel as IsolationLevelName } from "./IsolationLevel.js";
|
|
69
76
|
export type { Comparison } from "./statements/index.js";
|
|
70
|
-
export { ArrayExpression, CheckConstraint, ColumnDefault, Condition, ConditionRenderer, ExpressionRenderer, CreateIndexStatement, CreateTableStatement, CreateTableStatementTextRenderer, CreateIndexStatementTextRenderer, DropTableStatement, DropTableStatementTextRenderer, AlterTableStatement, AlterTableStatementTextRenderer, DropIndexStatement, DropIndexStatementTextRenderer, DropTriggerStatement, DropTriggerStatementTextRenderer, CreateTriggerStatement, CreateTriggerStatementTextRenderer, IdentityInsertStatement, IdentityInsertStatementTextRenderer, CreateCreateStoredProcedureStatement, CreateReadStoredProcedureStatement, CreateUpdateStoredProcedureStatement, CreateDeleteStoredProcedureStatement, CreateBulkCreateStoredProcedureStatement, CreateBulkUpdateStoredProcedureStatement, CreateBulkDeleteStoredProcedureStatement, CreateCreateStoredProcedureStatementTextRenderer, CreateReadStoredProcedureStatementTextRenderer, CreateUpdateStoredProcedureStatementTextRenderer, CreateDeleteStoredProcedureStatementTextRenderer, CreateBulkCreateStoredProcedureStatementTextRenderer, CreateBulkUpdateStoredProcedureStatementTextRenderer, CreateBulkDeleteStoredProcedureStatementTextRenderer, DropRoutineStatement, DropRoutineStatementTextRenderer, SelectStatementTextRenderer, InsertStatementTextRenderer, UpdateStatementTextRenderer, DeleteStatementTextRenderer, BulkInsertStatementTextRenderer, BulkUpdateStatementTextRenderer, BulkDeleteStatementTextRenderer, ExecuteStoredProcedureStatementTextRenderer, ReturnStatementTextRenderer, SelectInsertedIdStatementTextRenderer, DefaultStatementTextRenderer, DeleteStatement, ForeignKey, Identifier, InsertStatement, BulkInsertStatement, BulkUpdateStatement, BulkDeleteStatement, Literal, NotNull, Operator, eq, ne, gt, lt, ge, le, PrimaryKey, Aggregate, OrderBy, SelectStatement, StatementParser, StatementRenderer, StatementTextRenderer, Native, n, Subquery, ReferentialAction, ExpressionEvaluator, StatementEvaluator, ExecuteStoredProcedureStatement, SelectInsertedIdStatement, ReturnStatement, UniqueConstraint, UpdateStatement, WhereText, Where, Join, } from "./statements/index.js";
|
|
77
|
+
export { ArrayExpression, CheckConstraint, ColumnDefault, Condition, ConditionRenderer, ExpressionRenderer, CreateIndexStatement, CreateTableStatement, CreateTableStatementTextRenderer, CreateIndexStatementTextRenderer, DropTableStatement, DropTableStatementTextRenderer, AlterTableStatement, AlterTableStatementTextRenderer, DropIndexStatement, DropIndexStatementTextRenderer, DropTriggerStatement, DropTriggerStatementTextRenderer, CreateTriggerStatement, CreateTriggerStatementTextRenderer, IdentityInsertStatement, IdentityInsertStatementTextRenderer, CreateCreateStoredProcedureStatement, CreateReadStoredProcedureStatement, CreateNestedReadStoredProcedureStatement, CreateUpdateStoredProcedureStatement, CreateDeleteStoredProcedureStatement, CreateBulkCreateStoredProcedureStatement, CreateBulkUpdateStoredProcedureStatement, CreateBulkDeleteStoredProcedureStatement, CreateCreateStoredProcedureStatementTextRenderer, CreateReadStoredProcedureStatementTextRenderer, CreateNestedReadStoredProcedureStatementTextRenderer, CreateUpdateStoredProcedureStatementTextRenderer, CreateDeleteStoredProcedureStatementTextRenderer, CreateBulkCreateStoredProcedureStatementTextRenderer, CreateBulkUpdateStoredProcedureStatementTextRenderer, CreateBulkDeleteStoredProcedureStatementTextRenderer, DropRoutineStatement, DropRoutineStatementTextRenderer, SelectStatementTextRenderer, InsertStatementTextRenderer, UpdateStatementTextRenderer, DeleteStatementTextRenderer, BulkInsertStatementTextRenderer, BulkUpdateStatementTextRenderer, BulkDeleteStatementTextRenderer, ExecuteStoredProcedureStatementTextRenderer, ReturnStatementTextRenderer, SelectInsertedIdStatementTextRenderer, DefaultStatementTextRenderer, DeleteStatement, ForeignKey, Identifier, InsertStatement, BulkInsertStatement, BulkUpdateStatement, BulkDeleteStatement, Literal, NotNull, Operator, eq, ne, gt, lt, ge, le, PrimaryKey, Aggregate, OrderBy, SelectStatement, StatementParser, StatementRenderer, StatementTextRenderer, Native, n, Subquery, ReferentialAction, ExpressionEvaluator, StatementEvaluator, ExecuteStoredProcedureStatement, SelectInsertedIdStatement, ReturnStatement, UniqueConstraint, UpdateStatement, WhereText, Where, Join, } from "./statements/index.js";
|
|
71
78
|
export type { IDatasourceFactory } from "./IDatasourceFactory.js";
|
|
72
79
|
export type { Parameter } from "./Parameter.js";
|
|
73
80
|
export { ParameterDirection } from "./ParameterDirection.js";
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,9 @@ export { RepositoryTreeNode } from "./RepositoryTreeNode.js";
|
|
|
29
29
|
export { CRUDRepository } from "./CRUDRepository.js";
|
|
30
30
|
export { ReadonlyRepositoryBuilder } from "./ReadonlyRepositoryBuilder.js";
|
|
31
31
|
export { CRUDRepositoryBuilder } from "./CRUDRepositoryBuilder.js";
|
|
32
|
+
export { RepositoryBuilderOptionsFactory } from "./RepositoryBuilderOptionsFactory.js";
|
|
32
33
|
export { StatementMappers } from "./StatementMappers.js";
|
|
34
|
+
export { NestedSelectBuilder } from "./NestedSelectBuilder.js";
|
|
33
35
|
export { ReadonlyRepositoryStatements } from "./ReadonlyRepositoryStatements.js";
|
|
34
36
|
export { CRUDRepositoryStatements } from "./CRUDRepositoryStatements.js";
|
|
35
37
|
export { createCRUDRepositoryOptions } from "./createCRUDRepositoryOptions.js";
|
|
@@ -37,7 +39,7 @@ export { createReadonlyRepositoryMappingOptions } from "./createReadonlyReposito
|
|
|
37
39
|
export { Response } from "./Response.js";
|
|
38
40
|
export { UnitOfWorkTransaction } from "./UnitOfWorkTransaction.js";
|
|
39
41
|
export { IsolationLevel } from "./IsolationLevel.js";
|
|
40
|
-
export { ArrayExpression, CheckConstraint, ColumnDefault, Condition, ConditionRenderer, ExpressionRenderer, CreateIndexStatement, CreateTableStatement, CreateTableStatementTextRenderer, CreateIndexStatementTextRenderer, DropTableStatement, DropTableStatementTextRenderer, AlterTableStatement, AlterTableStatementTextRenderer, DropIndexStatement, DropIndexStatementTextRenderer, DropTriggerStatement, DropTriggerStatementTextRenderer, CreateTriggerStatement, CreateTriggerStatementTextRenderer, IdentityInsertStatement, IdentityInsertStatementTextRenderer, CreateCreateStoredProcedureStatement, CreateReadStoredProcedureStatement, CreateUpdateStoredProcedureStatement, CreateDeleteStoredProcedureStatement, CreateBulkCreateStoredProcedureStatement, CreateBulkUpdateStoredProcedureStatement, CreateBulkDeleteStoredProcedureStatement, CreateCreateStoredProcedureStatementTextRenderer, CreateReadStoredProcedureStatementTextRenderer, CreateUpdateStoredProcedureStatementTextRenderer, CreateDeleteStoredProcedureStatementTextRenderer, CreateBulkCreateStoredProcedureStatementTextRenderer, CreateBulkUpdateStoredProcedureStatementTextRenderer, CreateBulkDeleteStoredProcedureStatementTextRenderer, DropRoutineStatement, DropRoutineStatementTextRenderer, SelectStatementTextRenderer, InsertStatementTextRenderer, UpdateStatementTextRenderer, DeleteStatementTextRenderer, BulkInsertStatementTextRenderer, BulkUpdateStatementTextRenderer, BulkDeleteStatementTextRenderer, ExecuteStoredProcedureStatementTextRenderer, ReturnStatementTextRenderer, SelectInsertedIdStatementTextRenderer, DefaultStatementTextRenderer, DeleteStatement, ForeignKey, Identifier, InsertStatement, BulkInsertStatement, BulkUpdateStatement, BulkDeleteStatement, Literal, NotNull, Operator, eq, ne, gt, lt, ge, le, PrimaryKey, Aggregate, OrderBy, SelectStatement, StatementParser, StatementRenderer, StatementTextRenderer, Native, n, Subquery, ReferentialAction, ExpressionEvaluator, StatementEvaluator, ExecuteStoredProcedureStatement, SelectInsertedIdStatement, ReturnStatement, UniqueConstraint, UpdateStatement, WhereText, Where, Join, } from "./statements/index.js";
|
|
42
|
+
export { ArrayExpression, CheckConstraint, ColumnDefault, Condition, ConditionRenderer, ExpressionRenderer, CreateIndexStatement, CreateTableStatement, CreateTableStatementTextRenderer, CreateIndexStatementTextRenderer, DropTableStatement, DropTableStatementTextRenderer, AlterTableStatement, AlterTableStatementTextRenderer, DropIndexStatement, DropIndexStatementTextRenderer, DropTriggerStatement, DropTriggerStatementTextRenderer, CreateTriggerStatement, CreateTriggerStatementTextRenderer, IdentityInsertStatement, IdentityInsertStatementTextRenderer, CreateCreateStoredProcedureStatement, CreateReadStoredProcedureStatement, CreateNestedReadStoredProcedureStatement, CreateUpdateStoredProcedureStatement, CreateDeleteStoredProcedureStatement, CreateBulkCreateStoredProcedureStatement, CreateBulkUpdateStoredProcedureStatement, CreateBulkDeleteStoredProcedureStatement, CreateCreateStoredProcedureStatementTextRenderer, CreateReadStoredProcedureStatementTextRenderer, CreateNestedReadStoredProcedureStatementTextRenderer, CreateUpdateStoredProcedureStatementTextRenderer, CreateDeleteStoredProcedureStatementTextRenderer, CreateBulkCreateStoredProcedureStatementTextRenderer, CreateBulkUpdateStoredProcedureStatementTextRenderer, CreateBulkDeleteStoredProcedureStatementTextRenderer, DropRoutineStatement, DropRoutineStatementTextRenderer, SelectStatementTextRenderer, InsertStatementTextRenderer, UpdateStatementTextRenderer, DeleteStatementTextRenderer, BulkInsertStatementTextRenderer, BulkUpdateStatementTextRenderer, BulkDeleteStatementTextRenderer, ExecuteStoredProcedureStatementTextRenderer, ReturnStatementTextRenderer, SelectInsertedIdStatementTextRenderer, DefaultStatementTextRenderer, DeleteStatement, ForeignKey, Identifier, InsertStatement, BulkInsertStatement, BulkUpdateStatement, BulkDeleteStatement, Literal, NotNull, Operator, eq, ne, gt, lt, ge, le, PrimaryKey, Aggregate, OrderBy, SelectStatement, StatementParser, StatementRenderer, StatementTextRenderer, Native, n, Subquery, ReferentialAction, ExpressionEvaluator, StatementEvaluator, ExecuteStoredProcedureStatement, SelectInsertedIdStatement, ReturnStatement, UniqueConstraint, UpdateStatement, WhereText, Where, Join, } from "./statements/index.js";
|
|
41
43
|
export { ParameterDirection } from "./ParameterDirection.js";
|
|
42
44
|
export { ArrayReader } from "./ArrayReader.js";
|
|
43
45
|
export { FirstResultReader } from "./FirstResultReader.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const Aggregate: {
|
|
2
|
-
count: (column: string
|
|
3
|
-
sum: (column: string
|
|
4
|
-
min: (column: string
|
|
5
|
-
max: (column: string
|
|
2
|
+
count: (column: string) => string;
|
|
3
|
+
sum: (column: string) => string;
|
|
4
|
+
min: (column: string) => string;
|
|
5
|
+
max: (column: string) => string;
|
|
6
6
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const fragment = (op, column
|
|
1
|
+
const fragment = (op, column) => `${op}(${column})`;
|
|
2
2
|
export const Aggregate = {
|
|
3
|
-
count: (column
|
|
4
|
-
sum: (column
|
|
5
|
-
min: (column
|
|
6
|
-
max: (column
|
|
3
|
+
count: (column) => fragment("COUNT", column),
|
|
4
|
+
sum: (column) => fragment("SUM", column),
|
|
5
|
+
min: (column) => fragment("MIN", column),
|
|
6
|
+
max: (column) => fragment("MAX", column),
|
|
7
7
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { NestedSelectStatement } from "../NestedSelectStatement.js";
|
|
2
|
+
import type { ICreateNestedReadStoredProcedureStatement } from "./ICreateNestedReadStoredProcedureStatement.js";
|
|
3
|
+
import type { IStatementVisitor } from "./IStatementVisitor.js";
|
|
4
|
+
import type { NestedWhereArgument } from "./NestedWhereArgument.js";
|
|
5
|
+
import { SelectStatement } from "./SelectStatement.js";
|
|
6
|
+
export declare class CreateNestedReadStoredProcedureStatement implements ICreateNestedReadStoredProcedureStatement {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly nested: NestedSelectStatement;
|
|
9
|
+
readonly arguments: readonly NestedWhereArgument[];
|
|
10
|
+
constructor(name: string, nested: NestedSelectStatement, args: readonly NestedWhereArgument[]);
|
|
11
|
+
get select(): SelectStatement;
|
|
12
|
+
accept: (visitor: IStatementVisitor) => string;
|
|
13
|
+
static withArguments(select: SelectStatement, arguments_: readonly NestedWhereArgument[]): SelectStatement;
|
|
14
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Operator } from "./Operator.js";
|
|
2
|
+
import { Identifier } from "./Identifier.js";
|
|
3
|
+
import { SelectStatement } from "./SelectStatement.js";
|
|
4
|
+
import { Where } from "./Where.js";
|
|
5
|
+
export class CreateNestedReadStoredProcedureStatement {
|
|
6
|
+
name;
|
|
7
|
+
nested;
|
|
8
|
+
arguments;
|
|
9
|
+
constructor(name, nested, args) {
|
|
10
|
+
this.name = name;
|
|
11
|
+
this.nested = nested;
|
|
12
|
+
this.arguments = args;
|
|
13
|
+
}
|
|
14
|
+
get select() {
|
|
15
|
+
return CreateNestedReadStoredProcedureStatement.withArguments(this.nested.select, this.arguments);
|
|
16
|
+
}
|
|
17
|
+
accept = (visitor) => visitor.visit(this);
|
|
18
|
+
static withArguments(select, arguments_) {
|
|
19
|
+
const where = arguments_.reduce((clause, argument) => {
|
|
20
|
+
const equals = new Operator.Equals(new Identifier(argument.path), new Identifier(argument.parameter.name));
|
|
21
|
+
return clause instanceof Where ? new Where(new Operator.And(clause.condition, equals)) : new Where(equals);
|
|
22
|
+
}, select.where);
|
|
23
|
+
return new SelectStatement({
|
|
24
|
+
distinct: select.distinct,
|
|
25
|
+
table: select.table,
|
|
26
|
+
fields: select.fields,
|
|
27
|
+
aliases: select.aliases,
|
|
28
|
+
joins: select.joins,
|
|
29
|
+
where,
|
|
30
|
+
groupBy: select.groupBy,
|
|
31
|
+
having: select.having,
|
|
32
|
+
orderBy: select.orderBy,
|
|
33
|
+
limit: select.limit,
|
|
34
|
+
offset: select.offset,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NestedSelectStatement } from "../NestedSelectStatement.js";
|
|
2
|
+
import type { IStatement } from "./IStatement.js";
|
|
3
|
+
import type { NestedWhereArgument } from "./NestedWhereArgument.js";
|
|
4
|
+
export interface ICreateNestedReadStoredProcedureStatement extends IStatement {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly nested: NestedSelectStatement;
|
|
7
|
+
readonly arguments: readonly NestedWhereArgument[];
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -10,6 +10,7 @@ import type { DropIndexStatement } from "./DropIndexStatement.js";
|
|
|
10
10
|
import type { DropRoutineStatement } from "./DropRoutineStatement.js";
|
|
11
11
|
import type { CreateCreateStoredProcedureStatement } from "./CreateCreateStoredProcedureStatement.js";
|
|
12
12
|
import type { CreateReadStoredProcedureStatement } from "./CreateReadStoredProcedureStatement.js";
|
|
13
|
+
import type { CreateNestedReadStoredProcedureStatement } from "./CreateNestedReadStoredProcedureStatement.js";
|
|
13
14
|
import type { CreateUpdateStoredProcedureStatement } from "./CreateUpdateStoredProcedureStatement.js";
|
|
14
15
|
import type { CreateDeleteStoredProcedureStatement } from "./CreateDeleteStoredProcedureStatement.js";
|
|
15
16
|
import type { CreateBulkCreateStoredProcedureStatement } from "./CreateBulkCreateStoredProcedureStatement.js";
|
|
@@ -46,6 +47,7 @@ export interface IStatementVisitor {
|
|
|
46
47
|
visit(statement: DropRoutineStatement): string;
|
|
47
48
|
visit(statement: CreateCreateStoredProcedureStatement): string;
|
|
48
49
|
visit(statement: CreateReadStoredProcedureStatement): string;
|
|
50
|
+
visit(statement: CreateNestedReadStoredProcedureStatement): string;
|
|
49
51
|
visit(statement: CreateUpdateStoredProcedureStatement): string;
|
|
50
52
|
visit(statement: CreateDeleteStoredProcedureStatement): string;
|
|
51
53
|
visit(statement: CreateBulkCreateStoredProcedureStatement): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -9,6 +9,7 @@ export declare class SelectStatement implements ISelectStatement {
|
|
|
9
9
|
readonly distinct: boolean;
|
|
10
10
|
readonly table?: string;
|
|
11
11
|
readonly fields: string[];
|
|
12
|
+
readonly aliases: (string | undefined)[];
|
|
12
13
|
readonly joins: Join[];
|
|
13
14
|
readonly groupBy: string[];
|
|
14
15
|
readonly having?: IWhere;
|
|
@@ -3,6 +3,7 @@ export class SelectStatement {
|
|
|
3
3
|
distinct;
|
|
4
4
|
table;
|
|
5
5
|
fields;
|
|
6
|
+
aliases;
|
|
6
7
|
joins;
|
|
7
8
|
groupBy;
|
|
8
9
|
having;
|
|
@@ -14,6 +15,7 @@ export class SelectStatement {
|
|
|
14
15
|
this.distinct = options.distinct ?? false;
|
|
15
16
|
this.table = options.table;
|
|
16
17
|
this.fields = options.fields ?? [];
|
|
18
|
+
this.aliases = options.aliases ?? [];
|
|
17
19
|
this.joins = options.joins ?? [];
|
|
18
20
|
this.groupBy = options.groupBy ?? [];
|
|
19
21
|
this.having = options.having;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { orderText } from "./OrderBy.js";
|
|
2
|
+
import { applySelectFieldAlias } from "../SelectFieldAliases.js";
|
|
2
3
|
import { Where } from "./Where.js";
|
|
3
4
|
export class SelectStatementTextRenderer {
|
|
4
5
|
text;
|
|
@@ -6,7 +7,11 @@ export class SelectStatementTextRenderer {
|
|
|
6
7
|
this.text = text;
|
|
7
8
|
}
|
|
8
9
|
render(statement) {
|
|
9
|
-
return `SELECT ${statement.distinct ? "DISTINCT " : ""}${statement.fields.length === 0
|
|
10
|
+
return `SELECT ${statement.distinct ? "DISTINCT " : ""}${statement.fields.length === 0
|
|
11
|
+
? "*"
|
|
12
|
+
: statement.fields
|
|
13
|
+
.map((field, i) => applySelectFieldAlias(field, statement.aliases[i]))
|
|
14
|
+
.join(", ")} FROM ${statement.table}${this.joinSql(statement.joins)}${this.whereSql(statement.where)}${this.groupSql(statement.groupBy)}${this.havingSql(statement.having)}${this.orderSql(statement.orderBy)}${this.limit(statement.limit)}${this.offset(statement.offset)}`;
|
|
10
15
|
}
|
|
11
16
|
whereSql(where) {
|
|
12
17
|
return where ? ` WHERE ${this.text.render(where)}` : "";
|
|
@@ -11,6 +11,7 @@ import { DropIndexStatement } from "./DropIndexStatement.js";
|
|
|
11
11
|
import { DropRoutineStatement } from "./DropRoutineStatement.js";
|
|
12
12
|
import { CreateCreateStoredProcedureStatement } from "./CreateCreateStoredProcedureStatement.js";
|
|
13
13
|
import { CreateReadStoredProcedureStatement } from "./CreateReadStoredProcedureStatement.js";
|
|
14
|
+
import { CreateNestedReadStoredProcedureStatement } from "./CreateNestedReadStoredProcedureStatement.js";
|
|
14
15
|
import { CreateUpdateStoredProcedureStatement } from "./CreateUpdateStoredProcedureStatement.js";
|
|
15
16
|
import { CreateDeleteStoredProcedureStatement } from "./CreateDeleteStoredProcedureStatement.js";
|
|
16
17
|
import { CreateBulkCreateStoredProcedureStatement } from "./CreateBulkCreateStoredProcedureStatement.js";
|
|
@@ -50,6 +51,7 @@ export declare class StatementRenderer implements IStatementVisitor {
|
|
|
50
51
|
visit(statement: DropRoutineStatement): string;
|
|
51
52
|
visit(statement: CreateCreateStoredProcedureStatement): string;
|
|
52
53
|
visit(statement: CreateReadStoredProcedureStatement): string;
|
|
54
|
+
visit(statement: CreateNestedReadStoredProcedureStatement): string;
|
|
53
55
|
visit(statement: CreateUpdateStoredProcedureStatement): string;
|
|
54
56
|
visit(statement: CreateDeleteStoredProcedureStatement): string;
|
|
55
57
|
visit(statement: CreateBulkCreateStoredProcedureStatement): string;
|
|
@@ -76,6 +78,7 @@ export declare class StatementRenderer implements IStatementVisitor {
|
|
|
76
78
|
protected visitDropRoutine(statement: DropRoutineStatement): string;
|
|
77
79
|
protected visitCreateCreateStoredProcedureStatement(statement: CreateCreateStoredProcedureStatement): string;
|
|
78
80
|
protected visitCreateReadStoredProcedureStatement(statement: CreateReadStoredProcedureStatement): string;
|
|
81
|
+
protected visitCreateNestedReadStoredProcedureStatement(statement: CreateNestedReadStoredProcedureStatement): string;
|
|
79
82
|
protected visitCreateUpdateStoredProcedureStatement(statement: CreateUpdateStoredProcedureStatement): string;
|
|
80
83
|
protected visitCreateDeleteStoredProcedureStatement(statement: CreateDeleteStoredProcedureStatement): string;
|
|
81
84
|
protected visitCreateBulkCreateStoredProcedureStatement(statement: CreateBulkCreateStoredProcedureStatement): string;
|
|
@@ -10,6 +10,7 @@ import { DropIndexStatementTextRenderer } from "./DropIndexStatementTextRenderer
|
|
|
10
10
|
import { DropRoutineStatementTextRenderer } from "./DropRoutineStatementTextRenderer.js";
|
|
11
11
|
import { CreateCreateStoredProcedureStatementTextRenderer } from "./CreateCreateStoredProcedureStatementTextRenderer.js";
|
|
12
12
|
import { CreateReadStoredProcedureStatementTextRenderer } from "./CreateReadStoredProcedureStatementTextRenderer.js";
|
|
13
|
+
import { CreateNestedReadStoredProcedureStatementTextRenderer } from "./CreateNestedReadStoredProcedureStatementTextRenderer.js";
|
|
13
14
|
import { CreateUpdateStoredProcedureStatementTextRenderer } from "./CreateUpdateStoredProcedureStatementTextRenderer.js";
|
|
14
15
|
import { CreateDeleteStoredProcedureStatementTextRenderer } from "./CreateDeleteStoredProcedureStatementTextRenderer.js";
|
|
15
16
|
import { CreateBulkCreateStoredProcedureStatementTextRenderer } from "./CreateBulkCreateStoredProcedureStatementTextRenderer.js";
|
|
@@ -51,6 +52,7 @@ export class StatementRenderer {
|
|
|
51
52
|
DropRoutineStatement: () => this.visitDropRoutine(statement),
|
|
52
53
|
CreateCreateStoredProcedureStatement: () => this.visitCreateCreateStoredProcedureStatement(statement),
|
|
53
54
|
CreateReadStoredProcedureStatement: () => this.visitCreateReadStoredProcedureStatement(statement),
|
|
55
|
+
CreateNestedReadStoredProcedureStatement: () => this.visitCreateNestedReadStoredProcedureStatement(statement),
|
|
54
56
|
CreateUpdateStoredProcedureStatement: () => this.visitCreateUpdateStoredProcedureStatement(statement),
|
|
55
57
|
CreateDeleteStoredProcedureStatement: () => this.visitCreateDeleteStoredProcedureStatement(statement),
|
|
56
58
|
CreateBulkCreateStoredProcedureStatement: () => this.visitCreateBulkCreateStoredProcedureStatement(statement),
|
|
@@ -122,6 +124,9 @@ export class StatementRenderer {
|
|
|
122
124
|
visitCreateReadStoredProcedureStatement(statement) {
|
|
123
125
|
return new CreateReadStoredProcedureStatementTextRenderer().render(statement);
|
|
124
126
|
}
|
|
127
|
+
visitCreateNestedReadStoredProcedureStatement(statement) {
|
|
128
|
+
return new CreateNestedReadStoredProcedureStatementTextRenderer().render(statement);
|
|
129
|
+
}
|
|
125
130
|
visitCreateUpdateStoredProcedureStatement(statement) {
|
|
126
131
|
return new CreateUpdateStoredProcedureStatementTextRenderer().render(statement);
|
|
127
132
|
}
|
package/dist/statements/Where.js
CHANGED
|
@@ -56,6 +56,7 @@ const rewriteQuery = (query, column, value) => query.table === undefined
|
|
|
56
56
|
distinct: query.distinct,
|
|
57
57
|
table: query.table,
|
|
58
58
|
fields: query.fields,
|
|
59
|
+
aliases: query.aliases,
|
|
59
60
|
where: rewriteWhere(query.where, column, value),
|
|
60
61
|
joins: query.joins.map((join) => join.on ? { ...join, on: rewrite(join.on, column, value) } : join),
|
|
61
62
|
groupBy: query.groupBy,
|
|
@@ -23,6 +23,8 @@ export type { IIdentityInsertStatement } from "./IIdentityInsertStatement.js";
|
|
|
23
23
|
export type { IDropRoutineStatement } from "./IDropRoutineStatement.js";
|
|
24
24
|
export type { ICreateCreateStoredProcedureStatement } from "./ICreateCreateStoredProcedureStatement.js";
|
|
25
25
|
export type { ICreateReadStoredProcedureStatement } from "./ICreateReadStoredProcedureStatement.js";
|
|
26
|
+
export type { ICreateNestedReadStoredProcedureStatement } from "./ICreateNestedReadStoredProcedureStatement.js";
|
|
27
|
+
export type { NestedWhereArgument } from "./NestedWhereArgument.js";
|
|
26
28
|
export type { ICreateUpdateStoredProcedureStatement } from "./ICreateUpdateStoredProcedureStatement.js";
|
|
27
29
|
export type { ICreateDeleteStoredProcedureStatement } from "./ICreateDeleteStoredProcedureStatement.js";
|
|
28
30
|
export type { ICreateBulkCreateStoredProcedureStatement } from "./ICreateBulkCreateStoredProcedureStatement.js";
|
|
@@ -90,6 +92,8 @@ export { CreateCreateStoredProcedureStatement } from "./CreateCreateStoredProced
|
|
|
90
92
|
export { CreateCreateStoredProcedureStatementTextRenderer } from "./CreateCreateStoredProcedureStatementTextRenderer.js";
|
|
91
93
|
export { CreateReadStoredProcedureStatement } from "./CreateReadStoredProcedureStatement.js";
|
|
92
94
|
export { CreateReadStoredProcedureStatementTextRenderer } from "./CreateReadStoredProcedureStatementTextRenderer.js";
|
|
95
|
+
export { CreateNestedReadStoredProcedureStatement } from "./CreateNestedReadStoredProcedureStatement.js";
|
|
96
|
+
export { CreateNestedReadStoredProcedureStatementTextRenderer } from "./CreateNestedReadStoredProcedureStatementTextRenderer.js";
|
|
93
97
|
export { CreateUpdateStoredProcedureStatement } from "./CreateUpdateStoredProcedureStatement.js";
|
|
94
98
|
export { CreateUpdateStoredProcedureStatementTextRenderer } from "./CreateUpdateStoredProcedureStatementTextRenderer.js";
|
|
95
99
|
export { CreateDeleteStoredProcedureStatement } from "./CreateDeleteStoredProcedureStatement.js";
|
package/dist/statements/index.js
CHANGED
|
@@ -51,6 +51,8 @@ export { CreateCreateStoredProcedureStatement } from "./CreateCreateStoredProced
|
|
|
51
51
|
export { CreateCreateStoredProcedureStatementTextRenderer } from "./CreateCreateStoredProcedureStatementTextRenderer.js";
|
|
52
52
|
export { CreateReadStoredProcedureStatement } from "./CreateReadStoredProcedureStatement.js";
|
|
53
53
|
export { CreateReadStoredProcedureStatementTextRenderer } from "./CreateReadStoredProcedureStatementTextRenderer.js";
|
|
54
|
+
export { CreateNestedReadStoredProcedureStatement } from "./CreateNestedReadStoredProcedureStatement.js";
|
|
55
|
+
export { CreateNestedReadStoredProcedureStatementTextRenderer } from "./CreateNestedReadStoredProcedureStatementTextRenderer.js";
|
|
54
56
|
export { CreateUpdateStoredProcedureStatement } from "./CreateUpdateStoredProcedureStatement.js";
|
|
55
57
|
export { CreateUpdateStoredProcedureStatementTextRenderer } from "./CreateUpdateStoredProcedureStatementTextRenderer.js";
|
|
56
58
|
export { CreateDeleteStoredProcedureStatement } from "./CreateDeleteStoredProcedureStatement.js";
|