@@ -159,6 +159,98 @@ class ThinConnectionImpl extends ConnectionImpl {
159
159
}
160
160
}
161
161
162
+ //---------------------------------------------------------------------------
163
+ // _execute()
164
+ //
165
+ // Calls the RPC that executes a SQL statement and returns the results.
166
+ //---------------------------------------------------------------------------
167
+ async _execute ( statement , numIters , binds , options , executeManyFlag ) {
168
+
169
+ // perform binds
170
+ const numBinds = statement . bindInfoList . length ;
171
+ const numVars = binds . length ;
172
+ if ( numBinds !== numVars && ( numVars === 0 || ! binds [ 0 ] . name ) ) {
173
+ errors . throwErr ( errors . ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS , numBinds , numVars ) ;
174
+ }
175
+ for ( let i = 0 ; i < binds . length ; i ++ ) {
176
+ await this . _bind ( statement , binds [ i ] , i + 1 ) ;
177
+ }
178
+ if ( statement . isPlSql && ( options . batchErrors || options . dmlRowCounts ) ) {
179
+ errors . throwErr ( errors . ERR_EXEC_MODE_ONLY_FOR_DML ) ;
180
+ }
181
+
182
+ // send database request
183
+ const message = new messages . ExecuteMessage ( this , statement , options ) ;
184
+ message . numExecs = numIters ;
185
+ message . arrayDmlRowCounts = options . dmlRowCounts ;
186
+ message . batchErrors = options . batchErrors ;
187
+ if ( statement . isPlSql && statement . requiresFullExecute ) {
188
+ message . numExecs = 1 ;
189
+ await this . _protocol . _processMessage ( message ) ;
190
+ statement . requiresFullExecute = false ;
191
+ message . numExecs = numIters - 1 ;
192
+ message . offset = 1 ;
193
+ }
194
+ if ( message . numExecs > 0 ) {
195
+ await this . _protocol . _processMessage ( message ) ;
196
+ statement . requiresFullExecute = false ;
197
+ }
198
+
199
+ // if a define is required, send an additional request to the database
200
+ if ( statement . requiresDefine && statement . sql ) {
201
+ statement . requiresFullExecute = true ;
202
+ await this . _protocol . _processMessage ( message ) ;
203
+ statement . requiresFullExecute = false ;
204
+ statement . requiresDefine = false ;
205
+ }
206
+
207
+ // process results
208
+ const result = { } ;
209
+ if ( statement . numQueryVars > 0 ) {
210
+ result . resultSet = message . resultSet ;
211
+ } else {
212
+ statement . bufferRowIndex = 0 ;
213
+ const outBinds = thinUtil . getOutBinds ( statement , numIters ,
214
+ executeManyFlag ) ;
215
+ if ( outBinds ) {
216
+ result . outBinds = outBinds ;
217
+ }
218
+ if ( executeManyFlag ) {
219
+ if ( ! statement . isPlSql ) {
220
+ result . rowsAffected = statement . rowCount ;
221
+ delete statement . rowCount ;
222
+ }
223
+ if ( options . dmlRowCounts ) {
224
+ result . dmlRowCounts = options . dmlRowCounts ;
225
+ }
226
+ if ( options . batchErrors ) {
227
+ result . batchErrors = options . batchErrors ;
228
+ }
229
+ } else {
230
+ if ( statement . isPlSql && options . implicitResultSet ) {
231
+ result . implicitResults = options . implicitResultSet ;
232
+ }
233
+ if ( statement . lastRowid ) {
234
+ result . lastRowid = statement . lastRowid ;
235
+ delete statement . lastRowid ;
236
+ }
237
+ if ( statement . isPlSql ) {
238
+ if ( statement . rowCount ) {
239
+ result . rowsAffected = statement . rowCount ;
240
+ }
241
+ } else {
242
+ result . rowsAffected = statement . rowCount || 0 ;
243
+ }
244
+ if ( statement . rowCount ) {
245
+ delete statement . rowCount ;
246
+ }
247
+ }
248
+ this . _returnStatement ( statement ) ;
249
+ }
250
+
251
+ return result ;
252
+ }
253
+
162
254
//---------------------------------------------------------------------------
163
255
// _parseElementType()
164
256
//
@@ -778,26 +870,6 @@ class ThinConnectionImpl extends ConnectionImpl {
778
870
return resultSet ;
779
871
}
780
872
781
- //---------------------------------------------------------------------------
782
- // Prepares the sql given by user and binds the value to the statement object
783
- //---------------------------------------------------------------------------
784
- async _prepareAndBind ( sql , binds , options , isParse = false ) {
785
- const stmt = this . _prepare ( sql , options ) ;
786
- let position = 0 ;
787
- if ( ! isParse ) {
788
- const numBinds = stmt . bindInfoList . length ;
789
- const numVars = binds . length ;
790
- if ( numBinds !== numVars && ( numVars === 0 || ! binds [ 0 ] . name ) ) {
791
- errors . throwErr ( errors . ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS , numBinds , numVars ) ;
792
- }
793
- for ( const variable of binds ) {
794
- await this . _bind ( stmt , variable , position + 1 ) ;
795
- position += 1 ;
796
- }
797
- }
798
- return stmt ;
799
- }
800
-
801
873
//---------------------------------------------------------------------------
802
874
// Clears the statement cache for the connection
803
875
//---------------------------------------------------------------------------
@@ -818,139 +890,46 @@ class ThinConnectionImpl extends ConnectionImpl {
818
890
}
819
891
820
892
//---------------------------------------------------------------------------
821
- // Parses the sql given by User
822
- // calls the OAL8 RPC that parses the SQL statement and returns the metadata
823
- // information for a statment .
893
+ // getStatementInfo()
894
+ //
895
+ // Parses the SQL statement and returns information about the statement .
824
896
//---------------------------------------------------------------------------
825
897
async getStatementInfo ( sql ) {
826
898
const options = { } ;
827
899
const result = { } ;
828
- const statement = await this . _prepareAndBind ( sql , null , options , true ) ;
900
+ const statement = this . _prepare ( sql , options ) ;
829
901
options . connection = this ;
830
- // parse the statement (but not for DDL which doesn't support it)
831
- if ( ! statement . isDdl ) {
832
- const message = new messages . ExecuteMessage ( this , statement , options ) ;
833
- message . parseOnly = true ;
834
- await this . _protocol . _processMessage ( message ) ;
835
- }
836
- if ( statement . numQueryVars > 0 ) {
837
- result . metaData = thinUtil . getMetadataMany ( statement . queryVars ) ;
838
- }
839
- result . bindNames = Array . from ( statement . bindInfoDict . keys ( ) ) ;
840
- result . statementType = statement . statementType ;
841
- return result ;
842
- }
843
-
844
- //---------------------------------------------------------------------------
845
- // Prepares the sql given by the user,
846
- // calls the OAL8 RPC that executes a SQL statement and returns the results.
847
- //---------------------------------------------------------------------------
848
- async execute ( sql , numIters , binds , options , executeManyFlag ) {
849
- const result = { } ;
850
- if ( executeManyFlag ) {
851
- return await this . executeMany ( sql , numIters , binds , options ) ;
852
- }
853
- const statement = await this . _prepareAndBind ( sql , binds , options ) ;
854
-
855
- // send the initial request to the database
856
- const message = new messages . ExecuteMessage ( this , statement , options ) ;
857
- message . numExecs = 1 ;
858
- await this . _protocol . _processMessage ( message ) ;
859
- statement . requiresFullExecute = false ;
860
-
861
- // if a define is required, send an additional request to the database
862
- if ( statement . requiresDefine && statement . sql ) {
863
- statement . requiresFullExecute = true ;
864
- await this . _protocol . _processMessage ( message ) ;
865
- statement . requiresFullExecute = false ;
866
- statement . requiresDefine = false ;
867
- }
868
-
869
- // process message results
870
- if ( statement . numQueryVars > 0 ) {
871
- result . resultSet = message . resultSet ;
872
- } else {
873
- statement . bufferRowIndex = 0 ;
874
- const bindVars = thinUtil . getBindVars ( statement ) ;
875
- const outBinds = thinUtil . getExecuteOutBinds ( bindVars ) ;
876
- if ( outBinds ) {
877
- result . outBinds = outBinds ;
878
- }
879
- if ( statement . isPlSql ) {
880
- if ( options . implicitResultSet ) {
881
- result . implicitResults = options . implicitResultSet ;
882
- }
883
- }
884
- if ( statement . lastRowid ) {
885
- result . lastRowid = statement . lastRowid ;
886
- delete statement . lastRowid ;
887
- }
888
- if ( statement . isPlSql ) {
889
- if ( statement . rowCount ) {
890
- result . rowsAffected = statement . rowCount ;
891
- }
892
- } else {
893
- result . rowsAffected = statement . rowCount || 0 ;
902
+ try {
903
+ if ( ! statement . isDdl ) {
904
+ const message = new messages . ExecuteMessage ( this , statement , options ) ;
905
+ message . parseOnly = true ;
906
+ await this . _protocol . _processMessage ( message ) ;
894
907
}
895
- if ( statement . rowCount ) {
896
- delete statement . rowCount ;
908
+ if ( statement . numQueryVars > 0 ) {
909
+ result . metaData = thinUtil . getMetadataMany ( statement . queryVars ) ;
897
910
}
911
+ result . bindNames = Array . from ( statement . bindInfoDict . keys ( ) ) ;
912
+ result . statementType = statement . statementType ;
913
+ return result ;
914
+ } finally {
898
915
this . _returnStatement ( statement ) ;
899
916
}
900
-
901
- return result ;
902
917
}
903
918
904
919
//---------------------------------------------------------------------------
905
- // executeMany ()
920
+ // execute ()
906
921
//
907
- // Prepares the sql given by the user, calls the OAL8 RPC that executes a SQL
908
- // statement multiple times and returns the results.
922
+ // Calls the RPC that executes a SQL statement and returns the results.
909
923
//---------------------------------------------------------------------------
910
- async executeMany ( sql , numIters , binds , options ) {
911
- const statement = await this . _prepareAndBind ( sql , binds , options ) ;
912
- if ( statement . isPlSql && ( options . batchErrors || options . dmlRowCounts ) ) {
913
- errors . throwErr ( errors . ERR_EXEC_MODE_ONLY_FOR_DML ) ;
914
- }
915
-
916
- // send database request
917
- const message = new messages . ExecuteMessage ( this , statement , options ) ;
918
- message . numExecs = numIters ;
919
- message . arrayDmlRowCounts = options . dmlRowCounts ;
920
- message . batchErrors = options . batchErrors ;
921
- if ( statement . isPlSql && statement . requiresFullExecute ) {
922
- message . numExecs = 1 ;
923
- await this . _protocol . _processMessage ( message ) ;
924
- statement . requiresFullExecute = false ;
925
- message . numExecs = numIters - 1 ;
926
- message . offset = 1 ;
927
- }
928
- if ( message . numExecs > 0 ) {
929
- await this . _protocol . _processMessage ( message ) ;
930
- }
931
-
932
- // process results
933
- const returnObj = { } ;
934
- statement . bufferRowIndex = 0 ;
935
- const bindVars = thinUtil . getBindVars ( statement ) ;
936
- const outBinds = thinUtil . getExecuteManyOutBinds ( bindVars , numIters ) ;
937
- if ( outBinds ) {
938
- returnObj . outBinds = outBinds ;
939
- }
940
- const rowsAffected = ! statement . isPlSql ? statement . rowCount : undefined ;
941
- if ( rowsAffected ) {
942
- returnObj . rowsAffected = rowsAffected ;
943
- delete statement . rowCount ;
944
- }
945
- if ( options . dmlRowCounts ) {
946
- returnObj . dmlRowCounts = options . dmlRowCounts ;
947
- }
948
- if ( options . batchErrors ) {
949
- returnObj . batchErrors = options . batchErrors ;
924
+ async execute ( sql , numIters , binds , options , executeManyFlag ) {
925
+ const statement = this . _prepare ( sql , options ) ;
926
+ try {
927
+ return await this . _execute ( statement , numIters , binds , options ,
928
+ executeManyFlag ) ;
929
+ } catch ( err ) {
930
+ this . _returnStatement ( statement ) ;
931
+ throw err ;
950
932
}
951
- this . _returnStatement ( statement ) ;
952
-
953
- return returnObj ;
954
933
}
955
934
956
935
//---------------------------------------------------------------------------
0 commit comments