@stamhoofd/sql 2.118.1 → 2.120.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/dist/{src/ModelCache.d.ts → ModelCache.d.ts} +1 -1
- package/dist/ModelCache.d.ts.map +1 -0
- package/{src/ModelCache.ts → dist/ModelCache.js} +8 -16
- package/dist/ModelCache.js.map +1 -0
- package/dist/{src/QueryableModel.d.ts → QueryableModel.d.ts} +7 -6
- package/dist/QueryableModel.d.ts.map +1 -0
- package/dist/{src/QueryableModel.js → QueryableModel.js} +9 -13
- package/dist/QueryableModel.js.map +1 -0
- package/dist/{src/SQL.d.ts → SQL.d.ts} +7 -5
- package/dist/SQL.d.ts.map +1 -0
- package/dist/SQL.js +100 -0
- package/dist/SQL.js.map +1 -0
- package/dist/{src/SQLDelete.d.ts → SQLDelete.d.ts} +2 -2
- package/dist/SQLDelete.d.ts.map +1 -0
- package/dist/{src/SQLDelete.js → SQLDelete.js} +8 -12
- package/dist/SQLDelete.js.map +1 -0
- package/dist/SQLExpression.d.ts.map +1 -0
- package/dist/{src/SQLExpression.js → SQLExpression.js} +3 -8
- package/dist/SQLExpression.js.map +1 -0
- package/dist/{src/SQLExpressions.d.ts → SQLExpressions.d.ts} +2 -2
- package/dist/SQLExpressions.d.ts.map +1 -0
- package/dist/{src/SQLExpressions.js → SQLExpressions.js} +78 -115
- package/dist/SQLExpressions.js.map +1 -0
- package/dist/{src/SQLInsert.d.ts → SQLInsert.d.ts} +3 -2
- package/dist/SQLInsert.d.ts.map +1 -0
- package/dist/{src/SQLInsert.js → SQLInsert.js} +17 -21
- package/dist/SQLInsert.js.map +1 -0
- package/dist/{src/SQLJoin.d.ts → SQLJoin.d.ts} +1 -1
- package/dist/SQLJoin.d.ts.map +1 -0
- package/{src/SQLJoin.ts → dist/SQLJoin.js} +15 -18
- package/dist/SQLJoin.js.map +1 -0
- package/dist/{src/SQLJsonExpressions.d.ts → SQLJsonExpressions.d.ts} +2 -2
- package/dist/SQLJsonExpressions.d.ts.map +1 -0
- package/dist/{src/SQLJsonExpressions.js → SQLJsonExpressions.js} +32 -45
- package/dist/SQLJsonExpressions.js.map +1 -0
- package/dist/SQLLogger.d.ts.map +1 -0
- package/dist/{src/SQLLogger.js → SQLLogger.js} +5 -8
- package/dist/SQLLogger.js.map +1 -0
- package/dist/{src/SQLOrderBy.d.ts → SQLOrderBy.d.ts} +1 -1
- package/dist/SQLOrderBy.d.ts.map +1 -0
- package/dist/{src/SQLOrderBy.js → SQLOrderBy.js} +8 -13
- package/dist/SQLOrderBy.js.map +1 -0
- package/dist/{src/SQLSelect.d.ts → SQLSelect.d.ts} +3 -3
- package/dist/SQLSelect.d.ts.map +1 -0
- package/dist/{src/SQLSelect.js → SQLSelect.js} +24 -29
- package/dist/SQLSelect.js.map +1 -0
- package/dist/{src/SQLTranslatedStringHelper.d.ts → SQLTranslatedStringHelper.d.ts} +3 -2
- package/dist/SQLTranslatedStringHelper.d.ts.map +1 -0
- package/dist/SQLTranslatedStringHelper.js +33 -0
- package/dist/SQLTranslatedStringHelper.js.map +1 -0
- package/dist/{src/SQLUpdate.d.ts → SQLUpdate.d.ts} +3 -2
- package/dist/SQLUpdate.d.ts.map +1 -0
- package/{src/SQLUpdate.ts → dist/SQLUpdate.js} +18 -35
- package/dist/SQLUpdate.js.map +1 -0
- package/dist/{src/SQLWhere.d.ts → SQLWhere.d.ts} +3 -3
- package/dist/SQLWhere.d.ts.map +1 -0
- package/dist/{src/SQLWhere.js → SQLWhere.js} +42 -56
- package/dist/SQLWhere.js.map +1 -0
- package/dist/{src/filters → filters}/SQLFilter.d.ts +10 -6
- package/dist/filters/SQLFilter.d.ts.map +1 -0
- package/{src/filters/SQLFilter.ts → dist/filters/SQLFilter.js} +66 -127
- package/dist/filters/SQLFilter.js.map +1 -0
- package/dist/{src/filters → filters}/SQLSorter.d.ts +6 -6
- package/dist/filters/SQLSorter.d.ts.map +1 -0
- package/dist/{src/filters → filters}/SQLSorter.js +5 -8
- package/dist/filters/SQLSorter.js.map +1 -0
- package/dist/filters/compilers/contains.d.ts +4 -0
- package/dist/filters/compilers/contains.d.ts.map +1 -0
- package/dist/filters/compilers/contains.js +26 -0
- package/dist/filters/compilers/contains.js.map +1 -0
- package/dist/filters/compilers/equals.d.ts +4 -0
- package/dist/filters/compilers/equals.d.ts.map +1 -0
- package/dist/filters/compilers/equals.js +44 -0
- package/dist/filters/compilers/equals.js.map +1 -0
- package/dist/filters/compilers/greater.d.ts +4 -0
- package/dist/filters/compilers/greater.d.ts.map +1 -0
- package/dist/filters/compilers/greater.js +15 -0
- package/dist/filters/compilers/greater.js.map +1 -0
- package/dist/filters/compilers/in.d.ts +4 -0
- package/dist/filters/compilers/in.d.ts.map +1 -0
- package/{src/filters/compilers/in.ts → dist/filters/compilers/in.js} +11 -26
- package/dist/filters/compilers/in.js.map +1 -0
- package/dist/filters/compilers/index.d.ts.map +1 -0
- package/{src/filters/compilers/index.ts → dist/filters/compilers/index.js} +1 -0
- package/dist/filters/compilers/index.js.map +1 -0
- package/dist/filters/compilers/less.d.ts +4 -0
- package/dist/filters/compilers/less.d.ts.map +1 -0
- package/dist/filters/compilers/less.js +15 -0
- package/dist/filters/compilers/less.js.map +1 -0
- package/dist/filters/helpers/isJSONColumn.d.ts +5 -0
- package/dist/filters/helpers/isJSONColumn.d.ts.map +1 -0
- package/{src/filters/helpers/isJSONColumn.ts → dist/filters/helpers/isJSONColumn.js} +5 -5
- package/dist/filters/helpers/isJSONColumn.js.map +1 -0
- package/dist/{src/filters → filters}/helpers/normalizeCompareValue.d.ts +1 -1
- package/dist/filters/helpers/normalizeCompareValue.d.ts.map +1 -0
- package/{src/filters/helpers/normalizeCompareValue.ts → dist/filters/helpers/normalizeCompareValue.js} +3 -20
- package/dist/filters/helpers/normalizeCompareValue.js.map +1 -0
- package/dist/index.d.ts +14 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -25
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/dist/src/ModelCache.d.ts.map +0 -1
- package/dist/src/ModelCache.js +0 -57
- package/dist/src/ModelCache.js.map +0 -1
- package/dist/src/QueryableModel.d.ts.map +0 -1
- package/dist/src/QueryableModel.js.map +0 -1
- package/dist/src/SQL.d.ts.map +0 -1
- package/dist/src/SQL.js +0 -103
- package/dist/src/SQL.js.map +0 -1
- package/dist/src/SQLDelete.d.ts.map +0 -1
- package/dist/src/SQLDelete.js.map +0 -1
- package/dist/src/SQLExpression.d.ts.map +0 -1
- package/dist/src/SQLExpression.js.map +0 -1
- package/dist/src/SQLExpressions.d.ts.map +0 -1
- package/dist/src/SQLExpressions.js.map +0 -1
- package/dist/src/SQLInsert.d.ts.map +0 -1
- package/dist/src/SQLInsert.js.map +0 -1
- package/dist/src/SQLJoin.d.ts.map +0 -1
- package/dist/src/SQLJoin.js +0 -61
- package/dist/src/SQLJoin.js.map +0 -1
- package/dist/src/SQLJsonExpressions.d.ts.map +0 -1
- package/dist/src/SQLJsonExpressions.js.map +0 -1
- package/dist/src/SQLLogger.d.ts.map +0 -1
- package/dist/src/SQLLogger.js.map +0 -1
- package/dist/src/SQLOrderBy.d.ts.map +0 -1
- package/dist/src/SQLOrderBy.js.map +0 -1
- package/dist/src/SQLSelect.d.ts.map +0 -1
- package/dist/src/SQLSelect.js.map +0 -1
- package/dist/src/SQLTranslatedStringHelper.d.ts.map +0 -1
- package/dist/src/SQLTranslatedStringHelper.js +0 -37
- package/dist/src/SQLTranslatedStringHelper.js.map +0 -1
- package/dist/src/SQLUpdate.d.ts.map +0 -1
- package/dist/src/SQLUpdate.js +0 -60
- package/dist/src/SQLUpdate.js.map +0 -1
- package/dist/src/SQLWhere.d.ts.map +0 -1
- package/dist/src/SQLWhere.js.map +0 -1
- package/dist/src/filters/SQLFilter.d.ts.map +0 -1
- package/dist/src/filters/SQLFilter.js +0 -216
- package/dist/src/filters/SQLFilter.js.map +0 -1
- package/dist/src/filters/SQLSorter.d.ts.map +0 -1
- package/dist/src/filters/SQLSorter.js.map +0 -1
- package/dist/src/filters/compilers/contains.d.ts +0 -4
- package/dist/src/filters/compilers/contains.d.ts.map +0 -1
- package/dist/src/filters/compilers/contains.js +0 -28
- package/dist/src/filters/compilers/contains.js.map +0 -1
- package/dist/src/filters/compilers/equals.d.ts +0 -4
- package/dist/src/filters/compilers/equals.d.ts.map +0 -1
- package/dist/src/filters/compilers/equals.js +0 -46
- package/dist/src/filters/compilers/equals.js.map +0 -1
- package/dist/src/filters/compilers/greater.d.ts +0 -4
- package/dist/src/filters/compilers/greater.d.ts.map +0 -1
- package/dist/src/filters/compilers/greater.js +0 -17
- package/dist/src/filters/compilers/greater.js.map +0 -1
- package/dist/src/filters/compilers/in.d.ts +0 -4
- package/dist/src/filters/compilers/in.d.ts.map +0 -1
- package/dist/src/filters/compilers/in.js +0 -51
- package/dist/src/filters/compilers/in.js.map +0 -1
- package/dist/src/filters/compilers/index.d.ts.map +0 -1
- package/dist/src/filters/compilers/index.js +0 -8
- package/dist/src/filters/compilers/index.js.map +0 -1
- package/dist/src/filters/compilers/less.d.ts +0 -4
- package/dist/src/filters/compilers/less.d.ts.map +0 -1
- package/dist/src/filters/compilers/less.js +0 -17
- package/dist/src/filters/compilers/less.js.map +0 -1
- package/dist/src/filters/helpers/isJSONColumn.d.ts +0 -4
- package/dist/src/filters/helpers/isJSONColumn.d.ts.map +0 -1
- package/dist/src/filters/helpers/isJSONColumn.js +0 -16
- package/dist/src/filters/helpers/isJSONColumn.js.map +0 -1
- package/dist/src/filters/helpers/normalizeCompareValue.d.ts.map +0 -1
- package/dist/src/filters/helpers/normalizeCompareValue.js +0 -87
- package/dist/src/filters/helpers/normalizeCompareValue.js.map +0 -1
- package/dist/tests/filters/$and.test.d.ts +0 -2
- package/dist/tests/filters/$and.test.d.ts.map +0 -1
- package/dist/tests/filters/$and.test.js +0 -216
- package/dist/tests/filters/$and.test.js.map +0 -1
- package/dist/tests/filters/$contains.test.d.ts +0 -2
- package/dist/tests/filters/$contains.test.d.ts.map +0 -1
- package/dist/tests/filters/$contains.test.js +0 -701
- package/dist/tests/filters/$contains.test.js.map +0 -1
- package/dist/tests/filters/$eq.test.d.ts +0 -2
- package/dist/tests/filters/$eq.test.d.ts.map +0 -1
- package/dist/tests/filters/$eq.test.js +0 -1048
- package/dist/tests/filters/$eq.test.js.map +0 -1
- package/dist/tests/filters/$gt.test.d.ts +0 -2
- package/dist/tests/filters/$gt.test.d.ts.map +0 -1
- package/dist/tests/filters/$gt.test.js +0 -463
- package/dist/tests/filters/$gt.test.js.map +0 -1
- package/dist/tests/filters/$gte.test.d.ts +0 -2
- package/dist/tests/filters/$gte.test.d.ts.map +0 -1
- package/dist/tests/filters/$gte.test.js +0 -433
- package/dist/tests/filters/$gte.test.js.map +0 -1
- package/dist/tests/filters/$in.test.d.ts +0 -2
- package/dist/tests/filters/$in.test.d.ts.map +0 -1
- package/dist/tests/filters/$in.test.js +0 -590
- package/dist/tests/filters/$in.test.js.map +0 -1
- package/dist/tests/filters/$lt.test.d.ts +0 -2
- package/dist/tests/filters/$lt.test.d.ts.map +0 -1
- package/dist/tests/filters/$lt.test.js +0 -433
- package/dist/tests/filters/$lt.test.js.map +0 -1
- package/dist/tests/filters/$lte.test.d.ts +0 -2
- package/dist/tests/filters/$lte.test.d.ts.map +0 -1
- package/dist/tests/filters/$lte.test.js +0 -472
- package/dist/tests/filters/$lte.test.js.map +0 -1
- package/dist/tests/filters/$neq.test.d.ts +0 -2
- package/dist/tests/filters/$neq.test.d.ts.map +0 -1
- package/dist/tests/filters/$neq.test.js +0 -32
- package/dist/tests/filters/$neq.test.js.map +0 -1
- package/dist/tests/filters/$not.test.d.ts +0 -2
- package/dist/tests/filters/$not.test.d.ts.map +0 -1
- package/dist/tests/filters/$not.test.js +0 -50
- package/dist/tests/filters/$not.test.js.map +0 -1
- package/dist/tests/filters/$or.test.d.ts +0 -2
- package/dist/tests/filters/$or.test.d.ts.map +0 -1
- package/dist/tests/filters/$or.test.js +0 -185
- package/dist/tests/filters/$or.test.js.map +0 -1
- package/dist/tests/filters/SQLTranslatedStringHelper.test.d.ts +0 -2
- package/dist/tests/filters/SQLTranslatedStringHelper.test.d.ts.map +0 -1
- package/dist/tests/filters/SQLTranslatedStringHelper.test.js +0 -491
- package/dist/tests/filters/SQLTranslatedStringHelper.test.js.map +0 -1
- package/dist/tests/filters/dot-syntax.test.d.ts +0 -2
- package/dist/tests/filters/dot-syntax.test.d.ts.map +0 -1
- package/dist/tests/filters/dot-syntax.test.js +0 -210
- package/dist/tests/filters/dot-syntax.test.js.map +0 -1
- package/dist/tests/filters/exists.test.d.ts +0 -2
- package/dist/tests/filters/exists.test.d.ts.map +0 -1
- package/dist/tests/filters/exists.test.js +0 -96
- package/dist/tests/filters/exists.test.js.map +0 -1
- package/dist/tests/filters/joined-relations.test.d.ts +0 -2
- package/dist/tests/filters/joined-relations.test.d.ts.map +0 -1
- package/dist/tests/filters/joined-relations.test.js +0 -167
- package/dist/tests/filters/joined-relations.test.js.map +0 -1
- package/dist/tests/filters/special-cases.test.d.ts +0 -2
- package/dist/tests/filters/special-cases.test.d.ts.map +0 -1
- package/dist/tests/filters/special-cases.test.js +0 -114
- package/dist/tests/filters/special-cases.test.js.map +0 -1
- package/dist/tests/filters/wildcard.test.d.ts +0 -2
- package/dist/tests/filters/wildcard.test.d.ts.map +0 -1
- package/dist/tests/filters/wildcard.test.js +0 -67
- package/dist/tests/filters/wildcard.test.js.map +0 -1
- package/dist/tests/jest.global.setup.d.ts +0 -3
- package/dist/tests/jest.global.setup.d.ts.map +0 -1
- package/dist/tests/jest.global.setup.js +0 -7
- package/dist/tests/jest.global.setup.js.map +0 -1
- package/dist/tests/jest.setup.d.ts +0 -2
- package/dist/tests/jest.setup.d.ts.map +0 -1
- package/dist/tests/jest.setup.js +0 -5
- package/dist/tests/jest.setup.js.map +0 -1
- package/dist/tests/utils/index.d.ts +0 -57
- package/dist/tests/utils/index.d.ts.map +0 -1
- package/dist/tests/utils/index.js +0 -206
- package/dist/tests/utils/index.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/QueryableModel.ts +0 -134
- package/src/SQL.ts +0 -128
- package/src/SQLDelete.ts +0 -73
- package/src/SQLExpression.ts +0 -34
- package/src/SQLExpressions.ts +0 -587
- package/src/SQLInsert.ts +0 -113
- package/src/SQLJsonExpressions.ts +0 -283
- package/src/SQLLogger.ts +0 -82
- package/src/SQLOrderBy.ts +0 -69
- package/src/SQLSelect.ts +0 -520
- package/src/SQLTranslatedStringHelper.ts +0 -40
- package/src/SQLWhere.ts +0 -744
- package/src/filters/SQLSorter.ts +0 -60
- package/src/filters/compilers/contains.ts +0 -43
- package/src/filters/compilers/equals.ts +0 -72
- package/src/filters/compilers/greater.ts +0 -20
- package/src/filters/compilers/less.ts +0 -19
- /package/dist/{src/SQLExpression.d.ts → SQLExpression.d.ts} +0 -0
- /package/dist/{src/SQLLogger.d.ts → SQLLogger.d.ts} +0 -0
- /package/dist/{src/filters → filters}/compilers/index.d.ts +0 -0
package/src/SQLSelect.ts
DELETED
|
@@ -1,520 +0,0 @@
|
|
|
1
|
-
import { Database, SQLResultNamespacedRow } from '@simonbackx/simple-database';
|
|
2
|
-
import { Formatter } from '@stamhoofd/utility';
|
|
3
|
-
import { SQLExpression, SQLExpressionOptions, SQLNamedExpression, SQLQuery, joinSQLQuery, normalizeSQLQuery } from './SQLExpression.js';
|
|
4
|
-
import { SQLAlias, SQLColumnExpression, SQLCount, SQLSelectAs, SQLSum, SQLTableExpression } from './SQLExpressions.js';
|
|
5
|
-
import { SQLJoin } from './SQLJoin.js';
|
|
6
|
-
import { Orderable } from './SQLOrderBy.js';
|
|
7
|
-
import { Whereable } from './SQLWhere.js';
|
|
8
|
-
import { SQLLogger } from './SQLLogger.js';
|
|
9
|
-
|
|
10
|
-
class EmptyClass {}
|
|
11
|
-
|
|
12
|
-
export function parseTable(tableOrExpression: SQLNamedExpression | string, asNamespace?: string): SQLNamedExpression {
|
|
13
|
-
if (typeof tableOrExpression === 'string') {
|
|
14
|
-
return new SQLTableExpression(tableOrExpression, asNamespace);
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
return tableOrExpression;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export type IterableSQLSelect<T extends object = SQLResultNamespacedRow> = AsyncIterableIterator<T, undefined> & {
|
|
22
|
-
isDone: boolean;
|
|
23
|
-
options: IterableSQLSelectOptions;
|
|
24
|
-
maxQueries(maxQueries: number): IterableSQLSelect<T>;
|
|
25
|
-
};
|
|
26
|
-
export type IterableSQLSelectOptions = {
|
|
27
|
-
/**
|
|
28
|
-
* The loop will cancel after this amount of queries - but you can continue to loop over the results when starting a new for loop.
|
|
29
|
-
*/
|
|
30
|
-
maxQueries?: number;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export type SQLNamedSelect<T extends object = SQLResultNamespacedRow> = SQLSelect<T> & { getName(): string };
|
|
34
|
-
|
|
35
|
-
export class SQLSelect<T extends object = SQLResultNamespacedRow> extends Whereable(Orderable(EmptyClass)) implements SQLExpression {
|
|
36
|
-
_columns: SQLExpression[];
|
|
37
|
-
_from: SQLNamedExpression;
|
|
38
|
-
|
|
39
|
-
_limit: number | null = null;
|
|
40
|
-
_offset: number | null = null;
|
|
41
|
-
_groupBy: SQLExpression[] = [];
|
|
42
|
-
_joins: (InstanceType<typeof SQLJoin>)[] = [];
|
|
43
|
-
_max_execution_time: number | null = null;
|
|
44
|
-
private _name: string | null = null;
|
|
45
|
-
static slowQueryThresholdMs: number | null = null;
|
|
46
|
-
|
|
47
|
-
_transformer: ((row: SQLResultNamespacedRow) => T) | null = null;
|
|
48
|
-
|
|
49
|
-
constructor(...columns: (SQLExpression | string)[]);
|
|
50
|
-
constructor(transformer: ((row: SQLResultNamespacedRow) => T), ...columns: (SQLExpression | string)[]);
|
|
51
|
-
constructor(...columns: (SQLExpression | string | ((row: SQLResultNamespacedRow) => T))[]) {
|
|
52
|
-
super();
|
|
53
|
-
|
|
54
|
-
if (typeof columns[0] === 'function') {
|
|
55
|
-
this._transformer = columns.shift() as any;
|
|
56
|
-
}
|
|
57
|
-
this._columns = columns.map(c => typeof c === 'string' ? new SQLColumnExpression(c) : c) as any;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
clone(): this {
|
|
61
|
-
const c = new SQLSelect(...this._columns);
|
|
62
|
-
Object.assign(c, this);
|
|
63
|
-
this._where = this._where ? this._where.clone() : null;
|
|
64
|
-
return c as any;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
from(table: string, namespace: string): this;
|
|
68
|
-
from(table: string): this;
|
|
69
|
-
from(expression: SQLNamedExpression): this;
|
|
70
|
-
from(tableOrExpression: SQLNamedExpression | string, namespace?: string): this {
|
|
71
|
-
this._from = parseTable(tableOrExpression, namespace);
|
|
72
|
-
|
|
73
|
-
return this;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
select(...columns: (SQLExpression | string)[]): this {
|
|
77
|
-
this._columns.push(...columns.map(c => typeof c === 'string' ? new SQLColumnExpression(c) : c));
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
join(join: InstanceType<typeof SQLJoin>): this {
|
|
82
|
-
// prevent duplicate joins (reference of join should be the same)
|
|
83
|
-
if (!this._joins.includes(join)) {
|
|
84
|
-
this._joins.push(join);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return this;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
groupBy(...columns: SQLExpression[]): this {
|
|
91
|
-
this._groupBy.push(...columns);
|
|
92
|
-
return this;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
setMaxExecutionTime(ms: number): this {
|
|
96
|
-
this._max_execution_time = ms;
|
|
97
|
-
return this;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
101
|
-
if (!this._from) {
|
|
102
|
-
throw new Error('Forgot to define .from(...) for SQLSelect');
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const query: SQLQuery[] = [
|
|
106
|
-
'SELECT',
|
|
107
|
-
];
|
|
108
|
-
|
|
109
|
-
if (this._max_execution_time !== null) {
|
|
110
|
-
query.push('/*+ MAX_EXECUTION_TIME(' + this._max_execution_time + ') */');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Create a clone since we are mutating the default namespaces
|
|
114
|
-
const parentOptions = options;
|
|
115
|
-
options = options ? { ...options } : {};
|
|
116
|
-
options.defaultNamespace = this._from.getName();
|
|
117
|
-
|
|
118
|
-
if (parentOptions?.defaultNamespace) {
|
|
119
|
-
options.parentNamespace = parentOptions.defaultNamespace;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const columns = this._columns.map(c => c.getSQL(options));
|
|
123
|
-
query.push(
|
|
124
|
-
joinSQLQuery(columns, ', '),
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
query.push(
|
|
128
|
-
'FROM',
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
query.push(this._from.getSQL(options));
|
|
132
|
-
|
|
133
|
-
// Joins
|
|
134
|
-
query.push(...this._joins.map(j => j.getSQL(options)));
|
|
135
|
-
if (this._where) {
|
|
136
|
-
const whereJoins = Formatter.uniqueArray(this._where.getJoins()).filter(j => !this._joins.includes(j));
|
|
137
|
-
query.push(...whereJoins.map(j => j.getSQL(options)));
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Where
|
|
141
|
-
if (this._where) {
|
|
142
|
-
const always = this._where.isAlways;
|
|
143
|
-
if (always === false) {
|
|
144
|
-
throw new Error('Cannot use SQLSelect with a where that is not always true');
|
|
145
|
-
}
|
|
146
|
-
else if (always === null) {
|
|
147
|
-
query.push('WHERE');
|
|
148
|
-
query.push(this._where.getSQL(options));
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (this._groupBy.length > 0) {
|
|
153
|
-
query.push('GROUP BY');
|
|
154
|
-
query.push(
|
|
155
|
-
joinSQLQuery(
|
|
156
|
-
this._groupBy.map(c => c.getSQL(options)),
|
|
157
|
-
', ',
|
|
158
|
-
),
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (this._orderBy) {
|
|
163
|
-
query.push(this._orderBy.getSQL(options));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (this._limit !== null) {
|
|
167
|
-
query.push('LIMIT ' + this._limit);
|
|
168
|
-
if (this._offset !== null && this._offset !== 0) {
|
|
169
|
-
query.push('OFFSET ' + this._offset);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return joinSQLQuery(query, ' ');
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Returns true when it know all results will be included without filtering.
|
|
178
|
-
* Returns false when it knows no single result will be included.
|
|
179
|
-
* Null when it does not know.
|
|
180
|
-
*/
|
|
181
|
-
get isAlways() {
|
|
182
|
-
return this._where ? this._where.isAlways : true;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
limit(limit: number | null, offset: number | null = null): this {
|
|
186
|
-
this._limit = limit;
|
|
187
|
-
this._offset = offset;
|
|
188
|
-
return this;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async fetch(): Promise<T[]> {
|
|
192
|
-
if (this._where && this._where.isAlways === false) {
|
|
193
|
-
return [];
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const { query, params } = normalizeSQLQuery(this.getSQL());
|
|
197
|
-
|
|
198
|
-
// when debugging: log all queries
|
|
199
|
-
// console.log(query, params);
|
|
200
|
-
let rows: SQLResultNamespacedRow[];
|
|
201
|
-
try {
|
|
202
|
-
const [_rows] = await SQLLogger.log(Database.select(query, params, { nestTables: true }), query, params);
|
|
203
|
-
rows = _rows;
|
|
204
|
-
}
|
|
205
|
-
catch (e) {
|
|
206
|
-
console.error('Error executing SQL query', query, params, e);
|
|
207
|
-
throw e;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Now map aggregated queries to the correct namespace
|
|
211
|
-
for (const row of rows) {
|
|
212
|
-
if (row['']) {
|
|
213
|
-
for (const column in row['']) {
|
|
214
|
-
const splitted = column.split('__');
|
|
215
|
-
if (splitted.length <= 1) {
|
|
216
|
-
console.warn('Aggregated column without namespace', column);
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
const namespace = splitted[0];
|
|
220
|
-
const name = splitted[1];
|
|
221
|
-
row[namespace] = row[namespace] ?? {};
|
|
222
|
-
row[namespace][name] = row[''][column];
|
|
223
|
-
}
|
|
224
|
-
delete row[''];
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (this._transformer) {
|
|
229
|
-
return rows.map(this._transformer);
|
|
230
|
-
}
|
|
231
|
-
return rows as T[];
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
first(required: false): Promise<T | null>;
|
|
235
|
-
first(required: true): Promise<T>;
|
|
236
|
-
first(required: boolean): Promise<T | null>;
|
|
237
|
-
async first(required = true): Promise<T | null> {
|
|
238
|
-
const rows = await this.limit(1).fetch();
|
|
239
|
-
if (rows.length === 0) {
|
|
240
|
-
if (required) {
|
|
241
|
-
throw new Error('Expected at least one result at ' + this._from.getName());
|
|
242
|
-
}
|
|
243
|
-
return null;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return rows[0];
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
async count(expression?: SQLExpression): Promise<number> {
|
|
250
|
-
if (this._where && this._where.isAlways === false) {
|
|
251
|
-
return 0;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
this._columns = [
|
|
255
|
-
new SQLSelectAs(
|
|
256
|
-
new SQLCount(expression ?? null),
|
|
257
|
-
new SQLAlias('c'),
|
|
258
|
-
),
|
|
259
|
-
];
|
|
260
|
-
this._offset = null;
|
|
261
|
-
this._limit = null;
|
|
262
|
-
this._orderBy = null;
|
|
263
|
-
|
|
264
|
-
const { query, params } = normalizeSQLQuery(this.getSQL());
|
|
265
|
-
|
|
266
|
-
const [rows] = await SQLLogger.log(Database.select(query, params, { nestTables: true }), query, params);
|
|
267
|
-
if (rows.length === 1) {
|
|
268
|
-
const row = rows[0];
|
|
269
|
-
if ('' in row) {
|
|
270
|
-
const namespaced = row[''];
|
|
271
|
-
if ('c' in namespaced) {
|
|
272
|
-
const value = namespaced['c'];
|
|
273
|
-
if (typeof value === 'number' && Number.isInteger(value)) {
|
|
274
|
-
return value;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
console.warn('Invalid count SQL response', rows);
|
|
280
|
-
return 0;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
async sum(expression: SQLExpression): Promise<number> {
|
|
284
|
-
if (this._where && this._where.isAlways === false) {
|
|
285
|
-
return 0;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
this._columns = [
|
|
289
|
-
new SQLSelectAs(
|
|
290
|
-
new SQLSum(expression),
|
|
291
|
-
new SQLAlias('c'),
|
|
292
|
-
),
|
|
293
|
-
];
|
|
294
|
-
this._offset = null;
|
|
295
|
-
this._limit = null;
|
|
296
|
-
this._orderBy = null;
|
|
297
|
-
|
|
298
|
-
const { query, params } = normalizeSQLQuery(this.getSQL());
|
|
299
|
-
// console.log(query, params);
|
|
300
|
-
|
|
301
|
-
const [rows] = await SQLLogger.log(Database.select(query, params, { nestTables: true }), query, params);
|
|
302
|
-
if (rows.length === 1) {
|
|
303
|
-
const row = rows[0];
|
|
304
|
-
if ('' in row) {
|
|
305
|
-
const namespaced = row[''];
|
|
306
|
-
if ('c' in namespaced) {
|
|
307
|
-
const value = namespaced['c'];
|
|
308
|
-
if (typeof value === 'number' && Number.isInteger(value)) {
|
|
309
|
-
return value;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
console.warn('Invalid sum SQL response', rows);
|
|
315
|
-
return 0;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
all(options: IterableSQLSelectOptions = {}): T extends { id: string } ? IterableSQLSelect<T> : never {
|
|
319
|
-
if (this._orderBy) {
|
|
320
|
-
throw new Error('Cannot use async iterator with custom order by. Results should be ordered by ID');
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (this._offset !== null) {
|
|
324
|
-
throw new Error('Cannot use async iterator with offset');
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (!this._limit) {
|
|
328
|
-
this._limit = 100;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
const limit = this._limit;
|
|
332
|
-
this.orderBy('id');
|
|
333
|
-
|
|
334
|
-
let next: this | null = this.clone();
|
|
335
|
-
const base = this;
|
|
336
|
-
|
|
337
|
-
let stack: T[] = [];
|
|
338
|
-
let stackIndex = 0;
|
|
339
|
-
|
|
340
|
-
return {
|
|
341
|
-
queryCount: 0,
|
|
342
|
-
options,
|
|
343
|
-
[Symbol.asyncIterator]() {
|
|
344
|
-
return {
|
|
345
|
-
...this,
|
|
346
|
-
|
|
347
|
-
// Reset the iterator
|
|
348
|
-
queryCount: 0,
|
|
349
|
-
};
|
|
350
|
-
},
|
|
351
|
-
get isDone() {
|
|
352
|
-
return !next && (stackIndex + 1) >= stack.length;
|
|
353
|
-
},
|
|
354
|
-
async next(): Promise<IteratorResult<T, undefined>> {
|
|
355
|
-
stackIndex++;
|
|
356
|
-
|
|
357
|
-
if (stackIndex < stack.length) {
|
|
358
|
-
return {
|
|
359
|
-
done: false,
|
|
360
|
-
value: stack[stackIndex],
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if (!next) {
|
|
365
|
-
stack = []; // Clean up memory
|
|
366
|
-
return {
|
|
367
|
-
done: true,
|
|
368
|
-
value: undefined,
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (this.options.maxQueries !== undefined && this.queryCount >= this.options.maxQueries) {
|
|
373
|
-
// Stopping early
|
|
374
|
-
return {
|
|
375
|
-
done: true,
|
|
376
|
-
value: undefined,
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
stack = await next.fetch();
|
|
381
|
-
next = null;
|
|
382
|
-
this.queryCount += 1;
|
|
383
|
-
|
|
384
|
-
if (stack.length === 0) {
|
|
385
|
-
return {
|
|
386
|
-
done: true,
|
|
387
|
-
value: undefined,
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
stackIndex = 0;
|
|
391
|
-
|
|
392
|
-
if (stack.length >= limit) {
|
|
393
|
-
next = base.clone();
|
|
394
|
-
const lastResult = stack[stack.length - 1]!;
|
|
395
|
-
if (!('id' in lastResult)) {
|
|
396
|
-
throw new Error('Cannot use async iterator without ID column');
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
const lastId = lastResult.id;
|
|
400
|
-
if (typeof lastId !== 'string') {
|
|
401
|
-
throw new Error('Cannot use async iterator without string ID column');
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
next.andWhere('id', '>', lastId);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
return {
|
|
408
|
-
done: false,
|
|
409
|
-
value: stack[stackIndex],
|
|
410
|
-
};
|
|
411
|
-
},
|
|
412
|
-
maxQueries(maxQueries: number) {
|
|
413
|
-
this.options.maxQueries = maxQueries;
|
|
414
|
-
return this;
|
|
415
|
-
},
|
|
416
|
-
} as IterableSQLSelect<T> as any;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
allBatched(options: IterableSQLSelectOptions = {}): T extends { id: string } ? IterableSQLSelect<T[]> : never {
|
|
420
|
-
if (this._orderBy) {
|
|
421
|
-
throw new Error('Cannot use async iterator with custom order by. Results should be ordered by ID');
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
if (this._offset !== null) {
|
|
425
|
-
throw new Error('Cannot use async iterator with offset');
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
if (!this._limit) {
|
|
429
|
-
this._limit = 100;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
const limit = this._limit;
|
|
433
|
-
this.orderBy('id');
|
|
434
|
-
|
|
435
|
-
let next: this | null = this.clone();
|
|
436
|
-
const base = this;
|
|
437
|
-
|
|
438
|
-
return {
|
|
439
|
-
queryCount: 0,
|
|
440
|
-
options,
|
|
441
|
-
[Symbol.asyncIterator]() {
|
|
442
|
-
return {
|
|
443
|
-
...this,
|
|
444
|
-
|
|
445
|
-
// Reset the iterator
|
|
446
|
-
queryCount: 0,
|
|
447
|
-
};
|
|
448
|
-
},
|
|
449
|
-
get isDone() {
|
|
450
|
-
return !next;
|
|
451
|
-
},
|
|
452
|
-
async next(): Promise<IteratorResult<T[], undefined>> {
|
|
453
|
-
if (!next) {
|
|
454
|
-
return {
|
|
455
|
-
done: true,
|
|
456
|
-
value: undefined,
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
if (this.options.maxQueries !== undefined && this.queryCount >= this.options.maxQueries) {
|
|
461
|
-
// Stopping early
|
|
462
|
-
return {
|
|
463
|
-
done: true,
|
|
464
|
-
value: undefined,
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
const stack = await next.fetch();
|
|
469
|
-
next = null;
|
|
470
|
-
this.queryCount += 1;
|
|
471
|
-
|
|
472
|
-
if (stack.length === 0) {
|
|
473
|
-
return {
|
|
474
|
-
done: true,
|
|
475
|
-
value: undefined,
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
if (stack.length >= limit) {
|
|
480
|
-
next = base.clone();
|
|
481
|
-
const lastResult = stack[stack.length - 1]!;
|
|
482
|
-
if (!('id' in lastResult)) {
|
|
483
|
-
throw new Error('Cannot use async iterator without ID column');
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
const lastId = lastResult.id;
|
|
487
|
-
if (typeof lastId !== 'string') {
|
|
488
|
-
throw new Error('Cannot use async iterator without string ID column');
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
next.andWhere('id', '>', lastId);
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
return {
|
|
495
|
-
done: false,
|
|
496
|
-
value: stack,
|
|
497
|
-
};
|
|
498
|
-
},
|
|
499
|
-
maxQueries(maxQueries: number) {
|
|
500
|
-
this.options.maxQueries = maxQueries;
|
|
501
|
-
return this;
|
|
502
|
-
},
|
|
503
|
-
} as IterableSQLSelect<T[]> as any;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
getName(): string | null {
|
|
507
|
-
return this._name;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* By calling this method we make sure a name is set so we can return an SQLNamedSelect.
|
|
512
|
-
* @param name name of the select
|
|
513
|
-
* @returns an SQLNamedSelect
|
|
514
|
-
*/
|
|
515
|
-
as(name: string): SQLNamedSelect {
|
|
516
|
-
this._name = name;
|
|
517
|
-
|
|
518
|
-
return this as SQLNamedSelect;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { SQL, SQLColumnExpression, SQLExpression, SQLExpressionOptions, SQLQuery } from '@stamhoofd/sql';
|
|
2
|
-
import { Language } from '@stamhoofd/structures';
|
|
3
|
-
|
|
4
|
-
export class SQLTranslatedStringHelper implements SQLExpression {
|
|
5
|
-
constructor(private columnExpression: SQLColumnExpression, private path: string, private getLanguage: () => Language) {
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
getSQL(options?: SQLExpressionOptions): SQLQuery {
|
|
9
|
-
const currentLanguage = this.getLanguage();
|
|
10
|
-
|
|
11
|
-
const languageOrder: Language[] = [
|
|
12
|
-
Language.English,
|
|
13
|
-
Language.Dutch,
|
|
14
|
-
Language.French,
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
const languages = moveToFront(languageOrder, currentLanguage);
|
|
18
|
-
|
|
19
|
-
const languageValues: SQLExpression[] = languages.map((language) => {
|
|
20
|
-
return SQL.jsonValue(this.columnExpression, `${this.path}.${language}`, 'CHAR');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const type: SQLExpression = SQL.jsonType(SQL.jsonExtract(this.columnExpression, this.path));
|
|
24
|
-
|
|
25
|
-
return SQL.if(
|
|
26
|
-
type, '=', 'STRING',
|
|
27
|
-
).then(
|
|
28
|
-
SQL.jsonValue(this.columnExpression, this.path, 'CHAR'),
|
|
29
|
-
).else(
|
|
30
|
-
SQL.coalesce(...languageValues) as SQLExpression,
|
|
31
|
-
).getSQL(options);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function moveToFront<T>(arr: T[], value: T): T[] {
|
|
36
|
-
const index = arr.indexOf(value);
|
|
37
|
-
if (index === -1 || index === 0) return arr;
|
|
38
|
-
|
|
39
|
-
return [arr[index], ...arr.slice(0, index), ...arr.slice(index + 1)];
|
|
40
|
-
}
|