@@ -14,6 +14,8 @@ import { ColumnCode, Int64 } from './hive/Types';
1414import Status from './dto/Status' ;
1515import StatusFactory from './factory/StatusFactory' ;
1616import { definedOrError } from './utils' ;
17+ import OperationStateError from './errors/OperationStateError' ;
18+ import GetResult from './utils/GetResult' ;
1719
1820export default class DBSQLOperation implements IOperation {
1921 private driver : HiveDriver ;
@@ -22,7 +24,6 @@ export default class DBSQLOperation implements IOperation {
2224 private data : Array < TRowSet > ;
2325 private statusFactory : StatusFactory ;
2426
25- private maxRows : Int64 = new Int64 ( 100000 ) ;
2627 private fetchType : number = 0 ;
2728
2829 private _hasMoreRows : boolean = false ;
@@ -40,11 +41,22 @@ export default class DBSQLOperation implements IOperation {
4041 this . data = [ ] ;
4142 }
4243
44+ private async waitUntilReady ( ) : Promise < void > {
45+ if ( this . finished ( ) ) {
46+ return ;
47+ }
48+ if ( await this . isReady ( ) ) {
49+ return ;
50+ } else {
51+ return this . waitUntilReady ( ) ;
52+ }
53+ }
54+
4355 /**
4456 * Fetches result and schema from operation
4557 * @throws {StatusError }
4658 */
47- fetch ( ) : Promise < Status > {
59+ fetch ( chunkSize = 100000 ) : Promise < Status > {
4860 if ( ! this . hasResultSet ) {
4961 return Promise . resolve (
5062 this . statusFactory . create ( {
@@ -65,13 +77,37 @@ export default class DBSQLOperation implements IOperation {
6577 return this . initializeSchema ( )
6678 . then ( ( schema ) => {
6779 this . schema = schema ;
68-
69- return this . firstFetch ( ) ;
80+ return this . firstFetch ( chunkSize ) ;
7081 } )
7182 . then ( ( response ) => this . processFetchResponse ( response ) ) ;
7283 } else {
73- return this . nextFetch ( ) . then ( ( response ) => this . processFetchResponse ( response ) ) ;
84+ return this . nextFetch ( chunkSize ) . then ( ( response ) => this . processFetchResponse ( response ) ) ;
85+ }
86+ }
87+
88+ async fetchAll ( ) : Promise < Array < object > > {
89+ let data : Array < object > = [ ] ;
90+ do {
91+ let chunk = await this . fetchChunk ( ) ;
92+ if ( chunk ) {
93+ data . push ( ...chunk ) ;
94+ }
95+ } while ( this . hasMoreRows ( ) ) ;
96+ return data ;
97+ }
98+
99+ async fetchChunk ( chunkSize = 100000 ) : Promise < Array < object > > {
100+ if ( ! this . hasResultSet ) {
101+ return Promise . resolve ( [ ] ) ;
74102 }
103+
104+ await this . waitUntilReady ( ) ;
105+
106+ return await this . fetch ( chunkSize ) . then ( ( ) => {
107+ let data = new GetResult ( this ) . execute ( ) . getValue ( ) ;
108+ this . flush ( ) ;
109+ return Promise . resolve ( data ) ;
110+ } ) ;
75111 }
76112
77113 /**
@@ -134,10 +170,6 @@ export default class DBSQLOperation implements IOperation {
134170 return this . _hasMoreRows ;
135171 }
136172
137- setMaxRows ( maxRows : number ) : void {
138- this . maxRows = new Int64 ( maxRows ) ;
139- }
140-
141173 setFetchType ( fetchType : number ) : void {
142174 this . fetchType = fetchType ;
143175 }
@@ -174,20 +206,20 @@ export default class DBSQLOperation implements IOperation {
174206 } ) ;
175207 }
176208
177- private firstFetch ( ) {
209+ private firstFetch ( chunkSize : number ) {
178210 return this . driver . fetchResults ( {
179211 operationHandle : this . operationHandle ,
180212 orientation : TFetchOrientation . FETCH_FIRST ,
181- maxRows : this . maxRows ,
213+ maxRows : new Int64 ( chunkSize ) ,
182214 fetchType : this . fetchType ,
183215 } ) ;
184216 }
185217
186- private nextFetch ( ) {
218+ private nextFetch ( chunkSize : number ) {
187219 return this . driver . fetchResults ( {
188220 operationHandle : this . operationHandle ,
189221 orientation : TFetchOrientation . FETCH_NEXT ,
190- maxRows : this . maxRows ,
222+ maxRows : new Int64 ( chunkSize ) ,
191223 fetchType : this . fetchType ,
192224 } ) ;
193225 }
@@ -233,4 +265,29 @@ export default class DBSQLOperation implements IOperation {
233265
234266 return ( columnValue ?. values ?. length || 0 ) > 0 ;
235267 }
268+
269+ private async isReady ( ) : Promise < boolean > {
270+ let response = await this . status ( ) ;
271+ switch ( response . operationState ) {
272+ case TOperationState . INITIALIZED_STATE :
273+ return false ;
274+ case TOperationState . RUNNING_STATE :
275+ return false ;
276+ case TOperationState . FINISHED_STATE :
277+ return true ;
278+ case TOperationState . CANCELED_STATE :
279+ throw new OperationStateError ( 'The operation was canceled by a client' , response ) ;
280+ case TOperationState . CLOSED_STATE :
281+ throw new OperationStateError ( 'The operation was closed by a client' , response ) ;
282+ case TOperationState . ERROR_STATE :
283+ throw new OperationStateError ( 'The operation failed due to an error' , response ) ;
284+ case TOperationState . PENDING_STATE :
285+ throw new OperationStateError ( 'The operation is in a pending state' , response ) ;
286+ case TOperationState . TIMEDOUT_STATE :
287+ throw new OperationStateError ( 'The operation is in a timedout state' , response ) ;
288+ case TOperationState . UKNOWN_STATE :
289+ default :
290+ throw new OperationStateError ( 'The operation is in an unrecognized state' , response ) ;
291+ }
292+ }
236293}
0 commit comments