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

Breaking: remove deprecated put, del & batch events #104

Merged
merged 2 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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

db._assertValidKey(key)
db._assertValidValue(value)
Expand Down Expand Up @@ -146,14 +139,6 @@ class AbstractChainedBatch {
}

this.#publicOperations.push(publicOperation)
} else if (this.#legacyOperations !== null && !siblings) {
const legacyOperation = { ...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 @@ -182,7 +167,6 @@ class AbstractChainedBatch {

const delegated = options.sublevel != null
const db = delegated ? options.sublevel : this.db
const original = options

db._assertValidKey(key)

Expand Down Expand Up @@ -228,13 +212,6 @@ class AbstractChainedBatch {
}

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

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

this.#legacyOperations.push(legacyOperation)
}

op.key = this.db.prefixKey(encodedKey, keyFormat, true)
Expand All @@ -261,7 +238,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 @@ -330,8 +306,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
21 changes: 1 addition & 20 deletions abstract-level.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,11 @@ class AbstractLevel extends EventEmitter {
closing: true,
closed: true,
write: true,
put: true,
del: true,
batch: true,
clear: true
}
})

// 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' }])
vweevers marked this conversation as resolved.
Show resolved Hide resolved
this.#transcoder = new Transcoder(formats(this))
this.#keyEncoding = this.#transcoder.encoding(keyEncoding || 'utf8')
this.#valueEncoding = this.#transcoder.encoding(valueEncoding || 'utf8')
Expand Down Expand Up @@ -579,9 +569,6 @@ class AbstractLevel extends EventEmitter {
}

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

Expand Down Expand Up @@ -630,9 +617,6 @@ class AbstractLevel extends EventEmitter {
}

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

Expand Down Expand Up @@ -783,9 +767,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)
}
Loading
Loading