diff --git a/package.json b/package.json index 6c7f91a8..65f7b568 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "tar": "*", "mkfiletree": "*", "readfiletree": "*", - "slow-stream": "*", + "slow-stream": "~0.0.3", "delayed": "*", "boganipsum": "*" }, @@ -43,7 +43,10 @@ "test": "./node_modules/.bin/buster-test", "install": "node-gyp rebuild", "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" + "alltests": "npm test && npm run-script functionaltests", + "publish": "rm -rf ./node_modules/ npm-shrinkwrap.json && npm install --production && npm shrinkwrap && npm publish && rm npm-shrinkwrap.json && npm install", + "sr": "npm shrinkwrap", + "l": "npm ls" }, "license": "MIT", "gypfile": true diff --git a/src/database.cc b/src/database.cc index 90cad1ec..3be28c07 100644 --- a/src/database.cc +++ b/src/database.cc @@ -65,6 +65,14 @@ leveldb::Iterator* Database::NewIterator (ReadOptions* options) { return db->NewIterator(*options); } +const leveldb::Snapshot* Database::NewSnapshot () { + return db->GetSnapshot(); +} + +void Database::ReleaseSnapshot (const leveldb::Snapshot* snapshot) { + return db->ReleaseSnapshot(snapshot); +} + void Database::CloseDatabase () { delete db; db = NULL; diff --git a/src/database.h b/src/database.h index 1c333bb3..d4dcd1c9 100644 --- a/src/database.h +++ b/src/database.h @@ -23,13 +23,15 @@ class Database : public node::ObjectWrap { static void Init (); static v8::Handle NewInstance (const v8::Arguments& args); - Status OpenDatabase (Options* options, string location); - Status PutToDatabase (WriteOptions* options, Slice key, Slice value); - Status GetFromDatabase (ReadOptions* options, Slice key, string& value); - Status DeleteFromDatabase (WriteOptions* options, Slice key); - Status WriteBatchToDatabase (WriteOptions* options, WriteBatch* batch); + Status OpenDatabase (Options* options, string location); + Status PutToDatabase (WriteOptions* options, Slice key, Slice value); + Status GetFromDatabase (ReadOptions* options, Slice key, string& value); + Status DeleteFromDatabase (WriteOptions* options, Slice key); + Status WriteBatchToDatabase (WriteOptions* options, WriteBatch* batch); leveldb::Iterator* NewIterator (ReadOptions* options); - void CloseDatabase (); + const leveldb::Snapshot* NewSnapshot (); + void ReleaseSnapshot (const leveldb::Snapshot* snapshot); + void CloseDatabase (); private: Database (); diff --git a/test/common.js b/test/common.js index d75b0988..8612af94 100644 --- a/test/common.js +++ b/test/common.js @@ -92,4 +92,43 @@ module.exports.commonSetUp = function () { this.closeableDatabases = [] this.openTestDatabase = module.exports.openTestDatabase.bind(this) this.timeout = 10000 -} \ No newline at end of file +} + +module.exports.readStreamSetUp = function () { + module.exports.commonSetUp.call(this) + + this.readySpy = this.spy() + this.dataSpy = this.spy() + this.endSpy = this.spy() + this.sourceData = [] + + for (var i = 0; i < 100; i++) { + var k = (i < 10 ? '0' : '') + i + this.sourceData.push({ + type : 'put' + , key : k + , value : Math.random() + }) + } + + this.verify = function (rs, done, data) { + if (!data) data = this.sourceData // can pass alternative data array for verification + assert.isFalse(rs.writable) + assert.isFalse(rs.readable) + assert.equals(this.readySpy.callCount, 1, 'ReadStream emitted single "ready" event') + assert.equals(this.endSpy.callCount, 1, 'ReadStream emitted single "end" event') + assert.equals(this.dataSpy.callCount, data.length, 'ReadStream emitted correct number of "data" events') + data.forEach(function (d, i) { + var call = this.dataSpy.getCall(i) + if (call) { + //console.log('call', i, ':', call.args[0].key, '=', call.args[0].value, '(expected', d.key, '=', d.value, ')') + assert.equals(call.args.length, 1, 'ReadStream "data" event #' + i + ' fired with 1 argument') + refute.isNull(call.args[0].key, 'ReadStream "data" event #' + i + ' argument has "key" property') + refute.isNull(call.args[0].value, 'ReadStream "data" event #' + i + ' argument has "value" property') + assert.equals(call.args[0].key, d.key, 'ReadStream "data" event #' + i + ' argument has correct "key"') + assert.equals(call.args[0].value, d.value, 'ReadStream "data" event #' + i + ' argument has correct "value"') + } + }.bind(this)) + done() + }.bind(this) +} diff --git a/test/read-stream-test.js b/test/read-stream-test.js index f0c2ca7b..cc251298 100644 --- a/test/read-stream-test.js +++ b/test/read-stream-test.js @@ -10,44 +10,7 @@ var buster = require('buster') , async = require('async') buster.testCase('ReadStream', { - 'setUp': function () { - common.commonSetUp.call(this) - - this.readySpy = this.spy() - this.dataSpy = this.spy() - this.endSpy = this.spy() - this.sourceData = [] - - for (var i = 0; i < 100; i++) { - var k = (i < 10 ? '0' : '') + i - this.sourceData.push({ - type : 'put' - , key : k - , value : Math.random() - }) - } - - this.verify = function (rs, done, data) { - if (!data) data = this.sourceData // can pass alternative data array for verification - assert.isFalse(rs.writable) - assert.isFalse(rs.readable) - assert.equals(this.readySpy.callCount, 1, 'ReadStream emitted single "ready" event') - assert.equals(this.endSpy.callCount, 1, 'ReadStream emitted single "end" event') - assert.equals(this.dataSpy.callCount, data.length, 'ReadStream emitted correct number of "data" events') - data.forEach(function (d, i) { - var call = this.dataSpy.getCall(i) - if (call) { - //console.log('call', i, ':', call.args[0].key, '=', call.args[0].value, '(expected', d.key, '=', d.value, ')') - assert.equals(call.args.length, 1, 'ReadStream "data" event #' + i + ' fired with 1 argument') - refute.isNull(call.args[0].key, 'ReadStream "data" event #' + i + ' argument has "key" property') - refute.isNull(call.args[0].value, 'ReadStream "data" event #' + i + ' argument has "value" property') - assert.equals(call.args[0].key, d.key, 'ReadStream "data" event #' + i + ' argument has correct "key"') - assert.equals(call.args[0].value, d.value, 'ReadStream "data" event #' + i + ' argument has correct "value"') - } - }.bind(this)) - done() - }.bind(this) - } + 'setUp': common.readStreamSetUp , 'tearDown': common.commonTearDown