UNPKG

12.8 kBJavaScriptView Raw
1// Copyright (c) 2022, 2024, 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
29const constants = require('./constants.js');
30const errors = require('./errors.js');
31const util = require('util');
32
33const dbTypeByNum = new Map();
34const dbTypeByOraTypeNum = new Map();
35const dbTypeByColumnTypeName = new Map();
36
37// define class used for database types
38class DbType {
39
40 constructor(num, name, columnTypeName, options) {
41 this.num = num;
42 this.name = name;
43 this.columnTypeName = columnTypeName;
44 this._bufferSizeFactor = options.bufferSizeFactor || 0;
45 this._oraTypeNum = options.oraTypeNum || 0;
46 this._csfrm = options.csfrm || 0;
47 dbTypeByNum.set(num, this);
48 const key = (options.csfrm || 0) * 256 + options.oraTypeNum;
49 dbTypeByOraTypeNum.set(key, this);
50 dbTypeByColumnTypeName.set(columnTypeName, this);
51 }
52
53 [Symbol.toPrimitive](hint) {
54 switch (hint) {
55 case 'number':
56 return this.num;
57 default:
58 return this.toString();
59 }
60 }
61
62 [util.inspect.custom]() {
63 return this.toString();
64 }
65
66 toString() {
67 return `[DbType ${this.name}]`;
68 }
69
70}
71
72//-----------------------------------------------------------------------------
73// getTypeByColumnTypeName()
74//
75// Return the type given a column type name. If the column type name cannot be
76// found an exception is thrown.
77//-----------------------------------------------------------------------------
78function getTypeByColumnTypeName(name) {
79 const dbType = dbTypeByColumnTypeName.get(name);
80 if (!dbType)
81 errors.throwErr(errors.ERR_UNKNOWN_COLUMN_TYPE_NAME, name);
82 return dbType;
83}
84
85//-----------------------------------------------------------------------------
86// getTypeByNum()
87//
88// Return the type given the type number. If the type number is incorrect an
89// exception is thrown.
90//-----------------------------------------------------------------------------
91function getTypeByNum(num) {
92 const dbType = dbTypeByNum.get(num);
93 if (!dbType)
94 errors.throwErr(errors.ERR_INVALID_TYPE_NUM, num);
95 return dbType;
96}
97
98//-----------------------------------------------------------------------------
99// getTypeByOraTypeNum()
100//
101// Return the type given the Oracle type number and character set form. If the
102// Oracle type number and character set form are incorrect an exception is
103// thrown.
104//-----------------------------------------------------------------------------
105function getTypeByOraTypeNum(oraTypeNum, csfrm) {
106 const key = (csfrm || 0) * 256 + oraTypeNum;
107 const dbType = dbTypeByOraTypeNum.get(key);
108 if (!dbType)
109 errors.throwErr(errors.ERR_INVALID_ORACLE_TYPE_NUM, oraTypeNum, csfrm);
110 return dbType;
111}
112
113const DB_TYPE_BFILE = new DbType(2020,
114 "DB_TYPE_BFILE", "BFILE",
115 { oraTypeNum: 114, bufferSizeFactor: 112 });
116const DB_TYPE_BINARY_DOUBLE = new DbType(2008,
117 "DB_TYPE_BINARY_DOUBLE", "BINARY_DOUBLE",
118 { oraTypeNum: 101, bufferSizeFactor: 8 });
119const DB_TYPE_BINARY_FLOAT = new DbType(2007,
120 "DB_TYPE_BINARY_FLOAT", "BINARY_FLOAT",
121 { oraTypeNum: 100, bufferSizeFactor: 4 });
122const DB_TYPE_BINARY_INTEGER = new DbType(2009,
123 "DB_TYPE_BINARY_INTEGER", "BINARY_INTEGER",
124 { oraTypeNum: 3, bufferSizeFactor: 22 });
125const DB_TYPE_BLOB = new DbType(2019,
126 "DB_TYPE_BLOB", "BLOB",
127 { oraTypeNum: 113, bufferSizeFactor: 112 });
128const DB_TYPE_BOOLEAN = new DbType(2022,
129 "DB_TYPE_BOOLEAN", "BOOLEAN",
130 { oraTypeNum: 252, bufferSizeFactor: 4 });
131const DB_TYPE_CHAR = new DbType(2003,
132 "DB_TYPE_CHAR", "CHAR",
133 { oraTypeNum: 96, csfrm: constants.CSFRM_IMPLICIT, bufferSizeFactor: 4 });
134const DB_TYPE_CLOB = new DbType(2017,
135 "DB_TYPE_CLOB", "CLOB",
136 { oraTypeNum: 112, csfrm: constants.CSFRM_IMPLICIT, bufferSizeFactor: 112 });
137const DB_TYPE_CURSOR = new DbType(2021,
138 "DB_TYPE_CURSOR", "CURSOR",
139 { oraTypeNum: 102, bufferSizeFactor: 4 });
140const DB_TYPE_DATE = new DbType(2011,
141 "DB_TYPE_DATE", "DATE",
142 { oraTypeNum: 12, bufferSizeFactor: 7 });
143const DB_TYPE_INTERVAL_DS = new DbType(2015,
144 "DB_TYPE_INTERVAL_DS", "INTERVAL DAY TO SECOND",
145 { oraTypeNum: 183, bufferSizeFactor: 11 });
146const DB_TYPE_INTERVAL_YM = new DbType(2016,
147 "DB_TYPE_INTERVAL_YM", "INTERVAL YEAR TO MONTH",
148 { oraTypeNum: 182 });
149const DB_TYPE_JSON = new DbType(2027,
150 "DB_TYPE_JSON", "JSON",
151 { oraTypeNum: 119 });
152const DB_TYPE_LONG = new DbType(2024,
153 "DB_TYPE_LONG", "LONG",
154 { oraTypeNum: 8, csfrm: constants.CSFRM_IMPLICIT,
155 bufferSizeFactor: 2 ** 31 - 1 });
156const DB_TYPE_LONG_NVARCHAR = new DbType(2031,
157 "DB_TYPE_LONG_NVARCHAR", "LONG",
158 { oraTypeNum: 8, csfrm: constants.CSFRM_NCHAR,
159 bufferSizeFactor: 2 ** 31 - 1 });
160const DB_TYPE_LONG_RAW = new DbType(2025,
161 "DB_TYPE_LONG_RAW", "LONG RAW",
162 { oraTypeNum: 24, bufferSizeFactor: 2 ** 31 - 1 });
163const DB_TYPE_NCHAR = new DbType(2004,
164 "DB_TYPE_NCHAR", "NCHAR",
165 { oraTypeNum: 96, csfrm: constants.CSFRM_NCHAR, bufferSizeFactor: 4 });
166const DB_TYPE_NCLOB = new DbType(2018,
167 "DB_TYPE_NCLOB", "NCLOB",
168 { oraTypeNum: 112, csfrm: constants.CSFRM_NCHAR, bufferSizeFactor: 112 });
169const DB_TYPE_NUMBER = new DbType(2010,
170 "DB_TYPE_NUMBER", "NUMBER",
171 { oraTypeNum: 2, bufferSizeFactor: 22 });
172const DB_TYPE_NVARCHAR = new DbType(2002,
173 "DB_TYPE_NVARCHAR", "NVARCHAR2",
174 { oraTypeNum: 1, csfrm: constants.CSFRM_NCHAR, bufferSizeFactor: 4 });
175const DB_TYPE_OBJECT = new DbType(2023,
176 "DB_TYPE_OBJECT", "OBJECT",
177 { oraTypeNum: 109 });
178const DB_TYPE_RAW = new DbType(2006,
179 "DB_TYPE_RAW", "RAW",
180 { oraTypeNum: 23, bufferSizeFactor: 1 });
181const DB_TYPE_ROWID = new DbType(2005,
182 "DB_TYPE_ROWID", "ROWID",
183 { oraTypeNum: 11, bufferSizeFactor: 18 });
184const DB_TYPE_TIMESTAMP = new DbType(2012,
185 "DB_TYPE_TIMESTAMP", "TIMESTAMP",
186 { oraTypeNum: 180, bufferSizeFactor: 11 });
187const DB_TYPE_TIMESTAMP_LTZ = new DbType(2014,
188 "DB_TYPE_TIMESTAMP_LTZ", "TIMESTAMP WITH LOCAL TIME ZONE",
189 { oraTypeNum: 231, bufferSizeFactor: 11 });
190const DB_TYPE_TIMESTAMP_TZ = new DbType(2013,
191 "DB_TYPE_TIMESTAMP_TZ", "TIMESTAMP WITH TIME ZONE",
192 { oraTypeNum: 181, bufferSizeFactor: 13 });
193const DB_TYPE_UROWID = new DbType(2030,
194 "DB_TYPE_UROWID", "UROWID",
195 { oraTypeNum: 208 });
196const DB_TYPE_VARCHAR = new DbType(2001,
197 "DB_TYPE_VARCHAR", "VARCHAR2",
198 { oraTypeNum: 1, csfrm: constants.CSFRM_IMPLICIT, bufferSizeFactor: 4 });
199const DB_TYPE_XMLTYPE = new DbType(2032,
200 "DB_TYPE_XMLTYPE", "XMLTYPE",
201 { oraTypeNum: 109, csfrm: constants.CSFRM_IMPLICIT, bufferSizeFactor: 2147483647 });
202const DB_TYPE_VECTOR = new DbType(2033,
203 "DB_TYPE_VECTOR", "VECTOR",
204 { oraTypeNum: 127 });
205
206// database type conversion map: the top level key refers to the database
207// type being fetched and the value is another map; this map's key is the
208// type requested by the user and its value is the actual type that will be
209// used in the define call; only entries are included where the database type
210// and the requested fetch type are different
211const DB_TYPE_CONVERSION_MAP = new Map([
212 [DB_TYPE_BINARY_DOUBLE, new Map([
213 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR]
214 ])],
215 [DB_TYPE_BINARY_FLOAT, new Map([
216 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR]
217 ])],
218 [DB_TYPE_BLOB, new Map([
219 [DB_TYPE_RAW, DB_TYPE_LONG_RAW],
220 [DB_TYPE_LONG_RAW, DB_TYPE_LONG_RAW]
221 ])],
222 [DB_TYPE_CHAR, new Map([
223 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR]
224 ])],
225 [DB_TYPE_CLOB, new Map([
226 [DB_TYPE_VARCHAR, DB_TYPE_LONG],
227 [DB_TYPE_LONG, DB_TYPE_LONG]
228 ])],
229 [DB_TYPE_DATE, new Map([
230 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR],
231 [DB_TYPE_TIMESTAMP_LTZ, DB_TYPE_TIMESTAMP_LTZ]
232 ])],
233 [DB_TYPE_JSON, new Map([
234 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR]
235 ])],
236 [DB_TYPE_LONG, new Map([
237 [DB_TYPE_VARCHAR, DB_TYPE_LONG]
238 ])],
239 [DB_TYPE_LONG_RAW, new Map([
240 [DB_TYPE_RAW, DB_TYPE_LONG_RAW]
241 ])],
242 [DB_TYPE_NCHAR, new Map([
243 [DB_TYPE_CHAR, DB_TYPE_NCHAR],
244 [DB_TYPE_VARCHAR, DB_TYPE_NVARCHAR],
245 [DB_TYPE_NVARCHAR, DB_TYPE_NVARCHAR]
246 ])],
247 [DB_TYPE_NCLOB, new Map([
248 [DB_TYPE_VARCHAR, DB_TYPE_LONG_NVARCHAR],
249 [DB_TYPE_NVARCHAR, DB_TYPE_LONG_NVARCHAR],
250 [DB_TYPE_LONG, DB_TYPE_LONG_NVARCHAR],
251 [DB_TYPE_LONG_NVARCHAR, DB_TYPE_LONG_NVARCHAR]
252 ])],
253 [DB_TYPE_NUMBER, new Map([
254 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR]
255 ])],
256 [DB_TYPE_NVARCHAR, new Map([
257 [DB_TYPE_CHAR, DB_TYPE_NCHAR],
258 [DB_TYPE_NCHAR, DB_TYPE_NCHAR],
259 [DB_TYPE_VARCHAR, DB_TYPE_NVARCHAR]
260 ])],
261 [DB_TYPE_RAW, new Map([
262 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR]
263 ])],
264 [DB_TYPE_ROWID, new Map([
265 [DB_TYPE_VARCHAR, DB_TYPE_ROWID]
266 ])],
267 [DB_TYPE_TIMESTAMP, new Map([
268 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR],
269 [DB_TYPE_TIMESTAMP_LTZ, DB_TYPE_TIMESTAMP_LTZ]
270 ])],
271 [DB_TYPE_TIMESTAMP_LTZ, new Map([
272 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR],
273 [DB_TYPE_TIMESTAMP_TZ, DB_TYPE_TIMESTAMP_TZ]
274 ])],
275 [DB_TYPE_TIMESTAMP_TZ, new Map([
276 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR],
277 [DB_TYPE_TIMESTAMP_LTZ, DB_TYPE_TIMESTAMP_LTZ]
278 ])],
279 [DB_TYPE_UROWID, new Map([
280 [DB_TYPE_VARCHAR, DB_TYPE_ROWID]
281 ])],
282 [DB_TYPE_VECTOR, new Map([
283 [DB_TYPE_VARCHAR, DB_TYPE_LONG],
284 [DB_TYPE_LONG, DB_TYPE_LONG],
285 [DB_TYPE_CLOB, DB_TYPE_CLOB]
286 ])],
287]);
288
289// default fetch type map
290const DB_TYPE_FETCH_TYPE_MAP = new Map([
291 [DB_TYPE_BFILE, DB_TYPE_BFILE],
292 [DB_TYPE_BINARY_DOUBLE, DB_TYPE_BINARY_DOUBLE],
293 [DB_TYPE_BINARY_FLOAT, DB_TYPE_BINARY_FLOAT],
294 [DB_TYPE_BINARY_INTEGER, DB_TYPE_BINARY_INTEGER],
295 [DB_TYPE_BLOB, DB_TYPE_BLOB],
296 [DB_TYPE_BOOLEAN, DB_TYPE_BOOLEAN],
297 [DB_TYPE_CHAR, DB_TYPE_CHAR],
298 [DB_TYPE_CLOB, DB_TYPE_CLOB],
299 [DB_TYPE_CURSOR, DB_TYPE_CURSOR],
300 [DB_TYPE_DATE, DB_TYPE_DATE],
301 [DB_TYPE_INTERVAL_DS, DB_TYPE_INTERVAL_DS],
302 [DB_TYPE_INTERVAL_YM, DB_TYPE_INTERVAL_YM],
303 [DB_TYPE_JSON, DB_TYPE_JSON],
304 [DB_TYPE_LONG, DB_TYPE_LONG],
305 [DB_TYPE_LONG_NVARCHAR, DB_TYPE_LONG_NVARCHAR],
306 [DB_TYPE_LONG_RAW, DB_TYPE_LONG_RAW],
307 [DB_TYPE_NCHAR, DB_TYPE_NCHAR],
308 [DB_TYPE_NCLOB, DB_TYPE_NCLOB],
309 [DB_TYPE_NUMBER, DB_TYPE_NUMBER],
310 [DB_TYPE_NVARCHAR, DB_TYPE_NVARCHAR],
311 [DB_TYPE_OBJECT, DB_TYPE_OBJECT],
312 [DB_TYPE_RAW, DB_TYPE_RAW],
313 [DB_TYPE_ROWID, DB_TYPE_ROWID],
314 [DB_TYPE_TIMESTAMP, DB_TYPE_TIMESTAMP],
315 [DB_TYPE_TIMESTAMP_LTZ, DB_TYPE_TIMESTAMP_TZ],
316 [DB_TYPE_TIMESTAMP_TZ, DB_TYPE_TIMESTAMP_TZ],
317 [DB_TYPE_UROWID, DB_TYPE_UROWID],
318 [DB_TYPE_VARCHAR, DB_TYPE_VARCHAR],
319 [DB_TYPE_XMLTYPE, DB_TYPE_XMLTYPE],
320 [DB_TYPE_VECTOR, DB_TYPE_VECTOR]
321]);
322
323// additional aliases for types by column type name
324dbTypeByColumnTypeName.set("DOUBLE PRECISION", DB_TYPE_NUMBER);
325dbTypeByColumnTypeName.set("FLOAT", DB_TYPE_NUMBER);
326dbTypeByColumnTypeName.set("INTEGER", DB_TYPE_NUMBER);
327dbTypeByColumnTypeName.set("PL/SQL BOOLEAN", DB_TYPE_BOOLEAN);
328dbTypeByColumnTypeName.set("PL/SQL BINARY INTEGER", DB_TYPE_BINARY_INTEGER);
329dbTypeByColumnTypeName.set("PL/SQL PLS INTEGER", DB_TYPE_BINARY_INTEGER);
330dbTypeByColumnTypeName.set("REAL", DB_TYPE_NUMBER);
331dbTypeByColumnTypeName.set("SMALLINT", DB_TYPE_NUMBER);
332dbTypeByColumnTypeName.set("TIMESTAMP WITH LOCAL TZ", DB_TYPE_TIMESTAMP_LTZ);
333dbTypeByColumnTypeName.set("TIMESTAMP WITH TZ", DB_TYPE_TIMESTAMP_TZ);
334
335module.exports = {
336 DbType,
337 DB_TYPE_BFILE,
338 DB_TYPE_BINARY_DOUBLE,
339 DB_TYPE_BINARY_FLOAT,
340 DB_TYPE_BINARY_INTEGER,
341 DB_TYPE_BLOB,
342 DB_TYPE_BOOLEAN,
343 DB_TYPE_CHAR,
344 DB_TYPE_CLOB,
345 DB_TYPE_CURSOR,
346 DB_TYPE_DATE,
347 DB_TYPE_INTERVAL_DS,
348 DB_TYPE_INTERVAL_YM,
349 DB_TYPE_JSON,
350 DB_TYPE_LONG,
351 DB_TYPE_LONG_NVARCHAR,
352 DB_TYPE_LONG_RAW,
353 DB_TYPE_NCHAR,
354 DB_TYPE_NCLOB,
355 DB_TYPE_NUMBER,
356 DB_TYPE_NVARCHAR,
357 DB_TYPE_OBJECT,
358 DB_TYPE_RAW,
359 DB_TYPE_ROWID,
360 DB_TYPE_TIMESTAMP,
361 DB_TYPE_TIMESTAMP_LTZ,
362 DB_TYPE_TIMESTAMP_TZ,
363 DB_TYPE_UROWID,
364 DB_TYPE_VARCHAR,
365 DB_TYPE_VECTOR,
366 DB_TYPE_CONVERSION_MAP,
367 DB_TYPE_FETCH_TYPE_MAP,
368 DB_TYPE_XMLTYPE,
369 getTypeByColumnTypeName,
370 getTypeByNum,
371 getTypeByOraTypeNum
372};