ToolJet/plugins/packages/snowflake/lib/index.ts
Akshay 5b5b354842
Chore: Snowflake sdk update (#8179)
* update snowflake sdk
2023-12-07 18:00:35 +05:30

109 lines
2.9 KiB
TypeScript

import {
QueryError,
QueryResult,
QueryService,
ConnectionTestResult,
cacheConnection,
getCachedConnection,
} from '@tooljet-plugins/common';
import { SourceOptions, QueryOptions } from './types';
import * as snowflake from 'snowflake-sdk';
export default class Snowflake implements QueryService {
async connExecuteAsync(connection: snowflake.Connection, options: any) {
return new Promise((resolve, reject) => {
connection.execute({
...options,
complete: function (err, stmt, rows) {
if (err) {
reject(err);
} else {
resolve({ stmt, rows });
}
},
});
});
}
async run(
sourceOptions: SourceOptions,
queryOptions: QueryOptions,
dataSourceId: string,
dataSourceUpdatedAt: string
): Promise<QueryResult> {
const sqlText = queryOptions.query;
const connection: snowflake.Connection = await this.getConnection(
sourceOptions,
{},
true,
dataSourceId,
dataSourceUpdatedAt
);
try {
const result: any = await this.connExecuteAsync(connection, {
sqlText,
});
return { status: 'ok', data: result.rows };
} catch (err) {
throw new QueryError('Query could not be completed', err.message, {});
}
}
async testConnection(sourceOptions: SourceOptions): Promise<ConnectionTestResult> {
const connection = await this.getConnection(sourceOptions, {}, false);
const isConnectionValid = await connection.isValidAsync();
if (isConnectionValid) return { status: 'ok' };
throw new Error('Connection is invalid');
}
async connAsync(connection: snowflake.Connection) {
return new Promise((resolve, reject) => {
connection.connect(function (err, conn) {
if (err) reject(err);
resolve(conn);
});
});
}
async buildConnection(sourceOptions: SourceOptions) {
const connection = snowflake.createConnection({
account: sourceOptions.account,
username: sourceOptions.username,
password: sourceOptions.password,
warehouse: sourceOptions.warehouse,
database: sourceOptions.database,
schema: sourceOptions.schema,
role: sourceOptions.role,
clientSessionKeepAlive: true,
clientSessionKeepAliveHeartbeatFrequency: 900,
});
return await this.connAsync(connection);
}
async getConnection(
sourceOptions: any,
options: any,
checkCache: boolean,
dataSourceId?: string,
dataSourceUpdatedAt?: string
): Promise<any> {
if (checkCache) {
let connection = await getCachedConnection(dataSourceId, dataSourceUpdatedAt);
if (connection && (await connection.isValidAsync())) {
return connection;
} else {
connection = await this.buildConnection(sourceOptions);
await cacheConnection(dataSourceId, connection);
return connection;
}
} else {
return await this.buildConnection(sourceOptions);
}
}
}