@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.
Files changed (91) hide show
  1. package/CONTEXT.md +4 -3
  2. package/MALLOY_API.md +129 -0
  3. package/dist/annotation.d.ts +0 -2
  4. package/dist/annotation.js +29 -23
  5. package/dist/api/asynchronous.d.ts +1 -1
  6. package/dist/api/foundation/cache.d.ts +32 -0
  7. package/dist/api/foundation/cache.js +92 -0
  8. package/dist/api/foundation/compile.d.ts +175 -0
  9. package/dist/api/foundation/compile.js +391 -0
  10. package/dist/api/foundation/core.d.ts +493 -0
  11. package/dist/api/foundation/core.js +1247 -0
  12. package/dist/api/foundation/document.d.ts +167 -0
  13. package/dist/api/foundation/document.js +206 -0
  14. package/dist/api/foundation/index.d.ts +10 -0
  15. package/dist/api/foundation/index.js +77 -0
  16. package/dist/api/foundation/readers.d.ts +53 -0
  17. package/dist/api/foundation/readers.js +134 -0
  18. package/dist/api/foundation/result.d.ts +185 -0
  19. package/dist/api/foundation/result.js +704 -0
  20. package/dist/api/foundation/runtime.d.ts +361 -0
  21. package/dist/api/foundation/runtime.js +733 -0
  22. package/dist/api/foundation/types.d.ts +54 -0
  23. package/dist/api/foundation/types.js +7 -0
  24. package/dist/api/foundation/writers.d.ts +42 -0
  25. package/dist/api/foundation/writers.js +230 -0
  26. package/dist/api/util.d.ts +1 -1
  27. package/dist/connection/base_connection.d.ts +5 -0
  28. package/dist/connection/types.d.ts +5 -0
  29. package/dist/dialect/duckdb/duckdb.js +2 -1
  30. package/dist/dialect/snowflake/snowflake.js +7 -1
  31. package/dist/dialect/trino/trino.js +7 -2
  32. package/dist/index.d.ts +6 -3
  33. package/dist/index.js +30 -26
  34. package/dist/lang/ast/error-factory.js +3 -5
  35. package/dist/lang/ast/expressions/expr-count-distinct.js +7 -1
  36. package/dist/lang/ast/expressions/expr-granular-time.js +1 -1
  37. package/dist/lang/ast/expressions/expr-max.js +7 -1
  38. package/dist/lang/ast/expressions/expr-min.js +7 -1
  39. package/dist/lang/ast/expressions/for-range.js +1 -1
  40. package/dist/lang/ast/source-elements/query-source.js +2 -7
  41. package/dist/lang/ast/source-elements/refined-source.js +11 -1
  42. package/dist/lang/ast/source-elements/sql-source.d.ts +1 -1
  43. package/dist/lang/ast/source-elements/sql-source.js +18 -3
  44. package/dist/lang/ast/sql-elements/sql-string.d.ts +2 -2
  45. package/dist/lang/ast/sql-elements/sql-string.js +18 -1
  46. package/dist/lang/ast/statements/define-source.js +7 -2
  47. package/dist/lang/ast/statements/import-statement.js +53 -21
  48. package/dist/lang/ast/types/document-compile-result.d.ts +1 -0
  49. package/dist/lang/ast/types/expression-def.js +1 -1
  50. package/dist/lang/ast/types/malloy-element.d.ts +3 -1
  51. package/dist/lang/ast/types/malloy-element.js +23 -7
  52. package/dist/lang/malloy-to-ast.d.ts +1 -1
  53. package/dist/lang/malloy-to-ast.js +1 -1
  54. package/dist/lang/parse-malloy.d.ts +3 -2
  55. package/dist/lang/parse-malloy.js +14 -25
  56. package/dist/lang/test/test-translator.d.ts +9 -2
  57. package/dist/lang/test/test-translator.js +103 -77
  58. package/dist/lang/translate-response.d.ts +1 -0
  59. package/dist/model/constant_expression_compiler.js +6 -7
  60. package/dist/model/index.d.ts +3 -1
  61. package/dist/model/index.js +15 -9
  62. package/dist/model/malloy_types.d.ts +89 -15
  63. package/dist/model/malloy_types.js +12 -0
  64. package/dist/model/persist_utils.d.ts +47 -0
  65. package/dist/model/persist_utils.js +257 -0
  66. package/dist/model/query_model_impl.d.ts +2 -4
  67. package/dist/model/query_model_impl.js +5 -13
  68. package/dist/model/query_node.d.ts +1 -2
  69. package/dist/model/query_node.js +3 -13
  70. package/dist/model/query_query.d.ts +17 -1
  71. package/dist/model/query_query.js +81 -36
  72. package/dist/model/source_def_utils.d.ts +50 -0
  73. package/dist/model/source_def_utils.js +154 -0
  74. package/dist/model/sql_block.d.ts +5 -1
  75. package/dist/model/sql_block.js +29 -4
  76. package/dist/model/sql_compiled.d.ts +29 -0
  77. package/dist/model/sql_compiled.js +102 -0
  78. package/dist/model/stage_writer.d.ts +1 -3
  79. package/dist/model/stage_writer.js +7 -25
  80. package/dist/model/utils.d.ts +20 -1
  81. package/dist/model/utils.js +40 -0
  82. package/dist/run_sql_options.d.ts +0 -1
  83. package/dist/taggable.d.ts +10 -0
  84. package/dist/taggable.js +7 -0
  85. package/dist/version.d.ts +1 -1
  86. package/dist/version.js +1 -1
  87. package/package.json +6 -4
  88. package/dist/malloy.d.ts +0 -1365
  89. package/dist/malloy.js +0 -3421
  90. package/dist/model/materialization/utils.d.ts +0 -3
  91. 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