Skip to content

Commit c0ff5a6

Browse files
committed
3.1.0
Added `separator` option. Updated changelog and readme cleaned up tests added tests
1 parent bb8463e commit c0ff5a6

9 files changed

Lines changed: 118 additions & 27 deletions

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
# 3.1.0
2+
3+
- Added `separator` option.
4+
15
# 3.0.0
26

37
- Added support for `level-spaces@2`
48
- The check for whether a key is in a sub level is more thorough.
9+
- Breaking changes: Keys with '\x00', '\xff', or '~' in their name are not supported.
510

611
# 2.0.3
712

@@ -18,6 +23,7 @@
1823
# 2.0.0
1924

2025
- Added support for `level-spaces@1`.
26+
- Breaking changes: none.
2127

2228
# 1.1.0
2329

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Also, this respects the locks that [`level-lock`][lock] creates. If `tiny-level-
3030
- `opts` is an object with the following properties:
3131
- `ttl` is a number of milliseconds for how long a key lives in the `db`. Optional; defaults to `3600000`, (1 hour).
3232
- `checkInterval` is a number of milliseconds for how long the interval between checking keys is. Optional; defaults to `10000`, (10 seconds).
33+
- `separator` can be a string, buffer, or array of strings/buffers. These represent the separator used in the sub-database. For example, `level-spaces` by default has the separator `~`, so if you store the key `bar`, in the space `foo`, the key will be `~foo~bar`. Defaults to `[ '~', '\xff', '\x00' ]`.
3334

3435
# example
3536

index.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,49 @@ var lock = require('level-lock')
44
var spaces = require('level-spaces')
55
var defaultOpts = {
66
ttl: 3600000,
7-
checkInterval: 10000
7+
checkInterval: 10000,
8+
separator: [ '~', '\xff', '\x00' ]
89
}
910

10-
// https://github.com/rvagg/level-spaces/issues/2
11-
function isFromThisSpace(key) {
12-
function lacks(char) {
13-
return (key.indexOf(char) === -1)
11+
function isFromThisSpace(key, separator) {
12+
if (!Array.isArray(separator)) {
13+
separator = [ separator ]
1414
}
15-
return ( lacks('ÿ') && lacks('~') && lacks('\xff') && lacks('\x00') )
15+
return separator.every(function (sep) {
16+
return key.indexOf(sep) === -1
17+
})
1618
}
1719

18-
function onCmd(expirer, type, key) {
20+
function onCmd(expirer, separator, type, key) {
1921
var commandResponses = {
2022
del: expirer.forget,
2123
put: expirer.touch
2224
}
23-
if (isFromThisSpace(key)) {
25+
if (isFromThisSpace(key, separator)) {
2426
commandResponses[type](key)
2527
}
2628
}
2729

28-
function makeChildDb(db) {
29-
return db.sublevel ? db.sublevel('expirer') : spaces(db, 'expirer')
30+
function makeChildDb(db, separator) {
31+
return db.sublevel ?
32+
db.sublevel('expirer') :
33+
spaces(db, 'expirer', { separator: separator })
3034
}
3135

3236
module.exports = function ttl(db, opts) {
3337
if (!db) {
3438
throw new Error('You must pass a level database to ttl()')
3539
}
3640
var options = xtend(defaultOpts, opts)
37-
var childDb = makeChildDb(db)
41+
var separator = options.separator
42+
var childDb = makeChildDb(db, separator)
3843
var expirer = new Expirer(options.ttl, childDb, options.checkInterval)
3944

40-
db.on('put', onCmd.bind(null, expirer, 'put'))
41-
db.on('del', onCmd.bind(null, expirer, 'del'))
45+
db.on('put', onCmd.bind(null, expirer, separator, 'put'))
46+
db.on('del', onCmd.bind(null, expirer, separator, 'del'))
4247
db.on('batch', function (cmds) {
4348
cmds.forEach(function (cmd) {
44-
onCmd(expirer, cmd.type, cmd.key)
49+
onCmd(expirer, separator, cmd.type, cmd.key)
4550
})
4651
})
4752

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tiny-level-ttl",
3-
"version": "3.0.0",
3+
"version": "3.1.0",
44
"description": "Extension for node-level that enforces a time to live on a database (or sublevel db)",
55
"main": "index.js",
66
"scripts": {

test/testBasicFunctionality.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ test('basic functionality', function (t) {
77
t.plan(7)
88
var db = level('hello')
99
var ttlDb = spaces(db, 'ttl-expiration')
10-
ttl(db, {ttl: 1000, checkInterval: 50, db: ttlDb})
10+
ttl(db, {ttl: 1000, checkInterval: 50})
1111
db.put('hi', 'wuzzup', t.notOk.bind(t))
1212
setTimeout(function () { //before ttl
1313
db.get('hi', function (err, value) {

test/testDelayExpirationWithRefreshTtlCall.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ test('db inheritance and adding refreshTtl() to new db', function (t) {
66
var db = level('hello')
77
var doesNotReturn = ttl(db, {ttl: 1000, checkInterval: 50})
88

9-
t.type(db.refreshTtl, 'function', 'database has refresh ttl function')
10-
t.type(doesNotReturn, 'undefined', 'ttl() returns nothing!')
9+
t.equal(typeof db.refreshTtl, 'function', 'database has refresh ttl function')
10+
t.equal(typeof doesNotReturn, 'undefined', 'ttl() returns nothing!')
1111

1212
t.end()
1313
})

test/testSeparators.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
var test = require('tap').test
2+
var level = require('level-mem')
3+
var spaces = require('level-spaces')
4+
var ttl = require('../index.js')
5+
6+
test('separators work', function (t) {
7+
t.plan(14)
8+
9+
var db = level('hello')
10+
var ttlDb = spaces(db, 'ttl-expiration', { separator: '\xff' })
11+
12+
ttl(db, {
13+
ttl: 1000,
14+
checkInterval: 50,
15+
separator: '\xff'
16+
})
17+
18+
db.put('hi\x00', 'wuzzup', t.notOk.bind(t))
19+
db.put('hello\xff', 'coolness', t.notOk.bind(t))
20+
21+
setTimeout(function () { //before ttl
22+
db.get('hi\x00', function (err, value) {
23+
t.notOk(err, 'did not get an error')
24+
t.notOk(err && err.notFound, 'did not get a notFound error')
25+
t.equal(value, 'wuzzup', 'got back the expected value')
26+
27+
db.get('hello\xff', function (err, value) {
28+
t.notOk(err, 'did not get an error')
29+
t.notOk(err && err.notFound, 'did not get a notFound error')
30+
t.equal(value, 'coolness', 'got back the expected value')
31+
})
32+
})
33+
}, 900)
34+
35+
setTimeout(function () { //after ttl
36+
db.get('hi\x00', function (err, value) {
37+
t.ok(err, 'got an error')
38+
t.ok(err && err.notFound, 'got a notFound error')
39+
t.notOk(value, 'did not get a value')
40+
41+
db.get('hello\xff', function (err, value) {
42+
t.notOk(err, 'did not get an error')
43+
t.notOk(err && err.notFound, 'did not get a notFound error')
44+
t.equal(value, 'coolness', 'got back the expected value')
45+
46+
t.end()
47+
})
48+
})
49+
}, 1100)
50+
})
51+
52+
test('separators work', function (t) {
53+
t.plan(6)
54+
55+
var db = level('hello')
56+
var ttlDb = spaces(db, 'ttl-expiration', { separator: 'x' })
57+
58+
ttl(db, {
59+
ttl: 1000,
60+
checkInterval: 50,
61+
separator: 'x'
62+
})
63+
64+
db.put('hi', 'wuzzup', t.notOk.bind(t))
65+
db.put('hellox', 'coolness', t.notOk.bind(t))
66+
67+
setTimeout(function () { //before ttl
68+
db.get('hi', function (err, value) {
69+
t.equal(value, 'wuzzup')
70+
})
71+
db.get('hellox', function (err, value) {
72+
t.equal(value, 'coolness')
73+
})
74+
}, 900)
75+
76+
setTimeout(function () { //after ttl
77+
db.get('hi\x00', function (err, value) {
78+
t.notOk(value)
79+
db.get('hellox', function (err, value) {
80+
t.equal(value, 'coolness')
81+
82+
t.end()
83+
})
84+
})
85+
}, 1100)
86+
})
Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
var test = require('tap').test
2-
var level = require('level-mem')
32
var ttl = require('../index.js')
43

54
test('throw error on bad db', function (t) {
65
t.plan(1)
7-
var db = level('hello')
8-
try {
9-
ttl(null)
10-
t.fail('bad db must throw error')
11-
} catch (err) {
12-
t.equal(err.message, 'You must pass a level database to ttl()', 'correct error message')
13-
}
6+
t.throws(ttl, 'throws an error')
147
t.end()
158
})

test/testWorksInSublevel.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ test('still works in a sublevel', function (t) {
4444
t.end()
4545
})
4646
})
47-
47+
4848
}, 1100)
4949
})

0 commit comments

Comments
 (0)