Skip to content

Instantly share code, notes, and snippets.

@131
Last active April 24, 2016 20:50
Show Gist options
  • Save 131/be40a39e24e4ca1d0c485ff8cec6eb71 to your computer and use it in GitHub Desktop.
Save 131/be40a39e24e4ca1d0c485ff8cec6eb71 to your computer and use it in GitHub Desktop.
Proposal for pg-async transaction stack
"use strict";
var values = function(obj){
var val = []
Object.keys(obj).forEach(function(key) {
val.push(obj[key]);
});
return val;
};
var transactions_stack = {};
var get_transaction_level = function() {
var depths = values(transactions_stack);
var level = depths.length ? Math.max.apply(null, depths ) + 1: 0;
console.log(depths, level);
return level;
}
function* begin(lnk) {
var transaction_hash = `_trans_${Math.random().toString(16).substr(2)}`;
var level = get_transaction_level();
transactions_stack[transaction_hash] = level;
var query = `BEGIN`;
if(level != 0)
query = `SAVEPOINT ${transaction_hash}`;
yield lnk.query(query);
return Promise.resolve(transaction_hash);
}
function* commit(lnk, transaction_hash){
var level = transactions_stack[transaction_hash];
if(level === undefined)
throw `Incorrect transaction passed ${transaction_hash}`;
delete transactions_stack[transaction_hash];
var max_depth = get_transaction_level();
if(max_depth > level)
throw `Incorrect transaction level passed ${level} < ${max_depth}`;
if(level == 0)
yield lnk.query(`COMMIT`);
return Promise.resolve(true);
}
function* rollback(lnk, transaction_hash) {
var level = transactions_stack[transaction_hash];
if(level === undefined)
throw `Incorrect transaction passed ${transaction_hash}`;
for(var tmp_hash in transactions_stack)
if(transactions_stack[tmp_hash] >= level)
delete transactions_stack[tmp_hash];
var query = `ROLLBACK`;
if(level > 0)
query = `ROLLBACK TO SAVEPOINT ${transaction_hash}`;
yield lnk.query(query);
return Promise.resolve(true);
}
module.exports = {
begin,
commit,
rollback,
install : function(pgAsync){
pgAsync.prototype.begin = function(){
return begin(this);
};
pgAsync.prototype.rollback = function(token){
return rollback(this, token);
};
pgAsync.prototype.commit = function(token){
return commit(this, token);
};
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment