Permalink
Browse files

Merge pull request #48 from ulikoehler/syncopen

Synchronous Open Support
  • Loading branch information...
2 parents 1a258aa + 34b8aa0 commit fcd6f72388ff1c984d922ccd81590b79554df895 @my8bird committed Feb 7, 2013
Showing with 82 additions and 5 deletions.
  1. +19 −1 src/coffee/leveldb/handle.coffee
  2. +27 −3 src/cpp/handle.cc
  3. +36 −1 test/handle-test.coffee
View
20 src/coffee/leveldb/handle.coffee
@@ -46,6 +46,7 @@ noop = ->
###
+
exports.open = (path, options, callback) ->
# optional options
@@ -59,9 +60,26 @@ exports.open = (path, options, callback) ->
handle = self and new Handle self
callback err, handle
+###
+
+ Synchronous version of open
###
+exports.openSync = (path, options) ->
+ # optional options
+ if typeof options is 'function'
+ callback = options
+ options = null
+
+ #openSync throws an exception on error
+ self = binding.openSync path, options
+ handle = self and new Handle self
+ return handle
+
+
+###
+
Destroy a leveldb database.
@param {String} path The path to the database file.
@@ -107,7 +125,7 @@ exports.repair = (path, options, callback) ->
###
A handle represents an open leveldb database.
-
+hand
###
class Handle
View
30 src/cpp/handle.cc
@@ -164,9 +164,30 @@ class JHandle::OpenAsync : public OpAsync {
Persistent<Value> comparator_;
};
-
-
-
+static Handle<Value> openSync(const Arguments& args) {
+ if (args.Length() != 2 || !args[0]->IsString()) {
+ return ThrowTypeError("Invalid arguments");
+ }
+ //Process the arguments
+ std::string name_ = *String::Utf8Value(args[0]);
+ leveldb::Options options_;
+ Persistent<Value> comparator_;
+ UnpackOptions(args[1], options_, &comparator_);
+ //Open the database
+ leveldb::DB* db_;
+ leveldb::Status status_ = leveldb::DB::Open(options_, name_, &db_);
+ //Check if the database has been opened successfully
+ if (!status_.ok()) {
+ Handle<String> errMsg = String::New(status_.ToString().c_str());
+ return ThrowException(errMsg);
+ }
+ //Create and return the handle object
+ Handle<Value> handleArgs[] = { External::New(db_), Undefined() };
+ if (!comparator_.IsEmpty()) {
+ handleArgs[1] = comparator_;
+ }
+ return JHandle::constructor->GetFunction()->NewInstance(2, handleArgs);
+}
/**
@@ -591,6 +612,9 @@ void JHandle::Initialize(Handle<Object> target) {
NODE_SET_METHOD(target, "open", OpenAsync::Hook<OpenAsync>);
NODE_SET_METHOD(target, "destroy", OpenAsync::Hook<DestroyAsync>);
NODE_SET_METHOD(target, "repair", OpenAsync::Hook<RepairAsync>);
+
+ //Synchronous methods
+ NODE_SET_METHOD(target, "openSync", openSync);
// Set version
target->Set(String::New("majorVersion"),
View
37 test/handle-test.coffee
@@ -1,10 +1,45 @@
-assert = require 'assert'
+assert = require 'assert'
crypto = require 'crypto'
leveldb = require '../lib'
path = require 'path'
fs = require 'fs'
exists = fs.existsSync || path.existsSync
+#Test sync open -- Jus t test a single get/put cycle to verify it's a valid handle
+#As the code is basically the same as the async version's code, all subsequ
+describe 'syncOpen', ->
+ filename = "#{__dirname}/../tmp/open-sync-test-file"
+ db = null
+
+ beforeEach (done) ->
+ db = leveldb.openSync filename, {create_if_missing: true, error_if_exists: true}
+ done()
+ afterEach (done) ->
+ db = null
+ iterator = null
+ leveldb.destroy filename, done
+
+ itShouldBehave = (test) ->
+ describe 'with ascii values', ->
+ key = "Hello"
+ val = "World"
+ test key, val
+ describe 'as_buffer', -> test key, val, true
+ describe 'with buffer values', ->
+ key = new Buffer [1,9,9,9]
+ val = new Buffer [1,2,3,4]
+ test key, val
+ describe 'as_buffer', -> test key, val, true
+ itShouldBehave (key, val, asBuffer) ->
+ it 'should put key/value pair', (done) ->
+ db.put key, val, (err) ->
+ assert.ifError err
+ db.get key, as_buffer: asBuffer, (err, value) ->
+ assert.ifError err
+ assert Buffer.isBuffer value if asBuffer
+ assert.equal val.toString(), value.toString()
+ done()
+
describe 'Handle', ->
filename = "#{__dirname}/../tmp/handle-test-file"

0 comments on commit fcd6f72

Please sign in to comment.