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

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 (232) 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/axios/CHANGELOG.md +62 -0
  6. package/node_modules/axios/README.md +233 -5
  7. package/node_modules/axios/dist/axios.js +387 -89
  8. package/node_modules/axios/dist/axios.min.js +3 -3
  9. package/node_modules/axios/dist/axios.min.js.map +1 -1
  10. package/node_modules/axios/dist/browser/axios.cjs +458 -98
  11. package/node_modules/axios/dist/esm/axios.js +458 -98
  12. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  13. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  14. package/node_modules/axios/dist/node/axios.cjs +568 -116
  15. package/node_modules/axios/index.d.cts +4 -0
  16. package/node_modules/axios/index.d.ts +4 -0
  17. package/node_modules/axios/lib/adapters/fetch.js +64 -11
  18. package/node_modules/axios/lib/adapters/http.js +134 -50
  19. package/node_modules/axios/lib/adapters/xhr.js +52 -3
  20. package/node_modules/axios/lib/core/Axios.js +19 -14
  21. package/node_modules/axios/lib/core/InterceptorManager.js +107 -8
  22. package/node_modules/axios/lib/core/buildFullPath.js +1 -13
  23. package/node_modules/axios/lib/core/dispatchRequest.js +8 -2
  24. package/node_modules/axios/lib/core/mergeConfig.js +1 -1
  25. package/node_modules/axios/lib/core/methodList.js +17 -0
  26. package/node_modules/axios/lib/defaults/index.js +2 -1
  27. package/node_modules/axios/lib/env/data.js +1 -1
  28. package/node_modules/axios/lib/helpers/Http2Sessions.js +2 -0
  29. package/node_modules/axios/lib/helpers/HttpStatusCode.js +11 -1
  30. package/node_modules/axios/lib/helpers/fromDataURI.js +5 -4
  31. package/node_modules/axios/lib/helpers/normalizeURLForProtocolCheck.js +24 -0
  32. package/node_modules/axios/lib/helpers/progressEventReducer.js +1 -1
  33. package/node_modules/axios/lib/helpers/resolveConfig.js +4 -2
  34. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +182 -6
  35. package/node_modules/axios/lib/helpers/throttle.js +3 -2
  36. package/node_modules/axios/lib/helpers/toFormData.js +14 -21
  37. package/node_modules/axios/lib/utils.js +134 -13
  38. package/node_modules/axios/package.json +1 -1
  39. package/node_modules/ibm_db/APIDocumentation.md +2883 -2024
  40. package/node_modules/ibm_db/LICENSE +23 -23
  41. package/node_modules/ibm_db/README.md +735 -735
  42. package/node_modules/ibm_db/binding.gyp +99 -98
  43. package/node_modules/ibm_db/installer/driverInstall.js +984 -958
  44. package/node_modules/ibm_db/installer/ifx.sh +38 -38
  45. package/node_modules/ibm_db/installer/setenv.sh +23 -23
  46. package/node_modules/ibm_db/installer/testODBCConnection.bat +51 -51
  47. package/node_modules/ibm_db/installer/testODBCConnection.sh +61 -61
  48. package/node_modules/ibm_db/lib/climacros.js +431 -431
  49. package/node_modules/ibm_db/lib/odbc.js +4293 -3487
  50. package/node_modules/ibm_db/lib/simple-queue.js +41 -41
  51. package/node_modules/ibm_db/package.json +70 -70
  52. package/node_modules/ibm_db/src/odbc.cpp +1495 -1396
  53. package/node_modules/ibm_db/src/odbc.h +477 -473
  54. package/node_modules/ibm_db/src/odbc_connection.cpp +1762 -1612
  55. package/node_modules/ibm_db/src/odbc_connection.h +228 -215
  56. package/node_modules/ibm_db/src/odbc_result.cpp +1547 -1547
  57. package/node_modules/ibm_db/src/odbc_result.h +152 -152
  58. package/node_modules/ibm_db/src/odbc_statement.cpp +2047 -861
  59. package/node_modules/ibm_db/src/odbc_statement.h +257 -135
  60. package/node_modules/ibm_db/src/strptime.c +389 -389
  61. package/node_modules/ibm_db/src/strptime.h +46 -46
  62. package/node_modules/ibm_db/test/README +23 -23
  63. package/node_modules/ibm_db/test/bench-insert.js +62 -62
  64. package/node_modules/ibm_db/test/bench-insertBatch10.js +74 -74
  65. package/node_modules/ibm_db/test/bench-insertBatch100.js +75 -75
  66. package/node_modules/ibm_db/test/bench-insertBatch1000.js +75 -75
  67. package/node_modules/ibm_db/test/bench-insertBatch10000.js +75 -75
  68. package/node_modules/ibm_db/test/bench-prepare-bind-execute-closeSync.js +60 -60
  69. package/node_modules/ibm_db/test/bench-prepare-bind-executeNonQuery.js +53 -53
  70. package/node_modules/ibm_db/test/bench-prepare-bindSync-execute-closeSync.js +50 -50
  71. package/node_modules/ibm_db/test/bench-prepare-bindSync-executeNonQuery.js +48 -48
  72. package/node_modules/ibm_db/test/bench-prepare-execute-closeSync.js +51 -51
  73. package/node_modules/ibm_db/test/bench-prepare-executeNonQuery.js +47 -47
  74. package/node_modules/ibm_db/test/bench-prepare-not.js +43 -43
  75. package/node_modules/ibm_db/test/bench-query-fetch.js +59 -59
  76. package/node_modules/ibm_db/test/bench-query-fetchAll.js +49 -49
  77. package/node_modules/ibm_db/test/bench-query-fetchAllSync.js +43 -43
  78. package/node_modules/ibm_db/test/bench-query.js +40 -40
  79. package/node_modules/ibm_db/test/bench-querySync-fetchArray.js +28 -28
  80. package/node_modules/ibm_db/test/bench-querySync.js +29 -29
  81. package/node_modules/ibm_db/test/common.d.ts +10 -10
  82. package/node_modules/ibm_db/test/common.js +127 -127
  83. package/node_modules/ibm_db/test/config.json +7 -7
  84. package/node_modules/ibm_db/test/config.zos.json +4 -4
  85. package/node_modules/ibm_db/test/data/sample1.txt +9 -9
  86. package/node_modules/ibm_db/test/data/trc.fmt +30114 -30114
  87. package/node_modules/ibm_db/test/nodeEE-leak-huge-query.js +152 -152
  88. package/node_modules/ibm_db/test/nodeEE-leak-multiple-query-multiple-connections.js +148 -148
  89. package/node_modules/ibm_db/test/nodeEE-leak-multiple-query-pool-connections.js +154 -154
  90. package/node_modules/ibm_db/test/nodeEE-leak-multiple-query.js +133 -133
  91. package/node_modules/ibm_db/test/nodeEE-stress-async-waterfall-multiple-connections.js +174 -174
  92. package/node_modules/ibm_db/test/nodeEE-stress-async-waterfall.js +169 -169
  93. package/node_modules/ibm_db/test/nodeEE-stress-mixed-query-multiple-connections.js +159 -159
  94. package/node_modules/ibm_db/test/nodeEE-stress-mixed-query.js +148 -148
  95. package/node_modules/ibm_db/test/odbc-bench.c +123 -123
  96. package/node_modules/ibm_db/test/perfTest.js +53 -53
  97. package/node_modules/ibm_db/test/quick-example.sh +30 -30
  98. package/node_modules/ibm_db/test/quick-example.ts +80 -80
  99. package/node_modules/ibm_db/test/run-bench.js +96 -96
  100. package/node_modules/ibm_db/test/run-nodeEE.js +132 -132
  101. package/node_modules/ibm_db/test/run-tests.js +132 -138
  102. package/node_modules/ibm_db/test/sql-cli.js +28 -28
  103. package/node_modules/ibm_db/test/test-all-data-types.js +109 -109
  104. package/node_modules/ibm_db/test/test-array-insert.js +178 -178
  105. package/node_modules/ibm_db/test/test-async-await.js +105 -105
  106. package/node_modules/ibm_db/test/test-attributes.js +34 -34
  107. package/node_modules/ibm_db/test/test-bad-pool-connection-prepare-execute.js +57 -57
  108. package/node_modules/ibm_db/test/test-basic-test.js +138 -138
  109. package/node_modules/ibm_db/test/test-binary-array-insert.js +73 -73
  110. package/node_modules/ibm_db/test/test-blob-from-file.js +90 -90
  111. package/node_modules/ibm_db/test/test-blob-insert.js +144 -144
  112. package/node_modules/ibm_db/test/test-blob-stream-insert.js +321 -299
  113. package/node_modules/ibm_db/test/test-blob-to-file.js +370 -370
  114. package/node_modules/ibm_db/test/test-block-fetch.js +364 -364
  115. package/node_modules/ibm_db/test/test-blocking-issue210.js +123 -123
  116. package/node_modules/ibm_db/test/test-call-async.js +64 -64
  117. package/node_modules/ibm_db/test/test-call-stmt.js +53 -53
  118. package/node_modules/ibm_db/test/test-cancel.js +703 -0
  119. package/node_modules/ibm_db/test/test-chinese-char.js +59 -59
  120. package/node_modules/ibm_db/test/test-connection.js +306 -0
  121. package/node_modules/ibm_db/test/test-date.js +32 -32
  122. package/node_modules/ibm_db/test/test-dbclob.js +93 -93
  123. package/node_modules/ibm_db/test/test-decimals.js +135 -135
  124. package/node_modules/ibm_db/test/test-describe-metadata.js +148 -0
  125. package/node_modules/ibm_db/test/test-executeFile.js +167 -167
  126. package/node_modules/ibm_db/test/test-executeFileSync.js +85 -85
  127. package/node_modules/ibm_db/test/test-fetch-apis.js +146 -146
  128. package/node_modules/ibm_db/test/test-fetchN.js +130 -130
  129. package/node_modules/ibm_db/test/test-getinfo.js +197 -197
  130. package/node_modules/ibm_db/test/test-ibm-db-issue14.js +58 -58
  131. package/node_modules/ibm_db/test/test-ibm-db-issue17.js +54 -54
  132. package/node_modules/ibm_db/test/test-ibm-db-issue18.js +54 -54
  133. package/node_modules/ibm_db/test/test-issue-1059-fetchAll-undefined.js +67 -67
  134. package/node_modules/ibm_db/test/test-issue-1080-array-blob-insert.js +40 -0
  135. package/node_modules/ibm_db/test/test-issue-54.js +39 -39
  136. package/node_modules/ibm_db/test/test-issue-get-column-value-2.js +44 -44
  137. package/node_modules/ibm_db/test/test-issue211.js +80 -80
  138. package/node_modules/ibm_db/test/test-issue253.js +39 -39
  139. package/node_modules/ibm_db/test/test-max-pool-size.js +96 -96
  140. package/node_modules/ibm_db/test/test-memory-leaks-new-objects.js +32 -32
  141. package/node_modules/ibm_db/test/test-multi-open-query-close.js +75 -75
  142. package/node_modules/ibm_db/test/test-param-put-data.js +713 -0
  143. package/node_modules/ibm_db/test/test-pool-idle-connection.js +72 -72
  144. package/node_modules/ibm_db/test/test-pool-operations.js +325 -0
  145. package/node_modules/ibm_db/test/test-pool-stale-connections.js +111 -111
  146. package/node_modules/ibm_db/test/test-pool-uncommited.js +33 -33
  147. package/node_modules/ibm_db/test/test-prepare-execute.js +339 -0
  148. package/node_modules/ibm_db/test/test-prepareSync-multiple-execution.js +93 -93
  149. package/node_modules/ibm_db/test/test-primary-foreign-keys.js +246 -0
  150. package/node_modules/ibm_db/test/test-procedures.js +243 -0
  151. package/node_modules/ibm_db/test/test-promise-all-data-types.js +42 -42
  152. package/node_modules/ibm_db/test/test-query-operations.js +405 -0
  153. package/node_modules/ibm_db/test/test-quick-example.js +25 -25
  154. package/node_modules/ibm_db/test/test-row-array-insert.js +167 -167
  155. package/node_modules/ibm_db/test/test-sp-array.js +54 -54
  156. package/node_modules/ibm_db/test/test-sp-dbc-6000.js +88 -88
  157. package/node_modules/ibm_db/test/test-sp-memleak.js +136 -136
  158. package/node_modules/ibm_db/test/test-sp-resultset-execute.js +269 -269
  159. package/node_modules/ibm_db/test/test-sp-resultset.js +228 -228
  160. package/node_modules/ibm_db/test/test-transactions.js +261 -0
  161. package/node_modules/ibm_db/test/test-typescript.js +48 -48
  162. package/node_modules/ibm_db/test/test-xml-datatype.js +70 -70
  163. package/node_modules/ibm_db/test/testWebApp.js +56 -56
  164. package/node_modules/ibm_db/test/trace +51 -51
  165. package/node_modules/ibm_db/test/typescript-apis-test.js +978 -978
  166. package/node_modules/ibm_db/test/webapp.html +17 -17
  167. package/node_modules/ibm_db/test/webapp.js +79 -79
  168. package/node_modules/ibm_db/typescript/README.md +28 -28
  169. package/node_modules/ibm_db/typescript/dist/Database.d.ts +26 -0
  170. package/node_modules/ibm_db/typescript/dist/ODBCStatement.d.ts +93 -0
  171. package/package.json +10 -6
  172. package/node_modules/ibm_db/test/disabled/test-binding-statement-rebinding.js +0 -59
  173. package/node_modules/ibm_db/test/disabled/test-open-dont-close.js +0 -12
  174. package/node_modules/ibm_db/test/disabled/test-param-select-with-booleans-only.js +0 -21
  175. package/node_modules/ibm_db/test/disabled/test-param-select-with-decimals-only.js +0 -20
  176. package/node_modules/ibm_db/test/disabled/test-param-select-with-null.js +0 -21
  177. package/node_modules/ibm_db/test/disabled/test-param-select-with-nulls-mixed.js +0 -23
  178. package/node_modules/ibm_db/test/disabled/test-param-select-with-numbers-mixed.js +0 -22
  179. package/node_modules/ibm_db/test/disabled/test-param-select-with-numbers-only.js +0 -24
  180. package/node_modules/ibm_db/test/disabled/test-param-select-with-strings-only.js +0 -23
  181. package/node_modules/ibm_db/test/disabled/test-param-select-with-unicode.js +0 -15
  182. package/node_modules/ibm_db/test/disabled/test-prepare-bind-execute-closeSync.js +0 -62
  183. package/node_modules/ibm_db/test/disabled/test-prepare-bind-execute-error.js +0 -49
  184. package/node_modules/ibm_db/test/disabled/test-prepare-bind-execute-long-string.js +0 -63
  185. package/node_modules/ibm_db/test/disabled/test-prepare-bind-executeNonQuery.js +0 -63
  186. package/node_modules/ibm_db/test/disabled/test-prepare-bindSync-execute-closeSync.js +0 -46
  187. package/node_modules/ibm_db/test/disabled/test-prepare-bindSync-executeNonQuery.js +0 -50
  188. package/node_modules/ibm_db/test/disabled/test-prepare.js +0 -34
  189. package/node_modules/ibm_db/test/disabled/test-prepareSync.js +0 -29
  190. package/node_modules/ibm_db/test/disabled/test-query-select-fetchAll.js +0 -23
  191. package/node_modules/ibm_db/test/disabled/test-query-select-fetchAllSync.js +0 -23
  192. package/node_modules/ibm_db/test/disabled/test-query-select-unicode.js +0 -15
  193. package/node_modules/ibm_db/test/disabled/test-querySync-select-unicode.js +0 -20
  194. package/node_modules/ibm_db/test/test-affected-rows.js +0 -55
  195. package/node_modules/ibm_db/test/test-bad-connection-string.js +0 -30
  196. package/node_modules/ibm_db/test/test-binding-connection-timeOut.js +0 -31
  197. package/node_modules/ibm_db/test/test-binding-statement-executeSync.js +0 -84
  198. package/node_modules/ibm_db/test/test-binding-transaction-commit.js +0 -79
  199. package/node_modules/ibm_db/test/test-binding-transaction-commitSync.js +0 -53
  200. package/node_modules/ibm_db/test/test-closed.js +0 -14
  201. package/node_modules/ibm_db/test/test-connection-object.js +0 -16
  202. package/node_modules/ibm_db/test/test-describe-column.js +0 -92
  203. package/node_modules/ibm_db/test/test-describe-database.js +0 -18
  204. package/node_modules/ibm_db/test/test-describe-table.js +0 -31
  205. package/node_modules/ibm_db/test/test-domains-open.js +0 -19
  206. package/node_modules/ibm_db/test/test-global-open-close.js +0 -11
  207. package/node_modules/ibm_db/test/test-instantiate-one-and-end.js +0 -9
  208. package/node_modules/ibm_db/test/test-multi-open-close.js +0 -45
  209. package/node_modules/ibm_db/test/test-multi-openSync-closeSync.js +0 -52
  210. package/node_modules/ibm_db/test/test-open-close.js +0 -29
  211. package/node_modules/ibm_db/test/test-open-connectTimeout.js +0 -33
  212. package/node_modules/ibm_db/test/test-openSync.js +0 -31
  213. package/node_modules/ibm_db/test/test-pool-close.js +0 -120
  214. package/node_modules/ibm_db/test/test-pool-connect.js +0 -36
  215. package/node_modules/ibm_db/test/test-pool-rollbackTransaction.js +0 -35
  216. package/node_modules/ibm_db/test/test-prepareSync-bad-sql.js +0 -34
  217. package/node_modules/ibm_db/test/test-promise-open-close.js +0 -33
  218. package/node_modules/ibm_db/test/test-query-create-table-fetchSync.js +0 -23
  219. package/node_modules/ibm_db/test/test-query-create-table.js +0 -12
  220. package/node_modules/ibm_db/test/test-query-drop-table.js +0 -13
  221. package/node_modules/ibm_db/test/test-query-insert.js +0 -38
  222. package/node_modules/ibm_db/test/test-query-select-fetch.js +0 -21
  223. package/node_modules/ibm_db/test/test-query-select-fetchMode-array.js +0 -17
  224. package/node_modules/ibm_db/test/test-query-select.js +0 -64
  225. package/node_modules/ibm_db/test/test-queryResult.js +0 -35
  226. package/node_modules/ibm_db/test/test-queryStream.js +0 -43
  227. package/node_modules/ibm_db/test/test-querySync-select-with-exception.js +0 -25
  228. package/node_modules/ibm_db/test/test-querySync-select.js +0 -28
  229. package/node_modules/ibm_db/test/test-require-and-end.js +0 -8
  230. package/node_modules/ibm_db/test/test-statement-close.js +0 -118
  231. package/node_modules/ibm_db/test/test-transaction-commit-sync.js +0 -54
  232. package/node_modules/ibm_db/test/test-transaction-commit.js +0 -79
@@ -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
+ }