Transaction Global in Node-Firebird - node-firebird

I'm using "node-firebird" in my Firebird 2.5 project and I would like to use a single transaction for multiple inserts or update in some batches, but I couldn't use a global transaction. Could someone help me with this?
This is the single form in the official example:
Firebird.attach(options, function(err, db) {
if (err)
throw err;
// db = DATABASE
db.transaction(Firebird.ISOLATION_READ_COMMITED, function(err, transaction) {
transaction.query('INSERT INTO users VALUE(?,?)', [1, 'Janko'], function(err, result) {
if (err) {
transaction.rollback();
return;
}
transaction.commit(function(err) {
if (err)
transaction.rollback();
else
db.detach();
});
});
});
});
I trying this
const NewTransaction=()=>{
return new Promise((resolve, reject) => {
firebirdPool.get((err, db) => {
if (err) {
reject(err);
return;
}
DBGlobal=db;
DBGlobal.transaction(Firebird.ISOLATION_READ_COMMITED,
function(err, transaction) {
//here i trying save the transaction
TransactionGlobal=transaction;
if (err) {
reject(err);
return;
}
resolve(TransactionGlobal)
});
});//firebirdpool
});//promisse
}//function
const CommitTransaction=()=>{
return new Promise((resolve, reject) => {
TransactionGlobal.commit(function(err) {
if (err){
transaction.rollback();
reject(err);
return;
}
else {
DBGlobal.detach();
resolve(true);
}
});//transaction
});//promisse
}
const RollbackTransaction=()=>{
return new Promise((resolve, reject) => {
try{
TransactionGlobal.rollback();
resolve(true);
}
catch(err){
reject(err)
}
});//promisse
}
//usado com commit
const QueryExecTransaction = (sql,arrayparams=[]) => {
return new Promise((resolve, reject) => {
TransactionGlobal.query(sql,arrayparams,function(err, result) {
if (err) {
console.log('erro na execução da query');
TransactionGlobal.rollback();
reject(err);
return;
}
resolve(result);
return;
});//query
});//promisse
}
I run with this test
async function test(){
await NewTransaction();
console.log('Transacao Global',TransactionGlobal);
QueryExecTransaction(`insert into tabparametros(codigo,nome,valor) values (0,'teste1','')`);
CommitTransaction();
}
test();
But i received this error:
(node:9232) UnhandledPromiseRejectionWarning: Error: invalid transaction handle (expecting explicit transaction start)

I managed to solve, the alteration was in "commitretaining" and others small alters
below the code
//variaveis de "ambiente" salvas na raiz do projeto
//.env e .env.testing
require('dotenv').config({
path: (process.env.NODE_ENV === "test")||(process.env.NODE_ENV === "development") ? ".env.testing" : ".env"
})
var Firebird = require('node-firebird');
var fs = require('fs');
var options = {};
options.host = process.env.DB_HOST;
options.port = process.env.DB_PORT;
options.database = process.env.DB_DATABASE;
options.user = process.env.DB_USER;
options.password = process.env.DB_PASSWORD;
options.lowercase_keys = false; // set to true to lowercase keys
options.role = null; // default
options.pageSize = 4096; // default when creating database
//console.log(options);
//Conexao
// 5 = the number is count of opened sockets
var firebirdPool = Firebird.pool(5, options);
const NewTransaction=()=>{
return new Promise((resolve, reject) => {
firebirdPool.get((err, db) => {
if (err) {
reject(err);
return;
}
//aqui eu salvo o DB retornando
//DBGlobal=db;
db.transaction(Firebird.ISOLATION_READ_COMMITED,
function(err, transaction) {
//aqui eu salvo a transacao retornada
//TransactionGlobal=transaction;
if (err) {
reject(err);
return;
}
resolve({transaction,db});
});
});//firebirdpool
});//promisse
}//function
const CommitTransaction=(transaction,db)=>{
return new Promise((resolve, reject) => {
transaction.commitRetaining(function(err) {
if (err){
transaction.rollback();
reject(err);
return;
}
else {
db.detach();
resolve(true);
}
});//transaction
});//promisse
}
const RollbackTransaction=(transaction,db)=>{
return new Promise((resolve, reject) => {
try{
transaction.rollback();
db.detach();
resolve(true);
}
catch(err){
reject(err)
}
});//promisse
}
//usado com commit
const QueryExecTransaction = (transaction,sql,arrayparams=[]) => {
return new Promise((resolve, reject) => {
transaction.query(sql,arrayparams,function(err, result) {
if (err) {
console.log('erro na execução da query');
transaction.rollback();
reject(err);
return;
}
resolve(result);
return;
});//query
});//promisse
}
async function testa(){
const {transaction,db}=await NewTransaction();
//console.log('Transacao Global',transaction);
let psql='';
try{
for (let i=1;i<101;i++){
psql=`insert into tabparametros(codigo,nome,valor) values (0,'teste${i}-${new Date()}','')`
if (i==79){
//psql='forcando o erro';
}
await QueryExecTransaction(transaction,psql);
}
await CommitTransaction(transaction,db);
}
catch(e){
console.log('Erro no SQL');
console.log(e);
await RollbackTransaction(transaction,db);
}
console.log('Finalizado')
}
testa();

