From 7d070e0326e46316ee15b4d578be64c6987f8e21 Mon Sep 17 00:00:00 2001 From: Konstantin Burkalev Date: Thu, 27 Mar 2025 13:20:16 +0200 Subject: [PATCH 1/2] fix(schema-compiler): make compileSchema() async-debounced --- .../cubejs-server-core/src/core/CompilerApi.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/cubejs-server-core/src/core/CompilerApi.js b/packages/cubejs-server-core/src/core/CompilerApi.js index 71c5517e5976e..9bc5b82393241 100644 --- a/packages/cubejs-server-core/src/core/CompilerApi.js +++ b/packages/cubejs-server-core/src/core/CompilerApi.js @@ -1,8 +1,9 @@ import crypto from 'crypto'; import R from 'ramda'; +import { v4 as uuidv4, parse as uuidParse } from 'uuid'; import { createQuery, compile, queryClass, PreAggregations, QueryFactory } from '@cubejs-backend/schema-compiler'; -import { v4 as uuidv4, parse as uuidParse, stringify as uuidStringify } from 'uuid'; import { NativeInstance } from '@cubejs-backend/native'; +import { asyncDebounce } from '@cubejs-backend/shared'; export class CompilerApi { /** @@ -29,6 +30,7 @@ export class CompilerApi { this.sqlCache = options.sqlCache; this.standalone = options.standalone; this.nativeInstance = this.createNativeInstance(); + this.compileSchemaDebounced = asyncDebounce(this.compileSchema.bind(this)); } setGraphQLSchema(schema) { @@ -59,7 +61,7 @@ export class CompilerApi { } if (!this.compilers || this.compilerVersion !== compilerVersion) { - this.compilers = this.compileSchema(compilerVersion, requestId).catch(e => { + this.compilers = this.compileSchemaDebounced(compilerVersion, requestId).catch(e => { this.compilers = undefined; throw e; }); @@ -125,7 +127,7 @@ export class CompilerApi { } getDialectClass(dataSource = 'default', dbType) { - return this.dialectClass && this.dialectClass({ dataSource, dbType }); + return this.dialectClass?.({ dataSource, dbType }); } async getSqlGenerator(query, dataSource) { @@ -171,8 +173,8 @@ export class CompilerApi { external: sqlGenerator.externalPreAggregationQuery(), sql: sqlGenerator.buildSqlAndParams(exportAnnotatedSql), lambdaQueries: sqlGenerator.buildLambdaQuery(), - timeDimensionAlias: sqlGenerator.timeDimensions[0] && sqlGenerator.timeDimensions[0].unescapedAliasName(), - timeDimensionField: sqlGenerator.timeDimensions[0] && sqlGenerator.timeDimensions[0].dimension, + timeDimensionAlias: sqlGenerator.timeDimensions[0]?.unescapedAliasName(), + timeDimensionField: sqlGenerator.timeDimensions[0]?.dimension, order: sqlGenerator.order, cacheKeyQueries: sqlGenerator.cacheKeyQueries(), preAggregations: sqlGenerator.preAggregations.preAggregationsDescription(), @@ -206,7 +208,7 @@ export class CompilerApi { } roleMeetsConditions(evaluatedConditions) { - if (evaluatedConditions && evaluatedConditions.length) { + if (evaluatedConditions?.length) { return evaluatedConditions.reduce((a, b) => { if (typeof b !== 'boolean') { throw new Error(`Access policy condition must return boolean, got ${JSON.stringify(b)}`); From acc07efd62a1fc2a9e8341ac1ae4951ed6713ff5 Mon Sep 17 00:00:00 2001 From: Konstantin Burkalev Date: Thu, 27 Mar 2025 13:26:42 +0200 Subject: [PATCH 2/2] get rid of ramda --- packages/cubejs-server-core/src/core/CompilerApi.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/cubejs-server-core/src/core/CompilerApi.js b/packages/cubejs-server-core/src/core/CompilerApi.js index 9bc5b82393241..e1114d5a0322b 100644 --- a/packages/cubejs-server-core/src/core/CompilerApi.js +++ b/packages/cubejs-server-core/src/core/CompilerApi.js @@ -1,5 +1,4 @@ import crypto from 'crypto'; -import R from 'ramda'; import { v4 as uuidv4, parse as uuidParse } from 'uuid'; import { createQuery, compile, queryClass, PreAggregations, QueryFactory } from '@cubejs-backend/schema-compiler'; import { NativeInstance } from '@cubejs-backend/native'; @@ -109,9 +108,9 @@ export class CompilerApi { async createQueryFactory(compilers) { const { cubeEvaluator } = compilers; - const cubeToQueryClass = R.fromPairs( + const cubeToQueryClass = Object.fromEntries( await Promise.all( - cubeEvaluator.cubeNames().map(async cube => { + cubeEvaluator.cubeNames().map(async (cube) => { const dataSource = cubeEvaluator.cubeFromPath(cube).dataSource ?? 'default'; const dbType = await this.getDbType(dataSource); const dialectClass = this.getDialectClass(dataSource, dbType);