Skip to content

Commit 2e7cf58

Browse files
committed
feat(mysql-driver): Read only pre-aggregations support
1 parent 53e2c9f commit 2e7cf58

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

packages/cubejs-mysql-driver/driver/MySqlDriver.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const mysql = require('mysql');
22
const genericPool = require('generic-pool');
33
const { promisify } = require('util');
44
const BaseDriver = require('@cubejs-backend/query-orchestrator/driver/BaseDriver');
5+
const crypto = require('crypto');
56

67
const GenericTypeToMySql = {
78
string: 'varchar(255) CHARACTER SET utf8mb4',
@@ -101,12 +102,15 @@ class MySqlDriver extends BaseDriver {
101102
}
102103

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

110+
setTimeZone(db) {
111+
return db.execute(`SET time_zone = '${this.config.storeTimezone || '+00:00'}'`, []);
112+
}
113+
110114
async release() {
111115
await this.pool.drain();
112116
await this.pool.clear();
@@ -132,6 +136,27 @@ class MySqlDriver extends BaseDriver {
132136
return super.loadPreAggregationIntoTable(preAggregationTableName, loadSql, params, tx);
133137
}
134138

139+
async downloadQueryResults(query, values) {
140+
if (!this.config.database) {
141+
throw new Error(`Default database should be defined to be used for temporary tables during query results downloads`);
142+
}
143+
const tableName = crypto.randomBytes(10).toString('hex');
144+
const columns = await this.withConnection(async db => {
145+
await this.setTimeZone(db);
146+
await db.execute(`CREATE TEMPORARY TABLE ${this.config.database}.t_${tableName} AS ${query} LIMIT 0`, values);
147+
const result = await db.execute(`DESCRIBE ${this.config.database}.t_${tableName}`);
148+
await db.execute(`DROP TEMPORARY TABLE ${this.config.database}.t_${tableName}`);
149+
return result;
150+
});
151+
152+
const types = columns.map(c => ({ name: c.Field, type: this.toGenericType(c.Type) }));
153+
154+
return {
155+
rows: await this.query(query, values),
156+
types,
157+
};
158+
}
159+
135160
toColumnValue(value, genericType) {
136161
if (genericType === 'timestamp' && typeof value === 'string') {
137162
return value && value.replace('Z', '');

0 commit comments

Comments
 (0)