[Pkg-javascript-commits] [node-leveldown] 370/492: initial 0.11 compatibility attempt, using NAN
Andrew Kelley
andrewrk-guest at moszumanska.debian.org
Sun Jul 6 17:14:18 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 d4ed0d6a6237a4d9f0a485bf9cdc8634cbf6abed
Author: Rod Vagg <rod at vagg.org>
Date: Sat Jul 20 21:14:25 2013 +1000
initial 0.11 compatibility attempt, using NAN
---
binding.gyp | 3 +-
src/async.cc | 73 ----------
src/async.h | 31 ++--
src/batch.cc | 128 ++++++----------
src/batch.h | 14 +-
src/batch_async.cc | 4 +-
src/batch_async.h | 3 +-
src/database.cc | 387 +++++++++++++++++++++----------------------------
src/database.h | 61 ++++----
src/database_async.cc | 107 +++++++-------
src/database_async.h | 54 ++++---
src/iterator.cc | 149 ++++++++++---------
src/iterator.h | 33 ++---
src/iterator_async.cc | 19 ++-
src/iterator_async.h | 5 +-
src/leveldown.cc | 52 +++----
src/leveldown.h | 118 +++------------
src/leveldown_async.cc | 8 +-
src/leveldown_async.h | 4 +-
src/nan.h | 1 +
20 files changed, 499 insertions(+), 755 deletions(-)
diff --git a/binding.gyp b/binding.gyp
index 6c20da5..ddbd534 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -20,8 +20,7 @@
"<(module_root_dir)/deps/leveldb/leveldb.gyp:leveldb"
]
, "sources": [
- "src/async.cc"
- , "src/batch.cc"
+ "src/batch.cc"
, "src/batch_async.cc"
, "src/database.cc"
, "src/database_async.cc"
diff --git a/src/async.cc b/src/async.cc
deleted file mode 100644
index 45c90c5..0000000
--- a/src/async.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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>
- */
-
-#include <node.h>
-
-#include "database.h"
-#include "leveldown.h"
-#include "async.h"
-
-namespace leveldown {
-
-/** ASYNC BASE **/
-
-AsyncWorker::AsyncWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
-) : database(database)
- , callback(callback)
-{
- request.data = this;
-};
-
-AsyncWorker::~AsyncWorker () {}
-
-void AsyncWorker::WorkComplete () {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
-
- if (status.ok())
- HandleOKCallback();
- else
- HandleErrorCallback();
- callback.Dispose(LD_NODE_ISOLATE);
-}
-
-void AsyncWorker::HandleOKCallback () {
- LD_RUN_CALLBACK(callback, NULL, 0);
-}
-
-void AsyncWorker::HandleErrorCallback () {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
-
- v8::Local<v8::Value> argv[] = {
- v8::Local<v8::Value>::New(
- v8::Exception::Error(v8::String::New(status.ToString().c_str()))
- )
- };
- LD_RUN_CALLBACK(callback, argv, 1);
-}
-
-void AsyncExecute (uv_work_t* req) {
- static_cast<AsyncWorker*>(req->data)->Execute();
-}
-
-void AsyncExecuteComplete (uv_work_t* req) {
- AsyncWorker* worker = static_cast<AsyncWorker*>(req->data);
- worker->WorkComplete();
- delete worker;
-}
-
-void AsyncQueueWorker (AsyncWorker* worker) {
- uv_queue_work(
- uv_default_loop()
- , &worker->request
- , AsyncExecute
- , (uv_after_work_cb)AsyncExecuteComplete
- );
-}
-
-} // namespace leveldown
diff --git a/src/async.h b/src/async.h
index dc1b1e6..64646df 100644
--- a/src/async.h
+++ b/src/async.h
@@ -7,34 +7,35 @@
#define LD_ASYNC_H
#include <node.h>
+#include "nan.h"
#include "database.h"
namespace leveldown {
-/* abstract */ class AsyncWorker {
+class Database;
+
+/* abstract */ class AsyncWorker : public NanAsyncWorker {
public:
AsyncWorker (
leveldown::Database* database
- , v8::Persistent<v8::Function> callback
- );
-
- virtual ~AsyncWorker ();
- uv_work_t request;
- virtual void WorkComplete ();
- virtual void Execute () =0;
+ , NanCallback *callback
+ ) : NanAsyncWorker(callback), database(database) {
+ NanScope();
+ v8::Local<v8::Object> obj = v8::Object::New();
+ NanAssignPersistent(v8::Object, persistentHandle, obj);
+ }
protected:
+ void SetStatus(leveldb::Status status) {
+ this->status = status;
+ if (!status.ok())
+ this->errmsg = status.ToString().c_str();
+ }
Database* database;
- v8::Persistent<v8::Function> callback;
+private:
leveldb::Status status;
- virtual void HandleOKCallback ();
- virtual void HandleErrorCallback ();
};
-void AsyncExecute (uv_work_t* req);
-void AsyncExecuteComplete (uv_work_t* req);
-void AsyncQueueWorker (AsyncWorker* worker);
-
} // namespace leveldown
#endif
diff --git a/src/batch.cc b/src/batch.cc
index 3e68a52..695dcb1 100644
--- a/src/batch.cc
+++ b/src/batch.cc
@@ -1,19 +1,21 @@
#include <node.h>
#include <node_buffer.h>
+
+#include "nan.h"
#include "database.h"
#include "batch_async.h"
#include "batch.h"
namespace leveldown {
-v8::Persistent<v8::Function> Batch::constructor;
+static v8::Persistent<v8::FunctionTemplate> batch_constructor;
Batch::Batch (leveldown::Database* database, bool sync) : database(database) {
options = new leveldb::WriteOptions();
options->sync = sync;
batch = new leveldb::WriteBatch();
- references = new std::vector<Reference>;
+ references = new std::vector<Reference *>;
hasData = false;
written = false;
}
@@ -29,34 +31,18 @@ leveldb::Status Batch::Write () {
}
void Batch::Init () {
- LD_NODE_ISOLATE_DECL
v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(Batch::New);
- tpl->SetClassName(v8::String::NewSymbol("Batch"));
+ NanAssignPersistent(v8::FunctionTemplate, batch_constructor, tpl);
+ tpl->SetClassName(NanSymbol("Batch"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("put")
- , v8::FunctionTemplate::New(Batch::Put)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("del")
- , v8::FunctionTemplate::New(Batch::Del)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("clear")
- , v8::FunctionTemplate::New(Batch::Clear)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("write")
- , v8::FunctionTemplate::New(Batch::Write)->GetFunction()
- );
- constructor = v8::Persistent<v8::Function>::New(
- LD_NODE_ISOLATE_PRE
- tpl->GetFunction());
+ NODE_SET_PROTOTYPE_METHOD(tpl, "put", Batch::Put);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "del", Batch::Del);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "clear", Batch::Clear);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "write", Batch::Write);
}
-v8::Handle<v8::Value> Batch::New (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Batch::New) {
+ NanScope();
Database* database = node::ObjectWrap::Unwrap<Database>(args[0]->ToObject());
v8::Local<v8::Object> optionsObj;
@@ -65,12 +51,12 @@ v8::Handle<v8::Value> Batch::New (const v8::Arguments& args) {
optionsObj = v8::Local<v8::Object>::Cast(args[1]);
}
- bool sync = BooleanOptionValue(optionsObj, option_sync);
+ bool sync = NanBooleanOptionValue(optionsObj, NanSymbol("sync"));
Batch* batch = new Batch(database, sync);
batch->Wrap(args.This());
- return args.This();
+ NanReturnValue(args.This());
}
v8::Handle<v8::Value> Batch::NewInstance (
@@ -78,31 +64,31 @@ v8::Handle<v8::Value> Batch::NewInstance (
, v8::Handle<v8::Object> optionsObj
) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+ NanScope();
v8::Local<v8::Object> instance;
+ v8::Local<v8::FunctionTemplate> constructorHandle =
+ NanPersistentToLocal(batch_constructor);
+
if (optionsObj.IsEmpty()) {
v8::Handle<v8::Value> argv[1] = { database };
- instance = constructor->NewInstance(1, argv);
+ instance = constructorHandle->GetFunction()->NewInstance(1, argv);
} else {
v8::Handle<v8::Value> argv[2] = { database, optionsObj };
- instance = constructor->NewInstance(2, argv);
+ instance = constructorHandle->GetFunction()->NewInstance(2, argv);
}
return scope.Close(instance);
}
-v8::Handle<v8::Value> Batch::Put (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Batch::Put) {
+ NanScope();
Batch* batch = ObjectWrap::Unwrap<Batch>(args.Holder());
- if (batch->written) {
- LD_THROW_RETURN(write() already called on this batch)
- }
+ if (batch->written)
+ return NanThrowError("write() already called on this batch");
v8::Handle<v8::Function> callback; // purely for the error macros
@@ -114,31 +100,23 @@ v8::Handle<v8::Value> Batch::Put (const v8::Arguments& args) {
LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
LD_STRING_OR_BUFFER_TO_SLICE(value, valueBuffer, value)
- batch->references->push_back(Reference(
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBuffer)
- , key
- ));
- batch->references->push_back(Reference(
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE valueBuffer)
- , value
- ));
+ batch->references->push_back(new Reference(keyBuffer, key));
+ batch->references->push_back(new Reference(valueBuffer, value));
batch->batch->Put(key, value);
if (!batch->hasData)
batch->hasData = true;
- return scope.Close(args.Holder());
+ NanReturnValue(args.Holder());
}
-v8::Handle<v8::Value> Batch::Del (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Batch::Del) {
+ NanScope();
Batch* batch = ObjectWrap::Unwrap<Batch>(args.Holder());
- if (batch->written) {
- LD_THROW_RETURN(write() already called on this batch)
- }
+ if (batch->written)
+ return NanThrowError("write() already called on this batch");
v8::Handle<v8::Function> callback; // purely for the error macros
@@ -147,62 +125,52 @@ v8::Handle<v8::Value> Batch::Del (const v8::Arguments& args) {
v8::Local<v8::Value> keyBuffer = args[0];
LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
- batch->references->push_back(Reference(
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBuffer)
- , key
- ));
+ batch->references->push_back(new Reference(keyBuffer, key));
batch->batch->Delete(key);
if (!batch->hasData)
batch->hasData = true;
- return scope.Close(args.Holder());
+ NanReturnValue(args.Holder());
}
-v8::Handle<v8::Value> Batch::Clear (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Batch::Clear) {
+ NanScope();
Batch* batch = ObjectWrap::Unwrap<Batch>(args.Holder());
- if (batch->written) {
- LD_THROW_RETURN(write() already called on this batch)
- }
+ if (batch->written)
+ return NanThrowError("write() already called on this batch");
batch->batch->Clear();
batch->hasData = false;
- return scope.Close(args.Holder());
+ NanReturnValue(args.Holder());
}
-v8::Handle<v8::Value> Batch::Write (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Batch::Write) {
+ NanScope();
Batch* batch = ObjectWrap::Unwrap<Batch>(args.Holder());
- if (batch->written) {
- LD_THROW_RETURN(write() already called on this batch)
- }
+ if (batch->written)
+ return NanThrowError("write() already called on this batch");
- if (args.Length() == 0) {
- LD_THROW_RETURN(write() requires a callback argument)
- }
+ if (args.Length() == 0)
+ return NanThrowError("write() requires a callback argument");
batch->written = true;
if (batch->hasData) {
- v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New(
- LD_NODE_ISOLATE_PRE
- v8::Local<v8::Function>::Cast(args[0]));
-
+ NanCallback *callback =
+ new NanCallback(v8::Local<v8::Function>::Cast(args[0]));
BatchWriteWorker* worker = new BatchWriteWorker(batch, callback);
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
} else {
LD_RUN_CALLBACK(v8::Local<v8::Function>::Cast(args[0]), NULL, 0);
}
- return v8::Undefined();
+ NanReturnUndefined();
}
} // namespace leveldown
diff --git a/src/batch.h b/src/batch.h
index 31f1f04..7716d88 100644
--- a/src/batch.h
+++ b/src/batch.h
@@ -26,17 +26,15 @@ private:
leveldown::Database* database;
leveldb::WriteOptions* options;
leveldb::WriteBatch* batch;
- std::vector<Reference>* references;
+ std::vector<Reference *>* references;
bool hasData; // keep track of whether we're writing data or not
bool written;
- static v8::Persistent<v8::Function> constructor;
-
- LD_V8_METHOD( New )
- LD_V8_METHOD( Put )
- LD_V8_METHOD( Del )
- LD_V8_METHOD( Clear )
- LD_V8_METHOD( Write )
+ static NAN_METHOD(New);
+ static NAN_METHOD(Put);
+ static NAN_METHOD(Del);
+ static NAN_METHOD(Clear);
+ static NAN_METHOD(Write);
};
} // namespace leveldown
diff --git a/src/batch_async.cc b/src/batch_async.cc
index 93f34e1..4ff256c 100644
--- a/src/batch_async.cc
+++ b/src/batch_async.cc
@@ -14,7 +14,7 @@ namespace leveldown {
BatchWriteWorker::BatchWriteWorker (
Batch* batch
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
) : AsyncWorker(NULL, callback)
, batch(batch)
{};
@@ -22,7 +22,7 @@ BatchWriteWorker::BatchWriteWorker (
BatchWriteWorker::~BatchWriteWorker () {}
void BatchWriteWorker::Execute () {
- status = batch->Write();
+ SetStatus(batch->Write());
}
} // namespace leveldown
diff --git a/src/batch_async.h b/src/batch_async.h
index 46e459b..05fb4ad 100644
--- a/src/batch_async.h
+++ b/src/batch_async.h
@@ -8,6 +8,7 @@
#include <node.h>
+#include "nan.h"
#include "async.h"
#include "batch.h"
#include "database.h"
@@ -18,7 +19,7 @@ class BatchWriteWorker : public AsyncWorker {
public:
BatchWriteWorker (
Batch* batch
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
);
virtual ~BatchWriteWorker ();
diff --git a/src/database.cc b/src/database.cc
index 7f0bd10..8424048 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -19,6 +19,8 @@
namespace leveldown {
+static v8::Persistent<v8::FunctionTemplate> database_constructor;
+
Database::Database (char* location) : location(location) {
db = NULL;
currentIteratorId = 0;
@@ -105,7 +107,7 @@ void Database::ReleaseIterator (uint32_t id) {
// iterators to end before we can close them
iterators.erase(id);
if (iterators.size() == 0 && pendingCloseWorker != NULL) {
- AsyncQueueWorker((AsyncWorker*)pendingCloseWorker);
+ NanAsyncQueueWorker((AsyncWorker*)pendingCloseWorker);
pendingCloseWorker = NULL;
}
}
@@ -117,139 +119,109 @@ void Database::CloseDatabase () {
/* V8 exposed functions *****************************/
-v8::Persistent<v8::Function> Database::constructor;
-
-v8::Handle<v8::Value> LevelDOWN (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(LevelDOWN) {
+ NanScope();
- return scope.Close(Database::NewInstance(args));
+ v8::Local<v8::String> location;
+ if (args.Length() != 0 && args[0]->IsString())
+ location = args[0].As<v8::String>();
+ NanReturnValue(Database::NewInstance(location));
}
void Database::Init () {
- LD_NODE_ISOLATE_DECL
- v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(New);
- tpl->SetClassName(v8::String::NewSymbol("Database"));
+ v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(Database::New);
+ NanAssignPersistent(v8::FunctionTemplate, database_constructor, tpl);
+ tpl->SetClassName(NanSymbol("Database"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("open")
- , v8::FunctionTemplate::New(Open)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("close")
- , v8::FunctionTemplate::New(Close)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("put")
- , v8::FunctionTemplate::New(Put)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("get")
- , v8::FunctionTemplate::New(Get)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("del")
- , v8::FunctionTemplate::New(Delete)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("batch")
- , v8::FunctionTemplate::New(Batch)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("approximateSize")
- , v8::FunctionTemplate::New(ApproximateSize)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("getProperty")
- , v8::FunctionTemplate::New(GetProperty)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("iterator")
- , v8::FunctionTemplate::New(Iterator)->GetFunction()
- );
- constructor = v8::Persistent<v8::Function>::New(
- LD_NODE_ISOLATE_PRE
- tpl->GetFunction());
+ NODE_SET_PROTOTYPE_METHOD(tpl, "open", Database::Open);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "close", Database::Close);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "put", Database::Put);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "get", Database::Get);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "del", Database::Delete);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "batch", Database::Batch);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "approximateSize", Database::ApproximateSize);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "getProperty", Database::GetProperty);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "iterator", Database::Iterator);
}
-v8::Handle<v8::Value> Database::New (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::New) {
+ NanScope();
- if (args.Length() == 0) {
- LD_THROW_RETURN(constructor requires at least a location argument)
- }
+ if (args.Length() == 0)
+ return NanThrowError("constructor requires at least a location argument");
- if (!args[0]->IsString()) {
- LD_THROW_RETURN(constructor requires a location string argument)
- }
+ if (!args[0]->IsString())
+ return NanThrowError("constructor requires a location string argument");
- char* location = FromV8String(args[0]);
+ char* location = NanFromV8String(args[0]);
Database* obj = new Database(location);
obj->Wrap(args.This());
- return args.This();
+ NanReturnValue(args.This());
}
-v8::Handle<v8::Value> Database::NewInstance (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+v8::Handle<v8::Value> Database::NewInstance (v8::Local<v8::String> &location) {
+ NanScope();
v8::Local<v8::Object> instance;
- if (args.Length() == 0) {
- instance = constructor->NewInstance(0, NULL);
+ v8::Local<v8::FunctionTemplate> constructorHandle =
+ NanPersistentToLocal(database_constructor);
+
+ if (location.IsEmpty()) {
+ instance = constructorHandle->GetFunction()->NewInstance(0, NULL);
} else {
- v8::Handle<v8::Value> argv[] = { args[0] };
- instance = constructor->NewInstance(1, argv);
+ v8::Handle<v8::Value> argv[] = { location };
+ instance = constructorHandle->GetFunction()->NewInstance(1, argv);
}
- return scope.Close(instance);
+ return instance;
}
-v8::Handle<v8::Value> Database::Open (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::Open) {
+ NanScope();
LD_METHOD_SETUP_COMMON(open, 0, 1)
- bool createIfMissing = BooleanOptionValueDefTrue(
+ bool createIfMissing = NanBooleanOptionValue(
optionsObj
- , option_createIfMissing
+ , NanSymbol("createIfMissing")
+ , true
);
- bool errorIfExists = BooleanOptionValue(optionsObj, option_errorIfExists);
- bool compression = BooleanOptionValue(optionsObj, option_compression);
+ bool errorIfExists =
+ NanBooleanOptionValue(optionsObj, NanSymbol("errorIfExists"));
+ bool compression = NanBooleanOptionValue(optionsObj, NanSymbol("compression"));
- uint32_t cacheSize = UInt32OptionValue(
+ uint32_t cacheSize = NanUInt32OptionValue(
optionsObj
- , option_cacheSize
+ , NanSymbol("cacheSize")
, 8 << 20
);
- uint32_t writeBufferSize = UInt32OptionValue(
+ uint32_t writeBufferSize = NanUInt32OptionValue(
optionsObj
- , option_writeBufferSize
+ , NanSymbol("writeBufferSize")
, 4 << 20
);
- uint32_t blockSize = UInt32OptionValue(
+ uint32_t blockSize = NanUInt32OptionValue(
optionsObj
- , option_blockSize
+ , NanSymbol("blockSize")
, 4096
);
- uint32_t maxOpenFiles = UInt32OptionValue(
+ uint32_t maxOpenFiles = NanUInt32OptionValue(
optionsObj
- , option_maxOpenFiles
+ , NanSymbol("maxOpenFiles")
, 1000
);
- uint32_t blockRestartInterval = UInt32OptionValue(
+ uint32_t blockRestartInterval = NanUInt32OptionValue(
optionsObj
- , option_blockRestartInterval
+ , NanSymbol("blockRestartInterval")
, 16
);
OpenWorker* worker = new OpenWorker(
database
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
, createIfMissing
, errorIfExists
, compression
@@ -260,20 +232,19 @@ v8::Handle<v8::Value> Database::Open (const v8::Arguments& args) {
, blockRestartInterval
);
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
- return v8::Undefined();
+ NanReturnUndefined();
}
-v8::Handle<v8::Value> Database::Close (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::Close) {
+ NanScope();
LD_METHOD_SETUP_COMMON_ONEARG(close)
CloseWorker* worker = new CloseWorker(
database
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
);
if (database->iterators.size() > 0) {
@@ -283,7 +254,7 @@ v8::Handle<v8::Value> Database::Close (const v8::Arguments& args) {
database->pendingCloseWorker = worker;
for (
- std::map< uint32_t, v8::Persistent<v8::Object> >::iterator it
+ std::map< uint32_t, leveldown::Iterator * >::iterator it
= database->iterators.begin()
; it != database->iterators.end()
; ++it) {
@@ -294,150 +265,132 @@ v8::Handle<v8::Value> Database::Close (const v8::Arguments& args) {
// function and wait for it to hit ReleaseIterator() where our
// CloseWorker will be invoked
+ /*
+ v8::Local<v8::Object> localHandle = NanPersistentToLocal(it->second);
leveldown::Iterator* iterator =
- node::ObjectWrap::Unwrap<leveldown::Iterator>(it->second);
+ node::ObjectWrap::Unwrap<leveldown::Iterator>(localHandle->
+ Get(NanSymbol("iterator")).As<v8::Object>());
+ */
+ leveldown::Iterator *iterator = it->second;
if (!iterator->ended) {
v8::Local<v8::Function> end =
- v8::Local<v8::Function>::Cast(it->second->Get(
+ v8::Local<v8::Function>::Cast(NanObjectWrapHandle(iterator)->Get(
v8::String::NewSymbol("end")));
v8::Local<v8::Value> argv[] = {
v8::FunctionTemplate::New()->GetFunction() // empty callback
};
v8::TryCatch try_catch;
- end->Call(it->second, 1, argv);
+ end->Call(NanObjectWrapHandle(iterator), 1, argv);
if (try_catch.HasCaught()) {
node::FatalException(try_catch);
}
}
}
} else {
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
}
- return v8::Undefined();
+ NanReturnUndefined();
}
-v8::Handle<v8::Value> Database::Put (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::Put) {
+ NanScope();
LD_METHOD_SETUP_COMMON(put, 2, 3)
LD_CB_ERR_IF_NULL_OR_UNDEFINED(args[0], key)
LD_CB_ERR_IF_NULL_OR_UNDEFINED(args[1], value)
- v8::Local<v8::Value> keyBufferV = args[0];
- v8::Local<v8::Value> valueBufferV = args[1];
- LD_STRING_OR_BUFFER_TO_SLICE(key, keyBufferV, key)
- LD_STRING_OR_BUFFER_TO_SLICE(value, valueBufferV, value)
-
- v8::Persistent<v8::Value> keyBuffer =
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBufferV);
- v8::Persistent<v8::Value> valueBuffer =
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE valueBufferV);
+ v8::Local<v8::Object> keyHandle = args[0].As<v8::Object>();
+ v8::Local<v8::Object> valueHandle = args[1].As<v8::Object>();
+ LD_STRING_OR_BUFFER_TO_SLICE(key, keyHandle, key)
+ LD_STRING_OR_BUFFER_TO_SLICE(value, valueHandle, value)
- bool sync = BooleanOptionValue(optionsObj, option_sync);
+ bool sync = NanBooleanOptionValue(optionsObj, NanSymbol("sync"));
WriteWorker* worker = new WriteWorker(
database
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
, key
, value
, sync
- , keyBuffer
- , valueBuffer
+ , keyHandle
+ , valueHandle
);
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
- return v8::Undefined();
+ NanReturnUndefined();
}
-v8::Handle<v8::Value> Database::Get (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::Get) {
+ NanScope();
LD_METHOD_SETUP_COMMON(get, 1, 2)
LD_CB_ERR_IF_NULL_OR_UNDEFINED(args[0], key)
- v8::Local<v8::Value> keyBufferV = args[0];
- LD_STRING_OR_BUFFER_TO_SLICE(key, keyBufferV, key)
+ v8::Local<v8::Object> keyHandle = args[0].As<v8::Object>();
+ LD_STRING_OR_BUFFER_TO_SLICE(key, keyHandle, key)
- v8::Persistent<v8::Value> keyBuffer = v8::Persistent<v8::Value>::New(
- LD_NODE_ISOLATE_PRE
- keyBufferV);
-
- bool asBuffer = BooleanOptionValueDefTrue(optionsObj, option_asBuffer);
- bool fillCache = BooleanOptionValueDefTrue(optionsObj, option_fillCache);
+ bool asBuffer = NanBooleanOptionValue(optionsObj, NanSymbol("asBuffer"), true);
+ bool fillCache = NanBooleanOptionValue(optionsObj, NanSymbol("fillCache"), true);
ReadWorker* worker = new ReadWorker(
database
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
, key
, asBuffer
, fillCache
- , keyBuffer
+ , keyHandle
);
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
- return v8::Undefined();
+ NanReturnUndefined();
}
-v8::Handle<v8::Value> Database::Delete (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::Delete) {
+ NanScope();
LD_METHOD_SETUP_COMMON(del, 1, 2)
LD_CB_ERR_IF_NULL_OR_UNDEFINED(args[0], key)
- v8::Local<v8::Value> keyBufferV = args[0];
- LD_STRING_OR_BUFFER_TO_SLICE(key, keyBufferV, key)
-
- v8::Persistent<v8::Value> keyBuffer =
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBufferV);
+ v8::Local<v8::Object> keyHandle = args[0].As<v8::Object>();
+ LD_STRING_OR_BUFFER_TO_SLICE(key, keyHandle, key)
- bool sync = BooleanOptionValue(optionsObj, option_sync);
+ bool sync = NanBooleanOptionValue(optionsObj, NanSymbol("sync"));
DeleteWorker* worker = new DeleteWorker(
database
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
, key
, sync
- , keyBuffer
+ , keyHandle
);
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
- return v8::Undefined();
+ NanReturnUndefined();
}
-/* property key & value strings for elements of the array sent to batch() */
-LD_SYMBOL ( str_key , key );
-LD_SYMBOL ( str_value , value );
-LD_SYMBOL ( str_type , type );
-LD_SYMBOL ( str_del , del );
-LD_SYMBOL ( str_put , put );
-
-v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::Batch) {
+ NanScope();
if ((args.Length() == 0 || args.Length() == 1) && !args[0]->IsArray()) {
v8::Local<v8::Object> optionsObj;
if (args.Length() > 0 && args[0]->IsObject()) {
- optionsObj = v8::Local<v8::Object>::Cast(args[0]);
+ optionsObj = args[0].As<v8::Object>();
}
- return scope.Close(Batch::NewInstance(args.This(), optionsObj));
+ NanReturnValue(Batch::NewInstance(args.This(), optionsObj));
}
LD_METHOD_SETUP_COMMON(batch, 1, 2)
- bool sync = BooleanOptionValue(optionsObj, option_sync);
+ bool sync = NanBooleanOptionValue(optionsObj, NanSymbol("sync"));
v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[0]);
- std::vector< Reference >* references = new std::vector< Reference >;
+ std::vector< Reference *>* references = new std::vector< Reference *>;
leveldb::WriteBatch* batch = new leveldb::WriteBatch();
bool hasData = false;
@@ -447,24 +400,21 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(array->Get(i));
- LD_CB_ERR_IF_NULL_OR_UNDEFINED(obj->Get(str_type), type)
+ LD_CB_ERR_IF_NULL_OR_UNDEFINED(obj->Get(NanSymbol("type")), type)
- v8::Local<v8::Value> keyBuffer = obj->Get(str_key);
+ v8::Local<v8::Value> keyBuffer = obj->Get(NanSymbol("key"));
LD_CB_ERR_IF_NULL_OR_UNDEFINED(keyBuffer, key)
- if (obj->Get(str_type)->StrictEquals(str_del)) {
+ if (obj->Get(NanSymbol("type"))->StrictEquals(NanSymbol("del"))) {
LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
batch->Delete(key);
if (!hasData)
hasData = true;
- references->push_back(Reference(
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBuffer)
- , key
- ));
- } else if (obj->Get(str_type)->StrictEquals(str_put)) {
- v8::Local<v8::Value> valueBuffer = obj->Get(str_value);
+ references->push_back(new Reference(keyBuffer, key));
+ } else if (obj->Get(NanSymbol("type"))->StrictEquals(NanSymbol("put"))) {
+ v8::Local<v8::Value> valueBuffer = obj->Get(NanSymbol("value"));
LD_CB_ERR_IF_NULL_OR_UNDEFINED(valueBuffer, value)
LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
@@ -474,22 +424,16 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
if (!hasData)
hasData = true;
- references->push_back(Reference(
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE keyBuffer)
- , key
- ));
- references->push_back(Reference(
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE valueBuffer)
- , value
- ));
+ references->push_back(new Reference(keyBuffer, key));
+ references->push_back(new Reference(valueBuffer, value));
}
}
// don't allow an empty batch through
if (hasData) {
- AsyncQueueWorker(new BatchWorker(
+ NanAsyncQueueWorker(new BatchWorker(
database
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
, batch
, references
, sync
@@ -499,24 +443,23 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
LD_RUN_CALLBACK(callback, NULL, 0);
}
- return v8::Undefined();
+ NanReturnUndefined();
}
-v8::Handle<v8::Value> Database::ApproximateSize (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::ApproximateSize) {
+ NanScope();
- v8::Local<v8::Value> startBufferV = args[0];
- v8::Local<v8::Value> endBufferV = args[1];
+ v8::Local<v8::Object> startHandle = args[0].As<v8::Object>();
+ v8::Local<v8::Object> endHandle = args[1].As<v8::Object>();
- if (startBufferV->IsNull()
- || startBufferV->IsUndefined()
- || startBufferV->IsFunction() // callback in pos 0?
- || endBufferV->IsNull()
- || endBufferV->IsUndefined()
- || endBufferV->IsFunction() // callback in pos 1?
+ if (startHandle->IsNull()
+ || startHandle->IsUndefined()
+ || startHandle->IsFunction() // callback in pos 0?
+ || endHandle->IsNull()
+ || endHandle->IsUndefined()
+ || endHandle->IsFunction() // callback in pos 1?
) {
- LD_THROW_RETURN(approximateSize() requires valid `start`, `end` and `callback` arguments)
+ return NanThrowError("approximateSize() requires valid `start`, `end` and `callback` arguments");
}
LD_METHOD_SETUP_COMMON(approximateSize, -1, 2)
@@ -524,41 +467,34 @@ v8::Handle<v8::Value> Database::ApproximateSize (const v8::Arguments& args) {
LD_CB_ERR_IF_NULL_OR_UNDEFINED(args[0], start)
LD_CB_ERR_IF_NULL_OR_UNDEFINED(args[1], end)
- LD_STRING_OR_BUFFER_TO_SLICE(start, startBufferV, start)
- LD_STRING_OR_BUFFER_TO_SLICE(end, endBufferV, end)
-
- v8::Persistent<v8::Value> startBuffer =
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE startBufferV);
- v8::Persistent<v8::Value> endBuffer =
- v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE endBufferV);
+ LD_STRING_OR_BUFFER_TO_SLICE(start, startHandle, start)
+ LD_STRING_OR_BUFFER_TO_SLICE(end, endHandle, end)
ApproximateSizeWorker* worker = new ApproximateSizeWorker(
database
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
, start
, end
- , startBuffer
- , endBuffer
+ , startHandle
+ , endHandle
);
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
- return v8::Undefined();
+ NanReturnUndefined();
}
-v8::Handle<v8::Value> Database::GetProperty (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::GetProperty) {
+ NanScope();
- v8::Local<v8::Value> propertyV = args[0];
+ v8::Local<v8::Value> propertyHandle = args[0].As<v8::Object>();
v8::Local<v8::Function> callback; // for LD_CB_ERR_IF_NULL_OR_UNDEFINED
- if (!propertyV->IsString()) {
- LD_THROW_RETURN(getProperty() requires a valid `property` argument)
- }
+ if (!propertyHandle->IsString())
+ return NanThrowError("getProperty() requires a valid `property` argument");
- LD_CB_ERR_IF_NULL_OR_UNDEFINED(propertyV, property)
+ LD_CB_ERR_IF_NULL_OR_UNDEFINED(propertyHandle, property)
- LD_STRING_OR_BUFFER_TO_SLICE(property, propertyV, property)
+ LD_STRING_OR_BUFFER_TO_SLICE(property, propertyHandle, property)
leveldown::Database* database =
node::ObjectWrap::Unwrap<leveldown::Database>(args.This());
@@ -570,12 +506,11 @@ v8::Handle<v8::Value> Database::GetProperty (const v8::Arguments& args) {
delete value;
delete[] property.data();
- return returnValue;
+ NanReturnValue(returnValue);
}
-v8::Handle<v8::Value> Database::Iterator (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Database::Iterator) {
+ NanScope();
Database* database = node::ObjectWrap::Unwrap<Database>(args.This());
@@ -588,7 +523,7 @@ v8::Handle<v8::Value> Database::Iterator (const v8::Arguments& args) {
// easily store & lookup on our `iterators` map
uint32_t id = database->currentIteratorId++;
v8::TryCatch try_catch;
- v8::Handle<v8::Object> iterator = Iterator::NewInstance(
+ v8::Local<v8::Object> iteratorHandle = Iterator::NewInstance(
args.This()
, v8::Number::New(id)
, optionsObj
@@ -597,12 +532,22 @@ v8::Handle<v8::Value> Database::Iterator (const v8::Arguments& args) {
node::FatalException(try_catch);
}
- // register our iterator
- database->iterators[id] =
- v8::Persistent<v8::Object>::New(LD_NODE_ISOLATE_PRE
- node::ObjectWrap::Unwrap<leveldown::Iterator>(iterator)->handle_);
+ leveldown::Iterator *iterator =
+ node::ObjectWrap::Unwrap<leveldown::Iterator>(iteratorHandle);
- return scope.Close(iterator);
+ database->iterators[id] = iterator;
+
+ // register our iterator
+ /*
+ v8::Local<v8::Object> obj = v8::Object::New();
+ obj->Set(NanSymbol("iterator"), iteratorHandle);
+ v8::Persistent<v8::Object> persistent;
+ persistent.Reset(nan_isolate, obj);
+ database->iterators.insert(std::pair< uint32_t, v8::Persistent<v8::Object> & >
+ (id, persistent));
+ */
+
+ NanReturnValue(iteratorHandle);
}
diff --git a/src/database.h b/src/database.h
index 821edb1..2310f83 100644
--- a/src/database.h
+++ b/src/database.h
@@ -11,38 +11,30 @@
#include <node.h>
#include "leveldb/db.h"
-
+#include "nan.h"
#include "leveldown.h"
+#include "iterator.h"
namespace leveldown {
-LD_SYMBOL ( option_createIfMissing , createIfMissing ); // for open()
-LD_SYMBOL ( option_errorIfExists , errorIfExists ); // for open()
-LD_SYMBOL ( option_compression , compression ); // for open()
-LD_SYMBOL ( option_cacheSize , cacheSize ); // for open()
-LD_SYMBOL ( option_writeBufferSize , writeBufferSize ); // for open()
-LD_SYMBOL ( option_blockSize , blockSize ); // for open()
-LD_SYMBOL ( option_maxOpenFiles , maxOpenFiles ); // for open()
-LD_SYMBOL ( option_blockRestartInterval , blockRestartInterval ); // for open()
-LD_SYMBOL ( option_sync , sync ); // for put() and delete()
-LD_SYMBOL ( option_asBuffer , asBuffer ); // for get()
-LD_SYMBOL ( option_fillCache , fillcache ); // for get() and readStream()
-
-v8::Handle<v8::Value> LevelDOWN (const v8::Arguments& args);
+NAN_METHOD(LevelDOWN);
struct Reference {
- v8::Persistent<v8::Value> ptr;
+ v8::Persistent<v8::Object> handle;
leveldb::Slice slice;
- Reference(v8::Persistent<v8::Value> ptr, leveldb::Slice slice) :
- ptr(ptr)
- , slice(slice) { };
+
+ Reference(v8::Local<v8::Value> obj, leveldb::Slice slice) : slice(slice) {
+ v8::Local<v8::Object> _obj = v8::Object::New();
+ _obj->Set(NanSymbol("obj"), obj);
+ NanAssignPersistent(v8::Object, handle, _obj);
+ };
};
-static inline void ClearReferences (std::vector<Reference>* references) {
- for (std::vector<Reference>::iterator it = references->begin()
+static inline void ClearReferences (std::vector<Reference *> *references) {
+ for (std::vector<Reference *>::iterator it = references->begin()
; it != references->end()
; ) {
- DisposeStringOrBufferFromSlice(it->ptr, it->slice);
+ DisposeStringOrBufferFromSlice((*it)->handle, (*it)->slice);
it = references->erase(it);
}
delete references;
@@ -51,7 +43,7 @@ static inline void ClearReferences (std::vector<Reference>* references) {
class Database : public node::ObjectWrap {
public:
static void Init ();
- static v8::Handle<v8::Value> NewInstance (const v8::Arguments& args);
+ static v8::Handle<v8::Value> NewInstance (v8::Local<v8::String> &location);
leveldb::Status OpenDatabase (leveldb::Options* options, std::string location);
leveldb::Status PutToDatabase (
@@ -90,23 +82,22 @@ private:
uint32_t currentIteratorId;
void(*pendingCloseWorker);
- std::map< uint32_t, v8::Persistent<v8::Object> > iterators;
+ std::map< uint32_t, leveldown::Iterator * > iterators;
- static v8::Persistent<v8::Function> constructor;
static void WriteDoing(uv_work_t *req);
static void WriteAfter(uv_work_t *req);
- LD_V8_METHOD( New )
- LD_V8_METHOD( Open )
- LD_V8_METHOD( Close )
- LD_V8_METHOD( Put )
- LD_V8_METHOD( Delete )
- LD_V8_METHOD( Get )
- LD_V8_METHOD( Batch )
- LD_V8_METHOD( Write )
- LD_V8_METHOD( Iterator )
- LD_V8_METHOD( ApproximateSize )
- LD_V8_METHOD( GetProperty )
+ static NAN_METHOD(New);
+ static NAN_METHOD(Open);
+ static NAN_METHOD(Close);
+ static NAN_METHOD(Put);
+ static NAN_METHOD(Delete);
+ static NAN_METHOD(Get);
+ static NAN_METHOD(Batch);
+ static NAN_METHOD(Write);
+ static NAN_METHOD(Iterator);
+ static NAN_METHOD(ApproximateSize);
+ static NAN_METHOD(GetProperty);
};
} // namespace leveldown
diff --git a/src/database_async.cc b/src/database_async.cc
index bc11424..9f4c47d 100644
--- a/src/database_async.cc
+++ b/src/database_async.cc
@@ -16,8 +16,8 @@ namespace leveldown {
/** OPEN WORKER **/
OpenWorker::OpenWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, bool createIfMissing
, bool errorIfExists
, bool compression
@@ -46,14 +46,14 @@ OpenWorker::~OpenWorker () {
}
void OpenWorker::Execute () {
- status = database->OpenDatabase(options, database->Location());
+ SetStatus(database->OpenDatabase(options, database->Location()));
}
/** CLOSE WORKER **/
CloseWorker::CloseWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
) : AsyncWorker(database, callback)
{};
@@ -64,46 +64,46 @@ void CloseWorker::Execute () {
}
void CloseWorker::WorkComplete () {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+ NanScope();
HandleOKCallback();
- callback.Dispose(LD_NODE_ISOLATE);
}
/** IO WORKER (abstract) **/
IOWorker::IOWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice key
- , v8::Persistent<v8::Value> keyPtr
+ , v8::Local<v8::Object> &keyHandle
) : AsyncWorker(database, callback)
, key(key)
- , keyPtr(keyPtr)
-{};
+{
+ SavePersistent("key", keyHandle);
+};
IOWorker::~IOWorker () {}
void IOWorker::WorkComplete () {
- DisposeStringOrBufferFromSlice(keyPtr, key);
+ DisposeStringOrBufferFromSlice(GetFromPersistent("key"), key);
AsyncWorker::WorkComplete();
}
/** READ WORKER **/
ReadWorker::ReadWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice key
, bool asBuffer
, bool fillCache
- , v8::Persistent<v8::Value> keyPtr
-) : IOWorker(database, callback, key, keyPtr)
+ , v8::Local<v8::Object> &keyHandle
+) : IOWorker(database, callback, key, keyHandle)
, asBuffer(asBuffer)
{
options = new leveldb::ReadOptions();
options->fill_cache = fillCache;
+ SavePersistent("key", keyHandle);
};
ReadWorker::~ReadWorker () {
@@ -111,16 +111,15 @@ ReadWorker::~ReadWorker () {
}
void ReadWorker::Execute () {
- status = database->GetFromDatabase(options, key, value);
+ SetStatus(database->GetFromDatabase(options, key, value));
}
void ReadWorker::HandleOKCallback () {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+ NanScope();
v8::Local<v8::Value> returnValue;
if (asBuffer) {
- returnValue = LD_NEW_BUFFER_HANDLE((char*)value.data(), value.size());
+ returnValue = NanNewBufferHandle((char*)value.data(), value.size());
} else {
returnValue = v8::String::New((char*)value.data(), value.size());
}
@@ -128,21 +127,22 @@ void ReadWorker::HandleOKCallback () {
v8::Local<v8::Value>::New(v8::Null())
, returnValue
};
- LD_RUN_CALLBACK(callback, argv, 2);
+ callback->Run(2, argv);
}
/** DELETE WORKER **/
DeleteWorker::DeleteWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice key
, bool sync
- , v8::Persistent<v8::Value> keyPtr
-) : IOWorker(database, callback, key, keyPtr)
+ , v8::Local<v8::Object> &keyHandle
+) : IOWorker(database, callback, key, keyHandle)
{
options = new leveldb::WriteOptions();
options->sync = sync;
+ SavePersistent("key", keyHandle);
};
DeleteWorker::~DeleteWorker () {
@@ -150,42 +150,43 @@ DeleteWorker::~DeleteWorker () {
}
void DeleteWorker::Execute () {
- status = database->DeleteFromDatabase(options, key);
+ SetStatus(database->DeleteFromDatabase(options, key));
}
/** WRITE WORKER **/
WriteWorker::WriteWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice key
, leveldb::Slice value
, bool sync
- , v8::Persistent<v8::Value> keyPtr
- , v8::Persistent<v8::Value> valuePtr
-) : DeleteWorker(database, callback, key, sync, keyPtr)
+ , v8::Local<v8::Object> &keyHandle
+ , v8::Local<v8::Object> &valueHandle
+) : DeleteWorker(database, callback, key, sync, keyHandle)
, value(value)
- , valuePtr(valuePtr)
-{};
+{
+ SavePersistent("value", valueHandle);
+};
WriteWorker::~WriteWorker () {}
void WriteWorker::Execute () {
- status = database->PutToDatabase(options, key, value);
+ SetStatus(database->PutToDatabase(options, key, value));
}
void WriteWorker::WorkComplete () {
- DisposeStringOrBufferFromSlice(valuePtr, value);
+ DisposeStringOrBufferFromSlice(GetFromPersistent("value"), value);
IOWorker::WorkComplete();
}
/** BATCH WORKER **/
BatchWorker::BatchWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::WriteBatch* batch
- , std::vector<Reference>* references
+ , std::vector<Reference *>* references
, bool sync
) : AsyncWorker(database, callback)
, batch(batch)
@@ -201,23 +202,24 @@ BatchWorker::~BatchWorker () {
}
void BatchWorker::Execute () {
- status = database->WriteBatchToDatabase(options, batch);
+ SetStatus(database->WriteBatchToDatabase(options, batch));
}
/** APPROXIMATE SIZE WORKER **/
ApproximateSizeWorker::ApproximateSizeWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice start
, leveldb::Slice end
- , v8::Persistent<v8::Value> startPtr
- , v8::Persistent<v8::Value> endPtr
+ , v8::Local<v8::Object> &startHandle
+ , v8::Local<v8::Object> &endHandle
) : AsyncWorker(database, callback)
, range(start, end)
- , startPtr(startPtr)
- , endPtr(endPtr)
-{};
+{
+ SavePersistent("start", startHandle);
+ SavePersistent("end", endHandle);
+};
ApproximateSizeWorker::~ApproximateSizeWorker () {}
@@ -226,21 +228,20 @@ void ApproximateSizeWorker::Execute () {
}
void ApproximateSizeWorker::WorkComplete() {
- DisposeStringOrBufferFromSlice(startPtr, range.start);
- DisposeStringOrBufferFromSlice(endPtr, range.limit);
+ DisposeStringOrBufferFromSlice(GetFromPersistent("start"), range.start);
+ DisposeStringOrBufferFromSlice(GetFromPersistent("end"), range.limit);
AsyncWorker::WorkComplete();
}
void ApproximateSizeWorker::HandleOKCallback () {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+ NanScope();
v8::Local<v8::Value> returnValue = v8::Number::New((double) size);
v8::Local<v8::Value> argv[] = {
v8::Local<v8::Value>::New(v8::Null())
, returnValue
};
- LD_RUN_CALLBACK(callback, argv, 2);
+ callback->Run(2, argv);
}
} // namespace leveldown
diff --git a/src/database_async.h b/src/database_async.h
index 80dafff..909e7e6 100644
--- a/src/database_async.h
+++ b/src/database_async.h
@@ -18,8 +18,8 @@ namespace leveldown {
class OpenWorker : public AsyncWorker {
public:
OpenWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, bool createIfMissing
, bool errorIfExists
, bool compression
@@ -40,8 +40,8 @@ private:
class CloseWorker : public AsyncWorker {
public:
CloseWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
);
virtual ~CloseWorker ();
@@ -52,10 +52,10 @@ public:
class IOWorker : public AsyncWorker {
public:
IOWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice key
- , v8::Persistent<v8::Value> keyPtr
+ , v8::Local<v8::Object> &keyHandle
);
virtual ~IOWorker ();
@@ -63,18 +63,17 @@ public:
protected:
leveldb::Slice key;
- v8::Persistent<v8::Value> keyPtr;
};
class ReadWorker : public IOWorker {
public:
ReadWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice key
, bool asBuffer
, bool fillCache
- , v8::Persistent<v8::Value> keyPtr
+ , v8::Local<v8::Object> &keyHandle
);
virtual ~ReadWorker ();
@@ -90,11 +89,11 @@ private:
class DeleteWorker : public IOWorker {
public:
DeleteWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice key
, bool sync
- , v8::Persistent<v8::Value> keyPtr
+ , v8::Local<v8::Object> &keyHandle
);
virtual ~DeleteWorker ();
@@ -107,13 +106,13 @@ protected:
class WriteWorker : public DeleteWorker {
public:
WriteWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice key
, leveldb::Slice value
, bool sync
- , v8::Persistent<v8::Value> keyPtr
- , v8::Persistent<v8::Value> valuePtr
+ , v8::Local<v8::Object> &keyHandle
+ , v8::Local<v8::Object> &valueHandle
);
virtual ~WriteWorker ();
@@ -122,16 +121,15 @@ public:
private:
leveldb::Slice value;
- v8::Persistent<v8::Value> valuePtr;
};
class BatchWorker : public AsyncWorker {
public:
BatchWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::WriteBatch* batch
- , std::vector<Reference>* references
+ , std::vector<Reference *>* references
, bool sync
);
@@ -141,18 +139,18 @@ public:
private:
leveldb::WriteOptions* options;
leveldb::WriteBatch* batch;
- std::vector<Reference>* references;
+ std::vector<Reference *>* references;
};
class ApproximateSizeWorker : public AsyncWorker {
public:
ApproximateSizeWorker (
- Database* database
- , v8::Persistent<v8::Function> callback
+ Database *database
+ , NanCallback *callback
, leveldb::Slice start
, leveldb::Slice end
- , v8::Persistent<v8::Value> startPtr
- , v8::Persistent<v8::Value> endPtr
+ , v8::Local<v8::Object> &startHandle
+ , v8::Local<v8::Object> &endHandle
);
virtual ~ApproximateSizeWorker ();
@@ -162,8 +160,6 @@ public:
private:
leveldb::Range range;
- v8::Persistent<v8::Value> startPtr;
- v8::Persistent<v8::Value> endPtr;
uint64_t size;
};
diff --git a/src/iterator.cc b/src/iterator.cc
index 52a2493..d6b4553 100644
--- a/src/iterator.cc
+++ b/src/iterator.cc
@@ -12,6 +12,8 @@
namespace leveldown {
+static v8::Persistent<v8::FunctionTemplate> iterator_constructor;
+
Iterator::Iterator (
Database* database
, uint32_t id
@@ -24,7 +26,7 @@ Iterator::Iterator (
, bool fillCache
, bool keyAsBuffer
, bool valueAsBuffer
- , v8::Persistent<v8::Value> startPtr
+ , v8::Local<v8::Object> &startHandle
) : database(database)
, id(id)
, start(start)
@@ -35,8 +37,14 @@ Iterator::Iterator (
, limit(limit)
, keyAsBuffer(keyAsBuffer)
, valueAsBuffer(valueAsBuffer)
- , startPtr(startPtr)
{
+ NanScope();
+
+ v8::Local<v8::Object> obj = v8::Object::New();
+ if (!startHandle.IsEmpty())
+ obj->Set(NanSymbol("start"), startHandle);
+ NanAssignPersistent(v8::Object, persistentHandle, obj)
+
options = new leveldb::ReadOptions();
options->fill_cache = fillCache;
dbIterator = NULL;
@@ -48,9 +56,9 @@ Iterator::Iterator (
Iterator::~Iterator () {
- LD_NODE_ISOLATE_DECL
delete options;
- startPtr.Dispose(LD_NODE_ISOLATE);
+ if (!persistentHandle.IsEmpty())
+ NanDispose(persistentHandle);
if (start != NULL)
delete start;
if (end != NULL)
@@ -121,23 +129,21 @@ void Iterator::Release () {
void checkEndCallback (Iterator* iterator) {
iterator->nexting = false;
if (iterator->endWorker != NULL) {
- AsyncQueueWorker(iterator->endWorker);
+ NanAsyncQueueWorker(iterator->endWorker);
iterator->endWorker = NULL;
}
}
//void *ctx, void (*callback)(void *ctx, leveldb::Slice key, leveldb::Slice value)
-v8::Handle<v8::Value> Iterator::Next (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Iterator::Next) {
+ NanScope();
Iterator* iterator = node::ObjectWrap::Unwrap<Iterator>(args.This());
- if (args.Length() == 0 || !args[0]->IsFunction()) {
- LD_THROW_RETURN(next() requires a callback argument)
- }
+ if (args.Length() == 0 || !args[0]->IsFunction())
+ return NanThrowError("next() requires a callback argument");
- v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[0]);
+ v8::Local<v8::Function> callback = args[0].As<v8::Function>();
if (iterator->ended) {
LD_RETURN_CALLBACK_OR_ERROR(callback, "cannot call next() after end()")
@@ -149,24 +155,22 @@ v8::Handle<v8::Value> Iterator::Next (const v8::Arguments& args) {
NextWorker* worker = new NextWorker(
iterator
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
, checkEndCallback
);
iterator->nexting = true;
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
- return scope.Close(args.Holder());
+ NanReturnValue(args.Holder());
}
-v8::Handle<v8::Value> Iterator::End (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Iterator::End) {
+ NanScope();
Iterator* iterator = node::ObjectWrap::Unwrap<Iterator>(args.This());
- if (args.Length() == 0 || !args[0]->IsFunction()) {
- LD_THROW_RETURN(end() requires a callback argument)
- }
+ if (args.Length() == 0 || !args[0]->IsFunction())
+ return NanThrowError("end() requires a callback argument");
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[0]);
@@ -176,7 +180,7 @@ v8::Handle<v8::Value> Iterator::End (const v8::Arguments& args) {
EndWorker* worker = new EndWorker(
iterator
- , v8::Persistent<v8::Function>::New(LD_NODE_ISOLATE_PRE callback)
+ , new NanCallback(callback)
);
iterator->ended = true;
@@ -184,64 +188,54 @@ v8::Handle<v8::Value> Iterator::End (const v8::Arguments& args) {
// waiting for a next() to return, queue the end
iterator->endWorker = worker;
} else {
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
}
- return scope.Close(args.Holder());
+ NanReturnValue(args.Holder());
}
-v8::Persistent<v8::Function> Iterator::constructor;
-
void Iterator::Init () {
- LD_NODE_ISOLATE_DECL
- v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(New);
- tpl->SetClassName(v8::String::NewSymbol("Iterator"));
+ v8::Local<v8::FunctionTemplate> tpl =
+ v8::FunctionTemplate::New(Iterator::New);
+ NanAssignPersistent(v8::FunctionTemplate, iterator_constructor, tpl)
+ tpl->SetClassName(NanSymbol("Iterator"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("next")
- , v8::FunctionTemplate::New(Next)->GetFunction()
- );
- tpl->PrototypeTemplate()->Set(
- v8::String::NewSymbol("end")
- , v8::FunctionTemplate::New(End)->GetFunction()
- );
- constructor = v8::Persistent<v8::Function>::New(
- LD_NODE_ISOLATE_PRE
- tpl->GetFunction());
+ NODE_SET_PROTOTYPE_METHOD(tpl, "next", Iterator::Next);
+ NODE_SET_PROTOTYPE_METHOD(tpl, "end", Iterator::End);
}
-v8::Handle<v8::Object> Iterator::NewInstance (
- v8::Handle<v8::Object> database
- , v8::Handle<v8::Number> id
- , v8::Handle<v8::Object> optionsObj
+v8::Local<v8::Object> Iterator::NewInstance (
+ v8::Local<v8::Object> database
+ , v8::Local<v8::Number> id
+ , v8::Local<v8::Object> optionsObj
) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+ NanScope();
v8::Local<v8::Object> instance;
+ v8::Local<v8::FunctionTemplate> constructorHandle =
+ NanPersistentToLocal(iterator_constructor);
if (optionsObj.IsEmpty()) {
v8::Handle<v8::Value> argv[2] = { database, id };
- instance = constructor->NewInstance(2, argv);
+ instance = constructorHandle->GetFunction()->NewInstance(2, argv);
} else {
v8::Handle<v8::Value> argv[3] = { database, id, optionsObj };
- instance = constructor->NewInstance(3, argv);
+ instance = constructorHandle->GetFunction()->NewInstance(3, argv);
}
- return scope.Close(instance);
+ return instance;
}
-v8::Handle<v8::Value> Iterator::New (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(Iterator::New) {
+ NanScope();
Database* database = node::ObjectWrap::Unwrap<Database>(args[0]->ToObject());
//TODO: remove this, it's only here to make LD_STRING_OR_BUFFER_TO_SLICE happy
v8::Handle<v8::Function> callback;
- v8::Local<v8::Value> startBuffer;
+ v8::Local<v8::Object> startHandle;
leveldb::Slice* start = NULL;
std::string* end = NULL;
int limit = -1;
@@ -253,25 +247,25 @@ v8::Handle<v8::Value> Iterator::New (const v8::Arguments& args) {
if (args.Length() > 1 && args[2]->IsObject()) {
optionsObj = v8::Local<v8::Object>::Cast(args[2]);
- if (optionsObj->Has(option_start)
- && (node::Buffer::HasInstance(optionsObj->Get(option_start))
- || optionsObj->Get(option_start)->IsString())) {
+ if (optionsObj->Has(NanSymbol("start"))
+ && (node::Buffer::HasInstance(optionsObj->Get(NanSymbol("start")))
+ || optionsObj->Get(NanSymbol("start"))->IsString())) {
- startBuffer = v8::Local<v8::Value>::New(optionsObj->Get(option_start));
+ startHandle = optionsObj->Get(NanSymbol("start")).As<v8::Object>();
// ignore start if it has size 0 since a Slice can't have length 0
- if (StringOrBufferLength(startBuffer) > 0) {
- LD_STRING_OR_BUFFER_TO_SLICE(_start, startBuffer, start)
+ if (StringOrBufferLength(startHandle) > 0) {
+ LD_STRING_OR_BUFFER_TO_SLICE(_start, startHandle, start)
start = new leveldb::Slice(_start.data(), _start.size());
}
}
- if (optionsObj->Has(option_end)
- && (node::Buffer::HasInstance(optionsObj->Get(option_end))
- || optionsObj->Get(option_end)->IsString())) {
+ if (optionsObj->Has(NanSymbol("end"))
+ && (node::Buffer::HasInstance(optionsObj->Get(NanSymbol("end")))
+ || optionsObj->Get(NanSymbol("end"))->IsString())) {
v8::Local<v8::Value> endBuffer =
- v8::Local<v8::Value>::New(optionsObj->Get(option_end));
+ v8::Local<v8::Value>::New(optionsObj->Get(NanSymbol("end")));
// ignore end if it has size 0 since a Slice can't have length 0
if (StringOrBufferLength(endBuffer) > 0) {
@@ -280,21 +274,26 @@ v8::Handle<v8::Value> Iterator::New (const v8::Arguments& args) {
}
}
- if (!optionsObj.IsEmpty() && optionsObj->Has(option_limit)) {
- limit =
- v8::Local<v8::Integer>::Cast(optionsObj->Get(option_limit))->Value();
+ if (!optionsObj.IsEmpty() && optionsObj->Has(NanSymbol("limit"))) {
+ limit = v8::Local<v8::Integer>::Cast(optionsObj->Get(
+ NanSymbol("limit")))->Value();
}
}
- bool reverse = BooleanOptionValue(optionsObj, option_reverse);
- bool keys = BooleanOptionValueDefTrue(optionsObj, option_keys);
- bool values = BooleanOptionValueDefTrue(optionsObj, option_values);
- bool keyAsBuffer = BooleanOptionValueDefTrue(optionsObj, option_keyAsBuffer);
- bool valueAsBuffer = BooleanOptionValueDefTrue(
+ bool reverse = NanBooleanOptionValue(optionsObj, NanSymbol("reverse"));
+ bool keys = NanBooleanOptionValue(optionsObj, NanSymbol("keys"), true);
+ bool values = NanBooleanOptionValue(optionsObj, NanSymbol("values"), true);
+ bool keyAsBuffer = NanBooleanOptionValue(
+ optionsObj
+ , NanSymbol("keyAsBuffer")
+ , true
+ );
+ bool valueAsBuffer = NanBooleanOptionValue(
optionsObj
- , option_valueAsBuffer
+ , NanSymbol("valueAsBuffer")
+ , true
);
- bool fillCache = BooleanOptionValue(optionsObj, option_fillCache);
+ bool fillCache = NanBooleanOptionValue(optionsObj, NanSymbol("fillCache"));
Iterator* iterator = new Iterator(
database
@@ -308,11 +307,11 @@ v8::Handle<v8::Value> Iterator::New (const v8::Arguments& args) {
, fillCache
, keyAsBuffer
, valueAsBuffer
- , v8::Persistent<v8::Value>::New(LD_NODE_ISOLATE_PRE startBuffer)
+ , startHandle
);
iterator->Wrap(args.This());
- return args.This();
+ NanReturnValue(args.This());
}
} // namespace leveldown
diff --git a/src/iterator.h b/src/iterator.h
index fe9545c..4893dea 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -8,30 +8,25 @@
#include <node.h>
+#include "nan.h"
#include "leveldown.h"
#include "database.h"
#include "async.h"
namespace leveldown {
-LD_SYMBOL ( option_start , start );
-LD_SYMBOL ( option_end , end );
-LD_SYMBOL ( option_limit , limit );
-LD_SYMBOL ( option_reverse , reverse );
-LD_SYMBOL ( option_keys , keys );
-LD_SYMBOL ( option_values , values );
-LD_SYMBOL ( option_keyAsBuffer , keyAsBuffer );
-LD_SYMBOL ( option_valueAsBuffer , valueAsBuffer );
+class Database;
+class AsyncWorker;
-v8::Handle<v8::Value> CreateIterator (const v8::Arguments& args);
+v8::Local<v8::Value> CreateIterator (const v8::Arguments& args);
class Iterator : public node::ObjectWrap {
public:
static void Init ();
- static v8::Handle<v8::Object> NewInstance (
- v8::Handle<v8::Object> database
- , v8::Handle<v8::Number> id
- , v8::Handle<v8::Object> optionsObj
+ static v8::Local<v8::Object> NewInstance (
+ v8::Local<v8::Object> database
+ , v8::Local<v8::Number> id
+ , v8::Local<v8::Object> optionsObj
);
Iterator (
@@ -46,7 +41,7 @@ public:
, bool fillCache
, bool keyAsBuffer
, bool valueAsBuffer
- , v8::Persistent<v8::Value> startPtr
+ , v8::Local<v8::Object> &startHandle
);
~Iterator ();
@@ -77,15 +72,13 @@ public:
AsyncWorker* endWorker;
private:
- v8::Persistent<v8::Value> startPtr;
+ v8::Persistent<v8::Object> persistentHandle;
bool GetIterator ();
- static v8::Persistent<v8::Function> constructor;
-
- LD_V8_METHOD( New )
- LD_V8_METHOD( Next )
- LD_V8_METHOD( End )
+ static NAN_METHOD(New);
+ static NAN_METHOD(Next);
+ static NAN_METHOD(End);
};
} // namespace leveldown
diff --git a/src/iterator_async.cc b/src/iterator_async.cc
index 5f0e0c8..f8a5873 100644
--- a/src/iterator_async.cc
+++ b/src/iterator_async.cc
@@ -17,7 +17,7 @@ namespace leveldown {
NextWorker::NextWorker (
Iterator* iterator
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
, void (*localCallback)(Iterator*)
) : AsyncWorker(NULL, callback)
, iterator(iterator)
@@ -29,23 +29,22 @@ NextWorker::~NextWorker () {}
void NextWorker::Execute () {
ok = iterator->IteratorNext(key, value);
if (!ok)
- status = iterator->IteratorStatus();
+ SetStatus(iterator->IteratorStatus());
}
void NextWorker::HandleOKCallback () {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+ NanScope();
v8::Local<v8::Value> returnKey;
if (iterator->keyAsBuffer) {
- returnKey = LD_NEW_BUFFER_HANDLE((char*)key.data(), key.size())
+ returnKey = NanNewBufferHandle((char*)key.data(), key.size());
} else {
returnKey = v8::String::New((char*)key.data(), key.size());
}
v8::Local<v8::Value> returnValue;
if (iterator->valueAsBuffer) {
- returnValue = LD_NEW_BUFFER_HANDLE((char*)value.data(), value.size());
+ returnValue = NanNewBufferHandle((char*)value.data(), value.size());
} else {
returnValue = v8::String::New((char*)value.data(), value.size());
}
@@ -59,9 +58,9 @@ void NextWorker::HandleOKCallback () {
, returnKey
, returnValue
};
- LD_RUN_CALLBACK(callback, argv, 3);
+ callback->Run(3, argv);
} else {
- LD_RUN_CALLBACK(callback, NULL, 0);
+ callback->Run(0, NULL);
}
}
@@ -69,7 +68,7 @@ void NextWorker::HandleOKCallback () {
EndWorker::EndWorker (
Iterator* iterator
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
) : AsyncWorker(NULL, callback)
, iterator(iterator)
{};
@@ -82,7 +81,7 @@ void EndWorker::Execute () {
void EndWorker::HandleOKCallback () {
iterator->Release();
- LD_RUN_CALLBACK(callback, NULL, 0);
+ callback->Run(0, NULL);
}
} // namespace leveldown
diff --git a/src/iterator_async.h b/src/iterator_async.h
index 1c5e3fb..bbc1fd0 100644
--- a/src/iterator_async.h
+++ b/src/iterator_async.h
@@ -8,6 +8,7 @@
#include <node.h>
+#include "nan.h"
#include "async.h"
#include "iterator.h"
@@ -17,7 +18,7 @@ class NextWorker : public AsyncWorker {
public:
NextWorker (
Iterator* iterator
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
, void (*localCallback)(Iterator*)
);
@@ -37,7 +38,7 @@ class EndWorker : public AsyncWorker {
public:
EndWorker (
Iterator* iterator
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
);
virtual ~EndWorker ();
diff --git a/src/leveldown.cc b/src/leveldown.cc
index 5a3fc47..14ee6bd 100644
--- a/src/leveldown.cc
+++ b/src/leveldown.cc
@@ -13,70 +13,64 @@
namespace leveldown {
-v8::Handle<v8::Value> DestroyDB (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(DestroyDB) {
+ NanScope();
if (args.Length() < 2) {
- LD_THROW_RETURN(destroy() requires `location` and `callback` arguments)
+ return NanThrowError("destroy() requires `location` and `callback` arguments");
}
if (!args[0]->IsString()) {
- LD_THROW_RETURN(destroy() requires a location string argument)
+ return NanThrowError("destroy() requires a location string argument");
}
if (!args[1]->IsFunction()) {
- LD_THROW_RETURN(destroy() requires a callback function argument)
+ return NanThrowError("destroy() requires a callback function argument");
}
- char* location = FromV8String(args[0]);
+ char* location = NanFromV8String(args[0]);
- v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New(
- LD_NODE_ISOLATE_PRE
- v8::Local<v8::Function>::Cast(args[1])
- );
+ NanCallback* callback = new NanCallback(
+ v8::Local<v8::Function>::Cast(args[1]));
DestroyWorker* worker = new DestroyWorker(
location
, callback
);
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
- return scope.Close(v8::Undefined());
+ NanReturnUndefined();
}
-v8::Handle<v8::Value> RepairDB (const v8::Arguments& args) {
- LD_NODE_ISOLATE_DECL
- LD_HANDLESCOPE
+NAN_METHOD(RepairDB) {
+ NanScope();
if (args.Length() < 2) {
- LD_THROW_RETURN(repair() requires `location` and `callback` arguments)
+ return NanThrowError("repair() requires `location` and `callback` arguments");
}
if (!args[0]->IsString()) {
- LD_THROW_RETURN(repair() requires a location string argument)
+ return NanThrowError("repair() requires a location string argument");
}
if (!args[1]->IsFunction()) {
- LD_THROW_RETURN(repair() requires a callback function argument)
+ return NanThrowError("repair() requires a callback function argument");
}
- char* location = FromV8String(args[0]);
+ char* location = NanFromV8String(args[0]);
- v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New(
- LD_NODE_ISOLATE_PRE
- v8::Local<v8::Function>::Cast(args[1])
- );
+ NanCallback* callback = new NanCallback(
+ v8::Local<v8::Function>::Cast(args[1]));
RepairWorker* worker = new RepairWorker(
location
, callback
);
- AsyncQueueWorker(worker);
+ NanAsyncQueueWorker(worker);
- return scope.Close(v8::Undefined());
+ NanReturnUndefined();
}
void Init (v8::Handle<v8::Object> target) {
@@ -88,16 +82,16 @@ void Init (v8::Handle<v8::Object> target) {
v8::FunctionTemplate::New(LevelDOWN)->GetFunction();
leveldown->Set(
- v8::String::NewSymbol("destroy")
+ NanSymbol("destroy")
, v8::FunctionTemplate::New(DestroyDB)->GetFunction()
);
leveldown->Set(
- v8::String::NewSymbol("repair")
+ NanSymbol("repair")
, v8::FunctionTemplate::New(RepairDB)->GetFunction()
);
- target->Set(v8::String::NewSymbol("leveldown"), leveldown);
+ target->Set(NanSymbol("leveldown"), leveldown);
}
NODE_MODULE(leveldown, Init)
diff --git a/src/leveldown.h b/src/leveldown.h
index 371be34..b4e06ec 100644
--- a/src/leveldown.h
+++ b/src/leveldown.h
@@ -9,15 +9,7 @@
#include <node_buffer.h>
#include <leveldb/slice.h>
-static inline char* FromV8String(v8::Local<v8::Value> from) {
- size_t sz_;
- char* to;
- v8::Local<v8::String> toStr = from->ToString();
- sz_ = toStr->Utf8Length();
- to = new char[sz_ + 1];
- toStr->WriteUtf8(to, -1, NULL, v8::String::NO_OPTIONS);
- return to;
-}
+#include "nan.h"
static inline size_t StringOrBufferLength(v8::Local<v8::Value> obj) {
return node::Buffer::HasInstance(obj->ToObject())
@@ -25,86 +17,30 @@ static inline size_t StringOrBufferLength(v8::Local<v8::Value> obj) {
: obj->ToString()->Utf8Length();
}
-static inline bool BooleanOptionValue(
- v8::Local<v8::Object> optionsObj
- , v8::Handle<v8::String> opt) {
-
- return !optionsObj.IsEmpty()
- && optionsObj->Has(opt)
- && optionsObj->Get(opt)->BooleanValue();
-}
-
-static inline bool BooleanOptionValueDefTrue(
- v8::Local<v8::Object> optionsObj
- , v8::Handle<v8::String> opt) {
+// NOTE: this MUST be called on objects created by
+// LD_STRING_OR_BUFFER_TO_SLICE
+static inline void DisposeStringOrBufferFromSlice(
+ v8::Persistent<v8::Object> &handle
+ , leveldb::Slice slice) {
- return optionsObj.IsEmpty()
- || !optionsObj->Has(opt)
- || optionsObj->Get(opt)->BooleanValue();
+ if (!node::Buffer::HasInstance(NanPersistentToLocal(handle)->Get(NanSymbol("obj"))))
+ delete[] slice.data();
+ NanDispose(handle);
}
-static inline uint32_t UInt32OptionValue(
- v8::Local<v8::Object> optionsObj
- , v8::Handle<v8::String> opt
- , uint32_t def) {
+static inline void DisposeStringOrBufferFromSlice(
+ v8::Local<v8::Object> handle
+ , leveldb::Slice slice) {
- return !optionsObj.IsEmpty()
- && optionsObj->Has(opt)
- && optionsObj->Get(opt)->IsUint32()
- ? optionsObj->Get(opt)->Uint32Value()
- : def;
+ if (!node::Buffer::HasInstance(handle))
+ delete[] slice.data();
}
-// V8 Isolate stuff introduced with V8 upgrade, see https://github.com/joyent/node/pull/5077
-#if (NODE_MODULE_VERSION > 0x000B)
-# define LD_NODE_ISOLATE_GET v8::Isolate::GetCurrent()
-# define LD_NODE_ISOLATE_DECL v8::Isolate* isolate = LD_NODE_ISOLATE_GET;
-# define LD_NODE_ISOLATE isolate
-# define LD_NODE_ISOLATE_PRE isolate,
-# define LD_NODE_ISOLATE_POST , isolate
-#else
-# define LD_NODE_ISOLATE_GET
-# define LD_NODE_ISOLATE_DECL
-# define LD_NODE_ISOLATE
-# define LD_NODE_ISOLATE_PRE
-# define LD_NODE_ISOLATE_POST
-#endif
-
-#if (NODE_MODULE_VERSION > 0x000B)
-# define LD_SYMBOL(var, key) \
- static const v8::Persistent<v8::String> var = \
- v8::Persistent<v8::String>::New( \
- LD_NODE_ISOLATE_GET, v8::String::NewSymbol(#key));
-# define LD_HANDLESCOPE v8::HandleScope scope(LD_NODE_ISOLATE);
-# define LD_NEW_BUFFER_HANDLE(data, size) node::Buffer::New(data, size);
-#else
-# define LD_SYMBOL(var, key) \
- static const v8::Persistent<v8::String> var = \
- v8::Persistent<v8::String>::New(v8::String::NewSymbol(#key));
-# define LD_HANDLESCOPE v8::HandleScope scope;
-# define LD_NEW_BUFFER_HANDLE(data, size) \
- v8::Local<v8::Value>::New(node::Buffer::New(data, size)->handle_);
-#endif
-
-#define LD_V8_METHOD(name) \
- static v8::Handle<v8::Value> name (const v8::Arguments& args);
-
#define LD_CB_ERR_IF_NULL_OR_UNDEFINED(thing, name) \
if (thing->IsNull() || thing->IsUndefined()) { \
LD_RETURN_CALLBACK_OR_ERROR(callback, #name " cannot be `null` or `undefined`") \
}
-// NOTE: this MUST be called on objects created by
-// LD_STRING_OR_BUFFER_TO_SLICE
-static inline void DisposeStringOrBufferFromSlice(v8::Persistent<v8::Value> ptr
- , leveldb::Slice slice) {
-
- LD_NODE_ISOLATE_DECL
- if (!node::Buffer::HasInstance(ptr))
- delete[] slice.data();
- ptr.Dispose(LD_NODE_ISOLATE);
-}
-
// NOTE: must call DisposeStringOrBufferFromSlice() on objects created here
#define LD_STRING_OR_BUFFER_TO_SLICE(to, from, name) \
size_t to ## Sz_; \
@@ -138,10 +74,9 @@ static inline void DisposeStringOrBufferFromSlice(v8::Persistent<v8::Value> ptr
) \
}; \
LD_RUN_CALLBACK(callback, argv, 1) \
- return v8::Undefined(); \
+ NanReturnUndefined(); \
} \
- v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); \
- return v8::Undefined();
+ return NanThrowError(msg);
#define LD_RUN_CALLBACK(callback, argv, length) \
v8::TryCatch try_catch; \
@@ -150,35 +85,30 @@ static inline void DisposeStringOrBufferFromSlice(v8::Persistent<v8::Value> ptr
node::FatalException(try_catch); \
}
-#define LD_THROW_RETURN(...) \
- v8::ThrowException(v8::Exception::Error(v8::String::New(#__VA_ARGS__))); \
- return v8::Undefined();
-
/* LD_METHOD_SETUP_COMMON setup the following objects:
* - Database* database
* - v8::Local<v8::Object> optionsObj (may be empty)
* - v8::Persistent<v8::Function> callback (won't be empty)
- * Will LD_THROW_RETURN if there isn't a callback in arg 0 or 1
+ * Will throw/return if there isn't a callback in arg 0 or 1
*/
#define LD_METHOD_SETUP_COMMON(name, optionPos, callbackPos) \
- if (args.Length() == 0) { \
- LD_THROW_RETURN(name() requires a callback argument) \
- } \
+ if (args.Length() == 0) \
+ return NanThrowError(#name "() requires a callback argument"); \
leveldown::Database* database = \
node::ObjectWrap::Unwrap<leveldown::Database>(args.This()); \
v8::Local<v8::Object> optionsObj; \
v8::Local<v8::Function> callback; \
if (optionPos == -1 && args[callbackPos]->IsFunction()) { \
- callback = v8::Local<v8::Function>::Cast(args[callbackPos]); \
+ callback = args[callbackPos].As<v8::Function>(); \
} else if (optionPos != -1 && args[callbackPos - 1]->IsFunction()) { \
- callback = v8::Local<v8::Function>::Cast(args[callbackPos - 1]); \
+ callback = args[callbackPos - 1].As<v8::Function>(); \
} else if (optionPos != -1 \
&& args[optionPos]->IsObject() \
&& args[callbackPos]->IsFunction()) { \
- optionsObj = v8::Local<v8::Object>::Cast(args[optionPos]); \
- callback = v8::Local<v8::Function>::Cast(args[callbackPos]); \
+ optionsObj = args[optionPos].As<v8::Object>(); \
+ callback = args[callbackPos].As<v8::Function>(); \
} else { \
- LD_THROW_RETURN(name() requires a callback argument) \
+ return NanThrowError(#name "() requires a callback argument"); \
}
#define LD_METHOD_SETUP_COMMON_ONEARG(name) LD_METHOD_SETUP_COMMON(name, -1, 0)
diff --git a/src/leveldown_async.cc b/src/leveldown_async.cc
index 008f425..db84c1f 100644
--- a/src/leveldown_async.cc
+++ b/src/leveldown_async.cc
@@ -14,7 +14,7 @@ namespace leveldown {
DestroyWorker::DestroyWorker (
char* location
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
) : AsyncWorker(NULL, callback)
, location(location)
{};
@@ -25,14 +25,14 @@ DestroyWorker::~DestroyWorker () {
void DestroyWorker::Execute () {
leveldb::Options options;
- status = leveldb::DestroyDB(location, options);
+ SetStatus(leveldb::DestroyDB(location, options));
}
/** REPAIR WORKER **/
RepairWorker::RepairWorker (
char* location
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
) : AsyncWorker(NULL, callback)
, location(location)
{};
@@ -43,7 +43,7 @@ RepairWorker::~RepairWorker () {
void RepairWorker::Execute () {
leveldb::Options options;
- status = leveldb::RepairDB(location, options);
+ SetStatus(leveldb::RepairDB(location, options));
}
} // namespace leveldown
diff --git a/src/leveldown_async.h b/src/leveldown_async.h
index 6033769..d045a81 100644
--- a/src/leveldown_async.h
+++ b/src/leveldown_async.h
@@ -16,7 +16,7 @@ class DestroyWorker : public AsyncWorker {
public:
DestroyWorker (
char* location
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
);
virtual ~DestroyWorker ();
@@ -30,7 +30,7 @@ class RepairWorker : public AsyncWorker {
public:
RepairWorker (
char* location
- , v8::Persistent<v8::Function> callback
+ , NanCallback *callback
);
virtual ~RepairWorker ();
diff --git a/src/nan.h b/src/nan.h
new file mode 120000
index 0000000..b4f9768
--- /dev/null
+++ b/src/nan.h
@@ -0,0 +1 @@
+../../nan/nan.h
\ No newline at end of file
--
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