Related

Adding async await in node js

I am using node js function i have written the code long before but i need to add async and await in my functions i don know how to proceed with my code structure .
Here is my code structure
app.express.get('/api/member/logout', function (request, response) {
functionBal.logout(request.query.abc).then(function (result) {
if (result) {
response.set('Content-Type', 'application/json');
response.status(200);
response.json(result);
}
}).catch(function (err) {
response.set('Content-Type', 'application/json');
response.status(400);
response.json("Error -- " + err);
});
});
module.exports.log = function (abc) {
return new app.promise(function (resolve, reject) {
functionDal.log(abc).then(function (result) {
if (result)
resolve(result);
else {
reject("Error");
}
}).catch(function (err) {
reject(err);
});
})
};
module.exports.log = function (abc) {
return new app.promise(function (resolve, reject) {
mySqlConnection.connection().then(function (con) {
con.query("UPDATE member SET table1 = 0 WHERE abc = ?", [abc]).then(function (rows, fields) {
resolve('success');
}).catch(function (err) {
reject(err);
});
}).catch(function (err) {
reject(err);
});
});
}
Please help in adding async await in this coding structure
Give this is try.
app.express.get('/api/member/logout', async function (request, response) {
try {
let data = await functionBal.logout(request.query.abc)
response.set('Content-Type', 'application/json');
response.status(200);
response.json(result);
} catch (error) {
response.set('Content-Type', 'application/json');
response.status(400);
response.json("Error -- " + err);
}
});
module.exports.log = async function (abc) {
try {
return await functionDal.log(abc)
} catch (error) {
throw error
}
};
module.exports.log = async function (abc) {
try {
const con = await mySqlConnection.connection()
await con.query("UPDATE member SET table1 = 0 WHERE abc = ?", [abc])
return 'success'
} catch (error) {
throw error
}
}
Make sure, you have Node.js 8+.

Node.js MS SQL transaction

