Skip to content

Commit

Permalink
Breaking: remove deprecated put, del & batch events
Browse files Browse the repository at this point in the history
In favor of the `write` event.

While still printing a warning if listeners are added for these
events, because it's cheap and helps people who are upgrading.

Category: removal
  • Loading branch information
vweevers committed Dec 31, 2024
1 parent 9eeb291 commit 258e68f
Show file tree
Hide file tree
Showing 8 changed files with 16 additions and 170 deletions.
38 changes: 0 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -848,8 +848,6 @@ Lastly, one way or another, every implementation _must_ support `data` of type S

An `abstract-level` database is an [`EventEmitter`](https://nodejs.org/api/events.html) and emits the events listed below.

The `put`, `del` and `batch` events are deprecated in favor of the `write` event and will be removed in a future version of `abstract-level`. If one or more `write` event listeners exist or if the [`prewrite`](#hook--dbhooksprewrite) hook is in use, either of which implies opting-in to the `write` event, then the deprecated events will not be emitted.

#### `opening`

Emitted when database is opening. Receives 0 arguments:
Expand Down Expand Up @@ -967,42 +965,6 @@ The same is true for `db.put()` and `db.del()`.

Emitted when a `db.clear()` call completed and entries were thus successfully deleted from the database. Receives a single `options` argument, which is the verbatim `options` argument that was passed to `db.clear(options)` (or an empty object if none) before having encoded range options.

#### `put` (deprecated)

Emitted when a `db.put()` call completed and an entry was thus successfully written to the database. Receives `key` and `value` arguments, which are the verbatim `key` and `value` that were passed to `db.put(key, value)` before having encoded them.

```js
db.on('put', function (key, value) {
console.log('Wrote', key, value)
})
```

#### `del` (deprecated)

Emitted when a `db.del()` call completed and an entry was thus successfully deleted from the database. Receives a single `key` argument, which is the verbatim `key` that was passed to `db.del(key)` before having encoded it.

```js
db.on('del', function (key) {
console.log('Deleted', key)
})
```

#### `batch` (deprecated)

Emitted when a `db.batch([])` or chained `db.batch().write()` call completed and the data was thus successfully written to the database. Receives a single `operations` argument, which is the verbatim `operations` array that was passed to `db.batch(operations)` before having encoded it, or the equivalent for a chained `db.batch().write()`.

```js
db.on('batch', function (operations) {
for (const op of operations) {
if (op.type === 'put') {
console.log('Wrote', op.key, op.value)
} else {
console.log('Deleted', op.key)
}
}
})
```

### Order Of Operations

There is no defined order between parallel write operations. Consider:
Expand Down
26 changes: 0 additions & 26 deletions abstract-chained-batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class AbstractChainedBatch {
#length = 0
#closePromise = null
#publicOperations
#legacyOperations
#prewriteRun
#prewriteBatch
#prewriteData
Expand All @@ -33,11 +32,6 @@ class AbstractChainedBatch {
// operations, which is the expensive part) if there are 0 write event listeners.
this.#publicOperations = enableWriteEvent ? [] : null

// Operations for legacy batch event. If user opted-in to write event or prewrite
// hook, skip legacy batch event. We can't skip the batch event based on listener
// count, because a listener may be added between put() or del() and write().
this.#legacyOperations = enableWriteEvent || enablePrewriteHook ? null : []

this.#addMode = getOptions(options, emptyOptions).add === true

if (enablePrewriteHook) {
Expand Down Expand Up @@ -73,7 +67,6 @@ class AbstractChainedBatch {

const delegated = options.sublevel != null
const db = delegated ? options.sublevel : this.db
const original = options
const keyError = db._checkKey(key)
const valueError = db._checkValue(value)

Expand Down Expand Up @@ -148,14 +141,6 @@ class AbstractChainedBatch {
}

this.#publicOperations.push(publicOperation)
} else if (this.#legacyOperations !== null && !siblings) {
const legacyOperation = Object.assign({}, original)

legacyOperation.type = 'put'
legacyOperation.key = key
legacyOperation.value = value

this.#legacyOperations.push(legacyOperation)
}

// If we're forwarding the sublevel option then don't prefix the key yet
Expand Down Expand Up @@ -184,7 +169,6 @@ class AbstractChainedBatch {

const delegated = options.sublevel != null
const db = delegated ? options.sublevel : this.db
const original = options
const keyError = db._checkKey(key)

if (keyError != null) throw keyError
Expand Down Expand Up @@ -231,13 +215,6 @@ class AbstractChainedBatch {
}

this.#publicOperations.push(publicOperation)
} else if (this.#legacyOperations !== null) {
const legacyOperation = Object.assign({}, original)

legacyOperation.type = 'del'
legacyOperation.key = key

this.#legacyOperations.push(legacyOperation)
}

op.key = this.db.prefixKey(encodedKey, keyFormat, true)
Expand All @@ -264,7 +241,6 @@ class AbstractChainedBatch {
this._clear()

if (this.#publicOperations !== null) this.#publicOperations = []
if (this.#legacyOperations !== null) this.#legacyOperations = []
if (this.#prewriteData !== null) this.#prewriteData.clear()

this.#length = 0
Expand Down Expand Up @@ -333,8 +309,6 @@ class AbstractChainedBatch {
// db close which in turn triggers (idempotently) closing this batch.
if (this.#publicOperations !== null) {
this.db.emit('write', this.#publicOperations)
} else if (this.#legacyOperations !== null) {
this.db.emit('batch', this.#legacyOperations)
}

return this.#closePromise
Expand Down
18 changes: 1 addition & 17 deletions abstract-level.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,7 @@ class AbstractLevel extends EventEmitter {
})
})

// Monitor event listeners
this.#eventMonitor = new EventMonitor(this, [
{ name: 'write' },
{ name: 'put', deprecated: true, alt: 'write' },
{ name: 'del', deprecated: true, alt: 'write' },
{ name: 'batch', deprecated: true, alt: 'write' }
])

this.#eventMonitor = new EventMonitor(this, [{ name: 'write' }])
this.#transcoder = new Transcoder(formats(this))
this.#keyEncoding = this.#transcoder.encoding(keyEncoding || 'utf8')
this.#valueEncoding = this.#transcoder.encoding(valueEncoding || 'utf8')
Expand Down Expand Up @@ -591,9 +584,6 @@ class AbstractLevel extends EventEmitter {
})

this.emit('write', [op])
} else {
// TODO (semver-major): remove
this.emit('put', key, value)
}
}

Expand Down Expand Up @@ -643,9 +633,6 @@ class AbstractLevel extends EventEmitter {
})

this.emit('write', [op])
} else {
// TODO (semver-major): remove
this.emit('del', key)
}
}

Expand Down Expand Up @@ -799,9 +786,6 @@ class AbstractLevel extends EventEmitter {

if (enableWriteEvent) {
this.emit('write', publicOperations)
} else if (!enablePrewriteHook) {
// TODO (semver-major): remove
this.emit('batch', operations)
}
}

Expand Down
9 changes: 2 additions & 7 deletions lib/event-monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ exports.EventMonitor = class EventMonitor {
for (const event of events) {
// Track whether listeners are present
this[event.name] = false

// Prepare deprecation message
if (event.deprecated) {
event.message = `The '${event.name}' event is deprecated in favor of '${event.alt}' and will be removed in a future version of abstract-level`
}
}

const map = new Map(events.map(e => [e.name, e]))
Expand All @@ -26,8 +21,8 @@ exports.EventMonitor = class EventMonitor {
if (event !== undefined) {
monitor[name] = true

if (event.deprecated) {
deprecate(event.message)
if (name === 'put' || name === 'del' || name === 'batch') {
deprecate(`The '${name}' event has been removed in favor of 'write'`)
}
}
}
Expand Down
19 changes: 0 additions & 19 deletions test/batch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,24 +199,6 @@ exports.atomic = function (test, testCommon) {
})
}

exports.events = function (test, testCommon) {
test('batch([]) emits batch event', async function (t) {
t.plan(2)

const db = testCommon.factory()
await db.open()

t.ok(db.supports.events.batch)

db.on('batch', function (ops) {
t.same(ops, [{ type: 'put', key: 456, value: 99, custom: 123 }])
})

await db.batch([{ type: 'put', key: 456, value: 99, custom: 123 }])
return db.close()
})
}

exports.tearDown = function (test, testCommon) {
test('batch([]) teardown', async function (t) {
return db.close()
Expand All @@ -228,6 +210,5 @@ exports.all = function (test, testCommon) {
exports.args(test, testCommon)
exports.batch(test, testCommon)
exports.atomic(test, testCommon)
exports.events(test, testCommon)
exports.tearDown(test, testCommon)
}
36 changes: 10 additions & 26 deletions test/chained-batch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,15 @@ exports.batch = function (test, testCommon) {
const db = testCommon.factory()
await db.open()

db.once('batch', function (operations) {
const utf8 = db.keyEncoding('utf8')
const json = db.valueEncoding('json')

db.once('write', function (operations) {
t.same(operations, [
{ type: 'put', key: 'a', value: 'a', valueEncoding: 'json' },
{ type: 'put', key: 'b', value: 'b' },
{ type: 'put', key: '"c"', value: 'c' },
{ type: 'del', key: 'c', keyEncoding: 'json', arbitraryOption: true }
{ type: 'put', key: 'a', value: 'a', keyEncoding: utf8, valueEncoding: json, encodedKey: 'a', encodedValue: '"a"' },
{ type: 'put', key: 'b', value: 'b', keyEncoding: utf8, valueEncoding: utf8, encodedKey: 'b', encodedValue: 'b' },
{ type: 'put', key: '"c"', value: 'c', keyEncoding: utf8, valueEncoding: utf8, encodedKey: '"c"', encodedValue: 'c' },
{ type: 'del', key: 'c', keyEncoding: json, encodedKey: '"c"', arbitraryOption: true }
])
})

Expand All @@ -265,32 +268,13 @@ exports.batch = function (test, testCommon) {
}

exports.events = function (test, testCommon) {
test('chained batch emits batch event', async function (t) {
t.plan(2)

const db = testCommon.factory()
await db.open()

t.ok(db.supports.events.batch)

db.on('batch', function (ops) {
t.same(ops, [
{ type: 'put', key: 987, value: 'b', custom: 123 },
{ type: 'del', key: 216, custom: 999 }
])
})

await db.batch().put(987, 'b', { custom: 123 }).del(216, { custom: 999 }).write()
await db.close()
})

test('db.close() on chained batch event', async function (t) {
test('db.close() on chained batch write event', async function (t) {
const db = testCommon.factory()
await db.open()

let promise

db.on('batch', function () {
db.on('write', function () {
// Should not interfere with the current write() operation
promise = db.close()
})
Expand Down
25 changes: 3 additions & 22 deletions test/del-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,34 +41,16 @@ exports.del = function (test, testCommon) {

traits.open('del()', testCommon, async function (t, db) {
let emitted = false
db.once('del', () => { emitted = true })
t.is(await assertPromise(db.del('foo')), undefined, 'void promise')
t.ok(emitted)
db.once('write', () => { emitted = true })
t.is(await db.del('foo'), undefined, 'void promise')
t.ok(emitted) // Not sure what the purpose of this test is
})

traits.closed('del()', testCommon, async function (t, db) {
return db.del('foo')
})
}

exports.events = function (test, testCommon) {
test('del() emits del event', async function (t) {
t.plan(2)

const db = testCommon.factory()
await db.open()

t.ok(db.supports.events.del)

db.on('del', function (key) {
t.is(key, 456)
})

await db.del(456)
return db.close()
})
}

exports.tearDown = function (test, testCommon) {
test('del() teardown', async function (t) {
return db.close()
Expand All @@ -79,6 +61,5 @@ exports.all = function (test, testCommon) {
exports.setUp(test, testCommon)
exports.args(test, testCommon)
exports.del(test, testCommon)
exports.events(test, testCommon)
exports.tearDown(test, testCommon)
}
15 changes: 0 additions & 15 deletions test/put-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,6 @@ exports.put = function (test, testCommon) {
})
}

exports.events = function (test, testCommon) {
test('put() emits put event', async function (t) {
t.plan(3)
t.ok(db.supports.events.put)

db.on('put', function (key, value) {
t.is(key, 123)
t.is(value, 'b')
})

await db.put(123, 'b')
})
}

exports.tearDown = function (test, testCommon) {
test('put() teardown', async function (t) {
return db.close()
Expand All @@ -80,6 +66,5 @@ exports.all = function (test, testCommon) {
exports.setUp(test, testCommon)
exports.args(test, testCommon)
exports.put(test, testCommon)
exports.events(test, testCommon)
exports.tearDown(test, testCommon)
}

0 comments on commit 258e68f

Please sign in to comment.