diff options
author | adam <anton@adamansky.com> | 2012-10-30 18:45:25 +0700 |
---|---|---|
committer | adam <anton@adamansky.com> | 2012-10-30 18:45:25 +0700 |
commit | a60880266cd8b6f06bd8f67fdeded0326681beaa (patch) | |
tree | 1c2b05a91c6abef75f99f56ccce73aa11b06d33b /node | |
parent | 2fcd4c6df35d8b3c5f84d291c3ba9fbd8556a031 (diff) | |
download | ejdb-a60880266cd8b6f06bd8f67fdeded0326681beaa.tar.gz ejdb-a60880266cd8b6f06bd8f67fdeded0326681beaa.tar.bz2 ejdb-a60880266cd8b6f06bd8f67fdeded0326681beaa.zip |
#1
Diffstat (limited to 'node')
-rw-r--r-- | node/binding.gyp | 2 | ||||
-rw-r--r-- | node/ejdb_native.cc | 111 | ||||
-rw-r--r-- | node/package.json | 2 |
3 files changed, 102 insertions, 13 deletions
diff --git a/node/binding.gyp b/node/binding.gyp index af7afc2..5e3b4db 100644 --- a/node/binding.gyp +++ b/node/binding.gyp @@ -17,6 +17,8 @@ '-g', '-O0', '-fPIC', + '-pedantic', + '-Wno-variadic-macros', '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE' diff --git a/node/ejdb_native.cc b/node/ejdb_native.cc index e425399..5a34131 100644 --- a/node/ejdb_native.cc +++ b/node/ejdb_native.cc @@ -22,8 +22,65 @@ using namespace v8; static_cast<v8::PropertyAttribute>( \ v8::ReadOnly|v8::DontDelete)) +static Persistent<String> sym_close; +static Persistent<String> sym_save; +static Persistent<String> sym_load; +static Persistent<String> sym_query; + namespace ejdb { + /** Convert V8 object into binary json instance. After using it must be freed by bson_del() */ + static bson* toBSON(const Handle<Object>& obj) { + assert(obj->IsObject()); + bson *bs = bson_create(); + bson_init(bs); + Local<Array> pnames = obj->GetOwnPropertyNames(); + for (uint32_t i = 0; i < pnames->Length(); ++i) { + Local<Value> pn = pnames->Get(i); + String::Utf8Value spn(pn); + Local<Value> pv = obj->Get(pn); + if (pv->IsString()) { + String::Utf8Value val(pv); + bson_append_string(bs, *spn, *val); + } else if (pv->IsUint32()) { + bson_append_long(bs, *spn, pv->Uint32Value()); + } else if (pv->IsInt32()) { + bson_append_int(bs, *spn, pv->Int32Value()); + } else if (pv->IsNumber()) { + bson_append_double(bs, *spn, pv->NumberValue()); + } else if (pv->IsNull()) { + bson_append_null(bs, *spn); + } else if (pv->IsUndefined()) { + bson_append_undefined(bs, *spn); + } else if (pv->IsBoolean()) { + bson_append_bool(bs, *spn, pv->BooleanValue()); + } else if (pv->IsDate()) { + bson_append_long(bs, *spn, Handle<Date>::Cast(pv)->IntegerValue()); + } else if (pv->IsRegExp()) { + Handle<RegExp> regexp = Handle<RegExp>::Cast(pv); + int flags = regexp->GetFlags(); + String::Utf8Value sr(regexp->GetSource()); + std::string sf; + if (flags & RegExp::kIgnoreCase) { + sf.append("i"); + } + if (flags & RegExp::kGlobal) { + sf.append("g"); + } + if (flags & RegExp::kMultiline) { + sf.append("m"); + } + bson_append_regex(bs, *spn, *sr, sf.c_str()); + } + //TODO + } + return bs; + } + + /////////////////////////////////////////////////////////////////////////// + // Main NodeEJDB // + /////////////////////////////////////////////////////////////////////////// + class NodeEJDB : public ObjectWrap { typedef EIOCmdTask<NodeEJDB> EJTask; @@ -35,15 +92,39 @@ namespace ejdb { HandleScope scope; REQ_STR_ARG(0, dbPath); REQ_INT32_ARG(1, mode); - NodeEJDB *nejdb = new NodeEJDB(); - if (!nejdb->open(*dbPath, mode)) { + NodeEJDB *njb = new NodeEJDB(); + if (!njb->open(*dbPath, mode)) { std::ostringstream os; - os << "Unable to open database: " << (*dbPath) << " error: " << nejdb->jb_error_msg(); - EJ_LOG_ERROR(os.str().c_str()); - delete nejdb; + os << "Unable to open database: " << (*dbPath) << " error: " << njb->jb_error_msg(); + EJ_LOG_ERROR("%s", os.str().c_str()); + delete njb; return scope.Close(ThrowException(Exception::Error(String::New(os.str().c_str())))); } - nejdb->Wrap(args.This()); + njb->Wrap(args.This()); + return scope.Close(args.This()); + } + + static Handle<Value> s_close(const Arguments& args) { + HandleScope scope; + NodeEJDB *njb = ObjectWrap::Unwrap< NodeEJDB > (args.This()); + assert(njb); + if (!njb->close()) { + return scope.Close(ThrowException(Exception::Error(String::New(njb->jb_error_msg())))); + } + return scope.Close(args.This()); + } + + static Handle<Value> s_save(const Arguments& args) { + HandleScope scope; + REQ_OBJ_ARG(0, obj); + bson *bs = toBSON(obj); + if (bs->err) { + Local<String> msg = String::New(bs->errstr ? bs->errstr : "bson creation failed"); + bson_del(bs); + return scope.Close(ThrowException(Exception::Error(msg))); + } + + return scope.Close(args.This()); } @@ -65,13 +146,11 @@ namespace ejdb { } bool close() { - if (m_jb) { - return ejdbclose(m_jb); - } + return m_jb ? ejdbclose(m_jb) : false; } const char* jb_error_msg() { - return m_jb ? ejdberrmsg(ejdbecode(m_jb)) : "unknown"; + return m_jb ? ejdberrmsg(ejdbecode(m_jb)) : "unknown error"; } public: @@ -104,12 +183,20 @@ namespace ejdb { //Misc NODE_DEFINE_CONSTANT(target, JBQRYCOUNT); + //Symbols + sym_close = NODE_PSYMBOL("close"); + sym_save = NODE_PSYMBOL("save"); + sym_load = NODE_PSYMBOL("load"); + sym_query = NODE_PSYMBOL("query"); + target->Set(v8::String::NewSymbol("NodeEJDB"), constructor_template->GetFunction()); + + NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", s_close); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "save", s_save); } void Ref() { ObjectWrap::Ref(); - } void Unref() { @@ -129,4 +216,4 @@ namespace ejdb { } // Register the module with node. -NODE_MODULE(ejdb_native, ejdb::Init);
\ No newline at end of file +NODE_MODULE(ejdb_native, ejdb::Init)
\ No newline at end of file diff --git a/node/package.json b/node/package.json index 8b34e36..979e83d 100644 --- a/node/package.json +++ b/node/package.json @@ -1,5 +1,5 @@ { "name": "ejdb", "version": "1.0.0", - "main": "./build/Release/ejdb" + "main": "./ejdb.js" }
\ No newline at end of file |