@malloydata/malloy 0.0.336 → 0.0.338
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/api/foundation/compile.d.ts +26 -0
- package/dist/api/foundation/compile.js +38 -0
- package/dist/api/foundation/result.d.ts +4 -4
- package/dist/api/foundation/result.js +9 -9
- package/dist/api/foundation/writers.d.ts +1 -1
- package/dist/api/foundation/writers.js +9 -8
- package/dist/connection/index.d.ts +1 -0
- package/dist/connection/index.js +1 -0
- package/dist/connection/registry.d.ts +73 -0
- package/dist/connection/registry.js +106 -0
- package/dist/connection/types.d.ts +2 -17
- package/dist/dialect/dialect.d.ts +2 -1
- package/dist/dialect/dialect.js +3 -0
- package/dist/dialect/duckdb/duckdb.js +22 -1
- package/dist/dialect/mysql/mysql.d.ts +1 -0
- package/dist/dialect/mysql/mysql.js +1 -0
- package/dist/dialect/postgres/postgres.d.ts +1 -0
- package/dist/dialect/postgres/postgres.js +10 -0
- package/dist/dialect/standardsql/standardsql.js +21 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +11 -2
- package/dist/lang/ast/expressions/expr-cast.d.ts +3 -3
- package/dist/lang/ast/expressions/expr-cast.js +4 -2
- package/dist/lang/ast/expressions/expr-func.d.ts +3 -3
- package/dist/lang/ast/expressions/expr-func.js +7 -9
- package/dist/lang/ast/expressions/for-range.js +1 -1
- package/dist/lang/ast/source-elements/named-source.js +4 -2
- package/dist/lang/ast/time-utils.d.ts +2 -2
- package/dist/lang/ast/time-utils.js +4 -5
- package/dist/lang/lib/Malloy/MalloyParser.d.ts +88 -45
- package/dist/lang/lib/Malloy/MalloyParser.js +2193 -1862
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +33 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +21 -0
- package/dist/lang/malloy-to-ast.d.ts +4 -4
- package/dist/lang/malloy-to-ast.js +38 -22
- package/dist/model/malloy_types.d.ts +11 -8
- package/dist/model/malloy_types.js +23 -15
- package/dist/model/utils.d.ts +3 -5
- package/dist/model/utils.js +6 -10
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { LogMessage } from '../../lang';
|
|
2
2
|
import type { Connection, InfoConnection, LookupConnection, FetchSchemaOptions } from '../../connection/types';
|
|
3
|
+
import type { ConnectionTypeDef, ConnectionPropertyDefinition, ConnectionsConfig } from '../../connection/registry';
|
|
3
4
|
import type { URLReader, EventStream } from '../../runtime_types';
|
|
4
5
|
import type { SQLSourceDef, QueryRunStats } from '../../model';
|
|
5
6
|
import type { RunSQLOptions } from '../../run_sql_options';
|
|
@@ -55,6 +56,31 @@ export declare class MalloyError extends Error {
|
|
|
55
56
|
}
|
|
56
57
|
export declare class Malloy {
|
|
57
58
|
static get version(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Register a connection type with the global registry.
|
|
61
|
+
* Typically called by db-* packages on import as a side effect.
|
|
62
|
+
*/
|
|
63
|
+
static registerConnectionType(typeName: string, def: ConnectionTypeDef): void;
|
|
64
|
+
/**
|
|
65
|
+
* Get the property definitions for a registered connection type.
|
|
66
|
+
*/
|
|
67
|
+
static getConnectionProperties(typeName: string): ConnectionPropertyDefinition[] | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Get the names of all registered connection types.
|
|
70
|
+
*/
|
|
71
|
+
static getRegisteredConnectionTypes(): string[];
|
|
72
|
+
/**
|
|
73
|
+
* Parse a JSON config string into an editable ConnectionsConfig.
|
|
74
|
+
*/
|
|
75
|
+
static readConnectionsConfig(jsonText: string): ConnectionsConfig;
|
|
76
|
+
/**
|
|
77
|
+
* Serialize a ConnectionsConfig to a JSON string.
|
|
78
|
+
*/
|
|
79
|
+
static writeConnectionsConfig(config: ConnectionsConfig): string;
|
|
80
|
+
/**
|
|
81
|
+
* Create a LookupConnection from a ConnectionsConfig using registered factories.
|
|
82
|
+
*/
|
|
83
|
+
static createConnectionsFromConfig(config: ConnectionsConfig): LookupConnection<Connection>;
|
|
58
84
|
private static _parse;
|
|
59
85
|
/**
|
|
60
86
|
* Parse a Malloy document by URL.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.Malloy = exports.MalloyError = void 0;
|
|
8
8
|
const lang_1 = require("../../lang");
|
|
9
|
+
const registry_1 = require("../../connection/registry");
|
|
9
10
|
const model_1 = require("../../model");
|
|
10
11
|
const sql_block_1 = require("../../model/sql_block");
|
|
11
12
|
const version_1 = require("../../version");
|
|
@@ -43,6 +44,43 @@ class Malloy {
|
|
|
43
44
|
static get version() {
|
|
44
45
|
return version_1.MALLOY_VERSION;
|
|
45
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Register a connection type with the global registry.
|
|
49
|
+
* Typically called by db-* packages on import as a side effect.
|
|
50
|
+
*/
|
|
51
|
+
static registerConnectionType(typeName, def) {
|
|
52
|
+
(0, registry_1.registerConnectionType)(typeName, def);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get the property definitions for a registered connection type.
|
|
56
|
+
*/
|
|
57
|
+
static getConnectionProperties(typeName) {
|
|
58
|
+
return (0, registry_1.getConnectionProperties)(typeName);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the names of all registered connection types.
|
|
62
|
+
*/
|
|
63
|
+
static getRegisteredConnectionTypes() {
|
|
64
|
+
return (0, registry_1.getRegisteredConnectionTypes)();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Parse a JSON config string into an editable ConnectionsConfig.
|
|
68
|
+
*/
|
|
69
|
+
static readConnectionsConfig(jsonText) {
|
|
70
|
+
return (0, registry_1.readConnectionsConfig)(jsonText);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Serialize a ConnectionsConfig to a JSON string.
|
|
74
|
+
*/
|
|
75
|
+
static writeConnectionsConfig(config) {
|
|
76
|
+
return (0, registry_1.writeConnectionsConfig)(config);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create a LookupConnection from a ConnectionsConfig using registered factories.
|
|
80
|
+
*/
|
|
81
|
+
static createConnectionsFromConfig(config) {
|
|
82
|
+
return (0, registry_1.createConnectionsFromConfig)(config);
|
|
83
|
+
}
|
|
46
84
|
static _parse(source, url, eventStream, options, invalidationKey) {
|
|
47
85
|
if (url === undefined) {
|
|
48
86
|
url = new URL(MALLOY_INTERNAL_URL);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { QueryData,
|
|
1
|
+
import type { QueryData, QueryRecord, QueryResult, QueryRunStats, ModelDef } from '../../model';
|
|
2
2
|
import type { Explore, Field, AtomicField, StringField, NumberField, BooleanField, DateField, TimestampField, JSONField, UnsupportedField } from './core';
|
|
3
3
|
import { PreparedResult } from './core';
|
|
4
4
|
export type ResultJSON = {
|
|
@@ -163,17 +163,17 @@ export declare class DataRecord extends Data<{
|
|
|
163
163
|
protected _field: Explore;
|
|
164
164
|
readonly index: number | undefined;
|
|
165
165
|
private cellCache;
|
|
166
|
-
constructor(queryDataRow:
|
|
166
|
+
constructor(queryDataRow: QueryRecord, index: number | undefined, field: Explore, parent: DataArrayOrRecord | undefined, parentRecord: DataRecord | undefined);
|
|
167
167
|
/**
|
|
168
168
|
* @return Normalized data with JS native types (number | bigint, Date).
|
|
169
169
|
* Use this for CSV output, tests, and general programmatic access.
|
|
170
170
|
*/
|
|
171
|
-
toObject():
|
|
171
|
+
toObject(): QueryRecord;
|
|
172
172
|
/**
|
|
173
173
|
* @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
|
|
174
174
|
* Use this for JSON serialization.
|
|
175
175
|
*/
|
|
176
|
-
toJSON():
|
|
176
|
+
toJSON(): QueryRecord;
|
|
177
177
|
path(...path: (number | string)[]): DataColumn;
|
|
178
178
|
cell(fieldOrName: string | Field): DataColumn;
|
|
179
179
|
get value(): {
|
|
@@ -406,12 +406,12 @@ const JSON_NORMALIZERS = {
|
|
|
406
406
|
* Walk a QueryData array and normalize values according to the given normalizers.
|
|
407
407
|
*/
|
|
408
408
|
function walkQueryData(data, structDef, normalizers) {
|
|
409
|
-
return data.map(row =>
|
|
409
|
+
return data.map(row => walkQueryRecord(row, structDef, normalizers));
|
|
410
410
|
}
|
|
411
411
|
/**
|
|
412
|
-
* Walk a
|
|
412
|
+
* Walk a QueryRecord and normalize values according to the given normalizers.
|
|
413
413
|
*/
|
|
414
|
-
function
|
|
414
|
+
function walkQueryRecord(row, structDef, normalizers) {
|
|
415
415
|
var _a;
|
|
416
416
|
const result = {};
|
|
417
417
|
for (const fieldDef of structDef.fields) {
|
|
@@ -458,7 +458,7 @@ function walkValue(value, fieldDef, normalizers) {
|
|
|
458
458
|
}
|
|
459
459
|
if ((0, model_1.isRepeatedRecord)(fieldDef)) {
|
|
460
460
|
// Array of records - recurse into each record
|
|
461
|
-
return value.map(item =>
|
|
461
|
+
return value.map(item => walkQueryRecord(item, fieldDef, normalizers));
|
|
462
462
|
}
|
|
463
463
|
else if ((0, model_1.isBasicArray)(fieldDef)) {
|
|
464
464
|
// Scalar array - normalize each element based on elementTypeDef
|
|
@@ -470,7 +470,7 @@ function walkValue(value, fieldDef, normalizers) {
|
|
|
470
470
|
// Handle records (non-array)
|
|
471
471
|
if (fieldDef.type === 'record') {
|
|
472
472
|
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
473
|
-
return
|
|
473
|
+
return walkQueryRecord(value, fieldDef, normalizers);
|
|
474
474
|
}
|
|
475
475
|
}
|
|
476
476
|
// Fallback - pass through
|
|
@@ -505,7 +505,7 @@ function walkScalarValue(value, typeDef, normalizers) {
|
|
|
505
505
|
return value.map(item => walkScalarValue(item, elementType, normalizers));
|
|
506
506
|
}
|
|
507
507
|
else if ((0, model_1.isRepeatedRecord)(typeDef)) {
|
|
508
|
-
return value.map(item =>
|
|
508
|
+
return value.map(item => walkQueryRecord(item, typeDef, normalizers));
|
|
509
509
|
}
|
|
510
510
|
}
|
|
511
511
|
// Pass through other types
|
|
@@ -612,14 +612,14 @@ class DataRecord extends Data {
|
|
|
612
612
|
* Use this for CSV output, tests, and general programmatic access.
|
|
613
613
|
*/
|
|
614
614
|
toObject() {
|
|
615
|
-
return
|
|
615
|
+
return walkQueryRecord(this.queryDataRow, this._field.structDef, OBJECT_NORMALIZERS);
|
|
616
616
|
}
|
|
617
617
|
/**
|
|
618
618
|
* @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
|
|
619
619
|
* Use this for JSON serialization.
|
|
620
620
|
*/
|
|
621
621
|
toJSON() {
|
|
622
|
-
return
|
|
622
|
+
return walkQueryRecord(this.queryDataRow, this._field.structDef, JSON_NORMALIZERS);
|
|
623
623
|
}
|
|
624
624
|
path(...path) {
|
|
625
625
|
return getPath(this, path);
|
|
@@ -657,7 +657,7 @@ class DataRecord extends Data {
|
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
659
|
else if (field.isExploreField()) {
|
|
660
|
-
if (
|
|
660
|
+
if ((0, model_1.isCompoundArrayData)(value)) {
|
|
661
661
|
column = new DataArray(value, field, this, this);
|
|
662
662
|
}
|
|
663
663
|
else {
|
|
@@ -15,7 +15,7 @@ export declare class JSONWriter extends DataWriter {
|
|
|
15
15
|
* CSV writer class that handles nested data.
|
|
16
16
|
* This writer creates CSV using a DFS traversal of the result dataset.
|
|
17
17
|
* Each trivial column value is converted to a CSV of 1x1 matrix and all the
|
|
18
|
-
* columns are merged together to create a CSV that represents 1
|
|
18
|
+
* columns are merged together to create a CSV that represents 1 QueryRecord.
|
|
19
19
|
* Since this follows DFS, each non trivial data is rendered into a NxM matrix
|
|
20
20
|
* where N is the number of rows in the nested data and M is the number of
|
|
21
21
|
* columns it has.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.CSVWriter = exports.JSONWriter = exports.DataWriter = void 0;
|
|
8
|
+
const model_1 = require("../../model");
|
|
8
9
|
// =============================================================================
|
|
9
10
|
// DataWriter Base Class
|
|
10
11
|
// =============================================================================
|
|
@@ -47,7 +48,7 @@ exports.JSONWriter = JSONWriter;
|
|
|
47
48
|
* CSV writer class that handles nested data.
|
|
48
49
|
* This writer creates CSV using a DFS traversal of the result dataset.
|
|
49
50
|
* Each trivial column value is converted to a CSV of 1x1 matrix and all the
|
|
50
|
-
* columns are merged together to create a CSV that represents 1
|
|
51
|
+
* columns are merged together to create a CSV that represents 1 QueryRecord.
|
|
51
52
|
* Since this follows DFS, each non trivial data is rendered into a NxM matrix
|
|
52
53
|
* where N is the number of rows in the nested data and M is the number of
|
|
53
54
|
* columns it has.
|
|
@@ -108,7 +109,7 @@ class CSVWriter extends DataWriter {
|
|
|
108
109
|
for (const key in firstVal) {
|
|
109
110
|
numKeys = numKeys + 1;
|
|
110
111
|
const val = firstVal[key];
|
|
111
|
-
if (
|
|
112
|
+
if ((0, model_1.isCompoundArrayData)(val)) {
|
|
112
113
|
const weight = this.getColWeight(val) - 1;
|
|
113
114
|
numKeys = numKeys + weight;
|
|
114
115
|
}
|
|
@@ -123,7 +124,7 @@ class CSVWriter extends DataWriter {
|
|
|
123
124
|
csv.push(this.escape(key));
|
|
124
125
|
const val = row[key];
|
|
125
126
|
width++;
|
|
126
|
-
if (
|
|
127
|
+
if ((0, model_1.isCompoundArrayData)(val)) {
|
|
127
128
|
const numKeys = this.getColWeight(val) - 1;
|
|
128
129
|
width = width + numKeys;
|
|
129
130
|
for (let i = 0; i < numKeys; i++) {
|
|
@@ -193,7 +194,11 @@ class CSVWriter extends DataWriter {
|
|
|
193
194
|
const matrices = [];
|
|
194
195
|
for (const key in row) {
|
|
195
196
|
const val = row[key];
|
|
196
|
-
if (
|
|
197
|
+
if ((0, model_1.isCompoundArrayData)(val)) {
|
|
198
|
+
const cell = this.getChildMatrix(val);
|
|
199
|
+
matrices.push(cell);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
197
202
|
const cell = {
|
|
198
203
|
rows: [this.stringify(val)],
|
|
199
204
|
length: 1,
|
|
@@ -201,10 +206,6 @@ class CSVWriter extends DataWriter {
|
|
|
201
206
|
};
|
|
202
207
|
matrices.push(cell);
|
|
203
208
|
}
|
|
204
|
-
else {
|
|
205
|
-
const cell = this.getChildMatrix(val);
|
|
206
|
-
matrices.push(cell);
|
|
207
|
-
}
|
|
208
209
|
}
|
|
209
210
|
return this.mergeMatrices(matrices);
|
|
210
211
|
}
|
package/dist/connection/index.js
CHANGED
|
@@ -16,4 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./types"), exports);
|
|
18
18
|
__exportStar(require("./base_connection"), exports);
|
|
19
|
+
__exportStar(require("./registry"), exports);
|
|
19
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Connection, ConnectionConfig, LookupConnection } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* A factory function that creates a Connection from a config object.
|
|
4
|
+
*/
|
|
5
|
+
export type ConnectionTypeFactory = (config: ConnectionConfig) => Connection;
|
|
6
|
+
/**
|
|
7
|
+
* The type of a connection property value.
|
|
8
|
+
*/
|
|
9
|
+
export type ConnectionPropertyType = 'string' | 'number' | 'boolean' | 'password' | 'file' | 'text';
|
|
10
|
+
/**
|
|
11
|
+
* Describes a single configuration property for a connection type.
|
|
12
|
+
*/
|
|
13
|
+
export interface ConnectionPropertyDefinition {
|
|
14
|
+
name: string;
|
|
15
|
+
displayName: string;
|
|
16
|
+
type: ConnectionPropertyType;
|
|
17
|
+
optional?: true;
|
|
18
|
+
default?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
/** For type 'file': extension filters for picker dialogs. */
|
|
21
|
+
fileFilters?: Record<string, string[]>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A connection type definition: factory plus property metadata.
|
|
25
|
+
*/
|
|
26
|
+
export interface ConnectionTypeDef {
|
|
27
|
+
factory: ConnectionTypeFactory;
|
|
28
|
+
properties: ConnectionPropertyDefinition[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A single connection entry in a JSON config.
|
|
32
|
+
*/
|
|
33
|
+
export interface ConnectionConfigEntry {
|
|
34
|
+
is: string;
|
|
35
|
+
[key: string]: string | number | boolean | undefined;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The editable intermediate representation of a connections config file.
|
|
39
|
+
*/
|
|
40
|
+
export interface ConnectionsConfig {
|
|
41
|
+
connections: Record<string, ConnectionConfigEntry>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Register a connection type with its factory and property definitions.
|
|
45
|
+
*
|
|
46
|
+
* @param typeName The connection type name (e.g. "duckdb", "bigquery").
|
|
47
|
+
* @param def The connection type definition (factory + properties).
|
|
48
|
+
*/
|
|
49
|
+
export declare function registerConnectionType(typeName: string, def: ConnectionTypeDef): void;
|
|
50
|
+
/**
|
|
51
|
+
* Get the property definitions for a registered connection type.
|
|
52
|
+
*
|
|
53
|
+
* @param typeName The connection type name.
|
|
54
|
+
* @returns The property definitions, or undefined if the type is not registered.
|
|
55
|
+
*/
|
|
56
|
+
export declare function getConnectionProperties(typeName: string): ConnectionPropertyDefinition[] | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Get the names of all registered connection types.
|
|
59
|
+
*/
|
|
60
|
+
export declare function getRegisteredConnectionTypes(): string[];
|
|
61
|
+
/**
|
|
62
|
+
* Parse a JSON config string into a ConnectionsConfig.
|
|
63
|
+
* Validates that each connection entry has an `is` field.
|
|
64
|
+
*/
|
|
65
|
+
export declare function readConnectionsConfig(jsonText: string): ConnectionsConfig;
|
|
66
|
+
/**
|
|
67
|
+
* Serialize a ConnectionsConfig to a JSON string with 2-space indent.
|
|
68
|
+
*/
|
|
69
|
+
export declare function writeConnectionsConfig(config: ConnectionsConfig): string;
|
|
70
|
+
/**
|
|
71
|
+
* Create a LookupConnection from a ConnectionsConfig using registered factories.
|
|
72
|
+
*/
|
|
73
|
+
export declare function createConnectionsFromConfig(config: ConnectionsConfig): LookupConnection<Connection>;
|
|
@@ -0,0 +1,106 @@
|
|
|
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.registerConnectionType = registerConnectionType;
|
|
8
|
+
exports.getConnectionProperties = getConnectionProperties;
|
|
9
|
+
exports.getRegisteredConnectionTypes = getRegisteredConnectionTypes;
|
|
10
|
+
exports.readConnectionsConfig = readConnectionsConfig;
|
|
11
|
+
exports.writeConnectionsConfig = writeConnectionsConfig;
|
|
12
|
+
exports.createConnectionsFromConfig = createConnectionsFromConfig;
|
|
13
|
+
// Module-level registry
|
|
14
|
+
const registry = new Map();
|
|
15
|
+
/**
|
|
16
|
+
* Register a connection type with its factory and property definitions.
|
|
17
|
+
*
|
|
18
|
+
* @param typeName The connection type name (e.g. "duckdb", "bigquery").
|
|
19
|
+
* @param def The connection type definition (factory + properties).
|
|
20
|
+
*/
|
|
21
|
+
function registerConnectionType(typeName, def) {
|
|
22
|
+
registry.set(typeName, def);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get the property definitions for a registered connection type.
|
|
26
|
+
*
|
|
27
|
+
* @param typeName The connection type name.
|
|
28
|
+
* @returns The property definitions, or undefined if the type is not registered.
|
|
29
|
+
*/
|
|
30
|
+
function getConnectionProperties(typeName) {
|
|
31
|
+
var _a;
|
|
32
|
+
return (_a = registry.get(typeName)) === null || _a === void 0 ? void 0 : _a.properties;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get the names of all registered connection types.
|
|
36
|
+
*/
|
|
37
|
+
function getRegisteredConnectionTypes() {
|
|
38
|
+
return [...registry.keys()];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a JSON config string into a ConnectionsConfig.
|
|
42
|
+
* Validates that each connection entry has an `is` field.
|
|
43
|
+
*/
|
|
44
|
+
function readConnectionsConfig(jsonText) {
|
|
45
|
+
const parsed = JSON.parse(jsonText);
|
|
46
|
+
const connections = parsed.connections;
|
|
47
|
+
if (connections === undefined || typeof connections !== 'object') {
|
|
48
|
+
throw new Error('Invalid connections config: missing "connections" object');
|
|
49
|
+
}
|
|
50
|
+
for (const [name, entry] of Object.entries(connections)) {
|
|
51
|
+
if (typeof entry !== 'object' ||
|
|
52
|
+
entry === null ||
|
|
53
|
+
!entry.is) {
|
|
54
|
+
throw new Error(`Connection "${name}" is missing required "is" property`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return parsed;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Serialize a ConnectionsConfig to a JSON string with 2-space indent.
|
|
61
|
+
*/
|
|
62
|
+
function writeConnectionsConfig(config) {
|
|
63
|
+
return JSON.stringify(config, null, 2);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create a LookupConnection from a ConnectionsConfig using registered factories.
|
|
67
|
+
*/
|
|
68
|
+
function createConnectionsFromConfig(config) {
|
|
69
|
+
const entries = Object.entries(config.connections);
|
|
70
|
+
const firstConnectionName = entries.length > 0 ? entries[0][0] : undefined;
|
|
71
|
+
const cache = new Map();
|
|
72
|
+
return {
|
|
73
|
+
async lookupConnection(connectionName) {
|
|
74
|
+
if (connectionName === undefined) {
|
|
75
|
+
connectionName = firstConnectionName;
|
|
76
|
+
}
|
|
77
|
+
if (connectionName === undefined) {
|
|
78
|
+
throw new Error('No connections defined in config');
|
|
79
|
+
}
|
|
80
|
+
const cached = cache.get(connectionName);
|
|
81
|
+
if (cached)
|
|
82
|
+
return cached;
|
|
83
|
+
const entry = config.connections[connectionName];
|
|
84
|
+
if (!entry) {
|
|
85
|
+
throw new Error(`No connection named "${connectionName}" found in config`);
|
|
86
|
+
}
|
|
87
|
+
const typeDef = registry.get(entry.is);
|
|
88
|
+
if (!typeDef) {
|
|
89
|
+
throw new Error(`No registered connection type "${entry.is}" for connection "${connectionName}". ` +
|
|
90
|
+
'Did you forget to import the connection package?');
|
|
91
|
+
}
|
|
92
|
+
const connConfig = { name: connectionName };
|
|
93
|
+
for (const [key, value] of Object.entries(entry)) {
|
|
94
|
+
if (key === 'is')
|
|
95
|
+
continue;
|
|
96
|
+
if (value !== undefined) {
|
|
97
|
+
connConfig[key] = value;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const connection = typeDef.factory(connConfig);
|
|
101
|
+
cache.set(connectionName, connection);
|
|
102
|
+
return connection;
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { RunSQLOptions } from '../run_sql_options';
|
|
2
|
-
import type { Annotation, MalloyQueryData,
|
|
3
|
-
import type { Dialect } from '../dialect';
|
|
2
|
+
import type { Annotation, MalloyQueryData, QueryRecord, QueryRunStats, SQLSourceDef, TableSourceDef } from '../model/malloy_types';
|
|
4
3
|
import type { SQLSourceRequest } from '../lang/translate-response';
|
|
5
4
|
/**
|
|
6
5
|
* Options passed to fetchSchema methods.
|
|
@@ -49,24 +48,10 @@ export interface InfoConnection {
|
|
|
49
48
|
getDigest(): string;
|
|
50
49
|
}
|
|
51
50
|
export type ConnectionParameterValue = string | number | boolean | Array<ConnectionParameterValue>;
|
|
52
|
-
export interface ConnectionParameter {
|
|
53
|
-
name: string;
|
|
54
|
-
label: string;
|
|
55
|
-
type: 'string' | 'number' | 'boolean';
|
|
56
|
-
isOptional?: boolean;
|
|
57
|
-
isSecret?: boolean;
|
|
58
|
-
defaultValue?: ConnectionParameterValue;
|
|
59
|
-
}
|
|
60
|
-
export type ConnectionConfigSchema = ConnectionParameter[];
|
|
61
51
|
export interface ConnectionConfig {
|
|
62
52
|
name: string;
|
|
63
53
|
[key: string]: ConnectionParameterValue | undefined;
|
|
64
54
|
}
|
|
65
|
-
export interface ConnectionFactory {
|
|
66
|
-
connectionName: string;
|
|
67
|
-
configSchema: ConnectionConfigSchema;
|
|
68
|
-
createConnection(connectionConfig: ConnectionConfig, dialectRegistrar?: (dialect: Dialect) => void): Connection & TestableConnection;
|
|
69
|
-
}
|
|
70
55
|
export interface ConnectionMetadata {
|
|
71
56
|
url?: string;
|
|
72
57
|
}
|
|
@@ -105,7 +90,7 @@ export interface PersistSQLResults extends Connection {
|
|
|
105
90
|
manifestTemporaryTable(sqlCommand: string): Promise<string>;
|
|
106
91
|
}
|
|
107
92
|
export interface StreamingConnection extends Connection {
|
|
108
|
-
runSQLStream(sqlCommand: string, options?: RunSQLOptions): AsyncIterableIterator<
|
|
93
|
+
runSQLStream(sqlCommand: string, options?: RunSQLOptions): AsyncIterableIterator<QueryRecord>;
|
|
109
94
|
}
|
|
110
95
|
/**
|
|
111
96
|
* A mapping of connection names to connections.
|
|
@@ -74,6 +74,7 @@ export declare abstract class Dialect {
|
|
|
74
74
|
supportsBigIntPrecision: boolean;
|
|
75
75
|
supportsComplexFilteredSources: boolean;
|
|
76
76
|
supportsTempTables: boolean;
|
|
77
|
+
maxIdentifierLength: number;
|
|
77
78
|
hasModOperator: boolean;
|
|
78
79
|
supportsLeftJoinUnnest: boolean;
|
|
79
80
|
requiresExplicitUnnestOrdering: boolean;
|
|
@@ -368,7 +369,7 @@ export declare abstract class Dialect {
|
|
|
368
369
|
sqlCastPrep(cast: TypecastExpr): {
|
|
369
370
|
op: string;
|
|
370
371
|
srcTypeDef: BasicAtomicTypeDef | undefined;
|
|
371
|
-
dstTypeDef:
|
|
372
|
+
dstTypeDef: AtomicTypeDef | undefined;
|
|
372
373
|
dstSQLType: string;
|
|
373
374
|
};
|
|
374
375
|
/**
|
package/dist/dialect/dialect.js
CHANGED
|
@@ -95,6 +95,9 @@ class Dialect {
|
|
|
95
95
|
this.supportsComplexFilteredSources = true;
|
|
96
96
|
// can create temp tables
|
|
97
97
|
this.supportsTempTables = true;
|
|
98
|
+
// Maximum length of a table/view identifier. Used to truncate
|
|
99
|
+
// generated temp table names. 128 is a safe default for most databases.
|
|
100
|
+
this.maxIdentifierLength = 128;
|
|
98
101
|
this.hasModOperator = true;
|
|
99
102
|
// can LEFT JOIN UNNEST
|
|
100
103
|
this.supportsLeftJoinUnnest = true;
|
|
@@ -289,9 +289,30 @@ class DuckDBDialect extends pg_impl_1.PostgresBase {
|
|
|
289
289
|
else if (malloyType.type === 'string') {
|
|
290
290
|
return 'varchar';
|
|
291
291
|
}
|
|
292
|
-
if (malloyType.type === 'timestamptz') {
|
|
292
|
+
else if (malloyType.type === 'timestamptz') {
|
|
293
293
|
return 'timestamp with time zone';
|
|
294
294
|
}
|
|
295
|
+
else if (malloyType.type === 'record') {
|
|
296
|
+
const typeSpec = [];
|
|
297
|
+
for (const f of malloyType.fields) {
|
|
298
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
299
|
+
typeSpec.push(`${this.sqlMaybeQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return `STRUCT(${typeSpec.join(', ')})`;
|
|
303
|
+
}
|
|
304
|
+
else if (malloyType.type === 'array') {
|
|
305
|
+
if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
|
|
306
|
+
const typeSpec = [];
|
|
307
|
+
for (const f of malloyType.fields) {
|
|
308
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
309
|
+
typeSpec.push(`${this.sqlMaybeQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return `STRUCT(${typeSpec.join(', ')})[]`;
|
|
313
|
+
}
|
|
314
|
+
return `${this.malloyTypeToSQLType(malloyType.elementTypeDef)}[]`;
|
|
315
|
+
}
|
|
295
316
|
return malloyType.type;
|
|
296
317
|
}
|
|
297
318
|
parseDuckDBType(sqlType) {
|
|
@@ -31,6 +31,7 @@ export declare class MySQLDialect extends Dialect {
|
|
|
31
31
|
compoundObjectInSchema: boolean;
|
|
32
32
|
booleanType: BooleanTypeSupport;
|
|
33
33
|
orderByClause: OrderByClauseType;
|
|
34
|
+
maxIdentifierLength: number;
|
|
34
35
|
malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
|
|
35
36
|
sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
|
|
36
37
|
quoteTablePath(tablePath: string): string;
|
|
@@ -120,6 +120,7 @@ class MySQLDialect extends dialect_1.Dialect {
|
|
|
120
120
|
this.compoundObjectInSchema = false;
|
|
121
121
|
this.booleanType = 'simulated';
|
|
122
122
|
this.orderByClause = 'ordinal';
|
|
123
|
+
this.maxIdentifierLength = 64;
|
|
123
124
|
}
|
|
124
125
|
malloyTypeToSQLType(malloyType) {
|
|
125
126
|
switch (malloyType.type) {
|
|
@@ -26,6 +26,7 @@ export declare class PostgresDialect extends PostgresBase {
|
|
|
26
26
|
supportsComplexFilteredSources: boolean;
|
|
27
27
|
compoundObjectInSchema: boolean;
|
|
28
28
|
likeEscape: boolean;
|
|
29
|
+
maxIdentifierLength: number;
|
|
29
30
|
quoteTablePath(tablePath: string): string;
|
|
30
31
|
sqlGroupSetTable(groupSetCount: number): string;
|
|
31
32
|
sqlAnyValue(groupSet: number, fieldName: string): string;
|
|
@@ -97,6 +97,7 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
|
|
|
97
97
|
this.supportsComplexFilteredSources = false;
|
|
98
98
|
this.compoundObjectInSchema = false;
|
|
99
99
|
this.likeEscape = false;
|
|
100
|
+
this.maxIdentifierLength = 63;
|
|
100
101
|
}
|
|
101
102
|
quoteTablePath(tablePath) {
|
|
102
103
|
return tablePath
|
|
@@ -331,6 +332,15 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
|
|
|
331
332
|
else if (malloyType.type === 'string') {
|
|
332
333
|
return 'varchar';
|
|
333
334
|
}
|
|
335
|
+
else if (malloyType.type === 'record') {
|
|
336
|
+
throw new Error('PostgreSQL does not support CAST to record type');
|
|
337
|
+
}
|
|
338
|
+
else if (malloyType.type === 'array') {
|
|
339
|
+
if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
|
|
340
|
+
throw new Error('PostgreSQL does not support CAST to array of records');
|
|
341
|
+
}
|
|
342
|
+
return `${this.malloyTypeToSQLType(malloyType.elementTypeDef)}[]`;
|
|
343
|
+
}
|
|
334
344
|
return malloyType.type;
|
|
335
345
|
}
|
|
336
346
|
sqlTypeToMalloyType(rawSqlType) {
|
|
@@ -377,6 +377,27 @@ ${(0, utils_1.indent)(sql)}
|
|
|
377
377
|
return 'FLOAT64';
|
|
378
378
|
}
|
|
379
379
|
}
|
|
380
|
+
else if (malloyType.type === 'record') {
|
|
381
|
+
const typeSpec = [];
|
|
382
|
+
for (const f of malloyType.fields) {
|
|
383
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
384
|
+
typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return `STRUCT<${typeSpec.join(', ')}>`;
|
|
388
|
+
}
|
|
389
|
+
else if (malloyType.type === 'array') {
|
|
390
|
+
if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
|
|
391
|
+
const typeSpec = [];
|
|
392
|
+
for (const f of malloyType.fields) {
|
|
393
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
394
|
+
typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return `ARRAY<STRUCT<${typeSpec.join(', ')}>>`;
|
|
398
|
+
}
|
|
399
|
+
return `ARRAY<${this.malloyTypeToSQLType(malloyType.elementTypeDef)}>`;
|
|
400
|
+
}
|
|
380
401
|
return malloyType.type;
|
|
381
402
|
}
|
|
382
403
|
sqlTypeToMalloyType(sqlType) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, TinyParser, } from './dialect';
|
|
2
2
|
export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, TinyToken, } from './dialect';
|
|
3
|
-
export type {
|
|
4
|
-
export { isSourceDef, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
|
|
3
|
+
export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildManifest, BuildManifestEntry, } from './model';
|
|
4
|
+
export { isSourceDef, isAtomic, isBasicAtomic, isCompoundArrayData, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
|
|
5
5
|
export { malloyToQuery, MalloyTranslator, } from './lang';
|
|
6
6
|
export type { LogMessage, TranslateResponse } from './lang';
|
|
7
7
|
export { Model, Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, PreparedResult, Result, QueryMaterializer, CSVWriter, JSONWriter, Parse, DataWriter, Explore, InMemoryModelCache, CacheManager, } from './api/foundation';
|
|
8
8
|
export type { PreparedQuery, Field, AtomicField, ExploreField, QueryField, SortableField, DataArray, DataRecord, DataColumn, DataArrayOrRecord, Loggable, ModelMaterializer, DocumentTablePath, DocumentSymbol, ResultJSON, PreparedResultJSON, PreparedResultMaterializer, ExploreMaterializer, WriteStream, SerializedExplore, ModelCache, CachedModel, DateField, TimestampField, } from './api/foundation';
|
|
9
9
|
export type { QueryOptionsReader, RunSQLOptions } from './run_sql_options';
|
|
10
10
|
export type { EventStream, ModelString, ModelURL, QueryString, QueryURL, URLReader, InvalidationKey, } from './runtime_types';
|
|
11
|
-
export type { Connection, ConnectionConfig,
|
|
11
|
+
export type { Connection, ConnectionConfig, ConnectionParameterValue, FetchSchemaOptions, InfoConnection, LookupConnection, PersistSQLResults, PooledConnection, TestableConnection, StreamingConnection, } from './connection/types';
|
|
12
|
+
export { registerConnectionType, getConnectionProperties, getRegisteredConnectionTypes, readConnectionsConfig, writeConnectionsConfig, createConnectionsFromConfig, } from './connection/registry';
|
|
13
|
+
export type { ConnectionTypeFactory, ConnectionPropertyType, ConnectionPropertyDefinition, ConnectionTypeDef, ConnectionConfigEntry, ConnectionsConfig, } from './connection/registry';
|
|
12
14
|
export { toAsyncGenerator } from './connection_utils';
|
|
13
15
|
export { modelDefToModelInfo, sourceDefToSourceInfo, writeMalloyObjectToTag, extractMalloyObjectFromTag, } from './to_stable';
|
|
14
16
|
export * as API from './api';
|