Skip to content

Commit

Permalink
Merge branch 'master' into event-analytics-example
Browse files Browse the repository at this point in the history
* master:
  ResultSet.normalizePivotConfig() fix (#6)
  Serverless deployment
  Serverless deployment
  Add support for Athena in JDBC driver (#5)
  • Loading branch information
keydunov committed Feb 14, 2019
2 parents 487a1fc + 4e6a52c commit 9b32bf9
Show file tree
Hide file tree
Showing 25 changed files with 598 additions and 290 deletions.
83 changes: 28 additions & 55 deletions packages/cubejs-cli/cubejsCli.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const Analytics = require('analytics-node');
const client = new Analytics('dSR8JiNYIGKyQHKid9OaLYugXLao18hA', { flushInterval: 100 });
const { machineIdSync } = require('node-machine-id');
const { promisify } = require('util');
const templates = require('./templates');

const packageJson = require('./package.json');

Expand All @@ -30,54 +31,6 @@ const executeCommand = (command, args) => {
})
};

const indexJs = `const CubejsServer = require('@cubejs-backend/server');
const server = new CubejsServer();
server.listen().then(({ port }) => {
console.log(\`🚀 Cube.js server is listening on \${port}\`);
});
`;

const dotEnv = `CUBEJS_DB_HOST=<YOUR_DB_HOST_HERE>
CUBEJS_DB_NAME=<YOUR_DB_NAME_HERE>
CUBEJS_DB_USER=<YOUR_DB_USER_HERE>
CUBEJS_DB_PASS=<YOUR_DB_PASS_HERE>
`;

const ordersJs = `cube(\`Orders\`, {
sql: \`
select 1 as id, 100 as amount, 'new' status
UNION ALL
select 2 as id, 200 as amount, 'new' status
UNION ALL
select 3 as id, 300 as amount, 'processed' status
UNION ALL
select 4 as id, 500 as amount, 'processed' status
UNION ALL
select 5 as id, 600 as amount, 'shipped' status
\`,
measures: {
count: {
type: \`count\`
},
totalAmount: {
sql: \`amount\`,
type: \`sum\`
}
},
dimensions: {
status: {
sql: \`status\`,
type: \`string\`
}
}
});
`;

const anonymousId = machineIdSync();

const event = async (name, props) => {
Expand Down Expand Up @@ -141,6 +94,13 @@ const createApp = async (projectName, options) => {
createAppOptions
);
}
const template = options.template || 'express';
if (!templates[template]) {
await displayError(
`Unknown template ${chalk.red(template)}`,
createAppOptions
);
}
await fs.ensureDir(projectName);
process.chdir(projectName);

Expand All @@ -150,12 +110,9 @@ const createApp = async (projectName, options) => {
version: '0.0.1',
private: true,
scripts: {
dev: "node index.js"
dev: "./node_modules/.bin/cubejs-dev-server"
}
});
await fs.writeFile('index.js', indexJs);
await fs.ensureDir('schema');
await fs.writeFile(path.join('schema', 'Orders.js'), ordersJs);

logStage('Installing server dependencies');
await npmInstall(['@cubejs-backend/server']);
Expand Down Expand Up @@ -190,8 +147,23 @@ const createApp = async (projectName, options) => {
await executeCommand('npm', ['install']);
}

logStage('Creating default configuration');
await fs.writeFile('.env', dotEnv + `CUBEJS_DB_TYPE=${options.dbType}\nCUBEJS_API_SECRET=${crypto.randomBytes(64).toString('hex')}\n`);
logStage('Writing files from template');

const templateConfig = templates[template];
const env = {
dbType: options.dbType,
apiSecret: crypto.randomBytes(64).toString('hex'),
projectName
};
await Promise.all(Object.keys(templateConfig.files).map(async fileName => {
await fs.ensureDir(path.dirname(fileName));
await fs.writeFile(fileName, templateConfig.files[fileName](env));
}));

if (templateConfig.dependencies) {
logStage('Installing template dependencies');
await npmInstall(templateConfig.dependencies);
}

await event('Create App Success', { projectName, dbType: options.dbType });
logStage(`${chalk.green(projectName)} app has been created 🎉`);
Expand Down Expand Up @@ -255,7 +227,8 @@ program

