oracledb 5.4.0 → 6.0.0

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 (108) hide show
  1. package/CHANGELOG.md +1 -1849
  2. package/LICENSE.txt +8 -222
  3. package/NOTICE.txt +1 -1
  4. package/README.md +38 -30
  5. package/SECURITY.md +38 -0
  6. package/THIRD_PARTY_LICENSES.txt +1 -1
  7. package/build/Release/oracledb-6.0.0-darwin-x64.node +0 -0
  8. package/build/Release/oracledb-6.0.0-darwin-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.0.0-js-buildinfo.txt +1 -0
  10. package/build/Release/oracledb-6.0.0-linux-arm64.node +0 -0
  11. package/build/Release/oracledb-6.0.0-linux-arm64.node-buildinfo.txt +1 -0
  12. package/build/Release/oracledb-6.0.0-linux-x64.node +0 -0
  13. package/build/Release/oracledb-6.0.0-linux-x64.node-buildinfo.txt +1 -0
  14. package/build/Release/oracledb-6.0.0-win32-x64.node +0 -0
  15. package/build/Release/oracledb-6.0.0-win32-x64.node-buildinfo.txt +1 -0
  16. package/examples/README.md +113 -0
  17. package/examples/dbconfig.js +100 -0
  18. package/examples/example.js +156 -0
  19. package/index.js +26 -0
  20. package/lib/aqDeqOptions.js +146 -7
  21. package/lib/aqEnqOptions.js +59 -7
  22. package/lib/aqMessage.js +118 -7
  23. package/lib/aqQueue.js +242 -53
  24. package/lib/connection.js +1324 -465
  25. package/lib/constants.js +203 -0
  26. package/lib/dbObject.js +346 -32
  27. package/lib/errors.js +781 -0
  28. package/lib/impl/aqDeqOptions.js +197 -0
  29. package/lib/impl/aqEnqOptions.js +89 -0
  30. package/lib/impl/aqMessage.js +134 -0
  31. package/lib/impl/aqQueue.js +81 -0
  32. package/lib/impl/connection.js +529 -0
  33. package/lib/impl/dbObject.js +159 -0
  34. package/lib/impl/index.js +59 -0
  35. package/lib/impl/lob.js +85 -0
  36. package/lib/impl/pool.js +195 -0
  37. package/lib/impl/resultset.js +223 -0
  38. package/lib/impl/sodaCollection.js +174 -0
  39. package/lib/impl/sodaDatabase.js +81 -0
  40. package/lib/impl/sodaDocCursor.js +63 -0
  41. package/lib/impl/sodaDocument.js +98 -0
  42. package/lib/impl/sodaOperation.js +109 -0
  43. package/lib/lob.js +156 -68
  44. package/lib/oracledb.js +1051 -257
  45. package/lib/pool.js +654 -465
  46. package/lib/poolStatistics.js +23 -9
  47. package/lib/queryStream.js +14 -7
  48. package/lib/resultset.js +292 -171
  49. package/lib/settings.js +191 -0
  50. package/lib/sodaCollection.js +214 -201
  51. package/lib/sodaDatabase.js +107 -71
  52. package/lib/sodaDocCursor.js +44 -32
  53. package/lib/sodaDocument.js +76 -14
  54. package/lib/sodaOperation.js +131 -118
  55. package/lib/thin/connection.js +1038 -0
  56. package/lib/thin/dbObject.js +629 -0
  57. package/lib/thin/index.js +40 -0
  58. package/lib/thin/lob.js +188 -0
  59. package/lib/thin/pool.js +481 -0
  60. package/lib/thin/protocol/buffer.js +1040 -0
  61. package/lib/thin/protocol/capabilities.js +116 -0
  62. package/lib/thin/protocol/constants.js +764 -0
  63. package/lib/thin/protocol/encryptDecrypt.js +185 -0
  64. package/lib/thin/protocol/messages/auth.js +348 -0
  65. package/lib/thin/protocol/messages/base.js +475 -0
  66. package/lib/thin/protocol/messages/commit.js +56 -0
  67. package/lib/thin/protocol/messages/dataType.js +382 -0
  68. package/lib/thin/protocol/messages/execute.js +312 -0
  69. package/lib/thin/protocol/messages/fetch.js +60 -0
  70. package/lib/thin/protocol/messages/index.js +53 -0
  71. package/lib/thin/protocol/messages/lobOp.js +200 -0
  72. package/lib/thin/protocol/messages/logOff.js +53 -0
  73. package/lib/thin/protocol/messages/ping.js +56 -0
  74. package/lib/thin/protocol/messages/protocol.js +78 -0
  75. package/lib/thin/protocol/messages/rollback.js +56 -0
  76. package/lib/thin/protocol/messages/sessionRelease.js +60 -0
  77. package/lib/thin/protocol/messages/withData.js +811 -0
  78. package/lib/thin/protocol/oson.js +660 -0
  79. package/lib/thin/protocol/packet.js +520 -0
  80. package/lib/thin/protocol/protocol.js +202 -0
  81. package/lib/thin/protocol/utils.js +88 -0
  82. package/lib/thin/resultSet.js +122 -0
  83. package/lib/thin/sqlnet/connStrategy.js +175 -0
  84. package/lib/thin/sqlnet/constants.js +199 -0
  85. package/lib/thin/sqlnet/ezConnectResolver.js +488 -0
  86. package/lib/thin/sqlnet/navNodes.js +870 -0
  87. package/lib/thin/sqlnet/networkSession.js +620 -0
  88. package/lib/thin/sqlnet/ntTcp.js +525 -0
  89. package/lib/thin/sqlnet/nvStrToNvPair.js +783 -0
  90. package/lib/thin/sqlnet/packet.js +405 -0
  91. package/lib/thin/sqlnet/paramParser.js +205 -0
  92. package/lib/thin/sqlnet/sessionAtts.js +160 -0
  93. package/lib/thin/statement.js +301 -0
  94. package/lib/thin/util.js +289 -0
  95. package/lib/transformer.js +250 -0
  96. package/lib/types.js +357 -0
  97. package/lib/util.js +194 -108
  98. package/lib/version.js +36 -0
  99. package/package/README.md +33 -30
  100. package/package/install.js +89 -64
  101. package/package/prunebinaries.js +60 -12
  102. package/package.json +3 -3
  103. package/build/Release/oracledb-5.4.0-darwin-x64.node +0 -0
  104. package/build/Release/oracledb-5.4.0-darwin-x64.node-buildinfo.txt +0 -1
  105. package/build/Release/oracledb-5.4.0-linux-x64.node +0 -0
  106. package/build/Release/oracledb-5.4.0-linux-x64.node-buildinfo.txt +0 -1
  107. package/build/Release/oracledb-5.4.0-win32-x64.node +0 -0
  108. package/build/Release/oracledb-5.4.0-win32-x64.node-buildinfo.txt +0 -1
