@cubejs-backend/athena-driver 0.29.25 → 0.29.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/src/AthenaDriver.d.ts +51 -0
- package/dist/src/AthenaDriver.d.ts.map +1 -0
- package/dist/src/AthenaDriver.js +241 -0
- package/dist/src/AthenaDriver.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +14 -0
- package/dist/src/index.js.map +1 -0
- package/index.js +15 -0
- package/package.json +26 -8
- package/src/AthenaDriver.ts +0 -183
- package/src/index.d.ts +0 -14
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.29.28](https://github.com/cube-js/cube.js/compare/v0.29.27...v0.29.28) (2022-02-10)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **@cubejs-backend/athena-driver:** Batching and export support ([#4039](https://github.com/cube-js/cube.js/issues/4039)) ([108f42a](https://github.com/cube-js/cube.js/commit/108f42afdd58ae0027b1b81730f7ca9e72ab9122))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [0.29.25](https://github.com/cube-js/cube.js/compare/v0.29.24...v0.29.25) (2022-02-03)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @cubejs-backend/athena-driver
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { BaseDriver, DownloadTableCSVData, DriverInterface, QueryOptions, StreamOptions, StreamTableData } from '@cubejs-backend/query-orchestrator';
|
|
2
|
+
import { AthenaClientConfig } from '@aws-sdk/client-athena/dist-types/AthenaClient';
|
|
3
|
+
interface AthenaDriverOptions extends AthenaClientConfig {
|
|
4
|
+
readOnly?: boolean;
|
|
5
|
+
accessKeyId?: string;
|
|
6
|
+
secretAccessKey?: string;
|
|
7
|
+
workGroup?: string;
|
|
8
|
+
S3OutputLocation?: string;
|
|
9
|
+
pollTimeout?: number;
|
|
10
|
+
pollMaxInterval?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface AthenaQueryId {
|
|
13
|
+
QueryExecutionId: string;
|
|
14
|
+
}
|
|
15
|
+
interface AthenaTable {
|
|
16
|
+
schema: string;
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
interface AthenaColumn {
|
|
20
|
+
name: string;
|
|
21
|
+
type: string;
|
|
22
|
+
attributes: string[];
|
|
23
|
+
}
|
|
24
|
+
declare type AthenaSchema = Record<string, Record<string, AthenaColumn[]>>;
|
|
25
|
+
export declare class AthenaDriver extends BaseDriver implements DriverInterface {
|
|
26
|
+
private config;
|
|
27
|
+
private athena;
|
|
28
|
+
constructor(config?: AthenaDriverOptions);
|
|
29
|
+
readOnly(): boolean;
|
|
30
|
+
isUnloadSupported(): Promise<boolean>;
|
|
31
|
+
testConnection(): Promise<void>;
|
|
32
|
+
query<R = unknown>(query: string, values: unknown[], options?: QueryOptions): Promise<R[]>;
|
|
33
|
+
stream(query: string, values: unknown[], options: StreamOptions): Promise<StreamTableData>;
|
|
34
|
+
loadPreAggregationIntoTable(preAggregationTableName: string, loadSql: string, params: any): Promise<any>;
|
|
35
|
+
unload(tableName: string): Promise<DownloadTableCSVData>;
|
|
36
|
+
tablesSchema(): Promise<AthenaSchema>;
|
|
37
|
+
protected startQuery(query: string, values: unknown[]): Promise<AthenaQueryId>;
|
|
38
|
+
protected checkStatus(qid: AthenaQueryId): Promise<boolean>;
|
|
39
|
+
protected waitForSuccess(qid: AthenaQueryId): Promise<void>;
|
|
40
|
+
protected lazyRowIterator<R extends unknown>(qid: AthenaQueryId, query: string): AsyncGenerator<R>;
|
|
41
|
+
protected viewsSchema(tablesSchema: AthenaSchema): Promise<AthenaSchema>;
|
|
42
|
+
protected getAllTables(): Promise<AthenaTable[]>;
|
|
43
|
+
protected getColumns(table: AthenaTable): Promise<AthenaSchema>;
|
|
44
|
+
protected mergeSchemas(arrSchemas: AthenaSchema[]): AthenaSchema;
|
|
45
|
+
static splitS3Path(path: string): {
|
|
46
|
+
bucket: string;
|
|
47
|
+
prefix: string;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=AthenaDriver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AthenaDriver.d.ts","sourceRoot":"","sources":["../../src/AthenaDriver.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,eAAe,EACf,YAAY,EAAE,aAAa,EAC3B,eAAe,EAChB,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAGpF,UAAU,mBAAoB,SAAQ,kBAAkB;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAID,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,EAAE,CAAA;CACrB;AAED,aAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAMnE,qBAAa,YAAa,SAAQ,UAAW,YAAW,eAAe;IACrE,OAAO,CAAC,MAAM,CAAiC;IAE/C,OAAO,CAAC,MAAM,CAAS;gBAEJ,MAAM,GAAE,mBAAwB;IAmB5C,QAAQ,IAAI,OAAO;IAIb,iBAAiB;IAIjB,cAAc;IAMd,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAU1F,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;IAS1F,2BAA2B,CACtC,uBAAuB,EAAE,MAAM,EAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,GAAG,GACV,OAAO,CAAC,GAAG,CAAC;IASF,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA6CxD,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;cAOlC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;cAmBpE,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;cAejD,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;cAehD,eAAe,CAAC,CAAC,SAAS,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC;cAgCzF,WAAW,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;cAc9D,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;cAatC,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAarE,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,YAAY,EAAE,GAAG,YAAY;WAelD,WAAW,CAAC,IAAI,EAAE,MAAM;;;;CAOvC"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.AthenaDriver = void 0;
|
|
23
|
+
const client_athena_1 = require("@aws-sdk/client-athena");
|
|
24
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
25
|
+
const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
|
|
26
|
+
const stream = __importStar(require("stream"));
|
|
27
|
+
const query_orchestrator_1 = require("@cubejs-backend/query-orchestrator");
|
|
28
|
+
const shared_1 = require("@cubejs-backend/shared");
|
|
29
|
+
const SqlString = __importStar(require("sqlstring"));
|
|
30
|
+
const url_1 = require("url");
|
|
31
|
+
function applyParams(query, params) {
|
|
32
|
+
return SqlString.format(query, params);
|
|
33
|
+
}
|
|
34
|
+
class AthenaDriver extends query_orchestrator_1.BaseDriver {
|
|
35
|
+
constructor(config = {}) {
|
|
36
|
+
super();
|
|
37
|
+
const accessKeyId = config.accessKeyId || process.env.CUBEJS_AWS_KEY;
|
|
38
|
+
const secretAccessKey = config.secretAccessKey || process.env.CUBEJS_AWS_SECRET;
|
|
39
|
+
this.config = {
|
|
40
|
+
credentials: accessKeyId && secretAccessKey ? { accessKeyId, secretAccessKey } : undefined,
|
|
41
|
+
region: config.region || process.env.CUBEJS_AWS_REGION,
|
|
42
|
+
S3OutputLocation: config.S3OutputLocation || process.env.CUBEJS_AWS_S3_OUTPUT_LOCATION,
|
|
43
|
+
workGroup: config.workGroup || process.env.CUBEJS_AWS_ATHENA_WORKGROUP || 'primary',
|
|
44
|
+
...config,
|
|
45
|
+
pollTimeout: (config.pollTimeout || shared_1.getEnv('dbPollTimeout') || shared_1.getEnv('dbQueryTimeout')) * 1000,
|
|
46
|
+
pollMaxInterval: (config.pollMaxInterval || shared_1.getEnv('dbPollMaxInterval')) * 1000,
|
|
47
|
+
};
|
|
48
|
+
this.athena = new client_athena_1.Athena(this.config);
|
|
49
|
+
}
|
|
50
|
+
readOnly() {
|
|
51
|
+
return !!this.config.readOnly;
|
|
52
|
+
}
|
|
53
|
+
async isUnloadSupported() {
|
|
54
|
+
return this.config.S3OutputLocation !== undefined;
|
|
55
|
+
}
|
|
56
|
+
async testConnection() {
|
|
57
|
+
await this.athena.getWorkGroup({
|
|
58
|
+
WorkGroup: this.config.workGroup
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async query(query, values, options) {
|
|
62
|
+
const qid = await this.startQuery(query, values);
|
|
63
|
+
await this.waitForSuccess(qid);
|
|
64
|
+
const rows = [];
|
|
65
|
+
for await (const row of this.lazyRowIterator(qid, query)) {
|
|
66
|
+
rows.push(row);
|
|
67
|
+
}
|
|
68
|
+
return rows;
|
|
69
|
+
}
|
|
70
|
+
async stream(query, values, options) {
|
|
71
|
+
const qid = await this.startQuery(query, values);
|
|
72
|
+
await this.waitForSuccess(qid);
|
|
73
|
+
const rowStream = stream.Readable.from(this.lazyRowIterator(qid, query), { highWaterMark: options.highWaterMark });
|
|
74
|
+
return {
|
|
75
|
+
rowStream
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async loadPreAggregationIntoTable(preAggregationTableName, loadSql, params) {
|
|
79
|
+
if (this.config.S3OutputLocation === undefined) {
|
|
80
|
+
throw new Error('Unload is not configured');
|
|
81
|
+
}
|
|
82
|
+
const qid = await this.startQuery(loadSql, params);
|
|
83
|
+
await this.waitForSuccess(qid);
|
|
84
|
+
}
|
|
85
|
+
async unload(tableName) {
|
|
86
|
+
if (this.config.S3OutputLocation === undefined) {
|
|
87
|
+
throw new Error('Unload is not configured');
|
|
88
|
+
}
|
|
89
|
+
const path = `${this.config.S3OutputLocation}/${tableName}`;
|
|
90
|
+
const unloadSql = `
|
|
91
|
+
UNLOAD (SELECT * FROM ${tableName})
|
|
92
|
+
TO '${path}'
|
|
93
|
+
WITH (format = 'TEXTFILE', field_delimiter = ',', compression='GZIP')
|
|
94
|
+
`;
|
|
95
|
+
const qid = await this.startQuery(unloadSql, []);
|
|
96
|
+
await this.waitForSuccess(qid);
|
|
97
|
+
const client = new client_s3_1.S3({
|
|
98
|
+
credentials: this.config.credentials,
|
|
99
|
+
region: this.config.region,
|
|
100
|
+
});
|
|
101
|
+
const { bucket, prefix } = AthenaDriver.splitS3Path(path);
|
|
102
|
+
const list = await client.listObjectsV2({
|
|
103
|
+
Bucket: bucket,
|
|
104
|
+
// skip leading /
|
|
105
|
+
Prefix: prefix.slice(1),
|
|
106
|
+
});
|
|
107
|
+
if (list.Contents === undefined) {
|
|
108
|
+
throw new Error(`Unable to UNLOAD table ${path}`);
|
|
109
|
+
}
|
|
110
|
+
const csvFile = await Promise.all(list.Contents.map(async (file) => {
|
|
111
|
+
const command = new client_s3_1.GetObjectCommand({
|
|
112
|
+
Bucket: bucket,
|
|
113
|
+
Key: file.Key,
|
|
114
|
+
});
|
|
115
|
+
return s3_request_presigner_1.getSignedUrl(client, command, { expiresIn: 3600 });
|
|
116
|
+
}));
|
|
117
|
+
return {
|
|
118
|
+
csvFile,
|
|
119
|
+
csvNoHeader: true
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async tablesSchema() {
|
|
123
|
+
const tablesSchema = await super.tablesSchema();
|
|
124
|
+
const viewsSchema = await this.viewsSchema(tablesSchema);
|
|
125
|
+
return this.mergeSchemas([tablesSchema, viewsSchema]);
|
|
126
|
+
}
|
|
127
|
+
async startQuery(query, values) {
|
|
128
|
+
const queryString = applyParams(query, (values || []).map(s => (typeof s === 'string' ? {
|
|
129
|
+
toSqlString: () => SqlString.escape(s).replace(/\\\\([_%])/g, '\\$1').replace(/\\'/g, '\'\'')
|
|
130
|
+
} : s)));
|
|
131
|
+
const { QueryExecutionId } = await this.athena.startQueryExecution({
|
|
132
|
+
QueryString: queryString,
|
|
133
|
+
WorkGroup: this.config.workGroup,
|
|
134
|
+
ResultConfiguration: {
|
|
135
|
+
OutputLocation: this.config.S3OutputLocation
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
return { QueryExecutionId: shared_1.checkNonNullable('StartQueryExecution', QueryExecutionId) };
|
|
139
|
+
}
|
|
140
|
+
async checkStatus(qid) {
|
|
141
|
+
var _a, _b, _c, _d;
|
|
142
|
+
const queryExecution = await this.athena.getQueryExecution(qid);
|
|
143
|
+
const status = (_b = (_a = queryExecution.QueryExecution) === null || _a === void 0 ? void 0 : _a.Status) === null || _b === void 0 ? void 0 : _b.State;
|
|
144
|
+
if (status === 'FAILED') {
|
|
145
|
+
throw new Error((_d = (_c = queryExecution.QueryExecution) === null || _c === void 0 ? void 0 : _c.Status) === null || _d === void 0 ? void 0 : _d.StateChangeReason);
|
|
146
|
+
}
|
|
147
|
+
if (status === 'CANCELLED') {
|
|
148
|
+
throw new Error('Query has been cancelled');
|
|
149
|
+
}
|
|
150
|
+
return status === 'SUCCEEDED';
|
|
151
|
+
}
|
|
152
|
+
async waitForSuccess(qid) {
|
|
153
|
+
const startedTime = Date.now();
|
|
154
|
+
for (let i = 0; Date.now() - startedTime <= this.config.pollTimeout; i++) {
|
|
155
|
+
if (await this.checkStatus(qid)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
await shared_1.pausePromise(Math.min(this.config.pollMaxInterval, 500 * i));
|
|
159
|
+
}
|
|
160
|
+
throw new Error(`Athena job timeout reached ${this.config.pollTimeout}ms`);
|
|
161
|
+
}
|
|
162
|
+
async *lazyRowIterator(qid, query) {
|
|
163
|
+
var _a, _b, _c, _d;
|
|
164
|
+
let isFirstBatch = true;
|
|
165
|
+
let columnInfo = [];
|
|
166
|
+
for (let results = await this.athena.getQueryResults(qid); results; results = results.NextToken
|
|
167
|
+
? (await this.athena.getQueryResults({ ...qid, NextToken: results.NextToken }))
|
|
168
|
+
: undefined) {
|
|
169
|
+
let rows = (_b = (_a = results.ResultSet) === null || _a === void 0 ? void 0 : _a.Rows) !== null && _b !== void 0 ? _b : [];
|
|
170
|
+
if (isFirstBatch) {
|
|
171
|
+
isFirstBatch = false;
|
|
172
|
+
// Athena returns the columns names in first row, skip it.
|
|
173
|
+
rows = rows.slice(1);
|
|
174
|
+
columnInfo = /SHOW COLUMNS/.test(query) // Fix for getColumns method
|
|
175
|
+
? [{ Name: 'column' }]
|
|
176
|
+
: shared_1.checkNonNullable('ColumnInfo', (_d = (_c = results.ResultSet) === null || _c === void 0 ? void 0 : _c.ResultSetMetadata) === null || _d === void 0 ? void 0 : _d.ColumnInfo)
|
|
177
|
+
.map(info => ({ Name: shared_1.checkNonNullable('Name', info.Name) }));
|
|
178
|
+
}
|
|
179
|
+
for (const row of rows) {
|
|
180
|
+
const fields = {};
|
|
181
|
+
columnInfo
|
|
182
|
+
.forEach((c, j) => {
|
|
183
|
+
var _a;
|
|
184
|
+
fields[c.Name] = (_a = row.Data) === null || _a === void 0 ? void 0 : _a[j].VarCharValue;
|
|
185
|
+
});
|
|
186
|
+
yield fields;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async viewsSchema(tablesSchema) {
|
|
191
|
+
const isView = (table) => !tablesSchema[table.schema]
|
|
192
|
+
|| !tablesSchema[table.schema][table.name];
|
|
193
|
+
const allTables = await this.getAllTables();
|
|
194
|
+
const arrViewsSchema = await Promise.all(allTables
|
|
195
|
+
.filter(isView)
|
|
196
|
+
.map(table => this.getColumns(table)));
|
|
197
|
+
return this.mergeSchemas(arrViewsSchema);
|
|
198
|
+
}
|
|
199
|
+
async getAllTables() {
|
|
200
|
+
const data = await this.query(`
|
|
201
|
+
SELECT table_schema AS schema, table_name AS name
|
|
202
|
+
FROM information_schema.tables
|
|
203
|
+
WHERE tables.table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')
|
|
204
|
+
`, []);
|
|
205
|
+
return data;
|
|
206
|
+
}
|
|
207
|
+
async getColumns(table) {
|
|
208
|
+
const data = await this.query(`SHOW COLUMNS IN \`${table.schema}\`.\`${table.name}\``, []);
|
|
209
|
+
return {
|
|
210
|
+
[table.schema]: {
|
|
211
|
+
[table.name]: data.map(({ column }) => {
|
|
212
|
+
const [name, type] = column.split('\t');
|
|
213
|
+
return { name, type, attributes: [] };
|
|
214
|
+
})
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
mergeSchemas(arrSchemas) {
|
|
219
|
+
const result = {};
|
|
220
|
+
arrSchemas.forEach(schemas => {
|
|
221
|
+
Object.keys(schemas).forEach(schema => {
|
|
222
|
+
Object.keys(schemas[schema]).forEach((name) => {
|
|
223
|
+
if (!result[schema])
|
|
224
|
+
result[schema] = {};
|
|
225
|
+
if (!result[schema][name])
|
|
226
|
+
result[schema][name] = schemas[schema][name];
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
static splitS3Path(path) {
|
|
233
|
+
const url = new url_1.URL(path);
|
|
234
|
+
return {
|
|
235
|
+
bucket: url.host,
|
|
236
|
+
prefix: url.pathname
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
exports.AthenaDriver = AthenaDriver;
|
|
241
|
+
//# sourceMappingURL=AthenaDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AthenaDriver.js","sourceRoot":"","sources":["../../src/AthenaDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./AthenaDriver"), exports);
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iDAA+B"}
|
package/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const fromExports = require('./dist/src');
|
|
2
|
+
const { AthenaDriver } = require('./dist/src/AthenaDriver');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* After 5 years working with TypeScript, now I know
|
|
6
|
+
* that commonjs and nodejs require is not compatibility with using export default
|
|
7
|
+
*/
|
|
8
|
+
const toExport = AthenaDriver;
|
|
9
|
+
|
|
10
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
11
|
+
for (const [key, module] of Object.entries(fromExports)) {
|
|
12
|
+
toExport[key] = module;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = toExport;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@cubejs-backend/athena-driver",
|
|
3
3
|
"description": "Cube.js Athena database driver",
|
|
4
4
|
"author": "Cube Dev, Inc.",
|
|
5
|
-
"version": "0.29.
|
|
5
|
+
"version": "0.29.28",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/cube-js/cube.js.git",
|
|
@@ -12,22 +12,40 @@
|
|
|
12
12
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
|
-
"
|
|
15
|
+
"build": "rm -rf dist && npm run tsc",
|
|
16
|
+
"tsc": "tsc",
|
|
17
|
+
"watch": "tsc -w",
|
|
18
|
+
"test": "yarn integration",
|
|
19
|
+
"integration": "jest --verbose dist/test",
|
|
20
|
+
"lint": "eslint src/* --ext .ts",
|
|
21
|
+
"lint:fix": "eslint --fix src/* --ext .ts"
|
|
16
22
|
},
|
|
17
|
-
"
|
|
18
|
-
|
|
23
|
+
"files": [
|
|
24
|
+
"dist/src",
|
|
25
|
+
"index.js"
|
|
26
|
+
],
|
|
27
|
+
"main": "index.js",
|
|
28
|
+
"types": "dist/src/index.d.ts",
|
|
19
29
|
"dependencies": {
|
|
20
30
|
"@aws-sdk/client-athena": "^3.22.0",
|
|
21
|
-
"@
|
|
22
|
-
"@
|
|
31
|
+
"@aws-sdk/client-s3": "^3.49.0",
|
|
32
|
+
"@aws-sdk/s3-request-presigner": "^3.49.0",
|
|
33
|
+
"@cubejs-backend/query-orchestrator": "^0.29.28",
|
|
34
|
+
"@cubejs-backend/shared": "^0.29.28",
|
|
23
35
|
"sqlstring": "^2.3.1"
|
|
24
36
|
},
|
|
25
37
|
"devDependencies": {
|
|
26
|
-
"@cubejs-backend/linter": "^0.29.23"
|
|
38
|
+
"@cubejs-backend/linter": "^0.29.23",
|
|
39
|
+
"@cubejs-backend/testing": "^0.29.28",
|
|
40
|
+
"@types/ramda": "^0.27.40",
|
|
41
|
+
"typescript": "~4.1.5"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
27
45
|
},
|
|
28
46
|
"eslintConfig": {
|
|
29
47
|
"extends": "../cubejs-linter"
|
|
30
48
|
},
|
|
31
49
|
"license": "Apache-2.0",
|
|
32
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "a258a9e046cbf0f4d60c3c0e694a8dc03ccad363"
|
|
33
51
|
}
|
package/src/AthenaDriver.ts
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
const AWS = require('@aws-sdk/client-athena');
|
|
2
|
-
const { BaseDriver } = require('@cubejs-backend/query-orchestrator');
|
|
3
|
-
const { getEnv, pausePromise } = require('@cubejs-backend/shared');
|
|
4
|
-
const SqlString = require('sqlstring');
|
|
5
|
-
|
|
6
|
-
const applyParams = (query, params) => SqlString.format(query, params);
|
|
7
|
-
|
|
8
|
-
class AthenaDriver extends BaseDriver {
|
|
9
|
-
constructor(config = {}) {
|
|
10
|
-
super();
|
|
11
|
-
|
|
12
|
-
this.config = {
|
|
13
|
-
credentials: {
|
|
14
|
-
accessKeyId: config.accessKeyId || process.env.CUBEJS_AWS_KEY,
|
|
15
|
-
secretAccessKey: config.secretAccessKey || process.env.CUBEJS_AWS_SECRET,
|
|
16
|
-
},
|
|
17
|
-
region: process.env.CUBEJS_AWS_REGION,
|
|
18
|
-
S3OutputLocation: process.env.CUBEJS_AWS_S3_OUTPUT_LOCATION,
|
|
19
|
-
workGroup: process.env.CUBEJS_AWS_ATHENA_WORKGROUP || 'primary',
|
|
20
|
-
...config,
|
|
21
|
-
pollTimeout: (config.pollTimeout || getEnv('dbPollTimeout') || getEnv('dbQueryTimeout')) * 1000,
|
|
22
|
-
pollMaxInterval: (config.pollMaxInterval || getEnv('dbPollMaxInterval')) * 1000,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
this.athena = new AWS.Athena(this.config);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
readOnly() {
|
|
29
|
-
return !!this.config.readOnly;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async testConnection() {
|
|
33
|
-
await this.athena.getWorkGroup({
|
|
34
|
-
WorkGroup: this.config.workGroup
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async awaitForJobStatus(QueryExecutionId, query, options) {
|
|
39
|
-
const queryExecution = await this.athena.getQueryExecution({
|
|
40
|
-
QueryExecutionId
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const status = queryExecution.QueryExecution.Status.State;
|
|
44
|
-
if (status === 'FAILED') {
|
|
45
|
-
throw new Error(queryExecution.QueryExecution.Status.StateChangeReason);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (status === 'CANCELLED') {
|
|
49
|
-
throw new Error('Query has been cancelled');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
status === 'SUCCEEDED'
|
|
54
|
-
) {
|
|
55
|
-
const allRows = [];
|
|
56
|
-
let columnInfo;
|
|
57
|
-
|
|
58
|
-
this.reportQueryUsage({
|
|
59
|
-
dataScannedInBytes: queryExecution.QueryExecution.Statistics.DataScannedInBytes
|
|
60
|
-
}, options);
|
|
61
|
-
|
|
62
|
-
for (
|
|
63
|
-
let results = await this.athena.getQueryResults({ QueryExecutionId });
|
|
64
|
-
results;
|
|
65
|
-
results = results.NextToken && (await this.athena.getQueryResults({
|
|
66
|
-
QueryExecutionId, NextToken: results.NextToken
|
|
67
|
-
}))
|
|
68
|
-
) {
|
|
69
|
-
const [header, ...tableRows] = results.ResultSet.Rows;
|
|
70
|
-
allRows.push(...(allRows.length ? results.ResultSet.Rows : tableRows));
|
|
71
|
-
if (!columnInfo) {
|
|
72
|
-
columnInfo = /SHOW COLUMNS/.test(query) // Fix for getColumns method
|
|
73
|
-
? [{ Name: 'column' }]
|
|
74
|
-
: results.ResultSet.ResultSetMetadata.ColumnInfo;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return allRows.map(r => columnInfo
|
|
79
|
-
.map((c, i) => ({ [c.Name]: r.Data[i].VarCharValue }))
|
|
80
|
-
.reduce((a, b) => ({ ...a, ...b }), {}));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async query(query, values, options) {
|
|
87
|
-
const queryString = applyParams(
|
|
88
|
-
query,
|
|
89
|
-
(values || []).map(s => (typeof s === 'string' ? {
|
|
90
|
-
toSqlString: () => SqlString.escape(s).replace(/\\\\([_%])/g, '\\$1').replace(/\\'/g, '\'\'')
|
|
91
|
-
} : s))
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const { QueryExecutionId } = await this.athena.startQueryExecution({
|
|
95
|
-
QueryString: queryString,
|
|
96
|
-
WorkGroup: this.config.workGroup,
|
|
97
|
-
ResultConfiguration: {
|
|
98
|
-
OutputLocation: this.config.S3OutputLocation
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const startedTime = Date.now();
|
|
103
|
-
|
|
104
|
-
for (let i = 0; Date.now() - startedTime <= this.config.pollTimeout; i++) {
|
|
105
|
-
const result = await this.awaitForJobStatus(QueryExecutionId, query, options);
|
|
106
|
-
if (result) {
|
|
107
|
-
return result;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
await pausePromise(
|
|
111
|
-
Math.min(this.config.pollMaxInterval, 500 * i)
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
throw new Error(
|
|
116
|
-
`Athena job timeout reached ${this.config.pollTimeout}ms`
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async tablesSchema() {
|
|
121
|
-
const tablesSchema = await super.tablesSchema();
|
|
122
|
-
const viewsSchema = await this.viewsSchema(tablesSchema);
|
|
123
|
-
|
|
124
|
-
return this.mergeSchemas([tablesSchema, viewsSchema]);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async viewsSchema(tablesSchema) {
|
|
128
|
-
// eslint-disable-next-line camelcase
|
|
129
|
-
const isView = ({ table_schema, table_name }) => !tablesSchema[table_schema]
|
|
130
|
-
|| !tablesSchema[table_schema][table_name];
|
|
131
|
-
|
|
132
|
-
const allTables = await this.getAllTables();
|
|
133
|
-
const arrViewsSchema = await Promise.all(
|
|
134
|
-
allTables
|
|
135
|
-
.filter(isView)
|
|
136
|
-
.map(table => this.getColumns(table))
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
return this.mergeSchemas(arrViewsSchema);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async getAllTables() {
|
|
143
|
-
const data = await this.query(`
|
|
144
|
-
SELECT table_schema, table_name
|
|
145
|
-
FROM information_schema.tables
|
|
146
|
-
WHERE tables.table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')
|
|
147
|
-
`);
|
|
148
|
-
|
|
149
|
-
return data;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// eslint-disable-next-line camelcase
|
|
153
|
-
async getColumns({ table_schema, table_name } = {}) {
|
|
154
|
-
// eslint-disable-next-line camelcase
|
|
155
|
-
const data = await this.query(`SHOW COLUMNS IN \`${table_schema}\`.\`${table_name}\``);
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
[table_schema]: {
|
|
159
|
-
[table_name]: data.map(({ column }) => {
|
|
160
|
-
const [name, type] = column.split('\t');
|
|
161
|
-
return { name, type, attributes: [] };
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
mergeSchemas(arrSchemas) {
|
|
168
|
-
const result = {};
|
|
169
|
-
|
|
170
|
-
arrSchemas.forEach(schemas => {
|
|
171
|
-
Object.keys(schemas).forEach(schema => {
|
|
172
|
-
Object.keys(schemas[schema]).forEach((name) => {
|
|
173
|
-
if (!result[schema]) result[schema] = {};
|
|
174
|
-
if (!result[schema][name]) result[schema][name] = schemas[schema][name];
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
return result;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
module.exports = AthenaDriver;
|
package/src/index.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BaseDriver } from '@cubejs-backend/query-orchestrator';
|
|
2
|
-
import { AthenaClientConfig } from '@aws-sdk/client-athena';
|
|
3
|
-
|
|
4
|
-
declare module '@cubejs-backend/athena-driver' {
|
|
5
|
-
interface AthenaDriverOptions extends AthenaClientConfig {
|
|
6
|
-
readOnly?: boolean,
|
|
7
|
-
pollTimeout?: number,
|
|
8
|
-
pollMaxInterval?: number,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default class AthenaDriver extends BaseDriver {
|
|
12
|
-
public constructor(options?: AthenaDriverOptions);
|
|
13
|
-
}
|
|
14
|
-
}
|