Commit 804d3adb by Orlando Vazquez

Rename the old Database#prepare method to prepareAndStep and create a simpler Database#prepare()

parent 6f0d04f0
[submodule "async-testing"]
path = async-testing
url = http://github.com/bentomas/node-async-testing.git
Subproject commit 45a83e31c0e38086cb41a37e29e52215f9ec7674
...@@ -61,7 +61,7 @@ function _setBindingsByIndex(db, ...@@ -61,7 +61,7 @@ function _setBindingsByIndex(db,
function _queryDone(db, statement) { function _queryDone(db, statement) {
if (statement.tail) { if (statement.tail) {
statement.finalize(function () { statement.finalize(function () {
db.prepare(statement.tail, onPrepare); db.prepareAndStep(statement.tail, onPrepare);
}); });
return; return;
} }
...@@ -111,7 +111,7 @@ Database.prototype.query = function(sql, bindings, rowCallback, prepareMode) { ...@@ -111,7 +111,7 @@ Database.prototype.query = function(sql, bindings, rowCallback, prepareMode) {
if (typeof(prepareMode) == "undefined") if (typeof(prepareMode) == "undefined")
prepareMode = sqlite.EXEC_EMPTY; prepareMode = sqlite.EXEC_EMPTY;
this.prepare(sql, function(error, statement) { this.prepareAndStep(sql, function(error, statement) {
if (error) if (error)
return rowCallback (error); return rowCallback (error);
if (statement) { if (statement) {
...@@ -125,7 +125,7 @@ Database.prototype.query = function(sql, bindings, rowCallback, prepareMode) { ...@@ -125,7 +125,7 @@ Database.prototype.query = function(sql, bindings, rowCallback, prepareMode) {
Database.prototype.insert = function(sql, insertCallback) { Database.prototype.insert = function(sql, insertCallback) {
var self = this; var self = this;
this.prepare(sql, function(error, info) { this.prepareAndStep(sql, function(error, info) {
if (error) if (error)
return insertCallback (error); return insertCallback (error);
......
...@@ -39,6 +39,7 @@ void Database::Init(v8::Handle<Object> target) { ...@@ -39,6 +39,7 @@ void Database::Init(v8::Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor_template, "open", Open); NODE_SET_PROTOTYPE_METHOD(constructor_template, "open", Open);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", Close); NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", Close);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "prepare", Prepare); NODE_SET_PROTOTYPE_METHOD(constructor_template, "prepare", Prepare);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "prepareAndStep", PrepareAndStep);
// NODE_SET_PROTOTYPE_METHOD(constructor_template, "changes", Changes); // NODE_SET_PROTOTYPE_METHOD(constructor_template, "changes", Changes);
// NODE_SET_PROTOTYPE_METHOD(constructor_template, "lastInsertRowid", LastInsertRowid); // NODE_SET_PROTOTYPE_METHOD(constructor_template, "lastInsertRowid", LastInsertRowid);
...@@ -245,7 +246,7 @@ Handle<Value> Database::Close(const Arguments& args) { ...@@ -245,7 +246,7 @@ Handle<Value> Database::Close(const Arguments& args) {
// db->Emit(String::New("update"), 4, args); // db->Emit(String::New("update"), 4, args);
// } // }
int Database::EIO_AfterPrepare(eio_req *req) { int Database::EIO_AfterPrepareAndStep(eio_req *req) {
ev_unref(EV_DEFAULT_UC); ev_unref(EV_DEFAULT_UC);
struct prepare_request *prep_req = (struct prepare_request *)(req->data); struct prepare_request *prep_req = (struct prepare_request *)(req->data);
HandleScope scope; HandleScope scope;
...@@ -315,7 +316,7 @@ int Database::EIO_AfterPrepare(eio_req *req) { ...@@ -315,7 +316,7 @@ int Database::EIO_AfterPrepare(eio_req *req) {
return 0; return 0;
} }
int Database::EIO_Prepare(eio_req *req) { int Database::EIO_PrepareAndStep(eio_req *req) {
struct prepare_request *prep_req = (struct prepare_request *)(req->data); struct prepare_request *prep_req = (struct prepare_request *)(req->data);
prep_req->stmt = NULL; prep_req->stmt = NULL;
...@@ -356,6 +357,103 @@ int Database::EIO_Prepare(eio_req *req) { ...@@ -356,6 +357,103 @@ int Database::EIO_Prepare(eio_req *req) {
return 0; return 0;
} }
Handle<Value> Database::PrepareAndStep(const Arguments& args) {
HandleScope scope;
REQ_STR_ARG(0, sql);
REQ_FUN_ARG(1, cb);
OPT_INT_ARG(2, mode, EXEC_EMPTY);
Database* dbo = ObjectWrap::Unwrap<Database>(args.This());
struct prepare_request *prep_req = (struct prepare_request *)
calloc(1, sizeof(struct prepare_request) + sql.length());
if (!prep_req) {
V8::LowMemoryNotification();
return ThrowException(Exception::Error(
String::New("Could not allocate enough memory")));
}
strcpy(prep_req->sql, *sql);
prep_req->cb = Persistent<Function>::New(cb);
prep_req->dbo = dbo;
prep_req->mode = mode;
eio_custom(EIO_PrepareAndStep, EIO_PRI_DEFAULT, EIO_AfterPrepareAndStep, prep_req);
ev_ref(EV_DEFAULT_UC);
dbo->Ref();
return Undefined();
}
int Database::EIO_AfterPrepare(eio_req *req) {
ev_unref(EV_DEFAULT_UC);
struct prepare_request *prep_req = (struct prepare_request *)(req->data);
HandleScope scope;
Local<Value> argv[2];
int argc = 0;
// if the prepare failed
if (req->result != SQLITE_OK) {
argv[0] = Exception::Error(
String::New(sqlite3_errmsg(prep_req->dbo->db_)));
argc = 1;
}
else {
argv[0] = External::New(prep_req->stmt);
argv[1] = Integer::New(-1);
Persistent<Object> statement(
Statement::constructor_template->GetFunction()->NewInstance(2, argv));
if (prep_req->tail) {
statement->Set(String::New("tail"), String::New(prep_req->tail));
}
argv[0] = Local<Value>::New(Undefined());
argv[1] = Local<Value>::New(statement);
argc = 2;
}
TryCatch try_catch;
prep_req->dbo->Unref();
prep_req->cb->Call(Context::GetCurrent()->Global(), argc, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
prep_req->cb.Dispose();
free(prep_req);
return 0;
}
int Database::EIO_Prepare(eio_req *req) {
struct prepare_request *prep_req = (struct prepare_request *)(req->data);
prep_req->stmt = NULL;
prep_req->tail = NULL;
sqlite3* db = prep_req->dbo->db_;
int rc = sqlite3_prepare_v2(db, prep_req->sql, -1,
&(prep_req->stmt), &(prep_req->tail));
req->result = rc;
prep_req->lastInsertId = 0;
prep_req->affectedRows = 0;
// load custom properties
if (prep_req->mode & EXEC_LAST_INSERT_ID)
prep_req->lastInsertId = sqlite3_last_insert_rowid(db);
if (prep_req->mode & EXEC_AFFECTED_ROWS)
prep_req->affectedRows = sqlite3_changes(db);
return 0;
}
Handle<Value> Database::Prepare(const Arguments& args) { Handle<Value> Database::Prepare(const Arguments& args) {
HandleScope scope; HandleScope scope;
REQ_STR_ARG(0, sql); REQ_STR_ARG(0, sql);
......
...@@ -36,6 +36,7 @@ class Database : public EventEmitter { ...@@ -36,6 +36,7 @@ class Database : public EventEmitter {
~Database() { ~Database() {
assert(db_ == NULL); assert(db_ == NULL);
printf("Destroying statement\n");
} }
static Handle<Value> New(const Arguments& args); static Handle<Value> New(const Arguments& args);
...@@ -49,6 +50,10 @@ class Database : public EventEmitter { ...@@ -49,6 +50,10 @@ class Database : public EventEmitter {
static Handle<Value> Close(const Arguments& args); static Handle<Value> Close(const Arguments& args);
// static Handle<Value> LastInsertRowid(const Arguments& args); // static Handle<Value> LastInsertRowid(const Arguments& args);
static int EIO_AfterPrepareAndStep(eio_req *req);
static int EIO_PrepareAndStep(eio_req *req);
static Handle<Value> PrepareAndStep(const Arguments& args);
static int EIO_AfterPrepare(eio_req *req); static int EIO_AfterPrepare(eio_req *req);
static int EIO_Prepare(eio_req *req); static int EIO_Prepare(eio_req *req);
static Handle<Value> Prepare(const Arguments& args); static Handle<Value> Prepare(const Arguments& args);
......
...@@ -255,7 +255,6 @@ Handle<Value> Statement::BindArray(const Arguments& args) { ...@@ -255,7 +255,6 @@ Handle<Value> Statement::BindArray(const Arguments& args) {
pairs->key_type = KEY_INT; pairs->key_type = KEY_INT;
int *index = (int *) malloc(sizeof(int)); int *index = (int *) malloc(sizeof(int));
*index = i+1; *index = i+1;
// pairs->value_size = sizeof(int);
// don't forget to `free` this // don't forget to `free` this
pairs->key = index; pairs->key = index;
......
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