Comments (13)
That line calls levelup#down(). What would that implementation look like?
return this.db.down(type)
. It doesn't matter if this.db
is deferred-leveldown
or the open db
, the result would be the same.
I'm wondering what we can do as minimal change to get this working, without having to rewrite the whole world
I was thinking about that too. We might be able to get by with while (db.db) db = db.db
with some additional check that db.db
is an abstract-leveldown
(and not an underlying IndexedDB, for example).
from subleveldown.
@vweevers Had to tweak the first subdb
check to this.leveldown = down(subdb.db)
since calling this.leveldown = down(subdb)
will result back in subdb
.
from subleveldown.
Amazing write-up!
We need to implement a proper static encDown.isEncodingDown() function though which should support cross realms (using Symbol.for() etc).
I think it'd suffice to do it the same as the browserified Buffer.isBuffer()
:
encDown.prototype._isEncodingDown = true
encDown.isEncodingDown = function (db) {
return db != null && db._isEncodingDown === true &&
db !== encDown.prototype // so encDown.isEncodingDown(encDown.prototype) will be false
}
However, I wonder if there's isn't a more generic solution. There are similar use cases for wanting to get the "inner db", like getting access to .iterator()
which is not exposed by levelup
. If you want to get to leveldown's iterator for its iterator.seek()
method, you possibly have to bypass deferred-leveldown
and encoding-down
.
So what if both levelup
and abstract-leveldown
had a innerDown
method, that punches through the layers to get the innermost db
?
levelup
would return this.db
, abstract-leveldown
would default to returning this
, deferred-leveldown
would return this._db
, subleveldown
would return this.leveldown
.
from subleveldown.
a innerDown method
Or down()
:)
from subleveldown.
Hmm down()
would also need an optional type
argument that tells it where to stop traversing:
AbstractLevelDOWN.prototype.down = function (type) {
var db = this._down(type)
return db == null ? null : db === this ? db : db.down(type)
}
AbstractLevelDOWN.prototype._down = function (type) {
return type ? null : this
}
SubDown.prototype._down = function (type) {
return type === 'subleveldown' ? this : this.leveldown
}
SubDown.prototype._open = function (opts, cb) {
if (this.db.isOpen()) {
var subdb = this.db.down('subleveldown')
if (subdb && subdb.prefix) {
this.prefix = subdb.prefix + this.prefix
this.leveldown = subdb.down()
} else {
this.leveldown = this.db.down()
}
}
..
}
from subleveldown.
However, I wonder if there's isn't a more generic solution. There are similar use cases for wanting to get the "inner db", like getting access to .iterator() which is not exposed by levelup. If you want to get to leveldown's iterator for its iterator.seek() method, you possibly have to bypass deferred-leveldown and encoding-down.
So what if both levelup and abstract-leveldown had a innerDown method, that punches through the layers to get the innermost db?
levelup would return this.db, abstract-leveldown would default to returning this, deferred-leveldown would return this._db, subleveldown would return this.leveldown.
Great idea! This is also why I wanted to write this to get feedback on smart solutions. I just skimmed it right now, but will give it some more thought the coming day(s).
from subleveldown.
I'm wondering what we can do as minimal change to get this working, without having to rewrite the whole world, i.e. make a quick hack, then replace the hack underneath with a proper .down()
solution.
from subleveldown.
var subdb = this.db.down('subleveldown')
That line calls levelup#down()
. What would that implementation look like?
from subleveldown.
I was thinking about that too. We might be able to get by with while (db.db) db = db.db with some additional check that db.db is an abstract-leveldown (and not an underlying IndexedDB, for example).
Sounds good. I have something to play with now at least!
from subleveldown.
More complete plan for a temporary solution:
Renamesubdown#leveldown
tosubdown#db
.#db
is already levelup, that works- Set the value of
subdown#type
tosubleveldown
- Write a recursive utility that we can use as fallback in
subleveldown
,levelup
Γ‘ndabstract-leveldown
:
function down (db, type) {
if (typeof db.down === 'function') {
return db.down(type)
}
if (type && db.type === type) return db
if (isAbstract(db.db)) return down(db.db, type) // encdown, subleveldown, levelup
if (isAbstract(db._db)) return down(db._db, type) // deferred-leveldown
return type ? null : db
}
For isAbstract
, perhaps we can use the old is-leveldown.js
code.
from subleveldown.
So basically do
SubDown.prototype._open = function (opts, cb) {
if (this.db.isOpen()) {
var subdb = down(this.db, 'subleveldown')
if (subdb && subdb.prefix) {
this.prefix = subdb.prefix + this.prefix
this.leveldown = down(subdb)
} else {
this.leveldown = down(this.db)
}
}
..
}
from subleveldown.
Exactly. And later:
LevelUP.prototype.down = function (type) {
return down(this.db, type)
}
AbstractLevelDOWN.prototype.down = function (type) {
var db = this._down(type)
return db == null ? null : db === this ? db : down(db, type)
}
from subleveldown.
I now think it's better to not add down()
to levelup
and/or abstract-leveldown
, partly because of the recursive issue (#34 (comment)), partly because we don't need it in that many places, but mostly because we'd end up with multiple versions of the code.
Closing this, continuing at Level/community#82.
from subleveldown.
Related Issues (20)
- How to get the exception `Inner database is not open`? HOT 2
- Support buffer/Uint8Array prefixes HOT 7
- A way to get a deeply nested sublevel in one-go HOT 5
- Release v3.0.0 HOT 1
- Streams are ignoring fillCache option HOT 2
- Segfault with subleveldown HOT 27
- bytewise key-encoding on sub-level causes not found on other level HOT 20
- Adding _seek to SubIterator HOT 4
- Disable `clear()` HOT 2
- Take advantage of manifests and the squash down HOT 1
- An in-range update of abstract-leveldown is breaking the build π¨ HOT 3
- Applies prefix twice on nested sublevel HOT 12
- An in-range update of levelup is breaking the build π¨ HOT 2
- Remove unnecessary condition HOT 1
- Drop support of memdb
- Require deferredOpen support HOT 1
- Support "deep" option in clear() & iterator() HOT 10
- Possible issue with buffer keys HOT 10
- Decoder Err ! HOT 3
- Should the `createReadStream` method be scoped to the subs? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from subleveldown.