• cube.js 一个隐藏的schema 扩展服务


    cube.js 支持一种基于package.json deps 模式的schema 发现,但是目前默认是没有开启的,今天在开发基于
    s3扩展的时候觉得也有必要支持下,所以基于es6 的默认函数参数模式,将 async dataSchemaFiles(includeDependencies=true)
    这样默认就可以集成基于npm包的schema 发现了

    npm包约定

    包的名称需要是以-schema 结尾的,同时加载的是.js 的文件(支持递归)

    参考s3支持的扩展代码

    参考了官方的FileRepository 对于npm 包的处理

     
    const Minio = require('minio')
    const streamToPromise = require('stream-to-promise');
    const path = require('path');
    const fs = require('fs-extra');
    const R = require('ramda');
    /**
     * mys3 file repository
     */
    class S3FileRepository {
        // init config with env
        constructor() {
            this.minioClient = new Minio.Client({
                endPoint: process.env.cube_s3_endpoint,
                port: parseInt(process.env.cube_s3_port),
                useSSL: process.env.cube_s3_ssl == "true" ? true : false,
                accessKey: process.env.cube_s3_accesskey,
                secretKey: process.env.cube_s3_secretkey
            });
        }
        async dataSchemaFiles(includeDependencies=true) {
            var localminioClient = this.minioClient
            var bucket = process.env.cube_s3_bucket
            var Files = await streamToPromise(localminioClient.listObjectsV2(bucket, "", true))
            var fileContents = []
            for (const file of Files) {
                try {
                    const fileBuffer = await streamToPromise(await localminioClient.getObject(bucket, file.name))
                    let fileItemContent = fileBuffer.toString('utf-8');
                    fileContents.push({ fileName: file.name, content: fileItemContent })
                }
                catch (e) {
                    console.log(e)
                }
            }
            if (includeDependencies) {
                fileContents = fileContents.concat(await this.readModules());
            }
            return fileContents;
        }
        async readModules() {
            const packageJson = JSON.parse(await fs.readFile('package.json', 'utf-8'));
            const files = await Promise.all(
                Object.keys(packageJson.dependencies).map(async module => {
                    if (R.endsWith('-schema', module)) {
                        return this.readModuleFiles(path.join('node_modules', module));
                    }
                    return [];
                })
            );
            return files.reduce((a, b) => a.concat(b));
        }
        async readModuleFiles(modulePath) {
            const files = await fs.readdir(modulePath);
            return (await Promise.all(
                files.map(async file => {
                    const fileName = path.join(modulePath, file);
                    const stats = await fs.lstat(fileName);
                    if (stats.isDirectory()) {
                        return this.readModuleFiles(fileName);
                    } else if (R.endsWith('.js', file)) {
                        const content = await fs.readFile(fileName, 'utf-8');
                        return [
                            {
                                fileName,
                                content,
                                readOnly: true
                            }
                        ];
                    } else {
                        return [];
                    }
                })
            )).reduce((a, b) => a.concat(b), []);
        }
    }
    module.exports = {
        repositoryFactory: ({ authInfo }) => new S3FileRepository(),
    };

    参考使用

    还是以前的参考代码

    • 创建一个约定的schema npm 包
      demo 已经push npm 官方仓库了,可以直接使用


    mydemo.js

     
    cube(`dalongrong`, {
        sql: `SELECT * FROM public.demoapp`,
        joins: {
        },
        preAggregations: {
          mydemo: {
            type: `rollup`,
            measureReferences: [Demoapp.count],
            dimensionReferences: [name],
            external: true
          }
        },
        measures: {
          count: {
            type: `count`,
            drillMembers: [name, id]
          },
          "price": {
            sql: "id",
            "type":"count"
         }
        },
        dimensions: {
          name: {
            sql: `name`,
            type: `string`
          },
          id: {
            sql: `id`,
            type: `number`,
            primaryKey: true
          }
        }
      });

    package.json

    {
      "name": "@dalongrong/mycubejs-schema",
      "version": "1.0.0",
      "main": "index.js",
      "license": "MIT",
      "publishConfig": {
        "registry": "https://registry.npmjs.org/"
      },
      "scripts": {
        "p": "yarn publish --access public"
      }
    }
    • 集成s3 FileRepository
      具体s3配置部分和以前的一样,主要是添加一个符合schema发现约定的npm包到deps 就可以了
      参考项目的package.json
     
    {
      "name": "pre-age",
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "dev": "./node_modules/.bin/cubejs-server",
        "app": "node index.js"
      },
      "devDependencies": {
        "@cubejs-backend/cubestore-driver": "^0.25.24",
        "@cubejs-backend/postgres-driver": "^0.25.24",
        "@cubejs-backend/server": "^0.25.24"
      },
      "dependencies": {
        "@dalongrong/cube-s3repository": "^1.0.1",
        "@dalongrong/mycubejs-schema": "^1.0.0", // 自己开发的符合schema 的npm 包,demo 以及push npm 官方仓库
        "node-fetch": "^2.6.1",
        "throng": "^5.0.0"
      }
    }
    • 效果

    基于npm schema 发现的定义

    说明

    关于支持此特性的S3FileRepository 已经push npm 官方仓库了,大家可以直接使用

    参考资料

    https://cube.dev/docs/config#schema-file-repository
    https://github.com/rongfengliang/cube.js-s3-filerepository
    https://www.npmjs.com/package/@dalongrong/mycubejs-schema
    https://www.npmjs.com/package/@dalongrong/cube-s3repository

  • 相关阅读:
    Java——基本语法
    Java——基本概念
    [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和)
    Educational Codeforces Round 81 (Rated for Div. 2)] D. Same GCDs (数论,因子分解,容斥定理)
    Educational Codeforces Round 81 (Rated for Div. 2) C. Obtain The String(序列自动机,贪心)
    Educational Codeforces Round 81 B. Infinite Prefixes(数学,字符串,思维)
    Codeforces Round #615 (Div. 3) F. Three Paths on a Tree(树的直径,dfs)
    Codeforces Round #612 (Div. 2) C. Garland 动态规划
    Codeforces Round #612 (Div. 2) D. Numbers on Tree 构造,树dfs
    关于set/map 等容器对string类的时间性能指标对比
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/14332115.html
Copyright © 2020-2023  润新知