drizzle-cube 0.1.9 → 0.1.11
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/adapters/hono/index.js +39 -31
- package/dist/client/charts/chartConfigRegistry.d.ts +5 -0
- package/dist/client/charts/chartConfigs.d.ts +60 -0
- package/dist/client/components/AxisDropZone.d.ts +20 -0
- package/dist/client/components/ChartConfigPanel.d.ts +15 -0
- package/dist/client/components/ChartTypeSelector.d.ts +8 -0
- package/dist/client/components/DebugModal.d.ts +9 -0
- package/dist/client/components/Modal.d.ts +1 -1
- package/dist/client/components/charts/AreaChart.config.d.ts +5 -0
- package/dist/client/components/charts/BarChart.config.d.ts +5 -0
- package/dist/client/components/charts/BubbleChart.config.d.ts +5 -0
- package/dist/client/components/charts/BubbleChart.d.ts +2 -0
- package/dist/client/components/charts/DataTable.config.d.ts +5 -0
- package/dist/client/components/charts/DataTable.d.ts +1 -1
- package/dist/client/components/charts/LineChart.config.d.ts +5 -0
- package/dist/client/components/charts/PieChart.config.d.ts +5 -0
- package/dist/client/components/charts/RadarChart.config.d.ts +5 -0
- package/dist/client/components/charts/RadialBarChart.config.d.ts +5 -0
- package/dist/client/components/charts/ScatterChart.config.d.ts +5 -0
- package/dist/client/components/charts/TreeMapChart.config.d.ts +5 -0
- package/dist/client/components/charts/index.d.ts +1 -0
- package/dist/client/hooks/useCubeMeta.d.ts +29 -0
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.js +13735 -10142
- package/dist/client/providers/CubeProvider.d.ts +7 -0
- package/dist/client/styles.css +1 -1
- package/dist/client/types.d.ts +14 -2
- package/dist/client/utils/chartConstants.d.ts +1 -0
- package/dist/client/utils/chartUtils.d.ts +6 -2
- package/dist/server/index.d.ts +96 -8
- package/dist/server/index.js +894 -632
- package/package.json +10 -3
- package/dist/client/components/ChartConfigEditor.d.ts +0 -8
package/dist/server/index.js
CHANGED
|
@@ -1,20 +1,273 @@
|
|
|
1
|
-
var
|
|
2
|
-
var B = (o, e, t) => e in o ?
|
|
3
|
-
var
|
|
4
|
-
import { sql as
|
|
5
|
-
import { parse as
|
|
6
|
-
|
|
1
|
+
var W = Object.defineProperty;
|
|
2
|
+
var B = (o, e, t) => e in o ? W(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
|
|
3
|
+
var C = (o, e, t) => B(o, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { sql as m, and as h, or as j, gt as N, lt as $, gte as w, lte as D, isNull as _, isNotNull as z, eq as v, count as y, max as Y, min as R, avg as K, sum as J, countDistinct as H, notInArray as V, ne as G, inArray as P } from "drizzle-orm";
|
|
5
|
+
import { parse as Z, stringify as X } from "yaml";
|
|
6
|
+
class O {
|
|
7
|
+
/**
|
|
8
|
+
* Helper method to build pattern for string matching
|
|
9
|
+
* Can be overridden by specific adapters if needed
|
|
10
|
+
*/
|
|
11
|
+
buildPattern(e, t) {
|
|
12
|
+
switch (e) {
|
|
13
|
+
case "contains":
|
|
14
|
+
case "notContains":
|
|
15
|
+
return `%${t}%`;
|
|
16
|
+
case "startsWith":
|
|
17
|
+
return `${t}%`;
|
|
18
|
+
case "endsWith":
|
|
19
|
+
return `%${t}`;
|
|
20
|
+
default:
|
|
21
|
+
return t;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
class q extends O {
|
|
26
|
+
getEngineType() {
|
|
27
|
+
return "postgres";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build PostgreSQL time dimension using DATE_TRUNC function
|
|
31
|
+
* Extracted from executor.ts:649-670 and multi-cube-builder.ts:306-320
|
|
32
|
+
*/
|
|
33
|
+
buildTimeDimension(e, t) {
|
|
34
|
+
switch (e) {
|
|
35
|
+
case "year":
|
|
36
|
+
return m`DATE_TRUNC('year', ${t}::timestamp)`;
|
|
37
|
+
case "quarter":
|
|
38
|
+
return m`DATE_TRUNC('quarter', ${t}::timestamp)`;
|
|
39
|
+
case "month":
|
|
40
|
+
return m`DATE_TRUNC('month', ${t}::timestamp)`;
|
|
41
|
+
case "week":
|
|
42
|
+
return m`DATE_TRUNC('week', ${t}::timestamp)`;
|
|
43
|
+
case "day":
|
|
44
|
+
return m`DATE_TRUNC('day', ${t}::timestamp)::timestamp`;
|
|
45
|
+
case "hour":
|
|
46
|
+
return m`DATE_TRUNC('hour', ${t}::timestamp)`;
|
|
47
|
+
case "minute":
|
|
48
|
+
return m`DATE_TRUNC('minute', ${t}::timestamp)`;
|
|
49
|
+
case "second":
|
|
50
|
+
return m`DATE_TRUNC('second', ${t}::timestamp)`;
|
|
51
|
+
default:
|
|
52
|
+
return t;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build PostgreSQL string matching conditions using ILIKE (case-insensitive)
|
|
57
|
+
* Extracted from executor.ts:807-813 and multi-cube-builder.ts:468-474
|
|
58
|
+
*/
|
|
59
|
+
buildStringCondition(e, t, s) {
|
|
60
|
+
const n = this.buildPattern(t, s);
|
|
61
|
+
switch (t) {
|
|
62
|
+
case "contains":
|
|
63
|
+
return m`${e} ILIKE ${n}`;
|
|
64
|
+
case "notContains":
|
|
65
|
+
return m`${e} NOT ILIKE ${n}`;
|
|
66
|
+
case "startsWith":
|
|
67
|
+
return m`${e} ILIKE ${n}`;
|
|
68
|
+
case "endsWith":
|
|
69
|
+
return m`${e} ILIKE ${n}`;
|
|
70
|
+
default:
|
|
71
|
+
throw new Error(`Unsupported string operator: ${t}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build PostgreSQL type casting using :: syntax
|
|
76
|
+
* Extracted from various locations where ::timestamp was used
|
|
77
|
+
*/
|
|
78
|
+
castToType(e, t) {
|
|
79
|
+
switch (t) {
|
|
80
|
+
case "timestamp":
|
|
81
|
+
return m`${e}::timestamp`;
|
|
82
|
+
case "decimal":
|
|
83
|
+
return m`${e}::decimal`;
|
|
84
|
+
case "integer":
|
|
85
|
+
return m`${e}::integer`;
|
|
86
|
+
default:
|
|
87
|
+
throw new Error(`Unsupported cast type: ${t}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Build PostgreSQL COUNT aggregation
|
|
92
|
+
* Extracted from multi-cube-builder.ts:278
|
|
93
|
+
*/
|
|
94
|
+
buildCount(e) {
|
|
95
|
+
return m`COUNT(${e})`;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Build PostgreSQL COUNT DISTINCT aggregation
|
|
99
|
+
* Extracted from multi-cube-builder.ts:280
|
|
100
|
+
*/
|
|
101
|
+
buildCountDistinct(e) {
|
|
102
|
+
return m`COUNT(DISTINCT ${e})`;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Build PostgreSQL SUM aggregation
|
|
106
|
+
* Extracted from multi-cube-builder.ts:282
|
|
107
|
+
*/
|
|
108
|
+
buildSum(e) {
|
|
109
|
+
return m`SUM(${e})`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Build PostgreSQL AVG aggregation with COALESCE for NULL handling
|
|
113
|
+
* PostgreSQL AVG returns NULL for empty sets, so we use COALESCE for consistent behavior
|
|
114
|
+
* Extracted from multi-cube-builder.ts:284
|
|
115
|
+
*/
|
|
116
|
+
buildAvg(e) {
|
|
117
|
+
return m`COALESCE(AVG(${e}), 0)`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Build PostgreSQL MIN aggregation
|
|
121
|
+
* Extracted from multi-cube-builder.ts:286
|
|
122
|
+
*/
|
|
123
|
+
buildMin(e) {
|
|
124
|
+
return m`MIN(${e})`;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Build PostgreSQL MAX aggregation
|
|
128
|
+
* Extracted from multi-cube-builder.ts:288
|
|
129
|
+
*/
|
|
130
|
+
buildMax(e) {
|
|
131
|
+
return m`MAX(${e})`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
class ee extends O {
|
|
135
|
+
getEngineType() {
|
|
136
|
+
return "mysql";
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Build MySQL time dimension using DATE_FORMAT function
|
|
140
|
+
* MySQL equivalent to PostgreSQL's DATE_TRUNC
|
|
141
|
+
*/
|
|
142
|
+
buildTimeDimension(e, t) {
|
|
143
|
+
const s = {
|
|
144
|
+
year: "%Y-01-01 00:00:00",
|
|
145
|
+
quarter: "%Y-%q-01 00:00:00",
|
|
146
|
+
// %q gives quarter (1,2,3,4), but we need to map this properly
|
|
147
|
+
month: "%Y-%m-01 00:00:00",
|
|
148
|
+
week: "%Y-%u-01 00:00:00",
|
|
149
|
+
// %u gives week of year
|
|
150
|
+
day: "%Y-%m-%d 00:00:00",
|
|
151
|
+
hour: "%Y-%m-%d %H:00:00",
|
|
152
|
+
minute: "%Y-%m-%d %H:%i:00",
|
|
153
|
+
second: "%Y-%m-%d %H:%i:%s"
|
|
154
|
+
};
|
|
155
|
+
switch (e) {
|
|
156
|
+
case "quarter":
|
|
157
|
+
return m`DATE_ADD(MAKEDATE(YEAR(${t}), 1), INTERVAL (QUARTER(${t}) - 1) * 3 MONTH)`;
|
|
158
|
+
case "week":
|
|
159
|
+
return m`DATE_SUB(${t}, INTERVAL WEEKDAY(${t}) DAY)`;
|
|
160
|
+
default:
|
|
161
|
+
const n = s[e];
|
|
162
|
+
return n ? m`STR_TO_DATE(DATE_FORMAT(${t}, ${n}), '%Y-%m-%d %H:%i:%s')` : t;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Build MySQL string matching conditions using LIKE
|
|
167
|
+
* MySQL LIKE is case-insensitive by default (depending on collation)
|
|
168
|
+
* For guaranteed case-insensitive matching, we use LOWER() functions
|
|
169
|
+
*/
|
|
170
|
+
buildStringCondition(e, t, s) {
|
|
171
|
+
const n = this.buildPattern(t, s.toLowerCase());
|
|
172
|
+
switch (t) {
|
|
173
|
+
case "contains":
|
|
174
|
+
return m`LOWER(${e}) LIKE ${n}`;
|
|
175
|
+
case "notContains":
|
|
176
|
+
return m`LOWER(${e}) NOT LIKE ${n}`;
|
|
177
|
+
case "startsWith":
|
|
178
|
+
return m`LOWER(${e}) LIKE ${n}`;
|
|
179
|
+
case "endsWith":
|
|
180
|
+
return m`LOWER(${e}) LIKE ${n}`;
|
|
181
|
+
default:
|
|
182
|
+
throw new Error(`Unsupported string operator: ${t}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Build MySQL type casting using CAST() function
|
|
187
|
+
* MySQL equivalent to PostgreSQL's :: casting syntax
|
|
188
|
+
*/
|
|
189
|
+
castToType(e, t) {
|
|
190
|
+
switch (t) {
|
|
191
|
+
case "timestamp":
|
|
192
|
+
return m`CAST(${e} AS DATETIME)`;
|
|
193
|
+
case "decimal":
|
|
194
|
+
return m`CAST(${e} AS DECIMAL(10,2))`;
|
|
195
|
+
case "integer":
|
|
196
|
+
return m`CAST(${e} AS SIGNED INTEGER)`;
|
|
197
|
+
default:
|
|
198
|
+
throw new Error(`Unsupported cast type: ${t}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Build MySQL COUNT aggregation
|
|
203
|
+
* Standard SQL COUNT function
|
|
204
|
+
*/
|
|
205
|
+
buildCount(e) {
|
|
206
|
+
return m`COUNT(${e})`;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Build MySQL COUNT DISTINCT aggregation
|
|
210
|
+
* Standard SQL COUNT DISTINCT function
|
|
211
|
+
*/
|
|
212
|
+
buildCountDistinct(e) {
|
|
213
|
+
return m`COUNT(DISTINCT ${e})`;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Build MySQL SUM aggregation
|
|
217
|
+
* Standard SQL SUM function
|
|
218
|
+
*/
|
|
219
|
+
buildSum(e) {
|
|
220
|
+
return m`SUM(${e})`;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Build MySQL AVG aggregation with IFNULL for NULL handling
|
|
224
|
+
* MySQL AVG returns NULL for empty sets, using IFNULL for consistency
|
|
225
|
+
*/
|
|
226
|
+
buildAvg(e) {
|
|
227
|
+
return m`IFNULL(AVG(${e}), 0)`;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Build MySQL MIN aggregation
|
|
231
|
+
* Standard SQL MIN function
|
|
232
|
+
*/
|
|
233
|
+
buildMin(e) {
|
|
234
|
+
return m`MIN(${e})`;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Build MySQL MAX aggregation
|
|
238
|
+
* Standard SQL MAX function
|
|
239
|
+
*/
|
|
240
|
+
buildMax(e) {
|
|
241
|
+
return m`MAX(${e})`;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function te(o) {
|
|
245
|
+
switch (o) {
|
|
246
|
+
case "postgres":
|
|
247
|
+
return new q();
|
|
248
|
+
case "mysql":
|
|
249
|
+
return new ee();
|
|
250
|
+
case "sqlite":
|
|
251
|
+
throw new Error("SQLite adapter not yet implemented");
|
|
252
|
+
default:
|
|
253
|
+
throw new Error(`Unsupported database engine: ${o}`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function $e(o, e) {
|
|
7
257
|
return {
|
|
8
258
|
...e,
|
|
9
259
|
name: e.name
|
|
10
260
|
};
|
|
11
261
|
}
|
|
12
|
-
class
|
|
13
|
-
constructor(e, t) {
|
|
262
|
+
class S {
|
|
263
|
+
constructor(e, t, s) {
|
|
264
|
+
C(this, "databaseAdapter");
|
|
14
265
|
this.db = e, this.schema = t;
|
|
266
|
+
const n = s || this.getEngineType();
|
|
267
|
+
this.databaseAdapter = te(n);
|
|
15
268
|
}
|
|
16
269
|
}
|
|
17
|
-
class
|
|
270
|
+
class ne extends S {
|
|
18
271
|
async execute(e, t) {
|
|
19
272
|
if (e && typeof e == "object") {
|
|
20
273
|
if (typeof e.execute == "function") {
|
|
@@ -28,31 +281,31 @@ class X extends A {
|
|
|
28
281
|
} catch (n) {
|
|
29
282
|
if (typeof e.getSQL == "function") {
|
|
30
283
|
const r = e.getSQL(), a = await this.db.execute(r);
|
|
31
|
-
return Array.isArray(a) ? a.map((
|
|
284
|
+
return Array.isArray(a) ? a.map((i) => this.convertNumericFields(i, t)) : a;
|
|
32
285
|
}
|
|
33
286
|
throw n;
|
|
34
287
|
}
|
|
35
288
|
}
|
|
36
289
|
if (!this.db.execute)
|
|
37
290
|
throw new Error("PostgreSQL database instance must have an execute method");
|
|
38
|
-
const
|
|
39
|
-
return Array.isArray(
|
|
291
|
+
const s = await this.db.execute(e);
|
|
292
|
+
return Array.isArray(s) ? s.map((n) => this.convertNumericFields(n, t)) : s;
|
|
40
293
|
}
|
|
41
294
|
/**
|
|
42
295
|
* Convert numeric string fields to numbers (only for measure fields)
|
|
43
296
|
*/
|
|
44
297
|
convertNumericFields(e, t) {
|
|
45
298
|
if (!e || typeof e != "object") return e;
|
|
46
|
-
const
|
|
299
|
+
const s = {};
|
|
47
300
|
for (const [n, r] of Object.entries(e))
|
|
48
|
-
t && t.includes(n) ?
|
|
49
|
-
return
|
|
301
|
+
t && t.includes(n) ? s[n] = this.coerceToNumber(r) : s[n] = r;
|
|
302
|
+
return s;
|
|
50
303
|
}
|
|
51
304
|
/**
|
|
52
305
|
* Coerce a value to a number if it represents a numeric type
|
|
53
306
|
*/
|
|
54
307
|
coerceToNumber(e) {
|
|
55
|
-
var t,
|
|
308
|
+
var t, s;
|
|
56
309
|
if (e == null || typeof e == "number") return e;
|
|
57
310
|
if (typeof e == "bigint") return Number(e);
|
|
58
311
|
if (e && typeof e == "object") {
|
|
@@ -61,7 +314,7 @@ class X extends A {
|
|
|
61
314
|
if (/^-?\d+(\.\d+)?$/.test(n))
|
|
62
315
|
return n.includes(".") ? parseFloat(n) : parseInt(n, 10);
|
|
63
316
|
}
|
|
64
|
-
if (((t = e.constructor) == null ? void 0 : t.name) === "Numeric" || ((
|
|
317
|
+
if (((t = e.constructor) == null ? void 0 : t.name) === "Numeric" || ((s = e.constructor) == null ? void 0 : s.name) === "Decimal" || "digits" in e || "sign" in e) {
|
|
65
318
|
const n = e.toString();
|
|
66
319
|
return parseFloat(n);
|
|
67
320
|
}
|
|
@@ -79,23 +332,23 @@ class X extends A {
|
|
|
79
332
|
return "postgres";
|
|
80
333
|
}
|
|
81
334
|
}
|
|
82
|
-
class
|
|
335
|
+
class se extends S {
|
|
83
336
|
async execute(e, t) {
|
|
84
337
|
if (e && typeof e == "object" && typeof e.execute == "function") {
|
|
85
|
-
const
|
|
86
|
-
return Array.isArray(
|
|
338
|
+
const s = await e.execute();
|
|
339
|
+
return Array.isArray(s) ? s.map((n) => this.convertNumericFields(n, t)) : s;
|
|
87
340
|
}
|
|
88
341
|
try {
|
|
89
342
|
if (this.db.all) {
|
|
90
|
-
const
|
|
91
|
-
return Array.isArray(
|
|
343
|
+
const s = this.db.all(e);
|
|
344
|
+
return Array.isArray(s) ? s.map((n) => this.convertNumericFields(n, t)) : s;
|
|
92
345
|
} else {
|
|
93
346
|
if (this.db.run)
|
|
94
347
|
return this.db.run(e);
|
|
95
348
|
throw new Error("SQLite database instance must have an all() or run() method");
|
|
96
349
|
}
|
|
97
|
-
} catch (
|
|
98
|
-
throw new Error(`SQLite execution failed: ${
|
|
350
|
+
} catch (s) {
|
|
351
|
+
throw new Error(`SQLite execution failed: ${s instanceof Error ? s.message : "Unknown error"}`);
|
|
99
352
|
}
|
|
100
353
|
}
|
|
101
354
|
/**
|
|
@@ -103,10 +356,10 @@ class q extends A {
|
|
|
103
356
|
*/
|
|
104
357
|
convertNumericFields(e, t) {
|
|
105
358
|
if (!e || typeof e != "object") return e;
|
|
106
|
-
const
|
|
359
|
+
const s = {};
|
|
107
360
|
for (const [n, r] of Object.entries(e))
|
|
108
|
-
t && t.includes(n) ?
|
|
109
|
-
return
|
|
361
|
+
t && t.includes(n) ? s[n] = this.coerceToNumber(r) : s[n] = r;
|
|
362
|
+
return s;
|
|
110
363
|
}
|
|
111
364
|
/**
|
|
112
365
|
* Coerce a value to a number if it represents a numeric type
|
|
@@ -125,7 +378,7 @@ class q extends A {
|
|
|
125
378
|
return "sqlite";
|
|
126
379
|
}
|
|
127
380
|
}
|
|
128
|
-
class
|
|
381
|
+
class ie extends S {
|
|
129
382
|
async execute(e, t) {
|
|
130
383
|
if (e && typeof e == "object" && typeof e.execute == "function") {
|
|
131
384
|
const n = await e.execute();
|
|
@@ -133,18 +386,18 @@ class ee extends A {
|
|
|
133
386
|
}
|
|
134
387
|
if (!this.db.execute)
|
|
135
388
|
throw new Error("MySQL database instance must have an execute method");
|
|
136
|
-
const
|
|
137
|
-
return Array.isArray(
|
|
389
|
+
const s = await this.db.execute(e);
|
|
390
|
+
return Array.isArray(s) ? s.map((n) => this.convertNumericFields(n, t)) : s;
|
|
138
391
|
}
|
|
139
392
|
/**
|
|
140
|
-
* Convert numeric string fields to numbers (
|
|
393
|
+
* Convert numeric string fields to numbers (measure fields + numeric dimensions)
|
|
141
394
|
*/
|
|
142
395
|
convertNumericFields(e, t) {
|
|
143
396
|
if (!e || typeof e != "object") return e;
|
|
144
|
-
const
|
|
397
|
+
const s = {};
|
|
145
398
|
for (const [n, r] of Object.entries(e))
|
|
146
|
-
t && t.includes(n) ?
|
|
147
|
-
return
|
|
399
|
+
t && t.includes(n) ? s[n] = this.coerceToNumber(r) : s[n] = r;
|
|
400
|
+
return s;
|
|
148
401
|
}
|
|
149
402
|
/**
|
|
150
403
|
* Coerce a value to a number if it represents a numeric type
|
|
@@ -163,32 +416,32 @@ class ee extends A {
|
|
|
163
416
|
return "mysql";
|
|
164
417
|
}
|
|
165
418
|
}
|
|
166
|
-
function
|
|
167
|
-
return new
|
|
419
|
+
function F(o, e) {
|
|
420
|
+
return new ne(o, e, "postgres");
|
|
168
421
|
}
|
|
169
422
|
function M(o, e) {
|
|
170
|
-
return new
|
|
423
|
+
return new se(o, e, "sqlite");
|
|
171
424
|
}
|
|
172
|
-
function
|
|
173
|
-
return new
|
|
425
|
+
function re(o, e) {
|
|
426
|
+
return new ie(o, e, "mysql");
|
|
174
427
|
}
|
|
175
|
-
function
|
|
428
|
+
function L(o, e, t) {
|
|
176
429
|
if (t)
|
|
177
430
|
switch (t) {
|
|
178
431
|
case "postgres":
|
|
179
|
-
return
|
|
432
|
+
return F(o, e);
|
|
180
433
|
case "mysql":
|
|
181
|
-
return
|
|
434
|
+
return re(o, e);
|
|
182
435
|
case "sqlite":
|
|
183
436
|
return M(o, e);
|
|
184
437
|
}
|
|
185
438
|
if (o.all && o.run)
|
|
186
439
|
return M(o, e);
|
|
187
440
|
if (o.execute)
|
|
188
|
-
return
|
|
441
|
+
return F(o, e);
|
|
189
442
|
throw new Error("Unable to determine database engine type. Please specify engineType parameter.");
|
|
190
443
|
}
|
|
191
|
-
function
|
|
444
|
+
function Ee(o, e) {
|
|
192
445
|
return {
|
|
193
446
|
name: o,
|
|
194
447
|
...e
|
|
@@ -197,32 +450,41 @@ function De(o, e) {
|
|
|
197
450
|
function b(o, e) {
|
|
198
451
|
return typeof o == "function" ? o(e) : o;
|
|
199
452
|
}
|
|
200
|
-
function
|
|
453
|
+
function oe(o, e, t) {
|
|
201
454
|
return {
|
|
202
455
|
...o,
|
|
203
456
|
cubes: e,
|
|
204
457
|
currentCube: t
|
|
205
458
|
};
|
|
206
459
|
}
|
|
207
|
-
class
|
|
460
|
+
class ae {
|
|
461
|
+
constructor(e) {
|
|
462
|
+
this.databaseAdapter = e;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Set the database adapter (for use when not provided in constructor)
|
|
466
|
+
*/
|
|
467
|
+
setDatabaseAdapter(e) {
|
|
468
|
+
this.databaseAdapter = e;
|
|
469
|
+
}
|
|
208
470
|
/**
|
|
209
471
|
* Analyze a semantic query to determine which cubes are involved
|
|
210
472
|
*/
|
|
211
473
|
analyzeCubeUsage(e) {
|
|
212
474
|
const t = /* @__PURE__ */ new Set();
|
|
213
475
|
if (e.measures)
|
|
214
|
-
for (const
|
|
215
|
-
const [n] =
|
|
476
|
+
for (const s of e.measures) {
|
|
477
|
+
const [n] = s.split(".");
|
|
216
478
|
t.add(n);
|
|
217
479
|
}
|
|
218
480
|
if (e.dimensions)
|
|
219
|
-
for (const
|
|
220
|
-
const [n] =
|
|
481
|
+
for (const s of e.dimensions) {
|
|
482
|
+
const [n] = s.split(".");
|
|
221
483
|
t.add(n);
|
|
222
484
|
}
|
|
223
485
|
if (e.timeDimensions)
|
|
224
|
-
for (const
|
|
225
|
-
const [n] =
|
|
486
|
+
for (const s of e.timeDimensions) {
|
|
487
|
+
const [n] = s.dimension.split(".");
|
|
226
488
|
t.add(n);
|
|
227
489
|
}
|
|
228
490
|
return t;
|
|
@@ -230,20 +492,20 @@ class ie {
|
|
|
230
492
|
/**
|
|
231
493
|
* Build a multi-cube query plan
|
|
232
494
|
*/
|
|
233
|
-
buildMultiCubeQueryPlan(e, t,
|
|
495
|
+
buildMultiCubeQueryPlan(e, t, s) {
|
|
234
496
|
const n = this.analyzeCubeUsage(t), r = Array.from(n);
|
|
235
497
|
if (r.length === 1)
|
|
236
498
|
throw new Error("Single cube query should use QueryExecutor directly");
|
|
237
|
-
const a = this.choosePrimaryCube(r, t),
|
|
238
|
-
if (!
|
|
499
|
+
const a = this.choosePrimaryCube(r, t), i = e.get(a);
|
|
500
|
+
if (!i)
|
|
239
501
|
throw new Error(`Primary cube '${a}' not found`);
|
|
240
|
-
const c = this.buildJoinPlan(e,
|
|
502
|
+
const c = this.buildJoinPlan(e, i, r, s), u = this.buildMultiCubeSelections(e, t, s.securityContext), l = this.buildMultiCubeWhereConditions(e, t, s), d = this.buildMultiCubeGroupByFields(e, t, s.securityContext);
|
|
241
503
|
return {
|
|
242
|
-
primaryCube:
|
|
504
|
+
primaryCube: i,
|
|
243
505
|
joinCubes: c,
|
|
244
|
-
selections:
|
|
245
|
-
whereConditions:
|
|
246
|
-
groupByFields:
|
|
506
|
+
selections: u,
|
|
507
|
+
whereConditions: l,
|
|
508
|
+
groupByFields: d
|
|
247
509
|
};
|
|
248
510
|
}
|
|
249
511
|
/**
|
|
@@ -251,44 +513,38 @@ class ie {
|
|
|
251
513
|
*/
|
|
252
514
|
choosePrimaryCube(e, t) {
|
|
253
515
|
if (t.measures && t.measures.length > 0) {
|
|
254
|
-
const [
|
|
255
|
-
return
|
|
516
|
+
const [s] = t.measures[0].split(".");
|
|
517
|
+
return s;
|
|
256
518
|
}
|
|
257
519
|
if (t.dimensions && t.dimensions.length > 0) {
|
|
258
|
-
const [
|
|
259
|
-
return
|
|
520
|
+
const [s] = t.dimensions[0].split(".");
|
|
521
|
+
return s;
|
|
260
522
|
}
|
|
261
523
|
return e[0];
|
|
262
524
|
}
|
|
263
525
|
/**
|
|
264
526
|
* Build join plan for multi-cube query
|
|
265
527
|
*/
|
|
266
|
-
buildJoinPlan(e, t,
|
|
267
|
-
var
|
|
268
|
-
const r = [], a =
|
|
528
|
+
buildJoinPlan(e, t, s, n) {
|
|
529
|
+
var i;
|
|
530
|
+
const r = [], a = s.filter((c) => c !== t.name);
|
|
269
531
|
for (const c of a) {
|
|
270
|
-
const
|
|
271
|
-
if (!l)
|
|
272
|
-
throw new Error(`Cube '${c}' not found`);
|
|
273
|
-
const u = (s = t.joins) == null ? void 0 : s[c];
|
|
532
|
+
const u = e.get(c);
|
|
274
533
|
if (!u)
|
|
534
|
+
throw new Error(`Cube '${c}' not found`);
|
|
535
|
+
const l = (i = t.joins) == null ? void 0 : i[c];
|
|
536
|
+
if (!l)
|
|
275
537
|
throw new Error(`No join definition found from '${t.name}' to '${c}'`);
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
db: {},
|
|
279
|
-
// Will be filled in during execution
|
|
280
|
-
schema: {},
|
|
281
|
-
// Will be filled in during execution
|
|
282
|
-
securityContext: n
|
|
283
|
-
},
|
|
538
|
+
const d = oe(
|
|
539
|
+
n,
|
|
284
540
|
e,
|
|
285
|
-
|
|
286
|
-
),
|
|
541
|
+
u
|
|
542
|
+
), f = l.condition(d);
|
|
287
543
|
r.push({
|
|
288
|
-
cube:
|
|
544
|
+
cube: u,
|
|
289
545
|
alias: `${c.toLowerCase()}_cube`,
|
|
290
|
-
joinType:
|
|
291
|
-
joinCondition:
|
|
546
|
+
joinType: l.type || "left",
|
|
547
|
+
joinCondition: f
|
|
292
548
|
});
|
|
293
549
|
}
|
|
294
550
|
return r;
|
|
@@ -296,40 +552,40 @@ class ie {
|
|
|
296
552
|
/**
|
|
297
553
|
* Build selections across multiple cubes
|
|
298
554
|
*/
|
|
299
|
-
buildMultiCubeSelections(e, t,
|
|
555
|
+
buildMultiCubeSelections(e, t, s) {
|
|
300
556
|
const n = {}, r = {
|
|
301
557
|
db: {},
|
|
302
558
|
// Filled during execution
|
|
303
559
|
schema: {},
|
|
304
560
|
// Filled during execution
|
|
305
|
-
securityContext:
|
|
561
|
+
securityContext: s
|
|
306
562
|
};
|
|
307
563
|
if (t.dimensions)
|
|
308
564
|
for (const a of t.dimensions) {
|
|
309
|
-
const [
|
|
310
|
-
if (
|
|
311
|
-
const
|
|
312
|
-
n[a] =
|
|
565
|
+
const [i, c] = a.split("."), u = e.get(i);
|
|
566
|
+
if (u && u.dimensions[c]) {
|
|
567
|
+
const l = u.dimensions[c], d = b(l.sql, r);
|
|
568
|
+
n[a] = m`${d}`.as(a);
|
|
313
569
|
}
|
|
314
570
|
}
|
|
315
571
|
if (t.measures)
|
|
316
572
|
for (const a of t.measures) {
|
|
317
|
-
const [
|
|
318
|
-
if (
|
|
319
|
-
const
|
|
320
|
-
n[a] =
|
|
573
|
+
const [i, c] = a.split("."), u = e.get(i);
|
|
574
|
+
if (u && u.measures[c]) {
|
|
575
|
+
const l = u.measures[c], d = this.buildMeasureExpression(l, r);
|
|
576
|
+
n[a] = m`${d}`.as(a);
|
|
321
577
|
}
|
|
322
578
|
}
|
|
323
579
|
if (t.timeDimensions)
|
|
324
580
|
for (const a of t.timeDimensions) {
|
|
325
|
-
const [
|
|
326
|
-
if (
|
|
327
|
-
const
|
|
328
|
-
|
|
581
|
+
const [i, c] = a.dimension.split("."), u = e.get(i);
|
|
582
|
+
if (u && u.dimensions[c]) {
|
|
583
|
+
const l = u.dimensions[c], d = this.buildTimeDimensionExpression(
|
|
584
|
+
l.sql,
|
|
329
585
|
a.granularity,
|
|
330
586
|
r
|
|
331
587
|
);
|
|
332
|
-
n[a.dimension] =
|
|
588
|
+
n[a.dimension] = m`${d}`.as(a.dimension);
|
|
333
589
|
}
|
|
334
590
|
}
|
|
335
591
|
return n;
|
|
@@ -338,75 +594,60 @@ class ie {
|
|
|
338
594
|
* Build measure expression with aggregation (similar to single-cube approach)
|
|
339
595
|
*/
|
|
340
596
|
buildMeasureExpression(e, t) {
|
|
341
|
-
let
|
|
597
|
+
let s = b(e.sql, t);
|
|
342
598
|
if (e.filters && e.filters.length > 0) {
|
|
343
599
|
const n = e.filters.map((r) => r(t));
|
|
344
|
-
|
|
600
|
+
s = m`CASE WHEN ${h(...n)} THEN ${s} END`;
|
|
345
601
|
}
|
|
602
|
+
if (!this.databaseAdapter)
|
|
603
|
+
throw new Error("DatabaseAdapter is required for measure aggregation");
|
|
346
604
|
switch (e.type) {
|
|
347
605
|
case "count":
|
|
348
|
-
return
|
|
606
|
+
return this.databaseAdapter.buildCount(s);
|
|
349
607
|
case "countDistinct":
|
|
350
|
-
return
|
|
608
|
+
return this.databaseAdapter.buildCountDistinct(s);
|
|
351
609
|
case "sum":
|
|
352
|
-
return
|
|
610
|
+
return this.databaseAdapter.buildSum(s);
|
|
353
611
|
case "avg":
|
|
354
|
-
return
|
|
612
|
+
return this.databaseAdapter.buildAvg(s);
|
|
355
613
|
case "min":
|
|
356
|
-
return
|
|
614
|
+
return this.databaseAdapter.buildMin(s);
|
|
357
615
|
case "max":
|
|
358
|
-
return
|
|
616
|
+
return this.databaseAdapter.buildMax(s);
|
|
359
617
|
case "number":
|
|
360
|
-
return
|
|
618
|
+
return s;
|
|
361
619
|
default:
|
|
362
|
-
return
|
|
620
|
+
return this.databaseAdapter.buildCount(s);
|
|
363
621
|
}
|
|
364
622
|
}
|
|
365
623
|
/**
|
|
366
624
|
* Build time dimension expression (similar to single-cube approach)
|
|
367
625
|
*/
|
|
368
|
-
buildTimeDimensionExpression(e, t,
|
|
369
|
-
const n = b(e,
|
|
626
|
+
buildTimeDimensionExpression(e, t, s) {
|
|
627
|
+
const n = b(e, s);
|
|
370
628
|
if (!t)
|
|
371
629
|
return n;
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
case "quarter":
|
|
376
|
-
return f`DATE_TRUNC('quarter', ${n}::timestamp)`;
|
|
377
|
-
case "month":
|
|
378
|
-
return f`DATE_TRUNC('month', ${n}::timestamp)`;
|
|
379
|
-
case "week":
|
|
380
|
-
return f`DATE_TRUNC('week', ${n}::timestamp)`;
|
|
381
|
-
case "day":
|
|
382
|
-
return f`DATE_TRUNC('day', ${n}::timestamp)`;
|
|
383
|
-
case "hour":
|
|
384
|
-
return f`DATE_TRUNC('hour', ${n}::timestamp)`;
|
|
385
|
-
case "minute":
|
|
386
|
-
return f`DATE_TRUNC('minute', ${n}::timestamp)`;
|
|
387
|
-
case "second":
|
|
388
|
-
return f`DATE_TRUNC('second', ${n}::timestamp)`;
|
|
389
|
-
default:
|
|
390
|
-
return n;
|
|
391
|
-
}
|
|
630
|
+
if (!this.databaseAdapter)
|
|
631
|
+
throw new Error("DatabaseAdapter is required for time dimension building");
|
|
632
|
+
return this.databaseAdapter.buildTimeDimension(t, n);
|
|
392
633
|
}
|
|
393
634
|
/**
|
|
394
635
|
* Build WHERE conditions for multi-cube query
|
|
395
636
|
*/
|
|
396
|
-
buildMultiCubeWhereConditions(e, t,
|
|
637
|
+
buildMultiCubeWhereConditions(e, t, s) {
|
|
397
638
|
const n = [];
|
|
398
639
|
if (t.filters)
|
|
399
640
|
for (const r of t.filters) {
|
|
400
|
-
const a = this.processMultiCubeFilter(r, e,
|
|
641
|
+
const a = this.processMultiCubeFilter(r, e, s);
|
|
401
642
|
a && n.push(a);
|
|
402
643
|
}
|
|
403
644
|
if (t.timeDimensions) {
|
|
404
645
|
for (const r of t.timeDimensions)
|
|
405
646
|
if (r.dateRange) {
|
|
406
|
-
const [a,
|
|
407
|
-
if (c && c.dimensions[
|
|
408
|
-
const
|
|
409
|
-
|
|
647
|
+
const [a, i] = r.dimension.split("."), c = e.get(a);
|
|
648
|
+
if (c && c.dimensions[i]) {
|
|
649
|
+
const u = c.dimensions[i], l = b(u.sql, s), d = this.buildDateRangeCondition(l, r.dateRange);
|
|
650
|
+
d && n.push(d);
|
|
410
651
|
}
|
|
411
652
|
}
|
|
412
653
|
}
|
|
@@ -415,28 +656,28 @@ class ie {
|
|
|
415
656
|
/**
|
|
416
657
|
* Process a single filter for multi-cube queries (handles logical and simple filters)
|
|
417
658
|
*/
|
|
418
|
-
processMultiCubeFilter(e, t,
|
|
659
|
+
processMultiCubeFilter(e, t, s) {
|
|
419
660
|
if ("and" in e || "or" in e) {
|
|
420
661
|
if (e.and) {
|
|
421
|
-
const n = e.and.map((r) => this.processMultiCubeFilter(r, t,
|
|
662
|
+
const n = e.and.map((r) => this.processMultiCubeFilter(r, t, s)).filter((r) => r !== null);
|
|
422
663
|
return n.length > 0 ? h(...n) : null;
|
|
423
664
|
}
|
|
424
665
|
if (e.or) {
|
|
425
|
-
const n = e.or.map((r) => this.processMultiCubeFilter(r, t,
|
|
666
|
+
const n = e.or.map((r) => this.processMultiCubeFilter(r, t, s)).filter((r) => r !== null);
|
|
426
667
|
return n.length > 0 ? j(...n) : null;
|
|
427
668
|
}
|
|
428
669
|
}
|
|
429
670
|
if ("member" in e) {
|
|
430
671
|
const [n] = e.member.split("."), r = t.get(n);
|
|
431
672
|
if (r)
|
|
432
|
-
return this.buildFilterCondition(e, r,
|
|
673
|
+
return this.buildFilterCondition(e, r, s);
|
|
433
674
|
}
|
|
434
675
|
return null;
|
|
435
676
|
}
|
|
436
677
|
/**
|
|
437
678
|
* Filter condition builder with comprehensive operator support
|
|
438
679
|
*/
|
|
439
|
-
buildFilterCondition(e, t,
|
|
680
|
+
buildFilterCondition(e, t, s) {
|
|
440
681
|
if (!e.member || !e.operator)
|
|
441
682
|
return null;
|
|
442
683
|
const [n, r] = e.member.split(".");
|
|
@@ -445,61 +686,69 @@ class ie {
|
|
|
445
686
|
const a = t.dimensions[r] || t.measures[r];
|
|
446
687
|
if (!a)
|
|
447
688
|
return null;
|
|
448
|
-
const
|
|
449
|
-
if (
|
|
689
|
+
const i = b(a.sql, s), u = (e.values || []).filter((d) => d != null);
|
|
690
|
+
if (u.length === 0 && !["set", "notSet"].includes(e.operator))
|
|
450
691
|
return null;
|
|
451
|
-
const
|
|
692
|
+
const l = u[0];
|
|
452
693
|
switch (e.operator) {
|
|
453
694
|
case "equals":
|
|
454
|
-
if (
|
|
455
|
-
return
|
|
456
|
-
if (
|
|
457
|
-
const
|
|
458
|
-
return v(
|
|
695
|
+
if (u.length === 0)
|
|
696
|
+
return m`1 = 0`;
|
|
697
|
+
if (u.length === 1) {
|
|
698
|
+
const d = a.type === "time" && this.normalizeDate(l) || l;
|
|
699
|
+
return v(i, d);
|
|
459
700
|
} else if (a.type === "time") {
|
|
460
|
-
const
|
|
461
|
-
return
|
|
701
|
+
const d = u.map((f) => this.normalizeDate(f) || f);
|
|
702
|
+
return m`${i} IN (${m.join(d.map((f) => m`${f}`), m`, `)})`;
|
|
462
703
|
} else
|
|
463
|
-
return
|
|
704
|
+
return m`${i} IN (${m.join(u.map((d) => m`${d}`), m`, `)})`;
|
|
464
705
|
case "notEquals":
|
|
465
|
-
return
|
|
706
|
+
return u.length === 1 ? m`${i} <> ${l}` : u.length > 1 ? m`${i} NOT IN (${m.join(u.map((d) => m`${d}`), m`, `)})` : null;
|
|
466
707
|
case "contains":
|
|
467
|
-
|
|
708
|
+
if (!this.databaseAdapter)
|
|
709
|
+
throw new Error("DatabaseAdapter is required for string conditions");
|
|
710
|
+
return this.databaseAdapter.buildStringCondition(i, "contains", l);
|
|
468
711
|
case "notContains":
|
|
469
|
-
|
|
712
|
+
if (!this.databaseAdapter)
|
|
713
|
+
throw new Error("DatabaseAdapter is required for string conditions");
|
|
714
|
+
return this.databaseAdapter.buildStringCondition(i, "notContains", l);
|
|
470
715
|
case "startsWith":
|
|
471
|
-
|
|
716
|
+
if (!this.databaseAdapter)
|
|
717
|
+
throw new Error("DatabaseAdapter is required for string conditions");
|
|
718
|
+
return this.databaseAdapter.buildStringCondition(i, "startsWith", l);
|
|
472
719
|
case "endsWith":
|
|
473
|
-
|
|
720
|
+
if (!this.databaseAdapter)
|
|
721
|
+
throw new Error("DatabaseAdapter is required for string conditions");
|
|
722
|
+
return this.databaseAdapter.buildStringCondition(i, "endsWith", l);
|
|
474
723
|
case "gt":
|
|
475
|
-
return
|
|
724
|
+
return N(i, l);
|
|
476
725
|
case "gte":
|
|
477
|
-
return
|
|
726
|
+
return w(i, l);
|
|
478
727
|
case "lt":
|
|
479
|
-
return $(
|
|
728
|
+
return $(i, l);
|
|
480
729
|
case "lte":
|
|
481
|
-
return
|
|
730
|
+
return D(i, l);
|
|
482
731
|
case "set":
|
|
483
|
-
return z(
|
|
732
|
+
return z(i);
|
|
484
733
|
case "notSet":
|
|
485
|
-
return
|
|
734
|
+
return _(i);
|
|
486
735
|
case "inDateRange":
|
|
487
|
-
if (
|
|
488
|
-
const
|
|
489
|
-
if (
|
|
736
|
+
if (u.length >= 2) {
|
|
737
|
+
const d = this.normalizeDate(u[0]), f = this.normalizeDate(u[1]);
|
|
738
|
+
if (d && f)
|
|
490
739
|
return h(
|
|
491
|
-
|
|
492
|
-
|
|
740
|
+
w(i, d),
|
|
741
|
+
D(i, f)
|
|
493
742
|
);
|
|
494
743
|
}
|
|
495
744
|
return null;
|
|
496
745
|
case "beforeDate": {
|
|
497
|
-
const
|
|
498
|
-
return
|
|
746
|
+
const d = this.normalizeDate(l);
|
|
747
|
+
return d ? $(i, d) : null;
|
|
499
748
|
}
|
|
500
749
|
case "afterDate": {
|
|
501
|
-
const
|
|
502
|
-
return
|
|
750
|
+
const d = this.normalizeDate(l);
|
|
751
|
+
return d ? N(i, d) : null;
|
|
503
752
|
}
|
|
504
753
|
default:
|
|
505
754
|
return null;
|
|
@@ -511,21 +760,21 @@ class ie {
|
|
|
511
760
|
buildDateRangeCondition(e, t) {
|
|
512
761
|
if (!t) return null;
|
|
513
762
|
if (Array.isArray(t) && t.length >= 2) {
|
|
514
|
-
const
|
|
515
|
-
return !
|
|
516
|
-
|
|
517
|
-
|
|
763
|
+
const s = this.normalizeDate(t[0]), n = this.normalizeDate(t[1]);
|
|
764
|
+
return !s || !n ? null : h(
|
|
765
|
+
w(e, s),
|
|
766
|
+
D(e, n)
|
|
518
767
|
);
|
|
519
768
|
}
|
|
520
769
|
if (typeof t == "string") {
|
|
521
|
-
const
|
|
522
|
-
if (!
|
|
523
|
-
const n = new Date(
|
|
770
|
+
const s = this.normalizeDate(t);
|
|
771
|
+
if (!s) return null;
|
|
772
|
+
const n = new Date(s);
|
|
524
773
|
n.setUTCHours(0, 0, 0, 0);
|
|
525
|
-
const r = new Date(
|
|
774
|
+
const r = new Date(s);
|
|
526
775
|
return r.setUTCHours(23, 59, 59, 999), h(
|
|
527
|
-
|
|
528
|
-
|
|
776
|
+
w(e, n),
|
|
777
|
+
D(e, r)
|
|
529
778
|
);
|
|
530
779
|
}
|
|
531
780
|
return null;
|
|
@@ -553,47 +802,50 @@ class ie {
|
|
|
553
802
|
/**
|
|
554
803
|
* Build GROUP BY fields for multi-cube query
|
|
555
804
|
*/
|
|
556
|
-
buildMultiCubeGroupByFields(e, t,
|
|
805
|
+
buildMultiCubeGroupByFields(e, t, s) {
|
|
557
806
|
const n = [];
|
|
558
807
|
if (!(t.measures && t.measures.length > 0))
|
|
559
808
|
return [];
|
|
560
809
|
const a = {
|
|
561
810
|
db: {},
|
|
562
811
|
schema: {},
|
|
563
|
-
securityContext:
|
|
812
|
+
securityContext: s
|
|
564
813
|
};
|
|
565
814
|
if (t.dimensions)
|
|
566
|
-
for (const
|
|
567
|
-
const [c,
|
|
568
|
-
if (
|
|
569
|
-
const
|
|
570
|
-
n.push(
|
|
815
|
+
for (const i of t.dimensions) {
|
|
816
|
+
const [c, u] = i.split("."), l = e.get(c);
|
|
817
|
+
if (l && l.dimensions[u]) {
|
|
818
|
+
const d = l.dimensions[u], f = b(d.sql, a);
|
|
819
|
+
n.push(f);
|
|
571
820
|
}
|
|
572
821
|
}
|
|
573
822
|
if (t.timeDimensions)
|
|
574
|
-
for (const
|
|
575
|
-
const [c,
|
|
576
|
-
if (
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
|
|
823
|
+
for (const i of t.timeDimensions) {
|
|
824
|
+
const [c, u] = i.dimension.split("."), l = e.get(c);
|
|
825
|
+
if (l && l.dimensions[u]) {
|
|
826
|
+
const d = l.dimensions[u], f = this.buildTimeDimensionExpression(
|
|
827
|
+
d.sql,
|
|
828
|
+
i.granularity,
|
|
580
829
|
a
|
|
581
830
|
);
|
|
582
|
-
n.push(
|
|
831
|
+
n.push(f);
|
|
583
832
|
}
|
|
584
833
|
}
|
|
585
834
|
return n;
|
|
586
835
|
}
|
|
587
836
|
}
|
|
588
|
-
class
|
|
837
|
+
class T {
|
|
589
838
|
constructor(e) {
|
|
590
|
-
|
|
591
|
-
this
|
|
839
|
+
C(this, "multiCubeBuilder");
|
|
840
|
+
C(this, "databaseAdapter");
|
|
841
|
+
if (this.dbExecutor = e, this.databaseAdapter = e.databaseAdapter, !this.databaseAdapter)
|
|
842
|
+
throw new Error("DatabaseExecutor must have a databaseAdapter property");
|
|
843
|
+
this.multiCubeBuilder = new ae(this.databaseAdapter);
|
|
592
844
|
}
|
|
593
845
|
/**
|
|
594
846
|
* Unified query execution method that handles both single and multi-cube queries
|
|
595
847
|
*/
|
|
596
|
-
async execute(e, t,
|
|
848
|
+
async execute(e, t, s) {
|
|
597
849
|
try {
|
|
598
850
|
const n = Q(e, t);
|
|
599
851
|
if (!n.isValid)
|
|
@@ -602,12 +854,12 @@ class x {
|
|
|
602
854
|
if (r.size === 0)
|
|
603
855
|
throw new Error("No cubes found for query");
|
|
604
856
|
if (r.size === 1) {
|
|
605
|
-
const a = Array.from(r)[0],
|
|
606
|
-
if (!
|
|
857
|
+
const a = Array.from(r)[0], i = e.get(a);
|
|
858
|
+
if (!i)
|
|
607
859
|
throw new Error(`Cube '${a}' not found`);
|
|
608
|
-
return this.executeSingleCube(
|
|
860
|
+
return this.executeSingleCube(i, t, s);
|
|
609
861
|
} else
|
|
610
|
-
return this.executeMultiCube(e, t,
|
|
862
|
+
return this.executeMultiCube(e, t, s);
|
|
611
863
|
} catch (n) {
|
|
612
864
|
throw new Error(`Query execution failed: ${n instanceof Error ? n.message : "Unknown error"}`);
|
|
613
865
|
}
|
|
@@ -615,76 +867,67 @@ class x {
|
|
|
615
867
|
/**
|
|
616
868
|
* Legacy interface for single cube queries
|
|
617
869
|
*/
|
|
618
|
-
async executeQuery(e, t,
|
|
870
|
+
async executeQuery(e, t, s) {
|
|
619
871
|
const n = /* @__PURE__ */ new Map();
|
|
620
|
-
return n.set(e.name, e), this.execute(n, t,
|
|
872
|
+
return n.set(e.name, e), this.execute(n, t, s);
|
|
621
873
|
}
|
|
622
874
|
/**
|
|
623
875
|
* Execute a single cube query
|
|
624
876
|
*/
|
|
625
|
-
async executeSingleCube(e, t,
|
|
626
|
-
return this.executeCube(e, t,
|
|
877
|
+
async executeSingleCube(e, t, s) {
|
|
878
|
+
return this.executeCube(e, t, s);
|
|
627
879
|
}
|
|
628
880
|
/**
|
|
629
881
|
* Execute a Cube query (dynamic query building)
|
|
630
882
|
*/
|
|
631
|
-
async executeCube(e, t,
|
|
883
|
+
async executeCube(e, t, s) {
|
|
632
884
|
try {
|
|
633
885
|
const n = {
|
|
634
886
|
db: this.dbExecutor.db,
|
|
635
887
|
schema: this.dbExecutor.schema,
|
|
636
|
-
securityContext:
|
|
888
|
+
securityContext: s
|
|
637
889
|
}, r = e.sql(n), a = this.buildSelections(e, t, n);
|
|
638
|
-
let
|
|
890
|
+
let i = n.db.select(a).from(r.from);
|
|
639
891
|
if (r.joins)
|
|
640
892
|
for (const p of r.joins)
|
|
641
893
|
switch (p.type || "left") {
|
|
642
894
|
case "left":
|
|
643
|
-
|
|
895
|
+
i = i.leftJoin(p.table, p.on);
|
|
644
896
|
break;
|
|
645
897
|
case "inner":
|
|
646
|
-
|
|
898
|
+
i = i.innerJoin(p.table, p.on);
|
|
647
899
|
break;
|
|
648
900
|
case "right":
|
|
649
|
-
|
|
901
|
+
i = i.rightJoin(p.table, p.on);
|
|
650
902
|
break;
|
|
651
903
|
case "full":
|
|
652
|
-
|
|
904
|
+
i = i.fullJoin(p.table, p.on);
|
|
653
905
|
break;
|
|
654
906
|
}
|
|
655
|
-
r.where && (
|
|
907
|
+
r.where && (i = i.where(r.where));
|
|
656
908
|
const c = this.buildWhereConditions(e, t, n);
|
|
657
909
|
if (c.length > 0) {
|
|
658
910
|
const p = c.length === 1 ? c[0] : h(...c);
|
|
659
|
-
|
|
911
|
+
i = i.where(p);
|
|
660
912
|
}
|
|
661
|
-
const
|
|
662
|
-
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
s = s.limit(t.limit);
|
|
668
|
-
}
|
|
669
|
-
if (t.offset !== void 0) {
|
|
670
|
-
if (t.offset < 0)
|
|
671
|
-
throw new Error("Offset must be non-negative");
|
|
672
|
-
s = s.offset(t.offset);
|
|
673
|
-
}
|
|
674
|
-
const m = t.measures || [], d = await this.dbExecutor.execute(s, m), U = Array.isArray(d) ? d.map((p) => {
|
|
675
|
-
const N = { ...p };
|
|
913
|
+
const u = this.buildGroupByFields(e, t, n);
|
|
914
|
+
u.length > 0 && (i = i.groupBy(...u));
|
|
915
|
+
const l = this.buildOrderBy(t);
|
|
916
|
+
l.length > 0 && (i = i.orderBy(...l)), i = this.applyLimitAndOffset(i, t);
|
|
917
|
+
const d = this.collectNumericFields(e, t), f = await this.dbExecutor.execute(i, d), I = Array.isArray(f) ? f.map((p) => {
|
|
918
|
+
const A = { ...p };
|
|
676
919
|
if (t.timeDimensions) {
|
|
677
|
-
for (const
|
|
678
|
-
if (
|
|
679
|
-
let g =
|
|
680
|
-
typeof g == "string" && g.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/) && (g = g.replace(" ", "T"), !g.endsWith("Z") && !g.includes("+") && (g = g + "Z")),
|
|
920
|
+
for (const E of t.timeDimensions)
|
|
921
|
+
if (E.dimension in A) {
|
|
922
|
+
let g = A[E.dimension];
|
|
923
|
+
typeof g == "string" && g.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/) && (g = g.replace(" ", "T"), !g.endsWith("Z") && !g.includes("+") && (g = g + "Z")), A[E.dimension] = g;
|
|
681
924
|
}
|
|
682
925
|
}
|
|
683
|
-
return
|
|
684
|
-
}) : [
|
|
926
|
+
return A;
|
|
927
|
+
}) : [f], U = this.generateAnnotations(e, t);
|
|
685
928
|
return {
|
|
686
|
-
data:
|
|
687
|
-
annotation:
|
|
929
|
+
data: I,
|
|
930
|
+
annotation: U
|
|
688
931
|
};
|
|
689
932
|
} catch (n) {
|
|
690
933
|
throw new Error(`Cube query execution failed: ${n instanceof Error ? n.message : "Unknown error"}`);
|
|
@@ -693,28 +936,28 @@ class x {
|
|
|
693
936
|
/**
|
|
694
937
|
* Execute multi-cube query using JOIN resolution
|
|
695
938
|
*/
|
|
696
|
-
async executeMultiCube(e, t,
|
|
697
|
-
const n = this.buildMultiCubeQuery(e, t,
|
|
939
|
+
async executeMultiCube(e, t, s) {
|
|
940
|
+
const n = this.buildMultiCubeQuery(e, t, s), r = this.collectNumericFieldsMultiCube(e, t), a = await this.dbExecutor.execute(n, r), i = {
|
|
698
941
|
db: this.dbExecutor.db,
|
|
699
942
|
schema: this.dbExecutor.schema,
|
|
700
|
-
securityContext:
|
|
701
|
-
}, c = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t,
|
|
943
|
+
securityContext: s
|
|
944
|
+
}, c = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, i), u = this.generateMultiCubeAnnotations(c, t);
|
|
702
945
|
return {
|
|
703
946
|
data: Array.isArray(a) ? a : [a],
|
|
704
|
-
annotation:
|
|
947
|
+
annotation: u
|
|
705
948
|
};
|
|
706
949
|
}
|
|
707
950
|
/**
|
|
708
951
|
* Generate raw SQL for debugging (without execution)
|
|
709
952
|
*/
|
|
710
|
-
async generateSQL(e, t,
|
|
711
|
-
return this.generateCubeSQL(e, t,
|
|
953
|
+
async generateSQL(e, t, s) {
|
|
954
|
+
return this.generateCubeSQL(e, t, s);
|
|
712
955
|
}
|
|
713
956
|
/**
|
|
714
957
|
* Generate raw SQL for multi-cube queries without execution
|
|
715
958
|
*/
|
|
716
|
-
async generateMultiCubeSQL(e, t,
|
|
717
|
-
const r = this.buildMultiCubeQuery(e, t,
|
|
959
|
+
async generateMultiCubeSQL(e, t, s) {
|
|
960
|
+
const r = this.buildMultiCubeQuery(e, t, s).toSQL();
|
|
718
961
|
return {
|
|
719
962
|
sql: r.sql,
|
|
720
963
|
params: r.params
|
|
@@ -723,230 +966,249 @@ class x {
|
|
|
723
966
|
/**
|
|
724
967
|
* Build multi-cube query (extracted from executeMultiCube for reuse)
|
|
725
968
|
*/
|
|
726
|
-
buildMultiCubeQuery(e, t,
|
|
969
|
+
buildMultiCubeQuery(e, t, s) {
|
|
727
970
|
const n = {
|
|
728
971
|
db: this.dbExecutor.db,
|
|
729
972
|
schema: this.dbExecutor.schema,
|
|
730
|
-
securityContext:
|
|
973
|
+
securityContext: s
|
|
731
974
|
}, r = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, n), a = r.primaryCube.sql(n);
|
|
732
|
-
let
|
|
975
|
+
let i = n.db.select(r.selections).from(a.from);
|
|
733
976
|
if (a.joins)
|
|
734
|
-
for (const
|
|
735
|
-
switch (
|
|
977
|
+
for (const l of a.joins)
|
|
978
|
+
switch (l.type || "left") {
|
|
736
979
|
case "left":
|
|
737
|
-
|
|
980
|
+
i = i.leftJoin(l.table, l.on);
|
|
738
981
|
break;
|
|
739
982
|
case "inner":
|
|
740
|
-
|
|
983
|
+
i = i.innerJoin(l.table, l.on);
|
|
741
984
|
break;
|
|
742
985
|
case "right":
|
|
743
|
-
|
|
986
|
+
i = i.rightJoin(l.table, l.on);
|
|
744
987
|
break;
|
|
745
988
|
case "full":
|
|
746
|
-
|
|
989
|
+
i = i.fullJoin(l.table, l.on);
|
|
747
990
|
break;
|
|
748
991
|
default:
|
|
749
|
-
|
|
992
|
+
i = i.leftJoin(l.table, l.on);
|
|
750
993
|
}
|
|
751
994
|
if (r.joinCubes && r.joinCubes.length > 0)
|
|
752
|
-
for (const
|
|
753
|
-
const
|
|
995
|
+
for (const l of r.joinCubes) {
|
|
996
|
+
const d = l.cube.sql(n);
|
|
754
997
|
try {
|
|
755
|
-
switch (
|
|
998
|
+
switch (l.joinType || "left") {
|
|
756
999
|
case "left":
|
|
757
|
-
|
|
1000
|
+
i = i.leftJoin(d.from, l.joinCondition);
|
|
758
1001
|
break;
|
|
759
1002
|
case "inner":
|
|
760
|
-
|
|
1003
|
+
i = i.innerJoin(d.from, l.joinCondition);
|
|
761
1004
|
break;
|
|
762
1005
|
case "right":
|
|
763
|
-
|
|
1006
|
+
i = i.rightJoin(d.from, l.joinCondition);
|
|
764
1007
|
break;
|
|
765
1008
|
case "full":
|
|
766
|
-
|
|
1009
|
+
i = i.fullJoin(d.from, l.joinCondition);
|
|
767
1010
|
break;
|
|
768
1011
|
}
|
|
769
|
-
} catch (
|
|
770
|
-
console.warn(`Multi-cube join failed for ${
|
|
1012
|
+
} catch (f) {
|
|
1013
|
+
console.warn(`Multi-cube join failed for ${l.cube.name}: ${f instanceof Error ? f.message : "Unknown error"}`);
|
|
771
1014
|
}
|
|
772
1015
|
}
|
|
773
1016
|
const c = [];
|
|
774
1017
|
if (a.where && c.push(a.where), r.whereConditions.length > 0 && c.push(...r.whereConditions), c.length > 0) {
|
|
775
|
-
const
|
|
776
|
-
|
|
1018
|
+
const l = c.length === 1 ? c[0] : h(...c);
|
|
1019
|
+
i = i.where(l);
|
|
777
1020
|
}
|
|
778
|
-
r.groupByFields.length > 0 && (
|
|
779
|
-
const
|
|
780
|
-
|
|
781
|
-
|
|
1021
|
+
r.groupByFields.length > 0 && (i = i.groupBy(...r.groupByFields));
|
|
1022
|
+
const u = this.buildOrderBy(t);
|
|
1023
|
+
return u.length > 0 && (i = i.orderBy(...u)), i = this.applyLimitAndOffset(i, t), i;
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Collect numeric field names (measures + numeric dimensions) for type conversion
|
|
1027
|
+
*/
|
|
1028
|
+
collectNumericFields(e, t) {
|
|
1029
|
+
const s = [];
|
|
1030
|
+
if (t.measures && s.push(...t.measures), t.dimensions)
|
|
1031
|
+
for (const n of t.dimensions) {
|
|
1032
|
+
const r = n.includes(".") ? n.split(".")[1] : n, a = e.dimensions[r];
|
|
1033
|
+
a && a.type === "number" && s.push(n);
|
|
1034
|
+
}
|
|
1035
|
+
return s;
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Collect numeric field names for multi-cube queries
|
|
1039
|
+
*/
|
|
1040
|
+
collectNumericFieldsMultiCube(e, t) {
|
|
1041
|
+
const s = [];
|
|
1042
|
+
if (t.measures && s.push(...t.measures), t.dimensions)
|
|
1043
|
+
for (const n of t.dimensions) {
|
|
1044
|
+
const r = n.includes(".") ? n.split(".")[1] : n;
|
|
1045
|
+
for (const a of e.values()) {
|
|
1046
|
+
const i = a.dimensions[r];
|
|
1047
|
+
if (i && i.type === "number") {
|
|
1048
|
+
s.push(n);
|
|
1049
|
+
break;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
return s;
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Apply LIMIT and OFFSET to a query with validation
|
|
1057
|
+
* If offset is provided without limit, add a reasonable default limit
|
|
1058
|
+
*/
|
|
1059
|
+
applyLimitAndOffset(e, t) {
|
|
1060
|
+
let s = t.limit;
|
|
1061
|
+
t.offset !== void 0 && t.offset > 0 && s === void 0 && (s = 50);
|
|
1062
|
+
let n = e;
|
|
1063
|
+
if (s !== void 0) {
|
|
1064
|
+
if (s < 0)
|
|
782
1065
|
throw new Error("Limit must be non-negative");
|
|
783
|
-
|
|
1066
|
+
n = n.limit(s);
|
|
784
1067
|
}
|
|
785
1068
|
if (t.offset !== void 0) {
|
|
786
1069
|
if (t.offset < 0)
|
|
787
1070
|
throw new Error("Offset must be non-negative");
|
|
788
|
-
|
|
1071
|
+
n = n.offset(t.offset);
|
|
789
1072
|
}
|
|
790
|
-
return
|
|
1073
|
+
return n;
|
|
791
1074
|
}
|
|
792
1075
|
/**
|
|
793
1076
|
* Generate SQL for Cube
|
|
794
1077
|
*/
|
|
795
|
-
async generateCubeSQL(e, t,
|
|
1078
|
+
async generateCubeSQL(e, t, s) {
|
|
796
1079
|
const n = {
|
|
797
1080
|
db: this.dbExecutor.db,
|
|
798
1081
|
schema: this.dbExecutor.schema,
|
|
799
|
-
securityContext:
|
|
1082
|
+
securityContext: s
|
|
800
1083
|
}, r = e.sql(n), a = this.buildSelections(e, t, n);
|
|
801
|
-
let
|
|
1084
|
+
let i = n.db.select(a).from(r.from);
|
|
802
1085
|
if (r.joins)
|
|
803
|
-
for (const
|
|
804
|
-
switch (
|
|
1086
|
+
for (const f of r.joins)
|
|
1087
|
+
switch (f.type || "left") {
|
|
805
1088
|
case "left":
|
|
806
|
-
|
|
1089
|
+
i = i.leftJoin(f.table, f.on);
|
|
807
1090
|
break;
|
|
808
1091
|
case "inner":
|
|
809
|
-
|
|
1092
|
+
i = i.innerJoin(f.table, f.on);
|
|
810
1093
|
break;
|
|
811
1094
|
case "right":
|
|
812
|
-
|
|
1095
|
+
i = i.rightJoin(f.table, f.on);
|
|
813
1096
|
break;
|
|
814
1097
|
case "full":
|
|
815
|
-
|
|
1098
|
+
i = i.fullJoin(f.table, f.on);
|
|
816
1099
|
break;
|
|
817
1100
|
}
|
|
818
|
-
r.where && (
|
|
1101
|
+
r.where && (i = i.where(r.where));
|
|
819
1102
|
const c = this.buildWhereConditions(e, t, n);
|
|
820
1103
|
if (c.length > 0) {
|
|
821
|
-
const
|
|
822
|
-
|
|
1104
|
+
const f = c.length === 1 ? c[0] : h(...c);
|
|
1105
|
+
i = i.where(f);
|
|
823
1106
|
}
|
|
824
|
-
const
|
|
825
|
-
|
|
826
|
-
const
|
|
827
|
-
if (
|
|
1107
|
+
const u = this.buildGroupByFields(e, t, n);
|
|
1108
|
+
u.length > 0 && (i = i.groupBy(...u));
|
|
1109
|
+
const l = this.buildOrderBy(t);
|
|
1110
|
+
if (l.length > 0 && (i = i.orderBy(...l)), t.limit !== void 0) {
|
|
828
1111
|
if (t.limit < 0)
|
|
829
1112
|
throw new Error("Limit must be non-negative");
|
|
830
|
-
|
|
1113
|
+
i = i.limit(t.limit);
|
|
831
1114
|
}
|
|
832
1115
|
if (t.offset !== void 0) {
|
|
833
1116
|
if (t.offset < 0)
|
|
834
1117
|
throw new Error("Offset must be non-negative");
|
|
835
|
-
|
|
1118
|
+
i = i.offset(t.offset);
|
|
836
1119
|
}
|
|
837
|
-
const
|
|
1120
|
+
const d = i.toSQL();
|
|
838
1121
|
return {
|
|
839
|
-
sql:
|
|
840
|
-
params:
|
|
1122
|
+
sql: d.sql,
|
|
1123
|
+
params: d.params
|
|
841
1124
|
};
|
|
842
1125
|
}
|
|
843
1126
|
/**
|
|
844
1127
|
* Build dynamic selections for Cube measures and dimensions
|
|
845
1128
|
*/
|
|
846
|
-
buildSelections(e, t,
|
|
1129
|
+
buildSelections(e, t, s) {
|
|
847
1130
|
const n = {};
|
|
848
1131
|
if (t.dimensions)
|
|
849
1132
|
for (const r of t.dimensions) {
|
|
850
|
-
const [a,
|
|
851
|
-
if (a === e.name && e.dimensions[
|
|
852
|
-
const c = e.dimensions[
|
|
853
|
-
n[r] =
|
|
1133
|
+
const [a, i] = r.split(".");
|
|
1134
|
+
if (a === e.name && e.dimensions[i]) {
|
|
1135
|
+
const c = e.dimensions[i], u = b(c.sql, s);
|
|
1136
|
+
n[r] = m`${u}`.as(r);
|
|
854
1137
|
}
|
|
855
1138
|
}
|
|
856
1139
|
if (t.measures)
|
|
857
1140
|
for (const r of t.measures) {
|
|
858
|
-
const [a,
|
|
859
|
-
if (a === e.name && e.measures[
|
|
860
|
-
const c = e.measures[
|
|
861
|
-
n[r] =
|
|
1141
|
+
const [a, i] = r.split(".");
|
|
1142
|
+
if (a === e.name && e.measures[i]) {
|
|
1143
|
+
const c = e.measures[i], u = this.buildMeasureExpression(c, s);
|
|
1144
|
+
n[r] = m`${u}`.as(r);
|
|
862
1145
|
}
|
|
863
1146
|
}
|
|
864
1147
|
if (t.timeDimensions)
|
|
865
1148
|
for (const r of t.timeDimensions) {
|
|
866
|
-
const [a,
|
|
867
|
-
if (a === e.name && e.dimensions[
|
|
868
|
-
const c = e.dimensions[
|
|
1149
|
+
const [a, i] = r.dimension.split(".");
|
|
1150
|
+
if (a === e.name && e.dimensions[i]) {
|
|
1151
|
+
const c = e.dimensions[i], u = this.buildTimeDimensionExpression(
|
|
869
1152
|
c.sql,
|
|
870
1153
|
r.granularity,
|
|
871
|
-
|
|
1154
|
+
s
|
|
872
1155
|
);
|
|
873
|
-
n[r.dimension] =
|
|
1156
|
+
n[r.dimension] = m`${u}`.as(r.dimension);
|
|
874
1157
|
}
|
|
875
1158
|
}
|
|
876
|
-
return Object.keys(n).length === 0 && (n.count =
|
|
1159
|
+
return Object.keys(n).length === 0 && (n.count = y()), n;
|
|
877
1160
|
}
|
|
878
1161
|
/**
|
|
879
1162
|
* Build measure expression with aggregation and filters for Cube
|
|
880
1163
|
*/
|
|
881
1164
|
buildMeasureExpression(e, t) {
|
|
882
|
-
let
|
|
1165
|
+
let s = b(e.sql, t);
|
|
883
1166
|
if (e.filters && e.filters.length > 0) {
|
|
884
1167
|
const n = e.filters.map((r) => r(t));
|
|
885
|
-
|
|
1168
|
+
s = m`CASE WHEN ${h(...n)} THEN ${s} END`;
|
|
886
1169
|
}
|
|
887
1170
|
switch (e.type) {
|
|
888
1171
|
case "count":
|
|
889
|
-
return
|
|
1172
|
+
return y(s);
|
|
890
1173
|
case "countDistinct":
|
|
891
|
-
return
|
|
1174
|
+
return H(s);
|
|
892
1175
|
case "sum":
|
|
893
|
-
return J(
|
|
1176
|
+
return J(s);
|
|
894
1177
|
case "avg":
|
|
895
|
-
return
|
|
1178
|
+
return K(s);
|
|
896
1179
|
case "min":
|
|
897
|
-
return
|
|
1180
|
+
return R(s);
|
|
898
1181
|
case "max":
|
|
899
|
-
return
|
|
1182
|
+
return Y(s);
|
|
900
1183
|
case "number":
|
|
901
|
-
return
|
|
1184
|
+
return s;
|
|
902
1185
|
default:
|
|
903
|
-
return
|
|
1186
|
+
return y(s);
|
|
904
1187
|
}
|
|
905
1188
|
}
|
|
906
1189
|
/**
|
|
907
|
-
* Build time dimension expression with granularity
|
|
1190
|
+
* Build time dimension expression with granularity using database adapter
|
|
908
1191
|
*/
|
|
909
|
-
buildTimeDimensionExpression(e, t,
|
|
910
|
-
const n = b(e,
|
|
911
|
-
|
|
912
|
-
return f`${n}`;
|
|
913
|
-
switch (t) {
|
|
914
|
-
case "year":
|
|
915
|
-
return f`DATE_TRUNC('year', ${n}::timestamp)`;
|
|
916
|
-
case "quarter":
|
|
917
|
-
return f`DATE_TRUNC('quarter', ${n}::timestamp)`;
|
|
918
|
-
case "month":
|
|
919
|
-
return f`DATE_TRUNC('month', ${n}::timestamp)`;
|
|
920
|
-
case "week":
|
|
921
|
-
return f`DATE_TRUNC('week', ${n}::timestamp)`;
|
|
922
|
-
case "day":
|
|
923
|
-
return f`DATE_TRUNC('day', ${n}::timestamp)::timestamp`;
|
|
924
|
-
case "hour":
|
|
925
|
-
return f`DATE_TRUNC('hour', ${n}::timestamp)`;
|
|
926
|
-
case "minute":
|
|
927
|
-
return f`DATE_TRUNC('minute', ${n}::timestamp)`;
|
|
928
|
-
case "second":
|
|
929
|
-
return f`DATE_TRUNC('second', ${n}::timestamp)`;
|
|
930
|
-
default:
|
|
931
|
-
return n;
|
|
932
|
-
}
|
|
1192
|
+
buildTimeDimensionExpression(e, t, s) {
|
|
1193
|
+
const n = b(e, s);
|
|
1194
|
+
return t ? this.databaseAdapter.buildTimeDimension(t, n) : m`${n}`;
|
|
933
1195
|
}
|
|
934
1196
|
/**
|
|
935
1197
|
* Build WHERE conditions from semantic query filters (Cube)
|
|
936
1198
|
*/
|
|
937
|
-
buildWhereConditions(e, t,
|
|
1199
|
+
buildWhereConditions(e, t, s) {
|
|
938
1200
|
const n = [];
|
|
939
1201
|
if (t.filters && t.filters.length > 0)
|
|
940
1202
|
for (const r of t.filters) {
|
|
941
|
-
const a = this.processFilter(r, e,
|
|
1203
|
+
const a = this.processFilter(r, e, s);
|
|
942
1204
|
a && n.push(a);
|
|
943
1205
|
}
|
|
944
1206
|
if (t.timeDimensions)
|
|
945
1207
|
for (const r of t.timeDimensions) {
|
|
946
|
-
const [a,
|
|
947
|
-
if (a === e.name && e.dimensions[
|
|
948
|
-
const c = e.dimensions[
|
|
949
|
-
|
|
1208
|
+
const [a, i] = r.dimension.split(".");
|
|
1209
|
+
if (a === e.name && e.dimensions[i] && r.dateRange) {
|
|
1210
|
+
const c = e.dimensions[i], u = b(c.sql, s), l = this.buildDateRangeCondition(u, r.dateRange);
|
|
1211
|
+
l && n.push(l);
|
|
950
1212
|
}
|
|
951
1213
|
}
|
|
952
1214
|
return n;
|
|
@@ -954,67 +1216,67 @@ class x {
|
|
|
954
1216
|
/**
|
|
955
1217
|
* Process a single filter for Cube (basic or logical)
|
|
956
1218
|
*/
|
|
957
|
-
processFilter(e, t,
|
|
1219
|
+
processFilter(e, t, s) {
|
|
958
1220
|
if ("and" in e || "or" in e) {
|
|
959
|
-
const
|
|
960
|
-
if (
|
|
961
|
-
const
|
|
962
|
-
return
|
|
1221
|
+
const u = e;
|
|
1222
|
+
if (u.and) {
|
|
1223
|
+
const l = u.and.map((d) => this.processFilter(d, t, s)).filter((d) => d !== null);
|
|
1224
|
+
return l.length > 0 ? h(...l) : null;
|
|
963
1225
|
}
|
|
964
|
-
if (
|
|
965
|
-
const
|
|
966
|
-
return
|
|
1226
|
+
if (u.or) {
|
|
1227
|
+
const l = u.or.map((d) => this.processFilter(d, t, s)).filter((d) => d !== null);
|
|
1228
|
+
return l.length > 0 ? j(...l) : null;
|
|
967
1229
|
}
|
|
968
1230
|
}
|
|
969
1231
|
const n = e, [r, a] = n.member.split(".");
|
|
970
1232
|
if (r !== t.name) return null;
|
|
971
|
-
const
|
|
972
|
-
if (!
|
|
973
|
-
const c = b(
|
|
1233
|
+
const i = t.dimensions[a] || t.measures[a];
|
|
1234
|
+
if (!i) return null;
|
|
1235
|
+
const c = b(i.sql, s);
|
|
974
1236
|
return this.buildFilterCondition(c, n.operator, n.values);
|
|
975
1237
|
}
|
|
976
1238
|
/**
|
|
977
1239
|
* Build filter condition using Drizzle operators
|
|
978
1240
|
*/
|
|
979
|
-
buildFilterCondition(e, t,
|
|
980
|
-
if (!
|
|
981
|
-
return t === "equals" ?
|
|
982
|
-
const n =
|
|
1241
|
+
buildFilterCondition(e, t, s) {
|
|
1242
|
+
if (!s || s.length === 0)
|
|
1243
|
+
return t === "equals" ? m`FALSE` : null;
|
|
1244
|
+
const n = s.filter((a) => !(a == null || a === "" || typeof a == "string" && a.includes("\0")));
|
|
983
1245
|
if (n.length === 0 && !["set", "notSet"].includes(t))
|
|
984
|
-
return t === "equals" ?
|
|
1246
|
+
return t === "equals" ? m`FALSE` : null;
|
|
985
1247
|
const r = n[0];
|
|
986
1248
|
switch (t) {
|
|
987
1249
|
case "equals":
|
|
988
|
-
return n.length > 1 ?
|
|
1250
|
+
return n.length > 1 ? P(e, n) : n.length === 1 ? v(e, r) : m`FALSE`;
|
|
989
1251
|
case "notEquals":
|
|
990
|
-
return n.length > 1 ?
|
|
1252
|
+
return n.length > 1 ? V(e, n) : n.length === 1 ? G(e, r) : null;
|
|
991
1253
|
case "contains":
|
|
992
|
-
return
|
|
1254
|
+
return this.databaseAdapter.buildStringCondition(e, "contains", r);
|
|
993
1255
|
case "notContains":
|
|
994
|
-
return
|
|
1256
|
+
return this.databaseAdapter.buildStringCondition(e, "notContains", r);
|
|
995
1257
|
case "startsWith":
|
|
996
|
-
return
|
|
1258
|
+
return this.databaseAdapter.buildStringCondition(e, "startsWith", r);
|
|
997
1259
|
case "endsWith":
|
|
998
|
-
return
|
|
1260
|
+
return this.databaseAdapter.buildStringCondition(e, "endsWith", r);
|
|
999
1261
|
case "gt":
|
|
1000
|
-
return
|
|
1262
|
+
return N(e, r);
|
|
1001
1263
|
case "gte":
|
|
1002
|
-
return
|
|
1264
|
+
return w(e, r);
|
|
1003
1265
|
case "lt":
|
|
1004
1266
|
return $(e, r);
|
|
1005
1267
|
case "lte":
|
|
1006
|
-
return
|
|
1268
|
+
return D(e, r);
|
|
1007
1269
|
case "set":
|
|
1008
1270
|
return z(e);
|
|
1009
1271
|
case "notSet":
|
|
1010
|
-
return
|
|
1272
|
+
return _(e);
|
|
1011
1273
|
case "inDateRange":
|
|
1012
1274
|
if (n.length >= 2) {
|
|
1013
|
-
const a = this.normalizeDate(n[0]),
|
|
1014
|
-
if (a &&
|
|
1275
|
+
const a = this.normalizeDate(n[0]), i = this.normalizeDate(n[1]);
|
|
1276
|
+
if (a && i)
|
|
1015
1277
|
return h(
|
|
1016
|
-
|
|
1017
|
-
|
|
1278
|
+
w(e, a),
|
|
1279
|
+
D(e, i)
|
|
1018
1280
|
);
|
|
1019
1281
|
}
|
|
1020
1282
|
return null;
|
|
@@ -1024,7 +1286,7 @@ class x {
|
|
|
1024
1286
|
}
|
|
1025
1287
|
case "afterDate": {
|
|
1026
1288
|
const a = this.normalizeDate(r);
|
|
1027
|
-
return a ?
|
|
1289
|
+
return a ? N(e, a) : null;
|
|
1028
1290
|
}
|
|
1029
1291
|
default:
|
|
1030
1292
|
return null;
|
|
@@ -1036,18 +1298,18 @@ class x {
|
|
|
1036
1298
|
buildDateRangeCondition(e, t) {
|
|
1037
1299
|
if (!t) return null;
|
|
1038
1300
|
if (Array.isArray(t) && t.length >= 2) {
|
|
1039
|
-
const
|
|
1040
|
-
return !
|
|
1041
|
-
|
|
1042
|
-
|
|
1301
|
+
const s = this.normalizeDate(t[0]), n = this.normalizeDate(t[1]);
|
|
1302
|
+
return !s || !n ? null : h(
|
|
1303
|
+
w(e, s),
|
|
1304
|
+
D(e, n)
|
|
1043
1305
|
);
|
|
1044
1306
|
}
|
|
1045
1307
|
if (typeof t == "string") {
|
|
1046
|
-
const
|
|
1047
|
-
if (
|
|
1308
|
+
const s = this.parseRelativeDateRange(t);
|
|
1309
|
+
if (s)
|
|
1048
1310
|
return h(
|
|
1049
|
-
|
|
1050
|
-
|
|
1311
|
+
w(e, s.start),
|
|
1312
|
+
D(e, s.end)
|
|
1051
1313
|
);
|
|
1052
1314
|
const n = this.normalizeDate(t);
|
|
1053
1315
|
if (!n) return null;
|
|
@@ -1055,8 +1317,8 @@ class x {
|
|
|
1055
1317
|
r.setUTCHours(0, 0, 0, 0);
|
|
1056
1318
|
const a = new Date(n);
|
|
1057
1319
|
return a.setUTCHours(23, 59, 59, 999), h(
|
|
1058
|
-
|
|
1059
|
-
|
|
1320
|
+
w(e, r),
|
|
1321
|
+
D(e, a)
|
|
1060
1322
|
);
|
|
1061
1323
|
}
|
|
1062
1324
|
return null;
|
|
@@ -1065,30 +1327,30 @@ class x {
|
|
|
1065
1327
|
* Parse relative date range expressions like "last 7 days", "this month"
|
|
1066
1328
|
*/
|
|
1067
1329
|
parseRelativeDateRange(e) {
|
|
1068
|
-
const t = /* @__PURE__ */ new Date(),
|
|
1330
|
+
const t = /* @__PURE__ */ new Date(), s = e.toLowerCase().trim(), n = s.match(/^last\s+(\d+)\s+days?$/);
|
|
1069
1331
|
if (n) {
|
|
1070
|
-
const
|
|
1071
|
-
c.setDate(t.getDate() -
|
|
1072
|
-
const
|
|
1073
|
-
return
|
|
1332
|
+
const i = parseInt(n[1], 10), c = new Date(t);
|
|
1333
|
+
c.setDate(t.getDate() - i), c.setHours(0, 0, 0, 0);
|
|
1334
|
+
const u = new Date(t);
|
|
1335
|
+
return u.setHours(23, 59, 59, 999), { start: c, end: u };
|
|
1074
1336
|
}
|
|
1075
|
-
if (
|
|
1076
|
-
const
|
|
1077
|
-
return { start:
|
|
1337
|
+
if (s === "this month") {
|
|
1338
|
+
const i = new Date(t.getFullYear(), t.getMonth(), 1, 0, 0, 0, 0), c = new Date(t.getFullYear(), t.getMonth() + 1, 0, 23, 59, 59, 999);
|
|
1339
|
+
return { start: i, end: c };
|
|
1078
1340
|
}
|
|
1079
|
-
const r =
|
|
1341
|
+
const r = s.match(/^last\s+(\d+)\s+months?$/);
|
|
1080
1342
|
if (r) {
|
|
1081
|
-
const
|
|
1082
|
-
return
|
|
1343
|
+
const i = parseInt(r[1], 10), c = new Date(t.getFullYear(), t.getMonth() - i, 1, 0, 0, 0, 0), u = new Date(t);
|
|
1344
|
+
return u.setHours(23, 59, 59, 999), { start: c, end: u };
|
|
1083
1345
|
}
|
|
1084
|
-
if (
|
|
1085
|
-
const
|
|
1086
|
-
return { start:
|
|
1346
|
+
if (s === "this year") {
|
|
1347
|
+
const i = new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0), c = new Date(t.getFullYear(), 11, 31, 23, 59, 59, 999);
|
|
1348
|
+
return { start: i, end: c };
|
|
1087
1349
|
}
|
|
1088
|
-
const a =
|
|
1350
|
+
const a = s.match(/^last\s+(\d+)\s+years?$/);
|
|
1089
1351
|
if (a) {
|
|
1090
|
-
const
|
|
1091
|
-
return
|
|
1352
|
+
const i = parseInt(a[1], 10), c = new Date(t.getFullYear() - i, 0, 1, 0, 0, 0, 0), u = new Date(t);
|
|
1353
|
+
return u.setHours(23, 59, 59, 999), { start: c, end: u };
|
|
1092
1354
|
}
|
|
1093
1355
|
return null;
|
|
1094
1356
|
}
|
|
@@ -1101,8 +1363,8 @@ class x {
|
|
|
1101
1363
|
if (e instanceof Date)
|
|
1102
1364
|
return isNaN(e.getTime()) ? null : e;
|
|
1103
1365
|
if (typeof e == "string") {
|
|
1104
|
-
const
|
|
1105
|
-
return isNaN(
|
|
1366
|
+
const s = new Date(e);
|
|
1367
|
+
return isNaN(s.getTime()) ? null : s;
|
|
1106
1368
|
}
|
|
1107
1369
|
const t = new Date(e);
|
|
1108
1370
|
return isNaN(t.getTime()) ? null : t;
|
|
@@ -1110,26 +1372,26 @@ class x {
|
|
|
1110
1372
|
/**
|
|
1111
1373
|
* Build GROUP BY fields from dimensions and time dimensions (Cube)
|
|
1112
1374
|
*/
|
|
1113
|
-
buildGroupByFields(e, t,
|
|
1375
|
+
buildGroupByFields(e, t, s) {
|
|
1114
1376
|
const n = [];
|
|
1115
1377
|
if (t.dimensions)
|
|
1116
1378
|
for (const r of t.dimensions) {
|
|
1117
|
-
const [a,
|
|
1118
|
-
if (a === e.name && e.dimensions[
|
|
1119
|
-
const c = e.dimensions[
|
|
1120
|
-
n.push(
|
|
1379
|
+
const [a, i] = r.split(".");
|
|
1380
|
+
if (a === e.name && e.dimensions[i]) {
|
|
1381
|
+
const c = e.dimensions[i], u = b(c.sql, s);
|
|
1382
|
+
n.push(u);
|
|
1121
1383
|
}
|
|
1122
1384
|
}
|
|
1123
1385
|
if (t.timeDimensions)
|
|
1124
1386
|
for (const r of t.timeDimensions) {
|
|
1125
|
-
const [a,
|
|
1126
|
-
if (a === e.name && e.dimensions[
|
|
1127
|
-
const c = e.dimensions[
|
|
1387
|
+
const [a, i] = r.dimension.split(".");
|
|
1388
|
+
if (a === e.name && e.dimensions[i]) {
|
|
1389
|
+
const c = e.dimensions[i], u = this.buildTimeDimensionExpression(
|
|
1128
1390
|
c.sql,
|
|
1129
1391
|
r.granularity,
|
|
1130
|
-
|
|
1392
|
+
s
|
|
1131
1393
|
);
|
|
1132
|
-
n.push(
|
|
1394
|
+
n.push(u);
|
|
1133
1395
|
}
|
|
1134
1396
|
}
|
|
1135
1397
|
return n;
|
|
@@ -1139,71 +1401,71 @@ class x {
|
|
|
1139
1401
|
*/
|
|
1140
1402
|
buildOrderBy(e, t) {
|
|
1141
1403
|
var r;
|
|
1142
|
-
const
|
|
1404
|
+
const s = [], n = t || [
|
|
1143
1405
|
...e.measures || [],
|
|
1144
1406
|
...e.dimensions || [],
|
|
1145
1407
|
...((r = e.timeDimensions) == null ? void 0 : r.map((a) => a.dimension)) || []
|
|
1146
1408
|
];
|
|
1147
1409
|
if (e.order && Object.keys(e.order).length > 0)
|
|
1148
|
-
for (const [a,
|
|
1410
|
+
for (const [a, i] of Object.entries(e.order)) {
|
|
1149
1411
|
if (!n.includes(a))
|
|
1150
1412
|
throw new Error(`Cannot order by '${a}': field is not selected in the query`);
|
|
1151
|
-
const c =
|
|
1152
|
-
|
|
1413
|
+
const c = i === "desc" ? m`DESC` : m`ASC`;
|
|
1414
|
+
s.push(m`${m.identifier(a)} ${c}`);
|
|
1153
1415
|
}
|
|
1154
1416
|
if (e.timeDimensions && e.timeDimensions.length > 0) {
|
|
1155
|
-
const a = new Set(Object.keys(e.order || {})),
|
|
1156
|
-
(c,
|
|
1417
|
+
const a = new Set(Object.keys(e.order || {})), i = [...e.timeDimensions].sort(
|
|
1418
|
+
(c, u) => c.dimension.localeCompare(u.dimension)
|
|
1157
1419
|
);
|
|
1158
|
-
for (const c of
|
|
1159
|
-
a.has(c.dimension) ||
|
|
1420
|
+
for (const c of i)
|
|
1421
|
+
a.has(c.dimension) || s.push(m`${m.identifier(c.dimension)} ASC`);
|
|
1160
1422
|
}
|
|
1161
|
-
return
|
|
1423
|
+
return s;
|
|
1162
1424
|
}
|
|
1163
1425
|
/**
|
|
1164
1426
|
* Generate annotations for UI metadata
|
|
1165
1427
|
*/
|
|
1166
1428
|
generateAnnotations(e, t) {
|
|
1167
|
-
const
|
|
1429
|
+
const s = {}, n = {}, r = {};
|
|
1168
1430
|
if (t.measures)
|
|
1169
1431
|
for (const a of t.measures) {
|
|
1170
|
-
const [
|
|
1171
|
-
if (
|
|
1172
|
-
const
|
|
1173
|
-
|
|
1174
|
-
title:
|
|
1175
|
-
shortTitle:
|
|
1176
|
-
type:
|
|
1432
|
+
const [i, c] = a.split(".");
|
|
1433
|
+
if (i === e.name && e.measures[c]) {
|
|
1434
|
+
const u = e.measures[c];
|
|
1435
|
+
s[a] = {
|
|
1436
|
+
title: u.title || c,
|
|
1437
|
+
shortTitle: u.title || c,
|
|
1438
|
+
type: u.type
|
|
1177
1439
|
};
|
|
1178
1440
|
}
|
|
1179
1441
|
}
|
|
1180
1442
|
if (t.dimensions)
|
|
1181
1443
|
for (const a of t.dimensions) {
|
|
1182
|
-
const [
|
|
1183
|
-
if (
|
|
1184
|
-
const
|
|
1444
|
+
const [i, c] = a.split(".");
|
|
1445
|
+
if (i === e.name && e.dimensions[c]) {
|
|
1446
|
+
const u = e.dimensions[c];
|
|
1185
1447
|
n[a] = {
|
|
1186
|
-
title:
|
|
1187
|
-
shortTitle:
|
|
1188
|
-
type:
|
|
1448
|
+
title: u.title || c,
|
|
1449
|
+
shortTitle: u.title || c,
|
|
1450
|
+
type: u.type
|
|
1189
1451
|
};
|
|
1190
1452
|
}
|
|
1191
1453
|
}
|
|
1192
1454
|
if (t.timeDimensions)
|
|
1193
1455
|
for (const a of t.timeDimensions) {
|
|
1194
|
-
const [
|
|
1195
|
-
if (
|
|
1196
|
-
const
|
|
1456
|
+
const [i, c] = a.dimension.split(".");
|
|
1457
|
+
if (i === e.name && e.dimensions[c]) {
|
|
1458
|
+
const u = e.dimensions[c];
|
|
1197
1459
|
r[a.dimension] = {
|
|
1198
|
-
title:
|
|
1199
|
-
shortTitle:
|
|
1200
|
-
type:
|
|
1460
|
+
title: u.title || c,
|
|
1461
|
+
shortTitle: u.title || c,
|
|
1462
|
+
type: u.type,
|
|
1201
1463
|
granularity: a.granularity
|
|
1202
1464
|
};
|
|
1203
1465
|
}
|
|
1204
1466
|
}
|
|
1205
1467
|
return {
|
|
1206
|
-
measures:
|
|
1468
|
+
measures: s,
|
|
1207
1469
|
dimensions: n,
|
|
1208
1470
|
segments: {},
|
|
1209
1471
|
timeDimensions: r
|
|
@@ -1213,61 +1475,61 @@ class x {
|
|
|
1213
1475
|
* Generate annotations for multi-cube queries
|
|
1214
1476
|
*/
|
|
1215
1477
|
generateMultiCubeAnnotations(e, t) {
|
|
1216
|
-
const
|
|
1217
|
-
if (e.joinCubes && a.push(...e.joinCubes.map((
|
|
1218
|
-
for (const
|
|
1219
|
-
const [c,
|
|
1220
|
-
if (
|
|
1221
|
-
const
|
|
1222
|
-
i
|
|
1223
|
-
title:
|
|
1224
|
-
shortTitle:
|
|
1225
|
-
type:
|
|
1478
|
+
const s = {}, n = {}, r = {}, a = [e.primaryCube];
|
|
1479
|
+
if (e.joinCubes && a.push(...e.joinCubes.map((i) => i.cube)), t.measures)
|
|
1480
|
+
for (const i of t.measures) {
|
|
1481
|
+
const [c, u] = i.split("."), l = a.find((d) => d.name === c);
|
|
1482
|
+
if (l && l.measures[u]) {
|
|
1483
|
+
const d = l.measures[u];
|
|
1484
|
+
s[i] = {
|
|
1485
|
+
title: d.title || u,
|
|
1486
|
+
shortTitle: d.title || u,
|
|
1487
|
+
type: d.type
|
|
1226
1488
|
};
|
|
1227
1489
|
}
|
|
1228
1490
|
}
|
|
1229
1491
|
if (t.dimensions)
|
|
1230
|
-
for (const
|
|
1231
|
-
const [c,
|
|
1232
|
-
if (
|
|
1233
|
-
const
|
|
1234
|
-
n[
|
|
1235
|
-
title:
|
|
1236
|
-
shortTitle:
|
|
1237
|
-
type:
|
|
1492
|
+
for (const i of t.dimensions) {
|
|
1493
|
+
const [c, u] = i.split("."), l = a.find((d) => d.name === c);
|
|
1494
|
+
if (l && l.dimensions[u]) {
|
|
1495
|
+
const d = l.dimensions[u];
|
|
1496
|
+
n[i] = {
|
|
1497
|
+
title: d.title || u,
|
|
1498
|
+
shortTitle: d.title || u,
|
|
1499
|
+
type: d.type
|
|
1238
1500
|
};
|
|
1239
1501
|
}
|
|
1240
1502
|
}
|
|
1241
1503
|
if (t.timeDimensions)
|
|
1242
|
-
for (const
|
|
1243
|
-
const [c,
|
|
1244
|
-
if (
|
|
1245
|
-
const
|
|
1246
|
-
r[
|
|
1247
|
-
title:
|
|
1248
|
-
shortTitle:
|
|
1249
|
-
type:
|
|
1250
|
-
granularity:
|
|
1504
|
+
for (const i of t.timeDimensions) {
|
|
1505
|
+
const [c, u] = i.dimension.split("."), l = a.find((d) => d.name === c);
|
|
1506
|
+
if (l && l.dimensions && l.dimensions[u]) {
|
|
1507
|
+
const d = l.dimensions[u];
|
|
1508
|
+
r[i.dimension] = {
|
|
1509
|
+
title: d.title || u,
|
|
1510
|
+
shortTitle: d.title || u,
|
|
1511
|
+
type: d.type,
|
|
1512
|
+
granularity: i.granularity
|
|
1251
1513
|
};
|
|
1252
1514
|
}
|
|
1253
1515
|
}
|
|
1254
1516
|
return {
|
|
1255
|
-
measures:
|
|
1517
|
+
measures: s,
|
|
1256
1518
|
dimensions: n,
|
|
1257
1519
|
segments: {},
|
|
1258
1520
|
timeDimensions: r
|
|
1259
1521
|
};
|
|
1260
1522
|
}
|
|
1261
1523
|
}
|
|
1262
|
-
class
|
|
1524
|
+
class x {
|
|
1263
1525
|
// 5 minutes in milliseconds
|
|
1264
1526
|
constructor(e) {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
e != null && e.databaseExecutor ? this.dbExecutor = e.databaseExecutor : e != null && e.drizzle && (this.dbExecutor =
|
|
1527
|
+
C(this, "cubes", /* @__PURE__ */ new Map());
|
|
1528
|
+
C(this, "dbExecutor");
|
|
1529
|
+
C(this, "metadataCache");
|
|
1530
|
+
C(this, "metadataCacheTimestamp");
|
|
1531
|
+
C(this, "METADATA_CACHE_TTL", 5 * 60 * 1e3);
|
|
1532
|
+
e != null && e.databaseExecutor ? this.dbExecutor = e.databaseExecutor : e != null && e.drizzle && (this.dbExecutor = L(
|
|
1271
1533
|
e.drizzle,
|
|
1272
1534
|
e.schema,
|
|
1273
1535
|
e.engineType
|
|
@@ -1282,8 +1544,8 @@ class F {
|
|
|
1282
1544
|
/**
|
|
1283
1545
|
* Set Drizzle instance and schema directly
|
|
1284
1546
|
*/
|
|
1285
|
-
setDrizzle(e, t,
|
|
1286
|
-
this.dbExecutor =
|
|
1547
|
+
setDrizzle(e, t, s) {
|
|
1548
|
+
this.dbExecutor = L(e, t, s);
|
|
1287
1549
|
}
|
|
1288
1550
|
/**
|
|
1289
1551
|
* Check if database executor is configured
|
|
@@ -1321,7 +1583,7 @@ class F {
|
|
|
1321
1583
|
async execute(e, t) {
|
|
1322
1584
|
if (!this.dbExecutor)
|
|
1323
1585
|
throw new Error("Database executor not configured");
|
|
1324
|
-
return new
|
|
1586
|
+
return new T(this.dbExecutor).execute(this.cubes, e, t);
|
|
1325
1587
|
}
|
|
1326
1588
|
/**
|
|
1327
1589
|
* Execute a multi-cube query
|
|
@@ -1332,10 +1594,10 @@ class F {
|
|
|
1332
1594
|
/**
|
|
1333
1595
|
* Execute a single cube query
|
|
1334
1596
|
*/
|
|
1335
|
-
async executeQuery(e, t,
|
|
1597
|
+
async executeQuery(e, t, s) {
|
|
1336
1598
|
if (!this.cubes.get(e))
|
|
1337
1599
|
throw new Error(`Cube '${e}' not found`);
|
|
1338
|
-
return this.execute(t,
|
|
1600
|
+
return this.execute(t, s);
|
|
1339
1601
|
}
|
|
1340
1602
|
/**
|
|
1341
1603
|
* Get metadata for all cubes (for API responses)
|
|
@@ -1345,7 +1607,7 @@ class F {
|
|
|
1345
1607
|
const e = Date.now();
|
|
1346
1608
|
if (this.metadataCache && this.metadataCacheTimestamp && e - this.metadataCacheTimestamp < this.METADATA_CACHE_TTL)
|
|
1347
1609
|
return this.metadataCache;
|
|
1348
|
-
const t = Array.from(this.cubes.values()).map((
|
|
1610
|
+
const t = Array.from(this.cubes.values()).map((s) => this.generateCubeMetadata(s));
|
|
1349
1611
|
return this.metadataCache = t, this.metadataCacheTimestamp = e, t;
|
|
1350
1612
|
}
|
|
1351
1613
|
/**
|
|
@@ -1353,25 +1615,25 @@ class F {
|
|
|
1353
1615
|
* Optimized version that minimizes object iterations
|
|
1354
1616
|
*/
|
|
1355
1617
|
generateCubeMetadata(e) {
|
|
1356
|
-
const t = Object.keys(e.measures),
|
|
1618
|
+
const t = Object.keys(e.measures), s = Object.keys(e.dimensions), n = new Array(t.length), r = new Array(s.length);
|
|
1357
1619
|
for (let a = 0; a < t.length; a++) {
|
|
1358
|
-
const
|
|
1620
|
+
const i = t[a], c = e.measures[i];
|
|
1359
1621
|
n[a] = {
|
|
1360
|
-
name: `${e.name}.${
|
|
1361
|
-
title: c.title ||
|
|
1362
|
-
shortTitle: c.title ||
|
|
1622
|
+
name: `${e.name}.${i}`,
|
|
1623
|
+
title: c.title || i,
|
|
1624
|
+
shortTitle: c.title || i,
|
|
1363
1625
|
type: c.type,
|
|
1364
1626
|
format: void 0,
|
|
1365
1627
|
// Measure doesn't have format field
|
|
1366
1628
|
description: c.description
|
|
1367
1629
|
};
|
|
1368
1630
|
}
|
|
1369
|
-
for (let a = 0; a <
|
|
1370
|
-
const
|
|
1631
|
+
for (let a = 0; a < s.length; a++) {
|
|
1632
|
+
const i = s[a], c = e.dimensions[i];
|
|
1371
1633
|
r[a] = {
|
|
1372
|
-
name: `${e.name}.${
|
|
1373
|
-
title: c.title ||
|
|
1374
|
-
shortTitle: c.title ||
|
|
1634
|
+
name: `${e.name}.${i}`,
|
|
1635
|
+
title: c.title || i,
|
|
1636
|
+
shortTitle: c.title || i,
|
|
1375
1637
|
type: c.type,
|
|
1376
1638
|
format: void 0,
|
|
1377
1639
|
// Dimension doesn't have format field
|
|
@@ -1391,13 +1653,13 @@ class F {
|
|
|
1391
1653
|
/**
|
|
1392
1654
|
* Get SQL for a query without executing it (debugging)
|
|
1393
1655
|
*/
|
|
1394
|
-
async generateSQL(e, t,
|
|
1656
|
+
async generateSQL(e, t, s) {
|
|
1395
1657
|
const n = this.getCube(e);
|
|
1396
1658
|
if (!n)
|
|
1397
1659
|
throw new Error(`Cube '${e}' not found`);
|
|
1398
1660
|
if (!this.dbExecutor)
|
|
1399
1661
|
throw new Error("Database executor not configured");
|
|
1400
|
-
return new
|
|
1662
|
+
return new T(this.dbExecutor).generateSQL(n, t, s);
|
|
1401
1663
|
}
|
|
1402
1664
|
/**
|
|
1403
1665
|
* Get SQL for a multi-cube query without executing it (debugging)
|
|
@@ -1405,7 +1667,7 @@ class F {
|
|
|
1405
1667
|
async generateMultiCubeSQL(e, t) {
|
|
1406
1668
|
if (!this.dbExecutor)
|
|
1407
1669
|
throw new Error("Database executor not configured");
|
|
1408
|
-
return new
|
|
1670
|
+
return new T(this.dbExecutor).generateMultiCubeSQL(this.cubes, e, t);
|
|
1409
1671
|
}
|
|
1410
1672
|
/**
|
|
1411
1673
|
* Check if a cube exists
|
|
@@ -1448,7 +1710,7 @@ class F {
|
|
|
1448
1710
|
}
|
|
1449
1711
|
}
|
|
1450
1712
|
function Q(o, e) {
|
|
1451
|
-
const t = [],
|
|
1713
|
+
const t = [], s = /* @__PURE__ */ new Set();
|
|
1452
1714
|
if (e.measures)
|
|
1453
1715
|
for (const n of e.measures) {
|
|
1454
1716
|
const [r, a] = n.split(".");
|
|
@@ -1456,13 +1718,13 @@ function Q(o, e) {
|
|
|
1456
1718
|
t.push(`Invalid measure format: ${n}. Expected format: 'CubeName.fieldName'`);
|
|
1457
1719
|
continue;
|
|
1458
1720
|
}
|
|
1459
|
-
|
|
1460
|
-
const
|
|
1461
|
-
if (!
|
|
1721
|
+
s.add(r);
|
|
1722
|
+
const i = o.get(r);
|
|
1723
|
+
if (!i) {
|
|
1462
1724
|
t.push(`Cube '${r}' not found (referenced in measure '${n}')`);
|
|
1463
1725
|
continue;
|
|
1464
1726
|
}
|
|
1465
|
-
|
|
1727
|
+
i.measures[a] || t.push(`Measure '${a}' not found on cube '${r}'`);
|
|
1466
1728
|
}
|
|
1467
1729
|
if (e.dimensions)
|
|
1468
1730
|
for (const n of e.dimensions) {
|
|
@@ -1471,13 +1733,13 @@ function Q(o, e) {
|
|
|
1471
1733
|
t.push(`Invalid dimension format: ${n}. Expected format: 'CubeName.fieldName'`);
|
|
1472
1734
|
continue;
|
|
1473
1735
|
}
|
|
1474
|
-
|
|
1475
|
-
const
|
|
1476
|
-
if (!
|
|
1736
|
+
s.add(r);
|
|
1737
|
+
const i = o.get(r);
|
|
1738
|
+
if (!i) {
|
|
1477
1739
|
t.push(`Cube '${r}' not found (referenced in dimension '${n}')`);
|
|
1478
1740
|
continue;
|
|
1479
1741
|
}
|
|
1480
|
-
|
|
1742
|
+
i.dimensions[a] || t.push(`Dimension '${a}' not found on cube '${r}'`);
|
|
1481
1743
|
}
|
|
1482
1744
|
if (e.timeDimensions)
|
|
1483
1745
|
for (const n of e.timeDimensions) {
|
|
@@ -1486,27 +1748,27 @@ function Q(o, e) {
|
|
|
1486
1748
|
t.push(`Invalid timeDimension format: ${n.dimension}. Expected format: 'CubeName.fieldName'`);
|
|
1487
1749
|
continue;
|
|
1488
1750
|
}
|
|
1489
|
-
|
|
1490
|
-
const
|
|
1491
|
-
if (!
|
|
1751
|
+
s.add(r);
|
|
1752
|
+
const i = o.get(r);
|
|
1753
|
+
if (!i) {
|
|
1492
1754
|
t.push(`Cube '${r}' not found (referenced in timeDimension '${n.dimension}')`);
|
|
1493
1755
|
continue;
|
|
1494
1756
|
}
|
|
1495
|
-
|
|
1757
|
+
i.dimensions[a] || t.push(`TimeDimension '${a}' not found on cube '${r}' (must be a dimension with time type)`);
|
|
1496
1758
|
}
|
|
1497
1759
|
if (e.filters)
|
|
1498
1760
|
for (const n of e.filters)
|
|
1499
|
-
k(n, o, t,
|
|
1500
|
-
return
|
|
1761
|
+
k(n, o, t, s);
|
|
1762
|
+
return s.size === 0 && t.push("Query must reference at least one cube through measures, dimensions, or filters"), {
|
|
1501
1763
|
isValid: t.length === 0,
|
|
1502
1764
|
errors: t
|
|
1503
1765
|
};
|
|
1504
1766
|
}
|
|
1505
|
-
function k(o, e, t,
|
|
1767
|
+
function k(o, e, t, s) {
|
|
1506
1768
|
if ("and" in o || "or" in o) {
|
|
1507
|
-
const
|
|
1508
|
-
for (const c of
|
|
1509
|
-
k(c, e, t,
|
|
1769
|
+
const i = o.and || o.or || [];
|
|
1770
|
+
for (const c of i)
|
|
1771
|
+
k(c, e, t, s);
|
|
1510
1772
|
return;
|
|
1511
1773
|
}
|
|
1512
1774
|
if (!("member" in o)) {
|
|
@@ -1518,7 +1780,7 @@ function k(o, e, t, i) {
|
|
|
1518
1780
|
t.push(`Invalid filter member format: ${o.member}. Expected format: 'CubeName.fieldName'`);
|
|
1519
1781
|
return;
|
|
1520
1782
|
}
|
|
1521
|
-
|
|
1783
|
+
s.add(n);
|
|
1522
1784
|
const a = e.get(n);
|
|
1523
1785
|
if (!a) {
|
|
1524
1786
|
t.push(`Cube '${n}' not found (referenced in filter '${o.member}')`);
|
|
@@ -1526,11 +1788,11 @@ function k(o, e, t, i) {
|
|
|
1526
1788
|
}
|
|
1527
1789
|
!a.dimensions[r] && !a.measures[r] && t.push(`Filter field '${r}' not found on cube '${n}' (must be a dimension or measure)`);
|
|
1528
1790
|
}
|
|
1529
|
-
function
|
|
1530
|
-
return new
|
|
1791
|
+
function ye(o) {
|
|
1792
|
+
return new x(o);
|
|
1531
1793
|
}
|
|
1532
|
-
const
|
|
1533
|
-
function
|
|
1794
|
+
const ce = new x();
|
|
1795
|
+
function ue(o) {
|
|
1534
1796
|
const e = {
|
|
1535
1797
|
valid: !0,
|
|
1536
1798
|
errors: [],
|
|
@@ -1538,7 +1800,7 @@ function re(o) {
|
|
|
1538
1800
|
cubes: []
|
|
1539
1801
|
};
|
|
1540
1802
|
try {
|
|
1541
|
-
const t =
|
|
1803
|
+
const t = Z(o);
|
|
1542
1804
|
if (!t)
|
|
1543
1805
|
return e.valid = !1, e.errors.push("Invalid YAML: empty or malformed content"), e;
|
|
1544
1806
|
if (t.cubes && Array.isArray(t.cubes))
|
|
@@ -1547,8 +1809,8 @@ function re(o) {
|
|
|
1547
1809
|
e.cubes = [t];
|
|
1548
1810
|
else
|
|
1549
1811
|
return e.valid = !1, e.errors.push('YAML must contain either a "cubes" array or cube properties at root level'), e;
|
|
1550
|
-
for (const
|
|
1551
|
-
const n =
|
|
1812
|
+
for (const s of e.cubes) {
|
|
1813
|
+
const n = le(s);
|
|
1552
1814
|
e.errors.push(...n);
|
|
1553
1815
|
}
|
|
1554
1816
|
e.valid = e.errors.length === 0;
|
|
@@ -1557,32 +1819,32 @@ function re(o) {
|
|
|
1557
1819
|
}
|
|
1558
1820
|
return e;
|
|
1559
1821
|
}
|
|
1560
|
-
function
|
|
1822
|
+
function le(o) {
|
|
1561
1823
|
const e = [];
|
|
1562
|
-
return o.name || e.push("Cube name is required"), !o.sql && !o.sql_table && !o.sqlTable && e.push('Cube must have either "sql", "sql_table", or "sqlTable" property'), o.dimensions && o.dimensions.forEach((t,
|
|
1563
|
-
t.name || e.push(`Dimension at index ${
|
|
1564
|
-
}), o.measures && o.measures.forEach((t,
|
|
1565
|
-
t.name || e.push(`Measure at index ${
|
|
1566
|
-
}), o.joins && o.joins.forEach((t,
|
|
1567
|
-
t.name || e.push(`Join at index ${
|
|
1824
|
+
return o.name || e.push("Cube name is required"), !o.sql && !o.sql_table && !o.sqlTable && e.push('Cube must have either "sql", "sql_table", or "sqlTable" property'), o.dimensions && o.dimensions.forEach((t, s) => {
|
|
1825
|
+
t.name || e.push(`Dimension at index ${s} is missing name`), t.type || e.push(`Dimension "${t.name}" is missing type`), t.sql || e.push(`Dimension "${t.name}" is missing sql`);
|
|
1826
|
+
}), o.measures && o.measures.forEach((t, s) => {
|
|
1827
|
+
t.name || e.push(`Measure at index ${s} is missing name`), t.type || e.push(`Measure "${t.name}" is missing type`), t.sql || e.push(`Measure "${t.name}" is missing sql`);
|
|
1828
|
+
}), o.joins && o.joins.forEach((t, s) => {
|
|
1829
|
+
t.name || e.push(`Join at index ${s} is missing name`), t.relationship || e.push(`Join "${t.name}" is missing relationship`), t.sql || e.push(`Join "${t.name}" is missing sql`);
|
|
1568
1830
|
}), e;
|
|
1569
1831
|
}
|
|
1570
|
-
function
|
|
1832
|
+
function de(o) {
|
|
1571
1833
|
const e = {};
|
|
1572
|
-
o.dimensions && o.dimensions.forEach((
|
|
1573
|
-
e[
|
|
1834
|
+
o.dimensions && o.dimensions.forEach((i) => {
|
|
1835
|
+
e[i.name] = me(i);
|
|
1574
1836
|
});
|
|
1575
1837
|
const t = {};
|
|
1576
|
-
o.measures && o.measures.forEach((
|
|
1577
|
-
t[
|
|
1838
|
+
o.measures && o.measures.forEach((i) => {
|
|
1839
|
+
t[i.name] = fe(i);
|
|
1578
1840
|
});
|
|
1579
|
-
const
|
|
1580
|
-
o.joins && o.joins.forEach((
|
|
1581
|
-
i
|
|
1841
|
+
const s = {};
|
|
1842
|
+
o.joins && o.joins.forEach((i) => {
|
|
1843
|
+
s[i.name] = be(i);
|
|
1582
1844
|
});
|
|
1583
1845
|
const n = {};
|
|
1584
1846
|
(o.pre_aggregations || o.preAggregations) && (o.pre_aggregations || o.preAggregations || []).forEach((c) => {
|
|
1585
|
-
n[c.name] =
|
|
1847
|
+
n[c.name] = ge(c);
|
|
1586
1848
|
});
|
|
1587
1849
|
let r = o.sql;
|
|
1588
1850
|
!r && (o.sql_table || o.sqlTable) && (r = `SELECT * FROM ${o.sql_table || o.sqlTable}`);
|
|
@@ -1600,12 +1862,12 @@ function ae(o) {
|
|
|
1600
1862
|
} : void 0,
|
|
1601
1863
|
dimensions: e,
|
|
1602
1864
|
measures: t,
|
|
1603
|
-
joins: Object.keys(
|
|
1865
|
+
joins: Object.keys(s).length > 0 ? s : void 0,
|
|
1604
1866
|
preAggregations: Object.keys(n).length > 0 ? n : void 0,
|
|
1605
1867
|
meta: o.meta
|
|
1606
1868
|
};
|
|
1607
1869
|
}
|
|
1608
|
-
function
|
|
1870
|
+
function me(o) {
|
|
1609
1871
|
return {
|
|
1610
1872
|
name: o.name,
|
|
1611
1873
|
title: o.title,
|
|
@@ -1618,9 +1880,9 @@ function ce(o) {
|
|
|
1618
1880
|
meta: o.meta
|
|
1619
1881
|
};
|
|
1620
1882
|
}
|
|
1621
|
-
function
|
|
1622
|
-
var
|
|
1623
|
-
const e = (
|
|
1883
|
+
function fe(o) {
|
|
1884
|
+
var s;
|
|
1885
|
+
const e = (s = o.filters) == null ? void 0 : s.map((n) => ({
|
|
1624
1886
|
sql: n.sql
|
|
1625
1887
|
})), t = o.rolling_window || o.rollingWindow;
|
|
1626
1888
|
return {
|
|
@@ -1636,7 +1898,7 @@ function le(o) {
|
|
|
1636
1898
|
meta: o.meta
|
|
1637
1899
|
};
|
|
1638
1900
|
}
|
|
1639
|
-
function
|
|
1901
|
+
function he(o) {
|
|
1640
1902
|
switch (o) {
|
|
1641
1903
|
case "one_to_one":
|
|
1642
1904
|
return "hasOne";
|
|
@@ -1648,7 +1910,7 @@ function ue(o) {
|
|
|
1648
1910
|
return "belongsTo";
|
|
1649
1911
|
}
|
|
1650
1912
|
}
|
|
1651
|
-
function
|
|
1913
|
+
function pe(o) {
|
|
1652
1914
|
switch (o) {
|
|
1653
1915
|
case "hasOne":
|
|
1654
1916
|
return "one_to_one";
|
|
@@ -1660,15 +1922,15 @@ function me(o) {
|
|
|
1660
1922
|
return "many_to_one";
|
|
1661
1923
|
}
|
|
1662
1924
|
}
|
|
1663
|
-
function
|
|
1925
|
+
function be(o) {
|
|
1664
1926
|
return {
|
|
1665
1927
|
name: o.name,
|
|
1666
1928
|
type: o.type,
|
|
1667
|
-
relationship:
|
|
1929
|
+
relationship: he(o.relationship),
|
|
1668
1930
|
sql: o.sql
|
|
1669
1931
|
};
|
|
1670
1932
|
}
|
|
1671
|
-
function
|
|
1933
|
+
function ge(o) {
|
|
1672
1934
|
const e = o.time_dimension || o.timeDimension, t = o.refresh_key || o.refreshKey;
|
|
1673
1935
|
return {
|
|
1674
1936
|
name: o.name,
|
|
@@ -1679,7 +1941,7 @@ function de(o) {
|
|
|
1679
1941
|
indexes: o.indexes
|
|
1680
1942
|
};
|
|
1681
1943
|
}
|
|
1682
|
-
async function
|
|
1944
|
+
async function Ce() {
|
|
1683
1945
|
try {
|
|
1684
1946
|
const { promises: o } = await import("fs"), e = await o.readFile("non-existent-file.txt", "utf-8").catch((t) => t.message);
|
|
1685
1947
|
return !(typeof e == "string" && e.includes("not implemented"));
|
|
@@ -1687,29 +1949,29 @@ async function he() {
|
|
|
1687
1949
|
return !1;
|
|
1688
1950
|
}
|
|
1689
1951
|
}
|
|
1690
|
-
function
|
|
1691
|
-
const e =
|
|
1952
|
+
function we(o) {
|
|
1953
|
+
const e = ue(o);
|
|
1692
1954
|
if (!e.valid)
|
|
1693
1955
|
throw new Error(`Invalid YAML cube definition:
|
|
1694
1956
|
${e.errors.join(`
|
|
1695
1957
|
`)}`);
|
|
1696
|
-
return e.cubes.map((t) =>
|
|
1958
|
+
return e.cubes.map((t) => de(t));
|
|
1697
1959
|
}
|
|
1698
|
-
async function
|
|
1699
|
-
if (!await
|
|
1960
|
+
async function Te(o) {
|
|
1961
|
+
if (!await Ce())
|
|
1700
1962
|
return console.log("ℹ️ YAML file loading not supported in this environment (Cloudflare Workers/Edge Runtime). Use inline YAML strings or build-time transformations instead."), [];
|
|
1701
1963
|
try {
|
|
1702
|
-
const { promises: t } = await import("fs"),
|
|
1703
|
-
return
|
|
1964
|
+
const { promises: t } = await import("fs"), s = await t.readFile(o, "utf-8");
|
|
1965
|
+
return we(s);
|
|
1704
1966
|
} catch (t) {
|
|
1705
1967
|
return console.log(`ℹ️ Could not load YAML file ${o}:`, t instanceof Error ? t.message : t), [];
|
|
1706
1968
|
}
|
|
1707
1969
|
}
|
|
1708
|
-
function
|
|
1970
|
+
function Se(o) {
|
|
1709
1971
|
let e = o;
|
|
1710
1972
|
return e = e.replace(/\{CUBE\}/g, "${CUBE}"), e = e.replace(/\{([A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_]*)\}/g, "${$1}"), e = e.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g, "${$1}"), e = e.replace(/\$\$\{/g, "${"), e;
|
|
1711
1973
|
}
|
|
1712
|
-
function
|
|
1974
|
+
function xe(o) {
|
|
1713
1975
|
const e = {
|
|
1714
1976
|
name: o.name,
|
|
1715
1977
|
title: o.title,
|
|
@@ -1727,7 +1989,7 @@ function ye(o) {
|
|
|
1727
1989
|
meta: t.meta
|
|
1728
1990
|
})),
|
|
1729
1991
|
measures: Object.values(o.measures).map((t) => {
|
|
1730
|
-
var
|
|
1992
|
+
var s;
|
|
1731
1993
|
return {
|
|
1732
1994
|
name: t.name,
|
|
1733
1995
|
title: t.title,
|
|
@@ -1736,7 +1998,7 @@ function ye(o) {
|
|
|
1736
1998
|
sql: typeof t.sql == "string" ? t.sql : "",
|
|
1737
1999
|
format: t.format,
|
|
1738
2000
|
shown: t.shown,
|
|
1739
|
-
filters: (
|
|
2001
|
+
filters: (s = t.filters) == null ? void 0 : s.map((n) => ({
|
|
1740
2002
|
sql: typeof n.sql == "string" ? n.sql : ""
|
|
1741
2003
|
})),
|
|
1742
2004
|
rolling_window: t.rollingWindow,
|
|
@@ -1746,33 +2008,33 @@ function ye(o) {
|
|
|
1746
2008
|
joins: o.joins ? Object.values(o.joins).map((t) => ({
|
|
1747
2009
|
name: t.name || "",
|
|
1748
2010
|
type: t.type,
|
|
1749
|
-
relationship:
|
|
2011
|
+
relationship: pe(t.relationship),
|
|
1750
2012
|
sql: typeof t.sql == "string" ? t.sql : ""
|
|
1751
2013
|
})) : void 0,
|
|
1752
2014
|
meta: o.meta
|
|
1753
2015
|
};
|
|
1754
|
-
return
|
|
2016
|
+
return X(e, {
|
|
1755
2017
|
indent: 2,
|
|
1756
2018
|
lineWidth: 120,
|
|
1757
2019
|
minContentWidth: 40
|
|
1758
2020
|
});
|
|
1759
2021
|
}
|
|
1760
|
-
const
|
|
1761
|
-
function
|
|
1762
|
-
return new
|
|
2022
|
+
const Fe = ce;
|
|
2023
|
+
function Me(o) {
|
|
2024
|
+
return new x({
|
|
1763
2025
|
drizzle: o.drizzle,
|
|
1764
2026
|
schema: o.schema
|
|
1765
2027
|
});
|
|
1766
2028
|
}
|
|
1767
|
-
const
|
|
2029
|
+
const Le = {
|
|
1768
2030
|
/**
|
|
1769
2031
|
* Create a simple query builder
|
|
1770
2032
|
*/
|
|
1771
2033
|
query: () => {
|
|
1772
|
-
const o = (e, t = [],
|
|
2034
|
+
const o = (e, t = [], s = [], n = [], r, a) => ({
|
|
1773
2035
|
measures: e,
|
|
1774
2036
|
dimensions: t,
|
|
1775
|
-
filters:
|
|
2037
|
+
filters: s,
|
|
1776
2038
|
timeDimensions: n,
|
|
1777
2039
|
limit: r,
|
|
1778
2040
|
order: a
|
|
@@ -1780,64 +2042,64 @@ const Ae = {
|
|
|
1780
2042
|
return {
|
|
1781
2043
|
measures: (e) => ({
|
|
1782
2044
|
dimensions: (t = []) => ({
|
|
1783
|
-
filters: (
|
|
2045
|
+
filters: (s = []) => ({
|
|
1784
2046
|
timeDimensions: (n = []) => ({
|
|
1785
2047
|
limit: (r) => ({
|
|
1786
|
-
order: (a) => o(e, t,
|
|
2048
|
+
order: (a) => o(e, t, s, n, r, a)
|
|
1787
2049
|
}),
|
|
1788
|
-
order: (r) => o(e, t,
|
|
2050
|
+
order: (r) => o(e, t, s, n, void 0, r)
|
|
1789
2051
|
}),
|
|
1790
2052
|
limit: (n) => ({
|
|
1791
|
-
order: (r) => o(e, t,
|
|
2053
|
+
order: (r) => o(e, t, s, [], n, r)
|
|
1792
2054
|
}),
|
|
1793
|
-
order: (n) => o(e, t,
|
|
2055
|
+
order: (n) => o(e, t, s, [], void 0, n)
|
|
1794
2056
|
}),
|
|
1795
|
-
timeDimensions: (
|
|
2057
|
+
timeDimensions: (s = []) => ({
|
|
1796
2058
|
filters: (n = []) => ({
|
|
1797
2059
|
limit: (r) => ({
|
|
1798
|
-
order: (a) => o(e, t, n,
|
|
2060
|
+
order: (a) => o(e, t, n, s, r, a)
|
|
1799
2061
|
}),
|
|
1800
|
-
order: (r) => o(e, t, n,
|
|
2062
|
+
order: (r) => o(e, t, n, s, void 0, r)
|
|
1801
2063
|
}),
|
|
1802
2064
|
limit: (n) => ({
|
|
1803
|
-
order: (r) => o(e, t, [],
|
|
2065
|
+
order: (r) => o(e, t, [], s, n, r)
|
|
1804
2066
|
}),
|
|
1805
|
-
order: (n) => o(e, t, [],
|
|
2067
|
+
order: (n) => o(e, t, [], s, void 0, n)
|
|
1806
2068
|
}),
|
|
1807
|
-
limit: (
|
|
1808
|
-
order: (n) => o(e, t, [], [],
|
|
2069
|
+
limit: (s) => ({
|
|
2070
|
+
order: (n) => o(e, t, [], [], s, n)
|
|
1809
2071
|
}),
|
|
1810
|
-
order: (
|
|
2072
|
+
order: (s) => o(e, t, [], [], void 0, s)
|
|
1811
2073
|
}),
|
|
1812
2074
|
filters: (t = []) => ({
|
|
1813
|
-
dimensions: (
|
|
2075
|
+
dimensions: (s = []) => ({
|
|
1814
2076
|
timeDimensions: (n = []) => ({
|
|
1815
2077
|
limit: (r) => ({
|
|
1816
|
-
order: (a) => o(e,
|
|
2078
|
+
order: (a) => o(e, s, t, n, r, a)
|
|
1817
2079
|
}),
|
|
1818
|
-
order: (r) => o(e,
|
|
2080
|
+
order: (r) => o(e, s, t, n, void 0, r)
|
|
1819
2081
|
}),
|
|
1820
2082
|
limit: (n) => ({
|
|
1821
|
-
order: (r) => o(e,
|
|
2083
|
+
order: (r) => o(e, s, t, [], n, r)
|
|
1822
2084
|
}),
|
|
1823
|
-
order: (n) => o(e,
|
|
2085
|
+
order: (n) => o(e, s, t, [], void 0, n)
|
|
1824
2086
|
}),
|
|
1825
|
-
timeDimensions: (
|
|
2087
|
+
timeDimensions: (s = []) => ({
|
|
1826
2088
|
dimensions: (n = []) => ({
|
|
1827
2089
|
limit: (r) => ({
|
|
1828
|
-
order: (a) => o(e, n, t,
|
|
2090
|
+
order: (a) => o(e, n, t, s, r, a)
|
|
1829
2091
|
}),
|
|
1830
|
-
order: (r) => o(e, n, t,
|
|
2092
|
+
order: (r) => o(e, n, t, s, void 0, r)
|
|
1831
2093
|
}),
|
|
1832
2094
|
limit: (n) => ({
|
|
1833
|
-
order: (r) => o(e, [], t,
|
|
2095
|
+
order: (r) => o(e, [], t, s, n, r)
|
|
1834
2096
|
}),
|
|
1835
|
-
order: (n) => o(e, [], t,
|
|
2097
|
+
order: (n) => o(e, [], t, s, void 0, n)
|
|
1836
2098
|
}),
|
|
1837
|
-
limit: (
|
|
1838
|
-
order: (n) => o(e, [], t, [],
|
|
2099
|
+
limit: (s) => ({
|
|
2100
|
+
order: (n) => o(e, [], t, [], s, n)
|
|
1839
2101
|
}),
|
|
1840
|
-
order: (
|
|
2102
|
+
order: (s) => o(e, [], t, [], void 0, s)
|
|
1841
2103
|
})
|
|
1842
2104
|
})
|
|
1843
2105
|
};
|
|
@@ -1871,30 +2133,30 @@ const Ae = {
|
|
|
1871
2133
|
}
|
|
1872
2134
|
};
|
|
1873
2135
|
export {
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
2136
|
+
S as BaseDatabaseExecutor,
|
|
2137
|
+
ae as MultiCubeBuilder,
|
|
2138
|
+
ie as MySQLExecutor,
|
|
2139
|
+
ne as PostgresExecutor,
|
|
2140
|
+
T as QueryExecutor,
|
|
2141
|
+
se as SQLiteExecutor,
|
|
2142
|
+
x as SemanticLayerCompiler,
|
|
2143
|
+
Le as SemanticLayerUtils,
|
|
2144
|
+
Se as convertCubeReferences,
|
|
2145
|
+
L as createDatabaseExecutor,
|
|
2146
|
+
Me as createDrizzleSemanticLayer,
|
|
2147
|
+
oe as createMultiCubeContext,
|
|
2148
|
+
re as createMySQLExecutor,
|
|
2149
|
+
F as createPostgresExecutor,
|
|
1888
2150
|
M as createSQLiteExecutor,
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
2151
|
+
ye as createSemanticLayer,
|
|
2152
|
+
Fe as defaultSemanticLayer,
|
|
2153
|
+
Ee as defineCube,
|
|
2154
|
+
$e as defineLegacyCube,
|
|
2155
|
+
we as loadYamlCubes,
|
|
2156
|
+
Te as loadYamlCubesFromFile,
|
|
2157
|
+
ue as parseYamlCubes,
|
|
1896
2158
|
b as resolveSqlExpression,
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
2159
|
+
xe as semanticCubeToYaml,
|
|
2160
|
+
ce as semanticLayer,
|
|
2161
|
+
de as yamlCubeToSemanticCube
|
|
1900
2162
|
};
|