From a816c2d4fb7f96738464968952b1b3e99641fd86 Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Tue, 1 Oct 2019 16:24:13 +0200 Subject: [PATCH 1/5] Bump abstract-leveldown to prevent dedupe --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ec8dbb3..8dbe0ff 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "prepublishOnly": "npm run dependency-check" }, "dependencies": { - "abstract-leveldown": "^6.1.1", + "abstract-leveldown": "^6.2.1", "inherits": "^2.0.3", "level-codec": "^9.0.0", "level-errors": "^2.0.0" From 72dbd082e81f3f5e63be3f6ff9ae09fcf90078ea Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Tue, 1 Oct 2019 19:00:41 +0200 Subject: [PATCH 2/5] Add manifest (and encode compactRange) --- index.js | 58 +++++++++++++++++++++++++++++++++++++++++++++------ test/index.js | 32 +++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index b1bd592..39579e1 100644 --- a/index.js +++ b/index.js @@ -6,12 +6,25 @@ var AbstractIterator = require('abstract-leveldown').AbstractIterator var inherits = require('inherits') var Codec = require('level-codec') var EncodingError = require('level-errors').EncodingError +var specialMethods = ['approximateSize', 'compactRange'] module.exports = DB.default = DB function DB (db, opts) { if (!(this instanceof DB)) return new DB(db, opts) - AbstractLevelDOWN.call(this, '') + if (db.supports && db.supports.encodings) throw new Error('Double encoding') + + AbstractLevelDOWN.call(this, db.supports) + this.supports.encodings = true + + // TODO (future major): remove this fallback + specialMethods.forEach(function (m) { + if (typeof db[m] === 'function' && !this.supports.additionalMethods[m]) { + this.supports.additionalMethods[m] = { + args: [{ type: 'key' }, { type: 'key' }, { type: 'options' }] + } + } + }, this) opts = opts || {} if (typeof opts.keyEncoding === 'undefined') opts.keyEncoding = 'utf8' @@ -19,6 +32,29 @@ function DB (db, opts) { this.db = db this.codec = new Codec(opts) + + Object.keys(this.supports.additionalMethods).forEach(function (m) { + if (this[m] != null) return + + var signature = this.supports.additionalMethods[m] + var args = (signature && signature.args) || [] + + this[m] = function () { + var i = Math.min(arguments.length, args.length) + var opts + + while (i--) { + if (args[i].type === 'options' && !opts && isOptions(arguments[i])) { + opts = arguments[i] + arguments[i] = this.codec.encodeLtgt(opts) + } else if (args[i].type === 'key') { + arguments[i] = this.codec.encodeKey(arguments[i], opts) + } + } + + return this.db[m].apply(this.db, arguments) + } + }, this) } inherits(DB, AbstractLevelDOWN) @@ -84,11 +120,17 @@ DB.prototype._clear = function (opts, callback) { this.db.clear(opts, callback) } -DB.prototype.approximateSize = function (start, end, opts, cb) { - start = this.codec.encodeKey(start, opts) - end = this.codec.encodeKey(end, opts) - return this.db.approximateSize(start, end, opts, cb) -} +// DB.prototype.approximateSize = function (start, end, opts, cb) { +// start = this.codec.encodeKey(start, opts) +// end = this.codec.encodeKey(end, opts) +// return this.db.approximateSize(start, end, opts, cb) +// } +// +// DB.prototype.compactRange = function (start, end, opts, cb) { +// start = this.codec.encodeKey(start, opts) +// end = this.codec.encodeKey(end, opts) +// return this.db.compactRange(start, end, opts, cb) +// } function Iterator (db, opts) { AbstractIterator.call(this, db) @@ -159,3 +201,7 @@ Batch.prototype._clear = function () { Batch.prototype._write = function (opts, cb) { this.batch.write(opts, cb) } + +function isOptions (o) { + return typeof o === 'object' && o !== null +} diff --git a/test/index.js b/test/index.js index 3d815f1..877f525 100644 --- a/test/index.js +++ b/test/index.js @@ -579,7 +579,7 @@ test('iterator catches decoding error from valueEncoding', function (t) { }) }) -test('approximateSize() encodes start and end', function (t) { +test('encodes start and end of approximateSize()', function (t) { t.plan(2) var down = { @@ -592,6 +592,36 @@ test('approximateSize() encodes start and end', function (t) { encdown(down).approximateSize(1, 2, noop) }) +test('encodes start and end of approximateSize() with custom encoding', function (t) { + t.plan(2) + + var down = { + approximateSize: function (start, end) { + t.is(start, '"a"') + t.is(end, '"b"') + } + } + + encdown(down).approximateSize('a', 'b', { keyEncoding: 'json' }, noop) +}) + +test('encodes options of additionalMethod', function (t) { + t.plan(1) + + var down = { + supports: { + additionalMethods: { + foo: { args: [{ type: 'options' }] } + } + }, + foo: function (options) { + t.is(options.gt, '"a"') + } + } + + encdown(down).foo({ gt: 'a', keyEncoding: 'json' }) +}) + test('encodes seek target', function (t) { t.plan(1) From 2263d2f833abdf76968468b94ca3034f22f681b2 Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Fri, 4 Oct 2019 20:13:15 +0200 Subject: [PATCH 3/5] Remove dead code --- index.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/index.js b/index.js index 39579e1..7c73b8a 100644 --- a/index.js +++ b/index.js @@ -120,18 +120,6 @@ DB.prototype._clear = function (opts, callback) { this.db.clear(opts, callback) } -// DB.prototype.approximateSize = function (start, end, opts, cb) { -// start = this.codec.encodeKey(start, opts) -// end = this.codec.encodeKey(end, opts) -// return this.db.approximateSize(start, end, opts, cb) -// } -// -// DB.prototype.compactRange = function (start, end, opts, cb) { -// start = this.codec.encodeKey(start, opts) -// end = this.codec.encodeKey(end, opts) -// return this.db.compactRange(start, end, opts, cb) -// } - function Iterator (db, opts) { AbstractIterator.call(this, db) this.codec = db.codec From b36dafeadfe53e3c889bcc2cfb3cd188244295c4 Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Sun, 6 Oct 2019 15:18:07 +0200 Subject: [PATCH 4/5] Simplify (see Level/supports#1) --- index.js | 44 +++++++++------------------------ test/index.js | 67 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/index.js b/index.js index 7c73b8a..d26eb3c 100644 --- a/index.js +++ b/index.js @@ -6,22 +6,27 @@ var AbstractIterator = require('abstract-leveldown').AbstractIterator var inherits = require('inherits') var Codec = require('level-codec') var EncodingError = require('level-errors').EncodingError -var specialMethods = ['approximateSize', 'compactRange'] +var rangeMethods = ['approximateSize', 'compactRange'] module.exports = DB.default = DB function DB (db, opts) { if (!(this instanceof DB)) return new DB(db, opts) - if (db.supports && db.supports.encodings) throw new Error('Double encoding') AbstractLevelDOWN.call(this, db.supports) this.supports.encodings = true - // TODO (future major): remove this fallback - specialMethods.forEach(function (m) { + rangeMethods.forEach(function (m) { + // TODO (future major): remove this fallback if (typeof db[m] === 'function' && !this.supports.additionalMethods[m]) { - this.supports.additionalMethods[m] = { - args: [{ type: 'key' }, { type: 'key' }, { type: 'options' }] + this.supports.additionalMethods[m] = true + } + + if (this.supports.additionalMethods[m]) { + this[m] = function (start, end, opts, cb) { + start = this.codec.encodeKey(start, opts) + end = this.codec.encodeKey(end, opts) + return this.db[m](start, end, opts, cb) } } }, this) @@ -32,29 +37,6 @@ function DB (db, opts) { this.db = db this.codec = new Codec(opts) - - Object.keys(this.supports.additionalMethods).forEach(function (m) { - if (this[m] != null) return - - var signature = this.supports.additionalMethods[m] - var args = (signature && signature.args) || [] - - this[m] = function () { - var i = Math.min(arguments.length, args.length) - var opts - - while (i--) { - if (args[i].type === 'options' && !opts && isOptions(arguments[i])) { - opts = arguments[i] - arguments[i] = this.codec.encodeLtgt(opts) - } else if (args[i].type === 'key') { - arguments[i] = this.codec.encodeKey(arguments[i], opts) - } - } - - return this.db[m].apply(this.db, arguments) - } - }, this) } inherits(DB, AbstractLevelDOWN) @@ -189,7 +171,3 @@ Batch.prototype._clear = function () { Batch.prototype._write = function (opts, cb) { this.batch.write(opts, cb) } - -function isOptions (o) { - return typeof o === 'object' && o !== null -} diff --git a/test/index.js b/test/index.js index 877f525..ba5d013 100644 --- a/test/index.js +++ b/test/index.js @@ -579,47 +579,68 @@ test('iterator catches decoding error from valueEncoding', function (t) { }) }) -test('encodes start and end of approximateSize()', function (t) { - t.plan(2) +test('proxies approximateSize() if it exists', function (t) { + t.is(typeof encdown({ approximateSize: noop }).approximateSize, 'function') + t.ok(encdown({ approximateSize: noop }).supports.additionalMethods.approximateSize) + t.is(encdown({}).approximateSize, undefined) + t.notOk(encdown({}).supports.additionalMethods.approximateSize) + t.end() +}) - var down = { +test('proxies compactRange() if it exists', function (t) { + t.is(typeof encdown({ compactRange: noop }).compactRange, 'function') + t.ok(encdown({ compactRange: noop }).supports.additionalMethods.compactRange) + t.is(encdown({}).compactRange, undefined) + t.notOk(encdown({}).supports.additionalMethods.compactRange) + t.end() +}) + +test('encodes start and end of approximateSize()', function (t) { + var db = encdown({ approximateSize: function (start, end) { t.is(start, '1') t.is(end, '2') + t.end() } - } + }) - encdown(down).approximateSize(1, 2, noop) + db.approximateSize(1, 2, noop) }) -test('encodes start and end of approximateSize() with custom encoding', function (t) { - t.plan(2) +test('encodes start and end of compactRange()', function (t) { + var db = encdown({ + compactRange: function (start, end) { + t.is(start, '1') + t.is(end, '2') + t.end() + } + }) - var down = { + db.compactRange(1, 2, noop) +}) + +test('encodes start and end of approximateSize() with custom encoding', function (t) { + var db = encdown({ approximateSize: function (start, end) { t.is(start, '"a"') t.is(end, '"b"') + t.end() } - } + }) - encdown(down).approximateSize('a', 'b', { keyEncoding: 'json' }, noop) + db.approximateSize('a', 'b', { keyEncoding: 'json' }, noop) }) -test('encodes options of additionalMethod', function (t) { - t.plan(1) - - var down = { - supports: { - additionalMethods: { - foo: { args: [{ type: 'options' }] } - } - }, - foo: function (options) { - t.is(options.gt, '"a"') +test('encodes start and end of compactRange() with custom encoding', function (t) { + var db = encdown({ + compactRange: function (start, end) { + t.is(start, '"a"') + t.is(end, '"b"') + t.end() } - } + }) - encdown(down).foo({ gt: 'a', keyEncoding: 'json' }) + db.compactRange('a', 'b', { keyEncoding: 'json' }, noop) }) test('encodes seek target', function (t) { From d8a995846fd2a3190b71b5e13fc13505ac4f33f3 Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Sun, 13 Oct 2019 09:54:33 +0200 Subject: [PATCH 5/5] Don't inherit additionalMethods --- index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index d26eb3c..5e031fe 100644 --- a/index.js +++ b/index.js @@ -13,16 +13,21 @@ module.exports = DB.default = DB function DB (db, opts) { if (!(this instanceof DB)) return new DB(db, opts) - AbstractLevelDOWN.call(this, db.supports) + var manifest = db.supports || {} + var additionalMethods = manifest.additionalMethods || {} + + AbstractLevelDOWN.call(this, manifest) + this.supports.encodings = true + this.supports.additionalMethods = {} rangeMethods.forEach(function (m) { // TODO (future major): remove this fallback - if (typeof db[m] === 'function' && !this.supports.additionalMethods[m]) { + var fallback = typeof db[m] === 'function' + + if (additionalMethods[m] || fallback) { this.supports.additionalMethods[m] = true - } - if (this.supports.additionalMethods[m]) { this[m] = function (start, end, opts, cb) { start = this.codec.encodeKey(start, opts) end = this.codec.encodeKey(end, opts)