Skip to content
This repository was archived by the owner on Dec 1, 2024. It is now read-only.

Commit 45e73a9

Browse files
authored
Add clear() method to delete all entries or a range (#669)
* Add clear() method to delete all entries or a range * Upgrade deferred-leveldown from ~5.1.0 to ~5.2.0 * Upgrade encoding-down devDependency from ^6.0.0 to ^6.2.0 * Add link to Level/community#79
1 parent 1dbc5fe commit 45e73a9

File tree

5 files changed

+133
-2
lines changed

5 files changed

+133
-2
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ db.put('name', 'levelup', function (err) {
9595
- <a href="#createKeyStream"><code>db.<b>createKeyStream()</b></code></a>
9696
- <a href="#createValueStream"><code>db.<b>createValueStream()</b></code></a>
9797
- <a href="#iterator"><code>db.<b>iterator()</b></code></a>
98+
- <a href="#clear"><code>db.<b>clear()</b></code></a>
9899

99100
### Special Notes
100101

@@ -391,6 +392,23 @@ db.createReadStream({ keys: false, values: true })
391392

392393
Returns an [`abstract-leveldown` iterator](https://github.com/Level/abstract-leveldown/#abstractleveldown_iteratoroptions), which is what powers the readable streams above. Options are the same as the range options of <a href="#createReadStream"><code>createReadStream</code></a> and are passed to the underlying store.
393394

395+
<a name="clear"></a>
396+
397+
### `db.clear([options][, callback])`
398+
399+
**This method is experimental. Not all underlying stores support it yet. Consult [Level/community#79](https://github.com/Level/community/issues/79) to find out if your (combination of) dependencies support `db.clear()`.**
400+
401+
Delete all entries or a range. Not guaranteed to be atomic. Accepts the following range options (with the same rules as on iterators):
402+
403+
- `gt` (greater than), `gte` (greater than or equal) define the lower bound of the range to be deleted. Only entries where the key is greater than (or equal to) this option will be included in the range. When `reverse=true` the order will be reversed, but the entries deleted will be the same.
404+
- `lt` (less than), `lte` (less than or equal) define the higher bound of the range to be deleted. Only entries where the key is less than (or equal to) this option will be included in the range. When `reverse=true` the order will be reversed, but the entries deleted will be the same.
405+
- `reverse` _(boolean, default: `false`)_: delete entries in reverse order. Only effective in combination with `limit`, to remove the last N records.
406+
- `limit` _(number, default: `-1`)_: limit the number of entries to be deleted. This number represents a _maximum_ number of entries and may not be reached if you get to the end of the range first. A value of `-1` means there is no limit. When `reverse=true` the entries with the highest keys will be deleted instead of the lowest keys.
407+
408+
If no options are provided, all entries will be deleted. The `callback` function will be called with no arguments if the operation was successful or with an `WriteError` if it failed for any reason.
409+
410+
If no callback is passed, a promise is returned.
411+
394412
<a name="writeStreams"></a>
395413

396414
#### What happened to `db.createWriteStream`?
@@ -446,6 +464,7 @@ const main = async () => {
446464
| `put` | Key has been updated | `key, value` (any) |
447465
| `del` | Key has been deleted | `key` (any) |
448466
| `batch` | Batch has executed | `operations` (array) |
467+
| `clear` | Entries were deleted | `options` (object) |
449468
| `opening` | Underlying store is opening | - |
450469
| `open` | Store has opened | - |
451470
| `ready` | Alias of `open` | - |

lib/levelup.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,33 @@ LevelUP.prototype.iterator = function (options) {
276276
return this.db.iterator(options)
277277
}
278278

279+
LevelUP.prototype.clear = function (options, callback) {
280+
var self = this
281+
var promise
282+
283+
callback = getCallback(options, callback)
284+
options = getOptions(options)
285+
286+
if (!callback) {
287+
callback = promisify()
288+
promise = callback.promise
289+
}
290+
291+
if (maybeError(this, callback)) {
292+
return promise
293+
}
294+
295+
this.db.clear(options, function (err) {
296+
if (err) {
297+
return callback(new WriteError(err))
298+
}
299+
self.emit('clear', options)
300+
callback()
301+
})
302+
303+
return promise
304+
}
305+
279306
LevelUP.prototype.readStream =
280307
LevelUP.prototype.createReadStream = function (options) {
281308
options = extend({ keys: true, values: true }, options)

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"prepublishOnly": "npm run dependency-check"
1515
},
1616
"dependencies": {
17-
"deferred-leveldown": "~5.1.0",
17+
"deferred-leveldown": "~5.2.0",
1818
"level-errors": "~2.0.0",
1919
"level-iterator-stream": "~4.0.0",
2020
"xtend": "~4.0.0"
@@ -30,9 +30,10 @@
3030
"coveralls": "^3.0.2",
3131
"delayed": "^2.0.0",
3232
"dependency-check": "^3.3.0",
33-
"encoding-down": "^6.0.0",
33+
"encoding-down": "^6.2.0",
3434
"hallmark": "^2.0.0",
3535
"level-community": "^3.0.0",
36+
"level-concat-iterator": "^2.0.1",
3637
"memdown": "^5.0.0",
3738
"nyc": "^14.0.0",
3839
"pinkie": "^2.0.4",

test/clear-test.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
var test = require('tape')
2+
var memdown = require('memdown')
3+
var encode = require('encoding-down')
4+
var concat = require('level-concat-iterator')
5+
var levelup = require('../lib/levelup')
6+
7+
test('clear()', function (t) {
8+
function makeTest (name, fn) {
9+
t.test(name, function (t) {
10+
var mem = memdown()
11+
12+
mem.open(function (err) {
13+
t.ifError(err, 'no open error')
14+
15+
mem.batch([
16+
{ type: 'put', key: '"a"', value: 'a' },
17+
{ type: 'put', key: '"b"', value: 'b' }
18+
], function (err) {
19+
t.ifError(err, 'no batch error')
20+
21+
mem.close(function (err) {
22+
t.ifError(err, 'no close error')
23+
fn(t, mem)
24+
})
25+
})
26+
})
27+
})
28+
}
29+
30+
function verify (t, db, expectedKey) {
31+
concat(db.iterator({ keyAsBuffer: false }), function (err, entries) {
32+
t.ifError(err, 'no concat error')
33+
t.same(entries.map(function (e) { return e.key }), [expectedKey], 'got expected keys')
34+
db.close(t.end.bind(t))
35+
})
36+
}
37+
38+
makeTest('clear() without encoding, without deferred-open', function (t, mem) {
39+
var db = levelup(mem)
40+
41+
db.open(function (err) {
42+
t.ifError(err)
43+
44+
db.clear({ gte: '"b"' }, function (err) {
45+
t.ifError(err, 'no clear error')
46+
verify(t, db, '"a"')
47+
})
48+
})
49+
})
50+
51+
makeTest('clear() without encoding, with deferred-open', function (t, mem) {
52+
var db = levelup(mem)
53+
54+
db.clear({ gte: '"b"' }, function (err) {
55+
t.ifError(err, 'no clear error')
56+
verify(t, db, '"a"')
57+
})
58+
})
59+
60+
makeTest('clear() with encoding, with deferred-open', function (t, mem) {
61+
var db = levelup(encode(mem, { keyEncoding: 'json' }))
62+
63+
db.clear({ gte: 'b' }, function (err) {
64+
t.ifError(err, 'no clear error')
65+
verify(t, db, 'a')
66+
})
67+
})
68+
69+
makeTest('clear() with encoding, without deferred-open', function (t, mem) {
70+
var db = levelup(encode(mem, { keyEncoding: 'json' }))
71+
72+
db.open(function (err) {
73+
t.ifError(err)
74+
75+
db.clear({ gte: 'b' }, function (err) {
76+
t.ifError(err, 'no clear error')
77+
verify(t, db, 'a')
78+
})
79+
})
80+
})
81+
82+
t.end()
83+
})

test/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ if (process.browser && typeof Promise !== 'function') {
66
require('./argument-checking-test')
77
require('./batch-test')
88
require('./binary-test')
9+
require('./clear-test')
910
require('./deferred-open-test')
1011
require('./get-put-del-test')
1112
require('./idempotent-test')

0 commit comments

Comments
 (0)