diff --git a/lib/bcoin/env.js b/lib/bcoin/env.js index ac638874..86175d04 100644 --- a/lib/bcoin/env.js +++ b/lib/bcoin/env.js @@ -99,6 +99,7 @@ function Environment(options) { this.lru = require('./lru'); this.bloom = require('./bloom'); this.bst = require('./bst'); + this.lowlevelup = require('./lowlevelup'); this.protocol = require('./protocol')(this); this.profiler = require('./profiler')(this); diff --git a/lib/bcoin/ldb.js b/lib/bcoin/ldb.js index b54d739e..7f1edadb 100644 --- a/lib/bcoin/ldb.js +++ b/lib/bcoin/ldb.js @@ -7,7 +7,7 @@ module.exports = function(bcoin) { -var EventEmitter = require('events').EventEmitter; +var LowlevelUp = require('./lowlevelup'); var utils = bcoin.utils; var network = bcoin.protocol.network; var db = {}; @@ -105,117 +105,12 @@ function repair(options, callback) { backend.repair(file, callback); } -/** - * LowlevelUp - * - * Extremely low-level version of levelup. - * The only levelup feature it provides is - * error-wrapping. It gives a nice recallable - * `open()` method and event. It assumes ascii - * keys and binary values. - * - * This avoids pulling in extra deps and - * lowers memory usage. - */ - -function LowlevelUp(file, options) { - var self = this; - - if (!(this instanceof LowlevelUp)) - return new LowlevelUp(file, options); - - EventEmitter.call(this); - - this.loaded = false; - - this.db = new options.db(file); - - // Stay as close to the metal as possible. - // We want to make calls to C++ directly. - while (this.db.db && this.db.db.put && this.db.db !== this.db) - this.db = this.db.db; - - this.binding = this.db; - - if (this.db.binding) - this.binding = this.db.binding; - - this.binding.open(options, function(err) { - if (err) - return self.emit('error', err); - - self.loaded = true; - self.emit('open'); - }); -} - -utils.inherits(LowlevelUp, EventEmitter); - -LowlevelUp.prototype.open = function open(callback) { - if (this.loaded) - return utils.nextTick(callback); - - this.once('open', callback); -}; - -LowlevelUp.prototype.get = function get(key, options, callback) { - if (typeof options === 'function') { - callback = options; - options = {}; - } - return this.binding.get(key, options, function(err, result) { - if (err) { - if (err.notFound || /not\s*found/i.test(err.message)) { - err.notFound = true; - err.type = 'NotFoundError'; - } - return callback(err); - } - return callback(null, result); - }); -}; - -LowlevelUp.prototype.close = function close(callback) { - return this.binding.close(callback); -}; - -LowlevelUp.prototype.put = function put(key, value, options, callback) { - return this.binding.put(key, value, options, callback); -}; - -LowlevelUp.prototype.del = function del(key, options, callback) { - return this.binding.del(key, options, callback); -}; - -LowlevelUp.prototype.batch = function batch(ops, options, callback) { - if (!ops) - return this.binding.batch(); - return this.binding.batch(ops, options, callback); -}; - -LowlevelUp.prototype.iterator = function iterator(options) { - return this.db.iterator(options); -}; - -LowlevelUp.prototype.getProperty = function getProperty(name) { - if (!this.binding.getProperty) - return null; - - return this.binding.getProperty(name); -}; - -LowlevelUp.prototype.approximateSize = function approximateSize(start, end, callback) { - return this.binding.approximateSize(start, end, callback); -}; - /** * Expose */ -var exports = ldb; -exports.LowlevelUp = LowlevelUp; -exports.destroy = destroy; -exports.repair = repair; +ldb.destroy = destroy; +ldb.repair = repair; -return exports; +return ldb; }; diff --git a/lib/bcoin/lowlevelup.js b/lib/bcoin/lowlevelup.js new file mode 100644 index 00000000..0d8a0b3e --- /dev/null +++ b/lib/bcoin/lowlevelup.js @@ -0,0 +1,118 @@ +/** + * lowlevelup.js - low level levelup + * Copyright (c) 2014-2015, Fedor Indutny (MIT License) + * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). + * https://github.com/indutny/bcoin + */ + +var utils = require('./utils'); +var EventEmitter = require('events').EventEmitter; + +/** + * LowlevelUp + * + * Extremely low-level version of levelup. + * The only levelup feature it provides is + * error-wrapping. It gives a nice recallable + * `open()` method and event. It assumes ascii + * keys and binary values. + * + * This avoids pulling in extra deps and + * lowers memory usage. + */ + +function LowlevelUp(file, options) { + var self = this; + + if (!(this instanceof LowlevelUp)) + return new LowlevelUp(file, options); + + EventEmitter.call(this); + + this.loaded = false; + + this.db = new options.db(file); + + // Stay as close to the metal as possible. + // We want to make calls to C++ directly. + while (this.db.db && this.db.db.put && this.db.db !== this.db) + this.db = this.db.db; + + this.binding = this.db; + + if (this.db.binding) + this.binding = this.db.binding; + + this.binding.open(options, function(err) { + if (err) + return self.emit('error', err); + + self.loaded = true; + self.emit('open'); + }); +} + +utils.inherits(LowlevelUp, EventEmitter); + +LowlevelUp.prototype.open = function open(callback) { + if (this.loaded) + return utils.nextTick(callback); + + this.once('open', callback); +}; + +LowlevelUp.prototype.get = function get(key, options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + return this.binding.get(key, options, function(err, result) { + if (err) { + if (err.notFound || /not\s*found/i.test(err.message)) { + err.notFound = true; + err.type = 'NotFoundError'; + } + return callback(err); + } + return callback(null, result); + }); +}; + +LowlevelUp.prototype.close = function close(callback) { + return this.binding.close(callback); +}; + +LowlevelUp.prototype.put = function put(key, value, options, callback) { + return this.binding.put(key, value, options, callback); +}; + +LowlevelUp.prototype.del = function del(key, options, callback) { + return this.binding.del(key, options, callback); +}; + +LowlevelUp.prototype.batch = function batch(ops, options, callback) { + if (!ops) + return this.binding.batch(); + return this.binding.batch(ops, options, callback); +}; + +LowlevelUp.prototype.iterator = function iterator(options) { + return this.db.iterator(options); +}; + +LowlevelUp.prototype.getProperty = function getProperty(name) { + if (!this.binding.getProperty) + return null; + + return this.binding.getProperty(name); +}; + +LowlevelUp.prototype.approximateSize = function approximateSize(start, end, callback) { + return this.binding.approximateSize(start, end, callback); +}; + +/** + * Expose + */ + +module.exports = LowlevelUp; diff --git a/test/wallet-test.js b/test/wallet-test.js index b7eda7d1..5a63ea3c 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -1,5 +1,5 @@ var bn = require('bn.js'); -var bcoin = require('../')({ db: 'memory' }); +var bcoin = require('../')({ db: process.env.BCOIN_TEST_DB || 'memory' }); var constants = bcoin.protocol.constants; var utils = bcoin.utils; var assert = utils.assert;