summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authoradam <anton@adamansky.com>2012-10-30 18:45:25 +0700
committeradam <anton@adamansky.com>2012-10-30 18:45:25 +0700
commita60880266cd8b6f06bd8f67fdeded0326681beaa (patch)
tree1c2b05a91c6abef75f99f56ccce73aa11b06d33b /node
parent2fcd4c6df35d8b3c5f84d291c3ba9fbd8556a031 (diff)
downloadejdb-a60880266cd8b6f06bd8f67fdeded0326681beaa.tar.gz
ejdb-a60880266cd8b6f06bd8f67fdeded0326681beaa.tar.bz2
ejdb-a60880266cd8b6f06bd8f67fdeded0326681beaa.zip
#1
Diffstat (limited to 'node')
-rw-r--r--node/binding.gyp2
-rw-r--r--node/ejdb_native.cc111
-rw-r--r--node/package.json2
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