cube.js 动态schema 编译处理

时间:2021-01-24 01:09:35   收藏:0   阅读:44

cube.js 支持动态schema 的编译生成(只执行一次)

一些约定

基于asyncModule() 函数,自定义的schema 需要放schema 目录下(当然可以自己扩展resopitryFactory)
sql 以及drillMembers 需要是函数,函数的签名为()=>string

参考使用

 
export const convertStringPropToFunction = (propNames, dimensionDefinition) => {
  const newResult = { ...dimensionDefinition }
    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 {
      ...result,
      [dimensionName]: convertStringPropToFunction(
        [‘sql‘],
        dimensionDefinition
      )
    }
    }, {})
  };
 
 
export const transformMeasures = (measures) => {
  return Object.keys(measures).reduce((result, dimensionName) => {
    const dimensionDefinition = measures[dimensionName]
      return {
      ...result,
      [dimensionName]: convertStringPropToFunction(
        [‘sql‘, ‘drillMembers‘],
        dimensionDefinition
      )
    }
    }, {})
  };
 
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"
  }
]

运行&&效果

 
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);
    });
}

说明

完整代码可以参考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(...names, `return \`${this}\`;`)(...vals);
    }

参考资料

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

原文:https://www.cnblogs.com/rongfengliang/p/14319625.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!