[Pkg-javascript-commits] [node-leveldown] 208/492: improve instantiation & open() API

Andrew Kelley andrewrk-guest at moszumanska.debian.org
Sun Jul 6 17:14:00 UTC 2014


This is an automated email from the git hooks/post-receive script.

andrewrk-guest pushed a commit to annotated tag rocksdb-0.10.1
in repository node-leveldown.

commit ff4005d236b02c1713ebc2aac23aaaf54674da6e
Author: Rod Vagg <rod at vagg.org>
Date:   Sat Feb 16 10:33:57 2013 +1100

    improve instantiation & open() API
    
    export single function
    more consistent with levelup
---
 index.js              |  2 +-
 package.json          |  7 ++--
 src/database.cc       | 98 +++++++++++++++++++++++++++++++++++----------------
 src/database.h        |  6 ++--
 src/database_async.cc |  4 +--
 src/database_async.h  |  2 --
 src/leveldown.cc      | 12 +++++--
 src/leveldown.h       | 65 ++++++++++++++++++++++++++++++++--
 8 files changed, 147 insertions(+), 49 deletions(-)

diff --git a/index.js b/index.js
index 4e1e557..9193802 100644
--- a/index.js
+++ b/index.js
@@ -1 +1 @@
-module.exports = require('bindings')('leveldown.node')
\ No newline at end of file
+module.exports = require('bindings')('leveldown.node').leveldown
\ No newline at end of file
diff --git a/package.json b/package.json
index e8f69c4..2def413 100644
--- a/package.json
+++ b/package.json
@@ -25,16 +25,15 @@
         "bindings"        : "~1.0.0"
     }
   , "devDependencies" : {
-        "buster"          : "*"
+        "tap"             : "*"
+      , "rimraf"          : "*"
     }
   , "repository"      : {
         "type"            : "git"
       , "url"             : "https://github.com/rvagg/node-leveldown.git"
     }
   , "scripts"         : {
-        "test"            : "buster-test"
-      , "functionaltests" : "node ./test/functional/fstream-test.js && node ./test/functional/binary-data-test.js && node ./test/functional/compat-test.js"
-      , "alltests"        : "npm test && npm run-script functionaltests"
+        "test"            : "tap test/*-test.js"
     }
   , "license"         : "MIT"
   , "gypfile"         : true
diff --git a/src/database.cc b/src/database.cc
index 81920aa..df793d3 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -1,6 +1,7 @@
 /* Copyright (c) 2012-2013 LevelDOWN contributors
  * See list at <https://github.com/rvagg/node-leveldown#contributing>
- * MIT +no-false-attribs License <https://github.com/rvagg/node-leveldown/blob/master/LICENSE>
+ * MIT +no-false-attribs License
+ * <https://github.com/rvagg/node-leveldown/blob/master/LICENSE>
  */
 
 #include <cstdlib>
@@ -24,7 +25,7 @@ using namespace v8;
 using namespace node;
 using namespace leveldb;
 
