oracle-cg-lib
Version:
Library to connect and execute query's normal or in bulk in oracle databases
126 lines (120 loc) • 4.75 kB
JavaScript
const oracledb = require('oracledb');
const { log, constants, helpers, DatabaseConnection } = require('utils-nxg-cg');
const { messages_databases } = constants;
oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT;
oracledb.autoCommit = false;
/**
* options for operations DML in batch or bulk
* @type {{dmlRowCounts: boolean, batchErrors: boolean}}
*/
const options = {
batchErrors: true,
dmlRowCounts: true
};
/**
* Method for create connection to oracle database
* @param properties
* @returns {Promise<Connection>}
*/
const createConnection = async (properties) => {
try {
properties.port = (typeof properties.port === 'string') ? Number(properties.port) : properties.port;
properties.maximum = (typeof properties.maximum === 'string') ? Number(properties.maximum) : properties.maximum;
properties.minimum = (typeof properties.minimum === 'string') ? Number(properties.minimum) : properties.minimum;
if (properties.mode === 'thick' && properties.path_client) {
//create temporal env variable node_env_oracle_init only for initialize oracle client
if (!process.env.node_env_oracle_init && process.env.node_env_oracle_init !== 'false') {
process.env['node_env_oracle_init'] = 'true';
oracledb.initOracleClient();
}
} else {
if (process.env.node_env_oracle_init || properties.mode === 'thin') {
delete process.env.node_env_oracle_init;
}
if (properties.mode === 'thick' && !properties.path_client) {
throw Error('{ message: "No Oracle client found." }');
}
}
return await new DatabaseConnection(properties).getConnection();
} catch (e) {
throw Error(e);
}
};
/**
* Method for process query in oracle db
* @param properties
* @returns {Promise<object>}
*/
const processQuery = async (properties) => {
let result;
let connection;
try {
connection = await createConnection(properties);
let { content, limit, query } = properties;
//if content is not empty or null
if (content) {
let tmp = [];
if (Array.isArray(content) && content.length > 0) {
if (content.length > limit)
throw Error(`${messages_databases.ERROR_BATCH} ${limit}`);
//if first position on array is not array then convert an array
if (!Array.isArray(content[0]) && !helpers.isObjectValid(content[0]))
content = [[...content]];
tmp = [...content];
} else {
tmp.push(content);
}
let message = query.toLowerCase().startsWith('select') ? messages_databases.START_QUERY : messages_databases.START_BATCH;
log.debug(message);
if (query.toLowerCase().startsWith('update') || query.toLowerCase().startsWith('select')) {
for (const t of tmp) {
result = await connection.execute(query, t);
}
if (query.toLowerCase().startsWith('update')) {
result = { rowsAffected: tmp.length };
}
} else {
result = await connection.executeMany(query, tmp, options);
}
} else {
log.debug(messages_databases.START_QUERY);
result = await connection.execute(query);
}
const _result = await processResult(result);
await connection.commit();
await connection.close();
if (helpers.isObjectValid(_result)) {
log.debug(messages_databases.QUERY_EXECUTED);
return _result;
} else {
throw Error(constants.ERROR_JSON_FORMAT);
}
} catch (e) {
if (connection) {
log.error(messages_databases.TRANSACTION_ERROR);
await connection.rollback();
await connection.close();
}
throw Error(e.toString());
}
};
/**
* Method for process result or query on oracle db
* @param result
* @returns {Promise<object>}
*/
const processResult = (result) =>
new Promise((resolve, reject) => {
const { batchErrors, rows, rowsAffected } = result;
if (batchErrors)
if (Array.isArray(batchErrors))
reject(batchErrors[0]);
else
reject(batchErrors)
if (rows)
resolve(rows);
if (rowsAffected)
resolve({ rowsAffected });
resolve(result);
});
module.exports = processQuery;