Can anyone help to implement MS SQL transactions in Node.js . I am try to execute multiple stored procedures inside a promise.
Method 1
const executeProcedure = async (data1, data2) => {
try {
// sql connection
let dbConn = new sql.ConnectionPool(config));
await dbConn.connect();
let transaction = new sql.Transaction(dbConn);
await transaction.begin().then(async()=> {
// tranaciton create
// begin tran
let result = await insertOperation(transaction, data1);
let result2 = await updateOperation(transaction, data2);
let result1 = await Promise.all([result, result2]);
await transaction.commit();
dbConn.close();
}).catch(async(err)=> {
await transaction.rollback();
dbConn.close();
throw err;
});
return {};
}
catch (error) {
throw(error);
}
}
method 2
const insertOperation = async (transaction,data1) => {
return new Promise((resolve, reject) => {
try {
var request = new sql.Request(transaction);
request.input('data1' , sql.NVarChar(40) , data1)
.execute('dbo.insertOperation').then((recordSet) => {
resolve(recordSet.recordsets);
}).catch((err) => {
reject(err);
});
}
catch (error) {
reject(error);
}
});
}
method 3
const updateOperation = async (transaction,data2) => {
return new Promise((resolve, reject) => {
try {
var request = new sql.Request(transaction);
request.input('data2' , sql.NVarChar(40) , data2)
.execute('dbo.updateOperation').then((recordSet) => {
resolve(recordSet.recordsets);
}).catch((err) => {
reject(err);
});
}
catch (error) {
reject(error);
}
});
}
Now I get this error
Can't rollback transaction. There is a request in progress.
anybody please help me to solve this problem
You make some unnecessary Promise wrapper.
Example below:
const insertOperation = async (request, data1) => {
request.input("data1", sql.NVarChar(40), data1);
const result = await request.execute("dbo.insertOperation");
return result.recordsets;
};
const updateOperation = async (request, data2) => {
request.input("data2", sql.NVarChar(40), data2);
const result = await request.execute("dbo.updateOperation");
return result.recordsets;
};
const executeProcedure = async (data1, data2) => {
// sql connection
const dbConn = new sql.ConnectionPool(config);
await dbConn.connect();
let transaction;
try {
transaction = new sql.Transaction(dbConn);
await transaction.begin();
const request = new sql.Request(transaction);
const results = await Promise.all([
insertOperation(request, data1),
updateOperation(request, data2),
]);
await transaction.commit();
return results;
} catch (err) {
await transaction.rollback();
throw err;
} finally {
await dbConn.close();
}
};
#ikhvjs please check the below use case as well
try {
request.input("data", sql.NVarChar(40), data1);
const result = await request.execute("dbo.insertOperation");
return result.recordsets;
} catch (err) {
throw err;
}
};
const updateOperation = async (request, data2) => {
try {
request.input("data", sql.NVarChar(40), data2);
const result = await request.execute("dbo.updateOperation");
return result.recordsets;
} catch (err) {
throw err;
}
};
const executeProcedure = async (data1, data2) => {
try {
// sql connection
const dbConn = new sql.ConnectionPool(config);
await dbConn.connect();
const transaction = new sql.Transaction(dbConn);
try {
await transaction.begin();
const request = new sql.Request(transaction);
const results = await Promise.all([
insertOperation(request, data1),
updateOperation(request, data2),
]);
await transaction.commit();
} catch (err) {
await transaction.rollback();
throw err;
} finally {
await dbConn.close();
}
} catch (error) {
throw error;
}
};```

Nodejs Multiple pools created on refresh

I have several DBs for which i am using connection pools in node.js. Every time i refresh page i think pools are created again. i refresh page 3 times and 3 times promises resolved. i have removed several databases just to make it little bit easier to read here.
and if i un-comment connection close line my app crashes. i can't seem to figure out why
const config = require("../config/config");
const oracledb = require("oracledb");
var crm1connPromise = new Promise((resolve, reject) => {
oracledb.createPool({
user: config.crm1.user,
password: config.crm1.password,
connectString: config.crm1.connectString,
poolAlias: config.crm1.poolAlias,
poolMin: 0,
poolMax: 10,
poolTimeout: 300
}, (error, pool) => {
if (error) {
reject(err);
}
resolve("CRM1 Promise resolved")
});
});
var query2connPromise = new Promise((resolve, reject) => {
oracledb.createPool({
user: config.query2.user,
password: config.query2.password,
connectString: config.query2.connectString,
poolAlias: config.query2.poolAlias,
poolMin: 0,
poolMax: 10,
poolTimeout: 300
}, (error, pool) => {
if (error) {
reject(err);
}
resolve("QUERY2 Promise resolved --------")
});
});
var promiseArray = [crm1connPromise, crm2connPromise, crm3connPromise, crm4connPromise, csfp1connPromise, csfp2connPromise, csfp3connPromise, csfp4connPromise, cact1connPromise, cact2connPromise, cact3connPromise, cact4connPromise, cospconnPromise, cchnconnPromise, bbaseconnPromise, bcdrconnPromise, vcdbconnPromise, crptconnPromise, query2connPromise];
function getDBConnection (dbname) {
return new Promise((resolve, reject) => {
try {
Promise.all(promiseArray).then((message) => {
console.log(message);
const pool = oracledb.getPool(dbname);
pool.getConnection( (err, connection) => {
if (err) {
reject(err);
console.log(err);
}
resolve(connection);
});
});
} catch (error) {
reject(error);
}
});
}
module.exports.query = function(dbname, sql, bind = []){
return new Promise ((resolve,reject) =>{
var conn
try {
getDBConnection(dbname).then((connection) =>{
connection.execute(sql,bind,(err,result)=>{
if (err){
reject(err);
}
resolve(result);
})
//connection.close(0);
})
} catch (error) {
reject(error);
}
})
}
you can use 'Singleton'
please google 'Singleton pattern' and examples.
like this:
dataBaseManager.js:
'use strict'
var Singleton = (function () {
var instance;
function createInstance() {
var object = new dataBaseManager();
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
function dataBaseManager() {
this.connected = false;
this.client = null;
this.dataBase = null;
//public methods
this.connect = function () {
try {
your_database.connect({}, (err, client) => {
if (err) {
this.connected = false;
this.client = null;
this.dataBase = null;
return;
}
this.connected = true;
this.client = client;
this.dataBase = client.db();
});
} catch (error) {
}
};
this.disconnect = function () {
try {
if (this.client) {
this.client.close();
this.connected = false;
this.client = null;
this.dataBase = null;
}
} catch (error) {
}
}
}
module.exports = Singleton;
repository.js:
const dataBaseManager = require("./dataBaseManager").getInstance();
your_get_dample_data_from_data_base_func = function (data) {
dataBaseManager.dataBase
.find({})
.toArray(function (err, result) {
if (err) {
return callback(err, null);
}
callback(null, result);
});
};
index.js:
const dataBaseManager = require("./dataBaseManager").getInstance();
function connect() {
dataBaseManager.connect();
}
function disconnect() {
dataBaseManager.disconnect();
}
Look at the node-oracledb example webappawait.js which starts the pool outside the web listener code path.
async function init() {
try {
await oracledb.createPool({
user: dbConfig.user,
password: dbConfig.password,
connectString: dbConfig.connectString
});
const server = http.createServer();
server.on('error', (err) => {
console.log('HTTP server problem: ' + err);
});
server.on('request', (request, response) => {
handleRequest(request, response);
});
await server.listen(httpPort);
console.log("Server is running at http://localhost:" + httpPort);
} catch (err) {
console.error("init() error: " + err.message);
}
}
async function handleRequest(request, response) {
. . .
}

puppeteer - unexpected token new (Promise), cannot nest try/catch

So I'm trying to nest my try/catch to make things run quicker and smoother.
Here's the original block which was outside (this was working):
try {
await page.waitFor("#login-form-os-captcha", { timeout: 1500 });
security = true
captcha = await new Promise( function (resolve, reject) {
prompt.get(['captcha'], function (err, result) {
console.log('Command-line input received:');
console.log(' captcha: ' + result.captcha);
if (result)
{
resolve(result.captcha);
}
else
{
reject("error with prompt captcha");
}
})
});
}
catch (e) {
security = false
}
Here's my attempt to nest that logic:
try
{
if (form)
{
await page.evaluate( (result) => {
document.querySelector("#login-form-username").value = 'user'
document.querySelector("#login-form-password").value = result.password // require password
try
{
let captcha_input = document.querySelector("#login-form-os-captcha")
if (captcha_input)
{
/* error here, Unexpected token new */
captch_input.value = await new Promise( function (resolve, reject) {
prompt.get(['captcha'], function (err, result) {
console.log('Command-line input received:');
console.log(' captcha: ' + result.captcha);
if (result)
{
resolve(result.captcha);
}
else
{
reject("error with prompt captcha");
}
})
});
}
}
catch (e)
{
console.log("captcha input error")
console.log(e);
}
document.querySelector("#login-form-submit").click()
}, result)
}
}
catch (e)
{
console.log("evaluate fail");
console.log(e);
process.exit(1);
}
Currently doing it this way, one after the other. Still not what I'm optimally looking for.
try
{
await page.waitFor("#login-form-username", { timeout: 3000 })
}
catch (e)
{
console.log("No page or waited too long")
process.exit(1);
}
// Check for captcha
try
{
await page.waitFor("#login-form-os-captcha", { timeout: 500 })
security = true
}
catch (e)
{
console.log("No captcha")
}
// Input captcha if there was a captcha
if (security)
{
try {
let captcha =
await new Promise( function (resolve, reject) {
prompt.get(['captcha'], function (err, result) {
console.log('Command-line input received:');
console.log(' captcha: ' + result.captcha);
if (result)
{
resolve(result.captcha);
}
else
{
reject("error with prompt captcha");
}
})
});
console.log("captcha", captcha)
await page.evaluate( (captcha) => {
document.querySelector("#login-form-os-captcha").value = captcha
}, captcha);
} catch (e) {
console.log("captcha error")
}
}
Update
Okay so it turns out to be a lack of async beforehand.

Move file in Nodejs if file exists otherwise create file

I am trying to move a file from a location abc to location xyz if the file already exists in location xyz delete it then save the new one.
Here is my code
const promises = {
deleteFile: path => {
return new Promise((resolve, reject) => {
const fs = require('fs');
fs.stat(path, (err, stat) => {
if (err === null) {
fs.unlink(path, err => {
if (err) { return reject(err) }
resolve();
})
} else if(err.code == 'ENOENT') {
console.log('File does not exist');
resolve();
} else {
reject(err);
}
});
});
},
copyFile: (from, to) => {
return new Promise((resolve, reject)=> {
copyFile(from, to, (err) => {
if (err) { return reject(err); }
console.log(`Finished writing file ${to}`);
resolve();
})
})
}
}
const copyFile = (from, to, overallCb) => {
const fs = require('fs');
const rs = fs.createReadStream(from)
const ws = fs.createWriteStream(to)
let cbCalled = false;
function done (err) {
overallCb(err);
cbCalled = true;
}
rs.on('error', (err) => {
done(err);
})
ws.on('error', (err) => {
done(err);
})
rs.pipe(ws);
}
;
const OUTPUT_PATH = `./js/libs/`
, _NODE_MODULES = './node_modules/'
, filePath = `${_NODE_MODULES}somePathToAFile`
;
promises.deleteFile(`${OUTPUT_PATH}someFile.min.js`)
.then(promises.copyFile(filePath, `${OUTPUT_PATH}someFile.min.js`))
.then(words => {
console.log('**** done doing things ****');
})
.catch(error => { console.log(`ERROR`, error); })
If the file exists it just simply deletes the file and does nothing else.
If the file DOES NOT exist everything works fine.
Any idea on what im doing wrong?
I had some promise errors in my code... For future me here is the working version of the above code
'use strict';
const promises = {
deleteFile: path => {
return new Promise((resolve, reject) => {
const fs = require('fs');
fs.stat(path, (err, stat) => {
if (err === null) {
fs.unlink(path, err => {
if (err) { return reject(err) }
resolve(`Removing document at ${path}`);
})
} else if(err.code === 'ENOENT') {
resolve('File does not exist');
} else {
reject(err);
}
});
});
},
copyFile: (from, to) => {
return new Promise((resolve, reject) => {
copyFile(from, to, (err) => {
if (err) { return reject(err); }
resolve(`Finished writing file ${to}`);
})
})
}
}
const copyFile = (from, to, overallCb) => {
const fs = require('fs');
const rs = fs.createReadStream(from)
const ws = fs.createWriteStream(to)
let cbCalled = false;
function done (err) {
overallCb(err);
cbCalled = true;
}
rs.on('error', done)
ws.on('error', done)
.on('close', done)
rs.pipe(ws);
}
;
const OUTPUT_PATH = './js/libs/'
, _NODE_MODULES = './node_modules/'
, filePath = `${_NODE_MODULES}somePathToAFile`
;
promises.deleteFile(`${OUTPUT_PATH}someFile.min.js`)
.then(msg => {
console.log(msg)
return promises.copyFile(filePath, `${OUTPUT_PATH}someFile.js`)
})
.then(msg => {
console.log(msg)
})
.catch(err => { // Do errory things}

Resources