@malloydata/malloy 0.0.334 → 0.0.336
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/CONTEXT.md +4 -3
- package/MALLOY_API.md +129 -0
- package/dist/annotation.d.ts +0 -2
- package/dist/annotation.js +29 -23
- package/dist/api/asynchronous.d.ts +1 -1
- package/dist/api/foundation/cache.d.ts +32 -0
- package/dist/api/foundation/cache.js +92 -0
- package/dist/api/foundation/compile.d.ts +175 -0
- package/dist/api/foundation/compile.js +391 -0
- package/dist/api/foundation/core.d.ts +493 -0
- package/dist/api/foundation/core.js +1247 -0
- package/dist/api/foundation/document.d.ts +167 -0
- package/dist/api/foundation/document.js +206 -0
- package/dist/api/foundation/index.d.ts +10 -0
- package/dist/api/foundation/index.js +77 -0
- package/dist/api/foundation/readers.d.ts +53 -0
- package/dist/api/foundation/readers.js +134 -0
- package/dist/api/foundation/result.d.ts +185 -0
- package/dist/api/foundation/result.js +704 -0
- package/dist/api/foundation/runtime.d.ts +361 -0
- package/dist/api/foundation/runtime.js +733 -0
- package/dist/api/foundation/types.d.ts +54 -0
- package/dist/api/foundation/types.js +7 -0
- package/dist/api/foundation/writers.d.ts +42 -0
- package/dist/api/foundation/writers.js +230 -0
- package/dist/api/util.d.ts +1 -1
- package/dist/connection/base_connection.d.ts +5 -0
- package/dist/connection/types.d.ts +5 -0
- package/dist/dialect/duckdb/duckdb.js +2 -1
- package/dist/dialect/snowflake/snowflake.js +7 -1
- package/dist/dialect/trino/trino.js +7 -2
- package/dist/index.d.ts +6 -3
- package/dist/index.js +30 -26
- package/dist/lang/ast/error-factory.js +3 -5
- package/dist/lang/ast/expressions/expr-count-distinct.js +7 -1
- package/dist/lang/ast/expressions/expr-granular-time.js +1 -1
- package/dist/lang/ast/expressions/expr-max.js +7 -1
- package/dist/lang/ast/expressions/expr-min.js +7 -1
- package/dist/lang/ast/expressions/for-range.js +1 -1
- package/dist/lang/ast/source-elements/query-source.js +2 -7
- package/dist/lang/ast/source-elements/refined-source.js +11 -1
- package/dist/lang/ast/source-elements/sql-source.d.ts +1 -1
- package/dist/lang/ast/source-elements/sql-source.js +18 -3
- package/dist/lang/ast/sql-elements/sql-string.d.ts +2 -2
- package/dist/lang/ast/sql-elements/sql-string.js +18 -1
- package/dist/lang/ast/statements/define-source.js +7 -2
- package/dist/lang/ast/statements/import-statement.js +53 -21
- package/dist/lang/ast/types/document-compile-result.d.ts +1 -0
- package/dist/lang/ast/types/expression-def.js +1 -1
- package/dist/lang/ast/types/malloy-element.d.ts +3 -1
- package/dist/lang/ast/types/malloy-element.js +23 -7
- package/dist/lang/malloy-to-ast.d.ts +1 -1
- package/dist/lang/malloy-to-ast.js +1 -1
- package/dist/lang/parse-malloy.d.ts +3 -2
- package/dist/lang/parse-malloy.js +14 -25
- package/dist/lang/test/test-translator.d.ts +9 -2
- package/dist/lang/test/test-translator.js +103 -77
- package/dist/lang/translate-response.d.ts +1 -0
- package/dist/model/constant_expression_compiler.js +6 -7
- package/dist/model/index.d.ts +3 -1
- package/dist/model/index.js +15 -9
- package/dist/model/malloy_types.d.ts +89 -15
- package/dist/model/malloy_types.js +12 -0
- package/dist/model/persist_utils.d.ts +47 -0
- package/dist/model/persist_utils.js +257 -0
- package/dist/model/query_model_impl.d.ts +2 -4
- package/dist/model/query_model_impl.js +5 -13
- package/dist/model/query_node.d.ts +1 -2
- package/dist/model/query_node.js +3 -13
- package/dist/model/query_query.d.ts +17 -1
- package/dist/model/query_query.js +81 -36
- package/dist/model/source_def_utils.d.ts +50 -0
- package/dist/model/source_def_utils.js +154 -0
- package/dist/model/sql_block.d.ts +5 -1
- package/dist/model/sql_block.js +29 -4
- package/dist/model/sql_compiled.d.ts +29 -0
- package/dist/model/sql_compiled.js +102 -0
- package/dist/model/stage_writer.d.ts +1 -3
- package/dist/model/stage_writer.js +7 -25
- package/dist/model/utils.d.ts +20 -1
- package/dist/model/utils.js +40 -0
- package/dist/run_sql_options.d.ts +0 -1
- package/dist/taggable.d.ts +10 -0
- package/dist/taggable.js +7 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -4
- package/dist/malloy.d.ts +0 -1365
- package/dist/malloy.js +0 -3421
- package/dist/model/materialization/utils.d.ts +0 -3
- package/dist/model/materialization/utils.js +0 -41
|
@@ -0,0 +1,733 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Contributors to the Malloy project
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ExploreMaterializer = exports.PreparedResultMaterializer = exports.QueryMaterializer = exports.ModelMaterializer = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.Runtime = void 0;
|
|
8
|
+
const model_1 = require("../../model");
|
|
9
|
+
const dialect_1 = require("../../dialect");
|
|
10
|
+
const row_data_utils_1 = require("../../api/row_data_utils");
|
|
11
|
+
const readers_1 = require("./readers");
|
|
12
|
+
const core_1 = require("./core");
|
|
13
|
+
const compile_1 = require("./compile");
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// FluentState Base Class
|
|
16
|
+
// =============================================================================
|
|
17
|
+
class FluentState {
|
|
18
|
+
constructor(runtime, materialize) {
|
|
19
|
+
this.runtime = runtime;
|
|
20
|
+
this._materialize = materialize;
|
|
21
|
+
}
|
|
22
|
+
materialize() {
|
|
23
|
+
if (this.materialized === undefined) {
|
|
24
|
+
return this.rematerialize();
|
|
25
|
+
}
|
|
26
|
+
return this.materialized;
|
|
27
|
+
}
|
|
28
|
+
rematerialize() {
|
|
29
|
+
this.materialized = this._materialize();
|
|
30
|
+
return this.materialized;
|
|
31
|
+
}
|
|
32
|
+
makeQueryMaterializer(materialize, options) {
|
|
33
|
+
return new QueryMaterializer(this.runtime, materialize, options);
|
|
34
|
+
}
|
|
35
|
+
makeExploreMaterializer(materialize, options) {
|
|
36
|
+
return new ExploreMaterializer(this.runtime, materialize, options);
|
|
37
|
+
}
|
|
38
|
+
makePreparedResultMaterializer(materialize) {
|
|
39
|
+
return new PreparedResultMaterializer(this.runtime, materialize);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// Runtime
|
|
44
|
+
// =============================================================================
|
|
45
|
+
/**
|
|
46
|
+
* An environment for compiling and running Malloy queries.
|
|
47
|
+
*/
|
|
48
|
+
class Runtime {
|
|
49
|
+
constructor({ urlReader, connections, connection, eventStream, cacheManager, }) {
|
|
50
|
+
this.isTestRuntime = false;
|
|
51
|
+
if (connections === undefined) {
|
|
52
|
+
if (connection === undefined) {
|
|
53
|
+
throw new Error('A LookupConnection<Connection> or Connection is required.');
|
|
54
|
+
}
|
|
55
|
+
connections = {
|
|
56
|
+
lookupConnection: () => Promise.resolve(connection),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (urlReader === undefined) {
|
|
60
|
+
urlReader = new readers_1.EmptyURLReader();
|
|
61
|
+
}
|
|
62
|
+
this._urlReader = urlReader;
|
|
63
|
+
this._connections = connections;
|
|
64
|
+
this._eventStream = eventStream;
|
|
65
|
+
this._cacheManager = cacheManager;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* @return The `CacheManager` for this runtime instance.
|
|
69
|
+
*/
|
|
70
|
+
get cacheManager() {
|
|
71
|
+
return this._cacheManager;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* @return The `URLReader` for this runtime instance.
|
|
75
|
+
*/
|
|
76
|
+
get urlReader() {
|
|
77
|
+
return this._urlReader;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* @return The `LookupConnection<Connection>` for this runtime instance.
|
|
81
|
+
*/
|
|
82
|
+
get connections() {
|
|
83
|
+
return this._connections;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* @return The `EventStream` for this runtime instance.
|
|
87
|
+
*/
|
|
88
|
+
get eventStream() {
|
|
89
|
+
return this._eventStream;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Load a Malloy model by URL or contents.
|
|
93
|
+
*
|
|
94
|
+
* @param source The model URL or contents to load and (eventually) compile.
|
|
95
|
+
* @return A `ModelMaterializer` capable of materializing the requested model,
|
|
96
|
+
* or loading further related objects.
|
|
97
|
+
*/
|
|
98
|
+
loadModel(source, options) {
|
|
99
|
+
const { refreshSchemaCache, noThrowOnError } = options || {};
|
|
100
|
+
if (this.isTestRuntime) {
|
|
101
|
+
if (options === undefined) {
|
|
102
|
+
options = { testEnvironment: true };
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
options = { ...options, testEnvironment: true };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const compilable = source instanceof URL ? { url: source } : { source };
|
|
109
|
+
return new ModelMaterializer(this, async () => {
|
|
110
|
+
return compile_1.Malloy.compile({
|
|
111
|
+
...compilable,
|
|
112
|
+
urlReader: this.urlReader,
|
|
113
|
+
connections: this.connections,
|
|
114
|
+
refreshSchemaCache,
|
|
115
|
+
noThrowOnError,
|
|
116
|
+
eventStream: this.eventStream,
|
|
117
|
+
importBaseURL: options === null || options === void 0 ? void 0 : options.importBaseURL,
|
|
118
|
+
testEnvironment: options === null || options === void 0 ? void 0 : options.testEnvironment,
|
|
119
|
+
cacheManager: this.cacheManager,
|
|
120
|
+
});
|
|
121
|
+
}, options);
|
|
122
|
+
}
|
|
123
|
+
// TODO Consider formalizing this. Perhaps as a `withModel` method,
|
|
124
|
+
// as well as a `Model.fromModelDefinition` if we choose to expose
|
|
125
|
+
// `ModelDef` to the world formally. For now, this should only
|
|
126
|
+
// be used in tests.
|
|
127
|
+
_loadModelFromModelDef(modelDef, options) {
|
|
128
|
+
return new ModelMaterializer(this, async () => {
|
|
129
|
+
return new core_1.Model(modelDef, [], []);
|
|
130
|
+
}, options);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Load a Malloy query by URL or contents.
|
|
134
|
+
*
|
|
135
|
+
* @param query The query URL or contents to load and (eventually) compile.
|
|
136
|
+
* @return A `QueryMaterializer` capable of materializing the requested query, running it,
|
|
137
|
+
* or loading further related objects.
|
|
138
|
+
*/
|
|
139
|
+
loadQuery(query, options) {
|
|
140
|
+
return this.loadModel(query, options).loadFinalQuery();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Load a Malloy query by the URL or contents of a Malloy model document
|
|
144
|
+
* and the index of an unnamed query contained in the model.
|
|
145
|
+
*
|
|
146
|
+
* @param model The model URL or contents to load and (eventually) compile to retrieve the requested query.
|
|
147
|
+
* @param index The index of the query to use within the model.
|
|
148
|
+
* @return A `QueryMaterializer` capable of materializing the requested query, running it,
|
|
149
|
+
* or loading further related objects.
|
|
150
|
+
*/
|
|
151
|
+
loadQueryByIndex(model, index, options) {
|
|
152
|
+
return this.loadModel(model, options).loadQueryByIndex(index, options);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Load a Malloy query by the URL or contents of a Malloy model document
|
|
156
|
+
* and the name of a query contained in the model.
|
|
157
|
+
*
|
|
158
|
+
* @param model The model URL or contents to load and (eventually) compile to retrieve the requested query.
|
|
159
|
+
* @param name The name of the query to use within the model.
|
|
160
|
+
* @return A `QueryMaterializer` capable of materializing the requested query, running it,
|
|
161
|
+
* or loading further related objects.
|
|
162
|
+
*/
|
|
163
|
+
loadQueryByName(model, name, options) {
|
|
164
|
+
return this.loadModel(model, options).loadQueryByName(name, options);
|
|
165
|
+
}
|
|
166
|
+
// TODO maybe use overloads for the alternative parameters
|
|
167
|
+
/**
|
|
168
|
+
* Compile a Malloy model by URL or contents.
|
|
169
|
+
*
|
|
170
|
+
* @param source The URL or contents of a Malloy model document to compile.
|
|
171
|
+
* @return A promise of a compiled `Model`.
|
|
172
|
+
*/
|
|
173
|
+
getModel(source, options) {
|
|
174
|
+
return this.loadModel(source, options).getModel();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Compile a Malloy query by URL or contents.
|
|
178
|
+
*
|
|
179
|
+
* @param query The URL or contents of a Malloy query document to compile.
|
|
180
|
+
* @return A promise of a compiled `PreparedQuery`.
|
|
181
|
+
*/
|
|
182
|
+
getQuery(query, options) {
|
|
183
|
+
return this.loadQuery(query, options).getPreparedQuery();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Compile a Malloy query by the URL or contents of a model document
|
|
187
|
+
* and the index of an unnamed query contained within the model.
|
|
188
|
+
*
|
|
189
|
+
* @param model The URL or contents of a Malloy model document to compile.
|
|
190
|
+
* @param index The index of an unnamed query contained within the model.
|
|
191
|
+
* @return A promise of a compiled `PreparedQuery`.
|
|
192
|
+
*/
|
|
193
|
+
getQueryByIndex(model, index, options) {
|
|
194
|
+
return this.loadQueryByIndex(model, index, options).getPreparedQuery();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Compile a Malloy query by the URL or contents of a model document
|
|
198
|
+
* and the name of a query contained within the model.
|
|
199
|
+
*
|
|
200
|
+
* @param model The URL or contents of a Malloy model document to compile.
|
|
201
|
+
* @param name The name of a query contained within the model.
|
|
202
|
+
* @return A promise of a compiled `PreparedQuery`.
|
|
203
|
+
*/
|
|
204
|
+
getQueryByName(model, name, options) {
|
|
205
|
+
return this.loadQueryByName(model, name, options).getPreparedQuery();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
exports.Runtime = Runtime;
|
|
209
|
+
// =============================================================================
|
|
210
|
+
// ConnectionRuntime and SingleConnectionRuntime
|
|
211
|
+
// =============================================================================
|
|
212
|
+
class ConnectionRuntime extends Runtime {
|
|
213
|
+
constructor({ urlReader, connections, }) {
|
|
214
|
+
super({
|
|
215
|
+
connections: readers_1.FixedConnectionMap.fromArray(connections),
|
|
216
|
+
urlReader,
|
|
217
|
+
});
|
|
218
|
+
this.rawConnections = connections;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
exports.ConnectionRuntime = ConnectionRuntime;
|
|
222
|
+
class SingleConnectionRuntime extends Runtime {
|
|
223
|
+
constructor({ urlReader, connection, eventStream, cacheManager, }) {
|
|
224
|
+
super({
|
|
225
|
+
urlReader,
|
|
226
|
+
eventStream,
|
|
227
|
+
cacheManager,
|
|
228
|
+
connection,
|
|
229
|
+
});
|
|
230
|
+
this.connection = connection;
|
|
231
|
+
}
|
|
232
|
+
get supportsNesting() {
|
|
233
|
+
return (0, dialect_1.getDialect)(this.connection.dialectName).supportsNesting;
|
|
234
|
+
}
|
|
235
|
+
// quote a column name
|
|
236
|
+
quote(column) {
|
|
237
|
+
return (0, dialect_1.getDialect)(this.connection.dialectName).sqlMaybeQuoteIdentifier(column);
|
|
238
|
+
}
|
|
239
|
+
get dialect() {
|
|
240
|
+
return (0, dialect_1.getDialect)(this.connection.dialectName);
|
|
241
|
+
}
|
|
242
|
+
getQuoter() {
|
|
243
|
+
return (x) => this.quote(x.toString());
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.SingleConnectionRuntime = SingleConnectionRuntime;
|
|
247
|
+
// =============================================================================
|
|
248
|
+
// ModelMaterializer
|
|
249
|
+
// =============================================================================
|
|
250
|
+
/**
|
|
251
|
+
* An object representing the task of loading a `Model`, capable of
|
|
252
|
+
* materializing that model (via `getModel()`) or extending the task to load
|
|
253
|
+
* queries or explores (via e.g. `loadFinalQuery()`, `loadQuery`, `loadExploreByName`, etc.).
|
|
254
|
+
*/
|
|
255
|
+
class ModelMaterializer extends FluentState {
|
|
256
|
+
constructor(runtime, materialize, options) {
|
|
257
|
+
super(runtime, materialize);
|
|
258
|
+
this.runtime = runtime;
|
|
259
|
+
this.compileQueryOptions = options;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Load the final (unnamed) Malloy query contained within this loaded `Model`.
|
|
263
|
+
*
|
|
264
|
+
* @return A `QueryMaterializer` capable of materializing the requested query, running it,
|
|
265
|
+
* or loading further related objects.
|
|
266
|
+
*/
|
|
267
|
+
loadFinalQuery(options) {
|
|
268
|
+
return this.makeQueryMaterializer(async () => {
|
|
269
|
+
return (await this.materialize()).getPreparedQuery();
|
|
270
|
+
}, {
|
|
271
|
+
...this.compileQueryOptions,
|
|
272
|
+
...options,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Load an unnamed query contained within this loaded `Model` by index.
|
|
277
|
+
*
|
|
278
|
+
* @param index The index of the query to load.
|
|
279
|
+
* @return A `QueryMaterializer` capable of materializing the requested query, running it,
|
|
280
|
+
* or loading further related objects.
|
|
281
|
+
*/
|
|
282
|
+
loadQueryByIndex(index, options) {
|
|
283
|
+
return this.makeQueryMaterializer(async () => {
|
|
284
|
+
return (await this.materialize()).getPreparedQueryByIndex(index);
|
|
285
|
+
}, {
|
|
286
|
+
...this.compileQueryOptions,
|
|
287
|
+
...options,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Load a query contained within this loaded `Model` by its name.
|
|
292
|
+
*
|
|
293
|
+
* @param name The name of the query to load.
|
|
294
|
+
* @return A `QueryMaterializer` capable of materializing the requested query, running it,
|
|
295
|
+
* or loading further related objects.
|
|
296
|
+
*/
|
|
297
|
+
loadQueryByName(name, options) {
|
|
298
|
+
return this.makeQueryMaterializer(async () => {
|
|
299
|
+
return (await this.materialize()).getPreparedQueryByName(name);
|
|
300
|
+
}, {
|
|
301
|
+
...this.compileQueryOptions,
|
|
302
|
+
...options,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Load a query against this loaded `Model` by its URL or contents.
|
|
307
|
+
*
|
|
308
|
+
* @param query The URL or contents of the query to load and (eventually) compile.
|
|
309
|
+
* @return A `QueryMaterializer` capable of materializing the requested query, running it,
|
|
310
|
+
* or loading further related objects.
|
|
311
|
+
*/
|
|
312
|
+
loadQuery(query, options) {
|
|
313
|
+
const { refreshSchemaCache, noThrowOnError } = options || {};
|
|
314
|
+
return this.makeQueryMaterializer(async () => {
|
|
315
|
+
const urlReader = this.runtime.urlReader;
|
|
316
|
+
const connections = this.runtime.connections;
|
|
317
|
+
if (this.runtime.isTestRuntime) {
|
|
318
|
+
if (options === undefined) {
|
|
319
|
+
options = { testEnvironment: true };
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
options = { ...options, testEnvironment: true };
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const compilable = query instanceof URL ? { url: query } : { source: query };
|
|
326
|
+
const model = await this.getModel();
|
|
327
|
+
const queryModel = await compile_1.Malloy.compile({
|
|
328
|
+
...compilable,
|
|
329
|
+
urlReader,
|
|
330
|
+
connections,
|
|
331
|
+
model,
|
|
332
|
+
refreshSchemaCache,
|
|
333
|
+
noThrowOnError,
|
|
334
|
+
importBaseURL: options === null || options === void 0 ? void 0 : options.importBaseURL,
|
|
335
|
+
testEnvironment: options === null || options === void 0 ? void 0 : options.testEnvironment,
|
|
336
|
+
...this.compileQueryOptions,
|
|
337
|
+
});
|
|
338
|
+
return queryModel.preparedQuery;
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Extend a Malloy model by URL or contents.
|
|
343
|
+
*
|
|
344
|
+
* @param source The model URL or contents to load and (eventually) compile.
|
|
345
|
+
* @return A `ModelMaterializer` capable of materializing the requested model,
|
|
346
|
+
* or loading further related objects.
|
|
347
|
+
*/
|
|
348
|
+
extendModel(query, options) {
|
|
349
|
+
if (this.runtime.isTestRuntime) {
|
|
350
|
+
if (options === undefined) {
|
|
351
|
+
options = { testEnvironment: true };
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
options = { ...options, testEnvironment: true };
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return new ModelMaterializer(this.runtime, async () => {
|
|
358
|
+
const urlReader = this.runtime.urlReader;
|
|
359
|
+
const connections = this.runtime.connections;
|
|
360
|
+
const compilable = query instanceof URL ? { url: query } : { source: query };
|
|
361
|
+
const model = await this.getModel();
|
|
362
|
+
const queryModel = await compile_1.Malloy.compile({
|
|
363
|
+
...compilable,
|
|
364
|
+
urlReader,
|
|
365
|
+
connections,
|
|
366
|
+
model,
|
|
367
|
+
refreshSchemaCache: options === null || options === void 0 ? void 0 : options.refreshSchemaCache,
|
|
368
|
+
noThrowOnError: options === null || options === void 0 ? void 0 : options.noThrowOnError,
|
|
369
|
+
importBaseURL: options === null || options === void 0 ? void 0 : options.importBaseURL,
|
|
370
|
+
testEnvironment: options === null || options === void 0 ? void 0 : options.testEnvironment,
|
|
371
|
+
...this.compileQueryOptions,
|
|
372
|
+
});
|
|
373
|
+
return queryModel;
|
|
374
|
+
}, options);
|
|
375
|
+
}
|
|
376
|
+
async search(sourceName, searchTerm, limit = 1000, searchField = undefined) {
|
|
377
|
+
const model = await this.materialize();
|
|
378
|
+
const queryModel = model.queryModel;
|
|
379
|
+
const schema = model.getExploreByName(sourceName).structDef;
|
|
380
|
+
if (!(0, model_1.isSourceDef)(schema)) {
|
|
381
|
+
throw new Error('Source to be searched was unexpectedly, not a source');
|
|
382
|
+
}
|
|
383
|
+
const connectionName = schema.connection;
|
|
384
|
+
const connection = await this.runtime.connections.lookupConnection(connectionName);
|
|
385
|
+
return await queryModel.searchIndex(connection, sourceName, searchTerm, limit, searchField);
|
|
386
|
+
}
|
|
387
|
+
async searchValueMap(sourceName, limit = 10, options) {
|
|
388
|
+
const model = await this.materialize();
|
|
389
|
+
const schema = model.getExploreByName(sourceName);
|
|
390
|
+
if (!(0, model_1.isSourceDef)(schema.structDef)) {
|
|
391
|
+
throw new Error('Source to be searched was unexpectedly, not a source');
|
|
392
|
+
}
|
|
393
|
+
let indexQuery = '{index: *}';
|
|
394
|
+
if (schema.getFieldByNameIfExists('search_index')) {
|
|
395
|
+
indexQuery = 'search_index';
|
|
396
|
+
}
|
|
397
|
+
const searchMapMalloy = `
|
|
398
|
+
run: ${sourceName}
|
|
399
|
+
-> ${indexQuery}
|
|
400
|
+
-> {
|
|
401
|
+
where: fieldType = 'string'
|
|
402
|
+
group_by: fieldName
|
|
403
|
+
aggregate: cardinality is count(fieldValue)
|
|
404
|
+
nest: values is {
|
|
405
|
+
group_by: fieldValue, weight
|
|
406
|
+
order_by: weight desc
|
|
407
|
+
limit: ${limit}
|
|
408
|
+
}
|
|
409
|
+
limit: 1000
|
|
410
|
+
}
|
|
411
|
+
`;
|
|
412
|
+
const result = await this.loadQuery(searchMapMalloy, options).run({
|
|
413
|
+
rowLimit: 1000,
|
|
414
|
+
});
|
|
415
|
+
const rawResult = result._queryResult.result;
|
|
416
|
+
return rawResult.map(row => ({
|
|
417
|
+
...row,
|
|
418
|
+
cardinality: (0, row_data_utils_1.rowDataToNumber)(row.cardinality),
|
|
419
|
+
values: row.values.map(v => ({
|
|
420
|
+
...v,
|
|
421
|
+
weight: (0, row_data_utils_1.rowDataToNumber)(v.weight),
|
|
422
|
+
})),
|
|
423
|
+
}));
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Materialize the final query contained within this loaded `Model`.
|
|
427
|
+
*
|
|
428
|
+
* @return A promise to a prepared query.
|
|
429
|
+
*/
|
|
430
|
+
getFinalQuery() {
|
|
431
|
+
return this.loadFinalQuery().getPreparedQuery();
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Materialize an unnamed query contained within this loaded `Model` by index.
|
|
435
|
+
*
|
|
436
|
+
* @param index The index of the query contained within this loaded `Model`.
|
|
437
|
+
* @return A promise to a prepared query.
|
|
438
|
+
*/
|
|
439
|
+
getQueryByIndex(index) {
|
|
440
|
+
return this.loadQueryByIndex(index).getPreparedQuery();
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Materialize a query contained within this loaded `Model` by name.
|
|
444
|
+
*
|
|
445
|
+
* @param name The name of the query contained within this loaded `Model`.
|
|
446
|
+
* @return A promise to a prepared query.
|
|
447
|
+
*/
|
|
448
|
+
getQueryByName(name) {
|
|
449
|
+
return this.loadQueryByName(name).getPreparedQuery();
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Materialize a query against this loaded `Model` by its URL or contents.
|
|
453
|
+
*
|
|
454
|
+
* @param query The URL or contents of a query document to compile.
|
|
455
|
+
* @return A promise to a prepared query.
|
|
456
|
+
*/
|
|
457
|
+
getQuery(query, options) {
|
|
458
|
+
return this.loadQuery(query, options).getPreparedQuery();
|
|
459
|
+
}
|
|
460
|
+
// TODO Consider formalizing this. Perhaps as a `withQuery` method,
|
|
461
|
+
// as well as a `PreparedQuery.fromQueryDefinition` if we choose to expose
|
|
462
|
+
// `InternalQuery` to the world formally. For now, this should only
|
|
463
|
+
// be used in tests.
|
|
464
|
+
_loadQueryFromQueryDef(query, options) {
|
|
465
|
+
return this.makeQueryMaterializer(async () => {
|
|
466
|
+
const model = await this.materialize();
|
|
467
|
+
return new core_1.PreparedQuery(query, model, model.problems);
|
|
468
|
+
}, {
|
|
469
|
+
...this.compileQueryOptions,
|
|
470
|
+
...options,
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Load an explore contained within this loaded `Model` by name.
|
|
475
|
+
*
|
|
476
|
+
* @param name The name of the explore contained within this loaded `Model`.
|
|
477
|
+
* @return An `ExploreMaterializer` capable of materializing the requested explore,
|
|
478
|
+
* or loading further related objects.
|
|
479
|
+
*/
|
|
480
|
+
loadExploreByName(name) {
|
|
481
|
+
return this.makeExploreMaterializer(async () => {
|
|
482
|
+
return (await this.materialize()).getExploreByName(name);
|
|
483
|
+
}, this.compileQueryOptions);
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Materialize an explore contained within this loaded `Model` by its name.
|
|
487
|
+
*
|
|
488
|
+
* @param query The name of an explore within this loaded `Model`.
|
|
489
|
+
* @return A promise to an explore.
|
|
490
|
+
*/
|
|
491
|
+
getExploreByName(name) {
|
|
492
|
+
return this.loadExploreByName(name).getExplore();
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Compile and materialize this loaded `Model`.
|
|
496
|
+
*
|
|
497
|
+
* @return A promise to the compiled model that is loaded.
|
|
498
|
+
*/
|
|
499
|
+
getModel() {
|
|
500
|
+
return this.materialize();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
exports.ModelMaterializer = ModelMaterializer;
|
|
504
|
+
// =============================================================================
|
|
505
|
+
// QueryMaterializer
|
|
506
|
+
// =============================================================================
|
|
507
|
+
function runSQLOptionsWithAnnotations(preparedResult, givenOptions) {
|
|
508
|
+
return {
|
|
509
|
+
queryAnnotation: preparedResult.annotation,
|
|
510
|
+
modelAnnotation: preparedResult.modelAnnotation,
|
|
511
|
+
...givenOptions,
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* An object representing the task of loading a `Query`, capable of
|
|
516
|
+
* materializing the query (via `getPreparedQuery()`) or extending the task to load
|
|
517
|
+
* prepared results or run the query (via e.g. `loadPreparedResult()` or `run()`).
|
|
518
|
+
*/
|
|
519
|
+
class QueryMaterializer extends FluentState {
|
|
520
|
+
constructor(runtime, materialize, options) {
|
|
521
|
+
super(runtime, materialize);
|
|
522
|
+
this.runtime = runtime;
|
|
523
|
+
this.compileQueryOptions = options;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Run this loaded `Query`.
|
|
527
|
+
*
|
|
528
|
+
* @return The query results from running this loaded query.
|
|
529
|
+
*/
|
|
530
|
+
async run(options) {
|
|
531
|
+
const connections = this.runtime.connections;
|
|
532
|
+
const preparedResult = await this.getPreparedResult(options);
|
|
533
|
+
const finalOptions = runSQLOptionsWithAnnotations(preparedResult, options);
|
|
534
|
+
return compile_1.Malloy.run({ connections, preparedResult, options: finalOptions });
|
|
535
|
+
}
|
|
536
|
+
async *runStream(options) {
|
|
537
|
+
const preparedResult = await this.getPreparedResult(options);
|
|
538
|
+
const connections = this.runtime.connections;
|
|
539
|
+
const finalOptions = runSQLOptionsWithAnnotations(preparedResult, options);
|
|
540
|
+
const stream = compile_1.Malloy.runStream({
|
|
541
|
+
connections,
|
|
542
|
+
preparedResult,
|
|
543
|
+
options: finalOptions,
|
|
544
|
+
});
|
|
545
|
+
for await (const row of stream) {
|
|
546
|
+
yield row;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Load the prepared result of this loaded query.
|
|
551
|
+
*
|
|
552
|
+
* @return A `PreparedResultMaterializer` capable of materializing the requested
|
|
553
|
+
* prepared query or running it.
|
|
554
|
+
*/
|
|
555
|
+
loadPreparedResult(options) {
|
|
556
|
+
return this.makePreparedResultMaterializer(async () => {
|
|
557
|
+
const preparedQuery = await this.materialize();
|
|
558
|
+
const mergedOptions = {
|
|
559
|
+
eventStream: this.eventStream,
|
|
560
|
+
...this.compileQueryOptions,
|
|
561
|
+
...options,
|
|
562
|
+
};
|
|
563
|
+
// If buildManifest is provided, compute connectionDigests for manifest lookups
|
|
564
|
+
// TODO: This is inefficient - we call getBuildPlan just to find connection names.
|
|
565
|
+
// Consider adding a listConnections() method to LookupConnection, or caching this.
|
|
566
|
+
let connectionDigests;
|
|
567
|
+
if (mergedOptions.buildManifest) {
|
|
568
|
+
// Require experimental.persistence compiler flag to use buildManifest
|
|
569
|
+
const modelTag = preparedQuery.model.tagParse({ prefix: /^##! / }).tag;
|
|
570
|
+
if (!modelTag.has('experimental', 'persistence')) {
|
|
571
|
+
throw new Error('Model must have ##! experimental.persistence to use buildManifest');
|
|
572
|
+
}
|
|
573
|
+
const plan = preparedQuery.model.getBuildPlan();
|
|
574
|
+
const connectionNames = new Set(Object.values(plan.sources).map(s => s.connectionName));
|
|
575
|
+
connectionDigests = {};
|
|
576
|
+
for (const connName of connectionNames) {
|
|
577
|
+
const conn = await this.runtime.connections.lookupConnection(connName);
|
|
578
|
+
connectionDigests[connName] = conn.getDigest();
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
// Build PrepareResultOptions from CompileQueryOptions + connectionDigests
|
|
582
|
+
const prepareResultOptions = {
|
|
583
|
+
defaultRowLimit: mergedOptions.defaultRowLimit,
|
|
584
|
+
buildManifest: mergedOptions.buildManifest,
|
|
585
|
+
connectionDigests,
|
|
586
|
+
strictPersist: mergedOptions.strictPersist,
|
|
587
|
+
};
|
|
588
|
+
return preparedQuery.getPreparedResult({
|
|
589
|
+
...mergedOptions,
|
|
590
|
+
...prepareResultOptions,
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Materialize the prepared result of this loaded query.
|
|
596
|
+
*
|
|
597
|
+
* @return A promise of the prepared result of this loaded query.
|
|
598
|
+
*/
|
|
599
|
+
getPreparedResult(options) {
|
|
600
|
+
return this.loadPreparedResult(options).getPreparedResult();
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Materialize the SQL of this loaded query.
|
|
604
|
+
*
|
|
605
|
+
* @return A promise of the SQL string.
|
|
606
|
+
*/
|
|
607
|
+
async getSQL(options) {
|
|
608
|
+
return (await this.getPreparedResult(options)).sql;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Materialize this loaded query.
|
|
612
|
+
*
|
|
613
|
+
* @return A promise of the `PreparedQuery`.
|
|
614
|
+
*/
|
|
615
|
+
getPreparedQuery() {
|
|
616
|
+
return this.materialize();
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Estimates the cost of this loaded `Query`.
|
|
620
|
+
*
|
|
621
|
+
* @return The estimated cost of running this loaded query.
|
|
622
|
+
*/
|
|
623
|
+
async estimateQueryCost(options) {
|
|
624
|
+
const connections = this.runtime.connections;
|
|
625
|
+
const preparedResult = await this.getPreparedResult(options);
|
|
626
|
+
return compile_1.Malloy.estimateQueryCost({ connections, preparedResult });
|
|
627
|
+
}
|
|
628
|
+
get eventStream() {
|
|
629
|
+
return this.runtime.eventStream;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
exports.QueryMaterializer = QueryMaterializer;
|
|
633
|
+
// =============================================================================
|
|
634
|
+
// PreparedResultMaterializer
|
|
635
|
+
// =============================================================================
|
|
636
|
+
/**
|
|
637
|
+
* An object representing the task of loading a `PreparedResult`, capable of
|
|
638
|
+
* materializing the prepared result (via `getPreparedResult()`) or extending the task run
|
|
639
|
+
* the query.
|
|
640
|
+
*/
|
|
641
|
+
class PreparedResultMaterializer extends FluentState {
|
|
642
|
+
/**
|
|
643
|
+
* Run this prepared result.
|
|
644
|
+
*
|
|
645
|
+
* @return A promise to the query result data.
|
|
646
|
+
*/
|
|
647
|
+
async run(options) {
|
|
648
|
+
const preparedResult = await this.getPreparedResult();
|
|
649
|
+
const connections = this.runtime.connections;
|
|
650
|
+
const finalOptions = runSQLOptionsWithAnnotations(preparedResult, options);
|
|
651
|
+
return compile_1.Malloy.run({
|
|
652
|
+
connections,
|
|
653
|
+
preparedResult,
|
|
654
|
+
options: finalOptions,
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
async *runStream(options) {
|
|
658
|
+
const preparedResult = await this.getPreparedResult();
|
|
659
|
+
const connections = this.runtime.connections;
|
|
660
|
+
const finalOptions = runSQLOptionsWithAnnotations(preparedResult, options);
|
|
661
|
+
const stream = compile_1.Malloy.runStream({
|
|
662
|
+
connections,
|
|
663
|
+
preparedResult,
|
|
664
|
+
options: finalOptions,
|
|
665
|
+
});
|
|
666
|
+
for await (const row of stream) {
|
|
667
|
+
yield row;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Materialize this loaded prepared result.
|
|
672
|
+
*
|
|
673
|
+
* @return A promise of a prepared result.
|
|
674
|
+
*/
|
|
675
|
+
getPreparedResult() {
|
|
676
|
+
return this.materialize();
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Materialize the SQL of this loaded prepared result.
|
|
680
|
+
*
|
|
681
|
+
* @return A promise to the SQL string.
|
|
682
|
+
*/
|
|
683
|
+
async getSQL() {
|
|
684
|
+
return (await this.getPreparedResult()).sql;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
exports.PreparedResultMaterializer = PreparedResultMaterializer;
|
|
688
|
+
// =============================================================================
|
|
689
|
+
// ExploreMaterializer
|
|
690
|
+
// =============================================================================
|
|
691
|
+
/**
|
|
692
|
+
* An object representing the task of loading an `Explore`, capable of
|
|
693
|
+
* materializing the explore (via `getExplore()`) or extending the task to produce
|
|
694
|
+
* related queries.
|
|
695
|
+
*/
|
|
696
|
+
class ExploreMaterializer extends FluentState {
|
|
697
|
+
constructor(runtime, materialize, options) {
|
|
698
|
+
super(runtime, materialize);
|
|
699
|
+
this.runtime = runtime;
|
|
700
|
+
this.compileQueryOptions = options;
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Load a query contained within this loaded explore.
|
|
704
|
+
*
|
|
705
|
+
* @param name The name of the query to load.
|
|
706
|
+
* @return A `QueryMaterializer` capable of materializing the requested query, running it,
|
|
707
|
+
* or loading further related objects.
|
|
708
|
+
*/
|
|
709
|
+
loadQueryByName(name, options) {
|
|
710
|
+
return this.makeQueryMaterializer(async () => {
|
|
711
|
+
return (await this.materialize()).getQueryByName(name);
|
|
712
|
+
}, { ...this.compileQueryOptions, ...options });
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Materialize a query contained within this loaded explore.
|
|
716
|
+
*
|
|
717
|
+
* @param name The name of the query to materialize.
|
|
718
|
+
* @return A promise to the requested prepared query.
|
|
719
|
+
*/
|
|
720
|
+
getQueryByName(name) {
|
|
721
|
+
return this.loadQueryByName(name).getPreparedQuery();
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Materialize this loaded explore.
|
|
725
|
+
*
|
|
726
|
+
* @return A promise to the compiled `Explore`.
|
|
727
|
+
*/
|
|
728
|
+
getExplore() {
|
|
729
|
+
return this.materialize();
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
exports.ExploreMaterializer = ExploreMaterializer;
|
|
733
|
+
//# sourceMappingURL=runtime.js.map
|