You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
4.3 KiB

'use strict'
var AbstractLevelDOWN = require('abstract-leveldown').AbstractLevelDOWN
var AbstractChainedBatch = require('abstract-leveldown').AbstractChainedBatch
var AbstractIterator = require('abstract-leveldown').AbstractIterator
var inherits = require('inherits')
var Codec = require('level-codec')
var EncodingError = require('level-errors').EncodingError
var rangeMethods = ['approximateSize', 'compactRange']
module.exports = DB.default = DB
function DB (db, opts) {
if (!(this instanceof DB)) return new DB(db, opts)
var manifest = db.supports || {}
var additionalMethods = manifest.additionalMethods || {}
AbstractLevelDOWN.call(this, manifest)
this.supports.encodings = true
this.supports.additionalMethods = {}
rangeMethods.forEach(function (m) {
// TODO (future major): remove this fallback
var fallback = typeof db[m] === 'function'
if (additionalMethods[m] || fallback) {
this.supports.additionalMethods[m] = true
this[m] = function (start, end, opts, cb) {
start = this.codec.encodeKey(start, opts)
end = this.codec.encodeKey(end, opts)
return this.db[m](start, end, opts, cb)
}
}
}, this)
opts = opts || {}
if (typeof opts.keyEncoding === 'undefined') opts.keyEncoding = 'utf8'
if (typeof opts.valueEncoding === 'undefined') opts.valueEncoding = 'utf8'
this.db = db
this.codec = new Codec(opts)
}
inherits(DB, AbstractLevelDOWN)
DB.prototype.type = 'encoding-down'
DB.prototype._serializeKey =
DB.prototype._serializeValue = function (datum) {
return datum
}
DB.prototype._open = function (opts, cb) {
this.db.open(opts, cb)
}
DB.prototype._close = function (cb) {
this.db.close(cb)
}
DB.prototype._put = function (key, value, opts, cb) {
key = this.codec.encodeKey(key, opts)
value = this.codec.encodeValue(value, opts)
this.db.put(key, value, opts, cb)
}
DB.prototype._get = function (key, opts, cb) {
var self = this
key = this.codec.encodeKey(key, opts)
opts.asBuffer = this.codec.valueAsBuffer(opts)
this.db.get(key, opts, function (err, value) {
if (err) return cb(err)
try {
value = self.codec.decodeValue(value, opts)
} catch (err) {
return cb(new EncodingError(err))
}
cb(null, value)
})
}
DB.prototype._del = function (key, opts, cb) {
key = this.codec.encodeKey(key, opts)
this.db.del(key, opts, cb)
}
DB.prototype._chainedBatch = function () {
return new Batch(this)
}
DB.prototype._batch = function (ops, opts, cb) {
ops = this.codec.encodeBatch(ops, opts)
this.db.batch(ops, opts, cb)
}
DB.prototype._iterator = function (opts) {
opts.keyAsBuffer = this.codec.keyAsBuffer(opts)
opts.valueAsBuffer = this.codec.valueAsBuffer(opts)
return new Iterator(this, opts)
}
DB.prototype._clear = function (opts, callback) {
opts = this.codec.encodeLtgt(opts)
this.db.clear(opts, callback)
}
function Iterator (db, opts) {
AbstractIterator.call(this, db)
this.codec = db.codec
this.keys = opts.keys
this.values = opts.values
this.opts = this.codec.encodeLtgt(opts)
this.it = db.db.iterator(this.opts)
}
inherits(Iterator, AbstractIterator)
Iterator.prototype._next = function (cb) {
var self = this
this.it.next(function (err, key, value) {
if (err) return cb(err)
try {
if (self.keys && typeof key !== 'undefined') {
key = self.codec.decodeKey(key, self.opts)
} else {
key = undefined
}
if (self.values && typeof value !== 'undefined') {
value = self.codec.decodeValue(value, self.opts)
} else {
value = undefined
}
} catch (err) {
return cb(new EncodingError(err))
}
cb(null, key, value)
})
}
Iterator.prototype._seek = function (key) {
key = this.codec.encodeKey(key, this.opts)
this.it.seek(key)
}
Iterator.prototype._end = function (cb) {
this.it.end(cb)
}
function Batch (db, codec) {
AbstractChainedBatch.call(this, db)
this.codec = db.codec
this.batch = db.db.batch()
}
inherits(Batch, AbstractChainedBatch)
Batch.prototype._put = function (key, value) {
key = this.codec.encodeKey(key)
value = this.codec.encodeValue(value)
this.batch.put(key, value)
}
Batch.prototype._del = function (key) {
key = this.codec.encodeKey(key)
this.batch.del(key)
}
Batch.prototype._clear = function () {
this.batch.clear()
}
Batch.prototype._write = function (opts, cb) {
this.batch.write(opts, cb)
}