Skip to content
This repository was archived by the owner on Dec 2, 2024. It is now read-only.
/ subleveldown Public archive

Commit 9c59c60

Browse files
authored
Merge pull request #61 from Level/greenkeeper/initial
2 parents f06ad45 + 3981790 commit 9c59c60

File tree

7 files changed

+101
-91
lines changed

7 files changed

+101
-91
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
.nyc_output/
3+
coverage/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ sub(db, 'one', { valueEncoding: 'json' })
5959
sub(db, 'two', { keyEncoding: 'binary' })
6060
```
6161

62-
There is one limitation, however: keys must _encode to_ either strings or Buffers. This is not likely to affect you, unless you use custom encodings or the `id` encoding (which bypasses encodings and thus makes it your responsibility to ensure keys are either strings or Buffers).
62+
There is one limitation, however: keys must _encode to_ either strings or Buffers. This is not likely to affect you, unless you use custom encodings or the `id` encoding (which bypasses encodings and thus makes it your responsibility to ensure keys are either strings or Buffers). If in that case you do pass in a key that is not a string or Buffer, it will be irreversibly converted to a string.
6363

6464
Authored by [@mafintosh](https://github.com/mafintosh) and inspired by [`level-sublevel`][level-sublevel] by [@dominictarr](https://github.com/dominictarr), `subleveldown` has become an official part of [Level][level-org]. As `level-sublevel` is no longer under active development, we recommend switching to `subleveldown` to get the latest and greatest of the Level ecosystem. These two modules largely offer the same functionality, except for [hooks](https://github.com/dominictarr/level-sublevel#hooks) and [per-batch prefixes](https://github.com/dominictarr/level-sublevel#batches).
6565

example.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ var sub = require('./')
22
var levelup = require('levelup')
33
var memdown = require('memdown')
44

5-
var db = levelup('test', {db: memdown})
5+
var db = levelup('test', { db: memdown })
66

7-
var test = sub(db, 'test', {valueEncoding: 'utf-8', separator: '@'})
8-
var test2 = sub(test, 'tester', {valueEncoding: 'utf-8', separator: '@'})
7+
var test = sub(db, 'test', { valueEncoding: 'utf-8', separator: '@' })
8+
var test2 = sub(test, 'tester', { valueEncoding: 'utf-8', separator: '@' })
99

1010
test.put('hi', 'der')
1111
test.put('hello', ['world'], function () {

leveldown.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ function concat (prefix, key, force) {
1212
return key
1313
}
1414

15-
function SubIterator (ite, prefix) {
15+
function SubIterator (db, ite, prefix) {
1616
this.iterator = ite
1717
this.prefix = prefix
1818

19-
abstract.AbstractIterator.call(this)
19+
abstract.AbstractIterator.call(this, db)
2020
}
2121

2222
inherits(SubIterator, abstract.AbstractIterator)
@@ -36,7 +36,7 @@ SubIterator.prototype._end = function (cb) {
3636

3737
function SubDown (db, prefix, opts) {
3838
if (!(this instanceof SubDown)) return new SubDown(db, prefix, opts)
39-
if (typeof opts === 'string') opts = {separator: opts}
39+
if (typeof opts === 'string') opts = { separator: opts }
4040
if (!opts) opts = {}
4141

4242
var separator = opts.separator
@@ -63,7 +63,7 @@ function SubDown (db, prefix, opts) {
6363
}
6464
}
6565

66-
abstract.AbstractLevelDOWN.call(this, 'no-location')
66+
abstract.AbstractLevelDOWN.call(this)
6767
}
6868

6969
inherits(SubDown, abstract.AbstractLevelDOWN)
@@ -94,6 +94,10 @@ SubDown.prototype._close = function (cb) {
9494
this.leveldown.close(cb)
9595
}
9696

97+
SubDown.prototype._serializeKey = function (key) {
98+
return Buffer.isBuffer(key) ? key : String(key)
99+
}
100+
97101
SubDown.prototype._put = function (key, value, opts, cb) {
98102
this.leveldown.put(concat(this.prefix, key), value, opts, cb)
99103
}
@@ -107,16 +111,12 @@ SubDown.prototype._del = function (key, opts, cb) {
107111
}
108112

109113
SubDown.prototype._batch = function (operations, opts, cb) {
110-
if (arguments.length === 0) return new abstract.AbstractChainedBatch(this)
111-
if (!Array.isArray(operations)) return this.leveldown.batch.apply(null, arguments)
112-
113-
var subops = new Array(operations.length)
114+
// No need to make a copy of the array, abstract-leveldown does that
114115
for (var i = 0; i < operations.length; i++) {
115-
var o = operations[i]
116-
subops[i] = {type: o.type, key: concat(this.prefix, o.key), value: o.value}
116+
operations[i].key = concat(this.prefix, operations[i].key)
117117
}
118118

119-
this.leveldown.batch(subops, opts, cb)
119+
this.leveldown.batch(operations, opts, cb)
120120
}
121121

122122
function extend (xopts, opts) {
@@ -137,12 +137,12 @@ function extend (xopts, opts) {
137137
}
138138

139139
function fixRange (opts) {
140-
return (!opts.reverse || (!opts.end && !opts.start)) ? opts : {start: opts.end, end: opts.start}
140+
return (!opts.reverse || (!opts.end && !opts.start)) ? opts : { start: opts.end, end: opts.start }
141141
}
142142

143143
SubDown.prototype._iterator = function (opts) {
144144
var xopts = extend(wrap(fixRange(opts), this._wrap), opts)
145-
return new SubIterator(this.leveldown.iterator(xopts), this.prefix)
145+
return new SubIterator(this, this.leveldown.iterator(xopts), this.prefix)
146146
}
147147

148148
module.exports = SubDown

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,20 @@
1616
"test": "test"
1717
},
1818
"dependencies": {
19-
"abstract-leveldown": "^5.0.0",
20-
"encoding-down": "^5.0.3",
19+
"abstract-leveldown": "^6.0.2",
20+
"encoding-down": "^6.0.1",
2121
"inherits": "^2.0.3",
2222
"level-option-wrap": "^1.1.0",
23-
"levelup": "^3.0.1"
23+
"levelup": "^4.0.1"
2424
},
2525
"devDependencies": {
2626
"coveralls": "^3.0.2",
2727
"dependency-check": "^3.3.0",
2828
"hallmark": "^0.1.0",
2929
"level-community": "^3.0.0",
30-
"memdown": "^3.0.0",
31-
"nyc": "^12.0.2",
32-
"standard": "^11.0.1",
30+
"memdown": "^4.0.0",
31+
"nyc": "^13.3.0",
32+
"standard": "^12.0.1",
3333
"tape": "^4.9.0"
3434
},
3535
"hallmark": {

test/common.js

Lines changed: 0 additions & 51 deletions
This file was deleted.

test/index.js

Lines changed: 77 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,38 @@
11
var test = require('tape')
2+
var suite = require('abstract-leveldown/test')
23
var memdown = require('memdown')
34
var encoding = require('encoding-down')
45
var subdown = require('../leveldown')
56
var subdb = require('..')
67
var levelup = require('levelup')
7-
var testCommon = require('./common')
8-
9-
require('abstract-leveldown/abstract/open-test').args(down, test, testCommon)
10-
require('abstract-leveldown/abstract/open-test').open(down, test, testCommon)
11-
require('abstract-leveldown/abstract/del-test').all(down, test, testCommon)
12-
require('abstract-leveldown/abstract/get-test').all(down, test, testCommon)
13-
require('abstract-leveldown/abstract/put-test').all(down, test, testCommon)
14-
require('abstract-leveldown/abstract/put-get-del-test').all(down, test, testCommon)
15-
require('abstract-leveldown/abstract/batch-test').all(down, test, testCommon)
16-
require('abstract-leveldown/abstract/chained-batch-test').all(down, test, testCommon)
17-
require('abstract-leveldown/abstract/close-test').close(down, test, testCommon)
18-
require('abstract-leveldown/abstract/iterator-test').all(down, test, testCommon)
19-
require('abstract-leveldown/abstract/iterator-range-test').all(down, test, testCommon)
208

9+
// Test abstract-leveldown compliance
10+
suite({
11+
test: test,
12+
factory: function () {
13+
return subdown(levelup(memdown()), 'test')
14+
},
15+
16+
// Unsupported features
17+
seek: false,
18+
createIfMissing: false,
19+
errorIfExists: false
20+
})
21+
22+
// Test without a user-provided levelup layer
23+
suite({
24+
test: test,
25+
factory: function () {
26+
return subdown(memdown(), 'test')
27+
},
28+
29+
// Unsupported features
30+
seek: false,
31+
createIfMissing: false,
32+
errorIfExists: false
33+
})
34+
35+
// Additional tests for this implementation
2136
test('SubDown constructor', function (t) {
2237
t.test('can be called without new', function (t) {
2338
var sub = subdown()
@@ -72,6 +87,24 @@ test('SubDb main function', function (t) {
7287
})
7388
})
7489

90+
t.test('error from open() bubbles up', function (t) {
91+
t.plan(1)
92+
93+
var mockdb = {
94+
open: function (cb) {
95+
process.nextTick(cb, new Error('error from underlying store'))
96+
}
97+
}
98+
99+
subdb(mockdb, 'test')
100+
101+
// Awkward: we don't pass a callback to levelup() so levelup goes
102+
// into "promise mode" which we can't catch properly
103+
process.once('unhandledRejection', (err) => {
104+
t.is(err.message, 'error from underlying store')
105+
})
106+
})
107+
75108
t.test('levelup *down is set to subdown which has correct storage', function (t) {
76109
var db = levelup(memdown())
77110
var sub = subdb(db, 'test')
@@ -184,8 +217,35 @@ test('SubDb main function', function (t) {
184217
var sub = subdb(db, { valueEncoding: 'json' })
185218
t.equal(sub.db._db.db.prefix, '!!')
186219
})
187-
})
188220

189-
function down (loc) {
190-
return subdown(levelup(memdown()), 'test')
191-
}
221+
t.test('errors from iterator bubble up', function (t) {
222+
t.plan(2)
223+
224+
var mockdb = {
225+
open: function (cb) {
226+
process.nextTick(cb)
227+
},
228+
iterator: function () {
229+
return {
230+
next: function (cb) {
231+
process.nextTick(cb, new Error('next() error from underlying store'))
232+
},
233+
end: function (cb) {
234+
process.nextTick(cb, new Error('end() error from underlying store'))
235+
}
236+
}
237+
}
238+
}
239+
240+
var sub = subdb(mockdb, 'test')
241+
var it = sub.iterator()
242+
243+
it.next(function (err) {
244+
t.is(err.message, 'next() error from underlying store')
245+
246+
it.end(function (err) {
247+
t.is(err.message, 'end() error from underlying store')
248+
})
249+
})
250+
})
251+
})

0 commit comments

Comments
 (0)