oracledb-for-lambda
Version:
oracledb, precompiled for AWS Lambda
404 lines (356 loc) • 10.4 kB
JavaScript
/* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. */
/******************************************************************************
*
* You may not use the identified files except in compliance with the Apache
* License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************/
;
var oracledbCLib;
var oracledbInst;
var Lob = require('./lob.js').Lob;
var pool = require('./pool.js');
var connection = require('./connection.js');
var nodbUtil = require('./util.js');
var createPoolPromisified;
var getConnectionPromisified;
var poolCache = {};
var tempUsedPoolAliases = {};
var defaultPoolAlias = 'default';
try {
oracledbCLib = require('../build/Release/oracledb');
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err;
} else {
try {
oracledbCLib = require('../build/Debug/oracledb');
} catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') {
throw err;
} else {
throw new Error(nodbUtil.getErrorMessage('NJS-045'));
}
}
}
}
oracledbCLib.Oracledb.prototype.newLob = function(iLob) {
return new Lob(iLob, null, oracledbInst);
};
// This createPool function is used the override the createPool method of the
// Oracledb class, which is defined in the C layer. The override allows us to do
// things like extend out the pool instance prior to passing it to the caller.
function createPool(poolAttrs, createPoolCb) {
var self = this;
var poolAlias;
// Initial argument count and type checks are done first and throw in the same
// call stack.
nodbUtil.assert(arguments.length === 2, 'NJS-009');
nodbUtil.assert(nodbUtil.isObject(poolAttrs), 'NJS-006', 1);
nodbUtil.assert(typeof createPoolCb === 'function', 'NJS-006', 2);
// Additional validations should pass errors via the callback. Need to ensure
// that errors are raised prior to actually creating the pool via _createPool.
if (poolAttrs.poolAlias !== undefined) {
if (typeof poolAttrs.poolAlias !== 'string' || poolAttrs.poolAlias.length === 0) {
createPoolCb(new Error(nodbUtil.getErrorMessage('NJS-004', 'poolAttrs.poolAlias')));
return;
}
poolAlias = poolAttrs.poolAlias;
} else if (poolAttrs.poolAlias === undefined
&& !poolCache[defaultPoolAlias]
&& !tempUsedPoolAliases[defaultPoolAlias]
) {
poolAlias = defaultPoolAlias;
}
if (poolCache[poolAlias] || tempUsedPoolAliases[poolAlias]) {
createPoolCb(new Error(nodbUtil.getErrorMessage('NJS-046', poolAlias)));
return;
}
// Need to prevent another call in the same stack from succeeding, otherwise
// two pools could be created with the same poolAlias and the second one that
// comes back would overwrite the first in the cache.
if (poolAlias) {
tempUsedPoolAliases[poolAlias] = true;
}
self._createPool(poolAttrs, function(err, poolInst) {
if (err) {
// We need to free this up since the creation of the pool failed.
if (poolAlias) {
delete tempUsedPoolAliases[poolAlias];
}
createPoolCb(err);
return;
}
if (poolAlias) {
poolCache[poolAlias] = poolInst;
// It's now safe to remove this alias from the tempUsedPoolAliases.
delete tempUsedPoolAliases[poolAlias];
}
pool.extend(poolInst, poolAttrs, poolAlias, self);
poolInst.on('_after_close', function() {
var pool = this;
if (pool.poolAlias) {
delete poolCache[pool.poolAlias];
}
});
createPoolCb(null, poolInst);
});
}
createPoolPromisified = nodbUtil.promisify(createPool);
// The getPool function is a synchronous method used to retrieve pools from the
// pool cache.
function getPool(poolAlias) {
var pool;
nodbUtil.assert(arguments.length < 2, 'NJS-009');
if (poolAlias) {
nodbUtil.assert(typeof poolAlias === 'string' || typeof poolAlias === 'number', 'NJS-006', 1);
}
poolAlias = poolAlias || defaultPoolAlias;
pool = poolCache[poolAlias];
if (!pool) {
throw new Error(nodbUtil.getErrorMessage('NJS-047', poolAlias));
}
return pool;
}
// This getConnection function is used the override the getConnection method of the
// Oracledb class, which is defined in the C layer. The override allows us to do
// things like extend out the connection instance prior to passing it to the caller.
function getConnection(a1, a2) {
var self = this;
var pool;
var poolAlias;
var connAttrs;
var getConnectionCb;
nodbUtil.assert(arguments.length < 3, 'NJS-009');
// Verify the number and types of arguments, then initialize the local poolAlias,
// connAttrs, and getConnectionCb variables based on the arguments.
switch (arguments.length) {
case 1:
nodbUtil.assert(typeof a1 === 'function', 'NJS-006', 1);
poolAlias = defaultPoolAlias;
getConnectionCb = a1;
break;
case 2:
nodbUtil.assert(typeof a1 === 'string' || nodbUtil.isObject(a1), 'NJS-006', 1);
nodbUtil.assert(typeof a2 === 'function', 'NJS-006', 2);
if (typeof a1 === 'string') {
poolAlias = a1;
} else if (nodbUtil.isObject(a1)) {
connAttrs = a1;
if (connAttrs.poolAlias) {
poolAlias = connAttrs.poolAlias;
}
}
getConnectionCb = a2;
break;
}
// Proceed to execution based on values in local variables. Look for the poolAlias
// first and only attempt to use connAttrs if the poolAlias isn't set.
if (poolAlias) {
pool = poolCache[poolAlias];
if (!pool) {
getConnectionCb(new Error(nodbUtil.getErrorMessage('NJS-047', poolAlias)));
return;
}
pool.getConnection(getConnectionCb);
} else {
self._getConnection(connAttrs, function(err, connInst) {
if (err) {
getConnectionCb(err);
return;
}
connection.extend(connInst, self);
getConnectionCb(null, connInst);
});
}
}
getConnectionPromisified = nodbUtil.promisify(getConnection);
// The extend method is used to extend the Oracledb instance from the C layer with
// custom properties and method overrides. References to the original methods are
// maintained so they can be invoked by the overriding method at the right time.
function extend(oracledb) {
// Using Object.defineProperties to add properties to the Oracledb instance with
// special properties, such as enumerable but not writable. A number of constants
// (uppercase names) are added for use in various method calls.
Object.defineProperties(
oracledb,
{
_oracledb: { // Known to be used in util.js' promisify function.
value: oracledb
},
DEFAULT: {
value: 0,
enumerable: true
},
DB_TYPE_VARCHAR: {
value: 1,
enumerable: true
},
DB_TYPE_NUMBER: {
value: 2,
enumerable: true
},
DB_TYPE_DATE: {
value: 12,
enumerable: true
},
DB_TYPE_RAW: {
value: 23,
enumerable: true
},
DB_TYPE_CHAR: {
value: 96,
enumerable: true
},
DB_TYPE_BINARY_FLOAT: {
value: 100,
enumerable: true
},
DB_TYPE_BINARY_DOUBLE: {
value: 101,
enumerable: true
},
DB_TYPE_ROWID: {
value: 104,
enumerable: true
},
DB_TYPE_CLOB: {
value: 112,
enumerable: true
},
DB_TYPE_BLOB: {
value: 113,
enumerable: true
},
DB_TYPE_TIMESTAMP: {
value: 187,
enumerable: true
},
DB_TYPE_TIMESTAMP_TZ: {
value: 188,
enumerable: true
},
DB_TYPE_TIMESTAMP_LTZ: {
value: 232,
enumerable: true
},
STRING: {
value: 2001,
enumerable: true
},
NUMBER: {
value: 2002,
enumerable: true
},
DATE: {
value: 2003,
enumerable: true
},
CURSOR: {
value: 2004,
enumerable: true
},
BUFFER: {
value: 2005,
enumerable: true
},
CLOB: {
value: 2006,
enumerable: true
},
BLOB: {
value: 2007,
enumerable: true
},
BIND_IN: {
value: 3001,
enumerable: true
},
BIND_INOUT: {
value: 3002,
enumerable: true
},
BIND_OUT: {
value: 3003,
enumerable: true
},
ARRAY: {
value: 4001,
enumerable: true
},
OBJECT: {
value: 4002,
enumerable: true
},
Promise: {
value: global.Promise,
enumerable: true,
writable: true
},
Oracledb: {
value: oracledbCLib.Oracledb,
enumerable: true
},
Connection: {
value: oracledbCLib.Connection,
enumerable: true
},
Lob: {
value: Lob,
enumerable: true
},
Pool: {
value: oracledbCLib.Pool,
enumerable: true
},
ResultSet: {
value: oracledbCLib.ResultSet,
enumerable: true
},
queueRequests: {
value: true,
enumerable: true,
writable: true
},
queueTimeout: {
value: 60000,
enumerable: true,
writable: true
},
_createPool: {
value: oracledb.createPool
},
createPool: {
value: createPoolPromisified,
enumerable: true,
writable: true
},
getPool: {
value: getPool,
enumerable: true,
writable: true
},
_getConnection: {
value: oracledb.getConnection
},
getConnection: {
value: getConnectionPromisified,
enumerable: true,
writable: true
}
}
);
}
oracledbInst = new oracledbCLib.Oracledb();
extend(oracledbInst);
module.exports = oracledbInst;