From aa7802a12fd5944877ec2031e8335293361e3039 Mon Sep 17 00:00:00 2001 From: brettlangdon Date: Sun, 27 Oct 2013 20:31:20 -0400 Subject: [PATCH] added in more of the api --- src/wgdb.cc | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/wgdb.h | 2 + 2 files changed, 238 insertions(+), 3 deletions(-) diff --git a/src/wgdb.cc b/src/wgdb.cc index f10c1ab..d634c5a 100644 --- a/src/wgdb.cc +++ b/src/wgdb.cc @@ -15,6 +15,12 @@ struct Baton { void* data; }; +struct FieldData { + int field; + wg_int enc; + Record* record; +}; + struct Fields { int length; wg_int* encs; @@ -117,6 +123,44 @@ void do_create_record(uv_work_t* req){ baton->data = data; } +void do_first_record(uv_work_t* req){ + Baton* baton = static_cast(req->data); + + RecordData* data = static_cast(baton->data); + data->record = wg_get_first_record(baton->wgdb->db_ptr); + if(data->record == NULL){ + char buffer[1024]; + sprintf(buffer, "wgdb database %s could not create record of length %d", baton->wgdb->db_name, data->length); + baton->error = buffer; + delete data; + return; + } + + baton->data = data; +} + +void do_dump(uv_work_t* req){ + Baton* baton = static_cast(req->data); + char* filename = static_cast(baton->data); + + if(wg_dump(baton->wgdb->db_ptr, filename) != 0){ + char buffer[1024]; + sprintf(buffer, "error dumping database %s to %s", baton->wgdb->db_name, filename); + baton->error = buffer; + } +} + +void do_import(uv_work_t* req){ + Baton* baton = static_cast(req->data); + char* filename = static_cast(baton->data); + + if(wg_import_dump(baton->wgdb->db_ptr, filename) != 0){ + char buffer[1024]; + sprintf(buffer, "error importing %s to database %s", filename, baton->wgdb->db_name); + baton->error = buffer; + } +} + void do_record_next(uv_work_t* req){ Baton* baton = static_cast(req->data); @@ -128,6 +172,32 @@ void do_record_next(uv_work_t* req){ baton->data = new_data; } +void do_record_set(uv_work_t* req){ + Baton* baton = static_cast(req->data); + + FieldData* set_field = static_cast(baton->data); + wg_int result = wg_set_field(set_field->record->wgdb->db_ptr, set_field->record->rec_ptr, set_field->field, set_field->enc); + if(result < 0){ + char buffer[1024]; + sprintf(buffer, "error setting field %d on record for database %s", set_field->field, set_field->record->wgdb->db_name); + baton->error = buffer; + } +} + +void do_record_get(uv_work_t* req){ + Baton* baton = static_cast(req->data); + + FieldData* get_field = static_cast(baton->data); + wg_int result = wg_get_field(get_field->record->wgdb->db_ptr, get_field->record->rec_ptr, get_field->field); + if(result < 0){ + char buffer[1024]; + sprintf(buffer, "error getting field %d on record for database %s", get_field->field, get_field->record->wgdb->db_name); + baton->error = buffer; + } + + get_field->enc = result; +} + void do_record_fields(uv_work_t* req){ Baton* baton = static_cast(req->data); @@ -163,6 +233,16 @@ void do_after_no_result(uv_work_t* req, int status){ delete req; } +void do_after_enc_result(uv_work_t* req, int status){ + Baton* baton = static_cast(req->data); + FieldData* data = static_cast(baton->data); + Local result = encoded_to_v8(baton->wgdb->db_ptr, data->enc); + end_call(baton->has_cb, baton->callback, baton->error, result); + baton->callback.Dispose(); + delete baton; + delete req; +} + void do_after_fields(uv_work_t* req, int status){ Baton* baton = static_cast(req->data); Fields* fields = static_cast(baton->data); @@ -213,6 +293,12 @@ void WgDB::Init(Handle target){ FunctionTemplate::New(WgDB::Detach)->GetFunction()); tpl->PrototypeTemplate()->Set(String::NewSymbol("createRecord"), FunctionTemplate::New(WgDB::CreateRecord)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("firstRecord"), + FunctionTemplate::New(WgDB::FirstRecord)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("dump"), + FunctionTemplate::New(WgDB::Dump)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("import"), + FunctionTemplate::New(WgDB::Import)->GetFunction()); Persistent constructor = Persistent::New(tpl->GetFunction()); target->Set(String::NewSymbol("wgdb"), constructor); @@ -344,6 +430,83 @@ Handle WgDB::CreateRecord(const Arguments& args){ return scope.Close(Undefined()); } +Handle WgDB::FirstRecord(const Arguments& args){ + HandleScope scope; + int argc = args.Length(); + + Baton* baton = new Baton(); + RecordData* data = new RecordData(); + baton->data = data; + + if(argc > 0 && args[argc - 1]->IsFunction()){ + baton->has_cb = true; + baton->callback = Persistent::New(Local::Cast(args[argc - 1])); + } + + WgDB* db = ObjectWrap::Unwrap(args.This()); + baton->wgdb = db; + db->Ref(); + + uv_work_t *req = new uv_work_t; + req->data = baton; + uv_queue_work(uv_default_loop(), req, do_first_record, Record::do_after_create_record); + + return scope.Close(Undefined()); +} + +Handle WgDB::Dump(const Arguments& args){ + HandleScope scope; + int argc = args.Length(); + + Baton* baton = new Baton(); + if(argc > 1 && args[0]->IsString()){ + baton->data = get_str(args[0]->ToString()); + + if(args[argc - 1]->IsFunction()){ + baton->has_cb = true; + baton->callback = Persistent::New(Local::Cast(args[argc - 1])); + } + } else{ + return ThrowException(Exception::TypeError(String::New("dump argument 1 must be a string"))); + } + + WgDB* db = ObjectWrap::Unwrap(args.This()); + baton->wgdb = db; + db->Ref(); + + uv_work_t *req = new uv_work_t; + req->data = baton; + uv_queue_work(uv_default_loop(), req, do_dump, do_after_no_result); + + return scope.Close(Undefined()); +} + +Handle WgDB::Import(const Arguments& args){ + HandleScope scope; + int argc = args.Length(); + + Baton* baton = new Baton(); + if(argc > 1 && args[0]->IsString()){ + baton->data = get_str(args[0]->ToString()); + + if(args[argc - 1]->IsFunction()){ + baton->has_cb = true; + baton->callback = Persistent::New(Local::Cast(args[argc - 1])); + } + } else{ + return ThrowException(Exception::TypeError(String::New("import argument 1 must be a string"))); + } + + WgDB* db = ObjectWrap::Unwrap(args.This()); + baton->wgdb = db; + db->Ref(); + + uv_work_t *req = new uv_work_t; + req->data = baton; + uv_queue_work(uv_default_loop(), req, do_import, do_after_no_result); + + return scope.Close(Undefined()); +} /* * @@ -364,6 +527,8 @@ void Record::Init(){ FunctionTemplate::New(Record::Fields)->GetFunction()); tpl->PrototypeTemplate()->Set(String::NewSymbol("setField"), FunctionTemplate::New(Record::SetField)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("getField"), + FunctionTemplate::New(Record::GetField)->GetFunction()); constructor = Persistent::New(tpl->GetFunction()); } @@ -404,9 +569,6 @@ Handle Record::Length(const Arguments& args){ Record* record = ObjectWrap::Unwrap(args.This()); wg_int length = wg_get_record_len(record->wgdb->db_ptr, record->rec_ptr); - if(length < 0){ - - } return scope.Close(Int32::New(length)); } @@ -432,3 +594,74 @@ Handle Record::Fields(const Arguments& args){ return scope.Close(Undefined()); } + +Handle Record::SetField(const Arguments& args){ + HandleScope scope; + int argc = args.Length(); + + if(argc < 2){ + return ThrowException(Exception::Error(String::New("setField requires 2 parameters"))); + } + + Baton* baton = new Baton(); + if(argc > 2 && args[argc - 1]->IsFunction()){ + baton->has_cb = true; + baton->callback = Persistent::New(Local::Cast(args[argc - 1])); + } + + if(!args[0]->IsInt32()){ + return ThrowException(Exception::Error(String::New("setField argument 1 must be an integer"))); + } + + Record* record = ObjectWrap::Unwrap(args.This()); + baton->wgdb = record->wgdb; + + FieldData* set_field = new FieldData(); + set_field->field = (int)args[0]->Int32Value(); + set_field->enc = v8_to_encoded(record->wgdb->db_ptr, args[1]); + set_field->record = record; + + baton->data = set_field; + record->Ref(); + + uv_work_t *req = new uv_work_t; + req->data = baton; + uv_queue_work(uv_default_loop(), req, do_record_set, do_after_no_result); + + return scope.Close(Undefined()); +} + +Handle Record::GetField(const Arguments& args){ + HandleScope scope; + int argc = args.Length(); + + if(argc < 1){ + return ThrowException(Exception::Error(String::New("setField requires 1 parameters"))); + } + + Baton* baton = new Baton(); + if(argc > 1 && args[argc - 1]->IsFunction()){ + baton->has_cb = true; + baton->callback = Persistent::New(Local::Cast(args[argc - 1])); + } + + if(!args[0]->IsInt32()){ + return ThrowException(Exception::Error(String::New("getField argument 1 must be an integer"))); + } + + Record* record = ObjectWrap::Unwrap(args.This()); + baton->wgdb = record->wgdb; + + FieldData* get_field = new FieldData(); + get_field->field = (int)args[0]->Int32Value(); + get_field->record = record; + + baton->data = get_field; + record->Ref(); + + uv_work_t *req = new uv_work_t; + req->data = baton; + uv_queue_work(uv_default_loop(), req, do_record_get, do_after_enc_result); + + return scope.Close(Undefined()); +} diff --git a/src/wgdb.h b/src/wgdb.h index 9d8d098..06b25b9 100644 --- a/src/wgdb.h +++ b/src/wgdb.h @@ -23,6 +23,8 @@ class WgDB : ObjectWrap{ static Handle Delete(const Arguments& args); static Handle CreateRecord(const Arguments& args); static Handle FirstRecord(const Arguments& args); + static Handle Dump(const Arguments& args); + static Handle Import(const Arguments& args); }; class Record : ObjectWrap{