Commit 1888eea2 by Konstantin Käfer

make the baton handle refing and unrefing

parent 7e210540
...@@ -58,6 +58,7 @@ void Database::Process(Database* db) { ...@@ -58,6 +58,7 @@ void Database::Process(Database* db) {
called = true; called = true;
} }
db->queue.pop(); db->queue.pop();
delete call->baton;
delete call; delete call;
} }
...@@ -135,9 +136,7 @@ Handle<Value> Database::New(const Arguments& args) { ...@@ -135,9 +136,7 @@ Handle<Value> Database::New(const Arguments& args) {
args.This()->Set(String::NewSymbol("mode"), Integer::New(mode), ReadOnly); args.This()->Set(String::NewSymbol("mode"), Integer::New(mode), ReadOnly);
// Start opening the database. // Start opening the database.
OpenBaton* baton = new OpenBaton(); OpenBaton* baton = new OpenBaton(db, callback);
baton->db = db;
baton->callback = Persistent<Function>::New(callback);
baton->filename = *filename; baton->filename = *filename;
baton->mode = SQLITE_OPEN_FULLMUTEX | mode; baton->mode = SQLITE_OPEN_FULLMUTEX | mode;
EIO_BeginOpen(baton); EIO_BeginOpen(baton);
...@@ -146,8 +145,6 @@ Handle<Value> Database::New(const Arguments& args) { ...@@ -146,8 +145,6 @@ Handle<Value> Database::New(const Arguments& args) {
} }
void Database::EIO_BeginOpen(Baton* baton) { void Database::EIO_BeginOpen(Baton* baton) {
baton->db->Ref();
ev_ref(EV_DEFAULT_UC);
eio_custom(EIO_Open, EIO_PRI_DEFAULT, EIO_AfterOpen, baton); eio_custom(EIO_Open, EIO_PRI_DEFAULT, EIO_AfterOpen, baton);
} }
...@@ -175,9 +172,6 @@ int Database::EIO_AfterOpen(eio_req *req) { ...@@ -175,9 +172,6 @@ int Database::EIO_AfterOpen(eio_req *req) {
OpenBaton* baton = static_cast<OpenBaton*>(req->data); OpenBaton* baton = static_cast<OpenBaton*>(req->data);
Database* db = baton->db; Database* db = baton->db;
db->Unref();
ev_unref(EV_DEFAULT_UC);
Local<Value> argv[1]; Local<Value> argv[1];
if (baton->status != SQLITE_OK) { if (baton->status != SQLITE_OK) {
EXCEPTION(String::New(baton->message.c_str()), baton->status, exception); EXCEPTION(String::New(baton->message.c_str()), baton->status, exception);
...@@ -203,6 +197,7 @@ int Database::EIO_AfterOpen(eio_req *req) { ...@@ -203,6 +197,7 @@ int Database::EIO_AfterOpen(eio_req *req) {
} }
delete baton; delete baton;
return 0; return 0;
} }
...@@ -211,12 +206,7 @@ Handle<Value> Database::Close(const Arguments& args) { ...@@ -211,12 +206,7 @@ Handle<Value> Database::Close(const Arguments& args) {
Database* db = ObjectWrap::Unwrap<Database>(args.This()); Database* db = ObjectWrap::Unwrap<Database>(args.This());
OPTIONAL_ARGUMENT_FUNCTION(0, callback); OPTIONAL_ARGUMENT_FUNCTION(0, callback);
db->Ref(); Baton* baton = new Baton(db, callback);
ev_ref(EV_DEFAULT_UC);
Baton* baton = new Baton();
baton->db = db;
baton->callback = Persistent<Function>::New(callback);
Schedule(db, EIO_BeginClose, baton, true); Schedule(db, EIO_BeginClose, baton, true);
return args.This(); return args.This();
...@@ -250,9 +240,6 @@ int Database::EIO_AfterClose(eio_req *req) { ...@@ -250,9 +240,6 @@ int Database::EIO_AfterClose(eio_req *req) {
Baton* baton = static_cast<Baton*>(req->data); Baton* baton = static_cast<Baton*>(req->data);
Database* db = baton->db; Database* db = baton->db;
ev_unref(EV_DEFAULT_UC);
db->Unref();
Local<Value> argv[1]; Local<Value> argv[1];
if (baton->status != SQLITE_OK) { if (baton->status != SQLITE_OK) {
EXCEPTION(String::New(baton->message.c_str()), baton->status, exception); EXCEPTION(String::New(baton->message.c_str()), baton->status, exception);
......
...@@ -29,20 +29,6 @@ using namespace node; ...@@ -29,20 +29,6 @@ using namespace node;
class Database; class Database;
static struct Baton {
Database* db;
Persistent<Function> callback;
int status;
std::string message;
~Baton() {
callback.Dispose();
}
};
static struct OpenBaton : Baton {
std::string filename;
int mode;
};
class Database : public EventEmitter { class Database : public EventEmitter {
public: public:
...@@ -55,11 +41,36 @@ public: ...@@ -55,11 +41,36 @@ public:
return constructor_template->HasInstance(obj); return constructor_template->HasInstance(obj);
} }
static struct Baton {
Database* db;
Persistent<Function> callback;
int status;
std::string message;
Baton(Database* db_, Handle<Function> cb_) : db(db_) {
db->Ref();
ev_ref(EV_DEFAULT_UC);
callback = Persistent<Function>::New(cb_);
}
~Baton() {
db->Unref();
ev_unref(EV_DEFAULT_UC);
callback.Dispose();
}
};
static struct OpenBaton : Baton {
std::string filename;
int mode;
OpenBaton(Database* db_, Handle<Function> cb_) : Baton(db_, cb_) {}
};
typedef void (*EIO_Callback)(Baton* baton); typedef void (*EIO_Callback)(Baton* baton);
struct Call { struct Call {
Call(EIO_Callback callback_, Baton* baton_, bool exclusive_ = false) : Call(EIO_Callback cb_, Baton* baton_, bool exclusive_ = false) :
callback(callback_), exclusive(exclusive_), baton(baton_) {}; callback(cb_), exclusive(exclusive_), baton(baton_) {};
EIO_Callback callback; EIO_Callback callback;
bool exclusive; bool exclusive;
Baton* baton; Baton* baton;
......
...@@ -61,8 +61,6 @@ extern "C" void init (v8::Handle<Object> target) { ...@@ -61,8 +61,6 @@ extern "C" void init (v8::Handle<Object> target) {
DEFINE_CONSTANT_INTEGER(target, SQLITE_FORMAT, FORMAT); DEFINE_CONSTANT_INTEGER(target, SQLITE_FORMAT, FORMAT);
DEFINE_CONSTANT_INTEGER(target, SQLITE_RANGE, RANGE); DEFINE_CONSTANT_INTEGER(target, SQLITE_RANGE, RANGE);
DEFINE_CONSTANT_INTEGER(target, SQLITE_NOTADB, NOTADB); DEFINE_CONSTANT_INTEGER(target, SQLITE_NOTADB, NOTADB);
DEFINE_CONSTANT_INTEGER(target, SQLITE_ROW, ROW);
DEFINE_CONSTANT_INTEGER(target, SQLITE_DONE, DONE);
} }
const char* sqlite_code_string(int code) { const char* sqlite_code_string(int code) {
......
...@@ -85,11 +85,8 @@ Handle<Value> Statement::New(const Arguments& args) { ...@@ -85,11 +85,8 @@ Handle<Value> Statement::New(const Arguments& args) {
Statement* stmt = new Statement(db); Statement* stmt = new Statement(db);
stmt->Wrap(args.This()); stmt->Wrap(args.This());
PrepareBaton* baton = new PrepareBaton(db, Local<Function>::Cast(args[3]));
PrepareBaton* baton = new PrepareBaton();
baton->db = db;
baton->stmt = stmt; baton->stmt = stmt;
baton->callback = Persistent<Function>::New(Local<Function>::Cast(args[3]));
baton->sql = std::string(*String::Utf8Value(sql)); baton->sql = std::string(*String::Utf8Value(sql));
Database::Schedule(db, EIO_BeginPrepare, baton, false); Database::Schedule(db, EIO_BeginPrepare, baton, false);
...@@ -97,7 +94,7 @@ Handle<Value> Statement::New(const Arguments& args) { ...@@ -97,7 +94,7 @@ Handle<Value> Statement::New(const Arguments& args) {
} }
void Statement::EIO_BeginPrepare(Baton* baton) { void Statement::EIO_BeginPrepare(Database::Baton* baton) {
assert(baton->db->open); assert(baton->db->open);
assert(!baton->db->locked); assert(!baton->db->locked);
static_cast<PrepareBaton*>(baton)->stmt->Ref(); static_cast<PrepareBaton*>(baton)->stmt->Ref();
......
...@@ -31,9 +31,11 @@ using namespace node; ...@@ -31,9 +31,11 @@ using namespace node;
class Statement; class Statement;
static struct PrepareBaton : Baton { static struct PrepareBaton : Database::Baton {
Statement* stmt; Statement* stmt;
std::string sql; std::string sql;
PrepareBaton(Database* db_, Handle<Function> cb_) : Baton(db_, cb_) {}
}; };
...@@ -59,7 +61,7 @@ public: ...@@ -59,7 +61,7 @@ public:
} }
protected: protected:
static void EIO_BeginPrepare(Baton* baton); static void EIO_BeginPrepare(Database::Baton* baton);
static int EIO_Prepare(eio_req *req); static int EIO_Prepare(eio_req *req);
static int EIO_AfterPrepare(eio_req *req); static int EIO_AfterPrepare(eio_req *req);
......
...@@ -7,6 +7,34 @@ exports['constants'] = function() { ...@@ -7,6 +7,34 @@ exports['constants'] = function() {
assert.ok(sqlite3.OPEN_READONLY === 1); assert.ok(sqlite3.OPEN_READONLY === 1);
assert.ok(sqlite3.OPEN_READWRITE === 2); assert.ok(sqlite3.OPEN_READWRITE === 2);
assert.ok(sqlite3.OPEN_CREATE === 4); assert.ok(sqlite3.OPEN_CREATE === 4);
assert.ok(sqlite3.OK === 0);
assert.ok(sqlite3.ERROR === 1);
assert.ok(sqlite3.INTERNAL === 2);
assert.ok(sqlite3.PERM === 3);
assert.ok(sqlite3.ABORT === 4);
assert.ok(sqlite3.BUSY === 5);
assert.ok(sqlite3.LOCKED === 6);
assert.ok(sqlite3.NOMEM === 7);
assert.ok(sqlite3.READONLY === 8);
assert.ok(sqlite3.INTERRUPT === 9);
assert.ok(sqlite3.IOERR === 10);
assert.ok(sqlite3.CORRUPT === 11);
assert.ok(sqlite3.NOTFOUND === 12);
assert.ok(sqlite3.FULL === 13);
assert.ok(sqlite3.CANTOPEN === 14);
assert.ok(sqlite3.PROTOCOL === 15);
assert.ok(sqlite3.EMPTY === 16);
assert.ok(sqlite3.SCHEMA === 17);
assert.ok(sqlite3.TOOBIG === 18);
assert.ok(sqlite3.CONSTRAINT === 19);
assert.ok(sqlite3.MISMATCH === 20);
assert.ok(sqlite3.MISUSE === 21);
assert.ok(sqlite3.NOLFS === 22);
assert.ok(sqlite3.AUTH === 23);
assert.ok(sqlite3.FORMAT === 24);
assert.ok(sqlite3.RANGE === 25);
assert.ok(sqlite3.NOTADB === 26);
}; };
exports['open and close non-existent database'] = function(beforeExit) { exports['open and close non-existent database'] = function(beforeExit) {
...@@ -39,7 +67,7 @@ exports['open inaccessible database'] = function(beforeExit) { ...@@ -39,7 +67,7 @@ exports['open inaccessible database'] = function(beforeExit) {
var notOpened; var notOpened;
var db = new sqlite3.Database('/usr/bin/test.db', function(err) { var db = new sqlite3.Database('/usr/bin/test.db', function(err) {
if (err && err.code === 'SQLITE_CANTOPEN') { if (err && err.errno === sqlite3.CANTOPEN) {
notOpened = true; notOpened = true;
} }
else if (err) throw err; else if (err) throw err;
...@@ -57,7 +85,7 @@ exports['open non-existent database without create'] = function(beforeExit) { ...@@ -57,7 +85,7 @@ exports['open non-existent database without create'] = function(beforeExit) {
helper.deleteFile('tmp/test_readonly.db'); helper.deleteFile('tmp/test_readonly.db');
var db = new sqlite3.Database('tmp/test_readonly.db', sqlite3.OPEN_READONLY, var db = new sqlite3.Database('tmp/test_readonly.db', sqlite3.OPEN_READONLY,
function(err) { function(err) {
if (err && err.code === 'SQLITE_CANTOPEN') { if (err && err.errno === sqlite3.CANTOPEN) {
notOpened = true; notOpened = true;
} }
else if (err) throw err; else if (err) throw err;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment