Permalink
Browse files

added async transaction start

  • Loading branch information...
xdenser committed Dec 26, 2011
1 parent fa18daa commit fbb731119434206a87ed36d2f8332d0d3c5c9a29
@@ -31,6 +31,7 @@ void
NODE_SET_PROTOTYPE_METHOD(t, "prepareSync", PrepareSync);
NODE_SET_PROTOTYPE_METHOD(t, "newBlobSync", NewBlobSync);
NODE_SET_PROTOTYPE_METHOD(t, "startTransactionSync", StartSync);
+ NODE_SET_PROTOTYPE_METHOD(t, "startTransaction", Start);
// Properties
Local<v8::ObjectTemplate> instance_t = t->InstanceTemplate();
@@ -605,8 +606,16 @@ void Connection::EIO_After_TransactionRequest(uv_work_t *req)
void Connection::EIO_TransactionRequest(uv_work_t *req)
{
struct transaction_request *tr_req = (struct transaction_request *)(req->data);
- if(tr_req->commit) tr_req->result = tr_req->conn->commit_transaction();
- else tr_req->result = tr_req->conn->rollback_transaction();
+ switch(tr_req->type){
+ case rCommit:
+ tr_req->result = tr_req->conn->commit_transaction();
+ break;
+ case rRollback:
+ tr_req->result = tr_req->conn->rollback_transaction();
+ break;
+ case rStart:
+ tr_req->result = tr_req->conn->start_transaction();
+ }
return;
}
@@ -633,11 +642,11 @@ Handle<Value>
tr_req->conn = conn;
tr_req->callback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
- tr_req->commit = true;
+ tr_req->type = rCommit;
conn->start_async();
- uv_work_t* req = new uv_work_t();
+ uv_work_t* req = new uv_work_t();
req->data = tr_req;
uv_queue_work(uv_default_loop(), req, EIO_TransactionRequest, EIO_After_TransactionRequest);
@@ -670,7 +679,7 @@ Handle<Value>
tr_req->conn = conn;
tr_req->callback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
- tr_req->commit = false;
+ tr_req->type = rRollback;
conn->start_async();
@@ -684,6 +693,42 @@ Handle<Value>
return Undefined();
}
+Handle<Value>
+ Connection::Start (const Arguments& args)
+ {
+ HandleScope scope;
+ Connection *conn = ObjectWrap::Unwrap<Connection>(args.This());
+
+ struct transaction_request *tr_req =
+ (struct transaction_request *)calloc(1, sizeof(struct transaction_request));
+
+ if (!tr_req) {
+ V8::LowMemoryNotification();
+ return ThrowException(Exception::Error(
+ String::New("Could not allocate memory.")));
+ }
+
+ if (args.Length() < 1) {
+ return ThrowException(Exception::Error(
+ String::New("Expecting Callback Function argument")));
+ }
+
+ tr_req->conn = conn;
+ tr_req->callback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
+ tr_req->type = rStart;
+
+ conn->start_async();
+
+ uv_work_t* req = new uv_work_t();
+ req->data = tr_req;
+ uv_queue_work(uv_default_loop(), req, EIO_TransactionRequest, EIO_After_TransactionRequest);
+
+ uv_ref(uv_default_loop());
+ conn->Ref();
+
+ return Undefined();
+ }
+
Handle<Value>
Connection::QuerySync(const Arguments& args)
{
@@ -91,12 +91,18 @@ class Connection : public FBEventEmitter {
static Handle<Value>
StartSync (const Arguments& args);
+
+ enum TransReqType {
+ rCommit,
+ rRollback,
+ rStart
+ };
struct transaction_request {
Persistent<Function> callback;
Connection *conn;
- bool commit;
- bool result;
+ TransReqType type;
+ bool result;
};
static void EIO_After_TransactionRequest(uv_work_t *req);
@@ -109,6 +115,9 @@ class Connection : public FBEventEmitter {
static Handle<Value>
Rollback (const Arguments& args);
+ static Handle<Value>
+ Start (const Arguments& args);
+
static Handle<Value>
QuerySync(const Arguments& args);
@@ -0,0 +1,30 @@
+/*
+Copyright by Denys Khanzhiyev
+See license text in LICENSE file
+*/
+
+// Load configuration
+var cfg = require("../config").cfg;
+var fb = require('../../firebird');
+var util = require('util');
+
+var http = require('http');
+
+http.createServer(function (req, res) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ var con = fb.createConnection();
+ con.connect(cfg.db, cfg.user, cfg.password, cfg.role,function(){
+ con.query('select * from rdb$relations',function(err,rs){
+ var rows = [];
+ rs.fetch("all",true,function(r){
+ rows.push(r);
+ }, function(err){
+ con.disconnect();
+ res.end(util.inspect(rows));
+ });
+
+ });
+ });
+
+}).listen(1337, "127.0.0.1");
+console.log('Server running at http://127.0.0.1:1337/');
@@ -0,0 +1,22 @@
+/*
+Copyright by Denys Khanzhiyev
+See license text in LICENSE file
+*/
+
+// Load configuration
+var cfg = require("../config").cfg;
+var fb = require('../../firebird');
+var util = require('util');
+
+var http = require('http');
+
+http.createServer(function (req, res) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ var con = fb.createConnection();
+ con.connectSync(cfg.db, cfg.user, cfg.password, cfg.role);
+ var rs = con.querySync('select * from rdb$relations');
+ var rows = rs.fetchSync("all",true);
+ con.disconnect();
+ res.end(util.inspect(rows));
+}).listen(1337, "127.0.0.1");
+console.log('Server running at http://127.0.0.1:1337/');
@@ -0,0 +1,33 @@
+/*
+Copyright by Denys Khanzhiyev
+See license text in LICENSE file
+*/
+
+// Load configuration
+var cfg = require("../config").cfg;
+var fb = require('../../firebird');
+var util = require('util');
+
+var http = require('http');
+var con = fb.createConnection();
+ con.connectSync(cfg.db, cfg.user, cfg.password, cfg.role);
+
+http.createServer(function (req, res) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ if(!con.inTransaction) con.startTransactionSync();
+ con.query('select * from rdb$relations',function(err,rs){
+ var rows = [];
+ rs.fetch("all",true,function(r){
+ rows.push(r);
+ }, function(err){
+ res.end(util.inspect(rows));
+ con.commitSync();
+ });
+ });
+
+}).listen(1337, "127.0.0.1");
+console.log('Server running at http://127.0.0.1:1337/');
+
+process.on('exit',function(){
+ con.disconnect();
+});
@@ -0,0 +1,28 @@
+/*
+Copyright by Denys Khanzhiyev
+See license text in LICENSE file
+*/
+
+// Load configuration
+var cfg = require("../config").cfg;
+var fb = require('../../firebird');
+var util = require('util');
+
+var http = require('http');
+
+var con = fb.createConnection();
+ con.connectSync(cfg.db, cfg.user, cfg.password, cfg.role);
+
+http.createServer(function (req, res) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ if(!con.inTransaction) con.startTransactionSync();
+ var rs = con.querySync('select * from rdb$relations');
+ var rows = rs.fetchSync("all",true);
+ res.end(util.inspect(rows));
+ con.commitSync();
+}).listen(1337, "127.0.0.1");
+console.log('Server running at http://127.0.0.1:1337/');
+
+process.on('exit',function(){
+ con.disconnect();
+});
@@ -0,0 +1,106 @@
+/*
+Copyright by Denys Khanzhiyev
+See license text in LICENSE file
+*/
+
+// Load configuration
+var cfg = require("../config").cfg;
+var fb = require('../../firebird');
+var util = require('util');
+var events = require('events');
+
+var http = require('http');
+
+function StatementPool()
+{
+ events.EventEmitter.call(this);
+ this.conns = [];
+ this.busy = [];
+ this.MaxConns = 20;
+ this.newConn = function(){
+ var c ={
+ conn: fb.createConnection()
+ };
+ c.conn.connectSync(cfg.db, cfg.user, cfg.password, cfg.role);
+ c.stmt = c.conn.prepareSync('select * from rdb$relations');
+ this.conns.push(c);
+ };
+ this.get = function(cb)
+ {
+ var self = this;
+ var c = this.conns.pop();
+ if(c) {
+ this.busy.push(c);
+ cb(c);
+ }
+ else
+ if((this.busy.length) >=this.MaxConns){
+ this.once('release',function(){
+ self.get(cb);
+ });
+ }
+ else {
+ this.newConn();
+ this.get(cb);
+ }
+ };
+ this.release = function(con){
+ for(var i=0;i<this.busy.length;i++)
+ {
+ if(this.busy[i] == con){
+ this.conns.push(this.busy[i]);
+ this.busy.splice(i,1);
+ var self = this;
+ process.nextTick(function(){
+ self.emit('release');
+ });
+ return;
+ }
+ }
+ };
+
+}
+util.inherits(StatementPool, events.EventEmitter);
+
+var pool = new StatementPool();
+pool.setMaxListeners(2000);
+
+
+http.createServer(function (req, res) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+// console.log(stmt);
+ pool.get(function(con){
+
+ var exec = function(){
+ con.stmt.exec();
+ con.stmt.once('result',function(err){
+ var rows = [];
+ con.stmt.fetch("all",true,function(r){
+ rows.push(r);
+ }, function(err){
+ res.end(util.inspect(rows));
+ con.conn.commit(function(){
+ pool.release(con);
+ });
+ });
+ });
+ };
+
+ var resp = function(){
+ if(!con.conn.inTransaction) con.conn.startTransaction(function(err){
+ if(!err) exec();
+ });
+ else exec();
+ };
+
+
+ resp();
+
+ });
+
+}).listen(1337, "127.0.0.1");
+console.log('Server running at http://127.0.0.1:1337/');
+
+process.on('exit',function(){
+ con.disconnect();
+});
Oops, something went wrong.

0 comments on commit fbb7311

Please sign in to comment.