Commit e869be39 by Orlando Vazquez

have prepare go through libeio, roughly. will circle back to clean up a bit shortly

parent 6fa2200c
...@@ -143,7 +143,7 @@ protected: ...@@ -143,7 +143,7 @@ protected:
TryCatch try_catch; TryCatch try_catch;
open_req->cb->Call(Context::GetCurrent()->Global(), err && 1, argv); open_req->cb->Call(Context::GetCurrent()->Global(), err ? 1 : 0, argv);
if (try_catch.HasCaught()) { if (try_catch.HasCaught()) {
FatalException(try_catch); FatalException(try_catch);
...@@ -152,6 +152,8 @@ protected: ...@@ -152,6 +152,8 @@ protected:
open_req->cb.Dispose(); open_req->cb.Dispose();
free(open_req); free(open_req);
open_req->dbo->Unref();
return 0; return 0;
} }
...@@ -162,13 +164,15 @@ protected: ...@@ -162,13 +164,15 @@ protected:
sqlite3 **dbptr = open_req->dbo->GetDBPtr(); sqlite3 **dbptr = open_req->dbo->GetDBPtr();
printf("before assn %p\n", *dbptr); printf("before assn %p\n", *dbptr);
int rc = sqlite3_open(open_req->filename, dbptr); int rc = sqlite3_open(open_req->filename, dbptr);
req->result = rc;
printf("after assn %p\n", *dbptr); printf("after assn %p\n", *dbptr);
// XXX try pulling the sqlite5 handle lazily (ie don't store in struct)
sqlite3 *db = *dbptr; sqlite3 *db = *dbptr;
sqlite3_commit_hook(db, CommitHook, open_req->dbo); sqlite3_commit_hook(db, CommitHook, open_req->dbo);
sqlite3_rollback_hook(db, RollbackHook, open_req->dbo); sqlite3_rollback_hook(db, RollbackHook, open_req->dbo);
sqlite3_update_hook(db, UpdateHook, open_req->dbo); sqlite3_update_hook(db, UpdateHook, open_req->dbo);
req->result = rc;
return 0; return 0;
} }
...@@ -194,7 +198,7 @@ protected: ...@@ -194,7 +198,7 @@ protected:
printf("way before addr %p\n", ((sqlite3*) *dbo)); printf("way before addr %p\n", ((sqlite3*) *dbo));
struct open_request *open_req = (struct open_request *) struct open_request *open_req = (struct open_request *)
calloc(1, sizeof(struct open_request)); calloc(1, sizeof(struct open_request) + filename.length());
if (!open_req) { if (!open_req) {
V8::LowMemoryNotification(); V8::LowMemoryNotification();
...@@ -218,6 +222,7 @@ protected: ...@@ -218,6 +222,7 @@ protected:
// JS DatabaseSync bindings // JS DatabaseSync bindings
// //
// TODO: libeio'fy
static Handle<Value> Changes(const Arguments& args) { static Handle<Value> Changes(const Arguments& args) {
HandleScope scope; HandleScope scope;
Sqlite3Db* db = ObjectWrap::Unwrap<Sqlite3Db>(args.This()); Sqlite3Db* db = ObjectWrap::Unwrap<Sqlite3Db>(args.This());
...@@ -225,6 +230,7 @@ protected: ...@@ -225,6 +230,7 @@ protected:
return scope.Close(result); return scope.Close(result);
} }
// TODO: libeio'fy
static Handle<Value> Close(const Arguments& args) { static Handle<Value> Close(const Arguments& args) {
HandleScope scope; HandleScope scope;
Sqlite3Db* db = ObjectWrap::Unwrap<Sqlite3Db>(args.This()); Sqlite3Db* db = ObjectWrap::Unwrap<Sqlite3Db>(args.This());
...@@ -233,6 +239,7 @@ protected: ...@@ -233,6 +239,7 @@ protected:
return Undefined(); return Undefined();
} }
// TODO: libeio'fy
static Handle<Value> LastInsertRowid(const Arguments& args) { static Handle<Value> LastInsertRowid(const Arguments& args) {
HandleScope scope; HandleScope scope;
Sqlite3Db* db = ObjectWrap::Unwrap<Sqlite3Db>(args.This()); Sqlite3Db* db = ObjectWrap::Unwrap<Sqlite3Db>(args.This());
...@@ -240,6 +247,8 @@ protected: ...@@ -240,6 +247,8 @@ protected:
return scope.Close(result); return scope.Close(result);
} }
// Hooks
static int CommitHook(void* v_this) { static int CommitHook(void* v_this) {
HandleScope scope; HandleScope scope;
Sqlite3Db* db = static_cast<Sqlite3Db*>(v_this); Sqlite3Db* db = static_cast<Sqlite3Db*>(v_this);
...@@ -263,37 +272,99 @@ protected: ...@@ -263,37 +272,99 @@ protected:
db->Emit(String::New("update"), 4, args); db->Emit(String::New("update"), 4, args);
} }
/* struct prepare_request {
static Handle<Value> Open(const Arguments& args) { Persistent<Function> cb;
Sqlite3Db *dbo;
sqlite3_stmt* stmt;
const char* tail;
char sql[1];
};
static int EIO_AfterPrepare(eio_req *req) {
ev_unref(EV_DEFAULT_UC);
struct prepare_request *prep_req = (struct prepare_request *)(req->data);
HandleScope scope; HandleScope scope;
Sqlite3Db* db = ObjectWrap::Unwrap<Sqlite3Db>(args.This());
REQ_STR_ARG(0, filename);
Close(args); // ignores args anyway, except This
CHECK(sqlite3_open(*filename, &db->db_));
sqlite3_commit_hook(*db, CommitHook, db); printf("EIO_AfterPrepare %s\n", prep_req->sql);
sqlite3_rollback_hook(*db, RollbackHook, db);
sqlite3_update_hook(*db, UpdateHook, db);
return args.This(); Local<Value> argv[2];
bool err = false;
if (req->result) {
err = true;
argv[0] = Exception::Error(String::New("Error preparing statement"));
}
else {
Local<Value> arg = External::New(prep_req->stmt);
Persistent<Object> statement(Statement::constructor_template->
GetFunction()->NewInstance(1, &arg));
if (prep_req->tail)
statement->Set(String::New("tail"), String::New(prep_req->tail));
argv[1] = Local<Value>::New(Undefined());
argv[0] = scope.Close(statement);
}
TryCatch try_catch;
prep_req->cb->Call(Context::GetCurrent()->Global(), (err ? 1 : 2), argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
prep_req->cb.Dispose();
free(prep_req);
prep_req->dbo->Unref();
return 0;
}
static int EIO_Prepare(eio_req *req) {
struct prepare_request *prep_req = (struct prepare_request *)(req->data);
printf("EIO_Prepare %s\n",
static_cast<struct prepare_request*>(req->data)->sql);
prep_req->stmt = NULL;
prep_req->tail = NULL;
sqlite3* db = *(prep_req->dbo);
int rc = sqlite3_prepare_v2(db, prep_req->sql, -1,
&(prep_req->stmt), &(prep_req->tail));
printf("sqlite3_prepare called\n");
rc = rc || !prep_req->stmt;
req->result = rc;
return 0;
} }
*/
static Handle<Value> Prepare(const Arguments& args) { static Handle<Value> Prepare(const Arguments& args) {
HandleScope scope; HandleScope scope;
Sqlite3Db* db = ObjectWrap::Unwrap<Sqlite3Db>(args.This());
REQ_STR_ARG(0, sql); REQ_STR_ARG(0, sql);
sqlite3_stmt* stmt = NULL; REQ_FUN_ARG(1, cb);
const char* tail = NULL;
CHECK(sqlite3_prepare_v2(*db, *sql, -1, &stmt, &tail)); Sqlite3Db* dbo = ObjectWrap::Unwrap<Sqlite3Db>(args.This());
if (!stmt)
return Null(); struct prepare_request *prep_req = (struct prepare_request *)
Local<Value> arg = External::New(stmt); calloc(1, sizeof(struct prepare_request) + sql.length());
Persistent<Object> statement(Statement::constructor_template->
GetFunction()->NewInstance(1, &arg)); if (!prep_req) {
if (tail) V8::LowMemoryNotification();
statement->Set(String::New("tail"), String::New(tail)); return ThrowException(Exception::Error(
return scope.Close(statement); String::New("Could not allocate enough memory")));
}
strcpy(prep_req->sql, *sql);
prep_req->cb = Persistent<Function>::New(cb);
prep_req->dbo = dbo;
eio_custom(EIO_Prepare, EIO_PRI_DEFAULT, EIO_AfterPrepare, prep_req);
ev_ref(EV_DEFAULT_UC);
dbo->Ref();
return Undefined();
} }
class Statement : public EventEmitter { class Statement : public EventEmitter {
......
...@@ -14,6 +14,10 @@ throws(function () { ...@@ -14,6 +14,10 @@ throws(function () {
db.open("my.db"); db.open("my.db");
}); });
throws(function () {
db.open("foo.db");
});
db.open("my.db", function (err) { db.open("my.db", function (err) {
puts(inspect(arguments)); puts(inspect(arguments));
if (err) { if (err) {
...@@ -22,5 +26,12 @@ db.open("my.db", function (err) { ...@@ -22,5 +26,12 @@ db.open("my.db", function (err) {
} }
puts("open callback"); puts("open callback");
db.printIt(); db.printIt();
db.prepare("SELECT foo FROM bar", function (statement) {
puts("prepare callback");
});
db.prepare("SELECT foo FROM bar; SELECT bar FROM baz", function (statement) {
puts("prepare callback");
});
}); });
puts("done"); puts("done");
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