oracledb 5.5.0 → 6.0.1

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 (107) hide show
  1. package/CHANGELOG.md +1 -1875
  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/build/Release/oracledb-6.0.1-darwin-x64.node +0 -0
  7. package/build/Release/oracledb-6.0.1-darwin-x64.node-buildinfo.txt +1 -0
  8. package/build/Release/oracledb-6.0.1-js-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.0.1-linux-arm64.node +0 -0
  10. package/build/Release/oracledb-6.0.1-linux-arm64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.0.1-linux-x64.node +0 -0
  12. package/build/Release/oracledb-6.0.1-linux-x64.node-buildinfo.txt +1 -0
  13. package/build/Release/oracledb-6.0.1-win32-x64.node +0 -0
  14. package/build/Release/oracledb-6.0.1-win32-x64.node-buildinfo.txt +1 -0
  15. package/examples/README.md +113 -0
  16. package/examples/dbconfig.js +100 -0
  17. package/examples/example.js +156 -0
  18. package/index.js +26 -0
  19. package/lib/aqDeqOptions.js +148 -8
  20. package/lib/aqEnqOptions.js +59 -7
  21. package/lib/aqMessage.js +118 -7
  22. package/lib/aqQueue.js +243 -53
  23. package/lib/connection.js +1326 -465
  24. package/lib/constants.js +203 -0
  25. package/lib/dbObject.js +346 -32
  26. package/lib/errors.js +785 -0
  27. package/lib/impl/aqDeqOptions.js +197 -0
  28. package/lib/impl/aqEnqOptions.js +89 -0
  29. package/lib/impl/aqMessage.js +134 -0
  30. package/lib/impl/aqQueue.js +81 -0
  31. package/lib/impl/connection.js +529 -0
  32. package/lib/impl/dbObject.js +159 -0
  33. package/lib/impl/index.js +59 -0
  34. package/lib/impl/lob.js +85 -0
  35. package/lib/impl/pool.js +195 -0
  36. package/lib/impl/resultset.js +223 -0
  37. package/lib/impl/sodaCollection.js +174 -0
  38. package/lib/impl/sodaDatabase.js +81 -0
  39. package/lib/impl/sodaDocCursor.js +63 -0
  40. package/lib/impl/sodaDocument.js +98 -0
  41. package/lib/impl/sodaOperation.js +109 -0
  42. package/lib/lob.js +157 -68
  43. package/lib/oracledb.js +1047 -345
  44. package/lib/pool.js +654 -465
  45. package/lib/poolStatistics.js +24 -9
  46. package/lib/queryStream.js +16 -8
  47. package/lib/resultset.js +291 -183
  48. package/lib/settings.js +191 -0
  49. package/lib/sodaCollection.js +214 -201
  50. package/lib/sodaDatabase.js +108 -71
  51. package/lib/sodaDocCursor.js +44 -32
  52. package/lib/sodaDocument.js +76 -14
  53. package/lib/sodaOperation.js +131 -118
  54. package/lib/thin/connection.js +1043 -0
  55. package/lib/thin/dbObject.js +630 -0
  56. package/lib/thin/index.js +40 -0
  57. package/lib/thin/lob.js +189 -0
  58. package/lib/thin/pool.js +481 -0
  59. package/lib/thin/protocol/buffer.js +1043 -0
  60. package/lib/thin/protocol/capabilities.js +121 -0
  61. package/lib/thin/protocol/constants.js +765 -0
  62. package/lib/thin/protocol/encryptDecrypt.js +185 -0
  63. package/lib/thin/protocol/messages/auth.js +349 -0
  64. package/lib/thin/protocol/messages/base.js +476 -0
  65. package/lib/thin/protocol/messages/commit.js +56 -0
  66. package/lib/thin/protocol/messages/dataType.js +391 -0
  67. package/lib/thin/protocol/messages/execute.js +312 -0
  68. package/lib/thin/protocol/messages/fetch.js +60 -0
  69. package/lib/thin/protocol/messages/index.js +53 -0
  70. package/lib/thin/protocol/messages/lobOp.js +201 -0
  71. package/lib/thin/protocol/messages/logOff.js +53 -0
  72. package/lib/thin/protocol/messages/ping.js +56 -0
  73. package/lib/thin/protocol/messages/protocol.js +78 -0
  74. package/lib/thin/protocol/messages/rollback.js +56 -0
  75. package/lib/thin/protocol/messages/sessionRelease.js +60 -0
  76. package/lib/thin/protocol/messages/withData.js +812 -0
  77. package/lib/thin/protocol/oson.js +661 -0
  78. package/lib/thin/protocol/packet.js +519 -0
  79. package/lib/thin/protocol/protocol.js +202 -0
  80. package/lib/thin/protocol/utils.js +89 -0
  81. package/lib/thin/resultSet.js +122 -0
  82. package/lib/thin/sqlnet/connStrategy.js +175 -0
  83. package/lib/thin/sqlnet/constants.js +199 -0
  84. package/lib/thin/sqlnet/ezConnectResolver.js +488 -0
  85. package/lib/thin/sqlnet/navNodes.js +870 -0
  86. package/lib/thin/sqlnet/networkSession.js +621 -0
  87. package/lib/thin/sqlnet/ntTcp.js +527 -0
  88. package/lib/thin/sqlnet/nvStrToNvPair.js +783 -0
  89. package/lib/thin/sqlnet/packet.js +405 -0
  90. package/lib/thin/sqlnet/paramParser.js +206 -0
  91. package/lib/thin/sqlnet/sessionAtts.js +160 -0
  92. package/lib/thin/statement.js +300 -0
  93. package/lib/thin/util.js +289 -0
  94. package/lib/transformer.js +252 -0
  95. package/lib/types.js +357 -0
  96. package/lib/util.js +196 -110
  97. package/lib/version.js +36 -0
  98. package/package/README.md +33 -30
  99. package/package/install.js +89 -64
  100. package/package/prunebinaries.js +60 -12
  101. package/package.json +3 -3
  102. package/build/Release/oracledb-5.5.0-darwin-x64.node +0 -0
  103. package/build/Release/oracledb-5.5.0-darwin-x64.node-buildinfo.txt +0 -1
  104. package/build/Release/oracledb-5.5.0-linux-x64.node +0 -0
  105. package/build/Release/oracledb-5.5.0-linux-x64.node-buildinfo.txt +0 -1
  106. package/build/Release/oracledb-5.5.0-win32-x64.node +0 -0
  107. package/build/Release/oracledb-5.5.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,300 @@
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');
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 = /--.*/g;
52
+ const MULTI_LINE_COMMENT_PATTERN = /\/\*.*?\*\//sg;
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
+ const copiedStatement = new Statement();
114
+ copiedStatement.sql = this.sql;
115
+ copiedStatement.sqlBytes = this.sqlBytes;
116
+ copiedStatement.sqlLength = this.sqlLength;
117
+ copiedStatement.isQuery = this.isQuery;
118
+ copiedStatement.isPlSql = this.isPlSql;
119
+ copiedStatement.isDml = this.isDml;
120
+ copiedStatement.isDdl = this.isDdl;
121
+ copiedStatement.isReturning = this.isReturning;
122
+ copiedStatement.bindInfoList = [];
123
+ for (const bindInfo of this.bindInfoList) {
124
+ const newBindInfo = new BindInfo(bindInfo.bindName, bindInfo.isReturnBind);
125
+ copiedStatement.bindInfoList.push(newBindInfo);
126
+ }
127
+ const bindInfoDict = copiedStatement.bindInfoDict = new Map();
128
+ for (const bindInfo of copiedStatement.bindInfoList) {
129
+ if (bindInfoDict.has(bindInfo.bindName)) {
130
+ bindInfoDict.get(bindInfo.bindName).push(bindInfo);
131
+ } else {
132
+ bindInfoDict.set(bindInfo.bindName, [bindInfo]);
133
+ }
134
+ }
135
+ copiedStatement.returnToCache = false;
136
+ return copiedStatement;
137
+ }
138
+
139
+ //---------------------------------------------------------------------------
140
+ // _determineStatementType(sql)
141
+ //
142
+ // Determine the type of the SQL statement by examining the first keyword
143
+ // found in the statement
144
+ //---------------------------------------------------------------------------
145
+ _determineStatementType(sql) {
146
+ sql = thinUtil.cleanSql(sql);
147
+ let tokens = sql.trim().trimStart('(').substring(0, 10).split(" ");
148
+ if (tokens.length > 0) {
149
+ const sqlKeyword = tokens[0].toUpperCase();
150
+ if (["DECLARE", "BEGIN", "CALL"].includes(sqlKeyword)) {
151
+ this.isPlSql = true;
152
+ if (sqlKeyword === 'DECLARE') {
153
+ this.statementType = constants.STMT_TYPE_DECLARE;
154
+ } else if (sqlKeyword === 'BEGIN') {
155
+ this.statementType = constants.STMT_TYPE_BEGIN;
156
+ } else if (sqlKeyword === 'CALL') {
157
+ this.statementType = constants.STMT_TYPE_CALL;
158
+ }
159
+ } else if (["SELECT", "WITH"].includes(sqlKeyword)) {
160
+ this.isQuery = true;
161
+ if (sqlKeyword === "SELECT") {
162
+ this.statementType = constants.STMT_TYPE_SELECT;
163
+ }
164
+ } else if (["INSERT", "UPDATE", "DELETE", "MERGE"].includes(sqlKeyword)) {
165
+ this.isDml = true;
166
+ if (sqlKeyword === 'INSERT') {
167
+ this.statementType = constants.STMT_TYPE_INSERT;
168
+ } else if (sqlKeyword === 'UPDATE') {
169
+ this.statementType = constants.STMT_TYPE_UPDATE;
170
+ } else if (sqlKeyword === 'DELETE') {
171
+ this.statementType = constants.STMT_TYPE_DELETE;
172
+ } else if (sqlKeyword === 'MERGE') {
173
+ this.statementType = constants.STMT_TYPE_MERGE;
174
+ }
175
+ } else if (["CREATE", "ALTER", "DROP", "TRUNCATE"].includes(sqlKeyword)) {
176
+ this.isDdl = true;
177
+ if (sqlKeyword === 'CREATE') {
178
+ this.statementType = constants.STMT_TYPE_CREATE;
179
+ } else if (sqlKeyword === 'ALTER') {
180
+ this.statementType = constants.STMT_TYPE_ALTER;
181
+ } else if (sqlKeyword === 'DROP') {
182
+ this.statementType = constants.STMT_TYPE_DROP;
183
+ }
184
+ } else if (sqlKeyword === 'COMMIT') {
185
+ this.statementType = constants.STMT_TYPE_COMMIT;
186
+ } else if (sqlKeyword === 'ROLLBACK') {
187
+ this.statementType = constants.STMT_TYPE_ROLLBACK;
188
+ } else if (sqlKeyword === 'MERGE') {
189
+ this.statementType = constants.STMT_TYPE_MERGE;
190
+ } else {
191
+ this.statementType = constants.STMT_TYPE_UNKNOWN;
192
+ }
193
+ }
194
+ }
195
+
196
+ //---------------------------------------------------------------------------
197
+ // prepare(sql)
198
+ //
199
+ // Prepare the SQL for execution by determining the list of bind names
200
+ // that are found within it. The length of the SQL text is also calculated
201
+ // at this time.
202
+ //---------------------------------------------------------------------------
203
+ _prepare(sql) {
204
+ this.sql = sql;
205
+ this.sqlBytes = Buffer.from(this.sql, 'utf8');
206
+ this.sqlLength = this.sqlBytes.length;
207
+ // replace literals with a specific literal
208
+ sql = sql.replace(CONSTANT_STRING_PATTERN, "'S'");
209
+ sql = sql.replace(SINGLE_LINE_COMMENT_PATTERN, "");
210
+ sql = sql.replace(MULTI_LINE_COMMENT_PATTERN, "");
211
+ this._determineStatementType(sql);
212
+ let returningSql;
213
+ if (this.isQuery || this.isDml || this.isPlSql) {
214
+ let inputSql = sql;
215
+ if (this.isDml) {
216
+ /*
217
+ * get starting index after DML_RETURNING_KEY from begining of sql and starting index
218
+ * after DML_RETURNING_INTO_KEY from the end of sql
219
+ */
220
+ let result;
221
+ let intoKey = -1;
222
+ const retKey = sql.search(DML_RETURNING_KEY);
223
+ let intoRegex = DML_RETURNING_INTO_KEY;
224
+ // simulate lastInfdexOf with intoRegex input
225
+ while ((result = intoRegex.exec(sql.slice(retKey))) != null) {
226
+ intoKey = result.index;
227
+ intoRegex.lastIndex = result.index + 1;
228
+ }
229
+ if (retKey > -1 && intoKey > -1) {
230
+ intoKey = retKey + intoKey;
231
+ inputSql = sql.slice(0, intoKey);
232
+ returningSql = sql.slice(intoKey);
233
+ }
234
+ }
235
+ this._addBinds(inputSql, false);
236
+ if (returningSql) {
237
+ this.isReturning = true;
238
+ this._addBinds(returningSql, true);
239
+ }
240
+ }
241
+ }
242
+
243
+ //---------------------------------------------------------------------------
244
+ // _addBinds(sql)
245
+ //
246
+ // Add bind information to the statement by examining the passed SQL for
247
+ // bind variable names.
248
+ //---------------------------------------------------------------------------
249
+ _addBinds(sql, isReturnBind) {
250
+ const regexMatchArray = [...sql.matchAll(BIND_PATTERN)];
251
+ let name;
252
+ regexMatchArray.forEach(element => {
253
+ if (element[0].startsWith('"') && element[0].endsWith('"')) {
254
+ name = element[0].substring(1, element[0].length - 1);
255
+ } else {
256
+ name = element[0].trim().toUpperCase();
257
+ }
258
+ if (this.isPlSql && this.bindInfoDict.has(name)) {
259
+ return;
260
+ }
261
+ let info = new BindInfo(name, isReturnBind);
262
+ this.bindInfoList.push(info);
263
+
264
+ if (this.bindInfoDict.has(info.bindName)) {
265
+ this.bindInfoDict.get(info.bindName).push(info);
266
+ } else {
267
+ this.bindInfoDict.set(info.bindName, [info]);
268
+ }
269
+ });
270
+ }
271
+
272
+ //---------------------------------------------------------------------------
273
+ // _setVariable(sql)
274
+ //
275
+ // Set the variable on the bind information and copy across metadata that
276
+ // will be used for binding. If the bind metadata has changed, mark the
277
+ // statement as requiring a full execute. In addition, binding a REF
278
+ // cursor also requires a full execute.
279
+ //---------------------------------------------------------------------------
280
+ _setVariable(bindInfo, variable) {
281
+ if (variable.maxSize !== bindInfo.maxSize
282
+ || variable.dir !== bindInfo.dir
283
+ || variable.isArray !== bindInfo.isArray
284
+ || variable.values.length > bindInfo.numElements
285
+ || variable.type != bindInfo.type
286
+ || variable.maxArraySize != bindInfo.maxArraySize) {
287
+ bindInfo.isArray = variable.isArray;
288
+ bindInfo.numElements = variable.values.length;
289
+ bindInfo.maxSize = variable.maxSize;
290
+ bindInfo.type = variable.type;
291
+ bindInfo.dir = variable.dir;
292
+ bindInfo.maxArraySize = variable.maxArraySize;
293
+ this.requiresFullExecute = true;
294
+ }
295
+
296
+ bindInfo.bindVar = variable;
297
+ }
298
+ }
299
+
300
+ module.exports.Statement = Statement;