Skip to content

Commit f786fdd

Browse files
committed
feat: Pluggable dialects support
Fixes #590
1 parent b38d1be commit f786fdd

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

packages/cubejs-schema-compiler/adapter/QueryBuilder.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@ const ADAPTERS = {
3434
elasticsearch
3535
};
3636
exports.query = (compilers, dbType, queryOptions) => {
37-
if (!ADAPTERS[dbType]) {
37+
if (!queryOptions.dialectClass && !ADAPTERS[dbType]) {
3838
return null;
3939
}
4040

41-
return new (ADAPTERS[dbType])(compilers, {
41+
return new (queryOptions.dialectClass || ADAPTERS[dbType])(compilers, {
4242
...queryOptions,
43-
externalQueryClass: queryOptions.externalDbType && ADAPTERS[queryOptions.externalDbType]
43+
externalQueryClass: queryOptions.externalDialectClass ||
44+
queryOptions.externalDbType && ADAPTERS[queryOptions.externalDbType]
4445
});
4546
};

packages/cubejs-server-core/core/CompilerApi.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class CompilerApi {
66
constructor(repository, dbType, options) {
77
this.repository = repository;
88
this.dbType = dbType;
9+
this.dialectClass = options.dialectClass;
910
this.options = options || {};
1011
this.allowNodeRequire = options.allowNodeRequire == null ? true : options.allowNodeRequire;
1112
this.logger = this.options.logger;
@@ -47,12 +48,17 @@ class CompilerApi {
4748
return this.dbType;
4849
}
4950

51+
getDialectClass(dataSource) {
52+
return this.dialectClass && this.dialectClass({ dataSource: dataSource || 'default' });
53+
}
54+
5055
async getSql(query, options) {
5156
options = options || {};
5257
const { includeDebugInfo } = options;
5358
const dbType = this.getDbType('default');
59+
const dialectClass = this.getDialectClass('default');
5460
const compilers = await this.getCompilers({ requestId: query.requestId });
55-
let sqlGenerator = this.createQuery(compilers, dbType, query);
61+
let sqlGenerator = this.createQuery(compilers, dbType, dialectClass, query);
5662
if (!sqlGenerator) {
5763
throw new Error(`Unknown dbType: ${dbType}`);
5864
}
@@ -61,7 +67,12 @@ class CompilerApi {
6167

6268
if (dataSource !== 'default' && dbType !== this.getDbType(dataSource)) {
6369
// TODO consider more efficient way than instantiating query
64-
sqlGenerator = this.createQuery(compilers, this.getDbType(dataSource), query);
70+
sqlGenerator = this.createQuery(
71+
compilers,
72+
this.getDbType(dataSource),
73+
this.getDialectClass(dataSource),
74+
query
75+
);
6576
}
6677

6778
return compilers.compiler.withQuery(sqlGenerator, () => ({
@@ -85,11 +96,13 @@ class CompilerApi {
8596
return cubeEvaluator.scheduledPreAggregations();
8697
}
8798

88-
createQuery(compilers, dbType, query) {
99+
createQuery(compilers, dbType, dialectClass, query) {
89100
return QueryBuilder.query(
90101
compilers,
91102
dbType, {
92103
...query,
104+
dialectClass,
105+
externalDialectClass: this.options.externalDialectClass,
93106
externalDbType: this.options.externalDbType,
94107
preAggregationsSchema: this.preAggregationsSchema,
95108
allowUngroupedWithoutPrimaryKey: this.allowUngroupedWithoutPrimaryKey

packages/cubejs-server-core/core/index.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ class CubejsServerCore {
172172
options = options || {};
173173
options = {
174174
driverFactory: () => CubejsServerCore.createDriver(options.dbType),
175+
dialectFactory: () => CubejsServerCore.lookupDriverClass(options.dbType).dialectClass &&
176+
CubejsServerCore.lookupDriverClass(options.dbType).dialectClass(),
175177
apiSecret: process.env.CUBEJS_API_SECRET,
176178
dbType: process.env.CUBEJS_DB_TYPE,
177179
devServer: process.env.NODE_ENV !== 'production',
@@ -188,6 +190,8 @@ class CubejsServerCore {
188190
this.options = options;
189191
this.driverFactory = options.driverFactory;
190192
this.externalDriverFactory = options.externalDriverFactory;
193+
this.dialectFactory = options.dialectFactory;
194+
this.externalDialectFactory = options.externalDialectFactory;
191195
this.apiSecret = options.apiSecret;
192196
this.schemaPath = options.schemaPath || process.env.CUBEJS_SCHEMA_PATH || 'schema';
193197
this.dbType = options.dbType;
@@ -419,6 +423,9 @@ class CubejsServerCore {
419423
this.repositoryFactory(context), {
420424
dbType: (dataSourceContext) => this.contextToDbType({ ...context, ...dataSourceContext }),
421425
externalDbType: this.contextToExternalDbType(context),
426+
dialectClass: (dataSourceContext) => this.dialectFactory &&
427+
this.dialectFactory({ ...context, ...dataSourceContext }),
428+
externalDialectClass: this.externalDialectFactory && this.externalDialectFactory(context),
422429
schemaVersion: currentSchemaVersion,
423430
preAggregationsSchema: this.preAggregationsSchema(context),
424431
context
@@ -477,7 +484,9 @@ class CubejsServerCore {
477484
externalDbType: options.externalDbType,
478485
preAggregationsSchema: options.preAggregationsSchema,
479486
allowUngroupedWithoutPrimaryKey: this.options.allowUngroupedWithoutPrimaryKey,
480-
compileContext: options.context
487+
compileContext: options.context,
488+
dialectClass: options.dialectClass,
489+
externalDialectClass: options.externalDialectClass,
481490
});
482491
}
483492

@@ -506,15 +515,21 @@ class CubejsServerCore {
506515

507516
static createDriver(dbType) {
508517
checkEnvForPlaceholders();
518+
return new (CubejsServerCore.lookupDriverClass(dbType))();
519+
}
520+
521+
static lookupDriverClass(dbType) {
509522
// eslint-disable-next-line global-require,import/no-dynamic-require
510-
return new (require(CubejsServerCore.driverDependencies(dbType || process.env.CUBEJS_DB_TYPE)))();
523+
return require(CubejsServerCore.driverDependencies(dbType || process.env.CUBEJS_DB_TYPE));
511524
}
512525

513526
static driverDependencies(dbType) {
514-
if (!DriverDependencies[dbType]) {
515-
throw new Error(`Unsupported db type: ${dbType}`);
527+
if (DriverDependencies[dbType]) {
528+
return DriverDependencies[dbType];
529+
} else if (fs.existsSync(path.join('node_modules', `${dbType}-cubejs-driver`))) {
530+
return `${dbType}-cubejs-driver`;
516531
}
517-
return DriverDependencies[dbType];
532+
throw new Error(`Unsupported db type: ${dbType}`);
518533
}
519534

520535
testConnections() {

0 commit comments

Comments
 (0)