|
|
|
@ -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<Baton*>(req->data); |
|
|
|
|
|
|
|
RecordData* data = static_cast<RecordData*>(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<Baton*>(req->data); |
|
|
|
char* filename = static_cast<char*>(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<Baton*>(req->data); |
|
|
|
char* filename = static_cast<char*>(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<Baton*>(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<Baton*>(req->data); |
|
|
|
|
|
|
|
FieldData* set_field = static_cast<FieldData*>(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<Baton*>(req->data); |
|
|
|
|
|
|
|
FieldData* get_field = static_cast<FieldData*>(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<Baton*>(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<Baton*>(req->data); |
|
|
|
FieldData* data = static_cast<FieldData*>(baton->data); |
|
|
|
Local<Value> 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<Baton*>(req->data); |
|
|
|
Fields* fields = static_cast<Fields*>(baton->data); |
|
|
|
@ -213,6 +293,12 @@ void WgDB::Init(Handle<Object> 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<Function> constructor = Persistent<Function>::New(tpl->GetFunction()); |
|
|
|
target->Set(String::NewSymbol("wgdb"), constructor); |
|
|
|
@ -344,6 +430,83 @@ Handle<Value> WgDB::CreateRecord(const Arguments& args){ |
|
|
|
return scope.Close(Undefined()); |
|
|
|
} |
|
|
|
|
|
|
|
Handle<Value> 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<Function>::New(Local<Function>::Cast(args[argc - 1])); |
|
|
|
} |
|
|
|
|
|
|
|
WgDB* db = ObjectWrap::Unwrap<WgDB>(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<Value> 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<Function>::New(Local<Function>::Cast(args[argc - 1])); |
|
|
|
} |
|
|
|
} else{ |
|
|
|
return ThrowException(Exception::TypeError(String::New("dump argument 1 must be a string"))); |
|
|
|
} |
|
|
|
|
|
|
|
WgDB* db = ObjectWrap::Unwrap<WgDB>(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<Value> 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<Function>::New(Local<Function>::Cast(args[argc - 1])); |
|
|
|
} |
|
|
|
} else{ |
|
|
|
return ThrowException(Exception::TypeError(String::New("import argument 1 must be a string"))); |
|
|
|
} |
|
|
|
|
|
|
|
WgDB* db = ObjectWrap::Unwrap<WgDB>(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<Function>::New(tpl->GetFunction()); |
|
|
|
} |
|
|
|
|
|
|
|
@ -404,9 +569,6 @@ Handle<Value> Record::Length(const Arguments& args){ |
|
|
|
|
|
|
|
Record* record = ObjectWrap::Unwrap<Record>(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<Value> Record::Fields(const Arguments& args){ |
|
|
|
|
|
|
|
return scope.Close(Undefined()); |
|
|
|
} |
|
|
|
|
|
|
|
Handle<Value> 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<Function>::New(Local<Function>::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<Record>(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<Value> 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<Function>::New(Local<Function>::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<Record>(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()); |
|
|
|
} |