@effectuate/cubejs-mongosql-driver 1.0.0
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/LICENSE +23 -0
- package/README.md +579 -0
- package/dist/MongoSqlDriver.d.ts +238 -0
- package/dist/MongoSqlDriver.d.ts.map +1 -0
- package/dist/MongoSqlDriver.js +745 -0
- package/dist/MongoSqlDriver.js.map +1 -0
- package/dist/MongoSqlQuery.d.ts +353 -0
- package/dist/MongoSqlQuery.d.ts.map +1 -0
- package/dist/MongoSqlQuery.js +551 -0
- package/dist/MongoSqlQuery.js.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +298 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/native.d.ts +104 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +192 -0
- package/dist/native.js.map +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +24 -0
- package/dist/types.js.map +1 -0
- package/index.d.ts +160 -0
- package/index.js +316 -0
- package/package.json +108 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MongoSqlDriver — Cube data source driver for MongoDB via MongoSQL.
|
|
3
|
+
*
|
|
4
|
+
* See SPEC.md FR-1 (driver protocol), FR-7 (env-var configuration), and
|
|
5
|
+
* ARCHITECTURE.md §2.1.
|
|
6
|
+
*
|
|
7
|
+
* BaseDriver method-list audit (against
|
|
8
|
+
* `@cubejs-backend/base-driver/dist/src/BaseDriver.d.ts`):
|
|
9
|
+
*
|
|
10
|
+
* Required by DriverInterface (we override these):
|
|
11
|
+
* - query(sql, values?, options?) — REQUIRED, override (delegates + flattens)
|
|
12
|
+
* - testConnection() — REQUIRED, override (lazy native init)
|
|
13
|
+
* - release() — override (closes native client)
|
|
14
|
+
* - tablesSchema() — override (delegate to native)
|
|
15
|
+
* - downloadQueryResults(sql, ...) — override → memory shape; streamImport ignored
|
|
16
|
+
* (capabilities().streamImport=false; see below)
|
|
17
|
+
* - capabilities() — override → no export bucket / streaming source
|
|
18
|
+
* - nowTimestamp() — INHERIT (Date.now())
|
|
19
|
+
* - stream(table, values, opts) — NOT implemented; `streamImport: false`
|
|
20
|
+
* advertises this. Cube routes the
|
|
21
|
+
* pre-agg upload path through
|
|
22
|
+
* `downloadQueryResults` instead.
|
|
23
|
+
*
|
|
24
|
+
* Schema-introspection helpers (BaseDriver default reads information_schema —
|
|
25
|
+
* MongoSQL doesn't expose one, so we route every shape through the native
|
|
26
|
+
* cached `tablesSchema()` rendering):
|
|
27
|
+
* - tablesSchema() — override (full snapshot, bulk path)
|
|
28
|
+
* - getSchemas() — override (DB list from tablesSchema)
|
|
29
|
+
* - getTablesForSpecificSchemas(...) — override (filter tablesSchema by db)
|
|
30
|
+
* - getColumnsForSpecificTables(...) — override (filter tablesSchema by table)
|
|
31
|
+
* - capabilities().incrementalSchemaLoading=true — opts Cube into the
|
|
32
|
+
* granular three-method path; SQL
|
|
33
|
+
* information_schema queries are
|
|
34
|
+
* never issued against mongosql.
|
|
35
|
+
* - getTablesQuery(schema) — N/A — runs SQL against information_schema
|
|
36
|
+
* - informationSchemaQuery() — N/A (protected default)
|
|
37
|
+
* - tableColumnTypes(table) — INHERIT (uses query()); only needed for
|
|
38
|
+
* uploadTableWithIndexes path which we reject
|
|
39
|
+
*
|
|
40
|
+
* Mutation methods (read-only driver — explicit refusal beats silent no-op):
|
|
41
|
+
* - createSchemaIfNotExists(schemaName) — throw
|
|
42
|
+
* - dropTable(tableName, options?) — throw
|
|
43
|
+
* - uploadTable(...) — throw
|
|
44
|
+
* - uploadTableWithIndexes(...) — throw
|
|
45
|
+
* - createTable(...) — throw
|
|
46
|
+
* - createTableRaw(...) — throw
|
|
47
|
+
* - loadPreAggregationIntoTable(...) — INHERIT default (delegates to query())
|
|
48
|
+
* so partitioned/incremental pre-aggs work
|
|
49
|
+
*
|
|
50
|
+
* Bucket-export (no MongoDB equivalent — SPEC FR-6 says EXPORT_BUCKET unsupported):
|
|
51
|
+
* - downloadTable(...) — INHERIT (uses query(); fine for memory path)
|
|
52
|
+
* - parseBucketUrl / extractFilesFromS3 / extractFilesFromGCS / extractFilesFromAzure
|
|
53
|
+
* — N/A (only invoked via unload paths we don't expose)
|
|
54
|
+
* - readOnly() — override → true (signals to Cube/Cube Store)
|
|
55
|
+
*
|
|
56
|
+
* SQL-shape helpers used by Cube but irrelevant to MongoSQL (the dialect class
|
|
57
|
+
* handles quoting; the driver does not echo SQL strings):
|
|
58
|
+
* - quoteIdentifier(id) — INHERIT (default uses '"', dialect class
|
|
59
|
+
* in MongoSqlQuery overrides to backticks)
|
|
60
|
+
* - param(i) — INHERIT
|
|
61
|
+
* - wrapQueryWithLimit({query, limit}) — INHERIT (mutates the object in place)
|
|
62
|
+
*
|
|
63
|
+
* Static:
|
|
64
|
+
* - dialectClass() — override → MongoSqlQuery
|
|
65
|
+
*/
|
|
66
|
+
import { BaseDriver } from '@cubejs-backend/base-driver';
|
|
67
|
+
import type { DownloadQueryResultsOptions, DownloadQueryResultsResult, DownloadTableData, DriverCapabilities, ExternalCreateTableOptions, IndexesSQL, QueryColumnsResult, QueryOptions, QuerySchemasResult, QueryTablesResult, TableColumn, TableStructure } from '@cubejs-backend/base-driver';
|
|
68
|
+
import { type TablesSchema } from './native.js';
|
|
69
|
+
import { MongoSqlQuery } from './MongoSqlQuery.js';
|
|
70
|
+
import type { MongoSqlConfig } from './types.js';
|
|
71
|
+
/**
|
|
72
|
+
* Cube driver class. Cube instantiates this when CUBEJS_DB_TYPE=mongosql.
|
|
73
|
+
*
|
|
74
|
+
* Construction is cheap and pure: env vars are read and validated, but no
|
|
75
|
+
* native client is created. The native client is created lazily on the first
|
|
76
|
+
* `testConnection()` / `query()` / `tablesSchema()` call so that throwing in
|
|
77
|
+
* the constructor reports config errors crisply (Cube wraps construction
|
|
78
|
+
* exceptions less helpfully than runtime ones).
|
|
79
|
+
*
|
|
80
|
+
* **Configuration env vars (see `./config.ts` and README "Configuration"):**
|
|
81
|
+
*
|
|
82
|
+
* Cube-standard (`CUBEJS_DB_*`):
|
|
83
|
+
* - `CUBEJS_DB_URL` / `CUBEJS_DB_URI` — full MongoDB connection string
|
|
84
|
+
* - `CUBEJS_DB_HOST` / `_PORT` / `_USER` / `_PASS` / `_NAME` — composed URI parts
|
|
85
|
+
* - `CUBEJS_DB_NAME` — database (also required separately by the driver)
|
|
86
|
+
* - `CUBEJS_DB_SSL` — `tls=true|false`
|
|
87
|
+
* - `CUBEJS_DB_MAX_POOL` / `_MIN_POOL` — `maxPoolSize` / `minPoolSize`
|
|
88
|
+
* - `CUBEJS_DB_QUERY_TIMEOUT` — per-query `maxTimeMS` (duration string or ms)
|
|
89
|
+
* - `CUBEJS_DB_IDLE_TIMEOUT` — `maxIdleTimeMS` (duration string or ms)
|
|
90
|
+
*
|
|
91
|
+
* MongoDB-specific (`CUBEJS_MONGOSQL_*`):
|
|
92
|
+
* - `_SCHEMA_SOURCE` — `collection` (default), `file`, or `atlas-sql`
|
|
93
|
+
* - `_SCHEMA_FILE` — path (required if `_SCHEMA_SOURCE=file`)
|
|
94
|
+
* - `_SCHEMA_REFRESH_SEC` — background refresh cadence in seconds
|
|
95
|
+
* - `_SCHEMA_FAIL_OPEN` — `true` to soft-fail initial schema load
|
|
96
|
+
* - `_QUERY_TIMEOUT_MS` — (legacy) bare-ms timeout; overridden by
|
|
97
|
+
* `CUBEJS_DB_QUERY_TIMEOUT` when both set
|
|
98
|
+
* - `_MAX_ROWS` — row cap per query
|
|
99
|
+
* - `_APP_NAME` — `appName` (shows up in `serverStatus().connections`)
|
|
100
|
+
* - `_MAX_CONNECTING` — `maxConnecting`
|
|
101
|
+
* - `_WAIT_QUEUE_TIMEOUT_MS` — `waitQueueTimeoutMS`
|
|
102
|
+
* - `_CONNECT_TIMEOUT_MS` — `connectTimeoutMS`
|
|
103
|
+
* - `_SOCKET_TIMEOUT_MS` — `socketTimeoutMS`
|
|
104
|
+
* - `_SERVER_SELECTION_TIMEOUT_MS` — `serverSelectionTimeoutMS`
|
|
105
|
+
* - `_HEARTBEAT_FREQUENCY_MS` — `heartbeatFrequencyMS`
|
|
106
|
+
* - `_RETRY_WRITES` / `_RETRY_READS` — `retryWrites` / `retryReads`
|
|
107
|
+
* - `_COMPRESSORS` — `compressors`
|
|
108
|
+
*
|
|
109
|
+
* User-set URI params (those already encoded in `CUBEJS_DB_URL/URI`) ALWAYS
|
|
110
|
+
* win — we only append env-driven params for keys the URI doesn't already
|
|
111
|
+
* specify.
|
|
112
|
+
*/
|
|
113
|
+
export declare class MongoSqlDriver extends BaseDriver {
|
|
114
|
+
private readonly resolvedConfig;
|
|
115
|
+
private client;
|
|
116
|
+
constructor(config?: Partial<MongoSqlConfig>);
|
|
117
|
+
/** Test hook: surface the config the driver resolved from constructor + env. */
|
|
118
|
+
_config(): Readonly<MongoSqlConfig>;
|
|
119
|
+
testConnection(): Promise<void>;
|
|
120
|
+
query<R = unknown>(sql: string, values?: unknown[], options?: QueryOptions): Promise<R[]>;
|
|
121
|
+
tablesSchema(): Promise<TablesSchema>;
|
|
122
|
+
/**
|
|
123
|
+
* Cube's incremental-schema-loading entry point #1.
|
|
124
|
+
*
|
|
125
|
+
* Returns the list of schemas (databases) we expose. BaseDriver's
|
|
126
|
+
* default issues `SELECT table_schema ... FROM information_schema.tables`,
|
|
127
|
+
* which MongoSQL has no equivalent for. We re-render from the cached
|
|
128
|
+
* `tablesSchema()` snapshot — which the native side already keeps
|
|
129
|
+
* fresh via the background refresh task (SPEC FR-3 / ARCHITECTURE §3.2).
|
|
130
|
+
* Each call into `client.tablesSchema()` returns a fresh clone of the
|
|
131
|
+
* cached snapshot, so the cost is O(N) in catalog column count — for
|
|
132
|
+
* the typical few-thousand-cell catalog this is sub-millisecond on the
|
|
133
|
+
* hot path (no native I/O, no `__sql_schemas` round-trip).
|
|
134
|
+
*
|
|
135
|
+
* Driver only ever exposes the database configured at construction
|
|
136
|
+
* (FR-7 — `CUBEJS_DB_NAME`), so the returned list has at most one
|
|
137
|
+
* entry. An empty list is possible if no schemas have been loaded
|
|
138
|
+
* yet (e.g. `testConnection()` was never called or the schema source
|
|
139
|
+
* is empty); Cube handles that case the same way it would for the
|
|
140
|
+
* SQL path's empty resultset.
|
|
141
|
+
*/
|
|
142
|
+
getSchemas(): Promise<QuerySchemasResult[]>;
|
|
143
|
+
/**
|
|
144
|
+
* Cube's incremental-schema-loading entry point #2.
|
|
145
|
+
*
|
|
146
|
+
* For each requested schema, returns its table list from the cached
|
|
147
|
+
* `tablesSchema()`. Schemas the snapshot doesn't know about are
|
|
148
|
+
* silently dropped — mirrors the SQL path's "WHERE schema IN (...)"
|
|
149
|
+
* which would naturally exclude unknown names. Passing an empty
|
|
150
|
+
* `schemas` array returns an empty result with no native I/O cost
|
|
151
|
+
* beyond a single cache read.
|
|
152
|
+
*/
|
|
153
|
+
getTablesForSpecificSchemas(schemas: QuerySchemasResult[]): Promise<QueryTablesResult[]>;
|
|
154
|
+
/**
|
|
155
|
+
* Cube's incremental-schema-loading entry point #3.
|
|
156
|
+
*
|
|
157
|
+
* For each requested `(schema_name, table_name)`, returns one row
|
|
158
|
+
* per column with `column_name` and `data_type`. `data_type` is the
|
|
159
|
+
* Cube generic-type string emitted by the native side (`string`,
|
|
160
|
+
* `int`, `bigint`, `decimal`, `boolean`, `timestamp`, `text`) — the
|
|
161
|
+
* same values that surface in `tablesSchema()`. Unknown tables are
|
|
162
|
+
* silently dropped, same contract as `getTablesForSpecificSchemas`.
|
|
163
|
+
*
|
|
164
|
+
* `attributes` is forwarded verbatim from the column descriptor IF
|
|
165
|
+
* a future native version supplies one — but the Rust `do_tables_schema`
|
|
166
|
+
* (crates/native/src/client.rs:314) always emits `attributes: []` today,
|
|
167
|
+
* so in production this is effectively always an empty array. We do
|
|
168
|
+
* not emit `primaryKey` automatically — MongoDB's implicit `_id` IS a
|
|
169
|
+
* primary key, but tagging it without explicit schema annotation would
|
|
170
|
+
* surface as a foreign-key target in Cube's relationship inference and
|
|
171
|
+
* break heuristic joins. The TS-side forwarding path exists for a
|
|
172
|
+
* future Rust change where `__sql_schemas` documents' attribute fields
|
|
173
|
+
* are propagated; callers that need the tag today still must encode
|
|
174
|
+
* it explicitly in their __sql_schemas document AND in a Rust patch
|
|
175
|
+
* that surfaces it through `ColumnSchema::attributes`.
|
|
176
|
+
*
|
|
177
|
+
* `foreign_keys` is not derivable from MongoDB schema documents — the
|
|
178
|
+
* field is omitted (Cube's `QueryColumnsResult` declares it as
|
|
179
|
+
* optional via the spread of `TableColumnQueryResult`).
|
|
180
|
+
*/
|
|
181
|
+
getColumnsForSpecificTables(tables: QueryTablesResult[]): Promise<QueryColumnsResult[]>;
|
|
182
|
+
release(): Promise<void>;
|
|
183
|
+
downloadQueryResults(sql: string, values?: unknown[], options?: DownloadQueryResultsOptions): Promise<DownloadQueryResultsResult>;
|
|
184
|
+
capabilities(): DriverCapabilities;
|
|
185
|
+
readOnly(): boolean;
|
|
186
|
+
createSchemaIfNotExists(_schemaName: string): Promise<void>;
|
|
187
|
+
dropTable(_tableName: string, _options?: QueryOptions): Promise<unknown>;
|
|
188
|
+
uploadTable(_table: string, _columns: TableStructure, _tableData: DownloadTableData): Promise<void>;
|
|
189
|
+
uploadTableWithIndexes(_table: string, _columns: TableStructure, _tableData: DownloadTableData, _indexesSql: IndexesSQL, _uniqueKeyColumns: string[] | null, _queryTracingObj: unknown, _externalOptions: ExternalCreateTableOptions): Promise<void>;
|
|
190
|
+
createTable(_quotedTableName: string, _columns: TableColumn[]): Promise<void>;
|
|
191
|
+
createTableRaw(_query: string): Promise<void>;
|
|
192
|
+
static dialectClass(): typeof MongoSqlQuery;
|
|
193
|
+
private ensureClient;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Make every row's key set identical by null-filling missing keys.
|
|
197
|
+
*
|
|
198
|
+
* **Mutates `rows` in place** — callers must not retain references to
|
|
199
|
+
* the pre-normalize array if they need the original sparse shape. The
|
|
200
|
+
* returned reference is the same array.
|
|
201
|
+
*
|
|
202
|
+
* **Why this exists.** Mongosql's `$project` stage that references a
|
|
203
|
+
* nested-path expression (e.g. `agent.displayName` on a docs collection)
|
|
204
|
+
* OMITS the field entirely when the source path is missing on the
|
|
205
|
+
* underlying document — it does not emit `null`. This bites downstream
|
|
206
|
+
* consumers whenever the row at index 0 happens to be sparser than later
|
|
207
|
+
* rows; `ORDER BY <nested-field> ASC` is the most common way this
|
|
208
|
+
* surfaces, but any query whose row 0 lacks a key that later rows have
|
|
209
|
+
* triggers the same.
|
|
210
|
+
*
|
|
211
|
+
* Downstream consumers (notably Cube's native `getFinalQueryResult`
|
|
212
|
+
* transform in `@cubejs-backend/native`) compile their row→member
|
|
213
|
+
* extraction plan from the keys present in **row 0**. A sparse row 0
|
|
214
|
+
* causes Cube to drop the column from every row in the response — even
|
|
215
|
+
* rows that DO have the value. Reproduced empirically against the
|
|
216
|
+
* `configs` collection (`SELECT id, agent_display_name FROM configs ...
|
|
217
|
+
* ORDER BY agent_display_name ASC LIMIT 500` → 500 rows, all missing
|
|
218
|
+
* `configs.agent_display_name`, even though 497/500 source docs have it).
|
|
219
|
+
*
|
|
220
|
+
* **Fix shape.** Take the union of keys across all rows and null-fill
|
|
221
|
+
* each row so every row has every key. We can't simply look at `row[0]`
|
|
222
|
+
* because that's the symptom. Iteration is O(rows × cols). At the
|
|
223
|
+
* `MAX_ROWS=100000` pre-agg cap with a ~20-column projection this is
|
|
224
|
+
* roughly 2M property-existence checks and stays under 100ms in practice.
|
|
225
|
+
*
|
|
226
|
+
* `downloadQueryResults` uses the authoritative type list instead of
|
|
227
|
+
* a key union (the union would miss columns absent from every row); that
|
|
228
|
+
* variant is implemented inline at the call site, not via this helper.
|
|
229
|
+
*/
|
|
230
|
+
declare function normalizeRowShape<R>(rows: Array<Record<string, unknown>>): R[];
|
|
231
|
+
/**
|
|
232
|
+
* Test-only export. Lets `tests/unit/driver.test.ts` exercise the
|
|
233
|
+
* key-union null-fill in isolation without spinning up the driver.
|
|
234
|
+
* Not part of the public API.
|
|
235
|
+
*/
|
|
236
|
+
export declare const _normalizeRowShapeForTests: typeof normalizeRowShape;
|
|
237
|
+
export {};
|
|
238
|
+
//# sourceMappingURL=MongoSqlDriver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MongoSqlDriver.d.ts","sourceRoot":"","sources":["../src/MongoSqlDriver.ts"],"names":[],"mappings":"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"}
|