@@ -39,7 +39,8 @@ const SYSTEM_DATABASES = [
3939 'TD_SYSXML' ,
4040 'TDPUSER' ,
4141] ;
42- const SYSTEM_UDT = [
42+
43+ const SYSTEM_UDT = new Set ( [
4344 'ArrayVec' ,
4445 'InternalPeriodDateType' ,
4546 'InternalPeriodTimeStampType' ,
@@ -57,12 +58,15 @@ const SYSTEM_UDT = [
5758 'TD_JSON_BSON' ,
5859 'TD_JSON_UBJSON' ,
5960 'XML' ,
60- ] ;
61+ ] ) ;
62+
6163const MISSING_JAVA_PATH_MESSAGE =
6264 'Path to JAVA binary file is incorrect. Please specify JAVA_HOME variable in your system or put specific path to JAVA binary file in connection settings.' ;
6365
6466let connection ;
6567let useSshTunnel ;
68+ let abortController ;
69+ let activeQueries = new Set ( ) ;
6670
6771const isWindows = ( ) => os . platform ( ) === 'win32' ;
6872
@@ -172,16 +176,42 @@ const createConnection = async (connectionInfo, sshService, logger) => {
172176 const teradataClientCommandArguments = buildCommand ( teradataClientPath , connectionSettings ) ;
173177
174178 return {
175- execute : query => {
179+ execute : ( query , signal ) => {
176180 return new Promise ( ( resolve , reject ) => {
181+ if ( signal ?. aborted ) {
182+ return reject ( new Error ( 'Query execution was aborted' ) ) ;
183+ }
184+
177185 const queryArgument = createArgument ( 'query' , query ) ;
178186 const javaArgs = [ ...teradataClientCommandArguments , queryArgument ] ;
179187
180188 const queryResult = spawn ( `"${ javaPath } "` , javaArgs , {
181189 shell : true ,
182190 } ) ;
183191
192+ activeQueries . add ( queryResult ) ;
193+
194+ const abortHandler = ( ) => {
195+ if ( ! queryResult ?. killed ) {
196+ queryResult . kill ( 'SIGTERM' ) ;
197+ activeQueries . delete ( queryResult ) ;
198+ }
199+ reject ( new Error ( 'Query execution was aborted' ) ) ;
200+ } ;
201+
202+ if ( signal ) {
203+ signal . addEventListener ( 'abort' , abortHandler ) ;
204+ }
205+
206+ const cleanup = ( ) => {
207+ activeQueries . delete ( queryResult ) ;
208+ if ( signal ) {
209+ signal . removeEventListener ( 'abort' , abortHandler ) ;
210+ }
211+ } ;
212+
184213 queryResult . on ( 'error' , error => {
214+ cleanup ( ) ;
185215 reject ( new Error ( error ) ) ;
186216 } ) ;
187217
@@ -196,6 +226,12 @@ const createConnection = async (connectionInfo, sshService, logger) => {
196226 } ) ;
197227
198228 queryResult . on ( 'close' , code => {
229+ cleanup ( ) ;
230+
231+ if ( signal ?. aborted ) {
232+ return ;
233+ }
234+
199235 if ( code !== 0 ) {
200236 reject ( new Error ( Buffer . concat ( errorData ) . toString ( ) ) ) ;
201237 return ;
@@ -225,6 +261,7 @@ const createConnection = async (connectionInfo, sshService, logger) => {
225261 } ) ;
226262 } ) ;
227263 } ,
264+ getAbortController : ( ) => abortController ,
228265 } ;
229266} ;
230267
@@ -233,6 +270,9 @@ const connect = async (connectionInfo, sshService, logger) => {
233270 return connection ;
234271 }
235272
273+ abortController = new AbortController ( ) ;
274+ activeQueries . clear ( ) ;
275+
236276 useSshTunnel = connectionInfo . useSshTunnel ;
237277 connection = await createConnection ( connectionInfo , sshService , logger ) ;
238278
@@ -246,12 +286,14 @@ const getConcatenatedQueryResult = (queryResult = []) => {
246286} ;
247287
248288const createInstance = ( connection , _ ) => {
289+ const signal = connection . getAbortController ( ) ?. signal ;
290+
249291 const getDatabasesWithTableNames = async tableType => {
250292 const query = buildQuery ( queryType . GET_DATABASE_AND_TABLE_NAMES , {
251293 tableType,
252294 systemDatabases : SYSTEM_DATABASES ,
253295 } ) ;
254- const queryResult = await connection . execute ( query ) ;
296+ const queryResult = await connection . execute ( query , signal ) ;
255297
256298 return groupBy ( {
257299 items : queryResult ,
@@ -261,24 +303,27 @@ const createInstance = (connection, _) => {
261303 } ;
262304
263305 const getCount = async ( dbName , tableName ) => {
264- const count = await connection . execute ( buildQuery ( queryType . COUNT_COLUMNS , { dbName, tableName } ) ) ;
306+ const count = await connection . execute ( buildQuery ( queryType . COUNT_COLUMNS , { dbName, tableName } ) , signal ) ;
265307
266308 return Number ( count [ 0 ] ?. Quantity || 0 ) ;
267309 } ;
268310
269311 const getRecords = async ( dbName , tableName , limit ) => {
270- return connection . execute ( buildQuery ( queryType . GET_RECORDS , { dbName, tableName, limit } ) ) ;
312+ return connection . execute ( buildQuery ( queryType . GET_RECORDS , { dbName, tableName, limit } ) , signal ) ;
271313 } ;
272314
273315 const getVersion = async ( ) => {
274- const result = await connection . execute ( 'SELECT * FROM dbc.dbcinfo' ) ;
316+ const result = await connection . execute ( 'SELECT * FROM dbc.dbcinfo' , signal ) ;
275317 const versionInfo = result . find ( info => info . InfoKey === 'VERSION' ) ;
276318
277319 return versionInfo ?. InfoData ;
278320 } ;
279321
280322 const describeDatabase = async dbName => {
281- const databaseInfoResult = await connection . execute ( buildQuery ( queryType . DESCRIBE_DATABASE , { dbName } ) ) ;
323+ const databaseInfoResult = await connection . execute (
324+ buildQuery ( queryType . DESCRIBE_DATABASE , { dbName } ) ,
325+ signal ,
326+ ) ;
282327
283328 if ( ! databaseInfoResult . length ) {
284329 return { } ;
@@ -303,14 +348,15 @@ const createInstance = (connection, _) => {
303348 const showCreateEntity = async ( dbName , tableName , entityType ) => {
304349 const result = await connection . execute (
305350 buildQuery ( queryType . SHOW_CREATE_ENTITY_STATEMENT , { dbName, tableName, entityType } ) ,
351+ signal ,
306352 ) ;
307353
308354 return getConcatenatedQueryResult ( result ) ;
309355 } ;
310356
311357 const getColumns = async ( dbName , tableName ) => {
312358 const query = buildQuery ( queryType . GET_COLUMNS , { dbName, tableName } ) ;
313- const result = await connection . execute ( query ) ;
359+ const result = await connection . execute ( query , signal ) ;
314360
315361 return result . map ( raw => ( {
316362 dbName : raw . DatabaseName ,
@@ -322,7 +368,7 @@ const createInstance = (connection, _) => {
322368
323369 const getCreateIndexStatement = async index => {
324370 const query = `SHOW ${ index . indexType } INDEX "${ index . dbName } "."${ index . indxName } ";` ;
325- const createStatement = await connection . execute ( query ) ;
371+ const createStatement = await connection . execute ( query , signal ) ;
326372
327373 return {
328374 ...index ,
@@ -332,7 +378,7 @@ const createInstance = (connection, _) => {
332378
333379 const getIndexes = async dbName => {
334380 const query = buildQuery ( queryType . GET_INDEXES , { dbName } ) ;
335- const queryResult = await connection . execute ( query ) ;
381+ const queryResult = await connection . execute ( query , signal ) ;
336382
337383 const indexes = _ . uniqBy ( queryResult , 'IndexName' ) . map ( index => ( {
338384 dbName : index . DatabaseName ,
@@ -353,7 +399,7 @@ const createInstance = (connection, _) => {
353399 const getCreateUdtStatement = async type => {
354400 const name = type [ 'Table/View/Macro Dictionary Name' ] ;
355401 const query = `SHOW TYPE "${ name } ";` ;
356- const createStatement = await connection . execute ( query ) ;
402+ const createStatement = await connection . execute ( query , signal ) ;
357403
358404 return {
359405 name,
@@ -363,7 +409,7 @@ const createInstance = (connection, _) => {
363409
364410 const getUserDefinedTypes = async ( ) => {
365411 const query = 'HELP DATABASE SYSUDTLIB;' ;
366- const queryResult = await connection . execute ( query ) ;
412+ const queryResult = await connection . execute ( query , signal ) ;
367413
368414 return queryResult
369415 . filter ( filterUdt )
@@ -390,6 +436,19 @@ const createInstance = (connection, _) => {
390436} ;
391437
392438const close = async sshService => {
439+ if ( abortController ) {
440+ abortController . abort ( ) ;
441+ abortController = null ;
442+ }
443+
444+ for ( const activeQuery of activeQueries ) {
445+ if ( activeQuery && ! activeQuery . killed ) {
446+ activeQuery . kill ( 'SIGTERM' ) ;
447+ }
448+ }
449+
450+ activeQueries . clear ( ) ;
451+
393452 if ( connection ) {
394453 connection = null ;
395454 }
@@ -444,7 +503,7 @@ const getIndexType = index => {
444503
445504const filterUdt = object => object . Kind === 'U' ;
446505
447- const excludeSystemUdt = type => ! SYSTEM_UDT . includes ( type [ 'Table/View/Macro Dictionary Name' ] ) ;
506+ const excludeSystemUdt = type => ! SYSTEM_UDT . has ( type [ 'Table/View/Macro Dictionary Name' ] ) ;
448507
449508module . exports = {
450509 connect,
0 commit comments