limber-firebird-client
Version:
Cliente JavaScript/Typescrypt para Node.js de acesso a banco de dados Firebird charset ISO8859_1 e UTF8
424 lines (371 loc) • 16.6 kB
JavaScript
const fs = require('fs');
const path = require('path');
const firebird = require('./core');
const pack = require('../package');
const DEFAULT_FIREBIRD_USER = 'SYSDBA';
const DEFAULT_FIREBIRD_PASSWORD = 'masterkey';
const DEFAULT_FIREBIRD_HOST = '127.0.0.1';
const DEFAULT_FIREBIRD_PORT = 3050;
const DEFAULT_FIREBIRD_LOWERCASE_KEYS = false;
const DEFAULT_FIREBIRD_ROLE = null;
const DEFAULT_FIREBIRD_PAGE_SIZE = 16384;
const DEFAULT_FIREBIRD_MAX_POOL_CONNECTION = 5;
const DEFAULT_FIREBIRD_TIMEOUT_DESTROY_POOLS = 180000;
const DEFAULT_FIREBIRD_CONN_FORCE_CLEAR = false;
const DEFAULT_FIREBIRD_DISPLAY_LOGS = false;
const DEFAULT_FIREBIRD_ENCODING = 'latin1';
const DEFAULT_FIREBIRD_CACHE_QUERY = true;
let openPool, openPoolImage;
let timeoutDestroyPools = process.env.FIREBIRD_CONN_TIMEOUT_CLEAR || DEFAULT_FIREBIRD_TIMEOUT_DESTROY_POOLS;
let connForceDestroyPools = (process.env.FIREBIRD_CONN_FORCE_CLEAR && process.env.FIREBIRD_CONN_FORCE_CLEAR === 'true') || DEFAULT_FIREBIRD_CONN_FORCE_CLEAR;
const displayLogs = (process.env.FIREBIRD_DISPLAY_LOGS && process.env.FIREBIRD_DISPLAY_LOGS === 'true') || DEFAULT_FIREBIRD_DISPLAY_LOGS;
function databaseParser() {
let versao = pack.version;
let remoteProcess = pack.name;
let destroyPoolTimer;
openPool = firebird.pool(process.env.FIREBIRD_MAX_CONN || DEFAULT_FIREBIRD_MAX_POOL_CONNECTION, {
host: process.env.FIREBIRD_HOST || DEFAULT_FIREBIRD_HOST,
port: process.env.FIREBIRD_PORT || DEFAULT_FIREBIRD_PORT,
database: process.env.FIREBIRD_BASE || '',
user: process.env.FIREBIRD_USER || DEFAULT_FIREBIRD_USER,
password: process.env.FIREBIRD_PASSWD || DEFAULT_FIREBIRD_PASSWORD,
lowercase_keys: (process.env.FIREBIRD_LOWERCASE_KEYS ? process.env.FIREBIRD_LOWERCASE_KEYS === 'true' : DEFAULT_FIREBIRD_LOWERCASE_KEYS),
role: process.env.FIREBIRD_ROLE || DEFAULT_FIREBIRD_ROLE,
pageSize: process.env.FIREBIRD_PAGE_SIZE || DEFAULT_FIREBIRD_PAGE_SIZE,
encoding: process.env.FIREBIRD_ENCODING || DEFAULT_FIREBIRD_ENCODING,
cacheQuery: (process.env.FIREBIRD_CACHE_QUERY ? process.env.FIREBIRD_CACHE_QUERY === 'true' : DEFAULT_FIREBIRD_CACHE_QUERY),
});
module.exports.openPool = openPool;
openPoolImage = firebird.pool(process.env.FIREBIRD_IMG_MAX_CONN || DEFAULT_FIREBIRD_MAX_POOL_CONNECTION, {
host: process.env.FIREBIRD_IMG_HOST || DEFAULT_FIREBIRD_HOST,
port: process.env.FIREBIRD_IMG_PORT || DEFAULT_FIREBIRD_PORT,
database: process.env.FIREBIRD_IMG_BASE || '',
user: process.env.FIREBIRD_IMG_USER || DEFAULT_FIREBIRD_USER,
password: process.env.FIREBIRD_IMG_PASSWD || DEFAULT_FIREBIRD_PASSWORD,
lowercase_keys: (process.env.FIREBIRD_IMG_LOWERCASE_KEYS ? process.env.FIREBIRD_IMG_LOWERCASE_KEYS === 'true' : DEFAULT_FIREBIRD_LOWERCASE_KEYS),
role: process.env.FIREBIRD_IMG_ROLE || DEFAULT_FIREBIRD_ROLE,
pageSize: process.env.FIREBIRD_IMG_PAGE_SIZE || DEFAULT_FIREBIRD_PAGE_SIZE,
encoding: process.env.FIREBIRD_ENCODING || DEFAULT_FIREBIRD_ENCODING,
cacheQuery: (process.env.FIREBIRD_CACHE_QUERY ? process.env.FIREBIRD_CACHE_QUERY === 'true' : DEFAULT_FIREBIRD_CACHE_QUERY),
});
fs.readFile(path.join(path.dirname(require.main.filename || process.mainModule.filename), 'package.json'), (err, data) => {
if (!err) {
try {
let packageJson = JSON.parse(data.toString());
if (packageJson.version) {
versao = packageJson.version;
}
if (packageJson.name) {
remoteProcess = packageJson.name.substring(0, 100);
}
} catch (e) {
}
showMessage('VERSÃO: ' + versao);
showMessage('PROCESS: ' + remoteProcess);
process.env._FB_SET_USER_VERSION = versao;
process.env._FB_REMOTE_PROCESS = remoteProcess;
}
});
if (connForceDestroyPools) {
setInterval(() => {
if (openPool) {
openPool.destroy();
showMessage('DESTROY POOL DATA');
}
if (openPoolImage) {
openPoolImage.destroy();
showMessage('DESTROY POOL IMAGE');
}
}, timeoutDestroyPools);
}
return (req, res, next) => {
async function openDataBaseRead(usuario, descricao) {
res._db = await getDataBaseFromPool(usuario, descricao);
return res._db;
}
async function getDataBaseFromPool(usuario, descricao) {
const user = (usuario || (req.user && req.user.usuario ? req.user.usuario : 1));
const desc = (descricao || (req.originalUrl));
try {
const db = await openPool.get(user, desc);
showMessage(`OPEN ATTACH FROM POOL DATA (${user} - ${desc})`);
return db;
} catch (e) {
showMessage(`ERRO OPEN ATTACH FROM POOL DATA (${user} - ${desc})`, e);
throw e;
}
}
async function openDataBaseImageRead(usuario, descricao) {
const user = (usuario || (req.user && req.user.usuario ? req.user.usuario : 1));
const desc = (descricao || (req.originalUrl));
try {
res._dbImage = await openPool.get(user, desc);
showMessage(`OPEN ATTACH FROM POOL IMAGE (${user} - ${desc})`);
return res._dbImage;
} catch (e) {
showMessage(`ERRO OPEN ATTACH FROM POOL IMAGE (${user} - ${desc})`, e);
throw e;
}
}
async function openDataBaseWrite(usuario, descricao) {
const db = await openDataBaseRead(usuario, descricao);
try {
res._transaction = await db.transaction(firebird.ISOLATION_READ_COMMITED_NO_WAIT);
showMessage(`OPEN TRANSACTION`);
return res._transaction;
} catch (e) {
showMessage(`ERRO OPEN TRANSACTION`, e);
throw e;
}
}
async function openDataBaseImageWrite(usuario, descricao) {
const dbImage = await openDataBaseImageRead(usuario, descricao);
try {
res._transactionImage = await dbImage.transaction(firebird.ISOLATION_READ_COMMITED_NO_WAIT);
showMessage('OPEN TRANSACTION IMAGE');
return res._transactionImage;
} catch (e) {
showMessage('ERRO OPEN TRANSACTION IMAGE', e);
throw e;
}
}
function closeAttachs() {
if (res._dbImage) {
showMessage('CLOSE ATTACH IMAGE');
res._dbImage.detach(err => {
if (err) {
showMessage('CLOSE ATTACH IMAGE ERROR', err);
} else {
res._dbImage = null;
}
});
}
if (res._db) {
showMessage('CLOSE ATTACH DATA');
res._db.detach(err => {
if (err) {
showMessage('CLOSE ATTACH DATA ERROR', err);
} else {
res._db = null;
}
});
}
if (!connForceDestroyPools) {
destroyPools();
}
}
function rollbackTransactions(callback) {
let qtd = 0;
if (res._transactionImage) qtd++;
if (res._transaction) qtd++;
if (qtd === 0) {
return callback();
}
let cb = () => {
qtd--;
if (qtd === 0) {
return callback();
}
};
if (res._transactionImage) {
showMessage('ROLLBACK TRANSACTION IMAGE');
res._transactionImage.rollback(err => {
if (err) {
showMessage('ROLLBACK TRANSACTION IMAGE ERROR', err);
} else {
res._transactionImage = null;
}
cb();
});
}
if (res._transaction) {
showMessage('ROLLBACK TRANSACTION DATA');
res._transaction.rollback(err => {
if (err) {
showMessage('ROLLBACK TRANSACTION DATA ERROR', err);
} else {
res._transaction = null;
}
cb();
});
}
}
function commitTransactionData(callback) {
if (res._transaction) {
showMessage('START COMMIT TRANSACTION DATA');
res._transaction.commit(err => {
if (err) {
showMessage('ERRO COMMIT TRANSACTION DATA', err);
rollbackTransactions();
callback(err);
} else {
res._transaction = null;
callback(null);
showMessage('COMMIT TRANSACTION DATA');
}
});
} else {
callback(null);
}
}
function commitTransactionImage(callback) {
if (res._transactionImage) {
showMessage('START COMMIT TRANSACTION IMAGE');
res._transactionImage.commit(err => {
if (err) {
showMessage('ERRO COMMIT TRANSACTION IMAGE', err);
rollbackTransactions();
callback(err);
} else {
res._transaction = null;
callback(null);
showMessage('COMMIT TRANSACTION IMAGE');
}
});
} else {
callback(null);
}
}
function destroyPools() {
if (destroyPoolTimer) {
clearTimeout(destroyPoolTimer);
destroyPoolTimer = null;
showMessage('RESET TIMER DESTROY POOLS');
} else {
showMessage('START TIMER DESTROY POOLS');
}
if (timeoutDestroyPools < 180000) {
timeoutDestroyPools = 180000;
}
destroyPoolTimer = setTimeout(() => {
if (openPool) {
openPool.destroy();
showMessage('DESTROY POOL DATA');
}
if (openPoolImage) {
openPoolImage.destroy();
showMessage('DESTROY POOL IMAGE');
}
}, timeoutDestroyPools);
}
// noinspection JSUnusedGlobalSymbols
req.firebird = {
attachDataBase,
getDataBaseFromPool,
openDataBaseRead,
openDataBaseImageRead,
openDataBaseWrite,
openDataBaseImageWrite
};
let oldEnd = res.end;
res.end = function () {
if (res._transaction || res._transactionImage) {
if (res.statusCode && res.statusCode > 399) {
rollbackTransactions(() => {
oldEnd.apply(res, arguments);
closeAttachs();
});
} else {
commitTransactionData((err) => {
if (err) {
res.set({'Content-Type': 'text/html'});
next(err);
closeAttachs();
} else {
commitTransactionImage((err) => {
if (err) {
res.set({'Content-Type': 'text/html'});
next(err);
} else {
oldEnd.apply(res, arguments);
}
closeAttachs();
});
}
});
}
} else {
oldEnd.apply(res, arguments);
closeAttachs();
}
};
next();
};
}
async function attachPool(usuario, descricao) {
return await openPool.get(usuario, descricao);
}
async function attachPoolImage(usuario, descricao) {
return await openPoolImage.get(usuario, descricao);
}
async function poolStatus() {
let status = {};
status.dbinuse = openPool.dbinuse;
status.internaldb = {count: openPool.internaldb.length};
status.pooldb = {count: openPool.pooldb.length};
return status;
}
async function attachDataBase(options) {
return await firebird.attach({
host: options.host || DEFAULT_FIREBIRD_HOST,
port: options.port || DEFAULT_FIREBIRD_PORT,
database: options.database || '',
user: options.user || DEFAULT_FIREBIRD_USER,
password: options.password || DEFAULT_FIREBIRD_PASSWORD,
lowercase_keys: options.lowercase_keys || DEFAULT_FIREBIRD_LOWERCASE_KEYS,
role: options.role || DEFAULT_FIREBIRD_ROLE,
pageSize: options.pageSize || DEFAULT_FIREBIRD_PAGE_SIZE,
encoding: options.encoding || DEFAULT_FIREBIRD_ENCODING,
cacheQuery: options.cacheQuery || DEFAULT_FIREBIRD_CACHE_QUERY,
});
}
async function createDataBase(options) {
return await firebird.create({
host: options.host || DEFAULT_FIREBIRD_HOST,
port: options.port || DEFAULT_FIREBIRD_PORT,
database: options.database || '',
user: options.user || DEFAULT_FIREBIRD_USER,
password: options.password || DEFAULT_FIREBIRD_PASSWORD,
lowercase_keys: options.lowercase_keys || DEFAULT_FIREBIRD_LOWERCASE_KEYS,
role: options.role || DEFAULT_FIREBIRD_ROLE,
pageSize: options.pageSize || DEFAULT_FIREBIRD_PAGE_SIZE,
encoding: options.encoding || DEFAULT_FIREBIRD_ENCODING,
cacheQuery: options.cacheQuery || DEFAULT_FIREBIRD_CACHE_QUERY,
});
}
async function dropDataBase(options) {
return await firebird.drop({
host: options.host || DEFAULT_FIREBIRD_HOST,
port: options.port || DEFAULT_FIREBIRD_PORT,
database: options.database || '',
user: options.user || DEFAULT_FIREBIRD_USER,
password: options.password || DEFAULT_FIREBIRD_PASSWORD,
lowercase_keys: options.lowercase_keys || DEFAULT_FIREBIRD_LOWERCASE_KEYS,
role: options.role || DEFAULT_FIREBIRD_ROLE,
pageSize: options.pageSize || DEFAULT_FIREBIRD_PAGE_SIZE,
encoding: options.encoding || DEFAULT_FIREBIRD_ENCODING,
cacheQuery: options.cacheQuery || DEFAULT_FIREBIRD_CACHE_QUERY,
});
}
function showMessage(message, error) {
if (displayLogs) {
if (error) {
console.error('limberFirebirdClient', message, error);
} else {
console.log('limberFirebirdClient', message);
}
}
}
module.exports.ISOLATION_READ_UNCOMMITTED = firebird.ISOLATION_READ_UNCOMMITTED;
module.exports.ISOLATION_READ_COMMITED_NO_WAIT = firebird.ISOLATION_READ_COMMITED_NO_WAIT;
module.exports.ISOLATION_READ_COMMITED = firebird.ISOLATION_READ_COMMITED;
module.exports.ISOLATION_REPEATABLE_READ = firebird.ISOLATION_REPEATABLE_READ;
module.exports.ISOLATION_SERIALIZABLE = firebird.ISOLATION_SERIALIZABLE;
module.exports.ISOLATION_READ_COMMITED_READ_ONLY = firebird.ISOLATION_READ_COMMITED_READ_ONLY;
module.exports.attachPool = attachPool;
module.exports.attachPoolImage = attachPoolImage;
module.exports.attachDataBase = attachDataBase;
module.exports.createDataBase = createDataBase;
module.exports.dropDataBase = dropDataBase;
module.exports.databaseParser = databaseParser;
module.exports.poolStatus = poolStatus;