#1
authoradam <anton@adamansky.com>
Tue, 30 Oct 2012 11:45:25 +0000 (18:45 +0700)
committeradam <anton@adamansky.com>
Tue, 30 Oct 2012 11:45:25 +0000 (18:45 +0700)
node/binding.gyp
node/ejdb_native.cc
node/package.json
tcejdb/bson.c
tcejdb/bson.h
tcejdb/ejdb.h

index af7afc2..5e3b4db 100644 (file)
@@ -17,6 +17,8 @@
             '-g',
             '-O0',
             '-fPIC',
+            '-pedantic',
+            '-Wno-variadic-macros',
             '-D_GNU_SOURCE',
             '-D_FILE_OFFSET_BITS=64',
             '-D_LARGEFILE_SOURCE'
index e425399..5a34131 100644 (file)
@@ -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
index 8b34e36..979e83d 100644 (file)
@@ -1,5 +1,5 @@
 {
     "name": "ejdb",
     "version": "1.0.0",
-    "main": "./build/Release/ejdb"
+    "main": "./ejdb.js"
 }
\ No newline at end of file
index 96343a4..78d725c 100644 (file)
@@ -1099,19 +1099,19 @@ void bson_fatal_msg(int ok, const char *msg) {
 /* Efficiently copy an integer to a string. */
 extern const char bson_numstrs[1000][4];
 
-EJDB_EXPORT void bson_numstr(char *str, long long int i) {
+EJDB_EXPORT void bson_numstr(char *str, int64_t i) {
     if (i < 1000)
         memcpy(str, bson_numstrs[i], 4);
     else
-        bson_sprintf(str, "%lld", i);
+        bson_sprintf(str, "%lld", (long long int) i);
 }
 
-EJDB_EXPORT int bson_numstrn(char *str, int maxbuf, long long int i) {
+EJDB_EXPORT int bson_numstrn(char *str, int maxbuf, int64_t i) {
     if (i < 1000 && maxbuf > 4) {
         memcpy(str, bson_numstrs[i], 4);
         return strlen(bson_numstrs[i]);
     } else {
-        return snprintf(str, maxbuf, "%lld", i);
+        return snprintf(str, maxbuf, "%lld", (long long int) i);
     }
 }
 
index 2b0fb30..8a75c01 100644 (file)
@@ -941,8 +941,8 @@ EJDB_EXPORT int bson_append_finish_object(bson *b);
  */
 EJDB_EXPORT int bson_append_finish_array(bson *b);
 
-EJDB_EXPORT void bson_numstr(char *str, long long int i);
-EJDB_EXPORT int bson_numstrn(char *str, int maxbuf, long long int i);
+EJDB_EXPORT void bson_numstr(char *str, int64_t i);
+EJDB_EXPORT int bson_numstrn(char *str, int maxbuf, int64_t i);
 
 //void bson_incnumstr(char *str);
 
index 4669805..cdb1771 100644 (file)
@@ -62,7 +62,7 @@ enum { /** Index modes, index types. */
     JBIDXREBLD = 1 << 3, /**< Rebuild index. */
     JBIDXNUM = 1 << 4, /**< Number index. */
     JBIDXSTR = 1 << 5, /**< String index.*/
-    JBIDXARR = 1 << 6, /**< Array token index. */
+    JBIDXARR = 1 << 6 /**< Array token index. */
 };
 
 enum { /*< Query search mode flags in ejdbqrysearch() */