-Database::Database () {
+Database::Database (char* location) : location(location) {
   db = NULL;
 };
 
@@ -33,6 +34,8 @@ Database::~Database () {
     delete db;
 };
 
+const char* Database::Location() const { return location; }
+
 /* Calls from worker threads, NO V8 HERE *****************************/
 
 Status Database::OpenDatabase (Options* options, string location) {
@@ -43,7 +46,8 @@ Status Database::PutToDatabase (WriteOptions* options, Slice key, Slice value) {
   return db->Put(*options, key, value);
 }
 
-Status Database::GetFromDatabase (ReadOptions* options, Slice key, string& value) {
+Status Database::GetFromDatabase
+    (ReadOptions* options, Slice key, string& value) {
   return db->Get(*options, key, &value);
 }
 
@@ -51,7 +55,8 @@ Status Database::DeleteFromDatabase (WriteOptions* options, Slice key) {
   return db->Delete(*options, key);
 }
 
-Status Database::WriteBatchToDatabase (WriteOptions* options, WriteBatch* batch) {
+Status Database::WriteBatchToDatabase
+    (WriteOptions* options, WriteBatch* batch) {
   return db->Write(*options, batch);
 }
 
@@ -82,7 +87,7 @@ void Database::CloseDatabase () {
 
 Persistent<Function> Database::constructor;
 
-Handle<Value> CreateDatabase (const Arguments& args) {
+Handle<Value> LevelDOWN (const Arguments& args) {
   HandleScope scope;
   return scope.Close(Database::NewInstance(args));
 }
@@ -91,20 +96,37 @@ void Database::Init () {
   Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
   tpl->SetClassName(String::NewSymbol("Database"));
   tpl->InstanceTemplate()->SetInternalFieldCount(1);
-  tpl->PrototypeTemplate()->Set(String::NewSymbol("open")     , FunctionTemplate::New(Open)->GetFunction());
-  tpl->PrototypeTemplate()->Set(String::NewSymbol("close")    , FunctionTemplate::New(Close)->GetFunction());
-  tpl->PrototypeTemplate()->Set(String::NewSymbol("put")      , FunctionTemplate::New(Put)->GetFunction());
-  tpl->PrototypeTemplate()->Set(String::NewSymbol("get")      , FunctionTemplate::New(Get)->GetFunction());
-  tpl->PrototypeTemplate()->Set(String::NewSymbol("del")      , FunctionTemplate::New(Delete)->GetFunction());
-  tpl->PrototypeTemplate()->Set(String::NewSymbol("batch")    , FunctionTemplate::New(Batch)->GetFunction());
-  tpl->PrototypeTemplate()->Set(String::NewSymbol("approximateSize"), FunctionTemplate::New(ApproximateSize)->GetFunction());
+  tpl->PrototypeTemplate()->Set(String::NewSymbol("open")
+      , FunctionTemplate::New(Open)->GetFunction());
+  tpl->PrototypeTemplate()->Set(String::NewSymbol("close")
+      , FunctionTemplate::New(Close)->GetFunction());
+  tpl->PrototypeTemplate()->Set(String::NewSymbol("put")
+      , FunctionTemplate::New(Put)->GetFunction());
+  tpl->PrototypeTemplate()->Set(String::NewSymbol("get")
+      , FunctionTemplate::New(Get)->GetFunction());
+  tpl->PrototypeTemplate()->Set(String::NewSymbol("del")
+      , FunctionTemplate::New(Delete)->GetFunction());
+  tpl->PrototypeTemplate()->Set(String::NewSymbol("batch")
+      , FunctionTemplate::New(Batch)->GetFunction());
+  tpl->PrototypeTemplate()->Set(String::NewSymbol("approximateSize")
+      , FunctionTemplate::New(ApproximateSize)->GetFunction());
   constructor = Persistent<Function>::New(tpl->GetFunction());
 }
 
 Handle<Value> Database::New (const Arguments& args) {
   HandleScope scope;
 
-  Database* obj = new Database();
+  if (args.Length() == 0) {
+    THROW_RETURN("leveldown() requires at least a location argument")
+  }
+
+  if (!args[0]->IsString()) {
+    THROW_RETURN("leveldown() requires a location string argument")
+  }
+
+  FROM_V8_STRING(location, Handle<String>::Cast(args[0]))
+
+  Database* obj = new Database(location);
   obj->Wrap(args.This());
 
   return args.This();
@@ -113,8 +135,11 @@ Handle<Value> Database::New (const Arguments& args) {
 Handle<Value> Database::NewInstance (const Arguments& args) {
   HandleScope scope;
 
-  Handle<Value> argv[0];
-  Local<Object> instance = constructor->NewInstance(0, argv);
+  Handle<Value> argv[args.Length()];
+  for (int i = 0; i < args.Length(); i++)
+    argv[i] = args[i];
+
+  Local<Object> instance = constructor->NewInstance(args.Length(), argv);
 
   return scope.Close(instance);
 }
@@ -122,24 +147,22 @@ Handle<Value> Database::NewInstance (const Arguments& args) {
 Handle<Value> Database::Open (const Arguments& args) {
   HandleScope scope;
 
-  Database* database = ObjectWrap::Unwrap<Database>(args.This());
-  String::Utf8Value location(args[0]->ToString());
-  Local<Object> optionsObj = Local<Object>::Cast(args[1]);
-  BOOLEAN_OPTION_VALUE(optionsObj, createIfMissing)
+  METHOD_SETUP_COMMON(open, 0, 1)
+
+  BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, createIfMissing)
   BOOLEAN_OPTION_VALUE(optionsObj, errorIfExists)
   BOOLEAN_OPTION_VALUE(optionsObj, compression)
   UINT32_OPTION_VALUE(optionsObj, cacheSize, 8 << 20)
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
 
   OpenWorker* worker = new OpenWorker(
       database
     , callback
-    , *location
     , createIfMissing
     , errorIfExists
     , compression
     , cacheSize
   );
+
   AsyncQueueWorker(worker);
 
   return Undefined();
@@ -148,8 +171,7 @@ Handle<Value> Database::Open (const Arguments& args) {
 Handle<Value> Database::Close (const Arguments& args) {
   HandleScope scope;
 
-  Database* database = ObjectWrap::Unwrap<Database>(args.This());
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
+  METHOD_SETUP_COMMON_ONEARG(close)
 
   CloseWorker* worker = new CloseWorker(database, callback);
   AsyncQueueWorker(worker);
@@ -161,7 +183,8 @@ Handle<Value> Database::Put (const Arguments& args) {
   HandleScope scope;
 
   Database* database = ObjectWrap::Unwrap<Database>(args.This());
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[3]));
+  Persistent<Function> callback =
+      Persistent<Function>::New(Local<Function>::Cast(args[3]));
 
   CB_ERR_IF_NULL_OR_UNDEFINED(0, "Key")
   CB_ERR_IF_NULL_OR_UNDEFINED(1, "Value")
@@ -191,7 +214,8 @@ Handle<Value> Database::Get (const Arguments& args) {
   HandleScope scope;
 
   Database* database = ObjectWrap::Unwrap<Database>(args.This());
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
+  Persistent<Function> callback =
+      Persistent<Function>::New(Local<Function>::Cast(args[2]));
 
   CB_ERR_IF_NULL_OR_UNDEFINED(0, "Key")
 
@@ -218,7 +242,8 @@ Handle<Value> Database::Delete (const Arguments& args) {
   HandleScope scope;
 
   Database* database = ObjectWrap::Unwrap<Database>(args.This());
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
+  Persistent<Function> callback =
+      Persistent<Function>::New(Local<Function>::Cast(args[2]));
 
   CB_ERR_IF_NULL_OR_UNDEFINED(0, "Key")
 
@@ -246,7 +271,8 @@ Handle<Value> Database::Batch (const Arguments& args) {
   Local<Array> array = Local<Array>::Cast(args[0]);
   Local<Object> optionsObj = Local<Object>::Cast(args[1]);
   BOOLEAN_OPTION_VALUE(optionsObj, sync)
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
+  Persistent<Function> callback =
+      Persistent<Function>::New(Local<Function>::Cast(args[2]));
 
   vector<BatchOp*>* operations = new vector<BatchOp*>;
   for (unsigned int i = 0; i < array->Length(); i++) {
@@ -261,14 +287,23 @@ Handle<Value> Database::Batch (const Arguments& args) {
 
     if (obj->Get(str_type)->StrictEquals(str_del)) {
       STRING_OR_BUFFER_TO_SLICE(key, keyBuffer)
-      operations->push_back(new BatchDelete(key, Persistent<Value>::New(keyBuffer)));
-    } else if (obj->Get(str_type)->StrictEquals(str_put) && obj->Has(str_value)) {
+      operations->push_back(new BatchDelete(
+          key
+        , Persistent<Value>::New(keyBuffer)
+      ));
+    } else if (obj->Get(str_type)->StrictEquals(str_put)
+        && obj->Has(str_value)) {
       if (!obj->Has(str_value))
         continue;
       Local<Value> valueBuffer = obj->Get(str_value);
       STRING_OR_BUFFER_TO_SLICE(key, keyBuffer)
       STRING_OR_BUFFER_TO_SLICE(value, valueBuffer)
-      operations->push_back(new BatchWrite(key, value, Persistent<Value>::New(keyBuffer), Persistent<Value>::New(valueBuffer)));
+      operations->push_back(new BatchWrite(
+          key
+        , value
+        , Persistent<Value>::New(keyBuffer)
+        , Persistent<Value>::New(valueBuffer)
+      ));
     }
   }
 
@@ -286,7 +321,8 @@ Handle<Value> Database::ApproximateSize (const Arguments& args) {
   HandleScope scope;
 
   Database* database = ObjectWrap::Unwrap<Database>(args.This());
-  Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
+  Persistent<Function> callback =
+      Persistent<Function>::New(Local<Function>::Cast(args[2]));
 
   CB_ERR_IF_NULL_OR_UNDEFINED(0, "start")
   CB_ERR_IF_NULL_OR_UNDEFINED(1, "end")
diff --git a/src/database.h b/src/database.h
index c0c3e54..5383f6e 100644
--- a/src/database.h
+++ b/src/database.h
@@ -32,7 +32,7 @@ LU_STR    ( put   );
 
 struct AsyncDescriptor;
 
-Handle<Value> CreateDatabase (const Arguments& args);
+Handle<Value> LevelDOWN (const Arguments& args);
 
 class Database : public node::ObjectWrap {
 public:
@@ -49,12 +49,14 @@ public:
   const leveldb::Snapshot* NewSnapshot ();
   void ReleaseSnapshot (const leveldb::Snapshot* snapshot);
   void CloseDatabase ();
+  const char* Location() const;
 
 private:
-  Database ();
+  Database (char* location);
   ~Database ();
 
   DB* db;
+  char* location;
 
   static v8::Persistent<v8::Function> constructor;
 
diff --git a/src/database_async.cc b/src/database_async.cc
index 88f71dd..efeb950 100644
--- a/src/database_async.cc
+++ b/src/database_async.cc
@@ -26,13 +26,11 @@ using namespace leveldb;
 OpenWorker::OpenWorker (
     Database* database
   , Persistent<Function> callback
-  , string location
   , bool createIfMissing
   , bool errorIfExists
   , bool compression
   , uint32_t cacheSize
 ) : AsyncWorker(database, callback)
-  , location(location)
 {
   options = new Options();
   options->create_if_missing = createIfMissing;
@@ -46,7 +44,7 @@ OpenWorker::~OpenWorker () {
 }
 
 void OpenWorker::Execute () {
-  status = database->OpenDatabase(options, location);
+  status = database->OpenDatabase(options, database->Location());
 }
 
 /** CLOSE WORKER **/
diff --git a/src/database_async.h b/src/database_async.h
index 84b77cb..8f1b95f 100644
--- a/src/database_async.h
+++ b/src/database_async.h
@@ -22,7 +22,6 @@ public:
   OpenWorker (
       Database* database
     , Persistent<Function> callback
-    , string location
     , bool createIfMissing
     , bool errorIfExists
     , bool compression
@@ -33,7 +32,6 @@ public:
   virtual void Execute ();
 
 private:
-  string location;
   Options* options;
 };
 
diff --git a/src/leveldown.cc b/src/leveldown.cc
index 6adbb40..a8f78e5 100644
--- a/src/leveldown.cc
+++ b/src/leveldown.cc
@@ -17,15 +17,21 @@ void Init (Handle<Object> target) {
   Database::Init();
   leveldown::Iterator::Init();
 
-  target->Set(String::NewSymbol("createDatabase"), FunctionTemplate::New(CreateDatabase)->GetFunction());
-  target->Set(String::NewSymbol("createIterator"), FunctionTemplate::New(CreateIterator)->GetFunction());
+  target->Set(String::NewSymbol("leveldown")
+      , FunctionTemplate::New(LevelDOWN)->GetFunction());
+  target->Set(String::NewSymbol("createIterator")
+      , FunctionTemplate::New(CreateIterator)->GetFunction());
 }
 
 NODE_MODULE(leveldown, Init)
 
 // util
 
-void RunCallback (Persistent<Function> callback, Local<Value> argv[], int length) {
+void RunCallback (
+      Persistent<Function> callback
+    , Local<Value> argv[]
+    , int length) {
+
   TryCatch try_catch;
  
   callback->Call(Context::GetCurrent()->Global(), length, argv);
diff --git a/src/leveldown.h b/src/leveldown.h
index 0786d4a..1228e9d 100644
--- a/src/leveldown.h
+++ b/src/leveldown.h
@@ -24,6 +24,14 @@
     return Undefined(); \
   }
 
+#define FROM_V8_STRING(to, from) \
+  size_t to ## Sz_; \
+  char* to; \
+  Local<String> to ## Str = from->ToString(); \
+  to ## Sz_ = to ## Str->Utf8Length(); \
+  to = new char[to ## Sz_ + 1]; \
+  to ## Str->WriteUtf8(to, -1, NULL, String::NO_OPTIONS);
+
 #define STRING_OR_BUFFER_TO_SLICE(to, from) \
   size_t to ## Sz_; \
   char* to ## Ch_; \
@@ -39,11 +47,62 @@
   Slice to(to ## Ch_, to ## Sz_);
 
 #define BOOLEAN_OPTION_VALUE(optionsObj, opt) \
-  bool opt = optionsObj->Has(option_ ## opt) && optionsObj->Get(option_ ## opt)->BooleanValue();
+  bool opt = !optionsObj.IsEmpty() \
+    && optionsObj->Has(option_ ## opt) \
+    && optionsObj->Get(option_ ## opt)->BooleanValue();
+
 #define BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, opt) \
-  bool opt = !optionsObj->Has(option_ ## opt) || optionsObj->Get(option_ ## opt)->BooleanValue();
+  bool opt = optionsObj.IsEmpty() \
+    || !optionsObj->Has(option_ ## opt) \
+    || optionsObj->Get(option_ ## opt)->BooleanValue();
+
 #define UINT32_OPTION_VALUE(optionsObj, opt, default) \
-  uint32_t opt = optionsObj->Has(option_ ## opt) && optionsObj->Get(option_ ## opt)->IsUint32() ? optionsObj->Get(option_ ## opt)->Uint32Value() : default;
+  uint32_t opt = !optionsObj.IsEmpty() \
+    && optionsObj->Has(option_ ## opt) \
+    && optionsObj->Get(option_ ## opt)->IsUint32() \
+      ? optionsObj->Get(option_ ## opt)->Uint32Value() \
+      : default;
+
+#define RUN_CALLBACK(callback, length, argv) \
+  TryCatch try_catch; \
+  callback->Call(Context::GetCurrent()->Global(), length, argv); \
+  if (try_catch.HasCaught()) { \
+    FatalException(try_catch); \
+  }
+
+#define THROW_RETURN(msg) \
+  ThrowException(Exception::Error(String::New(#msg))); \
+  return Undefined();
+
+/* METHOD_SETUP_COMMON setup the following objects:
+ *  - Database* database
+ *  - Local<Object> optionsObj (may be empty)
+ *  - Persistent<Function> callback (won't be empty)
+ * Will THROW_RETURN if there isn't a callback in arg 0 or 1
+ */
+#define METHOD_SETUP_COMMON(name, optionPos, callbackPos) \
+  if (args.Length() == 0) { \
+    THROW_RETURN(name() requires a callback argument 2) \
+  } \
+  Database* database = ObjectWrap::Unwrap<Database>(args.This()); \
+  Local<Object> optionsObj; \
+  Persistent<Function> callback; \
+  if (optionPos == -1) { \
+    callback = Persistent<Function>::New(Local<Function>::Cast(args[callbackPos])); \
+  } else if (args[callbackPos - 1]->IsFunction()) { \
+    callback = Persistent<Function>::New(Local<Function>::Cast(args[callbackPos - 1])); \
+  } else if (args[optionPos]->IsObject()) { \
+    optionsObj = Local<Object>::Cast(args[optionPos]); \
+    callback = Persistent<Function>::New(Local<Function>::Cast(args[callbackPos])); \
+  } else { \
+    THROW_RETURN(name() requires a callback argument 3) \
+  }
+
+#define METHOD_SETUP_COMMON_ONEARG(name) \
+  if (!args[0]->IsFunction()) { \
+    THROW_RETURN(name() requires a callback argument 1) \
+  } \
+  METHOD_SETUP_COMMON(name, -1, 0)
 
 void RunCallback (v8::Persistent<v8::Function> callback, v8::Local<v8::Value> argv[], int length);
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-leveldown.git



More information about the Pkg-javascript-commits mailing list