@visactor/vquery 0.4.9 → 0.4.10
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/browser/esm/browser.js +91 -96
- package/dist/browser/esm/sql-builder/builders/having.d.ts +2 -2
- package/dist/browser/esm/sql-builder/builders/index.d.ts +2 -1
- package/dist/browser/esm/sql-builder/builders/order.d.ts +7 -0
- package/dist/browser/esm/sql-builder/builders/where.d.ts +2 -2
- package/dist/browser/esm/sql-builder/dslToSQL.d.ts +1 -1
- package/dist/browser/esm/types/dsl/QueryDSL.d.ts +1 -1
- package/dist/node/cjs/node.cjs +91 -96
- package/dist/node/cjs/sql-builder/builders/having.d.ts +2 -2
- package/dist/node/cjs/sql-builder/builders/index.d.ts +2 -1
- package/dist/node/cjs/sql-builder/builders/order.d.ts +7 -0
- package/dist/node/cjs/sql-builder/builders/where.d.ts +2 -2
- package/dist/node/cjs/sql-builder/dslToSQL.d.ts +1 -1
- package/dist/node/cjs/types/dsl/QueryDSL.d.ts +1 -1
- package/dist/node/esm/node.js +91 -96
- package/dist/node/esm/sql-builder/builders/having.d.ts +2 -2
- package/dist/node/esm/sql-builder/builders/index.d.ts +2 -1
- package/dist/node/esm/sql-builder/builders/order.d.ts +7 -0
- package/dist/node/esm/sql-builder/builders/where.d.ts +2 -2
- package/dist/node/esm/sql-builder/dslToSQL.d.ts +1 -1
- package/dist/node/esm/types/dsl/QueryDSL.d.ts +1 -1
- package/package.json +1 -1
|
@@ -51,7 +51,17 @@ const inlineParameters = (sql, params)=>{
|
|
|
51
51
|
});
|
|
52
52
|
return sql;
|
|
53
53
|
};
|
|
54
|
-
const
|
|
54
|
+
const operatorMap = {
|
|
55
|
+
gt: '>',
|
|
56
|
+
gte: '>=',
|
|
57
|
+
lt: '<',
|
|
58
|
+
lte: '<=',
|
|
59
|
+
eq: '=',
|
|
60
|
+
neq: '!='
|
|
61
|
+
};
|
|
62
|
+
const toSqlOperator = (op)=>operatorMap[op] ?? op;
|
|
63
|
+
const applyWhere = (qb, where)=>{
|
|
64
|
+
if (!where) return qb;
|
|
55
65
|
const toRaw = (w)=>{
|
|
56
66
|
if ('op' in w && 'conditions' in w) {
|
|
57
67
|
const parts = w.conditions.map((c)=>toRaw(c));
|
|
@@ -61,6 +71,7 @@ const applyWhere = (where)=>{
|
|
|
61
71
|
const leaf = w;
|
|
62
72
|
const field = leaf.field;
|
|
63
73
|
const value = leaf.value;
|
|
74
|
+
const sqlOp = toSqlOperator(leaf.op);
|
|
64
75
|
switch(leaf.op){
|
|
65
76
|
case 'is null':
|
|
66
77
|
return external_kysely_sql`${external_kysely_sql.ref(field)} is null`;
|
|
@@ -91,10 +102,10 @@ const applyWhere = (where)=>{
|
|
|
91
102
|
return external_kysely_sql`${external_kysely_sql.ref(field)} not between ${external_kysely_sql.val(a)} and ${external_kysely_sql.val(b)}`;
|
|
92
103
|
}
|
|
93
104
|
default:
|
|
94
|
-
return external_kysely_sql`${external_kysely_sql.ref(field)} ${external_kysely_sql.raw(
|
|
105
|
+
return external_kysely_sql`${external_kysely_sql.ref(field)} ${external_kysely_sql.raw(sqlOp)} ${external_kysely_sql.val(value)}`;
|
|
95
106
|
}
|
|
96
107
|
};
|
|
97
|
-
return toRaw(where);
|
|
108
|
+
return qb.where(toRaw(where));
|
|
98
109
|
};
|
|
99
110
|
const applyGroupBy = (qb, fields)=>{
|
|
100
111
|
if (fields && fields.length > 0) {
|
|
@@ -103,60 +114,17 @@ const applyGroupBy = (qb, fields)=>{
|
|
|
103
114
|
}
|
|
104
115
|
return qb;
|
|
105
116
|
};
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
day: '%Y-%m-%d',
|
|
114
|
-
week: '%Y-W%W',
|
|
115
|
-
hour: '%Y-%m-%d %H',
|
|
116
|
-
minute: '%Y-%m-%d %H:%M',
|
|
117
|
-
second: '%Y-%m-%d %H:%M:%S'
|
|
117
|
+
const having_operatorMap = {
|
|
118
|
+
gt: '>',
|
|
119
|
+
gte: '>=',
|
|
120
|
+
lt: '<',
|
|
121
|
+
lte: '<=',
|
|
122
|
+
eq: '=',
|
|
123
|
+
neq: '!='
|
|
118
124
|
};
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const field = item.field;
|
|
123
|
-
const expression = eb.ref(field);
|
|
124
|
-
if (item.aggr) {
|
|
125
|
-
const { func } = item.aggr;
|
|
126
|
-
const sqlAlias = field;
|
|
127
|
-
if ([
|
|
128
|
-
'avg',
|
|
129
|
-
'sum',
|
|
130
|
-
'min',
|
|
131
|
-
'max',
|
|
132
|
-
'variance',
|
|
133
|
-
'variancePop',
|
|
134
|
-
'stddev',
|
|
135
|
-
'median'
|
|
136
|
-
].includes(func)) {
|
|
137
|
-
if ('variance' === func) return external_kysely_sql`var_samp(${expression})`.as(sqlAlias);
|
|
138
|
-
if ('variancePop' === func) return external_kysely_sql`var_pop(${expression})`.as(sqlAlias);
|
|
139
|
-
return external_kysely_sql`${external_kysely_sql.raw(func)}(${expression})`.as(sqlAlias);
|
|
140
|
-
}
|
|
141
|
-
if ('count' === func) return external_kysely_sql`CAST(count(${expression}) AS INTEGER)`.as(sqlAlias);
|
|
142
|
-
if ('quantile' === func) {
|
|
143
|
-
const q = item.aggr.quantile ?? 0.5;
|
|
144
|
-
return external_kysely_sql`quantile(${expression}, ${q})`.as(sqlAlias);
|
|
145
|
-
} else if ('count_distinct' === func) return external_kysely_sql`CAST(count(distinct ${expression}) AS INTEGER)`.as(sqlAlias);
|
|
146
|
-
else if (func.startsWith('to_')) {
|
|
147
|
-
const dateTrunc = func.replace('to_', '');
|
|
148
|
-
const format = DATE_FORMAT_MAP[dateTrunc];
|
|
149
|
-
if (format) return external_kysely_sql`strftime(CAST(${expression} AS TIMESTAMP), ${format})`.as(sqlAlias);
|
|
150
|
-
if ('quarter' === dateTrunc) return external_kysely_sql`strftime(CAST(${expression} AS TIMESTAMP), '%Y') || '-Q' || date_part('quarter', CAST(${expression} AS TIMESTAMP))`.as(sqlAlias);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return expression.as(field);
|
|
154
|
-
}
|
|
155
|
-
return item;
|
|
156
|
-
}));
|
|
157
|
-
return qb.selectAll();
|
|
158
|
-
};
|
|
159
|
-
const applyHaving = (having)=>{
|
|
125
|
+
const having_toSqlOperator = (op)=>having_operatorMap[op] ?? op;
|
|
126
|
+
const applyHaving = (qb, having)=>{
|
|
127
|
+
if (!having) return qb;
|
|
160
128
|
const toRaw = (h)=>{
|
|
161
129
|
if ('op' in h && 'conditions' in h) {
|
|
162
130
|
const parts = h.conditions.map((c)=>toRaw(c));
|
|
@@ -166,7 +134,7 @@ const applyHaving = (having)=>{
|
|
|
166
134
|
const leaf = h;
|
|
167
135
|
const field = leaf.field;
|
|
168
136
|
const value = leaf.value;
|
|
169
|
-
const op = leaf.op;
|
|
137
|
+
const op = having_toSqlOperator(leaf.op);
|
|
170
138
|
if ([
|
|
171
139
|
'sum',
|
|
172
140
|
'avg',
|
|
@@ -177,7 +145,7 @@ const applyHaving = (having)=>{
|
|
|
177
145
|
const aggrExpr = external_kysely_sql`${external_kysely_sql.raw(op.toLowerCase())}(${external_kysely_sql.ref(field)})`;
|
|
178
146
|
return external_kysely_sql`${aggrExpr} = ${external_kysely_sql.val(value)}`;
|
|
179
147
|
}
|
|
180
|
-
switch(op){
|
|
148
|
+
switch(leaf.op){
|
|
181
149
|
case 'is null':
|
|
182
150
|
return external_kysely_sql`${external_kysely_sql.ref(field)} is null`;
|
|
183
151
|
case 'is not null':
|
|
@@ -210,22 +178,66 @@ const applyHaving = (having)=>{
|
|
|
210
178
|
return external_kysely_sql`${external_kysely_sql.ref(field)} ${external_kysely_sql.raw(op)} ${external_kysely_sql.val(value)}`;
|
|
211
179
|
}
|
|
212
180
|
};
|
|
213
|
-
return toRaw(having);
|
|
181
|
+
return qb.having(toRaw(having));
|
|
214
182
|
};
|
|
215
|
-
const
|
|
216
|
-
if (
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
183
|
+
const applyLimit = (qb, limit)=>{
|
|
184
|
+
if (limit && 'number' == typeof limit) qb = qb.limit(limit);
|
|
185
|
+
return qb;
|
|
186
|
+
};
|
|
187
|
+
const applyOrder = (qb, orderBy)=>{
|
|
188
|
+
if (orderBy && orderBy.length > 0) orderBy.forEach((o)=>{
|
|
189
|
+
qb = qb.orderBy(o.field, o.order ?? 'asc');
|
|
190
|
+
});
|
|
191
|
+
return qb;
|
|
192
|
+
};
|
|
193
|
+
const DATE_FORMAT_MAP = {
|
|
194
|
+
year: '%Y',
|
|
195
|
+
month: '%Y-%m',
|
|
196
|
+
day: '%Y-%m-%d',
|
|
197
|
+
week: '%Y-W%W',
|
|
198
|
+
hour: '%Y-%m-%d %H',
|
|
199
|
+
minute: '%Y-%m-%d %H:%M',
|
|
200
|
+
second: '%Y-%m-%d %H:%M:%S'
|
|
201
|
+
};
|
|
202
|
+
const applySelect = (qb, select)=>{
|
|
203
|
+
if (select && select.length > 0) return qb.select((eb)=>select.map((item)=>{
|
|
204
|
+
if (isSelectItem(item)) {
|
|
205
|
+
const field = item.field;
|
|
206
|
+
const expression = eb.ref(field);
|
|
207
|
+
const alias = item.alias ?? field;
|
|
208
|
+
if (item.aggr) {
|
|
209
|
+
const { func } = item.aggr;
|
|
210
|
+
if ([
|
|
211
|
+
'avg',
|
|
212
|
+
'sum',
|
|
213
|
+
'min',
|
|
214
|
+
'max',
|
|
215
|
+
'variance',
|
|
216
|
+
'variancePop',
|
|
217
|
+
'stddev',
|
|
218
|
+
'median'
|
|
219
|
+
].includes(func)) {
|
|
220
|
+
if ('variance' === func) return external_kysely_sql`var_samp(${expression})`.as(alias);
|
|
221
|
+
if ('variancePop' === func) return external_kysely_sql`var_pop(${expression})`.as(alias);
|
|
222
|
+
return external_kysely_sql`${external_kysely_sql.raw(func)}(${expression})`.as(alias);
|
|
223
|
+
}
|
|
224
|
+
if ('count' === func) return external_kysely_sql`CAST(count(${expression}) AS INTEGER)`.as(alias);
|
|
225
|
+
if ('quantile' === func) {
|
|
226
|
+
const q = item.aggr.quantile ?? 0.5;
|
|
227
|
+
return external_kysely_sql`quantile(${expression}, ${q})`.as(alias);
|
|
228
|
+
} else if ('count_distinct' === func) return external_kysely_sql`CAST(count(distinct ${expression}) AS INTEGER)`.as(alias);
|
|
229
|
+
else if (func.startsWith('to_')) {
|
|
230
|
+
const dateTrunc = func.replace('to_', '');
|
|
231
|
+
const format = DATE_FORMAT_MAP[dateTrunc];
|
|
232
|
+
if (format) return external_kysely_sql`strftime(CAST(${expression} AS TIMESTAMP), ${format})`.as(alias);
|
|
233
|
+
if ('quarter' === dateTrunc) return external_kysely_sql`strftime(CAST(${expression} AS TIMESTAMP), '%Y') || '-Q' || date_part('quarter', CAST(${expression} AS TIMESTAMP))`.as(alias);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return expression.as(alias);
|
|
237
|
+
}
|
|
238
|
+
return item;
|
|
239
|
+
}));
|
|
240
|
+
return qb.selectAll();
|
|
229
241
|
};
|
|
230
242
|
const convertDSLToSQL = (dsl, tableName)=>{
|
|
231
243
|
const db = new Kysely({
|
|
@@ -233,30 +245,13 @@ const convertDSLToSQL = (dsl, tableName)=>{
|
|
|
233
245
|
});
|
|
234
246
|
let qb = db.selectFrom(tableName);
|
|
235
247
|
qb = applySelect(qb, dsl.select);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const field = item.field;
|
|
241
|
-
const alias = item.alias;
|
|
242
|
-
if (alias && field) aliasToFieldMap[alias] = field;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
let resolvedGroupBy = dsl.groupBy;
|
|
246
|
-
if (dsl.groupBy && dsl.groupBy.length > 0) resolvedGroupBy = dsl.groupBy.map((g)=>aliasToFieldMap[g] || g);
|
|
247
|
-
qb = applyGroupBy(qb, resolvedGroupBy);
|
|
248
|
-
if (dsl.having) {
|
|
249
|
-
const resolvedHaving = resolveHavingAliases(dsl.having, aliasToFieldMap);
|
|
250
|
-
qb = qb.having(applyHaving(resolvedHaving));
|
|
251
|
-
}
|
|
252
|
-
if (dsl.orderBy && dsl.orderBy.length > 0) for (const o of dsl.orderBy){
|
|
253
|
-
const fieldStr = o.field;
|
|
254
|
-
const resolvedField = aliasToFieldMap[fieldStr] || fieldStr;
|
|
255
|
-
qb = qb.orderBy(resolvedField, o.order ?? 'asc');
|
|
256
|
-
}
|
|
248
|
+
qb = applyWhere(qb, dsl.where);
|
|
249
|
+
qb = applyGroupBy(qb, dsl.groupBy);
|
|
250
|
+
qb = applyHaving(qb, dsl.having);
|
|
251
|
+
qb = applyOrder(qb, dsl.orderBy);
|
|
257
252
|
qb = applyLimit(qb, dsl.limit);
|
|
258
|
-
const
|
|
259
|
-
return inlineParameters(
|
|
253
|
+
const { sql, parameters } = qb.compile();
|
|
254
|
+
return inlineParameters(sql, parameters);
|
|
260
255
|
};
|
|
261
256
|
const READ_FUNCTION_MAP = {
|
|
262
257
|
csv: 'read_csv_auto',
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
1
2
|
import { Having, HavingClause } from '../../types';
|
|
2
|
-
|
|
3
|
-
export declare const applyHaving: <T>(having: Having<T> | HavingClause<T>) => RawBuilder<boolean>;
|
|
3
|
+
export declare const applyHaving: <DB, TB extends keyof DB & string, O, T>(qb: SelectQueryBuilder<DB, TB, O>, having?: Having<T> | HavingClause<T>) => SelectQueryBuilder<DB, TB, O>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { applyWhere } from './where';
|
|
2
2
|
export { applyGroupBy } from './groupBy';
|
|
3
|
+
export { applyHaving } from './having';
|
|
3
4
|
export { applyLimit } from './limit';
|
|
5
|
+
export { applyOrder } from './order';
|
|
4
6
|
export { applySelect } from './select';
|
|
5
|
-
export { applyHaving } from './having';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
2
|
+
type OrderByItem = {
|
|
3
|
+
field: string;
|
|
4
|
+
order?: 'asc' | 'desc';
|
|
5
|
+
};
|
|
6
|
+
export declare const applyOrder: <DB, TB extends keyof DB & string, O>(qb: SelectQueryBuilder<DB, TB, O>, orderBy?: Array<OrderByItem>) => SelectQueryBuilder<DB, TB, O>;
|
|
7
|
+
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Where, WhereClause } from '../../types';
|
|
2
|
-
import type {
|
|
3
|
-
export declare const applyWhere: <T>(
|
|
2
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
3
|
+
export declare const applyWhere: <DB, TB extends keyof DB & string, O, T>(qb: SelectQueryBuilder<DB, TB, O>, where?: Where<T> | WhereClause<T>) => SelectQueryBuilder<DB, TB, O>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { QueryDSL, VQueryDSL } from '../types';
|
|
1
|
+
import type { QueryDSL, VQueryDSL } from '../types';
|
|
2
2
|
export declare const convertDSLToSQL: <T, TableName extends string>(dsl: QueryDSL<T> | VQueryDSL<T>, tableName: TableName) => string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { GroupBy } from './GroupBy';
|
|
2
|
+
import { Having } from './Having';
|
|
2
3
|
import { OrderBy } from './OrderBy';
|
|
3
4
|
import { Select } from './Select';
|
|
4
5
|
import { Where } from './Where';
|
|
5
|
-
import { Having } from './Having';
|
|
6
6
|
export interface QueryDSL<Table> {
|
|
7
7
|
select: Select<Table>;
|
|
8
8
|
where?: Where<Table>;
|
package/dist/node/cjs/node.cjs
CHANGED
|
@@ -89,7 +89,17 @@ const inlineParameters = (sql, params)=>{
|
|
|
89
89
|
});
|
|
90
90
|
return sql;
|
|
91
91
|
};
|
|
92
|
-
const
|
|
92
|
+
const operatorMap = {
|
|
93
|
+
gt: '>',
|
|
94
|
+
gte: '>=',
|
|
95
|
+
lt: '<',
|
|
96
|
+
lte: '<=',
|
|
97
|
+
eq: '=',
|
|
98
|
+
neq: '!='
|
|
99
|
+
};
|
|
100
|
+
const toSqlOperator = (op)=>operatorMap[op] ?? op;
|
|
101
|
+
const applyWhere = (qb, where)=>{
|
|
102
|
+
if (!where) return qb;
|
|
93
103
|
const toRaw = (w)=>{
|
|
94
104
|
if ('op' in w && 'conditions' in w) {
|
|
95
105
|
const parts = w.conditions.map((c)=>toRaw(c));
|
|
@@ -99,6 +109,7 @@ const applyWhere = (where)=>{
|
|
|
99
109
|
const leaf = w;
|
|
100
110
|
const field = leaf.field;
|
|
101
111
|
const value = leaf.value;
|
|
112
|
+
const sqlOp = toSqlOperator(leaf.op);
|
|
102
113
|
switch(leaf.op){
|
|
103
114
|
case 'is null':
|
|
104
115
|
return (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.ref(field)} is null`;
|
|
@@ -129,10 +140,10 @@ const applyWhere = (where)=>{
|
|
|
129
140
|
return (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.ref(field)} not between ${external_kysely_namespaceObject.sql.val(a)} and ${external_kysely_namespaceObject.sql.val(b)}`;
|
|
130
141
|
}
|
|
131
142
|
default:
|
|
132
|
-
return (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.ref(field)} ${external_kysely_namespaceObject.sql.raw(
|
|
143
|
+
return (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.ref(field)} ${external_kysely_namespaceObject.sql.raw(sqlOp)} ${external_kysely_namespaceObject.sql.val(value)}`;
|
|
133
144
|
}
|
|
134
145
|
};
|
|
135
|
-
return toRaw(where);
|
|
146
|
+
return qb.where(toRaw(where));
|
|
136
147
|
};
|
|
137
148
|
const applyGroupBy = (qb, fields)=>{
|
|
138
149
|
if (fields && fields.length > 0) {
|
|
@@ -141,60 +152,17 @@ const applyGroupBy = (qb, fields)=>{
|
|
|
141
152
|
}
|
|
142
153
|
return qb;
|
|
143
154
|
};
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
day: '%Y-%m-%d',
|
|
152
|
-
week: '%Y-W%W',
|
|
153
|
-
hour: '%Y-%m-%d %H',
|
|
154
|
-
minute: '%Y-%m-%d %H:%M',
|
|
155
|
-
second: '%Y-%m-%d %H:%M:%S'
|
|
155
|
+
const having_operatorMap = {
|
|
156
|
+
gt: '>',
|
|
157
|
+
gte: '>=',
|
|
158
|
+
lt: '<',
|
|
159
|
+
lte: '<=',
|
|
160
|
+
eq: '=',
|
|
161
|
+
neq: '!='
|
|
156
162
|
};
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const field = item.field;
|
|
161
|
-
const expression = eb.ref(field);
|
|
162
|
-
if (item.aggr) {
|
|
163
|
-
const { func } = item.aggr;
|
|
164
|
-
const sqlAlias = field;
|
|
165
|
-
if ([
|
|
166
|
-
'avg',
|
|
167
|
-
'sum',
|
|
168
|
-
'min',
|
|
169
|
-
'max',
|
|
170
|
-
'variance',
|
|
171
|
-
'variancePop',
|
|
172
|
-
'stddev',
|
|
173
|
-
'median'
|
|
174
|
-
].includes(func)) {
|
|
175
|
-
if ('variance' === func) return (0, external_kysely_namespaceObject.sql)`var_samp(${expression})`.as(sqlAlias);
|
|
176
|
-
if ('variancePop' === func) return (0, external_kysely_namespaceObject.sql)`var_pop(${expression})`.as(sqlAlias);
|
|
177
|
-
return (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.raw(func)}(${expression})`.as(sqlAlias);
|
|
178
|
-
}
|
|
179
|
-
if ('count' === func) return (0, external_kysely_namespaceObject.sql)`CAST(count(${expression}) AS INTEGER)`.as(sqlAlias);
|
|
180
|
-
if ('quantile' === func) {
|
|
181
|
-
const q = item.aggr.quantile ?? 0.5;
|
|
182
|
-
return (0, external_kysely_namespaceObject.sql)`quantile(${expression}, ${q})`.as(sqlAlias);
|
|
183
|
-
} else if ('count_distinct' === func) return (0, external_kysely_namespaceObject.sql)`CAST(count(distinct ${expression}) AS INTEGER)`.as(sqlAlias);
|
|
184
|
-
else if (func.startsWith('to_')) {
|
|
185
|
-
const dateTrunc = func.replace('to_', '');
|
|
186
|
-
const format = DATE_FORMAT_MAP[dateTrunc];
|
|
187
|
-
if (format) return (0, external_kysely_namespaceObject.sql)`strftime(CAST(${expression} AS TIMESTAMP), ${format})`.as(sqlAlias);
|
|
188
|
-
if ('quarter' === dateTrunc) return (0, external_kysely_namespaceObject.sql)`strftime(CAST(${expression} AS TIMESTAMP), '%Y') || '-Q' || date_part('quarter', CAST(${expression} AS TIMESTAMP))`.as(sqlAlias);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return expression.as(field);
|
|
192
|
-
}
|
|
193
|
-
return item;
|
|
194
|
-
}));
|
|
195
|
-
return qb.selectAll();
|
|
196
|
-
};
|
|
197
|
-
const applyHaving = (having)=>{
|
|
163
|
+
const having_toSqlOperator = (op)=>having_operatorMap[op] ?? op;
|
|
164
|
+
const applyHaving = (qb, having)=>{
|
|
165
|
+
if (!having) return qb;
|
|
198
166
|
const toRaw = (h)=>{
|
|
199
167
|
if ('op' in h && 'conditions' in h) {
|
|
200
168
|
const parts = h.conditions.map((c)=>toRaw(c));
|
|
@@ -204,7 +172,7 @@ const applyHaving = (having)=>{
|
|
|
204
172
|
const leaf = h;
|
|
205
173
|
const field = leaf.field;
|
|
206
174
|
const value = leaf.value;
|
|
207
|
-
const op = leaf.op;
|
|
175
|
+
const op = having_toSqlOperator(leaf.op);
|
|
208
176
|
if ([
|
|
209
177
|
'sum',
|
|
210
178
|
'avg',
|
|
@@ -215,7 +183,7 @@ const applyHaving = (having)=>{
|
|
|
215
183
|
const aggrExpr = (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.raw(op.toLowerCase())}(${external_kysely_namespaceObject.sql.ref(field)})`;
|
|
216
184
|
return (0, external_kysely_namespaceObject.sql)`${aggrExpr} = ${external_kysely_namespaceObject.sql.val(value)}`;
|
|
217
185
|
}
|
|
218
|
-
switch(op){
|
|
186
|
+
switch(leaf.op){
|
|
219
187
|
case 'is null':
|
|
220
188
|
return (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.ref(field)} is null`;
|
|
221
189
|
case 'is not null':
|
|
@@ -248,22 +216,66 @@ const applyHaving = (having)=>{
|
|
|
248
216
|
return (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.ref(field)} ${external_kysely_namespaceObject.sql.raw(op)} ${external_kysely_namespaceObject.sql.val(value)}`;
|
|
249
217
|
}
|
|
250
218
|
};
|
|
251
|
-
return toRaw(having);
|
|
219
|
+
return qb.having(toRaw(having));
|
|
252
220
|
};
|
|
253
|
-
const
|
|
254
|
-
if (
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
221
|
+
const applyLimit = (qb, limit)=>{
|
|
222
|
+
if (limit && 'number' == typeof limit) qb = qb.limit(limit);
|
|
223
|
+
return qb;
|
|
224
|
+
};
|
|
225
|
+
const applyOrder = (qb, orderBy)=>{
|
|
226
|
+
if (orderBy && orderBy.length > 0) orderBy.forEach((o)=>{
|
|
227
|
+
qb = qb.orderBy(o.field, o.order ?? 'asc');
|
|
228
|
+
});
|
|
229
|
+
return qb;
|
|
230
|
+
};
|
|
231
|
+
const DATE_FORMAT_MAP = {
|
|
232
|
+
year: '%Y',
|
|
233
|
+
month: '%Y-%m',
|
|
234
|
+
day: '%Y-%m-%d',
|
|
235
|
+
week: '%Y-W%W',
|
|
236
|
+
hour: '%Y-%m-%d %H',
|
|
237
|
+
minute: '%Y-%m-%d %H:%M',
|
|
238
|
+
second: '%Y-%m-%d %H:%M:%S'
|
|
239
|
+
};
|
|
240
|
+
const applySelect = (qb, select)=>{
|
|
241
|
+
if (select && select.length > 0) return qb.select((eb)=>select.map((item)=>{
|
|
242
|
+
if (isSelectItem(item)) {
|
|
243
|
+
const field = item.field;
|
|
244
|
+
const expression = eb.ref(field);
|
|
245
|
+
const alias = item.alias ?? field;
|
|
246
|
+
if (item.aggr) {
|
|
247
|
+
const { func } = item.aggr;
|
|
248
|
+
if ([
|
|
249
|
+
'avg',
|
|
250
|
+
'sum',
|
|
251
|
+
'min',
|
|
252
|
+
'max',
|
|
253
|
+
'variance',
|
|
254
|
+
'variancePop',
|
|
255
|
+
'stddev',
|
|
256
|
+
'median'
|
|
257
|
+
].includes(func)) {
|
|
258
|
+
if ('variance' === func) return (0, external_kysely_namespaceObject.sql)`var_samp(${expression})`.as(alias);
|
|
259
|
+
if ('variancePop' === func) return (0, external_kysely_namespaceObject.sql)`var_pop(${expression})`.as(alias);
|
|
260
|
+
return (0, external_kysely_namespaceObject.sql)`${external_kysely_namespaceObject.sql.raw(func)}(${expression})`.as(alias);
|
|
261
|
+
}
|
|
262
|
+
if ('count' === func) return (0, external_kysely_namespaceObject.sql)`CAST(count(${expression}) AS INTEGER)`.as(alias);
|
|
263
|
+
if ('quantile' === func) {
|
|
264
|
+
const q = item.aggr.quantile ?? 0.5;
|
|
265
|
+
return (0, external_kysely_namespaceObject.sql)`quantile(${expression}, ${q})`.as(alias);
|
|
266
|
+
} else if ('count_distinct' === func) return (0, external_kysely_namespaceObject.sql)`CAST(count(distinct ${expression}) AS INTEGER)`.as(alias);
|
|
267
|
+
else if (func.startsWith('to_')) {
|
|
268
|
+
const dateTrunc = func.replace('to_', '');
|
|
269
|
+
const format = DATE_FORMAT_MAP[dateTrunc];
|
|
270
|
+
if (format) return (0, external_kysely_namespaceObject.sql)`strftime(CAST(${expression} AS TIMESTAMP), ${format})`.as(alias);
|
|
271
|
+
if ('quarter' === dateTrunc) return (0, external_kysely_namespaceObject.sql)`strftime(CAST(${expression} AS TIMESTAMP), '%Y') || '-Q' || date_part('quarter', CAST(${expression} AS TIMESTAMP))`.as(alias);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return expression.as(alias);
|
|
275
|
+
}
|
|
276
|
+
return item;
|
|
277
|
+
}));
|
|
278
|
+
return qb.selectAll();
|
|
267
279
|
};
|
|
268
280
|
const convertDSLToSQL = (dsl, tableName)=>{
|
|
269
281
|
const db = new external_kysely_namespaceObject.Kysely({
|
|
@@ -271,30 +283,13 @@ const convertDSLToSQL = (dsl, tableName)=>{
|
|
|
271
283
|
});
|
|
272
284
|
let qb = db.selectFrom(tableName);
|
|
273
285
|
qb = applySelect(qb, dsl.select);
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const field = item.field;
|
|
279
|
-
const alias = item.alias;
|
|
280
|
-
if (alias && field) aliasToFieldMap[alias] = field;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
let resolvedGroupBy = dsl.groupBy;
|
|
284
|
-
if (dsl.groupBy && dsl.groupBy.length > 0) resolvedGroupBy = dsl.groupBy.map((g)=>aliasToFieldMap[g] || g);
|
|
285
|
-
qb = applyGroupBy(qb, resolvedGroupBy);
|
|
286
|
-
if (dsl.having) {
|
|
287
|
-
const resolvedHaving = resolveHavingAliases(dsl.having, aliasToFieldMap);
|
|
288
|
-
qb = qb.having(applyHaving(resolvedHaving));
|
|
289
|
-
}
|
|
290
|
-
if (dsl.orderBy && dsl.orderBy.length > 0) for (const o of dsl.orderBy){
|
|
291
|
-
const fieldStr = o.field;
|
|
292
|
-
const resolvedField = aliasToFieldMap[fieldStr] || fieldStr;
|
|
293
|
-
qb = qb.orderBy(resolvedField, o.order ?? 'asc');
|
|
294
|
-
}
|
|
286
|
+
qb = applyWhere(qb, dsl.where);
|
|
287
|
+
qb = applyGroupBy(qb, dsl.groupBy);
|
|
288
|
+
qb = applyHaving(qb, dsl.having);
|
|
289
|
+
qb = applyOrder(qb, dsl.orderBy);
|
|
295
290
|
qb = applyLimit(qb, dsl.limit);
|
|
296
|
-
const
|
|
297
|
-
return inlineParameters(
|
|
291
|
+
const { sql, parameters } = qb.compile();
|
|
292
|
+
return inlineParameters(sql, parameters);
|
|
298
293
|
};
|
|
299
294
|
const READ_FUNCTION_MAP = {
|
|
300
295
|
csv: 'read_csv_auto',
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
1
2
|
import { Having, HavingClause } from '../../types';
|
|
2
|
-
|
|
3
|
-
export declare const applyHaving: <T>(having: Having<T> | HavingClause<T>) => RawBuilder<boolean>;
|
|
3
|
+
export declare const applyHaving: <DB, TB extends keyof DB & string, O, T>(qb: SelectQueryBuilder<DB, TB, O>, having?: Having<T> | HavingClause<T>) => SelectQueryBuilder<DB, TB, O>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { applyWhere } from './where';
|
|
2
2
|
export { applyGroupBy } from './groupBy';
|
|
3
|
+
export { applyHaving } from './having';
|
|
3
4
|
export { applyLimit } from './limit';
|
|
5
|
+
export { applyOrder } from './order';
|
|
4
6
|
export { applySelect } from './select';
|
|
5
|
-
export { applyHaving } from './having';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
2
|
+
type OrderByItem = {
|
|
3
|
+
field: string;
|
|
4
|
+
order?: 'asc' | 'desc';
|
|
5
|
+
};
|
|
6
|
+
export declare const applyOrder: <DB, TB extends keyof DB & string, O>(qb: SelectQueryBuilder<DB, TB, O>, orderBy?: Array<OrderByItem>) => SelectQueryBuilder<DB, TB, O>;
|
|
7
|
+
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Where, WhereClause } from '../../types';
|
|
2
|
-
import type {
|
|
3
|
-
export declare const applyWhere: <T>(
|
|
2
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
3
|
+
export declare const applyWhere: <DB, TB extends keyof DB & string, O, T>(qb: SelectQueryBuilder<DB, TB, O>, where?: Where<T> | WhereClause<T>) => SelectQueryBuilder<DB, TB, O>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { QueryDSL, VQueryDSL } from '../types';
|
|
1
|
+
import type { QueryDSL, VQueryDSL } from '../types';
|
|
2
2
|
export declare const convertDSLToSQL: <T, TableName extends string>(dsl: QueryDSL<T> | VQueryDSL<T>, tableName: TableName) => string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { GroupBy } from './GroupBy';
|
|
2
|
+
import { Having } from './Having';
|
|
2
3
|
import { OrderBy } from './OrderBy';
|
|
3
4
|
import { Select } from './Select';
|
|
4
5
|
import { Where } from './Where';
|
|
5
|
-
import { Having } from './Having';
|
|
6
6
|
export interface QueryDSL<Table> {
|
|
7
7
|
select: Select<Table>;
|
|
8
8
|
where?: Where<Table>;
|
package/dist/node/esm/node.js
CHANGED
|
@@ -52,7 +52,17 @@ const inlineParameters = (sql, params)=>{
|
|
|
52
52
|
});
|
|
53
53
|
return sql;
|
|
54
54
|
};
|
|
55
|
-
const
|
|
55
|
+
const operatorMap = {
|
|
56
|
+
gt: '>',
|
|
57
|
+
gte: '>=',
|
|
58
|
+
lt: '<',
|
|
59
|
+
lte: '<=',
|
|
60
|
+
eq: '=',
|
|
61
|
+
neq: '!='
|
|
62
|
+
};
|
|
63
|
+
const toSqlOperator = (op)=>operatorMap[op] ?? op;
|
|
64
|
+
const applyWhere = (qb, where)=>{
|
|
65
|
+
if (!where) return qb;
|
|
56
66
|
const toRaw = (w)=>{
|
|
57
67
|
if ('op' in w && 'conditions' in w) {
|
|
58
68
|
const parts = w.conditions.map((c)=>toRaw(c));
|
|
@@ -62,6 +72,7 @@ const applyWhere = (where)=>{
|
|
|
62
72
|
const leaf = w;
|
|
63
73
|
const field = leaf.field;
|
|
64
74
|
const value = leaf.value;
|
|
75
|
+
const sqlOp = toSqlOperator(leaf.op);
|
|
65
76
|
switch(leaf.op){
|
|
66
77
|
case 'is null':
|
|
67
78
|
return external_kysely_sql`${external_kysely_sql.ref(field)} is null`;
|
|
@@ -92,10 +103,10 @@ const applyWhere = (where)=>{
|
|
|
92
103
|
return external_kysely_sql`${external_kysely_sql.ref(field)} not between ${external_kysely_sql.val(a)} and ${external_kysely_sql.val(b)}`;
|
|
93
104
|
}
|
|
94
105
|
default:
|
|
95
|
-
return external_kysely_sql`${external_kysely_sql.ref(field)} ${external_kysely_sql.raw(
|
|
106
|
+
return external_kysely_sql`${external_kysely_sql.ref(field)} ${external_kysely_sql.raw(sqlOp)} ${external_kysely_sql.val(value)}`;
|
|
96
107
|
}
|
|
97
108
|
};
|
|
98
|
-
return toRaw(where);
|
|
109
|
+
return qb.where(toRaw(where));
|
|
99
110
|
};
|
|
100
111
|
const applyGroupBy = (qb, fields)=>{
|
|
101
112
|
if (fields && fields.length > 0) {
|
|
@@ -104,60 +115,17 @@ const applyGroupBy = (qb, fields)=>{
|
|
|
104
115
|
}
|
|
105
116
|
return qb;
|
|
106
117
|
};
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
day: '%Y-%m-%d',
|
|
115
|
-
week: '%Y-W%W',
|
|
116
|
-
hour: '%Y-%m-%d %H',
|
|
117
|
-
minute: '%Y-%m-%d %H:%M',
|
|
118
|
-
second: '%Y-%m-%d %H:%M:%S'
|
|
118
|
+
const having_operatorMap = {
|
|
119
|
+
gt: '>',
|
|
120
|
+
gte: '>=',
|
|
121
|
+
lt: '<',
|
|
122
|
+
lte: '<=',
|
|
123
|
+
eq: '=',
|
|
124
|
+
neq: '!='
|
|
119
125
|
};
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const field = item.field;
|
|
124
|
-
const expression = eb.ref(field);
|
|
125
|
-
if (item.aggr) {
|
|
126
|
-
const { func } = item.aggr;
|
|
127
|
-
const sqlAlias = field;
|
|
128
|
-
if ([
|
|
129
|
-
'avg',
|
|
130
|
-
'sum',
|
|
131
|
-
'min',
|
|
132
|
-
'max',
|
|
133
|
-
'variance',
|
|
134
|
-
'variancePop',
|
|
135
|
-
'stddev',
|
|
136
|
-
'median'
|
|
137
|
-
].includes(func)) {
|
|
138
|
-
if ('variance' === func) return external_kysely_sql`var_samp(${expression})`.as(sqlAlias);
|
|
139
|
-
if ('variancePop' === func) return external_kysely_sql`var_pop(${expression})`.as(sqlAlias);
|
|
140
|
-
return external_kysely_sql`${external_kysely_sql.raw(func)}(${expression})`.as(sqlAlias);
|
|
141
|
-
}
|
|
142
|
-
if ('count' === func) return external_kysely_sql`CAST(count(${expression}) AS INTEGER)`.as(sqlAlias);
|
|
143
|
-
if ('quantile' === func) {
|
|
144
|
-
const q = item.aggr.quantile ?? 0.5;
|
|
145
|
-
return external_kysely_sql`quantile(${expression}, ${q})`.as(sqlAlias);
|
|
146
|
-
} else if ('count_distinct' === func) return external_kysely_sql`CAST(count(distinct ${expression}) AS INTEGER)`.as(sqlAlias);
|
|
147
|
-
else if (func.startsWith('to_')) {
|
|
148
|
-
const dateTrunc = func.replace('to_', '');
|
|
149
|
-
const format = DATE_FORMAT_MAP[dateTrunc];
|
|
150
|
-
if (format) return external_kysely_sql`strftime(CAST(${expression} AS TIMESTAMP), ${format})`.as(sqlAlias);
|
|
151
|
-
if ('quarter' === dateTrunc) return external_kysely_sql`strftime(CAST(${expression} AS TIMESTAMP), '%Y') || '-Q' || date_part('quarter', CAST(${expression} AS TIMESTAMP))`.as(sqlAlias);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return expression.as(field);
|
|
155
|
-
}
|
|
156
|
-
return item;
|
|
157
|
-
}));
|
|
158
|
-
return qb.selectAll();
|
|
159
|
-
};
|
|
160
|
-
const applyHaving = (having)=>{
|
|
126
|
+
const having_toSqlOperator = (op)=>having_operatorMap[op] ?? op;
|
|
127
|
+
const applyHaving = (qb, having)=>{
|
|
128
|
+
if (!having) return qb;
|
|
161
129
|
const toRaw = (h)=>{
|
|
162
130
|
if ('op' in h && 'conditions' in h) {
|
|
163
131
|
const parts = h.conditions.map((c)=>toRaw(c));
|
|
@@ -167,7 +135,7 @@ const applyHaving = (having)=>{
|
|
|
167
135
|
const leaf = h;
|
|
168
136
|
const field = leaf.field;
|
|
169
137
|
const value = leaf.value;
|
|
170
|
-
const op = leaf.op;
|
|
138
|
+
const op = having_toSqlOperator(leaf.op);
|
|
171
139
|
if ([
|
|
172
140
|
'sum',
|
|
173
141
|
'avg',
|
|
@@ -178,7 +146,7 @@ const applyHaving = (having)=>{
|
|
|
178
146
|
const aggrExpr = external_kysely_sql`${external_kysely_sql.raw(op.toLowerCase())}(${external_kysely_sql.ref(field)})`;
|
|
179
147
|
return external_kysely_sql`${aggrExpr} = ${external_kysely_sql.val(value)}`;
|
|
180
148
|
}
|
|
181
|
-
switch(op){
|
|
149
|
+
switch(leaf.op){
|
|
182
150
|
case 'is null':
|
|
183
151
|
return external_kysely_sql`${external_kysely_sql.ref(field)} is null`;
|
|
184
152
|
case 'is not null':
|
|
@@ -211,22 +179,66 @@ const applyHaving = (having)=>{
|
|
|
211
179
|
return external_kysely_sql`${external_kysely_sql.ref(field)} ${external_kysely_sql.raw(op)} ${external_kysely_sql.val(value)}`;
|
|
212
180
|
}
|
|
213
181
|
};
|
|
214
|
-
return toRaw(having);
|
|
182
|
+
return qb.having(toRaw(having));
|
|
215
183
|
};
|
|
216
|
-
const
|
|
217
|
-
if (
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
184
|
+
const applyLimit = (qb, limit)=>{
|
|
185
|
+
if (limit && 'number' == typeof limit) qb = qb.limit(limit);
|
|
186
|
+
return qb;
|
|
187
|
+
};
|
|
188
|
+
const applyOrder = (qb, orderBy)=>{
|
|
189
|
+
if (orderBy && orderBy.length > 0) orderBy.forEach((o)=>{
|
|
190
|
+
qb = qb.orderBy(o.field, o.order ?? 'asc');
|
|
191
|
+
});
|
|
192
|
+
return qb;
|
|
193
|
+
};
|
|
194
|
+
const DATE_FORMAT_MAP = {
|
|
195
|
+
year: '%Y',
|
|
196
|
+
month: '%Y-%m',
|
|
197
|
+
day: '%Y-%m-%d',
|
|
198
|
+
week: '%Y-W%W',
|
|
199
|
+
hour: '%Y-%m-%d %H',
|
|
200
|
+
minute: '%Y-%m-%d %H:%M',
|
|
201
|
+
second: '%Y-%m-%d %H:%M:%S'
|
|
202
|
+
};
|
|
203
|
+
const applySelect = (qb, select)=>{
|
|
204
|
+
if (select && select.length > 0) return qb.select((eb)=>select.map((item)=>{
|
|
205
|
+
if (isSelectItem(item)) {
|
|
206
|
+
const field = item.field;
|
|
207
|
+
const expression = eb.ref(field);
|
|
208
|
+
const alias = item.alias ?? field;
|
|
209
|
+
if (item.aggr) {
|
|
210
|
+
const { func } = item.aggr;
|
|
211
|
+
if ([
|
|
212
|
+
'avg',
|
|
213
|
+
'sum',
|
|
214
|
+
'min',
|
|
215
|
+
'max',
|
|
216
|
+
'variance',
|
|
217
|
+
'variancePop',
|
|
218
|
+
'stddev',
|
|
219
|
+
'median'
|
|
220
|
+
].includes(func)) {
|
|
221
|
+
if ('variance' === func) return external_kysely_sql`var_samp(${expression})`.as(alias);
|
|
222
|
+
if ('variancePop' === func) return external_kysely_sql`var_pop(${expression})`.as(alias);
|
|
223
|
+
return external_kysely_sql`${external_kysely_sql.raw(func)}(${expression})`.as(alias);
|
|
224
|
+
}
|
|
225
|
+
if ('count' === func) return external_kysely_sql`CAST(count(${expression}) AS INTEGER)`.as(alias);
|
|
226
|
+
if ('quantile' === func) {
|
|
227
|
+
const q = item.aggr.quantile ?? 0.5;
|
|
228
|
+
return external_kysely_sql`quantile(${expression}, ${q})`.as(alias);
|
|
229
|
+
} else if ('count_distinct' === func) return external_kysely_sql`CAST(count(distinct ${expression}) AS INTEGER)`.as(alias);
|
|
230
|
+
else if (func.startsWith('to_')) {
|
|
231
|
+
const dateTrunc = func.replace('to_', '');
|
|
232
|
+
const format = DATE_FORMAT_MAP[dateTrunc];
|
|
233
|
+
if (format) return external_kysely_sql`strftime(CAST(${expression} AS TIMESTAMP), ${format})`.as(alias);
|
|
234
|
+
if ('quarter' === dateTrunc) return external_kysely_sql`strftime(CAST(${expression} AS TIMESTAMP), '%Y') || '-Q' || date_part('quarter', CAST(${expression} AS TIMESTAMP))`.as(alias);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return expression.as(alias);
|
|
238
|
+
}
|
|
239
|
+
return item;
|
|
240
|
+
}));
|
|
241
|
+
return qb.selectAll();
|
|
230
242
|
};
|
|
231
243
|
const convertDSLToSQL = (dsl, tableName)=>{
|
|
232
244
|
const db = new Kysely({
|
|
@@ -234,30 +246,13 @@ const convertDSLToSQL = (dsl, tableName)=>{
|
|
|
234
246
|
});
|
|
235
247
|
let qb = db.selectFrom(tableName);
|
|
236
248
|
qb = applySelect(qb, dsl.select);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const field = item.field;
|
|
242
|
-
const alias = item.alias;
|
|
243
|
-
if (alias && field) aliasToFieldMap[alias] = field;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
let resolvedGroupBy = dsl.groupBy;
|
|
247
|
-
if (dsl.groupBy && dsl.groupBy.length > 0) resolvedGroupBy = dsl.groupBy.map((g)=>aliasToFieldMap[g] || g);
|
|
248
|
-
qb = applyGroupBy(qb, resolvedGroupBy);
|
|
249
|
-
if (dsl.having) {
|
|
250
|
-
const resolvedHaving = resolveHavingAliases(dsl.having, aliasToFieldMap);
|
|
251
|
-
qb = qb.having(applyHaving(resolvedHaving));
|
|
252
|
-
}
|
|
253
|
-
if (dsl.orderBy && dsl.orderBy.length > 0) for (const o of dsl.orderBy){
|
|
254
|
-
const fieldStr = o.field;
|
|
255
|
-
const resolvedField = aliasToFieldMap[fieldStr] || fieldStr;
|
|
256
|
-
qb = qb.orderBy(resolvedField, o.order ?? 'asc');
|
|
257
|
-
}
|
|
249
|
+
qb = applyWhere(qb, dsl.where);
|
|
250
|
+
qb = applyGroupBy(qb, dsl.groupBy);
|
|
251
|
+
qb = applyHaving(qb, dsl.having);
|
|
252
|
+
qb = applyOrder(qb, dsl.orderBy);
|
|
258
253
|
qb = applyLimit(qb, dsl.limit);
|
|
259
|
-
const
|
|
260
|
-
return inlineParameters(
|
|
254
|
+
const { sql, parameters } = qb.compile();
|
|
255
|
+
return inlineParameters(sql, parameters);
|
|
261
256
|
};
|
|
262
257
|
const READ_FUNCTION_MAP = {
|
|
263
258
|
csv: 'read_csv_auto',
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
1
2
|
import { Having, HavingClause } from '../../types';
|
|
2
|
-
|
|
3
|
-
export declare const applyHaving: <T>(having: Having<T> | HavingClause<T>) => RawBuilder<boolean>;
|
|
3
|
+
export declare const applyHaving: <DB, TB extends keyof DB & string, O, T>(qb: SelectQueryBuilder<DB, TB, O>, having?: Having<T> | HavingClause<T>) => SelectQueryBuilder<DB, TB, O>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { applyWhere } from './where';
|
|
2
2
|
export { applyGroupBy } from './groupBy';
|
|
3
|
+
export { applyHaving } from './having';
|
|
3
4
|
export { applyLimit } from './limit';
|
|
5
|
+
export { applyOrder } from './order';
|
|
4
6
|
export { applySelect } from './select';
|
|
5
|
-
export { applyHaving } from './having';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
2
|
+
type OrderByItem = {
|
|
3
|
+
field: string;
|
|
4
|
+
order?: 'asc' | 'desc';
|
|
5
|
+
};
|
|
6
|
+
export declare const applyOrder: <DB, TB extends keyof DB & string, O>(qb: SelectQueryBuilder<DB, TB, O>, orderBy?: Array<OrderByItem>) => SelectQueryBuilder<DB, TB, O>;
|
|
7
|
+
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Where, WhereClause } from '../../types';
|
|
2
|
-
import type {
|
|
3
|
-
export declare const applyWhere: <T>(
|
|
2
|
+
import type { SelectQueryBuilder } from 'kysely';
|
|
3
|
+
export declare const applyWhere: <DB, TB extends keyof DB & string, O, T>(qb: SelectQueryBuilder<DB, TB, O>, where?: Where<T> | WhereClause<T>) => SelectQueryBuilder<DB, TB, O>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { QueryDSL, VQueryDSL } from '../types';
|
|
1
|
+
import type { QueryDSL, VQueryDSL } from '../types';
|
|
2
2
|
export declare const convertDSLToSQL: <T, TableName extends string>(dsl: QueryDSL<T> | VQueryDSL<T>, tableName: TableName) => string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { GroupBy } from './GroupBy';
|
|
2
|
+
import { Having } from './Having';
|
|
2
3
|
import { OrderBy } from './OrderBy';
|
|
3
4
|
import { Select } from './Select';
|
|
4
5
|
import { Where } from './Where';
|
|
5
|
-
import { Having } from './Having';
|
|
6
6
|
export interface QueryDSL<Table> {
|
|
7
7
|
select: Select<Table>;
|
|
8
8
|
where?: Where<Table>;
|