pqb 0.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/dist/index.d.ts +3630 -0
- package/dist/index.esm.js +4587 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +4691 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
- package/rollup.config.js +35 -0
- package/src/adapter.test.ts +10 -0
- package/src/adapter.ts +171 -0
- package/src/columnSchema/array.ts +21 -0
- package/src/columnSchema/boolean.ts +10 -0
- package/src/columnSchema/columnType.test.ts +129 -0
- package/src/columnSchema/columnType.ts +77 -0
- package/src/columnSchema/columnTypes.ts +145 -0
- package/src/columnSchema/columnsSchema.test.ts +32 -0
- package/src/columnSchema/columnsSchema.ts +100 -0
- package/src/columnSchema/commonMethods.ts +130 -0
- package/src/columnSchema/dateTime.ts +104 -0
- package/src/columnSchema/enum.ts +13 -0
- package/src/columnSchema/index.ts +11 -0
- package/src/columnSchema/json/array.ts +55 -0
- package/src/columnSchema/json/discriminatedUnion.ts +91 -0
- package/src/columnSchema/json/enum.ts +29 -0
- package/src/columnSchema/json/instanceOf.ts +16 -0
- package/src/columnSchema/json/intersection.ts +23 -0
- package/src/columnSchema/json/lazy.ts +22 -0
- package/src/columnSchema/json/literal.ts +12 -0
- package/src/columnSchema/json/map.ts +29 -0
- package/src/columnSchema/json/nativeEnum.ts +30 -0
- package/src/columnSchema/json/nullable.ts +33 -0
- package/src/columnSchema/json/nullish.ts +30 -0
- package/src/columnSchema/json/object.ts +206 -0
- package/src/columnSchema/json/optional.ts +28 -0
- package/src/columnSchema/json/record.ts +40 -0
- package/src/columnSchema/json/scalarTypes.ts +117 -0
- package/src/columnSchema/json/set.ts +34 -0
- package/src/columnSchema/json/tuple.ts +40 -0
- package/src/columnSchema/json/typeBase.ts +202 -0
- package/src/columnSchema/json/union.ts +16 -0
- package/src/columnSchema/json.ts +64 -0
- package/src/columnSchema/number.ts +122 -0
- package/src/columnSchema/string.ts +222 -0
- package/src/columnSchema/utils.ts +27 -0
- package/src/common.ts +86 -0
- package/src/db.test.ts +67 -0
- package/src/db.ts +212 -0
- package/src/errors.ts +7 -0
- package/src/index.ts +18 -0
- package/src/operators.test.ts +608 -0
- package/src/operators.ts +177 -0
- package/src/query.ts +292 -0
- package/src/queryDataUtils.ts +50 -0
- package/src/queryMethods/aggregate.test.ts +583 -0
- package/src/queryMethods/aggregate.ts +878 -0
- package/src/queryMethods/callbacks.test.ts +69 -0
- package/src/queryMethods/callbacks.ts +55 -0
- package/src/queryMethods/clear.test.ts +64 -0
- package/src/queryMethods/clear.ts +58 -0
- package/src/queryMethods/columnInfo.test.ts +45 -0
- package/src/queryMethods/columnInfo.ts +67 -0
- package/src/queryMethods/delete.test.ts +135 -0
- package/src/queryMethods/delete.ts +50 -0
- package/src/queryMethods/for.test.ts +57 -0
- package/src/queryMethods/for.ts +99 -0
- package/src/queryMethods/from.test.ts +66 -0
- package/src/queryMethods/from.ts +58 -0
- package/src/queryMethods/get.test.ts +66 -0
- package/src/queryMethods/get.ts +88 -0
- package/src/queryMethods/having.test.ts +247 -0
- package/src/queryMethods/having.ts +99 -0
- package/src/queryMethods/insert.test.ts +555 -0
- package/src/queryMethods/insert.ts +453 -0
- package/src/queryMethods/join.test.ts +150 -0
- package/src/queryMethods/join.ts +508 -0
- package/src/queryMethods/json.test.ts +398 -0
- package/src/queryMethods/json.ts +259 -0
- package/src/queryMethods/log.test.ts +172 -0
- package/src/queryMethods/log.ts +123 -0
- package/src/queryMethods/queryMethods.test.ts +629 -0
- package/src/queryMethods/queryMethods.ts +428 -0
- package/src/queryMethods/select.test.ts +479 -0
- package/src/queryMethods/select.ts +249 -0
- package/src/queryMethods/then.ts +236 -0
- package/src/queryMethods/transaction.test.ts +66 -0
- package/src/queryMethods/transaction.ts +66 -0
- package/src/queryMethods/union.test.ts +59 -0
- package/src/queryMethods/union.ts +89 -0
- package/src/queryMethods/update.test.ts +417 -0
- package/src/queryMethods/update.ts +350 -0
- package/src/queryMethods/upsert.test.ts +56 -0
- package/src/queryMethods/upsert.ts +43 -0
- package/src/queryMethods/where.test.ts +1594 -0
- package/src/queryMethods/where.ts +450 -0
- package/src/queryMethods/window.test.ts +66 -0
- package/src/queryMethods/window.ts +108 -0
- package/src/queryMethods/with.test.ts +191 -0
- package/src/queryMethods/with.ts +92 -0
- package/src/quote.ts +36 -0
- package/src/relations.ts +194 -0
- package/src/sql/aggregate.ts +80 -0
- package/src/sql/columnInfo.ts +22 -0
- package/src/sql/common.ts +42 -0
- package/src/sql/delete.ts +41 -0
- package/src/sql/distinct.ts +19 -0
- package/src/sql/fromAndAs.ts +51 -0
- package/src/sql/having.ts +140 -0
- package/src/sql/index.ts +2 -0
- package/src/sql/insert.ts +102 -0
- package/src/sql/join.ts +242 -0
- package/src/sql/orderBy.ts +41 -0
- package/src/sql/select.ts +153 -0
- package/src/sql/toSql.ts +153 -0
- package/src/sql/truncate.ts +13 -0
- package/src/sql/types.ts +355 -0
- package/src/sql/update.ts +62 -0
- package/src/sql/where.ts +314 -0
- package/src/sql/window.ts +38 -0
- package/src/sql/with.ts +32 -0
- package/src/test-utils.ts +172 -0
- package/src/utils.ts +140 -0
- package/tsconfig.build.json +6 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import { Query, QueryBase, SelectableBase, WithDataBase } from '../query';
|
|
2
|
+
import { ColumnOperators, QueryData } from '../sql';
|
|
3
|
+
import { pushQueryArray, pushQueryValue } from '../queryDataUtils';
|
|
4
|
+
import { RawExpression } from '../common';
|
|
5
|
+
import { getClonedQueryData, MaybeArray } from '../utils';
|
|
6
|
+
import { JoinArgs, JoinCallback, JoinCallbackArg } from './join';
|
|
7
|
+
import { RelationsBase } from '../relations';
|
|
8
|
+
|
|
9
|
+
export type WhereArg<T extends QueryBase> =
|
|
10
|
+
| (Omit<
|
|
11
|
+
{
|
|
12
|
+
[K in keyof T['selectable']]?:
|
|
13
|
+
| T['selectable'][K]['column']['type']
|
|
14
|
+
| null
|
|
15
|
+
| ColumnOperators<T['selectable'], K>
|
|
16
|
+
| RawExpression;
|
|
17
|
+
},
|
|
18
|
+
'NOT' | 'OR' | 'IN' | 'EXISTS'
|
|
19
|
+
> & {
|
|
20
|
+
NOT?: MaybeArray<WhereArg<T>>;
|
|
21
|
+
OR?: MaybeArray<WhereArg<T>>[];
|
|
22
|
+
IN?: MaybeArray<{
|
|
23
|
+
columns: (keyof T['selectable'])[];
|
|
24
|
+
values: unknown[][] | Query | RawExpression;
|
|
25
|
+
}>;
|
|
26
|
+
EXISTS?: MaybeArray<JoinArgs<T> | JoinCallbackArg<T>>;
|
|
27
|
+
})
|
|
28
|
+
| QueryBase
|
|
29
|
+
| RawExpression
|
|
30
|
+
| ((q: WhereQueryBuilder<T>) => WhereQueryBuilder);
|
|
31
|
+
|
|
32
|
+
export type WhereInColumn<T extends QueryBase> =
|
|
33
|
+
| keyof T['selectable']
|
|
34
|
+
| [keyof T['selectable'], ...(keyof T['selectable'])[]];
|
|
35
|
+
|
|
36
|
+
export type WhereInValues<
|
|
37
|
+
T extends QueryBase,
|
|
38
|
+
Column extends WhereInColumn<T>,
|
|
39
|
+
> = Column extends keyof T['selectable']
|
|
40
|
+
? T['selectable'][Column]['column']['type'][] | Query | RawExpression
|
|
41
|
+
:
|
|
42
|
+
| ({
|
|
43
|
+
[I in keyof Column]: Column[I] extends keyof T['selectable']
|
|
44
|
+
? T['selectable'][Column[I]]['column']['type']
|
|
45
|
+
: never;
|
|
46
|
+
} & {
|
|
47
|
+
length: Column extends { length: number } ? Column['length'] : never;
|
|
48
|
+
})[]
|
|
49
|
+
| Query
|
|
50
|
+
| RawExpression;
|
|
51
|
+
|
|
52
|
+
export type WhereResult<T extends QueryBase> = Omit<T, 'hasWhere'> & {
|
|
53
|
+
hasWhere: true;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export type WhereInArg<T extends Pick<Query, 'selectable'>> = {
|
|
57
|
+
[K in keyof T['selectable']]?:
|
|
58
|
+
| T['selectable'][K]['column']['type'][]
|
|
59
|
+
| Query
|
|
60
|
+
| RawExpression;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const addWhere = <T extends Where>(
|
|
64
|
+
q: T,
|
|
65
|
+
args: WhereArg<T>[],
|
|
66
|
+
): WhereResult<T> => {
|
|
67
|
+
return pushQueryArray(q, 'and', args) as unknown as WhereResult<T>;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const addWhereNot = <T extends QueryBase>(
|
|
71
|
+
q: T,
|
|
72
|
+
args: WhereArg<T>[],
|
|
73
|
+
): WhereResult<T> => {
|
|
74
|
+
return pushQueryValue(q, 'and', {
|
|
75
|
+
NOT: args,
|
|
76
|
+
}) as unknown as WhereResult<T>;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const addOr = <T extends QueryBase>(
|
|
80
|
+
q: T,
|
|
81
|
+
args: WhereArg<T>[],
|
|
82
|
+
): WhereResult<T> => {
|
|
83
|
+
return pushQueryArray(
|
|
84
|
+
q,
|
|
85
|
+
'or',
|
|
86
|
+
args.map((item) => [item]),
|
|
87
|
+
) as unknown as WhereResult<T>;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const addOrNot = <T extends QueryBase>(
|
|
91
|
+
q: T,
|
|
92
|
+
args: WhereArg<T>[],
|
|
93
|
+
): WhereResult<T> => {
|
|
94
|
+
return pushQueryArray(
|
|
95
|
+
q,
|
|
96
|
+
'or',
|
|
97
|
+
args.map((item) => [{ NOT: item }]),
|
|
98
|
+
) as unknown as WhereResult<T>;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const addWhereIn = <T extends QueryBase>(
|
|
102
|
+
q: T,
|
|
103
|
+
and: boolean,
|
|
104
|
+
arg: unknown,
|
|
105
|
+
values: unknown[] | unknown[][] | Query | RawExpression | undefined,
|
|
106
|
+
not?: boolean,
|
|
107
|
+
): WhereResult<T> => {
|
|
108
|
+
const op = not ? 'notIn' : 'in';
|
|
109
|
+
|
|
110
|
+
let item;
|
|
111
|
+
if (values) {
|
|
112
|
+
if (Array.isArray(arg)) {
|
|
113
|
+
item = {
|
|
114
|
+
IN: {
|
|
115
|
+
columns: arg,
|
|
116
|
+
values,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
if (not) item = { NOT: item };
|
|
120
|
+
} else {
|
|
121
|
+
item = { [arg as string]: { [op]: values } };
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
item = {} as Record<string, { in: unknown[] }>;
|
|
125
|
+
for (const key in arg as Record<string, unknown[]>) {
|
|
126
|
+
item[key] = { [op as 'in']: (arg as Record<string, unknown[]>)[key] };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (and) {
|
|
131
|
+
pushQueryValue(q, 'and', item);
|
|
132
|
+
} else {
|
|
133
|
+
pushQueryValue(q, 'or', [item]);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return q as unknown as WhereResult<T>;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export abstract class Where implements QueryBase {
|
|
140
|
+
abstract clone<T extends this>(this: T): T;
|
|
141
|
+
abstract selectable: SelectableBase;
|
|
142
|
+
abstract relations: RelationsBase;
|
|
143
|
+
abstract withData: WithDataBase;
|
|
144
|
+
abstract __model: Query;
|
|
145
|
+
|
|
146
|
+
query = {} as QueryData;
|
|
147
|
+
table?: string;
|
|
148
|
+
tableAlias?: string;
|
|
149
|
+
|
|
150
|
+
where<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
151
|
+
return this.clone()._where(...args);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
_where<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
155
|
+
return addWhere(this, args);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
whereNot<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
159
|
+
return this.clone()._whereNot(...args);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
_whereNot<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
163
|
+
return addWhereNot(this, args);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
and<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
167
|
+
return this.where(...args);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
_and<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
171
|
+
return this._where(...args);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
andNot<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
175
|
+
return this.whereNot(...args);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
_andNot<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
179
|
+
return this._whereNot(...args);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
or<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
183
|
+
return this.clone()._or(...args);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
_or<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
187
|
+
return addOr(this, args);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
orNot<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
191
|
+
return this.clone()._orNot(...args);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
_orNot<T extends Where>(this: T, ...args: WhereArg<T>[]): WhereResult<T> {
|
|
195
|
+
return addOrNot(this, args);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
whereIn<T extends Where, Column extends WhereInColumn<T>>(
|
|
199
|
+
this: T,
|
|
200
|
+
column: Column,
|
|
201
|
+
values: WhereInValues<T, Column>,
|
|
202
|
+
): T;
|
|
203
|
+
whereIn<T extends Where>(this: T, arg: WhereInArg<T>): T;
|
|
204
|
+
whereIn<T extends Where>(
|
|
205
|
+
this: T,
|
|
206
|
+
arg: unknown | unknown[],
|
|
207
|
+
values?: unknown[] | unknown[][] | Query | RawExpression,
|
|
208
|
+
): WhereResult<T> {
|
|
209
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
210
|
+
return this.clone()._whereIn(
|
|
211
|
+
arg as any,
|
|
212
|
+
values as any,
|
|
213
|
+
) as unknown as WhereResult<T>;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
_whereIn<T extends Where, Column extends WhereInColumn<T>>(
|
|
217
|
+
this: T,
|
|
218
|
+
column: Column,
|
|
219
|
+
values: WhereInValues<T, Column>,
|
|
220
|
+
): WhereResult<T>;
|
|
221
|
+
_whereIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
222
|
+
_whereIn<T extends Where>(
|
|
223
|
+
this: T,
|
|
224
|
+
arg: unknown,
|
|
225
|
+
values?: unknown[] | unknown[][] | Query | RawExpression,
|
|
226
|
+
): WhereResult<T> {
|
|
227
|
+
return addWhereIn(this, true, arg, values);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
orWhereIn<T extends Where, Column extends WhereInColumn<T>>(
|
|
231
|
+
this: T,
|
|
232
|
+
column: Column,
|
|
233
|
+
values: WhereInValues<T, Column>,
|
|
234
|
+
): WhereResult<T>;
|
|
235
|
+
orWhereIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
236
|
+
orWhereIn<T extends Where>(
|
|
237
|
+
this: T,
|
|
238
|
+
arg: unknown | unknown[],
|
|
239
|
+
values?: unknown[] | unknown[][] | Query | RawExpression,
|
|
240
|
+
): WhereResult<T> {
|
|
241
|
+
return this.clone()._orWhereIn(
|
|
242
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
243
|
+
arg as any,
|
|
244
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
245
|
+
values as any,
|
|
246
|
+
) as unknown as WhereResult<T>;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
_orWhereIn<T extends Where, Column extends WhereInColumn<T>>(
|
|
250
|
+
this: T,
|
|
251
|
+
column: Column,
|
|
252
|
+
values: WhereInValues<T, Column>,
|
|
253
|
+
): WhereResult<T>;
|
|
254
|
+
_orWhereIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
255
|
+
_orWhereIn<T extends Where>(
|
|
256
|
+
this: T,
|
|
257
|
+
arg: unknown,
|
|
258
|
+
values?: unknown[] | unknown[][] | Query | RawExpression,
|
|
259
|
+
): WhereResult<T> {
|
|
260
|
+
return addWhereIn(this, false, arg, values);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
whereNotIn<T extends Where, Column extends WhereInColumn<T>>(
|
|
264
|
+
this: T,
|
|
265
|
+
column: Column,
|
|
266
|
+
values: WhereInValues<T, Column>,
|
|
267
|
+
): WhereResult<T>;
|
|
268
|
+
whereNotIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
269
|
+
whereNotIn<T extends Where>(
|
|
270
|
+
this: T,
|
|
271
|
+
arg: unknown | unknown[],
|
|
272
|
+
values?: unknown[] | unknown[][] | Query | RawExpression,
|
|
273
|
+
): WhereResult<T> {
|
|
274
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
275
|
+
return this.clone()._whereNotIn(arg as any, values as any);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
_whereNotIn<T extends Where, Column extends WhereInColumn<T>>(
|
|
279
|
+
this: T,
|
|
280
|
+
column: Column,
|
|
281
|
+
values: WhereInValues<T, Column>,
|
|
282
|
+
): WhereResult<T>;
|
|
283
|
+
_whereNotIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
284
|
+
_whereNotIn<T extends Where>(
|
|
285
|
+
this: T,
|
|
286
|
+
arg: unknown,
|
|
287
|
+
values?: unknown[] | unknown[][] | Query | RawExpression,
|
|
288
|
+
): WhereResult<T> {
|
|
289
|
+
return addWhereIn(this, true, arg, values, true);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
orWhereNotIn<T extends Where, Column extends WhereInColumn<T>>(
|
|
293
|
+
this: T,
|
|
294
|
+
column: Column,
|
|
295
|
+
values: WhereInValues<T, Column>,
|
|
296
|
+
): WhereResult<T>;
|
|
297
|
+
orWhereNotIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
298
|
+
orWhereNotIn<T extends Where>(
|
|
299
|
+
this: T,
|
|
300
|
+
arg: unknown | unknown[],
|
|
301
|
+
values?: unknown[] | unknown[][] | Query | RawExpression,
|
|
302
|
+
): WhereResult<T> {
|
|
303
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
304
|
+
return this.clone()._orWhereNotIn(arg as any, values as any);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
_orWhereNotIn<T extends Where, Column extends WhereInColumn<T>>(
|
|
308
|
+
this: T,
|
|
309
|
+
column: Column,
|
|
310
|
+
values: WhereInValues<T, Column>,
|
|
311
|
+
): WhereResult<T>;
|
|
312
|
+
_orWhereNotIn<T extends Where>(this: T, arg: WhereInArg<T>): WhereResult<T>;
|
|
313
|
+
_orWhereNotIn<T extends Where>(
|
|
314
|
+
this: T,
|
|
315
|
+
arg: unknown,
|
|
316
|
+
values?: unknown[] | unknown[][] | Query | RawExpression,
|
|
317
|
+
): WhereResult<T> {
|
|
318
|
+
return addWhereIn(this, false, arg, values, true);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
whereExists<T extends Where, Args extends JoinArgs<T>>(
|
|
322
|
+
this: T,
|
|
323
|
+
...args: Args
|
|
324
|
+
): WhereResult<T>;
|
|
325
|
+
whereExists<T extends Where, Arg extends JoinCallbackArg<T>>(
|
|
326
|
+
this: T,
|
|
327
|
+
arg: Arg,
|
|
328
|
+
cb: JoinCallback<T, Arg>,
|
|
329
|
+
): WhereResult<T>;
|
|
330
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
331
|
+
whereExists(...args: any) {
|
|
332
|
+
return this.clone()._whereExists(...args);
|
|
333
|
+
}
|
|
334
|
+
_whereExists<T extends Where, Args extends JoinArgs<T>>(
|
|
335
|
+
this: T,
|
|
336
|
+
...args: Args
|
|
337
|
+
): WhereResult<T>;
|
|
338
|
+
_whereExists<T extends Where, Arg extends JoinCallbackArg<T>>(
|
|
339
|
+
this: T,
|
|
340
|
+
arg: Arg,
|
|
341
|
+
cb: JoinCallback<T, Arg>,
|
|
342
|
+
): WhereResult<T>;
|
|
343
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
344
|
+
_whereExists(this: Where, ...args: any) {
|
|
345
|
+
return this._where({ EXISTS: args });
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
orWhereExists<T extends Where, Args extends JoinArgs<T>>(
|
|
349
|
+
this: T,
|
|
350
|
+
...args: Args
|
|
351
|
+
): WhereResult<T>;
|
|
352
|
+
orWhereExists<T extends Where, Arg extends JoinCallbackArg<T>>(
|
|
353
|
+
this: T,
|
|
354
|
+
arg: Arg,
|
|
355
|
+
cb: JoinCallback<T, Arg>,
|
|
356
|
+
): WhereResult<T>;
|
|
357
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
358
|
+
orWhereExists(...args: any) {
|
|
359
|
+
return this.clone()._orWhereExists(...args);
|
|
360
|
+
}
|
|
361
|
+
_orWhereExists<T extends Where, Args extends JoinArgs<T>>(
|
|
362
|
+
this: T,
|
|
363
|
+
...args: Args
|
|
364
|
+
): WhereResult<T>;
|
|
365
|
+
_orWhereExists<T extends Where, Arg extends JoinCallbackArg<T>>(
|
|
366
|
+
this: T,
|
|
367
|
+
arg: Arg,
|
|
368
|
+
cb: JoinCallback<T, Arg>,
|
|
369
|
+
): WhereResult<T>;
|
|
370
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
371
|
+
_orWhereExists(this: Where, ...args: any) {
|
|
372
|
+
return this._or({ EXISTS: args });
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
whereNotExists<T extends Where, Args extends JoinArgs<T>>(
|
|
376
|
+
this: T,
|
|
377
|
+
...args: Args
|
|
378
|
+
): WhereResult<T>;
|
|
379
|
+
whereNotExists<T extends Where, Arg extends JoinCallbackArg<T>>(
|
|
380
|
+
this: T,
|
|
381
|
+
arg: Arg,
|
|
382
|
+
cb: JoinCallback<T, Arg>,
|
|
383
|
+
): WhereResult<T>;
|
|
384
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
385
|
+
whereNotExists(...args: any) {
|
|
386
|
+
return this.clone()._whereNotExists(...args);
|
|
387
|
+
}
|
|
388
|
+
_whereNotExists<T extends Where, Args extends JoinArgs<T>>(
|
|
389
|
+
this: T,
|
|
390
|
+
...args: Args
|
|
391
|
+
): WhereResult<T>;
|
|
392
|
+
_whereNotExists<T extends Where, Arg extends JoinCallbackArg<T>>(
|
|
393
|
+
this: T,
|
|
394
|
+
arg: Arg,
|
|
395
|
+
cb: JoinCallback<T, Arg>,
|
|
396
|
+
): WhereResult<T>;
|
|
397
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
398
|
+
_whereNotExists(this: Where, ...args: any) {
|
|
399
|
+
return this._whereNot({ EXISTS: args });
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
orWhereNotExists<T extends Where, Args extends JoinArgs<T>>(
|
|
403
|
+
this: T,
|
|
404
|
+
...args: Args
|
|
405
|
+
): WhereResult<T>;
|
|
406
|
+
orWhereNotExists<T extends Where, Arg extends JoinCallbackArg<T>>(
|
|
407
|
+
this: T,
|
|
408
|
+
arg: Arg,
|
|
409
|
+
cb: JoinCallback<T, Arg>,
|
|
410
|
+
): WhereResult<T>;
|
|
411
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
412
|
+
orWhereNotExists(...args: any) {
|
|
413
|
+
return this.clone()._orWhereNotExists(...args);
|
|
414
|
+
}
|
|
415
|
+
_orWhereNotExists<T extends Where, Args extends JoinArgs<T>>(
|
|
416
|
+
this: T,
|
|
417
|
+
...args: Args
|
|
418
|
+
): WhereResult<T>;
|
|
419
|
+
_orWhereNotExists<T extends Where, Arg extends JoinCallbackArg<T>>(
|
|
420
|
+
this: T,
|
|
421
|
+
arg: Arg,
|
|
422
|
+
cb: JoinCallback<T, Arg>,
|
|
423
|
+
): WhereResult<T>;
|
|
424
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
425
|
+
_orWhereNotExists(this: Where, ...args: any) {
|
|
426
|
+
return this._orNot({ EXISTS: args });
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
export class WhereQueryBuilder<Q extends QueryBase = QueryBase>
|
|
431
|
+
extends Where
|
|
432
|
+
implements QueryBase
|
|
433
|
+
{
|
|
434
|
+
query = {} as QueryData;
|
|
435
|
+
selectable!: Q['selectable'];
|
|
436
|
+
__model: Query;
|
|
437
|
+
relations = {};
|
|
438
|
+
withData = {};
|
|
439
|
+
|
|
440
|
+
constructor(public table: Q['table'], public tableAlias: Q['tableAlias']) {
|
|
441
|
+
super();
|
|
442
|
+
this.__model = this as unknown as Query;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
clone<T extends this>(this: T): T {
|
|
446
|
+
const cloned = Object.create(this.__model);
|
|
447
|
+
cloned.query = getClonedQueryData(this.query);
|
|
448
|
+
return cloned as unknown as T;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AssertEqual,
|
|
3
|
+
expectQueryNotMutated,
|
|
4
|
+
expectSql,
|
|
5
|
+
User,
|
|
6
|
+
userData,
|
|
7
|
+
useTestDatabase,
|
|
8
|
+
} from '../test-utils';
|
|
9
|
+
|
|
10
|
+
describe('window functions', () => {
|
|
11
|
+
useTestDatabase();
|
|
12
|
+
|
|
13
|
+
describe.each`
|
|
14
|
+
method | functionName | results
|
|
15
|
+
${'selectRowNumber'} | ${'row_number'} | ${[1, 2, 1, 2]}
|
|
16
|
+
${'selectRank'} | ${'rank'} | ${[1, 1, 1, 1]}
|
|
17
|
+
${'selectDenseRank'} | ${'dense_rank'} | ${[1, 1, 1, 1]}
|
|
18
|
+
${'selectPercentRank'} | ${'percent_rank'} | ${[0, 0, 0, 0]}
|
|
19
|
+
${'selectCumeDist'} | ${'cume_dist'} | ${[1, 1, 1, 1]}
|
|
20
|
+
`('$method', ({ method, functionName, results }) => {
|
|
21
|
+
it('should return array of objects with number value', async () => {
|
|
22
|
+
if (method === 'selectCumeDist') {
|
|
23
|
+
await User.insert([
|
|
24
|
+
{ ...userData, age: 20 },
|
|
25
|
+
{ ...userData, age: 20 },
|
|
26
|
+
]);
|
|
27
|
+
await User.insert([
|
|
28
|
+
{ ...userData, age: 30 },
|
|
29
|
+
{ ...userData, age: 30 },
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
const value = await User[method as 'selectRowNumber']({
|
|
33
|
+
partitionBy: 'age',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const eq: AssertEqual<typeof value, { row_number: number }[]> = true;
|
|
37
|
+
expect(eq).toBe(true);
|
|
38
|
+
|
|
39
|
+
expect(value).toEqual(
|
|
40
|
+
(results as number[]).map((item) => ({ [functionName]: item })),
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it(`should perform ${method} query`, () => {
|
|
46
|
+
const q = User.clone();
|
|
47
|
+
const expectedSql = `SELECT ${functionName}() OVER (PARTITION BY "user"."name" ORDER BY "user"."createdAt" DESC) AS "as" FROM "user"`;
|
|
48
|
+
expectSql(
|
|
49
|
+
q[method as 'selectRank']({
|
|
50
|
+
as: 'as',
|
|
51
|
+
partitionBy: 'name',
|
|
52
|
+
order: { createdAt: 'DESC' },
|
|
53
|
+
}).toSql(),
|
|
54
|
+
expectedSql,
|
|
55
|
+
);
|
|
56
|
+
expectQueryNotMutated(q);
|
|
57
|
+
|
|
58
|
+
q[`_${method}` as '_selectRank']({
|
|
59
|
+
as: 'as',
|
|
60
|
+
partitionBy: 'name',
|
|
61
|
+
order: { createdAt: 'DESC' },
|
|
62
|
+
});
|
|
63
|
+
expectSql(q.toSql(), expectedSql);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Query } from '../query';
|
|
2
|
+
import { ColumnType, IntegerColumn } from '../columnSchema';
|
|
3
|
+
import { SelectAgg, WindowFunctionOptions } from './aggregate';
|
|
4
|
+
import { pushQueryValue } from '../queryDataUtils';
|
|
5
|
+
import { addParserToQuery } from './select';
|
|
6
|
+
|
|
7
|
+
const selectWindowFunction = <
|
|
8
|
+
T extends Query,
|
|
9
|
+
Func extends string,
|
|
10
|
+
As extends string | undefined,
|
|
11
|
+
Value extends ColumnType,
|
|
12
|
+
>(
|
|
13
|
+
self: T,
|
|
14
|
+
functionName: Func,
|
|
15
|
+
options: WindowFunctionOptions<T, As>,
|
|
16
|
+
parse?: (input: unknown) => Value['type'],
|
|
17
|
+
): SelectAgg<T, Func, As, Value> => {
|
|
18
|
+
pushQueryValue(self, 'select', {
|
|
19
|
+
function: functionName,
|
|
20
|
+
options: {
|
|
21
|
+
as: options.as,
|
|
22
|
+
over: options,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (parse) {
|
|
27
|
+
addParserToQuery(self.query, options.as || functionName, parse);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return self as unknown as SelectAgg<T, Func, As, Value>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const toInt = (input: unknown) => parseInt(input as string);
|
|
34
|
+
|
|
35
|
+
export class Window {
|
|
36
|
+
selectRowNumber<T extends Query, As extends string | undefined = undefined>(
|
|
37
|
+
this: T,
|
|
38
|
+
options: WindowFunctionOptions<T, As>,
|
|
39
|
+
): SelectAgg<T, 'row_number', As, IntegerColumn> {
|
|
40
|
+
return this.clone()._selectRowNumber(options);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
_selectRowNumber<T extends Query, As extends string | undefined = undefined>(
|
|
44
|
+
this: T,
|
|
45
|
+
options: WindowFunctionOptions<T, As>,
|
|
46
|
+
): SelectAgg<T, 'row_number', As, IntegerColumn> {
|
|
47
|
+
return selectWindowFunction(this, 'row_number', options, toInt);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
selectRank<T extends Query, As extends string | undefined = undefined>(
|
|
51
|
+
this: T,
|
|
52
|
+
options: WindowFunctionOptions<T, As>,
|
|
53
|
+
): SelectAgg<T, 'rank', As, IntegerColumn> {
|
|
54
|
+
return this.clone()._selectRank(options);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
_selectRank<T extends Query, As extends string | undefined = undefined>(
|
|
58
|
+
this: T,
|
|
59
|
+
options: WindowFunctionOptions<T, As>,
|
|
60
|
+
): SelectAgg<T, 'rank', As, IntegerColumn> {
|
|
61
|
+
return selectWindowFunction(this, 'rank', options, toInt);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
selectDenseRank<T extends Query, As extends string | undefined = undefined>(
|
|
65
|
+
this: T,
|
|
66
|
+
options: WindowFunctionOptions<T, As>,
|
|
67
|
+
): SelectAgg<T, 'dense_rank', As, IntegerColumn> {
|
|
68
|
+
return this.clone()._selectDenseRank(options);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_selectDenseRank<T extends Query, As extends string | undefined = undefined>(
|
|
72
|
+
this: T,
|
|
73
|
+
options: WindowFunctionOptions<T, As>,
|
|
74
|
+
): SelectAgg<T, 'dense_rank', As, IntegerColumn> {
|
|
75
|
+
return selectWindowFunction(this, 'dense_rank', options, toInt);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
selectPercentRank<T extends Query, As extends string | undefined = undefined>(
|
|
79
|
+
this: T,
|
|
80
|
+
options: WindowFunctionOptions<T, As>,
|
|
81
|
+
): SelectAgg<T, 'percent_rank', As, IntegerColumn> {
|
|
82
|
+
return this.clone()._selectPercentRank(options);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
_selectPercentRank<
|
|
86
|
+
T extends Query,
|
|
87
|
+
As extends string | undefined = undefined,
|
|
88
|
+
>(
|
|
89
|
+
this: T,
|
|
90
|
+
options: WindowFunctionOptions<T, As>,
|
|
91
|
+
): SelectAgg<T, 'percent_rank', As, IntegerColumn> {
|
|
92
|
+
return selectWindowFunction(this, 'percent_rank', options, toInt);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
selectCumeDist<T extends Query, As extends string | undefined = undefined>(
|
|
96
|
+
this: T,
|
|
97
|
+
options: WindowFunctionOptions<T, As>,
|
|
98
|
+
): SelectAgg<T, 'cume_dist', As, IntegerColumn> {
|
|
99
|
+
return this.clone()._selectCumeDist(options);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
_selectCumeDist<T extends Query, As extends string | undefined = undefined>(
|
|
103
|
+
this: T,
|
|
104
|
+
options: WindowFunctionOptions<T, As>,
|
|
105
|
+
): SelectAgg<T, 'cume_dist', As, IntegerColumn> {
|
|
106
|
+
return selectWindowFunction(this, 'cume_dist', options, toInt);
|
|
107
|
+
}
|
|
108
|
+
}
|