program
.command('create <name>')
.option('-d, --db-type <db-type>', 'Preconfigure for selected database (options: postgres, mysql)')
.option('-d, --db-type <db-type>', 'Preconfigure for selected database. Options: postgres, mysql')
.option('-t, --template <template>', 'App template. Options: express (default), serverless.')
.description('Create new Cube.js app')
.action((projectName, options) => createApp(projectName, options)
.catch(e => displayError(e.stack || e, { projectName, dbType: options.dbType }))
Expand Down
2 changes: 1 addition & 1 deletion packages/cubejs-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "cubejs-cli",
"description": "Cube.js Command Line Interface",
"author": "Statsbot, Inc.",
"version": "0.0.11",
"version": "0.0.12",
"engines": {
"node": ">=8.11.1"
},
Expand Down
120 changes: 120 additions & 0 deletions packages/cubejs-cli/templates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const indexJs = `const CubejsServer = require('@cubejs-backend/server');
const server = new CubejsServer();
server.listen().then(({ port }) => {
console.log(\`🚀 Cube.js server is listening on \${port}\`);
});
`;

const appJs = `const express = require('serverless-express/express');
const app = express();
app.use(require('cors')());
const serverCore = require('@cubejs-backend/server-core').create();
serverCore.initApp(app);
module.exports = app;
`;

const handlerJs = `const handler = require('serverless-express/handler');
const app = require('./app');
exports.api = handler(app);
`;

const dotEnv = (env) => `CUBEJS_DB_HOST=<YOUR_DB_HOST_HERE>
CUBEJS_DB_NAME=<YOUR_DB_NAME_HERE>
CUBEJS_DB_USER=<YOUR_DB_USER_HERE>
CUBEJS_DB_PASS=<YOUR_DB_PASS_HERE>
CUBEJS_DB_TYPE=${env.dbType}
CUBEJS_API_SECRET=${env.apiSecret}
`;

const serverlessYml = (env) => `service: ${env.projectName}
provider:
name: aws
runtime: nodejs8.10
environment:
CUBEJS_DB_HOST: <YOUR_DB_HOST_HERE>
CUBEJS_DB_NAME: <YOUR_DB_NAME_HERE>
CUBEJS_DB_USER: <YOUR_DB_USER_HERE>
CUBEJS_DB_PASS: <YOUR_DB_PASS_HERE>
CUBEJS_DB_PORT: <YOUR_DB_PORT_HERE>
CUBEJS_DB_TYPE: ${env.dbType}
CUBEJS_API_SECRET: ${env.apiSecret}
REDIS_URL: <YOUR_REDIS_URL_HERE>
functions:
cubejs:
handler: handler.api
timeout: 30
# vpc:
# securityGroupIds:
# - sg-12345678901234567 # Your DB and Redis security groups here
# subnetIds:
# - subnet-12345678901234567 # Your DB and Redis subnets here
events:
- http:
path: /
method: GET
- http:
path: /{proxy+}
method: ANY
plugins:
- serverless-express
`;

const ordersJs = `cube(\`Orders\`, {
sql: \`
select 1 as id, 100 as amount, 'new' status
UNION ALL
select 2 as id, 200 as amount, 'new' status
UNION ALL
select 3 as id, 300 as amount, 'processed' status
UNION ALL
select 4 as id, 500 as amount, 'processed' status
UNION ALL
select 5 as id, 600 as amount, 'shipped' status
\`,
measures: {
count: {
type: \`count\`
},
totalAmount: {
sql: \`amount\`,
type: \`sum\`
}
},
dimensions: {
status: {
sql: \`status\`,
type: \`string\`
}
}
});
`;

exports.express = {
files: {
'index.js': () => indexJs,
'.env': dotEnv,
'schema/Orders.js': () => ordersJs
}
};

exports.serverless = {
files: {
'handler.js': () => handlerJs,
'app.js': () => appJs,
'serverless.yml': serverlessYml,
'.env': dotEnv,
'schema/Orders.js': () => ordersJs
},
dependencies: ['serverless-express']
};
2 changes: 1 addition & 1 deletion packages/cubejs-client-core/dist/cubejs-client-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ function () {
var _this = this;

return this.loadMethod(function () {
return _this.request("/load?query=".concat(JSON.stringify(query)));
return _this.request("/load?query=".concat(encodeURIComponent(JSON.stringify(query))));
}, function (body) {
return new ResultSet(body);
}, options, callback);
Expand Down
2 changes: 1 addition & 1 deletion packages/cubejs-client-core/dist/cubejs-client-core.umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -14798,7 +14798,7 @@
var _this = this;

return this.loadMethod(function () {
return _this.request("/load?query=".concat(JSON.stringify(query)));
return _this.request("/load?query=".concat(encodeURIComponent(JSON.stringify(query))));
}, function (body) {
return new ResultSet(body);
}, options, callback);
Expand Down
2 changes: 1 addition & 1 deletion packages/cubejs-client-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cubejs-client/core",
"version": "0.2.2",
"version": "0.2.3",
"description": "cube.js client",
"main": "dist/cubejs-client-core.js",
"author": "Statsbot, Inc.",
Expand Down
6 changes: 3 additions & 3 deletions packages/cubejs-client-core/src/ResultSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ export default class ResultSet {
normalizePivotConfig(pivotConfig) {
const query = this.loadResponse.query;
let timeDimensions = (query.timeDimensions || []).filter(td => !!td.granularity);
pivotConfig = pivotConfig || timeDimensions.length ? {
pivotConfig = pivotConfig || (timeDimensions.length ? {
x: timeDimensions.map(td => td.dimension),
y: query.dimensions || []
} : {
x: query.dimensions || [],
y: []
};
});
if (!pivotConfig.x.concat(pivotConfig.y).find(d => d === 'measures')) {
pivotConfig.y = pivotConfig.y.concat(['measures']);
}
Expand Down Expand Up @@ -208,4 +208,4 @@ export default class ResultSet {
rawData() {
return this.loadResponse.data;
}
}
}
2 changes: 1 addition & 1 deletion packages/cubejs-client-core/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class CubejsApi {

load(query, options, callback) {
return this.loadMethod(
() => this.request(`/load?query=${JSON.stringify(query)}`),
() => this.request(`/load?query=${encodeURIComponent(JSON.stringify(query))}`),
(body) => new ResultSet(body),
options,
callback
Expand Down
9 changes: 7 additions & 2 deletions packages/cubejs-mysql-driver/driver/MySqlDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,13 @@ class MySqlDriver extends BaseDriver {
return promise;
}

testConnection() {
return this.withConnection((conn) => conn.execute('SELECT 1'));
async testConnection() {
const conn = await this.pool._factory.create();
try {
return await conn.execute('SELECT 1');
} finally {
await this.pool._factory.destroy(conn);
}
}

query(query, values) {
Expand Down
4 changes: 2 additions & 2 deletions packages/cubejs-mysql-driver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@cubejs-backend/mysql-driver",
"description": "Cube.js Mysql database driver",
"author": "Statsbot, Inc.",
"version": "0.0.19",
"version": "0.0.21",
"engines": {
"node": ">=8.11.1"
},
Expand All @@ -11,7 +11,7 @@
"test": "mocha"
},
"dependencies": {
"@cubejs-backend/query-orchestrator": "^0.0.7",
"@cubejs-backend/query-orchestrator": "^0.0.21",
"generic-pool": "^3.6.0",
"mysql": "^2.16.0"
},
Expand Down
8 changes: 4 additions & 4 deletions packages/cubejs-mysql-driver/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# yarn lockfile v1


"@cubejs-backend/query-orchestrator@^0.0.7":
version "0.0.7"
resolved "https://registry.yarnpkg.com/@cubejs-backend/query-orchestrator/-/query-orchestrator-0.0.7.tgz#5c6a5d95e7e17d26a1dfd8a6bb1068607df681a7"
integrity sha512-bC5ohIyALcgYzyuO3Z0olN9hr5RFbRPv8eEtQAYnbXouS1Se+hiculMj3olbx6eeCEj98ZXLrMdLAQMPrZtCOg==
"@cubejs-backend/query-orchestrator@^0.0.21":
version "0.0.21"
resolved "https://registry.yarnpkg.com/@cubejs-backend/query-orchestrator/-/query-orchestrator-0.0.21.tgz#b5a0422a34931a834f4429280679460d08dc6112"
integrity sha512-jQS5F2D9PzKEJ4guzba6S2PymruA5pTIFu4DnOnM7Y3sFQkjVDcl7KYEr5VmpX6+Hu1u+naApuCQo2l6PtOXKg==
dependencies:
ramda "^0.24.1"
redis "^2.8.0"
Expand Down
Loading

0 comments on commit 9b32bf9

Please sign in to comment.