From 4c24d7440287d780e452f8d341bbbc012482e5bc Mon Sep 17 00:00:00 2001 From: Yichao 'Peak' Ji Date: Mon, 28 Nov 2016 13:00:21 +0800 Subject: [PATCH] seek with buffers --- iterator.js | 2 -- src/iterator.cc | 14 ++++++++++++- test/iterator-test.js | 47 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/iterator.js b/iterator.js index d5181a6c..ddc8872e 100644 --- a/iterator.js +++ b/iterator.js @@ -15,8 +15,6 @@ function Iterator (db, options) { util.inherits(Iterator, AbstractIterator) Iterator.prototype.seek = function (key) { - if (typeof key !== 'string') - throw new Error('seek requires a string key') this.cache = null this.binding.seek(key) } diff --git a/src/iterator.cc b/src/iterator.cc index 5ac0bf67..c74bcffc 100644 --- a/src/iterator.cc +++ b/src/iterator.cc @@ -215,9 +215,21 @@ void checkEndCallback (Iterator* iterator) { NAN_METHOD(Iterator::Seek) { Iterator* iterator = Nan::ObjectWrap::Unwrap(info.This()); + + if (!node::Buffer::HasInstance(info[0]) && !info[0]->IsString()) + return Nan::ThrowError("seek() requires a string or buffer key"); + + if (StringOrBufferLength(info[0]) == 0) + return Nan::ThrowError("cannot seek() to an empty key"); + + std::string* key = NULL; + v8::Local keyBuffer = info[0].As(); + LD_STRING_OR_BUFFER_TO_COPY(_key, keyBuffer, key); + key = new std::string(_keyCh_, _keySz_); + delete[] _keyCh_; + iterator->GetIterator(); leveldb::Iterator* dbIterator = iterator->dbIterator; - Nan::Utf8String key(info[0]); dbIterator->Seek(*key); iterator->seeking = true; diff --git a/test/iterator-test.js b/test/iterator-test.js index 87db93b7..75df4f40 100644 --- a/test/iterator-test.js +++ b/test/iterator-test.js @@ -6,17 +6,28 @@ const test = require('tape') abstract.all(leveldown, test, testCommon) -make('iterator throws if key is not a string', function (db, t, done) { - var ite = db.iterator() - var error - try { - ite.seek() - } catch (e) { - error = e - } +make('iterator throws if key is not a string or buffer', function (db, t, done) { + var keys = [null, undefined, 1, true, false] + var pending = keys.length + + keys.forEach(function (key) { + var error + var ite = db.iterator() + + try { + ite.seek(key) + } catch (e) { + error = e + } - t.ok(error, 'had error') - t.end() + t.ok(error, 'had error from seek()') + ite.end(end) + }) + + function end(err) { + t.error(err, 'no error from end()') + if (!--pending) done() + } }) make('iterator is seekable', function (db, t, done) { @@ -35,6 +46,22 @@ make('iterator is seekable', function (db, t, done) { }) }) +make('iterator is seekable with buffer', function (db, t, done) { + var ite = db.iterator() + ite.seek(Buffer('two')) + ite.next(function (err, key, value) { + t.error(err, 'no error from next()') + t.equal(key.toString(), 'two', 'key matches') + t.equal(value.toString(), '2', 'value matches') + ite.next(function (err, key, value) { + t.error(err, 'no error from next()') + t.equal(key, undefined, 'end of iterator') + t.equal(value, undefined, 'end of iterator') + ite.end(done) + }) + }) +}) + make('reverse seek in the middle', function (db, t, done) { var ite = db.iterator({reverse: true, limit: 1}) ite.seek('three!')