@zowe/db2-for-zowe-cli 6.1.17 → 6.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/README.md +12 -10
  2. package/lib/Db2PluginLifeCycle.d.ts +11 -9
  3. package/lib/Db2PluginLifeCycle.js +18 -13
  4. package/lib/Db2PluginLifeCycle.js.map +1 -1
  5. package/node_modules/adm-zip/adm-zip.js +32 -6
  6. package/node_modules/adm-zip/headers/entryHeader.js +13 -1
  7. package/node_modules/adm-zip/methods/inflater.js +33 -3
  8. package/node_modules/adm-zip/package.json +2 -2
  9. package/node_modules/adm-zip/util/errors.js +3 -0
  10. package/node_modules/adm-zip/util/utils.js +102 -14
  11. package/node_modules/adm-zip/zipEntry.js +43 -18
  12. package/node_modules/adm-zip/zipFile.js +10 -0
  13. package/node_modules/axios/CHANGELOG.md +62 -0
  14. package/node_modules/axios/README.md +236 -73
  15. package/node_modules/axios/dist/axios.js +1308 -357
  16. package/node_modules/axios/dist/axios.min.js +3 -3
  17. package/node_modules/axios/dist/axios.min.js.map +1 -1
  18. package/node_modules/axios/dist/browser/axios.cjs +1443 -403
  19. package/node_modules/axios/dist/esm/axios.js +1443 -403
  20. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  21. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  22. package/node_modules/axios/dist/node/axios.cjs +1483 -348
  23. package/node_modules/axios/index.d.cts +24 -1
  24. package/node_modules/axios/index.d.ts +22 -1
  25. package/node_modules/axios/lib/adapters/fetch.js +136 -30
  26. package/node_modules/axios/lib/adapters/http.js +277 -74
  27. package/node_modules/axios/lib/adapters/xhr.js +172 -16
  28. package/node_modules/axios/lib/core/Axios.js +87 -27
  29. package/node_modules/axios/lib/core/AxiosError.js +59 -0
  30. package/node_modules/axios/lib/core/AxiosHeaders.js +17 -4
  31. package/node_modules/axios/lib/core/InterceptorManager.js +118 -8
  32. package/node_modules/axios/lib/core/assertParamsAcyclic.js +49 -0
  33. package/node_modules/axios/lib/core/buildFullPath.js +1 -13
  34. package/node_modules/axios/lib/core/createMultipartBody.js +37 -0
  35. package/node_modules/axios/lib/core/dispatchRequest.js +28 -2
  36. package/node_modules/axios/lib/core/mergeConfig.js +183 -120
  37. package/node_modules/axios/lib/core/methodList.js +17 -0
  38. package/node_modules/axios/lib/defaults/index.js +2 -1
  39. package/node_modules/axios/lib/defaults/transitional.js +1 -0
  40. package/node_modules/axios/lib/env/data.js +1 -1
  41. package/node_modules/axios/lib/helpers/AxiosTransformStream.js +11 -2
  42. package/node_modules/axios/lib/helpers/Http2Sessions.js +4 -1
  43. package/node_modules/axios/lib/helpers/HttpStatusCode.js +11 -1
  44. package/node_modules/axios/lib/helpers/composeSignals.js +6 -3
  45. package/node_modules/axios/lib/helpers/cookies.js +30 -6
  46. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +34 -7
  47. package/node_modules/axios/lib/helpers/formDataToBlob.js +113 -0
  48. package/node_modules/axios/lib/helpers/formDataToJSON.js +25 -1
  49. package/node_modules/axios/lib/helpers/fromDataURI.js +11 -4
  50. package/node_modules/axios/lib/helpers/isURLSameOrigin.js +4 -9
  51. package/node_modules/axios/lib/helpers/normalizeURLForProtocolCheck.js +24 -0
  52. package/node_modules/axios/lib/helpers/parseHeaders.js +2 -1
  53. package/node_modules/axios/lib/helpers/parseProtocol.js +1 -1
  54. package/node_modules/axios/lib/helpers/progressEventReducer.js +1 -1
  55. package/node_modules/axios/lib/helpers/resolveConfig.js +20 -5
  56. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +197 -6
  57. package/node_modules/axios/lib/helpers/throttle.js +3 -2
  58. package/node_modules/axios/lib/helpers/toFormData.js +14 -21
  59. package/node_modules/axios/lib/utils.js +192 -20
  60. package/node_modules/axios/package.json +1 -2
  61. package/node_modules/follow-redirects/README.md +27 -1
  62. package/node_modules/follow-redirects/index.js +11 -6
  63. package/node_modules/follow-redirects/package.json +1 -1
  64. package/node_modules/fs-extra/README.md +0 -1
  65. package/node_modules/fs-extra/lib/empty/index.js +4 -2
  66. package/node_modules/fs-extra/lib/util/stat.js +12 -2
  67. package/node_modules/fs-extra/package.json +1 -1
  68. package/node_modules/ibm_db/APIDocumentation.md +2883 -2024
  69. package/node_modules/ibm_db/LICENSE +23 -23
  70. package/node_modules/ibm_db/README.md +735 -735
  71. package/node_modules/ibm_db/binding.gyp +99 -98
  72. package/node_modules/ibm_db/installer/driverInstall.js +984 -958
  73. package/node_modules/ibm_db/installer/ifx.sh +38 -38
  74. package/node_modules/ibm_db/installer/setenv.sh +23 -23
  75. package/node_modules/ibm_db/installer/testODBCConnection.bat +51 -51
  76. package/node_modules/ibm_db/installer/testODBCConnection.sh +61 -61
  77. package/node_modules/ibm_db/lib/climacros.js +431 -431
  78. package/node_modules/ibm_db/lib/odbc.js +4293 -3487
  79. package/node_modules/ibm_db/lib/simple-queue.js +41 -41
  80. package/node_modules/ibm_db/package.json +70 -70
  81. package/node_modules/ibm_db/src/odbc.cpp +1495 -1396
  82. package/node_modules/ibm_db/src/odbc.h +477 -473
  83. package/node_modules/ibm_db/src/odbc_connection.cpp +1762 -1612
  84. package/node_modules/ibm_db/src/odbc_connection.h +228 -215
  85. package/node_modules/ibm_db/src/odbc_result.cpp +1547 -1547
  86. package/node_modules/ibm_db/src/odbc_result.h +152 -152
  87. package/node_modules/ibm_db/src/odbc_statement.cpp +2047 -861
  88. package/node_modules/ibm_db/src/odbc_statement.h +257 -135
  89. package/node_modules/ibm_db/src/strptime.c +389 -389
  90. package/node_modules/ibm_db/src/strptime.h +46 -46
  91. package/node_modules/ibm_db/test/README +23 -23
  92. package/node_modules/ibm_db/test/bench-insert.js +62 -62
  93. package/node_modules/ibm_db/test/bench-insertBatch10.js +74 -74
  94. package/node_modules/ibm_db/test/bench-insertBatch100.js +75 -75
  95. package/node_modules/ibm_db/test/bench-insertBatch1000.js +75 -75
  96. package/node_modules/ibm_db/test/bench-insertBatch10000.js +75 -75
  97. package/node_modules/ibm_db/test/bench-prepare-bind-execute-closeSync.js +60 -60
  98. package/node_modules/ibm_db/test/bench-prepare-bind-executeNonQuery.js +53 -53
  99. package/node_modules/ibm_db/test/bench-prepare-bindSync-execute-closeSync.js +50 -50
  100. package/node_modules/ibm_db/test/bench-prepare-bindSync-executeNonQuery.js +48 -48
  101. package/node_modules/ibm_db/test/bench-prepare-execute-closeSync.js +51 -51
  102. package/node_modules/ibm_db/test/bench-prepare-executeNonQuery.js +47 -47
  103. package/node_modules/ibm_db/test/bench-prepare-not.js +43 -43
  104. package/node_modules/ibm_db/test/bench-query-fetch.js +59 -59
  105. package/node_modules/ibm_db/test/bench-query-fetchAll.js +49 -49
  106. package/node_modules/ibm_db/test/bench-query-fetchAllSync.js +43 -43
  107. package/node_modules/ibm_db/test/bench-query.js +40 -40
  108. package/node_modules/ibm_db/test/bench-querySync-fetchArray.js +28 -28
  109. package/node_modules/ibm_db/test/bench-querySync.js +29 -29
  110. package/node_modules/ibm_db/test/common.d.ts +10 -10
  111. package/node_modules/ibm_db/test/common.js +127 -127
  112. package/node_modules/ibm_db/test/config.json +7 -7
  113. package/node_modules/ibm_db/test/config.zos.json +4 -4
  114. package/node_modules/ibm_db/test/data/sample1.txt +9 -9
  115. package/node_modules/ibm_db/test/data/trc.fmt +30114 -30114
  116. package/node_modules/ibm_db/test/nodeEE-leak-huge-query.js +152 -152
  117. package/node_modules/ibm_db/test/nodeEE-leak-multiple-query-multiple-connections.js +148 -148
  118. package/node_modules/ibm_db/test/nodeEE-leak-multiple-query-pool-connections.js +154 -154
  119. package/node_modules/ibm_db/test/nodeEE-leak-multiple-query.js +133 -133
  120. package/node_modules/ibm_db/test/nodeEE-stress-async-waterfall-multiple-connections.js +174 -174
  121. package/node_modules/ibm_db/test/nodeEE-stress-async-waterfall.js +169 -169
  122. package/node_modules/ibm_db/test/nodeEE-stress-mixed-query-multiple-connections.js +159 -159
  123. package/node_modules/ibm_db/test/nodeEE-stress-mixed-query.js +148 -148
  124. package/node_modules/ibm_db/test/odbc-bench.c +123 -123
  125. package/node_modules/ibm_db/test/perfTest.js +53 -53
  126. package/node_modules/ibm_db/test/quick-example.sh +30 -30
  127. package/node_modules/ibm_db/test/quick-example.ts +80 -80
  128. package/node_modules/ibm_db/test/run-bench.js +96 -96
  129. package/node_modules/ibm_db/test/run-nodeEE.js +132 -132
  130. package/node_modules/ibm_db/test/run-tests.js +132 -138
  131. package/node_modules/ibm_db/test/sql-cli.js +28 -28
  132. package/node_modules/ibm_db/test/test-all-data-types.js +109 -109
  133. package/node_modules/ibm_db/test/test-array-insert.js +178 -178
  134. package/node_modules/ibm_db/test/test-async-await.js +105 -105
  135. package/node_modules/ibm_db/test/test-attributes.js +34 -34
  136. package/node_modules/ibm_db/test/test-bad-pool-connection-prepare-execute.js +57 -57
  137. package/node_modules/ibm_db/test/test-basic-test.js +138 -138
  138. package/node_modules/ibm_db/test/test-binary-array-insert.js +73 -73
  139. package/node_modules/ibm_db/test/test-blob-from-file.js +90 -90
  140. package/node_modules/ibm_db/test/test-blob-insert.js +144 -144
  141. package/node_modules/ibm_db/test/test-blob-stream-insert.js +321 -299
  142. package/node_modules/ibm_db/test/test-blob-to-file.js +370 -370
  143. package/node_modules/ibm_db/test/test-block-fetch.js +364 -364
  144. package/node_modules/ibm_db/test/test-blocking-issue210.js +123 -123
  145. package/node_modules/ibm_db/test/test-call-async.js +64 -64
  146. package/node_modules/ibm_db/test/test-call-stmt.js +53 -53
  147. package/node_modules/ibm_db/test/test-cancel.js +703 -0
  148. package/node_modules/ibm_db/test/test-chinese-char.js +59 -59
  149. package/node_modules/ibm_db/test/test-connection.js +306 -0
  150. package/node_modules/ibm_db/test/test-date.js +32 -32
  151. package/node_modules/ibm_db/test/test-dbclob.js +93 -93
  152. package/node_modules/ibm_db/test/test-decimals.js +135 -135
  153. package/node_modules/ibm_db/test/test-describe-metadata.js +148 -0
  154. package/node_modules/ibm_db/test/test-executeFile.js +167 -167
  155. package/node_modules/ibm_db/test/test-executeFileSync.js +85 -85
  156. package/node_modules/ibm_db/test/test-fetch-apis.js +146 -146
  157. package/node_modules/ibm_db/test/test-fetchN.js +130 -130
  158. package/node_modules/ibm_db/test/test-getinfo.js +197 -197
  159. package/node_modules/ibm_db/test/test-ibm-db-issue14.js +58 -58
  160. package/node_modules/ibm_db/test/test-ibm-db-issue17.js +54 -54
  161. package/node_modules/ibm_db/test/test-ibm-db-issue18.js +54 -54
  162. package/node_modules/ibm_db/test/test-issue-1059-fetchAll-undefined.js +67 -67
  163. package/node_modules/ibm_db/test/test-issue-1080-array-blob-insert.js +40 -0
  164. package/node_modules/ibm_db/test/test-issue-54.js +39 -39
  165. package/node_modules/ibm_db/test/test-issue-get-column-value-2.js +44 -44
  166. package/node_modules/ibm_db/test/test-issue211.js +80 -80
  167. package/node_modules/ibm_db/test/test-issue253.js +39 -39
  168. package/node_modules/ibm_db/test/test-max-pool-size.js +96 -96
  169. package/node_modules/ibm_db/test/test-memory-leaks-new-objects.js +32 -32
  170. package/node_modules/ibm_db/test/test-multi-open-query-close.js +75 -75
  171. package/node_modules/ibm_db/test/test-param-put-data.js +713 -0
  172. package/node_modules/ibm_db/test/test-pool-idle-connection.js +72 -72
  173. package/node_modules/ibm_db/test/test-pool-operations.js +325 -0
  174. package/node_modules/ibm_db/test/test-pool-stale-connections.js +111 -111
  175. package/node_modules/ibm_db/test/test-pool-uncommited.js +33 -33
  176. package/node_modules/ibm_db/test/test-prepare-execute.js +339 -0
  177. package/node_modules/ibm_db/test/test-prepareSync-multiple-execution.js +93 -93
  178. package/node_modules/ibm_db/test/test-primary-foreign-keys.js +246 -0
  179. package/node_modules/ibm_db/test/test-procedures.js +243 -0
  180. package/node_modules/ibm_db/test/test-promise-all-data-types.js +42 -42
  181. package/node_modules/ibm_db/test/test-query-operations.js +405 -0
  182. package/node_modules/ibm_db/test/test-quick-example.js +25 -25
  183. package/node_modules/ibm_db/test/test-row-array-insert.js +167 -167
  184. package/node_modules/ibm_db/test/test-sp-array.js +54 -54
  185. package/node_modules/ibm_db/test/test-sp-dbc-6000.js +88 -88
  186. package/node_modules/ibm_db/test/test-sp-memleak.js +136 -136
  187. package/node_modules/ibm_db/test/test-sp-resultset-execute.js +269 -269
  188. package/node_modules/ibm_db/test/test-sp-resultset.js +228 -228
  189. package/node_modules/ibm_db/test/test-transactions.js +261 -0
  190. package/node_modules/ibm_db/test/test-typescript.js +48 -48
  191. package/node_modules/ibm_db/test/test-xml-datatype.js +70 -70
  192. package/node_modules/ibm_db/test/testWebApp.js +56 -56
  193. package/node_modules/ibm_db/test/trace +51 -51
  194. package/node_modules/ibm_db/test/typescript-apis-test.js +978 -978
  195. package/node_modules/ibm_db/test/webapp.html +17 -17
  196. package/node_modules/ibm_db/test/webapp.js +79 -79
  197. package/node_modules/ibm_db/typescript/README.md +28 -28
  198. package/node_modules/ibm_db/typescript/dist/Database.d.ts +26 -0
  199. package/node_modules/ibm_db/typescript/dist/ODBCStatement.d.ts +93 -0
  200. package/node_modules/string_decoder/node_modules/safe-buffer/LICENSE +21 -0
  201. package/node_modules/string_decoder/node_modules/safe-buffer/README.md +584 -0
  202. package/node_modules/string_decoder/node_modules/safe-buffer/index.d.ts +187 -0
  203. package/node_modules/string_decoder/node_modules/safe-buffer/index.js +62 -0
  204. package/node_modules/string_decoder/node_modules/safe-buffer/package.json +37 -0
  205. package/node_modules/which-typed-array/CHANGELOG.md +14 -0
  206. package/node_modules/which-typed-array/README.md +0 -2
  207. package/node_modules/which-typed-array/index.d.ts +288 -11
  208. package/node_modules/which-typed-array/index.js +6 -7
  209. package/node_modules/which-typed-array/package.json +12 -11
  210. package/package.json +10 -11
  211. package/node_modules/ibm_db/test/disabled/test-binding-statement-rebinding.js +0 -59
  212. package/node_modules/ibm_db/test/disabled/test-open-dont-close.js +0 -12
  213. package/node_modules/ibm_db/test/disabled/test-param-select-with-booleans-only.js +0 -21
  214. package/node_modules/ibm_db/test/disabled/test-param-select-with-decimals-only.js +0 -20
  215. package/node_modules/ibm_db/test/disabled/test-param-select-with-null.js +0 -21
  216. package/node_modules/ibm_db/test/disabled/test-param-select-with-nulls-mixed.js +0 -23
  217. package/node_modules/ibm_db/test/disabled/test-param-select-with-numbers-mixed.js +0 -22
  218. package/node_modules/ibm_db/test/disabled/test-param-select-with-numbers-only.js +0 -24
  219. package/node_modules/ibm_db/test/disabled/test-param-select-with-strings-only.js +0 -23
  220. package/node_modules/ibm_db/test/disabled/test-param-select-with-unicode.js +0 -15
  221. package/node_modules/ibm_db/test/disabled/test-prepare-bind-execute-closeSync.js +0 -62
  222. package/node_modules/ibm_db/test/disabled/test-prepare-bind-execute-error.js +0 -49
  223. package/node_modules/ibm_db/test/disabled/test-prepare-bind-execute-long-string.js +0 -63
  224. package/node_modules/ibm_db/test/disabled/test-prepare-bind-executeNonQuery.js +0 -63
  225. package/node_modules/ibm_db/test/disabled/test-prepare-bindSync-execute-closeSync.js +0 -46
  226. package/node_modules/ibm_db/test/disabled/test-prepare-bindSync-executeNonQuery.js +0 -50
  227. package/node_modules/ibm_db/test/disabled/test-prepare.js +0 -34
  228. package/node_modules/ibm_db/test/disabled/test-prepareSync.js +0 -29
  229. package/node_modules/ibm_db/test/disabled/test-query-select-fetchAll.js +0 -23
  230. package/node_modules/ibm_db/test/disabled/test-query-select-fetchAllSync.js +0 -23
  231. package/node_modules/ibm_db/test/disabled/test-query-select-unicode.js +0 -15
  232. package/node_modules/ibm_db/test/disabled/test-querySync-select-unicode.js +0 -20
  233. package/node_modules/ibm_db/test/test-affected-rows.js +0 -55
  234. package/node_modules/ibm_db/test/test-bad-connection-string.js +0 -30
  235. package/node_modules/ibm_db/test/test-binding-connection-timeOut.js +0 -31
  236. package/node_modules/ibm_db/test/test-binding-statement-executeSync.js +0 -84
  237. package/node_modules/ibm_db/test/test-binding-transaction-commit.js +0 -79
  238. package/node_modules/ibm_db/test/test-binding-transaction-commitSync.js +0 -53
  239. package/node_modules/ibm_db/test/test-closed.js +0 -14
  240. package/node_modules/ibm_db/test/test-connection-object.js +0 -16
  241. package/node_modules/ibm_db/test/test-describe-column.js +0 -92
  242. package/node_modules/ibm_db/test/test-describe-database.js +0 -18
  243. package/node_modules/ibm_db/test/test-describe-table.js +0 -31
  244. package/node_modules/ibm_db/test/test-domains-open.js +0 -19
  245. package/node_modules/ibm_db/test/test-global-open-close.js +0 -11
  246. package/node_modules/ibm_db/test/test-instantiate-one-and-end.js +0 -9
  247. package/node_modules/ibm_db/test/test-multi-open-close.js +0 -45
  248. package/node_modules/ibm_db/test/test-multi-openSync-closeSync.js +0 -52
  249. package/node_modules/ibm_db/test/test-open-close.js +0 -29
  250. package/node_modules/ibm_db/test/test-open-connectTimeout.js +0 -33
  251. package/node_modules/ibm_db/test/test-openSync.js +0 -31
  252. package/node_modules/ibm_db/test/test-pool-close.js +0 -120
  253. package/node_modules/ibm_db/test/test-pool-connect.js +0 -36
  254. package/node_modules/ibm_db/test/test-pool-rollbackTransaction.js +0 -35
  255. package/node_modules/ibm_db/test/test-prepareSync-bad-sql.js +0 -34
  256. package/node_modules/ibm_db/test/test-promise-open-close.js +0 -33
  257. package/node_modules/ibm_db/test/test-query-create-table-fetchSync.js +0 -23
  258. package/node_modules/ibm_db/test/test-query-create-table.js +0 -12
  259. package/node_modules/ibm_db/test/test-query-drop-table.js +0 -13
  260. package/node_modules/ibm_db/test/test-query-insert.js +0 -38
  261. package/node_modules/ibm_db/test/test-query-select-fetch.js +0 -21
  262. package/node_modules/ibm_db/test/test-query-select-fetchMode-array.js +0 -17
  263. package/node_modules/ibm_db/test/test-query-select.js +0 -64
  264. package/node_modules/ibm_db/test/test-queryResult.js +0 -35
  265. package/node_modules/ibm_db/test/test-queryStream.js +0 -43
  266. package/node_modules/ibm_db/test/test-querySync-select-with-exception.js +0 -25
  267. package/node_modules/ibm_db/test/test-querySync-select.js +0 -28
  268. package/node_modules/ibm_db/test/test-require-and-end.js +0 -8
  269. package/node_modules/ibm_db/test/test-statement-close.js +0 -118
  270. package/node_modules/ibm_db/test/test-transaction-commit-sync.js +0 -54
  271. package/node_modules/ibm_db/test/test-transaction-commit.js +0 -79
  272. package/node_modules/which-typed-array/eslint.config.mjs +0 -12
  273. package/node_modules/which-typed-array/test/index.js +0 -105
  274. /package/node_modules/{tar-fs/node_modules/chownr → chownr}/LICENSE +0 -0
  275. /package/node_modules/{tar-fs/node_modules/chownr → chownr}/README.md +0 -0
  276. /package/node_modules/{tar-fs/node_modules/chownr → chownr}/chownr.js +0 -0
  277. /package/node_modules/{tar-fs/node_modules/chownr → chownr}/package.json +0 -0
  278. /package/node_modules/{tar-stream/node_modules/string_decoder → string_decoder}/.travis.yml +0 -0
  279. /package/node_modules/{tar-stream/node_modules/string_decoder → string_decoder}/LICENSE +0 -0
  280. /package/node_modules/{tar-stream/node_modules/string_decoder → string_decoder}/README.md +0 -0
  281. /package/node_modules/{tar-stream/node_modules/string_decoder → string_decoder}/lib/string_decoder.js +0 -0
  282. /package/node_modules/{tar-stream/node_modules/string_decoder → string_decoder}/package.json +0 -0
