cube.js 动态schema 编译处理
cube.js 支持动态schema 的编译生成(只执行一次)
一些约定
基于asyncModule() 函数,自定义的schema 需要放schema 目录下(当然可以自己扩展resopitryFactory)
sql 以及drillMembers 需要是函数,函数的签名为()=>string
参考使用
- schema 帮助函数
sql 函数以及drillMembers 的处理,按照上边的约定
schema/utils.js
export const convertStringPropToFunction = (propNames, dimensionDefinition) => {
const newResult = {
propNames.forEach((propName) => {
const propValue = newResult[propName]
if (!propValue) {
return
}
newResult[propName] = () => propValue
})
return newResult
};
export const transformDimensions = (dimensions) => {
return Object.keys(dimensions).reduce((result, dimensionName) => {
const dimensionDefinition = dimensions[dimensionName]
return {
[dimensionName]: convertStringPropToFunction(
['sql'],
dimensionDefinition
)
}
}, {})
};
export const transformMeasures = (measures) => {
return Object.keys(measures).reduce((result, dimensionName) => {
const dimensionDefinition = measures[dimensionName]
return {
[dimensionName]: convertStringPropToFunction(
['sql', 'drillMembers'],
dimensionDefinition
)
}
}, {})
};
- schema 动态生成
基于node-fetch 通过api 获取定义asyncModule
是比较重要的
const fetch = require('node-fetch');
import {
transformDimensions,
transformMeasures,
} from './utils';
asyncModule(async () => {
const dynamicCubes = await (
await fetch('http://localhost:8080/app.json')
).json();
console.log(dynamicCubes);
dynamicCubes.forEach((dynamicCube) => {
const dimensions = transformDimensions(dynamicCube.dimensions);
const measures = transformMeasures(dynamicCube.measures);
cube(dynamicCube.title, {
sql: dynamicCube.sql,
dimensions,
measures,
preAggregations: {
main: {
type: `originalSql`,
},
},
});
});
});
app.json
[
{
"preAggregations": {
"mydemo": {
"type": "autoRollup",
"measureReferences": [
"DynamicCubeSchema.price"
],
"dimensionReferences": [
"name"
],
"external": true
}
},
"dimensions": {
"name": {
"sql": "name",
"type": "string"
}
},
"measures": {
"price": {
"drillMembers": [
"name",
"id"
],
"type": "count"
}
},
"title": "DynamicCubeSchema",
"sql": "SELECT * FROM demoapp"
}
]
运行&&效果
- 入口
index.js 基于throng 提升多线程能力
const CubejsServer = require('@cubejs-backend/server');
const cubejs = require("./cube")
const throng = require('throng')
const WORKERS = process.env.WEB_CONCURRENCY || 2
const server = new CubejsServer(cubejs);
throng(WORKERS, start)
function start(){
server
.listen()
.then(({ version, port }) => {
console.log(`🚀 Cube.js server (${version}) is listening on ${port}`);
})
.catch((e) => {
console.error('Fatal error during server start: ');
console.error(e.stack || e);
});
}
- 启动
需要先启动提供动态schema 的api 然后提供cube.js 效果
说明
完整代码可以参考GitHub https://github.com/rongfengliang/cubejs-pre-age/tree/v2 包含了cubestore的使用,但是一些不太好的地方是es6 string 模版的
支持,因为api 的特性,但是我们可以通过扩展function 支持,参考
String.prototype.interpolate = function(params) {
const names = Object.keys(params);
const vals = Object.values(params);
return new Function(
}
参考资料
https://cube.dev/docs/schema-execution-environment#cube-js-globals-cube-and-others
https://cube.dev/docs/schema/dynamic-schema-creation
https://github.com/rongfengliang/cubejs-pre-age/tree/v2
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2017-01-23 Automating CSS Regression Testing
2014-01-23 vertx.io 与nodejs 一个简单的性能比较