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.
176 lines
4.4 KiB
176 lines
4.4 KiB
var EventEmitter = require('events').EventEmitter |
|
var addpre = require('./range').addPrefix |
|
|
|
var errors = require('levelup/lib/errors') |
|
|
|
function isFunction (f) { |
|
return 'function' === typeof f |
|
} |
|
|
|
function isString (s) { |
|
return 'string' === typeof s |
|
} |
|
|
|
function isObject (o) { |
|
return o && 'object' === typeof o |
|
} |
|
|
|
var version = require('./package.json').version |
|
|
|
var sublevel = module.exports = function (nut, prefix, createStream, options) { |
|
var emitter = new EventEmitter() |
|
emitter.sublevels = {} |
|
emitter.options = options |
|
|
|
emitter.version = version |
|
|
|
emitter.methods = {} |
|
prefix = prefix || [] |
|
|
|
function errback (err) { if (err) emitter.emit('error', err) } |
|
|
|
createStream = createStream || function (e) { return e } |
|
|
|
function mergeOpts(opts) { |
|
var o = {} |
|
if(options) |
|
for(var k in options) |
|
if(options[k] != undefined)o[k] = options[k] |
|
if(opts) |
|
for(var k in opts) |
|
if(opts[k] != undefined) o[k] = opts[k] |
|
return o |
|
} |
|
|
|
emitter.put = function (key, value, opts, cb) { |
|
if('function' === typeof opts) cb = opts, opts = {} |
|
if(!cb) cb = errback |
|
|
|
nut.apply([{ |
|
key: key, value: value, |
|
prefix: prefix.slice(), type: 'put' |
|
}], mergeOpts(opts), function (err) { |
|
if(!err) { emitter.emit('put', key, value); cb(null) } |
|
if(err) return cb(err) |
|
}) |
|
} |
|
|
|
emitter.prefix = function () { |
|
return prefix.slice() |
|
} |
|
|
|
emitter.del = function (key, opts, cb) { |
|
if('function' === typeof opts) cb = opts, opts = {} |
|
if(!cb) cb = errback |
|
|
|
nut.apply([{ |
|
key: key, |
|
prefix: prefix.slice(), type: 'del' |
|
}], mergeOpts(opts), function (err) { |
|
if(!err) { emitter.emit('del', key); cb(null) } |
|
if(err) return cb(err) |
|
}) |
|
} |
|
|
|
emitter.batch = function (ops, opts, cb) { |
|
if('function' === typeof opts) |
|
cb = opts, opts = {} |
|
if(!cb) cb = errback |
|
|
|
ops = ops.map(function (op) { |
|
return { |
|
key: op.key, |
|
value: op.value, |
|
prefix: op.prefix || prefix, |
|
keyEncoding: op.keyEncoding, // * |
|
valueEncoding: op.valueEncoding, // * (TODO: encodings on sublevel) |
|
type: op.type |
|
} |
|
}) |
|
|
|
nut.apply(ops, mergeOpts(opts), function (err) { |
|
if(!err) { emitter.emit('batch', ops); cb(null) } |
|
if(err) return cb(err) |
|
}) |
|
} |
|
|
|
emitter.get = function (key, opts, cb) { |
|
if('function' === typeof opts) |
|
cb = opts, opts = {} |
|
nut.get(key, prefix, mergeOpts(opts), function (err, value) { |
|
if(err) cb(new errors.NotFoundError('Key not found in database', err)) |
|
else cb(null, value) |
|
}) |
|
} |
|
|
|
emitter.clone = function(opts) { |
|
return sublevel(nut, prefix, createStream, mergeOpts(opts)) |
|
} |
|
|
|
emitter.sublevel = function (name, opts) { |
|
return emitter.sublevels[name] = |
|
emitter.sublevels[name] || sublevel(nut, prefix.concat(name), createStream, mergeOpts(opts)) |
|
} |
|
|
|
emitter.pre = function (key, hook) { |
|
if(isFunction(key)) return nut.pre([prefix], key) |
|
if(isString(key)) return nut.pre([prefix, key], hook) |
|
if(isObject(key)) return nut.pre(addpre(prefix, key), hook) |
|
|
|
throw new Error('not implemented yet') |
|
} |
|
|
|
emitter.post = function (key, hook) { |
|
if(isFunction(key)) return nut.post([prefix], key) |
|
if(isString(key)) return nut.post([prefix, key], hook) |
|
if(isObject(key)) return nut.post(addpre(prefix, key), hook) |
|
|
|
//TODO: handle ranges, needed for level-live-stream, etc. |
|
throw new Error('not implemented yet') |
|
} |
|
|
|
emitter.readStream = |
|
emitter.createReadStream = function (opts) { |
|
opts = mergeOpts(opts) |
|
opts.prefix = prefix |
|
var stream |
|
var it = nut.iterator(opts, function (err, it) { |
|
stream.setIterator(it) |
|
}) |
|
|
|
stream = createStream(opts, nut.createDecoder(opts)) |
|
if(it) stream.setIterator(it) |
|
|
|
return stream |
|
} |
|
|
|
emitter.valueStream = |
|
emitter.createValueStream = function (opts) { |
|
opts = opts || {} |
|
opts.values = true |
|
opts.keys = false |
|
return emitter.createReadStream(opts) |
|
} |
|
|
|
emitter.keyStream = |
|
emitter.createKeyStream = function (opts) { |
|
opts = opts || {} |
|
opts.values = false |
|
opts.keys = true |
|
return emitter.createReadStream(opts) |
|
} |
|
|
|
emitter.close = function (cb) { |
|
//TODO: deregister all hooks |
|
cb = cb || function () {} |
|
if (!prefix.length) nut.close(cb) |
|
else process.nextTick(cb) |
|
} |
|
|
|
emitter.isOpen = nut.isOpen |
|
emitter.isClosed = nut.isClosed |
|
|
|
emitter.location = nut.location |
|
|
|
return emitter |
|
}
|
|
|