@@ -1,861 +1,2047 @@
1
- /*
2
- Copyright (c) 2013, Dan VerWeire <dverweire@gmail.com>
3
-
4
- Permission to use, copy, modify, and/or distribute this software for any
5
- purpose with or without fee is hereby granted, provided that the above
6
- copyright notice and this permission notice appear in all copies.
7
-
8
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
- */
16
-
17
- #include <string.h>
18
- #include <time.h>
19
- #include <uv.h>
20
-
21
- #include "odbc.h"
22
- #include "odbc_connection.h"
23
- #include "odbc_result.h"
24
- #include "odbc_statement.h"
25
-
26
- Napi::FunctionReference ODBCStatement::constructor;
27
-
28
- Napi::Object ODBCStatement::Init(Napi::Env env, Napi::Object exports)
29
- {
30
- DEBUG_PRINTF("ODBCStatement::Init\n");
31
-
32
- Napi::Function func = DefineClass(env, "ODBCStatement", {
33
- InstanceMethod("execute", &ODBCStatement::Execute, NAPI_METHOD_ATTR),
34
- InstanceMethod("executeSync", &ODBCStatement::ExecuteSync, NAPI_METHOD_ATTR),
35
- InstanceMethod("executeDirect", &ODBCStatement::ExecuteDirect, NAPI_METHOD_ATTR),
36
- InstanceMethod("executeDirectSync", &ODBCStatement::ExecuteDirectSync, NAPI_METHOD_ATTR),
37
- InstanceMethod("executeNonQuery", &ODBCStatement::ExecuteNonQuery, NAPI_METHOD_ATTR),
38
- InstanceMethod("executeNonQuerySync", &ODBCStatement::ExecuteNonQuerySync, NAPI_METHOD_ATTR),
39
- InstanceMethod("prepare", &ODBCStatement::Prepare, NAPI_METHOD_ATTR),
40
- InstanceMethod("prepareSync", &ODBCStatement::PrepareSync, NAPI_METHOD_ATTR),
41
- InstanceMethod("bind", &ODBCStatement::Bind, NAPI_METHOD_ATTR),
42
- InstanceMethod("bindSync", &ODBCStatement::BindSync, NAPI_METHOD_ATTR),
43
- InstanceMethod("setAttr", &ODBCStatement::SetAttr, NAPI_METHOD_ATTR),
44
- InstanceMethod("setAttrSync", &ODBCStatement::SetAttrSync, NAPI_METHOD_ATTR),
45
- InstanceMethod("close", &ODBCStatement::Close, NAPI_METHOD_ATTR),
46
- InstanceMethod("closeSync", &ODBCStatement::CloseSync, NAPI_METHOD_ATTR),
47
- });
48
-
49
- constructor = Napi::Persistent(func);
50
- constructor.SuppressDestruct();
51
- exports.Set("ODBCStatement", func);
52
- return exports;
53
- }
54
-
55
- ODBCStatement::~ODBCStatement()
56
- {
57
- DEBUG_PRINTF("ODBCStatement::~ODBCStatement m_hSTMT=%X\n", m_hSTMT);
58
- this->Free();
59
- }
60
-
61
- void ODBCStatement::Free()
62
- {
63
- DEBUG_PRINTF("ODBCStatement::Free - Entry: paramCount=%i, m_hSTMT=%X\n", paramCount, m_hSTMT);
64
- if (paramCount) { FREE_PARAMS(params, paramCount); }
65
- if (m_hSTMT) {
66
- SQLFreeHandle(SQL_HANDLE_STMT, m_hSTMT);
67
- m_hSTMT = (SQLHSTMT)NULL;
68
- }
69
- if (buffer != NULL) { free((uint16_t *)buffer); buffer = NULL; }
70
- bufferLength = 0;
71
- DEBUG_PRINTF("ODBCStatement::Free - Exit\n");
72
- }
73
-
74
- ODBCStatement::ODBCStatement(const Napi::CallbackInfo &info) : Napi::ObjectWrap<ODBCStatement>(info)
75
- {
76
- DEBUG_PRINTF("ODBCStatement::New - Entry\n");
77
- Napi::Env env = info.Env();
78
-
79
- if (info.Length() < 3 || !info[0].IsExternal() || !info[1].IsExternal() || !info[2].IsExternal())
80
- {
81
- Napi::TypeError::New(env, "ODBCStatement::New requires 3 external arguments").ThrowAsJavaScriptException();
82
- return;
83
- }
84
-
85
- m_hENV = (SQLHENV)((intptr_t)info[0].As<Napi::External<void>>().Data());
86
- m_hDBC = (SQLHDBC)((intptr_t)info[1].As<Napi::External<void>>().Data());
87
- m_hSTMT = (SQLHSTMT)((intptr_t)info[2].As<Napi::External<void>>().Data());
88
-
89
- bufferLength = MAX_VALUE_SIZE;
90
- buffer = NULL;
91
- colCount = 0;
92
- paramCount = 0;
93
- params = 0;
94
- DEBUG_PRINTF("ODBCStatement::New - Exit\n");
95
- }
96
-
97
- /*
98
- * Execute
99
- */
100
- Napi::Value ODBCStatement::Execute(const Napi::CallbackInfo &info)
101
- {
102
- DEBUG_PRINTF("ODBCStatement::Execute - Entry\n");
103
- Napi::Env env = info.Env();
104
- REQ_FUN_ARG(0, cb);
105
-
106
- uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
107
- MEMCHECK(work_req);
108
- execute_work_data *data = (execute_work_data *)calloc(1, sizeof(execute_work_data));
109
- if (!data) free(work_req);
110
- MEMCHECK(data);
111
-
112
- data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
113
- data->stmt = this;
114
- data->env = env;
115
- work_req->data = data;
116
-
117
- uv_queue_work(uv_default_loop(), work_req, UV_Execute, (uv_after_work_cb)UV_AfterExecute);
118
- this->Ref();
119
- return env.Undefined();
120
- }
121
-
122
- void ODBCStatement::UV_Execute(uv_work_t *req)
123
- {
124
- DEBUG_PRINTF("ODBCStatement::UV_Execute - Entry\n");
125
- execute_work_data *data = (execute_work_data *)(req->data);
126
-
127
- SQLRETURN ret = SQLExecute(data->stmt->m_hSTMT);
128
- if (ret == SQL_NEED_DATA)
129
- ret = ODBC::PutDataLoop(data->stmt->m_hSTMT, data->stmt->params, data->stmt->paramCount);
130
-
131
- data->result = ret;
132
- DEBUG_PRINTF("ODBCStatement::UV_Execute - Exit\n");
133
- }
134
-
135
- void ODBCStatement::UV_AfterExecute(uv_work_t *req, int status)
136
- {
137
- DEBUG_PRINTF("ODBCStatement::UV_AfterExecute - Entry\n");
138
- execute_work_data *data = (execute_work_data *)(req->data);
139
- Napi::Env env(data->env);
140
- Napi::HandleScope scope(env);
141
-
142
- ODBCStatement *stmt = data->stmt->self();
143
- int outParamCount = 0;
144
- Napi::Array sp_result = Napi::Array::New(env);
145
-
146
- if (SQL_SUCCEEDED(data->result))
147
- {
148
- for (int i = 0; i < stmt->paramCount; i++)
149
- {
150
- if (stmt->params[i].paramtype % 2 == 0)
151
- {
152
- sp_result.Set(outParamCount, ODBC::GetOutputParameter(env, &stmt->params[i]));
153
- outParamCount++;
154
- }
155
- }
156
- }
157
- if (stmt->paramCount) { FREE_PARAMS(stmt->params, stmt->paramCount); }
158
-
159
- if (data->result == SQL_ERROR)
160
- {
161
- ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
162
- }
163
- else
164
- {
165
- bool *canFreeHandle = new bool(false);
166
- Napi::Value args[4] = {
167
- Napi::External<void>::New(env, (void *)(intptr_t)stmt->m_hENV),
168
- Napi::External<void>::New(env, (void *)(intptr_t)stmt->m_hDBC),
169
- Napi::External<void>::New(env, (void *)(intptr_t)stmt->m_hSTMT),
170
- Napi::External<void>::New(env, (void *)canFreeHandle)
171
- };
172
- Napi::Object js_result = ODBCResult::constructor.New({args[0], args[1], args[2], args[3]});
173
- data->cb->Call({env.Null(), js_result, outParamCount ? (Napi::Value)sp_result : env.Null()});
174
- }
175
-
176
- stmt->Unref();
177
- delete data->cb;
178
- free(data);
179
- free(req);
180
- DEBUG_PRINTF("ODBCStatement::UV_AfterExecute - Exit\n");
181
- }
182
-
183
- /*
184
- * ExecuteSync
185
- */
186
- Napi::Value ODBCStatement::ExecuteSync(const Napi::CallbackInfo &info)
187
- {
188
- DEBUG_PRINTF("ODBCStatement::ExecuteSync - Entry\n");
189
- Napi::Env env = info.Env();
190
- int outParamCount = 0;
191
- Napi::Array sp_result = Napi::Array::New(env);
192
-
193
- SQLRETURN ret = SQLExecute(m_hSTMT);
194
- if (ret == SQL_NEED_DATA)
195
- ret = ODBC::PutDataLoop(m_hSTMT, params, paramCount);
196
-
197
- if (SQL_SUCCEEDED(ret))
198
- {
199
- for (int i = 0; i < paramCount; i++)
200
- {
201
- if (params[i].paramtype % 2 == 0)
202
- {
203
- sp_result.Set(outParamCount, ODBC::GetOutputParameter(env, &params[i]));
204
- outParamCount++;
205
- }
206
- }
207
- }
208
- if (paramCount) { FREE_PARAMS(params, paramCount); }
209
-
210
- if (ret == SQL_ERROR)
211
- {
212
- napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
213
- (char *)"[node-odbc] Error in ODBCStatement::ExecuteSync"));
214
- return env.Null();
215
- }
216
- else
217
- {
218
- bool *canFreeHandle = new bool(false);
219
- Napi::Value result[4] = {
220
- Napi::External<void>::New(env, (void *)(intptr_t)m_hENV),
221
- Napi::External<void>::New(env, (void *)(intptr_t)m_hDBC),
222
- Napi::External<void>::New(env, (void *)(intptr_t)m_hSTMT),
223
- Napi::External<void>::New(env, (void *)canFreeHandle)
224
- };
225
- Napi::Object js_result = ODBCResult::constructor.New({result[0], result[1], result[2], result[3]});
226
-
227
- if (outParamCount)
228
- {
229
- Napi::Array resultset = Napi::Array::New(env);
230
- resultset.Set((uint32_t)0, js_result);
231
- resultset.Set((uint32_t)1, sp_result);
232
- return resultset;
233
- }
234
- return js_result;
235
- }
236
- }
237
-
238
- /*
239
- * ExecuteNonQuery
240
- */
241
- Napi::Value ODBCStatement::ExecuteNonQuery(const Napi::CallbackInfo &info)
242
- {
243
- DEBUG_PRINTF("ODBCStatement::ExecuteNonQuery - Entry\n");
244
- Napi::Env env = info.Env();
245
- REQ_FUN_ARG(0, cb);
246
-
247
- uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
248
- MEMCHECK(work_req);
249
- execute_work_data *data = (execute_work_data *)calloc(1, sizeof(execute_work_data));
250
- if (!data) free(work_req);
251
- MEMCHECK(data);
252
-
253
- data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
254
- data->stmt = this;
255
- data->env = env;
256
- work_req->data = data;
257
-
258
- uv_queue_work(uv_default_loop(), work_req, UV_ExecuteNonQuery, (uv_after_work_cb)UV_AfterExecuteNonQuery);
259
- this->Ref();
260
- return env.Undefined();
261
- }
262
-
263
- void ODBCStatement::UV_ExecuteNonQuery(uv_work_t *req)
264
- {
265
- DEBUG_PRINTF("ODBCStatement::UV_ExecuteNonQuery - Entry\n");
266
- execute_work_data *data = (execute_work_data *)(req->data);
267
-
268
- SQLRETURN ret = SQLExecute(data->stmt->m_hSTMT);
269
- if (ret == SQL_NEED_DATA)
270
- ret = ODBC::PutDataLoop(data->stmt->m_hSTMT, data->stmt->params, data->stmt->paramCount);
271
-
272
- data->result = ret;
273
- DEBUG_PRINTF("ODBCStatement::UV_ExecuteNonQuery - Exit\n");
274
- }
275
-
276
- void ODBCStatement::UV_AfterExecuteNonQuery(uv_work_t *req, int status)
277
- {
278
- DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteNonQuery - Entry\n");
279
- execute_work_data *data = (execute_work_data *)(req->data);
280
- Napi::Env env(data->env);
281
- Napi::HandleScope scope(env);
282
-
283
- ODBCStatement *self = data->stmt->self();
284
- SQLLEN rowCount = 0;
285
- SQLRETURN ret = data->result;
286
- Napi::Value warning;
287
- bool hasWarning = false;
288
-
289
- if (ret > SQL_SUCCESS && ret != SQL_NO_DATA_FOUND)
290
- {
291
- warning = ODBC::GetSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT,
292
- (char *)"[node-ibm_db] Warning in ODBCStatement::UV_AfterExecuteNonQuery");
293
- hasWarning = true;
294
- }
295
- if ((ret == SQL_SUCCESS) || (ret == SQL_SUCCESS_WITH_INFO))
296
- ret = SQLRowCount(self->m_hSTMT, &rowCount);
297
-
298
- if (ret < SQL_SUCCESS)
299
- {
300
- ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT, data->cb);
301
- }
302
- else
303
- {
304
- Napi::Value err;
305
- if ((ret > SQL_SUCCESS) && !hasWarning && (ret != SQL_NO_DATA_FOUND))
306
- err = ODBC::GetSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT,
307
- (char *)"[node-ibm_db] Warning in ODBCStatement::UV_AfterExecuteNonQuery for SQLRowCount.");
308
- else if (hasWarning)
309
- err = warning;
310
- else
311
- err = env.Null();
312
-
313
- data->cb->Call({err, Napi::Number::New(env, (double)rowCount)});
314
- }
315
-
316
- SQLFreeStmt(self->m_hSTMT, SQL_CLOSE);
317
- self->Unref();
318
- delete data->cb;
319
- free(data);
320
- free(req);
321
- DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteNonQuery - Exit\n");
322
- }
323
-
324
- /*
325
- * ExecuteNonQuerySync
326
- */
327
- Napi::Value ODBCStatement::ExecuteNonQuerySync(const Napi::CallbackInfo &info)
328
- {
329
- DEBUG_PRINTF("ODBCStatement::ExecuteNonQuerySync - Entry\n");
330
- Napi::Env env = info.Env();
331
- SQLLEN rowCount = 0;
332
-
333
- SQLRETURN ret = SQLExecute(m_hSTMT);
334
- if (ret == SQL_NEED_DATA)
335
- ret = ODBC::PutDataLoop(m_hSTMT, params, paramCount);
336
-
337
- if ((ret == SQL_SUCCESS) || (ret == SQL_SUCCESS_WITH_INFO))
338
- ret = SQLRowCount(m_hSTMT, &rowCount);
339
-
340
- if (ret < SQL_SUCCESS)
341
- {
342
- napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
343
- (char *)"[node-ibm_db] Error in ODBCStatement::ExecuteNonQuerySync"));
344
- SQLFreeStmt(m_hSTMT, SQL_CLOSE);
345
- return env.Null();
346
- }
347
-
348
- SQLFreeStmt(m_hSTMT, SQL_CLOSE);
349
- return Napi::Number::New(env, (double)rowCount);
350
- }
351
-
352
- /*
353
- * ExecuteDirect
354
- */
355
- Napi::Value ODBCStatement::ExecuteDirect(const Napi::CallbackInfo &info)
356
- {
357
- DEBUG_PRINTF("ODBCStatement::ExecuteDirect - Entry\n");
358
- Napi::Env env = info.Env();
359
-
360
- REQ_STRO_ARG(0, sql);
361
- REQ_FUN_ARG(1, cb);
362
- int len = (int)sql.length();
363
- void *cppSQL = NULL;
364
- GETCPPSTR(cppSQL, sql, len);
365
-
366
- uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
367
- if (!work_req) free(cppSQL);
368
- MEMCHECK(work_req);
369
- execute_direct_work_data *data = (execute_direct_work_data *)calloc(1, sizeof(execute_direct_work_data));
370
- if (!data) { free(cppSQL); free(work_req); }
371
- MEMCHECK(data);
372
-
373
- data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
374
- data->sql = cppSQL;
375
- data->sqlLen = len;
376
- data->stmt = this;
377
- data->env = env;
378
- work_req->data = data;
379
-
380
- uv_queue_work(uv_default_loop(), work_req, UV_ExecuteDirect, (uv_after_work_cb)UV_AfterExecuteDirect);
381
- this->Ref();
382
- return env.Undefined();
383
- }
384
-
385
- void ODBCStatement::UV_ExecuteDirect(uv_work_t *req)
386
- {
387
- DEBUG_PRINTF("ODBCStatement::UV_ExecuteDirect - Entry\n");
388
- execute_direct_work_data *data = (execute_direct_work_data *)(req->data);
389
- data->result = SQLExecDirect(data->stmt->m_hSTMT, (SQLTCHAR *)data->sql, data->sqlLen);
390
- DEBUG_PRINTF("ODBCStatement::UV_ExecuteDirect - Exit\n");
391
- }
392
-
393
- void ODBCStatement::UV_AfterExecuteDirect(uv_work_t *req, int status)
394
- {
395
- DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteDirect - Entry\n");
396
- execute_direct_work_data *data = (execute_direct_work_data *)(req->data);
397
- Napi::Env env(data->env);
398
- Napi::HandleScope scope(env);
399
- ODBCStatement *self = data->stmt->self();
400
-
401
- if (data->result == SQL_ERROR)
402
- {
403
- ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT, data->cb);
404
- }
405
- else
406
- {
407
- bool *canFreeHandle = new bool(false);
408
- Napi::Value args[4] = {
409
- Napi::External<void>::New(env, (void *)(intptr_t)self->m_hENV),
410
- Napi::External<void>::New(env, (void *)(intptr_t)self->m_hDBC),
411
- Napi::External<void>::New(env, (void *)(intptr_t)self->m_hSTMT),
412
- Napi::External<void>::New(env, (void *)canFreeHandle)
413
- };
414
- Napi::Object js_result = ODBCResult::constructor.New({args[0], args[1], args[2], args[3]});
415
- data->cb->Call({env.Null(), js_result});
416
- }
417
-
418
- self->Unref();
419
- delete data->cb;
420
- free(data->sql);
421
- free(data);
422
- free(req);
423
- DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteDirect - Exit\n");
424
- }
425
-
426
- /*
427
- * ExecuteDirectSync
428
- */
429
- Napi::Value ODBCStatement::ExecuteDirectSync(const Napi::CallbackInfo &info)
430
- {
431
- DEBUG_PRINTF("ODBCStatement::ExecuteDirectSync - Entry\n");
432
- Napi::Env env = info.Env();
433
-
434
- REQ_STRO_ARG(0, sql);
435
- int len = (int)sql.length();
436
- void *cppSQL = NULL;
437
- GETCPPSTR(cppSQL, sql, len);
438
-
439
- SQLRETURN ret = SQLExecDirect(m_hSTMT, (SQLTCHAR *)cppSQL, len);
440
- free(cppSQL);
441
-
442
- if (ret == SQL_ERROR)
443
- {
444
- napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
445
- (char *)"[node-odbc] Error in ODBCStatement::ExecuteDirectSync"));
446
- return env.Null();
447
- }
448
-
449
- bool *canFreeHandle = new bool(false);
450
- Napi::Value result[4] = {
451
- Napi::External<void>::New(env, (void *)(intptr_t)m_hENV),
452
- Napi::External<void>::New(env, (void *)(intptr_t)m_hDBC),
453
- Napi::External<void>::New(env, (void *)(intptr_t)m_hSTMT),
454
- Napi::External<void>::New(env, (void *)canFreeHandle)
455
- };
456
- return ODBCResult::constructor.New({result[0], result[1], result[2], result[3]});
457
- }
458
-
459
- /*
460
- * PrepareSync
461
- */
462
- Napi::Value ODBCStatement::PrepareSync(const Napi::CallbackInfo &info)
463
- {
464
- DEBUG_PRINTF("ODBCStatement::PrepareSync - Entry\n");
465
- Napi::Env env = info.Env();
466
-
467
- REQ_STRO_ARG(0, sql);
468
- int sqlLen = (int)sql.length();
469
- void *sql2 = NULL;
470
- GETCPPSTR(sql2, sql, sqlLen);
471
-
472
- SQLRETURN ret = SQLPrepare(m_hSTMT, (SQLTCHAR *)sql2, sqlLen);
473
- free(sql2);
474
-
475
- if (SQL_SUCCEEDED(ret))
476
- return Napi::Boolean::New(env, true);
477
-
478
- napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
479
- (char *)"[node-odbc] Error in ODBCStatement::PrepareSync"));
480
- return Napi::Boolean::New(env, false);
481
- }
482
-
483
- /*
484
- * Prepare
485
- */
486
- Napi::Value ODBCStatement::Prepare(const Napi::CallbackInfo &info)
487
- {
488
- DEBUG_PRINTF("ODBCStatement::Prepare - Entry\n");
489
- Napi::Env env = info.Env();
490
-
491
- REQ_STRO_ARG(0, sql);
492
- REQ_FUN_ARG(1, cb);
493
- int sqlLen = (int)sql.length();
494
- void *cppSQL = NULL;
495
- GETCPPSTR(cppSQL, sql, sqlLen);
496
-
497
- uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
498
- if (!work_req) free(cppSQL);
499
- MEMCHECK(work_req);
500
- prepare_work_data *data = (prepare_work_data *)calloc(1, sizeof(prepare_work_data));
501
- if (!data) { free(cppSQL); free(work_req); }
502
- MEMCHECK(data);
503
-
504
- data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
505
- data->sql = cppSQL;
506
- data->sqlLen = sqlLen;
507
- data->stmt = this;
508
- data->env = env;
509
- work_req->data = data;
510
-
511
- uv_queue_work(uv_default_loop(), work_req, UV_Prepare, (uv_after_work_cb)UV_AfterPrepare);
512
- this->Ref();
513
- return env.Undefined();
514
- }
515
-
516
- void ODBCStatement::UV_Prepare(uv_work_t *req)
517
- {
518
- DEBUG_PRINTF("ODBCStatement::UV_Prepare - Entry\n");
519
- prepare_work_data *data = (prepare_work_data *)(req->data);
520
- data->result = SQLPrepare(data->stmt->m_hSTMT, (SQLTCHAR *)data->sql, data->sqlLen);
521
- DEBUG_PRINTF("ODBCStatement::UV_Prepare - Exit\n");
522
- }
523
-
524
- void ODBCStatement::UV_AfterPrepare(uv_work_t *req, int status)
525
- {
526
- DEBUG_PRINTF("ODBCStatement::UV_AfterPrepare - Entry\n");
527
- prepare_work_data *data = (prepare_work_data *)(req->data);
528
- Napi::Env env(data->env);
529
- Napi::HandleScope scope(env);
530
-
531
- if (data->result == SQL_ERROR)
532
- ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, data->stmt->m_hSTMT, data->cb);
533
- else
534
- data->cb->Call({env.Null(), Napi::Boolean::New(env, true)});
535
-
536
- data->stmt->Unref();
537
- delete data->cb;
538
- free(data->sql);
539
- free(data);
540
- free(req);
541
- DEBUG_PRINTF("ODBCStatement::UV_AfterPrepare - Exit\n");
542
- }
543
-
544
- /*
545
- * BindSync
546
- */
547
- Napi::Value ODBCStatement::BindSync(const Napi::CallbackInfo &info)
548
- {
549
- DEBUG_PRINTF("ODBCStatement::BindSync - Entry\n");
550
- Napi::Env env = info.Env();
551
-
552
- if (!info[0].IsArray())
553
- {
554
- Napi::TypeError::New(env, "Argument 1 must be an Array").ThrowAsJavaScriptException();
555
- return env.Undefined();
556
- }
557
-
558
- if (paramCount) { FREE_PARAMS(params, paramCount); }
559
- params = ODBC::GetParametersFromArray(env, info[0].As<Napi::Array>(), &paramCount);
560
- SQLRETURN ret = ODBC::BindParameters(m_hSTMT, params, paramCount);
561
-
562
- if (SQL_SUCCEEDED(ret))
563
- return Napi::Boolean::New(env, true);
564
-
565
- napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
566
- (char *)"[node-odbc] Error in ODBCStatement::BindSync"));
567
- return Napi::Boolean::New(env, false);
568
- }
569
-
570
- /*
571
- * Bind
572
- */
573
- Napi::Value ODBCStatement::Bind(const Napi::CallbackInfo &info)
574
- {
575
- DEBUG_PRINTF("ODBCStatement::Bind - Entry\n");
576
- Napi::Env env = info.Env();
577
-
578
- if (!info[0].IsArray())
579
- {
580
- Napi::TypeError::New(env, "Argument 1 must be an Array").ThrowAsJavaScriptException();
581
- return env.Undefined();
582
- }
583
- REQ_FUN_ARG(1, cb);
584
-
585
- uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
586
- MEMCHECK(work_req);
587
- bind_work_data *data = (bind_work_data *)calloc(1, sizeof(bind_work_data));
588
- if (!data) free(work_req);
589
- MEMCHECK(data);
590
-
591
- if (paramCount) { FREE_PARAMS(params, paramCount); }
592
-
593
- data->stmt = this;
594
- data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
595
- data->env = env;
596
-
597
- params = ODBC::GetParametersFromArray(env, info[0].As<Napi::Array>(), &paramCount);
598
- work_req->data = data;
599
-
600
- uv_queue_work(uv_default_loop(), work_req, UV_Bind, (uv_after_work_cb)UV_AfterBind);
601
- this->Ref();
602
- return env.Undefined();
603
- }
604
-
605
- void ODBCStatement::UV_Bind(uv_work_t *req)
606
- {
607
- DEBUG_PRINTF("ODBCStatement::UV_Bind - Entry\n");
608
- bind_work_data *data = (bind_work_data *)(req->data);
609
- data->result = ODBC::BindParameters(data->stmt->m_hSTMT, data->stmt->params, data->stmt->paramCount);
610
- DEBUG_PRINTF("ODBCStatement::UV_Bind - Exit\n");
611
- }
612
-
613
- void ODBCStatement::UV_AfterBind(uv_work_t *req, int status)
614
- {
615
- DEBUG_PRINTF("ODBCStatement::UV_AfterBind - Entry\n");
616
- bind_work_data *data = (bind_work_data *)(req->data);
617
- Napi::Env env(data->env);
618
- Napi::HandleScope scope(env);
619
- ODBCStatement *self = data->stmt->self();
620
-
621
- if (data->result == SQL_ERROR)
622
- ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT, data->cb);
623
- else
624
- data->cb->Call({env.Null(), Napi::Boolean::New(env, true)});
625
-
626
- self->Unref();
627
- delete data->cb;
628
- free(data);
629
- free(req);
630
- DEBUG_PRINTF("ODBCStatement::UV_AfterBind - Exit\n");
631
- }
632
-
633
- /*
634
- * SetAttrSync
635
- */
636
- Napi::Value ODBCStatement::SetAttrSync(const Napi::CallbackInfo &info)
637
- {
638
- DEBUG_PRINTF("ODBCStatement::SetAttrSync - Entry\n");
639
- Napi::Env env = info.Env();
640
- REQ_ARGS(2);
641
- REQ_INT_ARG(0, attr);
642
-
643
- SQLPOINTER valuePtr = NULL;
644
- SQLINTEGER stringLength = SQL_IS_INTEGER;
645
-
646
- if (info[1].IsNumber())
647
- valuePtr = reinterpret_cast<SQLPOINTER>(static_cast<intptr_t>(info[1].As<Napi::Number>().Int32Value()));
648
- else if (info[1].IsNull())
649
- valuePtr = (SQLPOINTER)0;
650
- else if (info[1].IsString())
651
- {
652
- std::string value = info[1].As<Napi::String>().Utf8Value();
653
- stringLength = (SQLINTEGER)value.length();
654
- GETCPPSTR(valuePtr, value, stringLength);
655
- }
656
- else
657
- {
658
- Napi::TypeError::New(env, "Unsupported Statement Attribute Value.").ThrowAsJavaScriptException();
659
- return env.Undefined();
660
- }
661
-
662
- SQLRETURN ret = SQLSetStmtAttr(m_hSTMT, attr, valuePtr, stringLength);
663
-
664
- if (stringLength != SQL_IS_INTEGER) { FREE(valuePtr); }
665
-
666
- if (SQL_SUCCEEDED(ret))
667
- return Napi::Boolean::New(env, true);
668
-
669
- napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
670
- (char *)"[node-odbc] Error in ODBCStatement::SetAttrSync"));
671
- return Napi::Boolean::New(env, false);
672
- }
673
-
674
- /*
675
- * SetAttr
676
- */
677
- Napi::Value ODBCStatement::SetAttr(const Napi::CallbackInfo &info)
678
- {
679
- DEBUG_PRINTF("ODBCStatement::SetAttr - Entry\n");
680
- Napi::Env env = info.Env();
681
- REQ_ARGS(3);
682
- REQ_INT_ARG(0, attr);
683
- REQ_FUN_ARG(2, cb);
684
-
685
- SQLPOINTER valuePtr = NULL;
686
- SQLINTEGER stringLength = SQL_IS_INTEGER;
687
-
688
- if (info[1].IsNumber())
689
- valuePtr = reinterpret_cast<SQLPOINTER>(static_cast<intptr_t>(info[1].As<Napi::Number>().Int32Value()));
690
- else if (info[1].IsNull())
691
- valuePtr = (SQLPOINTER)0;
692
- else if (info[1].IsString())
693
- {
694
- std::string value = info[1].As<Napi::String>().Utf8Value();
695
- stringLength = (SQLINTEGER)value.length();
696
- GETCPPSTR(valuePtr, value, stringLength);
697
- }
698
- else
699
- {
700
- Napi::TypeError::New(env, "Unsupported Statement Attribute Value.").ThrowAsJavaScriptException();
701
- return env.Undefined();
702
- }
703
-
704
- uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
705
- if (!work_req && info[1].IsString()) free(valuePtr);
706
- MEMCHECK(work_req);
707
- stmt_setattr_work_data *data = (stmt_setattr_work_data *)calloc(1, sizeof(stmt_setattr_work_data));
708
- if (!data) { if (info[1].IsString()) free(valuePtr); free(work_req); }
709
- MEMCHECK(data);
710
-
711
- data->stmt = this;
712
- data->attr = attr;
713
- data->valuePtr = valuePtr;
714
- data->stringLength = stringLength;
715
- data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
716
- data->env = env;
717
- work_req->data = data;
718
-
719
- uv_queue_work(uv_default_loop(), work_req, UV_SetAttr, (uv_after_work_cb)UV_AfterSetAttr);
720
- this->Ref();
721
- return env.Undefined();
722
- }
723
-
724
- void ODBCStatement::UV_SetAttr(uv_work_t *req)
725
- {
726
- DEBUG_PRINTF("ODBCStatement::UV_SetAttr - Entry\n");
727
- stmt_setattr_work_data *data = (stmt_setattr_work_data *)(req->data);
728
- data->result = SQLSetStmtAttr(data->stmt->m_hSTMT, data->attr, data->valuePtr, data->stringLength);
729
- DEBUG_PRINTF("ODBCStatement::UV_SetAttr - Exit\n");
730
- }
731
-
732
- void ODBCStatement::UV_AfterSetAttr(uv_work_t *req, int status)
733
- {
734
- DEBUG_PRINTF("ODBCStatement::UV_AfterSetAttr - Entry\n");
735
- stmt_setattr_work_data *data = (stmt_setattr_work_data *)(req->data);
736
- Napi::Env env(data->env);
737
- Napi::HandleScope scope(env);
738
- ODBCStatement *self = data->stmt->self();
739
-
740
- if (data->result == SQL_ERROR)
741
- ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT, data->cb);
742
- else
743
- data->cb->Call({env.Null(), Napi::Boolean::New(env, true)});
744
-
745
- self->Unref();
746
- delete data->cb;
747
- if (data->stringLength != SQL_IS_INTEGER) { FREE(data->valuePtr); }
748
- free(data);
749
- free(req);
750
- DEBUG_PRINTF("ODBCStatement::UV_AfterSetAttr - Exit\n");
751
- }
752
-
753
- /*
754
- * Close
755
- */
756
- Napi::Value ODBCStatement::Close(const Napi::CallbackInfo &info)
757
- {
758
- DEBUG_PRINTF("ODBCStatement::Close - Entry\n");
759
- Napi::Env env = info.Env();
760
- Napi::Function cb;
761
- SQLUSMALLINT closeOption = SQL_DROP;
762
-
763
- if (info.Length() == 2)
764
- {
765
- if (!info[0].IsNumber())
766
- {
767
- Napi::TypeError::New(env, "Argument 0 must be an Integer.").ThrowAsJavaScriptException();
768
- return env.Undefined();
769
- }
770
- if (!info[1].IsFunction())
771
- {
772
- Napi::TypeError::New(env, "Argument 1 must be a Function.").ThrowAsJavaScriptException();
773
- return env.Undefined();
774
- }
775
- closeOption = (SQLUSMALLINT)info[0].As<Napi::Number>().Int32Value();
776
- cb = info[1].As<Napi::Function>();
777
- }
778
- else if (info.Length() == 1)
779
- {
780
- if (!info[0].IsFunction())
781
- {
782
- Napi::TypeError::New(env, "ODBCStatement::Close(): Argument 0 must be a Function.").ThrowAsJavaScriptException();
783
- return env.Undefined();
784
- }
785
- cb = info[0].As<Napi::Function>();
786
- }
787
-
788
- uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
789
- MEMCHECK(work_req);
790
- stmt_close_work_data *data = (stmt_close_work_data *)(calloc(1, sizeof(stmt_close_work_data)));
791
- if (!data) free(work_req);
792
- MEMCHECK(data);
793
-
794
- data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
795
- data->stmt = this;
796
- data->closeOption = closeOption;
797
- data->env = env;
798
- work_req->data = data;
799
-
800
- uv_queue_work(uv_default_loop(), work_req, UV_Close, (uv_after_work_cb)UV_AfterClose);
801
- this->Ref();
802
- return env.Undefined();
803
- }
804
-
805
- void ODBCStatement::UV_Close(uv_work_t *req)
806
- {
807
- DEBUG_PRINTF("ODBCStatement::UV_Close - Entry\n");
808
- stmt_close_work_data *data = (stmt_close_work_data *)(req->data);
809
- ODBCStatement *stmt = data->stmt;
810
-
811
- if (data->closeOption == SQL_DROP)
812
- {
813
- stmt->Free();
814
- data->result = 0;
815
- }
816
- else
817
- {
818
- data->result = SQLFreeStmt((SQLHSTMT)stmt->m_hSTMT, data->closeOption);
819
- }
820
- DEBUG_PRINTF("ODBCStatement::UV_Close - Exit\n");
821
- }
822
-
823
- void ODBCStatement::UV_AfterClose(uv_work_t *req, int status)
824
- {
825
- DEBUG_PRINTF("ODBCStatement::UV_AfterClose - Entry\n");
826
- stmt_close_work_data *data = (stmt_close_work_data *)(req->data);
827
- Napi::Env env(data->env);
828
- Napi::HandleScope scope(env);
829
- ODBCStatement *self = data->stmt->self();
830
-
831
- if (data->result != SQL_SUCCESS)
832
- ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, data->stmt->m_hSTMT, data->cb);
833
- else
834
- data->cb->Call({env.Null()});
835
-
836
- self->Unref();
837
- delete data->cb;
838
- free(data);
839
- free(req);
840
- DEBUG_PRINTF("ODBCStatement::UV_AfterClose - Exit\n");
841
- }
842
-
843
- /*
844
- * CloseSync
845
- */
846
- Napi::Value ODBCStatement::CloseSync(const Napi::CallbackInfo &info)
847
- {
848
- DEBUG_PRINTF("ODBCStatement::CloseSync - Entry\n");
849
- Napi::Env env = info.Env();
850
- SQLUSMALLINT closeOption = SQL_DROP;
851
-
852
- if (info.Length() > 0 && info[0].IsNumber())
853
- closeOption = (SQLUSMALLINT)info[0].As<Napi::Number>().Int32Value();
854
-
855
- if (closeOption == SQL_DROP)
856
- this->Free();
857
- else
858
- SQLFreeStmt(m_hSTMT, closeOption);
859
-
860
- return Napi::Boolean::New(env, true);
861
- }
1
+ /*
2
+ Copyright (c) 2013, Dan VerWeire <dverweire@gmail.com>
3
+
4
+ Permission to use, copy, modify, and/or distribute this software for any
5
+ purpose with or without fee is hereby granted, provided that the above
6
+ copyright notice and this permission notice appear in all copies.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #include <string.h>
18
+ #include <time.h>
19
+ #include <uv.h>
20
+
21
+ #include "odbc.h"
22
+ #include "odbc_connection.h"
23
+ #include "odbc_result.h"
24
+ #include "odbc_statement.h"
25
+
26
+ Napi::FunctionReference ODBCStatement::constructor;
27
+
28
+ Napi::Object ODBCStatement::Init(Napi::Env env, Napi::Object exports)
29
+ {
30
+ DEBUG_PRINTF("ODBCStatement::Init\n");
31
+
32
+ Napi::Function func = DefineClass(env, "ODBCStatement", {
33
+ InstanceMethod("execute", &ODBCStatement::Execute, NAPI_METHOD_ATTR),
34
+ InstanceMethod("executeSync", &ODBCStatement::ExecuteSync, NAPI_METHOD_ATTR),
35
+ InstanceMethod("executeDirect", &ODBCStatement::ExecuteDirect, NAPI_METHOD_ATTR),
36
+ InstanceMethod("executeDirectSync", &ODBCStatement::ExecuteDirectSync, NAPI_METHOD_ATTR),
37
+ InstanceMethod("executeNonQuery", &ODBCStatement::ExecuteNonQuery, NAPI_METHOD_ATTR),
38
+ InstanceMethod("executeNonQuerySync", &ODBCStatement::ExecuteNonQuerySync, NAPI_METHOD_ATTR),
39
+ InstanceMethod("prepare", &ODBCStatement::Prepare, NAPI_METHOD_ATTR),
40
+ InstanceMethod("prepareSync", &ODBCStatement::PrepareSync, NAPI_METHOD_ATTR),
41
+ InstanceMethod("bind", &ODBCStatement::Bind, NAPI_METHOD_ATTR),
42
+ InstanceMethod("bindSync", &ODBCStatement::BindSync, NAPI_METHOD_ATTR),
43
+ InstanceMethod("setAttr", &ODBCStatement::SetAttr, NAPI_METHOD_ATTR),
44
+ InstanceMethod("setAttrSync", &ODBCStatement::SetAttrSync, NAPI_METHOD_ATTR),
45
+ InstanceMethod("close", &ODBCStatement::Close, NAPI_METHOD_ATTR),
46
+ InstanceMethod("closeSync", &ODBCStatement::CloseSync, NAPI_METHOD_ATTR),
47
+ InstanceMethod("primaryKeys", &ODBCStatement::PrimaryKeys, NAPI_METHOD_ATTR),
48
+ InstanceMethod("primaryKeysSync", &ODBCStatement::PrimaryKeysSync, NAPI_METHOD_ATTR),
49
+ InstanceMethod("foreignKeys", &ODBCStatement::ForeignKeys, NAPI_METHOD_ATTR),
50
+ InstanceMethod("foreignKeysSync", &ODBCStatement::ForeignKeysSync, NAPI_METHOD_ATTR),
51
+ InstanceMethod("procedures", &ODBCStatement::Procedures, NAPI_METHOD_ATTR),
52
+ InstanceMethod("proceduresSync", &ODBCStatement::ProceduresSync, NAPI_METHOD_ATTR),
53
+ InstanceMethod("procedureColumns", &ODBCStatement::ProcedureColumns, NAPI_METHOD_ATTR),
54
+ InstanceMethod("procedureColumnsSync", &ODBCStatement::ProcedureColumnsSync, NAPI_METHOD_ATTR),
55
+ InstanceMethod("paramData", &ODBCStatement::ParamData, NAPI_METHOD_ATTR),
56
+ InstanceMethod("paramDataSync", &ODBCStatement::ParamDataSync, NAPI_METHOD_ATTR),
57
+ InstanceMethod("putData", &ODBCStatement::PutData, NAPI_METHOD_ATTR),
58
+ InstanceMethod("putDataSync", &ODBCStatement::PutDataSync, NAPI_METHOD_ATTR),
59
+ InstanceMethod("executeForStreaming", &ODBCStatement::ExecuteForStreaming, NAPI_METHOD_ATTR),
60
+ InstanceMethod("executeForStreamingSync", &ODBCStatement::ExecuteForStreamingSync, NAPI_METHOD_ATTR),
61
+ InstanceMethod("cancel", &ODBCStatement::Cancel, NAPI_METHOD_ATTR),
62
+ InstanceMethod("cancelSync", &ODBCStatement::CancelSync, NAPI_METHOD_ATTR),
63
+ });
64
+
65
+ constructor = Napi::Persistent(func);
66
+ constructor.SuppressDestruct();
67
+ exports.Set("ODBCStatement", func);
68
+ return exports;
69
+ }
70
+
71
+ ODBCStatement::~ODBCStatement()
72
+ {
73
+ DEBUG_PRINTF("ODBCStatement::~ODBCStatement m_hSTMT=%X\n", m_hSTMT);
74
+ this->Free();
75
+ }
76
+
77
+ void ODBCStatement::Free()
78
+ {
79
+ DEBUG_PRINTF("ODBCStatement::Free - Entry: paramCount=%i, m_hSTMT=%X\n", paramCount, m_hSTMT);
80
+ if (paramCount) { FREE_PARAMS(params, paramCount); }
81
+ if (m_hSTMT) {
82
+ SQLFreeHandle(SQL_HANDLE_STMT, m_hSTMT);
83
+ m_hSTMT = (SQLHSTMT)NULL;
84
+ }
85
+ if (buffer != NULL) { free((uint16_t *)buffer); buffer = NULL; }
86
+ bufferLength = 0;
87
+ DEBUG_PRINTF("ODBCStatement::Free - Exit\n");
88
+ }
89
+
90
+ ODBCStatement::ODBCStatement(const Napi::CallbackInfo &info) : Napi::ObjectWrap<ODBCStatement>(info)
91
+ {
92
+ DEBUG_PRINTF("ODBCStatement::New - Entry\n");
93
+ Napi::Env env = info.Env();
94
+
95
+ if (info.Length() < 3 || !info[0].IsExternal() || !info[1].IsExternal() || !info[2].IsExternal())
96
+ {
97
+ Napi::TypeError::New(env, "ODBCStatement::New requires 3 external arguments").ThrowAsJavaScriptException();
98
+ return;
99
+ }
100
+
101
+ m_hENV = (SQLHENV)((intptr_t)info[0].As<Napi::External<void>>().Data());
102
+ m_hDBC = (SQLHDBC)((intptr_t)info[1].As<Napi::External<void>>().Data());
103
+ m_hSTMT = (SQLHSTMT)((intptr_t)info[2].As<Napi::External<void>>().Data());
104
+
105
+ Value().TypeTag(&ODBCStatement::type_tag);
106
+
107
+ bufferLength = MAX_VALUE_SIZE;
108
+ buffer = NULL;
109
+ colCount = 0;
110
+ paramCount = 0;
111
+ params = 0;
112
+ DEBUG_PRINTF("ODBCStatement::New - Exit\n");
113
+ }
114
+
115
+ /*
116
+ * Execute
117
+ */
118
+ Napi::Value ODBCStatement::Execute(const Napi::CallbackInfo &info)
119
+ {
120
+ DEBUG_PRINTF("ODBCStatement::Execute - Entry\n");
121
+ Napi::Env env = info.Env();
122
+ REQ_FUN_ARG(0, cb);
123
+
124
+ uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
125
+ MEMCHECK(work_req);
126
+ execute_work_data *data = (execute_work_data *)calloc(1, sizeof(execute_work_data));
127
+ if (!data) free(work_req);
128
+ MEMCHECK(data);
129
+
130
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
131
+ data->stmt = this;
132
+ data->env = env;
133
+ work_req->data = data;
134
+
135
+ uv_queue_work(uv_default_loop(), work_req, UV_Execute, (uv_after_work_cb)UV_AfterExecute);
136
+ this->Ref();
137
+ return env.Undefined();
138
+ }
139
+
140
+ void ODBCStatement::UV_Execute(uv_work_t *req)
141
+ {
142
+ DEBUG_PRINTF("ODBCStatement::UV_Execute - Entry\n");
143
+ execute_work_data *data = (execute_work_data *)(req->data);
144
+
145
+ SQLRETURN ret = SQLExecute(data->stmt->m_hSTMT);
146
+ if (ret == SQL_NEED_DATA)
147
+ ret = ODBC::PutDataLoop(data->stmt->m_hSTMT, data->stmt->params, data->stmt->paramCount);
148
+
149
+ data->result = ret;
150
+ DEBUG_PRINTF("ODBCStatement::UV_Execute - Exit\n");
151
+ }
152
+
153
+ void ODBCStatement::UV_AfterExecute(uv_work_t *req, int status)
154
+ {
155
+ DEBUG_PRINTF("ODBCStatement::UV_AfterExecute - Entry\n");
156
+ execute_work_data *data = (execute_work_data *)(req->data);
157
+ Napi::Env env(data->env);
158
+ Napi::HandleScope scope(env);
159
+
160
+ ODBCStatement *stmt = data->stmt->self();
161
+ int outParamCount = 0;
162
+ Napi::Array sp_result = Napi::Array::New(env);
163
+
164
+ if (SQL_SUCCEEDED(data->result))
165
+ {
166
+ for (int i = 0; i < stmt->paramCount; i++)
167
+ {
168
+ if (stmt->params[i].paramtype % 2 == 0)
169
+ {
170
+ sp_result.Set(outParamCount, ODBC::GetOutputParameter(env, &stmt->params[i]));
171
+ outParamCount++;
172
+ }
173
+ }
174
+ }
175
+ if (stmt->paramCount) { FREE_PARAMS(stmt->params, stmt->paramCount); }
176
+
177
+ if (data->result == SQL_ERROR)
178
+ {
179
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
180
+ }
181
+ else
182
+ {
183
+ bool *canFreeHandle = new bool(false);
184
+ Napi::Value args[4] = {
185
+ Napi::External<void>::New(env, (void *)(intptr_t)stmt->m_hENV),
186
+ Napi::External<void>::New(env, (void *)(intptr_t)stmt->m_hDBC),
187
+ Napi::External<void>::New(env, (void *)(intptr_t)stmt->m_hSTMT),
188
+ Napi::External<void>::New(env, (void *)canFreeHandle)
189
+ };
190
+ Napi::Object js_result = ODBCResult::constructor.New({args[0], args[1], args[2], args[3]});
191
+ data->cb->Call({env.Null(), js_result, outParamCount ? (Napi::Value)sp_result : env.Null()});
192
+ }
193
+
194
+ stmt->Unref();
195
+ delete data->cb;
196
+ free(data);
197
+ free(req);
198
+ DEBUG_PRINTF("ODBCStatement::UV_AfterExecute - Exit\n");
199
+ }
200
+
201
+ /*
202
+ * ExecuteSync
203
+ */
204
+ Napi::Value ODBCStatement::ExecuteSync(const Napi::CallbackInfo &info)
205
+ {
206
+ DEBUG_PRINTF("ODBCStatement::ExecuteSync - Entry\n");
207
+ Napi::Env env = info.Env();
208
+ int outParamCount = 0;
209
+ Napi::Array sp_result = Napi::Array::New(env);
210
+
211
+ SQLRETURN ret = SQLExecute(m_hSTMT);
212
+ if (ret == SQL_NEED_DATA)
213
+ ret = ODBC::PutDataLoop(m_hSTMT, params, paramCount);
214
+
215
+ if (SQL_SUCCEEDED(ret))
216
+ {
217
+ for (int i = 0; i < paramCount; i++)
218
+ {
219
+ if (params[i].paramtype % 2 == 0)
220
+ {
221
+ sp_result.Set(outParamCount, ODBC::GetOutputParameter(env, &params[i]));
222
+ outParamCount++;
223
+ }
224
+ }
225
+ }
226
+ if (paramCount) { FREE_PARAMS(params, paramCount); }
227
+
228
+ if (ret == SQL_ERROR)
229
+ {
230
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
231
+ (char *)"[node-odbc] Error in ODBCStatement::ExecuteSync"));
232
+ return env.Null();
233
+ }
234
+ else
235
+ {
236
+ bool *canFreeHandle = new bool(false);
237
+ Napi::Value result[4] = {
238
+ Napi::External<void>::New(env, (void *)(intptr_t)m_hENV),
239
+ Napi::External<void>::New(env, (void *)(intptr_t)m_hDBC),
240
+ Napi::External<void>::New(env, (void *)(intptr_t)m_hSTMT),
241
+ Napi::External<void>::New(env, (void *)canFreeHandle)
242
+ };
243
+ Napi::Object js_result = ODBCResult::constructor.New({result[0], result[1], result[2], result[3]});
244
+
245
+ if (outParamCount)
246
+ {
247
+ Napi::Array resultset = Napi::Array::New(env);
248
+ resultset.Set((uint32_t)0, js_result);
249
+ resultset.Set((uint32_t)1, sp_result);
250
+ return resultset;
251
+ }
252
+ return js_result;
253
+ }
254
+ }
255
+
256
+ /*
257
+ * ExecuteNonQuery
258
+ */
259
+ Napi::Value ODBCStatement::ExecuteNonQuery(const Napi::CallbackInfo &info)
260
+ {
261
+ DEBUG_PRINTF("ODBCStatement::ExecuteNonQuery - Entry\n");
262
+ Napi::Env env = info.Env();
263
+ REQ_FUN_ARG(0, cb);
264
+
265
+ uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
266
+ MEMCHECK(work_req);
267
+ execute_work_data *data = (execute_work_data *)calloc(1, sizeof(execute_work_data));
268
+ if (!data) free(work_req);
269
+ MEMCHECK(data);
270
+
271
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
272
+ data->stmt = this;
273
+ data->env = env;
274
+ work_req->data = data;
275
+
276
+ uv_queue_work(uv_default_loop(), work_req, UV_ExecuteNonQuery, (uv_after_work_cb)UV_AfterExecuteNonQuery);
277
+ this->Ref();
278
+ return env.Undefined();
279
+ }
280
+
281
+ void ODBCStatement::UV_ExecuteNonQuery(uv_work_t *req)
282
+ {
283
+ DEBUG_PRINTF("ODBCStatement::UV_ExecuteNonQuery - Entry\n");
284
+ execute_work_data *data = (execute_work_data *)(req->data);
285
+
286
+ SQLRETURN ret = SQLExecute(data->stmt->m_hSTMT);
287
+ if (ret == SQL_NEED_DATA)
288
+ ret = ODBC::PutDataLoop(data->stmt->m_hSTMT, data->stmt->params, data->stmt->paramCount);
289
+
290
+ data->result = ret;
291
+ DEBUG_PRINTF("ODBCStatement::UV_ExecuteNonQuery - Exit\n");
292
+ }
293
+
294
+ void ODBCStatement::UV_AfterExecuteNonQuery(uv_work_t *req, int status)
295
+ {
296
+ DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteNonQuery - Entry\n");
297
+ execute_work_data *data = (execute_work_data *)(req->data);
298
+ Napi::Env env(data->env);
299
+ Napi::HandleScope scope(env);
300
+
301
+ ODBCStatement *self = data->stmt->self();
302
+ SQLLEN rowCount = 0;
303
+ SQLRETURN ret = data->result;
304
+ Napi::Value warning;
305
+ bool hasWarning = false;
306
+
307
+ if (ret > SQL_SUCCESS && ret != SQL_NO_DATA_FOUND)
308
+ {
309
+ warning = ODBC::GetSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT,
310
+ (char *)"[node-ibm_db] Warning in ODBCStatement::UV_AfterExecuteNonQuery");
311
+ hasWarning = true;
312
+ }
313
+ if ((ret == SQL_SUCCESS) || (ret == SQL_SUCCESS_WITH_INFO))
314
+ ret = SQLRowCount(self->m_hSTMT, &rowCount);
315
+
316
+ if (ret < SQL_SUCCESS)
317
+ {
318
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT, data->cb);
319
+ }
320
+ else
321
+ {
322
+ Napi::Value err;
323
+ if ((ret > SQL_SUCCESS) && !hasWarning && (ret != SQL_NO_DATA_FOUND))
324
+ err = ODBC::GetSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT,
325
+ (char *)"[node-ibm_db] Warning in ODBCStatement::UV_AfterExecuteNonQuery for SQLRowCount.");
326
+ else if (hasWarning)
327
+ err = warning;
328
+ else
329
+ err = env.Null();
330
+
331
+ data->cb->Call({err, Napi::Number::New(env, (double)rowCount)});
332
+ }
333
+
334
+ SQLFreeStmt(self->m_hSTMT, SQL_CLOSE);
335
+ self->Unref();
336
+ delete data->cb;
337
+ free(data);
338
+ free(req);
339
+ DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteNonQuery - Exit\n");
340
+ }
341
+
342
+ /*
343
+ * ExecuteNonQuerySync
344
+ */
345
+ Napi::Value ODBCStatement::ExecuteNonQuerySync(const Napi::CallbackInfo &info)
346
+ {
347
+ DEBUG_PRINTF("ODBCStatement::ExecuteNonQuerySync - Entry\n");
348
+ Napi::Env env = info.Env();
349
+ SQLLEN rowCount = 0;
350
+
351
+ SQLRETURN ret = SQLExecute(m_hSTMT);
352
+ if (ret == SQL_NEED_DATA)
353
+ ret = ODBC::PutDataLoop(m_hSTMT, params, paramCount);
354
+
355
+ if ((ret == SQL_SUCCESS) || (ret == SQL_SUCCESS_WITH_INFO))
356
+ ret = SQLRowCount(m_hSTMT, &rowCount);
357
+
358
+ if (ret < SQL_SUCCESS)
359
+ {
360
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
361
+ (char *)"[node-ibm_db] Error in ODBCStatement::ExecuteNonQuerySync"));
362
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
363
+ return env.Null();
364
+ }
365
+
366
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
367
+ return Napi::Number::New(env, (double)rowCount);
368
+ }
369
+
370
+ /*
371
+ * ExecuteDirect
372
+ */
373
+ Napi::Value ODBCStatement::ExecuteDirect(const Napi::CallbackInfo &info)
374
+ {
375
+ DEBUG_PRINTF("ODBCStatement::ExecuteDirect - Entry\n");
376
+ Napi::Env env = info.Env();
377
+
378
+ REQ_STRO_ARG(0, sql);
379
+ REQ_FUN_ARG(1, cb);
380
+ int len = (int)sql.length();
381
+ void *cppSQL = NULL;
382
+ GETCPPSTR(cppSQL, sql, len);
383
+
384
+ uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
385
+ if (!work_req) free(cppSQL);
386
+ MEMCHECK(work_req);
387
+ execute_direct_work_data *data = (execute_direct_work_data *)calloc(1, sizeof(execute_direct_work_data));
388
+ if (!data) { free(cppSQL); free(work_req); }
389
+ MEMCHECK(data);
390
+
391
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
392
+ data->sql = cppSQL;
393
+ data->sqlLen = len;
394
+ data->stmt = this;
395
+ data->env = env;
396
+ work_req->data = data;
397
+
398
+ uv_queue_work(uv_default_loop(), work_req, UV_ExecuteDirect, (uv_after_work_cb)UV_AfterExecuteDirect);
399
+ this->Ref();
400
+ return env.Undefined();
401
+ }
402
+
403
+ void ODBCStatement::UV_ExecuteDirect(uv_work_t *req)
404
+ {
405
+ DEBUG_PRINTF("ODBCStatement::UV_ExecuteDirect - Entry\n");
406
+ execute_direct_work_data *data = (execute_direct_work_data *)(req->data);
407
+ data->result = SQLExecDirect(data->stmt->m_hSTMT, (SQLTCHAR *)data->sql, data->sqlLen);
408
+ DEBUG_PRINTF("ODBCStatement::UV_ExecuteDirect - Exit\n");
409
+ }
410
+
411
+ void ODBCStatement::UV_AfterExecuteDirect(uv_work_t *req, int status)
412
+ {
413
+ DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteDirect - Entry\n");
414
+ execute_direct_work_data *data = (execute_direct_work_data *)(req->data);
415
+ Napi::Env env(data->env);
416
+ Napi::HandleScope scope(env);
417
+ ODBCStatement *self = data->stmt->self();
418
+
419
+ if (data->result == SQL_ERROR)
420
+ {
421
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT, data->cb);
422
+ }
423
+ else
424
+ {
425
+ bool *canFreeHandle = new bool(false);
426
+ Napi::Value args[4] = {
427
+ Napi::External<void>::New(env, (void *)(intptr_t)self->m_hENV),
428
+ Napi::External<void>::New(env, (void *)(intptr_t)self->m_hDBC),
429
+ Napi::External<void>::New(env, (void *)(intptr_t)self->m_hSTMT),
430
+ Napi::External<void>::New(env, (void *)canFreeHandle)
431
+ };
432
+ Napi::Object js_result = ODBCResult::constructor.New({args[0], args[1], args[2], args[3]});
433
+ data->cb->Call({env.Null(), js_result});
434
+ }
435
+
436
+ self->Unref();
437
+ delete data->cb;
438
+ free(data->sql);
439
+ free(data);
440
+ free(req);
441
+ DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteDirect - Exit\n");
442
+ }
443
+
444
+ /*
445
+ * ExecuteDirectSync
446
+ */
447
+ Napi::Value ODBCStatement::ExecuteDirectSync(const Napi::CallbackInfo &info)
448
+ {
449
+ DEBUG_PRINTF("ODBCStatement::ExecuteDirectSync - Entry\n");
450
+ Napi::Env env = info.Env();
451
+
452
+ REQ_STRO_ARG(0, sql);
453
+ int len = (int)sql.length();
454
+ void *cppSQL = NULL;
455
+ GETCPPSTR(cppSQL, sql, len);
456
+
457
+ SQLRETURN ret = SQLExecDirect(m_hSTMT, (SQLTCHAR *)cppSQL, len);
458
+ free(cppSQL);
459
+
460
+ if (ret == SQL_ERROR)
461
+ {
462
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
463
+ (char *)"[node-odbc] Error in ODBCStatement::ExecuteDirectSync"));
464
+ return env.Null();
465
+ }
466
+
467
+ bool *canFreeHandle = new bool(false);
468
+ Napi::Value result[4] = {
469
+ Napi::External<void>::New(env, (void *)(intptr_t)m_hENV),
470
+ Napi::External<void>::New(env, (void *)(intptr_t)m_hDBC),
471
+ Napi::External<void>::New(env, (void *)(intptr_t)m_hSTMT),
472
+ Napi::External<void>::New(env, (void *)canFreeHandle)
473
+ };
474
+ return ODBCResult::constructor.New({result[0], result[1], result[2], result[3]});
475
+ }
476
+
477
+ /*
478
+ * PrepareSync
479
+ */
480
+ Napi::Value ODBCStatement::PrepareSync(const Napi::CallbackInfo &info)
481
+ {
482
+ DEBUG_PRINTF("ODBCStatement::PrepareSync - Entry\n");
483
+ Napi::Env env = info.Env();
484
+
485
+ REQ_STRO_ARG(0, sql);
486
+ int sqlLen = (int)sql.length();
487
+ void *sql2 = NULL;
488
+ GETCPPSTR(sql2, sql, sqlLen);
489
+
490
+ SQLRETURN ret = SQLPrepare(m_hSTMT, (SQLTCHAR *)sql2, sqlLen);
491
+ free(sql2);
492
+
493
+ if (SQL_SUCCEEDED(ret))
494
+ return Napi::Boolean::New(env, true);
495
+
496
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
497
+ (char *)"[node-odbc] Error in ODBCStatement::PrepareSync"));
498
+ return Napi::Boolean::New(env, false);
499
+ }
500
+
501
+ /*
502
+ * Prepare
503
+ */
504
+ Napi::Value ODBCStatement::Prepare(const Napi::CallbackInfo &info)
505
+ {
506
+ DEBUG_PRINTF("ODBCStatement::Prepare - Entry\n");
507
+ Napi::Env env = info.Env();
508
+
509
+ REQ_STRO_ARG(0, sql);
510
+ REQ_FUN_ARG(1, cb);
511
+ int sqlLen = (int)sql.length();
512
+ void *cppSQL = NULL;
513
+ GETCPPSTR(cppSQL, sql, sqlLen);
514
+
515
+ uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
516
+ if (!work_req) free(cppSQL);
517
+ MEMCHECK(work_req);
518
+ prepare_work_data *data = (prepare_work_data *)calloc(1, sizeof(prepare_work_data));
519
+ if (!data) { free(cppSQL); free(work_req); }
520
+ MEMCHECK(data);
521
+
522
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
523
+ data->sql = cppSQL;
524
+ data->sqlLen = sqlLen;
525
+ data->stmt = this;
526
+ data->env = env;
527
+ work_req->data = data;
528
+
529
+ uv_queue_work(uv_default_loop(), work_req, UV_Prepare, (uv_after_work_cb)UV_AfterPrepare);
530
+ this->Ref();
531
+ return env.Undefined();
532
+ }
533
+
534
+ void ODBCStatement::UV_Prepare(uv_work_t *req)
535
+ {
536
+ DEBUG_PRINTF("ODBCStatement::UV_Prepare - Entry\n");
537
+ prepare_work_data *data = (prepare_work_data *)(req->data);
538
+ data->result = SQLPrepare(data->stmt->m_hSTMT, (SQLTCHAR *)data->sql, data->sqlLen);
539
+ DEBUG_PRINTF("ODBCStatement::UV_Prepare - Exit\n");
540
+ }
541
+
542
+ void ODBCStatement::UV_AfterPrepare(uv_work_t *req, int status)
543
+ {
544
+ DEBUG_PRINTF("ODBCStatement::UV_AfterPrepare - Entry\n");
545
+ prepare_work_data *data = (prepare_work_data *)(req->data);
546
+ Napi::Env env(data->env);
547
+ Napi::HandleScope scope(env);
548
+
549
+ if (data->result == SQL_ERROR)
550
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, data->stmt->m_hSTMT, data->cb);
551
+ else
552
+ data->cb->Call({env.Null(), Napi::Boolean::New(env, true)});
553
+
554
+ data->stmt->Unref();
555
+ delete data->cb;
556
+ free(data->sql);
557
+ free(data);
558
+ free(req);
559
+ DEBUG_PRINTF("ODBCStatement::UV_AfterPrepare - Exit\n");
560
+ }
561
+
562
+ /*
563
+ * BindSync
564
+ */
565
+ Napi::Value ODBCStatement::BindSync(const Napi::CallbackInfo &info)
566
+ {
567
+ DEBUG_PRINTF("ODBCStatement::BindSync - Entry\n");
568
+ Napi::Env env = info.Env();
569
+
570
+ if (!info[0].IsArray())
571
+ {
572
+ Napi::TypeError::New(env, "Argument 1 must be an Array").ThrowAsJavaScriptException();
573
+ return env.Undefined();
574
+ }
575
+
576
+ if (paramCount) { FREE_PARAMS(params, paramCount); }
577
+ params = ODBC::GetParametersFromArray(env, info[0].As<Napi::Array>(), &paramCount);
578
+ if (env.IsExceptionPending()) { FREE_PARAMS(params, paramCount); return env.Undefined(); }
579
+ SQLRETURN ret = ODBC::BindParameters(m_hSTMT, params, paramCount);
580
+
581
+ if (SQL_SUCCEEDED(ret))
582
+ return Napi::Boolean::New(env, true);
583
+
584
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
585
+ (char *)"[node-odbc] Error in ODBCStatement::BindSync"));
586
+ return Napi::Boolean::New(env, false);
587
+ }
588
+
589
+ /*
590
+ * Bind
591
+ */
592
+ Napi::Value ODBCStatement::Bind(const Napi::CallbackInfo &info)
593
+ {
594
+ DEBUG_PRINTF("ODBCStatement::Bind - Entry\n");
595
+ Napi::Env env = info.Env();
596
+
597
+ if (!info[0].IsArray())
598
+ {
599
+ Napi::TypeError::New(env, "Argument 1 must be an Array").ThrowAsJavaScriptException();
600
+ return env.Undefined();
601
+ }
602
+ REQ_FUN_ARG(1, cb);
603
+
604
+ uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
605
+ MEMCHECK(work_req);
606
+ bind_work_data *data = (bind_work_data *)calloc(1, sizeof(bind_work_data));
607
+ if (!data) free(work_req);
608
+ MEMCHECK(data);
609
+
610
+ if (paramCount) { FREE_PARAMS(params, paramCount); }
611
+
612
+ data->stmt = this;
613
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
614
+ data->env = env;
615
+
616
+ params = ODBC::GetParametersFromArray(env, info[0].As<Napi::Array>(), &paramCount);
617
+ if (env.IsExceptionPending()) { FREE_PARAMS(params, paramCount); delete data->cb; free(data); free(work_req); return env.Undefined(); }
618
+ work_req->data = data;
619
+
620
+ uv_queue_work(uv_default_loop(), work_req, UV_Bind, (uv_after_work_cb)UV_AfterBind);
621
+ this->Ref();
622
+ return env.Undefined();
623
+ }
624
+
625
+ void ODBCStatement::UV_Bind(uv_work_t *req)
626
+ {
627
+ DEBUG_PRINTF("ODBCStatement::UV_Bind - Entry\n");
628
+ bind_work_data *data = (bind_work_data *)(req->data);
629
+ data->result = ODBC::BindParameters(data->stmt->m_hSTMT, data->stmt->params, data->stmt->paramCount);
630
+ DEBUG_PRINTF("ODBCStatement::UV_Bind - Exit\n");
631
+ }
632
+
633
+ void ODBCStatement::UV_AfterBind(uv_work_t *req, int status)
634
+ {
635
+ DEBUG_PRINTF("ODBCStatement::UV_AfterBind - Entry\n");
636
+ bind_work_data *data = (bind_work_data *)(req->data);
637
+ Napi::Env env(data->env);
638
+ Napi::HandleScope scope(env);
639
+ ODBCStatement *self = data->stmt->self();
640
+
641
+ if (data->result == SQL_ERROR)
642
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT, data->cb);
643
+ else
644
+ data->cb->Call({env.Null(), Napi::Boolean::New(env, true)});
645
+
646
+ self->Unref();
647
+ delete data->cb;
648
+ free(data);
649
+ free(req);
650
+ DEBUG_PRINTF("ODBCStatement::UV_AfterBind - Exit\n");
651
+ }
652
+
653
+ /*
654
+ * SetAttrSync
655
+ */
656
+ Napi::Value ODBCStatement::SetAttrSync(const Napi::CallbackInfo &info)
657
+ {
658
+ DEBUG_PRINTF("ODBCStatement::SetAttrSync - Entry\n");
659
+ Napi::Env env = info.Env();
660
+ REQ_ARGS(2);
661
+ REQ_INT_ARG(0, attr);
662
+
663
+ SQLPOINTER valuePtr = NULL;
664
+ SQLINTEGER stringLength = SQL_IS_INTEGER;
665
+
666
+ if (info[1].IsNumber())
667
+ valuePtr = reinterpret_cast<SQLPOINTER>(static_cast<intptr_t>(info[1].As<Napi::Number>().Int32Value()));
668
+ else if (info[1].IsNull())
669
+ valuePtr = (SQLPOINTER)0;
670
+ else if (info[1].IsString())
671
+ {
672
+ std::string value = info[1].As<Napi::String>().Utf8Value();
673
+ stringLength = (SQLINTEGER)value.length();
674
+ GETCPPSTR(valuePtr, value, stringLength);
675
+ }
676
+ else
677
+ {
678
+ Napi::TypeError::New(env, "Unsupported Statement Attribute Value.").ThrowAsJavaScriptException();
679
+ return env.Undefined();
680
+ }
681
+
682
+ SQLRETURN ret = SQLSetStmtAttr(m_hSTMT, attr, valuePtr, stringLength);
683
+
684
+ if (stringLength != SQL_IS_INTEGER) { FREE(valuePtr); }
685
+
686
+ if (SQL_SUCCEEDED(ret))
687
+ return Napi::Boolean::New(env, true);
688
+
689
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
690
+ (char *)"[node-odbc] Error in ODBCStatement::SetAttrSync"));
691
+ return Napi::Boolean::New(env, false);
692
+ }
693
+
694
+ /*
695
+ * SetAttr
696
+ */
697
+ Napi::Value ODBCStatement::SetAttr(const Napi::CallbackInfo &info)
698
+ {
699
+ DEBUG_PRINTF("ODBCStatement::SetAttr - Entry\n");
700
+ Napi::Env env = info.Env();
701
+ REQ_ARGS(3);
702
+ REQ_INT_ARG(0, attr);
703
+ REQ_FUN_ARG(2, cb);
704
+
705
+ SQLPOINTER valuePtr = NULL;
706
+ SQLINTEGER stringLength = SQL_IS_INTEGER;
707
+
708
+ if (info[1].IsNumber())
709
+ valuePtr = reinterpret_cast<SQLPOINTER>(static_cast<intptr_t>(info[1].As<Napi::Number>().Int32Value()));
710
+ else if (info[1].IsNull())
711
+ valuePtr = (SQLPOINTER)0;
712
+ else if (info[1].IsString())
713
+ {
714
+ std::string value = info[1].As<Napi::String>().Utf8Value();
715
+ stringLength = (SQLINTEGER)value.length();
716
+ GETCPPSTR(valuePtr, value, stringLength);
717
+ }
718
+ else
719
+ {
720
+ Napi::TypeError::New(env, "Unsupported Statement Attribute Value.").ThrowAsJavaScriptException();
721
+ return env.Undefined();
722
+ }
723
+
724
+ uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
725
+ if (!work_req && info[1].IsString()) free(valuePtr);
726
+ MEMCHECK(work_req);
727
+ stmt_setattr_work_data *data = (stmt_setattr_work_data *)calloc(1, sizeof(stmt_setattr_work_data));
728
+ if (!data) { if (info[1].IsString()) free(valuePtr); free(work_req); }
729
+ MEMCHECK(data);
730
+
731
+ data->stmt = this;
732
+ data->attr = attr;
733
+ data->valuePtr = valuePtr;
734
+ data->stringLength = stringLength;
735
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
736
+ data->env = env;
737
+ work_req->data = data;
738
+
739
+ uv_queue_work(uv_default_loop(), work_req, UV_SetAttr, (uv_after_work_cb)UV_AfterSetAttr);
740
+ this->Ref();
741
+ return env.Undefined();
742
+ }
743
+
744
+ void ODBCStatement::UV_SetAttr(uv_work_t *req)
745
+ {
746
+ DEBUG_PRINTF("ODBCStatement::UV_SetAttr - Entry\n");
747
+ stmt_setattr_work_data *data = (stmt_setattr_work_data *)(req->data);
748
+ data->result = SQLSetStmtAttr(data->stmt->m_hSTMT, data->attr, data->valuePtr, data->stringLength);
749
+ DEBUG_PRINTF("ODBCStatement::UV_SetAttr - Exit\n");
750
+ }
751
+
752
+ void ODBCStatement::UV_AfterSetAttr(uv_work_t *req, int status)
753
+ {
754
+ DEBUG_PRINTF("ODBCStatement::UV_AfterSetAttr - Entry\n");
755
+ stmt_setattr_work_data *data = (stmt_setattr_work_data *)(req->data);
756
+ Napi::Env env(data->env);
757
+ Napi::HandleScope scope(env);
758
+ ODBCStatement *self = data->stmt->self();
759
+
760
+ if (data->result == SQL_ERROR)
761
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, self->m_hSTMT, data->cb);
762
+ else
763
+ data->cb->Call({env.Null(), Napi::Boolean::New(env, true)});
764
+
765
+ self->Unref();
766
+ delete data->cb;
767
+ if (data->stringLength != SQL_IS_INTEGER) { FREE(data->valuePtr); }
768
+ free(data);
769
+ free(req);
770
+ DEBUG_PRINTF("ODBCStatement::UV_AfterSetAttr - Exit\n");
771
+ }
772
+
773
+ /*
774
+ * Close
775
+ */
776
+ Napi::Value ODBCStatement::Close(const Napi::CallbackInfo &info)
777
+ {
778
+ DEBUG_PRINTF("ODBCStatement::Close - Entry\n");
779
+ Napi::Env env = info.Env();
780
+ Napi::Function cb;
781
+ SQLUSMALLINT closeOption = SQL_DROP;
782
+
783
+ if (info.Length() == 2)
784
+ {
785
+ if (!info[0].IsNumber())
786
+ {
787
+ Napi::TypeError::New(env, "Argument 0 must be an Integer.").ThrowAsJavaScriptException();
788
+ return env.Undefined();
789
+ }
790
+ if (!info[1].IsFunction())
791
+ {
792
+ Napi::TypeError::New(env, "Argument 1 must be a Function.").ThrowAsJavaScriptException();
793
+ return env.Undefined();
794
+ }
795
+ closeOption = (SQLUSMALLINT)info[0].As<Napi::Number>().Int32Value();
796
+ cb = info[1].As<Napi::Function>();
797
+ }
798
+ else if (info.Length() == 1)
799
+ {
800
+ if (!info[0].IsFunction())
801
+ {
802
+ Napi::TypeError::New(env, "ODBCStatement::Close(): Argument 0 must be a Function.").ThrowAsJavaScriptException();
803
+ return env.Undefined();
804
+ }
805
+ cb = info[0].As<Napi::Function>();
806
+ }
807
+
808
+ uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
809
+ MEMCHECK(work_req);
810
+ stmt_close_work_data *data = (stmt_close_work_data *)(calloc(1, sizeof(stmt_close_work_data)));
811
+ if (!data) free(work_req);
812
+ MEMCHECK(data);
813
+
814
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
815
+ data->stmt = this;
816
+ data->closeOption = closeOption;
817
+ data->env = env;
818
+ work_req->data = data;
819
+
820
+ uv_queue_work(uv_default_loop(), work_req, UV_Close, (uv_after_work_cb)UV_AfterClose);
821
+ this->Ref();
822
+ return env.Undefined();
823
+ }
824
+
825
+ void ODBCStatement::UV_Close(uv_work_t *req)
826
+ {
827
+ DEBUG_PRINTF("ODBCStatement::UV_Close - Entry\n");
828
+ stmt_close_work_data *data = (stmt_close_work_data *)(req->data);
829
+ ODBCStatement *stmt = data->stmt;
830
+
831
+ if (data->closeOption == SQL_DROP)
832
+ {
833
+ stmt->Free();
834
+ data->result = 0;
835
+ }
836
+ else
837
+ {
838
+ data->result = SQLFreeStmt((SQLHSTMT)stmt->m_hSTMT, data->closeOption);
839
+ }
840
+ DEBUG_PRINTF("ODBCStatement::UV_Close - Exit\n");
841
+ }
842
+
843
+ void ODBCStatement::UV_AfterClose(uv_work_t *req, int status)
844
+ {
845
+ DEBUG_PRINTF("ODBCStatement::UV_AfterClose - Entry\n");
846
+ stmt_close_work_data *data = (stmt_close_work_data *)(req->data);
847
+ Napi::Env env(data->env);
848
+ Napi::HandleScope scope(env);
849
+ ODBCStatement *self = data->stmt->self();
850
+
851
+ if (data->result != SQL_SUCCESS)
852
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, data->stmt->m_hSTMT, data->cb);
853
+ else
854
+ data->cb->Call({env.Null()});
855
+
856
+ self->Unref();
857
+ delete data->cb;
858
+ free(data);
859
+ free(req);
860
+ DEBUG_PRINTF("ODBCStatement::UV_AfterClose - Exit\n");
861
+ }
862
+
863
+ /*
864
+ * CloseSync
865
+ */
866
+ Napi::Value ODBCStatement::CloseSync(const Napi::CallbackInfo &info)
867
+ {
868
+ DEBUG_PRINTF("ODBCStatement::CloseSync - Entry\n");
869
+ Napi::Env env = info.Env();
870
+ SQLUSMALLINT closeOption = SQL_DROP;
871
+
872
+ if (info.Length() > 0 && info[0].IsNumber())
873
+ closeOption = (SQLUSMALLINT)info[0].As<Napi::Number>().Int32Value();
874
+
875
+ if (closeOption == SQL_DROP)
876
+ this->Free();
877
+ else
878
+ SQLFreeStmt(m_hSTMT, closeOption);
879
+
880
+ return Napi::Boolean::New(env, true);
881
+ }
882
+
883
+ /*
884
+ * PrimaryKeys
885
+ */
886
+ Napi::Value ODBCStatement::PrimaryKeys(const Napi::CallbackInfo &info)
887
+ {
888
+ DEBUG_PRINTF("ODBCStatement::PrimaryKeys - Entry\n");
889
+ Napi::Env env = info.Env();
890
+ const char *errmsg = NULL;
891
+ uv_work_t *work_req = NULL;
892
+ primary_keys_work_data *data = NULL;
893
+
894
+ REQ_STRO_OR_NULL_ARG(0, catalog);
895
+ REQ_STRO_OR_NULL_ARG(1, schema);
896
+ REQ_STRO_OR_NULL_ARG(2, table);
897
+ REQ_FUN_ARG(3, cb);
898
+
899
+ work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
900
+ MEMCHECK2(work_req, errmsg);
901
+ data = (primary_keys_work_data *)calloc(1, sizeof(primary_keys_work_data));
902
+ MEMCHECK2(data, errmsg);
903
+
904
+ data->catalog = NULL; data->schema = NULL; data->table = NULL;
905
+
906
+ int len;
907
+ len = (int)catalog.length(); GETCPPSTR2(data->catalog, catalog, len, errmsg);
908
+ len = (int)schema.length(); GETCPPSTR2(data->schema, schema, len, errmsg);
909
+ len = (int)table.length(); GETCPPSTR2(data->table, table, len, errmsg);
910
+
911
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
912
+ data->stmt = this;
913
+ data->env = env;
914
+ work_req->data = data;
915
+
916
+ uv_queue_work(uv_default_loop(), work_req, UV_PrimaryKeys, (uv_after_work_cb)UV_AfterPrimaryKeys);
917
+ this->Ref();
918
+
919
+ exit:
920
+ if (errmsg)
921
+ {
922
+ if (data) { FREE(data->catalog); FREE(data->schema); FREE(data->table); free(data); }
923
+ free(work_req);
924
+ Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
925
+ }
926
+ return env.Undefined();
927
+ }
928
+
929
+ void ODBCStatement::UV_PrimaryKeys(uv_work_t *req)
930
+ {
931
+ DEBUG_PRINTF("ODBCStatement::UV_PrimaryKeys - Entry\n");
932
+ primary_keys_work_data *data = (primary_keys_work_data *)(req->data);
933
+
934
+ data->result = SQLPrimaryKeys(data->stmt->m_hSTMT,
935
+ #ifdef __MVS__
936
+ NULL, 0,
937
+ #else
938
+ (SQLTCHAR *)data->catalog, SQL_NTS,
939
+ #endif
940
+ (SQLTCHAR *)data->schema, SQL_NTS,
941
+ (SQLTCHAR *)data->table, SQL_NTS);
942
+
943
+ FREE(data->catalog); FREE(data->schema); FREE(data->table);
944
+ DEBUG_PRINTF("ODBCStatement::UV_PrimaryKeys - Exit\n");
945
+ }
946
+
947
+ void ODBCStatement::UV_AfterPrimaryKeys(uv_work_t *req, int status)
948
+ {
949
+ DEBUG_PRINTF("ODBCStatement::UV_AfterPrimaryKeys - Entry\n");
950
+ primary_keys_work_data *data = (primary_keys_work_data *)(req->data);
951
+ Napi::Env env(data->env);
952
+ Napi::HandleScope scope(env);
953
+
954
+ ODBCStatement *stmt = data->stmt->self();
955
+
956
+ if (data->result == SQL_ERROR)
957
+ {
958
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
959
+ SQLFreeStmt(stmt->m_hSTMT, SQL_CLOSE);
960
+ }
961
+ else
962
+ {
963
+ {
964
+ Napi::Array rows = ODBC::GetAllRecordsSync(env, stmt->m_hENV, stmt->m_hDBC,
965
+ stmt->m_hSTMT, NULL, MAX_VALUE_SIZE);
966
+ SQLFreeStmt(stmt->m_hSTMT, SQL_CLOSE);
967
+ data->cb->Call({env.Null(), rows});
968
+ }
969
+ }
970
+ PropagateCallbackException(env);
971
+
972
+ stmt->Unref();
973
+ delete data->cb;
974
+ free(data);
975
+ free(req);
976
+ DEBUG_PRINTF("ODBCStatement::UV_AfterPrimaryKeys - Exit\n");
977
+ }
978
+
979
+ /*
980
+ * PrimaryKeysSync
981
+ */
982
+ Napi::Value ODBCStatement::PrimaryKeysSync(const Napi::CallbackInfo &info)
983
+ {
984
+ DEBUG_PRINTF("ODBCStatement::PrimaryKeysSync - Entry\n");
985
+ Napi::Env env = info.Env();
986
+ void *cppCatalog = NULL, *cppSchema = NULL, *cppTable = NULL;
987
+ int len;
988
+ const char *errmsg = NULL;
989
+
990
+ REQ_STRO_OR_NULL_ARG(0, catalog);
991
+ REQ_STRO_OR_NULL_ARG(1, schema);
992
+ REQ_STRO_OR_NULL_ARG(2, table);
993
+
994
+ len = (int)catalog.length(); GETCPPSTR2(cppCatalog, catalog, len, errmsg);
995
+ len = (int)schema.length(); GETCPPSTR2(cppSchema, schema, len, errmsg);
996
+ len = (int)table.length(); GETCPPSTR2(cppTable, table, len, errmsg);
997
+
998
+ {
999
+ SQLRETURN ret = SQLPrimaryKeys(m_hSTMT,
1000
+ #ifdef __MVS__
1001
+ NULL, 0,
1002
+ #else
1003
+ (SQLTCHAR *)cppCatalog, SQL_NTS,
1004
+ #endif
1005
+ (SQLTCHAR *)cppSchema, SQL_NTS,
1006
+ (SQLTCHAR *)cppTable, SQL_NTS);
1007
+
1008
+ FREE(cppCatalog); FREE(cppSchema); FREE(cppTable);
1009
+
1010
+ if (ret == SQL_ERROR)
1011
+ {
1012
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
1013
+ (char *)"[node-ibm_db] Error in ODBCStatement::PrimaryKeysSync"));
1014
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
1015
+ return env.Null();
1016
+ }
1017
+ }
1018
+
1019
+ {
1020
+ Napi::Array rows = ODBC::GetAllRecordsSync(env, m_hENV, m_hDBC, m_hSTMT, NULL, MAX_VALUE_SIZE);
1021
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
1022
+ DEBUG_PRINTF("ODBCStatement::PrimaryKeysSync - Exit\n");
1023
+ return rows;
1024
+ }
1025
+
1026
+ exit:
1027
+ FREE(cppCatalog); FREE(cppSchema); FREE(cppTable);
1028
+ if (errmsg) Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1029
+ return env.Null();
1030
+ }
1031
+
1032
+ /*
1033
+ * ForeignKeys
1034
+ */
1035
+ Napi::Value ODBCStatement::ForeignKeys(const Napi::CallbackInfo &info)
1036
+ {
1037
+ DEBUG_PRINTF("ODBCStatement::ForeignKeys - Entry\n");
1038
+ Napi::Env env = info.Env();
1039
+ const char *errmsg = NULL;
1040
+ uv_work_t *work_req = NULL;
1041
+ foreign_keys_work_data *data = NULL;
1042
+
1043
+ REQ_STRO_OR_NULL_ARG(0, pkCatalog);
1044
+ REQ_STRO_OR_NULL_ARG(1, pkSchema);
1045
+ REQ_STRO_OR_NULL_ARG(2, pkTable);
1046
+ REQ_STRO_OR_NULL_ARG(3, fkCatalog);
1047
+ REQ_STRO_OR_NULL_ARG(4, fkSchema);
1048
+ REQ_STRO_OR_NULL_ARG(5, fkTable);
1049
+ REQ_FUN_ARG(6, cb);
1050
+
1051
+ work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
1052
+ MEMCHECK2(work_req, errmsg);
1053
+ data = (foreign_keys_work_data *)calloc(1, sizeof(foreign_keys_work_data));
1054
+ MEMCHECK2(data, errmsg);
1055
+
1056
+ data->pkCatalog = NULL; data->pkSchema = NULL; data->pkTable = NULL;
1057
+ data->fkCatalog = NULL; data->fkSchema = NULL; data->fkTable = NULL;
1058
+
1059
+ int len;
1060
+ len = (int)pkCatalog.length(); GETCPPSTR2(data->pkCatalog, pkCatalog, len, errmsg);
1061
+ len = (int)pkSchema.length(); GETCPPSTR2(data->pkSchema, pkSchema, len, errmsg);
1062
+ len = (int)pkTable.length(); GETCPPSTR2(data->pkTable, pkTable, len, errmsg);
1063
+ len = (int)fkCatalog.length(); GETCPPSTR2(data->fkCatalog, fkCatalog, len, errmsg);
1064
+ len = (int)fkSchema.length(); GETCPPSTR2(data->fkSchema, fkSchema, len, errmsg);
1065
+ len = (int)fkTable.length(); GETCPPSTR2(data->fkTable, fkTable, len, errmsg);
1066
+
1067
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
1068
+ data->stmt = this;
1069
+ data->env = env;
1070
+ work_req->data = data;
1071
+
1072
+ uv_queue_work(uv_default_loop(), work_req, UV_ForeignKeys, (uv_after_work_cb)UV_AfterForeignKeys);
1073
+ this->Ref();
1074
+
1075
+ exit:
1076
+ if (errmsg)
1077
+ {
1078
+ if (data) { FREE(data->pkCatalog); FREE(data->pkSchema); FREE(data->pkTable);
1079
+ FREE(data->fkCatalog); FREE(data->fkSchema); FREE(data->fkTable); free(data); }
1080
+ free(work_req);
1081
+ Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1082
+ }
1083
+ return env.Undefined();
1084
+ }
1085
+
1086
+ void ODBCStatement::UV_ForeignKeys(uv_work_t *req)
1087
+ {
1088
+ DEBUG_PRINTF("ODBCStatement::UV_ForeignKeys - Entry\n");
1089
+ foreign_keys_work_data *data = (foreign_keys_work_data *)(req->data);
1090
+
1091
+ data->result = SQLForeignKeys(data->stmt->m_hSTMT,
1092
+ #ifdef __MVS__
1093
+ NULL, 0,
1094
+ #else
1095
+ (SQLTCHAR *)data->pkCatalog, SQL_NTS,
1096
+ #endif
1097
+ (SQLTCHAR *)data->pkSchema, SQL_NTS,
1098
+ (SQLTCHAR *)data->pkTable, SQL_NTS,
1099
+ #ifdef __MVS__
1100
+ NULL, 0,
1101
+ #else
1102
+ (SQLTCHAR *)data->fkCatalog, SQL_NTS,
1103
+ #endif
1104
+ (SQLTCHAR *)data->fkSchema, SQL_NTS,
1105
+ (SQLTCHAR *)data->fkTable, SQL_NTS);
1106
+
1107
+ FREE(data->pkCatalog); FREE(data->pkSchema); FREE(data->pkTable);
1108
+ FREE(data->fkCatalog); FREE(data->fkSchema); FREE(data->fkTable);
1109
+ DEBUG_PRINTF("ODBCStatement::UV_ForeignKeys - Exit\n");
1110
+ }
1111
+
1112
+ void ODBCStatement::UV_AfterForeignKeys(uv_work_t *req, int status)
1113
+ {
1114
+ DEBUG_PRINTF("ODBCStatement::UV_AfterForeignKeys - Entry\n");
1115
+ foreign_keys_work_data *data = (foreign_keys_work_data *)(req->data);
1116
+ Napi::Env env(data->env);
1117
+ Napi::HandleScope scope(env);
1118
+
1119
+ ODBCStatement *stmt = data->stmt->self();
1120
+
1121
+ if (data->result == SQL_ERROR)
1122
+ {
1123
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
1124
+ SQLFreeStmt(stmt->m_hSTMT, SQL_CLOSE);
1125
+ }
1126
+ else
1127
+ {
1128
+ {
1129
+ Napi::Array rows = ODBC::GetAllRecordsSync(env, stmt->m_hENV, stmt->m_hDBC,
1130
+ stmt->m_hSTMT, NULL, MAX_VALUE_SIZE);
1131
+ SQLFreeStmt(stmt->m_hSTMT, SQL_CLOSE);
1132
+ data->cb->Call({env.Null(), rows});
1133
+ }
1134
+ }
1135
+ PropagateCallbackException(env);
1136
+
1137
+ stmt->Unref();
1138
+ delete data->cb;
1139
+ free(data);
1140
+ free(req);
1141
+ DEBUG_PRINTF("ODBCStatement::UV_AfterForeignKeys - Exit\n");
1142
+ }
1143
+
1144
+ /*
1145
+ * ForeignKeysSync
1146
+ */
1147
+ Napi::Value ODBCStatement::ForeignKeysSync(const Napi::CallbackInfo &info)
1148
+ {
1149
+ DEBUG_PRINTF("ODBCStatement::ForeignKeysSync - Entry\n");
1150
+ Napi::Env env = info.Env();
1151
+ void *cppPkCatalog = NULL, *cppPkSchema = NULL, *cppPkTable = NULL;
1152
+ void *cppFkCatalog = NULL, *cppFkSchema = NULL, *cppFkTable = NULL;
1153
+ int len;
1154
+ const char *errmsg = NULL;
1155
+
1156
+ REQ_STRO_OR_NULL_ARG(0, pkCatalog);
1157
+ REQ_STRO_OR_NULL_ARG(1, pkSchema);
1158
+ REQ_STRO_OR_NULL_ARG(2, pkTable);
1159
+ REQ_STRO_OR_NULL_ARG(3, fkCatalog);
1160
+ REQ_STRO_OR_NULL_ARG(4, fkSchema);
1161
+ REQ_STRO_OR_NULL_ARG(5, fkTable);
1162
+
1163
+ len = (int)pkCatalog.length(); GETCPPSTR2(cppPkCatalog, pkCatalog, len, errmsg);
1164
+ len = (int)pkSchema.length(); GETCPPSTR2(cppPkSchema, pkSchema, len, errmsg);
1165
+ len = (int)pkTable.length(); GETCPPSTR2(cppPkTable, pkTable, len, errmsg);
1166
+ len = (int)fkCatalog.length(); GETCPPSTR2(cppFkCatalog, fkCatalog, len, errmsg);
1167
+ len = (int)fkSchema.length(); GETCPPSTR2(cppFkSchema, fkSchema, len, errmsg);
1168
+ len = (int)fkTable.length(); GETCPPSTR2(cppFkTable, fkTable, len, errmsg);
1169
+
1170
+ {
1171
+ SQLRETURN ret = SQLForeignKeys(m_hSTMT,
1172
+ #ifdef __MVS__
1173
+ NULL, 0,
1174
+ #else
1175
+ (SQLTCHAR *)cppPkCatalog, SQL_NTS,
1176
+ #endif
1177
+ (SQLTCHAR *)cppPkSchema, SQL_NTS,
1178
+ (SQLTCHAR *)cppPkTable, SQL_NTS,
1179
+ #ifdef __MVS__
1180
+ NULL, 0,
1181
+ #else
1182
+ (SQLTCHAR *)cppFkCatalog, SQL_NTS,
1183
+ #endif
1184
+ (SQLTCHAR *)cppFkSchema, SQL_NTS,
1185
+ (SQLTCHAR *)cppFkTable, SQL_NTS);
1186
+
1187
+ FREE(cppPkCatalog); FREE(cppPkSchema); FREE(cppPkTable);
1188
+ FREE(cppFkCatalog); FREE(cppFkSchema); FREE(cppFkTable);
1189
+
1190
+ if (ret == SQL_ERROR)
1191
+ {
1192
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
1193
+ (char *)"[node-ibm_db] Error in ODBCStatement::ForeignKeysSync"));
1194
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
1195
+ return env.Null();
1196
+ }
1197
+ }
1198
+
1199
+ {
1200
+ Napi::Array rows = ODBC::GetAllRecordsSync(env, m_hENV, m_hDBC, m_hSTMT, NULL, MAX_VALUE_SIZE);
1201
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
1202
+ DEBUG_PRINTF("ODBCStatement::ForeignKeysSync - Exit\n");
1203
+ return rows;
1204
+ }
1205
+
1206
+ exit:
1207
+ FREE(cppPkCatalog); FREE(cppPkSchema); FREE(cppPkTable);
1208
+ FREE(cppFkCatalog); FREE(cppFkSchema); FREE(cppFkTable);
1209
+ if (errmsg) Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1210
+ return env.Null();
1211
+ }
1212
+
1213
+ /*
1214
+ * Procedures
1215
+ */
1216
+ Napi::Value ODBCStatement::Procedures(const Napi::CallbackInfo &info)
1217
+ {
1218
+ DEBUG_PRINTF("ODBCStatement::Procedures - Entry\n");
1219
+ Napi::Env env = info.Env();
1220
+ const char *errmsg = NULL;
1221
+ uv_work_t *work_req = NULL;
1222
+ procedures_work_data *data = NULL;
1223
+
1224
+ REQ_STRO_OR_NULL_ARG(0, catalog);
1225
+ REQ_STRO_OR_NULL_ARG(1, schema);
1226
+ REQ_STRO_OR_NULL_ARG(2, procedure);
1227
+ REQ_FUN_ARG(3, cb);
1228
+
1229
+ work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
1230
+ MEMCHECK2(work_req, errmsg);
1231
+ data = (procedures_work_data *)calloc(1, sizeof(procedures_work_data));
1232
+ MEMCHECK2(data, errmsg);
1233
+
1234
+ data->catalog = NULL; data->schema = NULL; data->procedure = NULL;
1235
+
1236
+ int len;
1237
+ len = (int)catalog.length(); GETCPPSTR2(data->catalog, catalog, len, errmsg);
1238
+ len = (int)schema.length(); GETCPPSTR2(data->schema, schema, len, errmsg);
1239
+ len = (int)procedure.length(); GETCPPSTR2(data->procedure, procedure, len, errmsg);
1240
+
1241
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
1242
+ data->stmt = this;
1243
+ data->env = env;
1244
+ work_req->data = data;
1245
+
1246
+ uv_queue_work(uv_default_loop(), work_req, UV_Procedures, (uv_after_work_cb)UV_AfterProcedures);
1247
+ this->Ref();
1248
+
1249
+ exit:
1250
+ if (errmsg)
1251
+ {
1252
+ if (data) { FREE(data->catalog); FREE(data->schema); FREE(data->procedure); free(data); }
1253
+ free(work_req);
1254
+ Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1255
+ }
1256
+ return env.Undefined();
1257
+ }
1258
+
1259
+ void ODBCStatement::UV_Procedures(uv_work_t *req)
1260
+ {
1261
+ DEBUG_PRINTF("ODBCStatement::UV_Procedures - Entry\n");
1262
+ procedures_work_data *data = (procedures_work_data *)(req->data);
1263
+
1264
+ data->result = SQLProcedures(data->stmt->m_hSTMT,
1265
+ #ifdef __MVS__
1266
+ NULL, 0,
1267
+ #else
1268
+ (SQLTCHAR *)data->catalog, SQL_NTS,
1269
+ #endif
1270
+ (SQLTCHAR *)data->schema, SQL_NTS,
1271
+ (SQLTCHAR *)data->procedure, SQL_NTS);
1272
+
1273
+ FREE(data->catalog); FREE(data->schema); FREE(data->procedure);
1274
+ DEBUG_PRINTF("ODBCStatement::UV_Procedures - Exit\n");
1275
+ }
1276
+
1277
+ void ODBCStatement::UV_AfterProcedures(uv_work_t *req, int status)
1278
+ {
1279
+ DEBUG_PRINTF("ODBCStatement::UV_AfterProcedures - Entry\n");
1280
+ procedures_work_data *data = (procedures_work_data *)(req->data);
1281
+ Napi::Env env(data->env);
1282
+ Napi::HandleScope scope(env);
1283
+
1284
+ ODBCStatement *stmt = data->stmt->self();
1285
+
1286
+ if (data->result == SQL_ERROR)
1287
+ {
1288
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
1289
+ SQLFreeStmt(stmt->m_hSTMT, SQL_CLOSE);
1290
+ }
1291
+ else
1292
+ {
1293
+ {
1294
+ Napi::Array rows = ODBC::GetAllRecordsSync(env, stmt->m_hENV, stmt->m_hDBC,
1295
+ stmt->m_hSTMT, NULL, MAX_VALUE_SIZE);
1296
+ SQLFreeStmt(stmt->m_hSTMT, SQL_CLOSE);
1297
+ data->cb->Call({env.Null(), rows});
1298
+ }
1299
+ }
1300
+ PropagateCallbackException(env);
1301
+
1302
+ stmt->Unref();
1303
+ delete data->cb;
1304
+ free(data);
1305
+ free(req);
1306
+ DEBUG_PRINTF("ODBCStatement::UV_AfterProcedures - Exit\n");
1307
+ }
1308
+
1309
+ /*
1310
+ * ProceduresSync
1311
+ */
1312
+ Napi::Value ODBCStatement::ProceduresSync(const Napi::CallbackInfo &info)
1313
+ {
1314
+ DEBUG_PRINTF("ODBCStatement::ProceduresSync - Entry\n");
1315
+ Napi::Env env = info.Env();
1316
+ void *cppCatalog = NULL, *cppSchema = NULL, *cppProcedure = NULL;
1317
+ int len;
1318
+ const char *errmsg = NULL;
1319
+
1320
+ REQ_STRO_OR_NULL_ARG(0, catalog);
1321
+ REQ_STRO_OR_NULL_ARG(1, schema);
1322
+ REQ_STRO_OR_NULL_ARG(2, procedure);
1323
+
1324
+ len = (int)catalog.length(); GETCPPSTR2(cppCatalog, catalog, len, errmsg);
1325
+ len = (int)schema.length(); GETCPPSTR2(cppSchema, schema, len, errmsg);
1326
+ len = (int)procedure.length(); GETCPPSTR2(cppProcedure, procedure, len, errmsg);
1327
+
1328
+ {
1329
+ SQLRETURN ret = SQLProcedures(m_hSTMT,
1330
+ #ifdef __MVS__
1331
+ NULL, 0,
1332
+ #else
1333
+ (SQLTCHAR *)cppCatalog, SQL_NTS,
1334
+ #endif
1335
+ (SQLTCHAR *)cppSchema, SQL_NTS,
1336
+ (SQLTCHAR *)cppProcedure, SQL_NTS);
1337
+
1338
+ FREE(cppCatalog); FREE(cppSchema); FREE(cppProcedure);
1339
+
1340
+ if (ret == SQL_ERROR)
1341
+ {
1342
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
1343
+ (char *)"[node-ibm_db] Error in ODBCStatement::ProceduresSync"));
1344
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
1345
+ return env.Null();
1346
+ }
1347
+ }
1348
+
1349
+ {
1350
+ Napi::Array rows = ODBC::GetAllRecordsSync(env, m_hENV, m_hDBC, m_hSTMT, NULL, MAX_VALUE_SIZE);
1351
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
1352
+ DEBUG_PRINTF("ODBCStatement::ProceduresSync - Exit\n");
1353
+ return rows;
1354
+ }
1355
+
1356
+ exit:
1357
+ FREE(cppCatalog); FREE(cppSchema); FREE(cppProcedure);
1358
+ if (errmsg) Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1359
+ return env.Null();
1360
+ }
1361
+
1362
+ /*
1363
+ * ProcedureColumns
1364
+ */
1365
+ Napi::Value ODBCStatement::ProcedureColumns(const Napi::CallbackInfo &info)
1366
+ {
1367
+ DEBUG_PRINTF("ODBCStatement::ProcedureColumns - Entry\n");
1368
+ Napi::Env env = info.Env();
1369
+ const char *errmsg = NULL;
1370
+ uv_work_t *work_req = NULL;
1371
+ procedure_columns_work_data *data = NULL;
1372
+
1373
+ REQ_STRO_OR_NULL_ARG(0, catalog);
1374
+ REQ_STRO_OR_NULL_ARG(1, schema);
1375
+ REQ_STRO_OR_NULL_ARG(2, procedure);
1376
+ REQ_STRO_OR_NULL_ARG(3, column);
1377
+ REQ_FUN_ARG(4, cb);
1378
+
1379
+ work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
1380
+ MEMCHECK2(work_req, errmsg);
1381
+ data = (procedure_columns_work_data *)calloc(1, sizeof(procedure_columns_work_data));
1382
+ MEMCHECK2(data, errmsg);
1383
+
1384
+ data->catalog = NULL; data->schema = NULL; data->procedure = NULL; data->column = NULL;
1385
+
1386
+ int len;
1387
+ len = (int)catalog.length(); GETCPPSTR2(data->catalog, catalog, len, errmsg);
1388
+ len = (int)schema.length(); GETCPPSTR2(data->schema, schema, len, errmsg);
1389
+ len = (int)procedure.length(); GETCPPSTR2(data->procedure, procedure, len, errmsg);
1390
+ len = (int)column.length(); GETCPPSTR2(data->column, column, len, errmsg);
1391
+
1392
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
1393
+ data->stmt = this;
1394
+ data->env = env;
1395
+ work_req->data = data;
1396
+
1397
+ uv_queue_work(uv_default_loop(), work_req, UV_ProcedureColumns, (uv_after_work_cb)UV_AfterProcedureColumns);
1398
+ this->Ref();
1399
+
1400
+ exit:
1401
+ if (errmsg)
1402
+ {
1403
+ if (data) { FREE(data->catalog); FREE(data->schema); FREE(data->procedure); FREE(data->column); free(data); }
1404
+ free(work_req);
1405
+ Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1406
+ }
1407
+ return env.Undefined();
1408
+ }
1409
+
1410
+ void ODBCStatement::UV_ProcedureColumns(uv_work_t *req)
1411
+ {
1412
+ DEBUG_PRINTF("ODBCStatement::UV_ProcedureColumns - Entry\n");
1413
+ procedure_columns_work_data *data = (procedure_columns_work_data *)(req->data);
1414
+
1415
+ data->result = SQLProcedureColumns(data->stmt->m_hSTMT,
1416
+ #ifdef __MVS__
1417
+ NULL, 0,
1418
+ #else
1419
+ (SQLTCHAR *)data->catalog, SQL_NTS,
1420
+ #endif
1421
+ (SQLTCHAR *)data->schema, SQL_NTS,
1422
+ (SQLTCHAR *)data->procedure, SQL_NTS,
1423
+ (SQLTCHAR *)data->column, SQL_NTS);
1424
+
1425
+ FREE(data->catalog); FREE(data->schema); FREE(data->procedure); FREE(data->column);
1426
+ DEBUG_PRINTF("ODBCStatement::UV_ProcedureColumns - Exit\n");
1427
+ }
1428
+
1429
+ void ODBCStatement::UV_AfterProcedureColumns(uv_work_t *req, int status)
1430
+ {
1431
+ DEBUG_PRINTF("ODBCStatement::UV_AfterProcedureColumns - Entry\n");
1432
+ procedure_columns_work_data *data = (procedure_columns_work_data *)(req->data);
1433
+ Napi::Env env(data->env);
1434
+ Napi::HandleScope scope(env);
1435
+
1436
+ ODBCStatement *stmt = data->stmt->self();
1437
+
1438
+ if (data->result == SQL_ERROR)
1439
+ {
1440
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
1441
+ SQLFreeStmt(stmt->m_hSTMT, SQL_CLOSE);
1442
+ }
1443
+ else
1444
+ {
1445
+ {
1446
+ Napi::Array rows = ODBC::GetAllRecordsSync(env, stmt->m_hENV, stmt->m_hDBC,
1447
+ stmt->m_hSTMT, NULL, MAX_VALUE_SIZE);
1448
+ SQLFreeStmt(stmt->m_hSTMT, SQL_CLOSE);
1449
+ data->cb->Call({env.Null(), rows});
1450
+ }
1451
+ }
1452
+ PropagateCallbackException(env);
1453
+
1454
+ stmt->Unref();
1455
+ delete data->cb;
1456
+ free(data);
1457
+ free(req);
1458
+ DEBUG_PRINTF("ODBCStatement::UV_AfterProcedureColumns - Exit\n");
1459
+ }
1460
+
1461
+ /*
1462
+ * ProcedureColumnsSync
1463
+ */
1464
+ Napi::Value ODBCStatement::ProcedureColumnsSync(const Napi::CallbackInfo &info)
1465
+ {
1466
+ DEBUG_PRINTF("ODBCStatement::ProcedureColumnsSync - Entry\n");
1467
+ Napi::Env env = info.Env();
1468
+ void *cppCatalog = NULL, *cppSchema = NULL, *cppProcedure = NULL, *cppColumn = NULL;
1469
+ int len;
1470
+ const char *errmsg = NULL;
1471
+
1472
+ REQ_STRO_OR_NULL_ARG(0, catalog);
1473
+ REQ_STRO_OR_NULL_ARG(1, schema);
1474
+ REQ_STRO_OR_NULL_ARG(2, procedure);
1475
+ REQ_STRO_OR_NULL_ARG(3, column);
1476
+
1477
+ len = (int)catalog.length(); GETCPPSTR2(cppCatalog, catalog, len, errmsg);
1478
+ len = (int)schema.length(); GETCPPSTR2(cppSchema, schema, len, errmsg);
1479
+ len = (int)procedure.length(); GETCPPSTR2(cppProcedure, procedure, len, errmsg);
1480
+ len = (int)column.length(); GETCPPSTR2(cppColumn, column, len, errmsg);
1481
+
1482
+ {
1483
+ SQLRETURN ret = SQLProcedureColumns(m_hSTMT,
1484
+ #ifdef __MVS__
1485
+ NULL, 0,
1486
+ #else
1487
+ (SQLTCHAR *)cppCatalog, SQL_NTS,
1488
+ #endif
1489
+ (SQLTCHAR *)cppSchema, SQL_NTS,
1490
+ (SQLTCHAR *)cppProcedure, SQL_NTS,
1491
+ (SQLTCHAR *)cppColumn, SQL_NTS);
1492
+
1493
+ FREE(cppCatalog); FREE(cppSchema); FREE(cppProcedure); FREE(cppColumn);
1494
+
1495
+ if (ret == SQL_ERROR)
1496
+ {
1497
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
1498
+ (char *)"[node-ibm_db] Error in ODBCStatement::ProcedureColumnsSync"));
1499
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
1500
+ return env.Null();
1501
+ }
1502
+ }
1503
+
1504
+ {
1505
+ Napi::Array rows = ODBC::GetAllRecordsSync(env, m_hENV, m_hDBC, m_hSTMT, NULL, MAX_VALUE_SIZE);
1506
+ SQLFreeStmt(m_hSTMT, SQL_CLOSE);
1507
+ DEBUG_PRINTF("ODBCStatement::ProcedureColumnsSync - Exit\n");
1508
+ return rows;
1509
+ }
1510
+
1511
+ exit:
1512
+ FREE(cppCatalog); FREE(cppSchema); FREE(cppProcedure); FREE(cppColumn);
1513
+ if (errmsg) Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1514
+ return env.Null();
1515
+ }
1516
+
1517
+ /*
1518
+ * ParamData
1519
+ * Calls SQLParamData to get the next parameter for which a data value is needed.
1520
+ * Returns an object: { needsData: boolean, paramIndex: number|null }
1521
+ */
1522
+ Napi::Value ODBCStatement::ParamData(const Napi::CallbackInfo &info)
1523
+ {
1524
+ DEBUG_PRINTF("ODBCStatement::ParamData - Entry\n");
1525
+ Napi::Env env = info.Env();
1526
+ const char *errmsg = NULL;
1527
+ uv_work_t *work_req = NULL;
1528
+ param_data_work_data *data = NULL;
1529
+
1530
+ REQ_FUN_ARG(0, cb);
1531
+
1532
+ work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
1533
+ MEMCHECK2(work_req, errmsg);
1534
+ data = (param_data_work_data *)calloc(1, sizeof(param_data_work_data));
1535
+ MEMCHECK2(data, errmsg);
1536
+
1537
+ data->env = env;
1538
+ data->cb = new Napi::FunctionReference();
1539
+ *(data->cb) = Napi::Persistent(cb);
1540
+ data->stmt = this;
1541
+ data->valuePtr = NULL;
1542
+
1543
+ work_req->data = data;
1544
+
1545
+ this->Ref();
1546
+
1547
+ uv_queue_work(
1548
+ uv_default_loop(),
1549
+ work_req,
1550
+ UV_ParamData,
1551
+ (uv_after_work_cb)UV_AfterParamData);
1552
+
1553
+ DEBUG_PRINTF("ODBCStatement::ParamData - Exit\n");
1554
+ return env.Undefined();
1555
+
1556
+ exit:
1557
+ if (data) { delete data->cb; free(data); }
1558
+ if (work_req) free(work_req);
1559
+ if (errmsg) Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1560
+ return env.Undefined();
1561
+ }
1562
+
1563
+ void ODBCStatement::UV_ParamData(uv_work_t *req)
1564
+ {
1565
+ DEBUG_PRINTF("ODBCStatement::UV_ParamData - Entry\n");
1566
+ param_data_work_data *data = (param_data_work_data *)(req->data);
1567
+
1568
+ data->result = SQLParamData(data->stmt->m_hSTMT, &data->valuePtr);
1569
+
1570
+ DEBUG_PRINTF("ODBCStatement::UV_ParamData - Exit, result=%d\n", data->result);
1571
+ }
1572
+
1573
+ void ODBCStatement::UV_AfterParamData(uv_work_t *req, int status)
1574
+ {
1575
+ DEBUG_PRINTF("ODBCStatement::UV_AfterParamData - Entry\n");
1576
+ param_data_work_data *data = (param_data_work_data *)(req->data);
1577
+ Napi::Env env = data->env;
1578
+ Napi::HandleScope scope(env);
1579
+
1580
+ ODBCStatement *stmt = data->stmt;
1581
+
1582
+ if (data->result == SQL_ERROR)
1583
+ {
1584
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
1585
+ }
1586
+ else
1587
+ {
1588
+ Napi::Object result = Napi::Object::New(env);
1589
+ if (data->result == SQL_NEED_DATA)
1590
+ {
1591
+ result.Set("needsData", Napi::Boolean::New(env, true));
1592
+ // valuePtr is the token passed to SQLBindParameter (usually parameter index)
1593
+ result.Set("paramIndex", Napi::Number::New(env, (double)(intptr_t)data->valuePtr));
1594
+ }
1595
+ else
1596
+ {
1597
+ // SQL_SUCCESS or SQL_SUCCESS_WITH_INFO - all parameters satisfied
1598
+ result.Set("needsData", Napi::Boolean::New(env, false));
1599
+ result.Set("paramIndex", env.Null());
1600
+ }
1601
+ data->cb->Call({env.Null(), result});
1602
+ }
1603
+
1604
+ stmt->Unref();
1605
+ delete data->cb;
1606
+ free(data);
1607
+ free(req);
1608
+ DEBUG_PRINTF("ODBCStatement::UV_AfterParamData - Exit\n");
1609
+ }
1610
+
1611
+ /*
1612
+ * ParamDataSync
1613
+ */
1614
+ Napi::Value ODBCStatement::ParamDataSync(const Napi::CallbackInfo &info)
1615
+ {
1616
+ DEBUG_PRINTF("ODBCStatement::ParamDataSync - Entry\n");
1617
+ Napi::Env env = info.Env();
1618
+
1619
+ SQLPOINTER valuePtr = NULL;
1620
+ SQLRETURN ret = SQLParamData(m_hSTMT, &valuePtr);
1621
+
1622
+ if (ret == SQL_ERROR)
1623
+ {
1624
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
1625
+ (char *)"[node-ibm_db] Error in ODBCStatement::ParamDataSync"));
1626
+ return env.Null();
1627
+ }
1628
+
1629
+ Napi::Object result = Napi::Object::New(env);
1630
+ if (ret == SQL_NEED_DATA)
1631
+ {
1632
+ result.Set("needsData", Napi::Boolean::New(env, true));
1633
+ result.Set("paramIndex", Napi::Number::New(env, (double)(intptr_t)valuePtr));
1634
+ }
1635
+ else
1636
+ {
1637
+ result.Set("needsData", Napi::Boolean::New(env, false));
1638
+ result.Set("paramIndex", env.Null());
1639
+ }
1640
+
1641
+ DEBUG_PRINTF("ODBCStatement::ParamDataSync - Exit\n");
1642
+ return result;
1643
+ }
1644
+
1645
+ /*
1646
+ * PutData
1647
+ * Calls SQLPutData to send data for a parameter.
1648
+ */
1649
+ Napi::Value ODBCStatement::PutData(const Napi::CallbackInfo &info)
1650
+ {
1651
+ DEBUG_PRINTF("ODBCStatement::PutData - Entry\n");
1652
+ Napi::Env env = info.Env();
1653
+ const char *errmsg = NULL;
1654
+ uv_work_t *work_req = NULL;
1655
+ put_data_work_data *data = NULL;
1656
+
1657
+ if (info.Length() < 1)
1658
+ {
1659
+ Napi::Error::New(env, "putData requires at least 1 argument").ThrowAsJavaScriptException();
1660
+ return env.Undefined();
1661
+ }
1662
+
1663
+ // Get callback (last argument)
1664
+ int cbIndex = info.Length() - 1;
1665
+ if (!info[cbIndex].IsFunction())
1666
+ {
1667
+ Napi::Error::New(env, "Last argument must be a callback function").ThrowAsJavaScriptException();
1668
+ return env.Undefined();
1669
+ }
1670
+ Napi::Function cb = info[cbIndex].As<Napi::Function>();
1671
+
1672
+ work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
1673
+ MEMCHECK2(work_req, errmsg);
1674
+ data = (put_data_work_data *)calloc(1, sizeof(put_data_work_data));
1675
+ MEMCHECK2(data, errmsg);
1676
+
1677
+ data->env = env;
1678
+ data->cb = new Napi::FunctionReference();
1679
+ *(data->cb) = Napi::Persistent(cb);
1680
+ data->stmt = this;
1681
+ data->freeData = false;
1682
+
1683
+ // Get data from first argument
1684
+ if (info[0].IsBuffer())
1685
+ {
1686
+ Napi::Buffer<char> buf = info[0].As<Napi::Buffer<char>>();
1687
+ data->dataLen = buf.Length();
1688
+ data->data = malloc(data->dataLen);
1689
+ if (!data->data) { errmsg = "Memory allocation failed"; goto exit; }
1690
+ memcpy(data->data, buf.Data(), data->dataLen);
1691
+ data->freeData = true;
1692
+ }
1693
+ else if (info[0].IsString())
1694
+ {
1695
+ std::string str = info[0].As<Napi::String>().Utf8Value();
1696
+ data->dataLen = str.length();
1697
+ data->data = malloc(data->dataLen + 1);
1698
+ if (!data->data) { errmsg = "Memory allocation failed"; goto exit; }
1699
+ memcpy(data->data, str.c_str(), data->dataLen + 1);
1700
+ data->freeData = true;
1701
+ }
1702
+ else if (info[0].IsNull())
1703
+ {
1704
+ data->data = NULL;
1705
+ data->dataLen = SQL_NULL_DATA;
1706
+ }
1707
+ else
1708
+ {
1709
+ errmsg = "First argument must be a Buffer, String, or null";
1710
+ goto exit;
1711
+ }
1712
+
1713
+ // Optional length argument
1714
+ if (cbIndex > 1 && info[1].IsNumber())
1715
+ {
1716
+ data->dataLen = info[1].As<Napi::Number>().Int64Value();
1717
+ }
1718
+
1719
+ work_req->data = data;
1720
+
1721
+ this->Ref();
1722
+
1723
+ uv_queue_work(
1724
+ uv_default_loop(),
1725
+ work_req,
1726
+ UV_PutData,
1727
+ (uv_after_work_cb)UV_AfterPutData);
1728
+
1729
+ DEBUG_PRINTF("ODBCStatement::PutData - Exit\n");
1730
+ return env.Undefined();
1731
+
1732
+ exit:
1733
+ if (data) {
1734
+ if (data->freeData && data->data) free(data->data);
1735
+ delete data->cb;
1736
+ free(data);
1737
+ }
1738
+ if (work_req) free(work_req);
1739
+ if (errmsg) Napi::Error::New(env, errmsg).ThrowAsJavaScriptException();
1740
+ return env.Undefined();
1741
+ }
1742
+
1743
+ void ODBCStatement::UV_PutData(uv_work_t *req)
1744
+ {
1745
+ DEBUG_PRINTF("ODBCStatement::UV_PutData - Entry\n");
1746
+ put_data_work_data *data = (put_data_work_data *)(req->data);
1747
+
1748
+ data->result = SQLPutData(data->stmt->m_hSTMT, data->data, data->dataLen);
1749
+
1750
+ DEBUG_PRINTF("ODBCStatement::UV_PutData - Exit, result=%d\n", data->result);
1751
+ }
1752
+
1753
+ void ODBCStatement::UV_AfterPutData(uv_work_t *req, int status)
1754
+ {
1755
+ DEBUG_PRINTF("ODBCStatement::UV_AfterPutData - Entry\n");
1756
+ put_data_work_data *data = (put_data_work_data *)(req->data);
1757
+ Napi::Env env = data->env;
1758
+ Napi::HandleScope scope(env);
1759
+
1760
+ ODBCStatement *stmt = data->stmt;
1761
+
1762
+ if (!SQL_SUCCEEDED(data->result))
1763
+ {
1764
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
1765
+ }
1766
+ else
1767
+ {
1768
+ data->cb->Call({env.Null(), Napi::Boolean::New(env, true)});
1769
+ }
1770
+
1771
+ if (data->freeData && data->data) free(data->data);
1772
+ stmt->Unref();
1773
+ delete data->cb;
1774
+ free(data);
1775
+ free(req);
1776
+ DEBUG_PRINTF("ODBCStatement::UV_AfterPutData - Exit\n");
1777
+ }
1778
+
1779
+ /*
1780
+ * PutDataSync
1781
+ */
1782
+ Napi::Value ODBCStatement::PutDataSync(const Napi::CallbackInfo &info)
1783
+ {
1784
+ DEBUG_PRINTF("ODBCStatement::PutDataSync - Entry\n");
1785
+ Napi::Env env = info.Env();
1786
+
1787
+ if (info.Length() < 1)
1788
+ {
1789
+ Napi::Error::New(env, "putDataSync requires at least 1 argument").ThrowAsJavaScriptException();
1790
+ return env.Null();
1791
+ }
1792
+
1793
+ void *dataPtr = NULL;
1794
+ SQLLEN dataLen = 0;
1795
+ bool freeData = false;
1796
+
1797
+ // Get data from first argument
1798
+ if (info[0].IsBuffer())
1799
+ {
1800
+ Napi::Buffer<char> buf = info[0].As<Napi::Buffer<char>>();
1801
+ dataLen = buf.Length();
1802
+ dataPtr = buf.Data();
1803
+ }
1804
+ else if (info[0].IsString())
1805
+ {
1806
+ std::string str = info[0].As<Napi::String>().Utf8Value();
1807
+ dataLen = str.length();
1808
+ dataPtr = malloc(dataLen + 1);
1809
+ if (!dataPtr)
1810
+ {
1811
+ Napi::Error::New(env, "Memory allocation failed").ThrowAsJavaScriptException();
1812
+ return env.Null();
1813
+ }
1814
+ memcpy(dataPtr, str.c_str(), dataLen + 1);
1815
+ freeData = true;
1816
+ }
1817
+ else if (info[0].IsNull())
1818
+ {
1819
+ dataPtr = NULL;
1820
+ dataLen = SQL_NULL_DATA;
1821
+ }
1822
+ else
1823
+ {
1824
+ Napi::Error::New(env, "First argument must be a Buffer, String, or null").ThrowAsJavaScriptException();
1825
+ return env.Null();
1826
+ }
1827
+
1828
+ // Optional length argument
1829
+ if (info.Length() > 1 && info[1].IsNumber())
1830
+ {
1831
+ dataLen = info[1].As<Napi::Number>().Int64Value();
1832
+ }
1833
+
1834
+ SQLRETURN ret = SQLPutData(m_hSTMT, dataPtr, dataLen);
1835
+
1836
+ if (freeData && dataPtr) free(dataPtr);
1837
+
1838
+ if (!SQL_SUCCEEDED(ret))
1839
+ {
1840
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
1841
+ (char *)"[node-ibm_db] Error in ODBCStatement::PutDataSync"));
1842
+ return env.Null();
1843
+ }
1844
+
1845
+ DEBUG_PRINTF("ODBCStatement::PutDataSync - Exit\n");
1846
+ return Napi::Boolean::New(env, true);
1847
+ }
1848
+
1849
+ /*
1850
+ * ExecuteForStreaming
1851
+ *
1852
+ * Like Execute but does NOT auto-complete PutDataLoop when SQL_NEED_DATA.
1853
+ * Returns { needsData: boolean } to let JS layer drive the paramData/putData loop.
1854
+ */
1855
+ Napi::Value ODBCStatement::ExecuteForStreaming(const Napi::CallbackInfo &info)
1856
+ {
1857
+ DEBUG_PRINTF("ODBCStatement::ExecuteForStreaming - Entry\n");
1858
+ Napi::Env env = info.Env();
1859
+
1860
+ Napi::Function cb;
1861
+
1862
+ if (info.Length() < 1 || !info[0].IsFunction())
1863
+ {
1864
+ Napi::Error::New(env, "executeForStreaming requires a callback function").ThrowAsJavaScriptException();
1865
+ return env.Undefined();
1866
+ }
1867
+
1868
+ cb = info[0].As<Napi::Function>();
1869
+
1870
+ uv_work_t *work_req = (uv_work_t *)calloc(1, sizeof(uv_work_t));
1871
+ MEMCHECK(work_req);
1872
+
1873
+ execute_streaming_work_data *data = (execute_streaming_work_data *)calloc(1, sizeof(execute_streaming_work_data));
1874
+ if (!data) free(work_req);
1875
+ MEMCHECK(data);
1876
+
1877
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
1878
+ data->stmt = this;
1879
+ data->env = env;
1880
+ data->needsData = false;
1881
+ work_req->data = data;
1882
+
1883
+ uv_queue_work(uv_default_loop(), work_req, UV_ExecuteForStreaming, (uv_after_work_cb)UV_AfterExecuteForStreaming);
1884
+ this->Ref();
1885
+ DEBUG_PRINTF("ODBCStatement::ExecuteForStreaming - Exit\n");
1886
+ return env.Undefined();
1887
+ }
1888
+
1889
+ void ODBCStatement::UV_ExecuteForStreaming(uv_work_t *req)
1890
+ {
1891
+ DEBUG_PRINTF("ODBCStatement::UV_ExecuteForStreaming - Entry\n");
1892
+ execute_streaming_work_data *data = (execute_streaming_work_data *)(req->data);
1893
+
1894
+ SQLRETURN ret = SQLExecute(data->stmt->m_hSTMT);
1895
+
1896
+ // If SQL_NEED_DATA, do NOT call PutDataLoop - let JS handle it
1897
+ if (ret == SQL_NEED_DATA)
1898
+ {
1899
+ data->needsData = true;
1900
+ data->result = ret;
1901
+ }
1902
+ else
1903
+ {
1904
+ data->needsData = false;
1905
+ data->result = ret;
1906
+ }
1907
+
1908
+ DEBUG_PRINTF("ODBCStatement::UV_ExecuteForStreaming - Exit, ret=%d, needsData=%d\n", ret, data->needsData);
1909
+ }
1910
+
1911
+ void ODBCStatement::UV_AfterExecuteForStreaming(uv_work_t *req, int status)
1912
+ {
1913
+ DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteForStreaming - Entry\n");
1914
+ execute_streaming_work_data *data = (execute_streaming_work_data *)(req->data);
1915
+ Napi::Env env(data->env);
1916
+ Napi::HandleScope scope(env);
1917
+
1918
+ ODBCStatement *stmt = data->stmt->self();
1919
+
1920
+ if (data->result == SQL_ERROR)
1921
+ {
1922
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
1923
+ }
1924
+ else
1925
+ {
1926
+ // Return { needsData: bool } to indicate if paramData/putData loop is required
1927
+ Napi::Object result = Napi::Object::New(env);
1928
+ result.Set("needsData", Napi::Boolean::New(env, data->needsData));
1929
+ data->cb->Call({env.Null(), result});
1930
+ }
1931
+
1932
+ stmt->Unref();
1933
+ delete data->cb;
1934
+ free(data);
1935
+ free(req);
1936
+ DEBUG_PRINTF("ODBCStatement::UV_AfterExecuteForStreaming - Exit\n");
1937
+ }
1938
+
1939
+ /*
1940
+ * ExecuteForStreamingSync
1941
+ *
1942
+ * Synchronous version of ExecuteForStreaming.
1943
+ * Returns { needsData: boolean } to let JS layer drive the paramData/putData loop.
1944
+ */
1945
+ Napi::Value ODBCStatement::ExecuteForStreamingSync(const Napi::CallbackInfo &info)
1946
+ {
1947
+ DEBUG_PRINTF("ODBCStatement::ExecuteForStreamingSync - Entry\n");
1948
+ Napi::Env env = info.Env();
1949
+
1950
+ SQLRETURN ret = SQLExecute(m_hSTMT);
1951
+
1952
+ if (ret == SQL_ERROR)
1953
+ {
1954
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
1955
+ (char *)"[node-ibm_db] Error in ODBCStatement::ExecuteForStreamingSync"));
1956
+ return env.Null();
1957
+ }
1958
+
1959
+ Napi::Object result = Napi::Object::New(env);
1960
+ result.Set("needsData", Napi::Boolean::New(env, ret == SQL_NEED_DATA));
1961
+
1962
+ DEBUG_PRINTF("ODBCStatement::ExecuteForStreamingSync - Exit, needsData=%d\n", ret == SQL_NEED_DATA);
1963
+ return result;
1964
+ }
1965
+
1966
+ /*
1967
+ * Cancel
1968
+ * Calls SQLCancel to cancel an executing SQL statement on this statement handle.
1969
+ * This can be called from another thread to cancel a long-running query.
1970
+ */
1971
+ Napi::Value ODBCStatement::Cancel(const Napi::CallbackInfo &info)
1972
+ {
1973
+ DEBUG_PRINTF("ODBCStatement::Cancel - Entry\n");
1974
+ Napi::Env env = info.Env();
1975
+ REQ_FUN_ARG(0, cb);
1976
+
1977
+ uv_work_t *work_req = (uv_work_t *)(calloc(1, sizeof(uv_work_t)));
1978
+ MEMCHECK(work_req);
1979
+ stmt_cancel_work_data *data = (stmt_cancel_work_data *)calloc(1, sizeof(stmt_cancel_work_data));
1980
+ if (!data) free(work_req);
1981
+ MEMCHECK(data);
1982
+
1983
+ data->cb = new Napi::FunctionReference(Napi::Persistent(cb));
1984
+ data->stmt = this;
1985
+ data->env = env;
1986
+ work_req->data = data;
1987
+
1988
+ uv_queue_work(uv_default_loop(), work_req, UV_Cancel, (uv_after_work_cb)UV_AfterCancel);
1989
+ this->Ref();
1990
+ DEBUG_PRINTF("ODBCStatement::Cancel - Exit\n");
1991
+ return env.Undefined();
1992
+ }
1993
+
1994
+ void ODBCStatement::UV_Cancel(uv_work_t *req)
1995
+ {
1996
+ DEBUG_PRINTF("ODBCStatement::UV_Cancel - Entry\n");
1997
+ stmt_cancel_work_data *data = (stmt_cancel_work_data *)(req->data);
1998
+ data->result = SQLCancel(data->stmt->m_hSTMT);
1999
+ DEBUG_PRINTF("ODBCStatement::UV_Cancel - Exit, result=%d\n", data->result);
2000
+ }
2001
+
2002
+ void ODBCStatement::UV_AfterCancel(uv_work_t *req, int status)
2003
+ {
2004
+ DEBUG_PRINTF("ODBCStatement::UV_AfterCancel - Entry\n");
2005
+ stmt_cancel_work_data *data = (stmt_cancel_work_data *)(req->data);
2006
+ Napi::Env env(data->env);
2007
+ Napi::HandleScope scope(env);
2008
+
2009
+ ODBCStatement *stmt = data->stmt->self();
2010
+
2011
+ if (!SQL_SUCCEEDED(data->result))
2012
+ {
2013
+ ODBC::CallbackSQLError(env, SQL_HANDLE_STMT, stmt->m_hSTMT, data->cb);
2014
+ }
2015
+ else
2016
+ {
2017
+ data->cb->Call({env.Null(), Napi::Boolean::New(env, true)});
2018
+ }
2019
+
2020
+ stmt->Unref();
2021
+ delete data->cb;
2022
+ free(data);
2023
+ free(req);
2024
+ DEBUG_PRINTF("ODBCStatement::UV_AfterCancel - Exit\n");
2025
+ }
2026
+
2027
+ /*
2028
+ * CancelSync
2029
+ * Synchronous version of Cancel. Calls SQLCancel to cancel an executing statement.
2030
+ */
2031
+ Napi::Value ODBCStatement::CancelSync(const Napi::CallbackInfo &info)
2032
+ {
2033
+ DEBUG_PRINTF("ODBCStatement::CancelSync - Entry\n");
2034
+ Napi::Env env = info.Env();
2035
+
2036
+ SQLRETURN ret = SQLCancel(m_hSTMT);
2037
+
2038
+ if (!SQL_SUCCEEDED(ret))
2039
+ {
2040
+ napi_throw(env, ODBC::GetSQLError(env, SQL_HANDLE_STMT, m_hSTMT,
2041
+ (char *)"[node-ibm_db] Error in ODBCStatement::CancelSync"));
2042
+ return Napi::Boolean::New(env, false);
2043
+ }
2044
+
2045
+ DEBUG_PRINTF("ODBCStatement::CancelSync - Exit\n");
2046
+ return Napi::Boolean::New(env, true);
2047
+ }