@@ -0,0 +1,160 @@
1
+ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+
29
+ const crypto = require('crypto');
30
+ const path = require('path');
31
+ const constants = require("./constants.js");
32
+ const fs = require("fs");
33
+
34
+ /**
35
+ * Generate UUID (Used for Connection ID)
36
+ * @returns Promise
37
+ */
38
+ async function genuuid() {
39
+ return await new Promise((resolve, reject) => {
40
+ crypto.randomBytes(16, (err, buf) => {
41
+ if (err) {
42
+ reject(err);
43
+ } else {
44
+ resolve(buf);
45
+ }
46
+ });
47
+ });
48
+ }
49
+
50
+ /**
51
+ * Network Session Attributes
52
+ */
53
+ class SessionAtts {
54
+
55
+ constructor(uuid) {
56
+ this.largeSDU = false;
57
+ this.tdu = constants.NSPDFTDULN;
58
+ this.nt = {};
59
+ this.nt.tcpNoDelay = true;
60
+ this.uuid = uuid;
61
+ this.nt.sslServerDNMatch = true;
62
+ }
63
+
64
+ /**
65
+ * Update Session attributes with input Parameters
66
+ * @param {object} Params Input paramters
67
+ */
68
+ setFrom(params) {
69
+ if (params) {
70
+ if (params.sdu > 0) {
71
+ this.sdu = parseInt(params.sdu);
72
+ }
73
+ if (typeof params.walletLocation === 'string') {
74
+ this.nt.walletFile = path.join(params.walletLocation, constants.PEM_WALLET_FILE_NAME);
75
+ }
76
+ if (typeof params.walletPassword === 'string') {
77
+ this.nt.walletPassword = params.walletPassword;
78
+ }
79
+ if (params.expireTime > 0) {
80
+ this.nt.expireTime = params.expireTime * 1000 * 60;
81
+ }
82
+ if (params.connectTimeout > 0) {
83
+ this.connectTimeout = params.connectTimeout * 1000;
84
+ }
85
+ if (params.transportConnectTimeout > 0) {
86
+ this.transportConnectTimeout = params.transportConnectTimeout * 1000;
87
+ }
88
+ if (params.recvTimeout > 0) {
89
+ this.recvTimeout = params.recvTimeout * 1000;
90
+ }
91
+ if (params.sendTimeout > 0) {
92
+ this.sendTimeout = params.sendTimeout * 1000;
93
+ }
94
+ if (typeof params.connectionIdPrefix === 'string') {
95
+ this.connectionIdPrefix = params.connectionIdPrefix;
96
+ }
97
+ if (typeof params.tcpNoDelay === 'boolean') {
98
+ this.nt.tcpNoDelay = params.tcpNoDelay;
99
+ }
100
+ if (typeof params.sslServerDNMatch === 'boolean') {
101
+ this.nt.sslServerDNMatch = params.sslServerDNMatch;
102
+ }
103
+ if (typeof params.sslServerCertDN === 'string') {
104
+ this.nt.sslServerCertDN = params.sslServerCertDN;
105
+ }
106
+ if (typeof params.enable === 'string' && params.enable.toUpperCase() == "BROKEN") {
107
+ this.nt.enabledDCD = true;
108
+ }
109
+ if (typeof params.httpsProxy === 'string') {
110
+ this.nt.httpsProxy = params.httpsProxy;
111
+ }
112
+ if (params.httpsProxyPort >= 0) {
113
+ this.nt.httpsProxyPort = parseInt(params.httpsProxyPort);
114
+ }
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Read wallet
120
+ * @returns Promise
121
+ */
122
+ readWalletFile() {
123
+ return new Promise((resolve, reject)=> {
124
+ fs.readFile(this.nt.walletFile, (err, data) => {
125
+ if (err) {
126
+ reject(err);
127
+ } else {
128
+ resolve(data);
129
+ }
130
+ });
131
+ });
132
+ }
133
+
134
+ /**
135
+ * Prepare attributes for connection, Generate Connection ID and read Wallet file
136
+ *
137
+ */
138
+ async prepare(protocol) {
139
+ if (!this.uuid) {
140
+ this.uuid = await genuuid();
141
+ this.uuid = this.uuid.toString('base64');
142
+ }
143
+ if (this.connectionIdPrefix) {
144
+ this.connectionId = this.connectionIdPrefix + this.uuid;
145
+ } else {
146
+ this.connectionId = this.uuid;
147
+ }
148
+ this.nt.connectionId = this.connectionId;
149
+
150
+ if (protocol && (protocol.toUpperCase() == "TCPS" && this.nt.walletFile)) {
151
+ this.nt.wallet = await this.readWalletFile();
152
+ }
153
+
154
+ if (!this.connectTimeout && !this.transportConnectTimeout)
155
+ this.transportConnectTimeout = 60 * 1000; /* Default to 60 secs */
156
+ }
157
+
158
+ }
159
+
160
+ module.exports = SessionAtts;
@@ -0,0 +1,301 @@
1
+ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+
29
+ const buffer = require('buffer').Buffer;
30
+ const constants = require('../constants');
31
+ const thinUtil = require("./util.js");
32
+
33
+ /* eslint-disable no-useless-escape */
34
+ // Rules for named binds:
35
+ // 1. Quoted and non-quoted bind names are allowed.
36
+ // 2. Quoted binds can contain any characters.
37
+ // 3. Non-quoted binds must begin with an alphabet character.
38
+ // 4. Non-quoted binds can only contain alphanumeric characters, the underscore,
39
+ // the dollar sign and the pound sign.
40
+ // 5. Non-quoted binds cannot be Oracle Database Reserved Names
41
+ // (Server handles this case and returns an appropriate error)
42
+ const BIND_PATTERN = /(?<=:)\s*((?:".*?")|(?:[\p{L}][\p{L}\p{Nd}_\$#]*)|\p{Nd}+)/gu;
43
+
44
+ // pattern used for detecting a DML returning clause; bind variables in the
45
+ // first group are input variables; bind variables in the second group are
46
+ // output only variables
47
+ // assumes expressions/variables are seperated by delimiters space and comma
48
+ const DML_RETURNING_KEY = /(?<=\bRETURN(?:ING)?\b)/si;
49
+ const DML_RETURNING_INTO_KEY = /(?<=\bINTO\b)/gsi;
50
+
51
+ const SINGLE_LINE_COMMENT_PATTERN = /--.*/;
52
+ const MULTI_LINE_COMMENT_PATTERN = /\/\*.*?\*\//s;
53
+ const CONSTANT_STRING_PATTERN = /'.*?'/sg;
54
+
55
+ /**
56
+ * It is used to cache the metadata about bind information
57
+ * associated with the statement. This will determine if statement needs
58
+ * to use Execute or Re-Execute.
59
+ */
60
+ class BindInfo {
61
+ constructor(name, isReturnBind = false) {
62
+ this.bindName = name;
63
+ this.isReturnBind = isReturnBind;
64
+ this.maxSize = 0;
65
+ this.numElements = 0;
66
+ this.maxArraySize = 0;
67
+ this.type = null;
68
+ this.isArray = false;
69
+ this.dir = constants.BIND_IN;
70
+ this.bindVar = null;
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Encapsulates the SQL statement run on the connection.
76
+ * It has information like type of stmt, bind infrmation, cursor number, ...
77
+ */
78
+ module.exports.BindInfo = BindInfo;
79
+
80
+ class Statement {
81
+ constructor() {
82
+ this.sql = "";
83
+ this.sqlBytes = [];
84
+ this.sqlLength = 0;
85
+ this.cursorId = 0;
86
+ this.requiresDefine = false;
87
+ this.isQuery = false;
88
+ this.isPlSql = false;
89
+ this.isDml = false;
90
+ this.isDdl = false;
91
+ this.isReturning = false;
92
+ this.bindInfoList = [];
93
+ this.queryVars = [];
94
+ this.bindInfoDict = new Map();
95
+ this.requiresFullExecute = false;
96
+ this.returnToCache = false;
97
+ this.numColumns = 0;
98
+ this.lastRowIndex;
99
+ this.lastRowid;
100
+ this.moreRowsToFetch = true;
101
+ this.inUse = false;
102
+ this.bufferRowIndex = 0;
103
+ this.bufferRowCount = 0;
104
+ this.statementType = constants.STMT_TYPE_UNKNOWN;
105
+ }
106
+
107
+ //---------------------------------------------------------------------------
108
+ // _copy()
109
+ //
110
+ // Copying existing statement into new statement object required by drcp
111
+ //---------------------------------------------------------------------------
112
+ _copy() {
113
+ let copiedStatement = new Statement();
114
+ let bindInfoDict;
115
+ copiedStatement.sql = this.sql;
116
+ copiedStatement.sqlBytes = this.sqlBytes;
117
+ copiedStatement.sqlLength = this.sqlLength;
118
+ copiedStatement.isQuery = this.isQuery;
119
+ copiedStatement.isPlSql = this.isPlSql;
120
+ copiedStatement.isDml = this.isDml;
121
+ copiedStatement.isDdl = this.isDdl;
122
+ copiedStatement.isReturning = this.isReturning;
123
+ copiedStatement.bindInfoList = [];
124
+ for (let bindInfo of this.bindInfoList) {
125
+ copiedStatement.bindInfoList.push(bindInfo);
126
+ }
127
+ copiedStatement.bindInfoDict = new Map();
128
+ bindInfoDict = copiedStatement.bindInfoDict;
129
+ for (let bindInfoObj of this.bindInfoList) {
130
+ if (bindInfoDict.has(bindInfoObj.bindName)) {
131
+ bindInfoDict.get(bindInfoObj.bindName).push(bindInfoObj);
132
+ } else {
133
+ bindInfoDict.set(bindInfoObj.bindName, [bindInfoObj]);
134
+ }
135
+ }
136
+ copiedStatement.returnToCache = false;
137
+ return copiedStatement;
138
+ }
139
+
140
+ //---------------------------------------------------------------------------
141
+ // _determineStatementType(sql)
142
+ //
143
+ // Determine the type of the SQL statement by examining the first keyword
144
+ // found in the statement
145
+ //---------------------------------------------------------------------------
146
+ _determineStatementType(sql) {
147
+ sql = thinUtil.cleanSql(sql);
148
+ let tokens = sql.trim().trimStart('(').substring(0, 10).split(" ");
149
+ if (tokens.length > 0) {
150
+ const sqlKeyword = tokens[0].toUpperCase();
151
+ if (["DECLARE", "BEGIN", "CALL"].includes(sqlKeyword)) {
152
+ this.isPlSql = true;
153
+ if (sqlKeyword === 'DECLARE') {
154
+ this.statementType = constants.STMT_TYPE_DECLARE;
155
+ } else if (sqlKeyword === 'BEGIN') {
156
+ this.statementType = constants.STMT_TYPE_BEGIN;
157
+ } else if (sqlKeyword === 'CALL') {
158
+ this.statementType = constants.STMT_TYPE_CALL;
159
+ }
160
+ } else if (["SELECT", "WITH"].includes(sqlKeyword)) {
161
+ this.isQuery = true;
162
+ if (sqlKeyword === "SELECT") {
163
+ this.statementType = constants.STMT_TYPE_SELECT;
164
+ }
165
+ } else if (["INSERT", "UPDATE", "DELETE", "MERGE"].includes(sqlKeyword)) {
166
+ this.isDml = true;
167
+ if (sqlKeyword === 'INSERT') {
168
+ this.statementType = constants.STMT_TYPE_INSERT;
169
+ } else if (sqlKeyword === 'UPDATE') {
170
+ this.statementType = constants.STMT_TYPE_UPDATE;
171
+ } else if (sqlKeyword === 'DELETE') {
172
+ this.statementType = constants.STMT_TYPE_DELETE;
173
+ } else if (sqlKeyword === 'MERGE') {
174
+ this.statementType = constants.STMT_TYPE_MERGE;
175
+ }
176
+ } else if (["CREATE", "ALTER", "DROP", "TRUNCATE"].includes(sqlKeyword)) {
177
+ this.isDdl = true;
178
+ if (sqlKeyword === 'CREATE') {
179
+ this.statementType = constants.STMT_TYPE_CREATE;
180
+ } else if (sqlKeyword === 'ALTER') {
181
+ this.statementType = constants.STMT_TYPE_ALTER;
182
+ } else if (sqlKeyword === 'DROP') {
183
+ this.statementType = constants.STMT_TYPE_DROP;
184
+ }
185
+ } else if (sqlKeyword === 'COMMIT') {
186
+ this.statementType = constants.STMT_TYPE_COMMIT;
187
+ } else if (sqlKeyword === 'ROLLBACK') {
188
+ this.statementType = constants.STMT_TYPE_ROLLBACK;
189
+ } else if (sqlKeyword === 'MERGE') {
190
+ this.statementType = constants.STMT_TYPE_MERGE;
191
+ } else {
192
+ this.statementType = constants.STMT_TYPE_UNKNOWN;
193
+ }
194
+ }
195
+ }
196
+
197
+ //---------------------------------------------------------------------------
198
+ // prepare(sql)
199
+ //
200
+ // Prepare the SQL for execution by determining the list of bind names
201
+ // that are found within it. The length of the SQL text is also calculated
202
+ // at this time.
203
+ //---------------------------------------------------------------------------
204
+ _prepare(sql) {
205
+ this.sql = sql;
206
+ this.sqlBytes = buffer.from(this.sql, 'utf8');
207
+ this.sqlLength = this.sqlBytes.length;
208
+ // replace literals with a specific literal
209
+ sql = sql.replace(CONSTANT_STRING_PATTERN, "'S'");
210
+ sql = sql.replace(SINGLE_LINE_COMMENT_PATTERN, "");
211
+ sql = sql.replace(MULTI_LINE_COMMENT_PATTERN, "");
212
+ this._determineStatementType(sql);
213
+ let returningSql;
214
+ if (this.isQuery || this.isDml || this.isPlSql) {
215
+ let inputSql = sql;
216
+ if (this.isDml) {
217
+ /*
218
+ * get starting index after DML_RETURNING_KEY from begining of sql and starting index
219
+ * after DML_RETURNING_INTO_KEY from the end of sql
220
+ */
221
+ let result;
222
+ let intoKey = -1;
223
+ const retKey = sql.search(DML_RETURNING_KEY);
224
+ let intoRegex = DML_RETURNING_INTO_KEY;
225
+ // simulate lastInfdexOf with intoRegex input
226
+ while ((result = intoRegex.exec(sql.slice(retKey))) != null) {
227
+ intoKey = result.index;
228
+ intoRegex.lastIndex = result.index + 1;
229
+ }
230
+ if (retKey > -1 && intoKey > -1) {
231
+ intoKey = retKey + intoKey;
232
+ inputSql = sql.slice(0, intoKey);
233
+ returningSql = sql.slice(intoKey);
234
+ }
235
+ }
236
+ this._addBinds(inputSql, false);
237
+ if (returningSql) {
238
+ this.isReturning = true;
239
+ this._addBinds(returningSql, true);
240
+ }
241
+ }
242
+ }
243
+
244
+ //---------------------------------------------------------------------------
245
+ // _addBinds(sql)
246
+ //
247
+ // Add bind information to the statement by examining the passed SQL for
248
+ // bind variable names.
249
+ //---------------------------------------------------------------------------
250
+ _addBinds(sql, isReturnBind) {
251
+ const regexMatchArray = [...sql.matchAll(BIND_PATTERN)];
252
+ let name;
253
+ regexMatchArray.forEach(element => {
254
+ if (element[0].startsWith('"') && element[0].endsWith('"')) {
255
+ name = element[0].substring(1, element[0].length - 1);
256
+ } else {
257
+ name = element[0].trim().toUpperCase();
258
+ }
259
+ if (this.isPlSql && this.bindInfoDict.has(name)) {
260
+ return;
261
+ }
262
+ let info = new BindInfo(name, isReturnBind);
263
+ this.bindInfoList.push(info);
264
+
265
+ if (this.bindInfoDict.has(info.bindName)) {
266
+ this.bindInfoDict.get(info.bindName).push(info);
267
+ } else {
268
+ this.bindInfoDict.set(info.bindName, [info]);
269
+ }
270
+ });
271
+ }
272
+
273
+ //---------------------------------------------------------------------------
274
+ // _setVariable(sql)
275
+ //
276
+ // Set the variable on the bind information and copy across metadata that
277
+ // will be used for binding. If the bind metadata has changed, mark the
278
+ // statement as requiring a full execute. In addition, binding a REF
279
+ // cursor also requires a full execute.
280
+ //---------------------------------------------------------------------------
281
+ _setVariable(bindInfo, variable) {
282
+ if (variable.maxSize !== bindInfo.maxSize
283
+ || variable.dir !== bindInfo.dir
284
+ || variable.isArray !== bindInfo.isArray
285
+ || variable.values.length > bindInfo.numElements
286
+ || variable.type != bindInfo.type
287
+ || variable.maxArraySize != bindInfo.maxArraySize) {
288
+ bindInfo.isArray = variable.isArray;
289
+ bindInfo.numElements = variable.values.length;
290
+ bindInfo.maxSize = variable.maxSize;
291
+ bindInfo.type = variable.type;
292
+ bindInfo.dir = variable.dir;
293
+ bindInfo.maxArraySize = variable.maxArraySize;
294
+ this.requiresFullExecute = true;
295
+ }
296
+
297
+ bindInfo.bindVar = variable;
298
+ }
299
+ }
300
+
301
+ module.exports.Statement = Statement;