@nestjs-kitchen/connextion-presto
Version:
A flexible module to provide presto-client interface in NextJS.
130 lines (129 loc) • 4.72 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrestoInstance = void 0;
const common_1 = require("@nestjs/common");
const connextion_1 = require("@nestjs-kitchen/connextion");
const presto_client_1 = require("presto-client");
const constants_1 = require("./constants");
const errors_1 = require("./errors");
const utils_1 = require("./utils");
const END_STATE_LIST = ['FINISHED', 'CANCELED', 'FAILED'];
class PrestoInstance extends connextion_1.ConnextionInstance {
constructor(name, options) {
super(name, options);
this.client = undefined;
this.queryIdMap = new Map();
this.logger = new common_1.Logger(`Presto][${name}`);
const debug = Boolean(process.env[constants_1.CONNEXTION_PRESTO_DEBUG]) || options?.debug;
this.debugLogger = debug ? (0, utils_1.createDebugLogger)(this.logger.debug.bind(this.logger), debug) : utils_1.noop;
}
end(client, queryIdMap) {
if (!client || !queryIdMap || !queryIdMap.size) {
return;
}
const queryIds = [...queryIdMap.entries()].filter(([_, stat]) => !END_STATE_LIST.includes(stat)).map(([id]) => id);
if (!queryIds.length) {
return;
}
return Promise.allSettled(queryIds.map((id) => {
const { promise, reject, resolve } = Promise.withResolvers();
const startOn = (0, utils_1.getCurrentDateStr)();
client.kill(id, (err) => {
this.debugLogger({
Instance: this.name,
QueryId: id,
Type: 'Kill',
'Started On': startOn,
'Ended On': (0, utils_1.getCurrentDateStr)(),
Status: err ? 'Failed' : 'Successful',
Error: err
});
this.logger.error(err);
return err ? reject(err) : resolve();
});
return promise;
}));
}
dispose() {
if (!this.client) {
return;
}
const queryIdMap = this.queryIdMap;
const client = this.client;
this.queryIdMap = new Map();
this.client = undefined;
return this.end(client, queryIdMap);
}
create(options) {
this.dispose();
options.user = options.user ?? options.basic_auth?.user;
try {
this.client = new presto_client_1.Client(options);
}
catch (error) {
this.logger.error(error.message);
}
}
execute(options) {
const { promise, reject, resolve } = Promise.withResolvers();
if (!this.client) {
reject(new errors_1.PrestoError('client not found.'));
return promise;
}
const columns = [];
const rawData = [];
const startOn = (0, utils_1.getCurrentDateStr)();
let queryId = '';
this.client.execute({
columns: (_, data) => {
columns.push(...data);
},
data: (_, data) => {
rawData.push(...data);
},
...options,
state: (_, query_id, stats) => {
queryId = query_id;
if (END_STATE_LIST.includes(stats.state)) {
this.queryIdMap.delete(query_id);
}
else {
this.queryIdMap.set(query_id, stats.state);
}
},
error: (error) => {
this.debugLogger({
Instance: this.name,
QueryId: queryId,
Type: 'Query',
SQL: options.query,
'Started On': startOn,
'Ended On': (0, utils_1.getCurrentDateStr)(),
Status: 'Failed',
Error: error
});
reject(new errors_1.PrestoError(error.message, error));
},
success: () => {
const rows = (0, utils_1.buildDataRows)(columns, rawData);
this.debugLogger({
Instance: this.name,
QueryId: queryId,
Type: 'Query',
SQL: options.query,
'Started On': startOn,
'Ended On': (0, utils_1.getCurrentDateStr)(),
Status: 'Successful'
});
resolve({
columns,
rows,
rowCount: rows.length,
queryId
});
}
});
return promise;
}
}
exports.PrestoInstance = PrestoInstance;