Skip to content

Commit

Permalink
feat(mysql-driver): Read only pre-aggregations support
Browse files Browse the repository at this point in the history
  • Loading branch information
paveltiunov committed Mar 29, 2020
1 parent 53e2c9f commit 2e7cf58
Showing 1 changed file with 27 additions and 2 deletions.
29 changes: 27 additions & 2 deletions packages/cubejs-mysql-driver/driver/MySqlDriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const mysql = require('mysql');
const genericPool = require('generic-pool');
const { promisify } = require('util');
const BaseDriver = require('@cubejs-backend/query-orchestrator/driver/BaseDriver');
const crypto = require('crypto');

const GenericTypeToMySql = {
string: 'varchar(255) CHARACTER SET utf8mb4',
Expand Down Expand Up @@ -101,12 +102,15 @@ class MySqlDriver extends BaseDriver {
}

query(query, values) {
const self = this;
return this.withConnection(db => db.execute(`SET time_zone = '${self.config.storeTimezone || '+00:00'}'`, [])
return this.withConnection(db => this.setTimeZone(db)
.then(() => db.execute(query, values))
.then(res => res));
}

setTimeZone(db) {
return db.execute(`SET time_zone = '${this.config.storeTimezone || '+00:00'}'`, []);
}

async release() {
await this.pool.drain();
await this.pool.clear();
Expand All @@ -132,6 +136,27 @@ class MySqlDriver extends BaseDriver {
return super.loadPreAggregationIntoTable(preAggregationTableName, loadSql, params, tx);
}

async downloadQueryResults(query, values) {
if (!this.config.database) {
throw new Error(`Default database should be defined to be used for temporary tables during query results downloads`);
}
const tableName = crypto.randomBytes(10).toString('hex');
const columns = await this.withConnection(async db => {
await this.setTimeZone(db);
await db.execute(`CREATE TEMPORARY TABLE ${this.config.database}.t_${tableName} AS ${query} LIMIT 0`, values);
const result = await db.execute(`DESCRIBE ${this.config.database}.t_${tableName}`);
await db.execute(`DROP TEMPORARY TABLE ${this.config.database}.t_${tableName}`);
return result;
});

const types = columns.map(c => ({ name: c.Field, type: this.toGenericType(c.Type) }));

return {
rows: await this.query(query, values),
types,
};
}

toColumnValue(value, genericType) {
if (genericType === 'timestamp' && typeof value === 'string') {
return value && value.replace('Z', '');
Expand Down

0 comments on commit 2e7cf58

Please sign in to comment.