Skip to content

Commit

Permalink
Breaking: parent db must support deferredOpen
Browse files Browse the repository at this point in the history
DeferredOpen means that the db opens itself and defers operations
until it's open. Currently that's only supported by level(up) and
friends. Before, subleveldown would also accept abstract-leveldown
db's that were not wrapped in levelup.

Opening and closing a sublevel no longer opens or closes the parent
db. The sublevel does wait for the parent to open (which in the
case of levelup already happens automatically) but never initiates
a state change.

Drops support of old modules:

- memdb (use level-mem instead)
- deferred-leveldown < 2.0.0 (and thus levelup < 2.0.0)
- abstract-leveldown < 2.4.0

Closes #84, #83 and #60.
  • Loading branch information
vweevers committed Apr 4, 2020
1 parent 01b2d50 commit 3e31520
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 76 deletions.
61 changes: 43 additions & 18 deletions leveldown.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,36 @@ function SubDown (db, prefix, opts) {
})

this.db = db
this.leveldown = null
this.ownPrefix = separator + prefix + separator
this.prefix = this.ownPrefix
this.prefix = separator + prefix + separator
this._beforeOpen = opts.open

var self = this
var manifest = db.supports || {}

// The parent db must open itself or be (re)opened by the user because a
// sublevel can't (shouldn't) initiate state changes on the rest of the db.
if (!manifest.deferredOpen && !reachdown.is(db, 'levelup')) {
throw new Error('The parent db must support deferredOpen')
}

var subdb = reachdown(db, 'subleveldown')

if (subdb) {
// Old subleveldown doesn't know its prefix and leveldown until opened
if (!subdb.prefix || !subdb.leveldown) {
throw new Error('Incompatible with subleveldown < 5.0.0')
}

this.prefix = subdb.prefix + this.prefix
this.leveldown = subdb.leveldown
} else {
this.leveldown = reachdown(db, matchdown, false)
}

// Old deferred-leveldown doesn't expose its underlying db until opened
if (reachdown.is(this.leveldown, 'deferred-leveldown')) {
throw new Error('Incompatible with deferred-leveldown < 2.0.0')
}

this._wrap = {
gt: function (x) {
Expand All @@ -91,28 +115,29 @@ inherits(SubDown, abstract.AbstractLevelDOWN)

SubDown.prototype.type = 'subleveldown'

// TODO: remove _open() once abstract-leveldown supports deferredOpen,
// because that means we can always do operations on this.leveldown.
SubDown.prototype._open = function (opts, cb) {
var self = this

this.db.open(function (err) {
if (err) return cb(err)
// TODO: make _isOpening public in levelup or add a method like
// ready(cb) which waits for - but does not initiate - a state change.
var m = typeof this.db.isOpening === 'function' ? 'isOpening' : '_isOpening'

var subdb = reachdown(self.db, 'subleveldown')
if (this.db[m]()) {
this.db.once('open', onopen)
} else {
this._nextTick(onopen)
}

if (subdb && subdb.prefix) {
self.prefix = subdb.prefix + self.ownPrefix
self.leveldown = subdb.leveldown
} else {
self.leveldown = reachdown(self.db, matchdown, false)
}
function onopen () {
if (!self.db.isOpen()) return cb(new Error('Parent db is not open'))

if (self._beforeOpen) self._beforeOpen(cb)
else cb()
})
}
// TODO: add hooks to abstract-leveldown
if (self._beforeOpen) return self._beforeOpen(cb)

SubDown.prototype._close = function (cb) {
this.leveldown.close(cb)
cb()
}
}

SubDown.prototype._serializeKey = function (key) {
Expand Down
1 change: 1 addition & 0 deletions matchdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = function matchdown (db, type) {
if (type === 'levelup') return false
if (type === 'encoding-down') return false
if (type === 'deferred-leveldown') return false
if (type === 'subleveldown') return false

return true
}
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
"test": "test"
},
"dependencies": {
"abstract-leveldown": "^6.1.1",
"abstract-leveldown": "^6.2.3",
"encoding-down": "^6.2.0",
"inherits": "^2.0.3",
"level-option-wrap": "^1.1.0",
"levelup": "^4.3.1",
"reachdown": "^1.0.0"
"reachdown": "github:vweevers/reachdown"
},
"devDependencies": {
"after": "^0.8.2",
Expand All @@ -31,7 +31,6 @@
"hallmark": "^2.0.0",
"level-community": "^3.0.0",
"level-concat-iterator": "^2.0.1",
"memdb": "^1.3.1",
"memdown": "^5.0.0",
"nyc": "^14.0.0",
"standard": "^14.0.0",
Expand Down
Loading

0 comments on commit 3e31520

Please sign in to comment.