@@ -14,6 +14,8 @@ import { ColumnCode, Int64 } from './hive/Types';
14
14
import Status from './dto/Status' ;
15
15
import StatusFactory from './factory/StatusFactory' ;
16
16
import { definedOrError } from './utils' ;
17
+ import OperationStateError from './errors/OperationStateError' ;
18
+ import GetResult from './utils/GetResult' ;
17
19
18
20
export default class DBSQLOperation implements IOperation {
19
21
private driver : HiveDriver ;
@@ -22,7 +24,6 @@ export default class DBSQLOperation implements IOperation {
22
24
private data : Array < TRowSet > ;
23
25
private statusFactory : StatusFactory ;
24
26
25
- private maxRows : Int64 = new Int64 ( 100000 ) ;
26
27
private fetchType : number = 0 ;
27
28
28
29
private _hasMoreRows : boolean = false ;
@@ -40,11 +41,22 @@ export default class DBSQLOperation implements IOperation {
40
41
this . data = [ ] ;
41
42
}
42
43
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
+
43
55
/**
44
56
* Fetches result and schema from operation
45
57
* @throws {StatusError }
46
58
*/
47
- fetch ( ) : Promise < Status > {
59
+ fetch ( chunkSize = 100000 ) : Promise < Status > {
48
60
if ( ! this . hasResultSet ) {
49
61
return Promise . resolve (
50
62
this . statusFactory . create ( {
@@ -65,13 +77,37 @@ export default class DBSQLOperation implements IOperation {
65
77
return this . initializeSchema ( )
66
78
. then ( ( schema ) => {
67
79
this . schema = schema ;
68
-
69
- return this . firstFetch ( ) ;
80
+ return this . firstFetch ( chunkSize ) ;
70
81
} )
71
82
. then ( ( response ) => this . processFetchResponse ( response ) ) ;
72
83
} 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 ( [ ] ) ;
74
102
}
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
+ } ) ;
75
111
}
76
112
77
113
/**
@@ -134,10 +170,6 @@ export default class DBSQLOperation implements IOperation {
134
170
return this . _hasMoreRows ;
135
171
}
136
172
137
- setMaxRows ( maxRows : number ) : void {
138
- this . maxRows = new Int64 ( maxRows ) ;
139
- }
140
-
141
173
setFetchType ( fetchType : number ) : void {
142
174
this . fetchType = fetchType ;
143
175
}
@@ -174,20 +206,20 @@ export default class DBSQLOperation implements IOperation {
174
206
} ) ;
175
207
}
176
208
177
- private firstFetch ( ) {
209
+ private firstFetch ( chunkSize : number ) {
178
210
return this . driver . fetchResults ( {
179
211
operationHandle : this . operationHandle ,
180
212
orientation : TFetchOrientation . FETCH_FIRST ,
181
- maxRows : this . maxRows ,
213
+ maxRows : new Int64 ( chunkSize ) ,
182
214
fetchType : this . fetchType ,
183
215
} ) ;
184
216
}
185
217
186
- private nextFetch ( ) {
218
+ private nextFetch ( chunkSize : number ) {
187
219
return this . driver . fetchResults ( {
188
220
operationHandle : this . operationHandle ,
189
221
orientation : TFetchOrientation . FETCH_NEXT ,
190
- maxRows : this . maxRows ,
222
+ maxRows : new Int64 ( chunkSize ) ,
191
223
fetchType : this . fetchType ,
192
224
} ) ;
193
225
}
@@ -233,4 +265,29 @@ export default class DBSQLOperation implements IOperation {
233
265
234
266
return ( columnValue ?. values ?. length || 0 ) > 0 ;
235
267
}
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
+ }
236
293
}
0 commit comments