Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

range options should be serialized #130

Closed
vweevers opened this issue Oct 2, 2017 · 14 comments · Fixed by #277
Closed

range options should be serialized #130

vweevers opened this issue Oct 2, 2017 · 14 comments · Fixed by #277
Labels
bug Something isn't working
Milestone

Comments

@vweevers
Copy link
Member

vweevers commented Oct 2, 2017

See #121 (comment).

@ralphtheninja @juliangruber should we include this in levelup@2? If so I can try to tackle this today/tomorrow.

@vweevers vweevers added the bug Something isn't working label Oct 2, 2017
@ralphtheninja
Copy link
Member

Would be nice to know what happened here. Has this always been the case or did we break it?

@vweevers
Copy link
Member Author

vweevers commented Oct 2, 2017

Has been the case since the _serialize functions were added. Simply forgot to include them in iterators.

@vweevers
Copy link
Member Author

vweevers commented Oct 2, 2017

But no one has been bitten by this yet, it seems

@vweevers
Copy link
Member Author

vweevers commented Oct 2, 2017

Even before _serialize (#85), when we just coerced non-buffers to strings, range options were not coerced AFAICT.

@vweevers
Copy link
Member Author

vweevers commented Oct 2, 2017

@juliangruber can you think of any reason why this has been the case since forever? Are we missing something?

@juliangruber
Copy link
Member

the null / undefined, buffer / utf8 etc situation was weird to me from the very beginning, and no one ever really understood the whole picture iirc

@juliangruber
Copy link
Member

same as for example the process.browser checks

@ralphtheninja
Copy link
Member

Maybe we could write some tests for it to to illustrate when it happens. What is the exact usage of the serialization code when doing db.createReadStream()? And when does it become a problem?

@vweevers
Copy link
Member Author

vweevers commented Oct 2, 2017

So far I can't actually think of a use case that would fail without range option serialization. It merely feels like the right thing to do.

I know two Buffers can become equal when serialized to (UTF8) strings:

Buffer('90', 'hex').toString() === Buffer('80', 'hex').toString()

Maybe we can find something there, some case where the sort order is off.

@vweevers
Copy link
Member Author

vweevers commented Oct 2, 2017

Then again, if we need to actively search for issues..

@vweevers
Copy link
Member Author

vweevers commented Oct 4, 2017

If nothing else, I think it's a safety mechanism. In normal use of level(up), you'd use an encoding for non-standard types. Take:

db.createReadStream({ gt: 2 })

The db here should be level, levelup with encoding-down, or otherwise backed by an abstract-leveldown that supports numbers for keys.

In case it is not, abstract-leveldown must serialize the gt option to a type supported by the underlying store. If not to prevent errors, then for symmetry with serialized keys.

In the case of leveldown it'd be for symmetry, because the C++ currently ignores options that aren't buffers or strings. Without encoding-down and range option serialization, the following example would output two keys (a stringified 1 and 2) because the gt option is ignored, against expectation.

db.batch([
  { key: 1, value: 'one' },
  { key: 2, value: 'two' }
], function (err) {
  db.createKeyStream({ gt: 2 }).on('data', function (key) {
    console.log(key)
  })
})

@vweevers
Copy link
Member Author

vweevers commented Oct 4, 2017

Even before _serialize (#85), when we just coerced non-buffers to strings, range options were not coerced AFAICT.

Makes sense because encodings used to be built-in, so users were protected against the above scenario (unless they used the id aka none encoding).

@vweevers
Copy link
Member Author

vweevers commented Oct 4, 2017

@juliangruber @ralphtheninja in conclusion, I do think we need this, but it's not a priority. 🦆

@vweevers
Copy link
Member Author

Found a use case. If localstorage-down wants to support Buffer keys, it needs to convert them to lexicographically ordered strings (with d64 or base64-lex). Ideally _serializeKey is the only code path used to achieve this. Then internally, localstorage-down can just work on strings, and use native comparators for sorting keys.

@vweevers vweevers added this to the v6 milestone Jul 7, 2018
@vweevers vweevers mentioned this issue Jul 13, 2018
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants