Skip to content

Commit

Permalink
Use classes
Browse files Browse the repository at this point in the history
  • Loading branch information
vweevers committed Jan 2, 2022
1 parent 978c78f commit df94011
Show file tree
Hide file tree
Showing 4 changed files with 790 additions and 794 deletions.
255 changes: 127 additions & 128 deletions abstract-chained-batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,172 +10,171 @@ const kOperations = Symbol('operations')
const kFinishClose = Symbol('finishClose')
const kCloseCallbacks = Symbol('closeCallbacks')

function AbstractChainedBatch (db) {
if (typeof db !== 'object' || db === null) {
const hint = db === null ? 'null' : typeof db
throw new TypeError(`The first argument must be an abstract-level database, received ${hint}`)
}

this[kOperations] = []
this[kCloseCallbacks] = []
this[kStatus] = 'open'
this[kFinishClose] = this[kFinishClose].bind(this)
class AbstractChainedBatch {
constructor (db) {
if (typeof db !== 'object' || db === null) {
const hint = db === null ? 'null' : typeof db
throw new TypeError(`The first argument must be an abstract-level database, received ${hint}`)
}

this.db = db
this.db.attachResource(this)
this.nextTick = db.nextTick
}
this[kOperations] = []
this[kCloseCallbacks] = []
this[kStatus] = 'open'
this[kFinishClose] = this[kFinishClose].bind(this)

Object.defineProperty(AbstractChainedBatch.prototype, 'length', {
enumerable: true,
get () {
return this[kOperations].length
this.db = db
this.db.attachResource(this)
this.nextTick = db.nextTick
}
})

AbstractChainedBatch.prototype.put = function (key, value, options) {
if (this[kStatus] !== 'open') {
throw new ModuleError('Batch is not open: cannot call put() after write() or close()', {
code: 'LEVEL_BATCH_NOT_OPEN'
})
get length () {
return this[kOperations].length
}

const err = this.db._checkKey(key) || this.db._checkValue(value)
if (err) throw err
put (key, value, options) {
if (this[kStatus] !== 'open') {
throw new ModuleError('Batch is not open: cannot call put() after write() or close()', {
code: 'LEVEL_BATCH_NOT_OPEN'
})
}

const db = options && options.sublevel != null ? options.sublevel : this.db
const original = options
const keyEncoding = db.keyEncoding(options && options.keyEncoding)
const valueEncoding = db.valueEncoding(options && options.valueEncoding)
const keyFormat = keyEncoding.format
const err = this.db._checkKey(key) || this.db._checkValue(value)
if (err) throw err

// Forward encoding options
options = { ...options, keyEncoding: keyFormat, valueEncoding: valueEncoding.format }
const db = options && options.sublevel != null ? options.sublevel : this.db
const original = options
const keyEncoding = db.keyEncoding(options && options.keyEncoding)
const valueEncoding = db.valueEncoding(options && options.valueEncoding)
const keyFormat = keyEncoding.format

// Prevent double prefixing
if (db !== this.db) {
options.sublevel = null
}
// Forward encoding options
options = { ...options, keyEncoding: keyFormat, valueEncoding: valueEncoding.format }

const mappedKey = db.prefixKey(keyEncoding.encode(key), keyFormat)
const mappedValue = valueEncoding.encode(value)

this._put(mappedKey, mappedValue, options)
this[kOperations].push({ ...original, type: 'put', key, value })
// Prevent double prefixing
if (db !== this.db) {
options.sublevel = null
}

return this
}
const mappedKey = db.prefixKey(keyEncoding.encode(key), keyFormat)
const mappedValue = valueEncoding.encode(value)

AbstractChainedBatch.prototype._put = function (key, value, options) {}
this._put(mappedKey, mappedValue, options)
this[kOperations].push({ ...original, type: 'put', key, value })

AbstractChainedBatch.prototype.del = function (key, options) {
if (this[kStatus] !== 'open') {
throw new ModuleError('Batch is not open: cannot call del() after write() or close()', {
code: 'LEVEL_BATCH_NOT_OPEN'
})
return this
}

const err = this.db._checkKey(key)
if (err) throw err
_put (key, value, options) {}

const db = options && options.sublevel != null ? options.sublevel : this.db
const original = options
const keyEncoding = db.keyEncoding(options && options.keyEncoding)
const keyFormat = keyEncoding.format
del (key, options) {
if (this[kStatus] !== 'open') {
throw new ModuleError('Batch is not open: cannot call del() after write() or close()', {
code: 'LEVEL_BATCH_NOT_OPEN'
})
}

// Forward encoding options
options = { ...options, keyEncoding: keyFormat }
const err = this.db._checkKey(key)
if (err) throw err

// Prevent double prefixing
if (db !== this.db) {
options.sublevel = null
}
const db = options && options.sublevel != null ? options.sublevel : this.db
const original = options
const keyEncoding = db.keyEncoding(options && options.keyEncoding)
const keyFormat = keyEncoding.format

this._del(db.prefixKey(keyEncoding.encode(key), keyFormat), options)
this[kOperations].push({ ...original, type: 'del', key })
// Forward encoding options
options = { ...options, keyEncoding: keyFormat }

return this
}
// Prevent double prefixing
if (db !== this.db) {
options.sublevel = null
}

AbstractChainedBatch.prototype._del = function (key, options) {}
this._del(db.prefixKey(keyEncoding.encode(key), keyFormat), options)
this[kOperations].push({ ...original, type: 'del', key })

AbstractChainedBatch.prototype.clear = function () {
if (this[kStatus] !== 'open') {
throw new ModuleError('Batch is not open: cannot call clear() after write() or close()', {
code: 'LEVEL_BATCH_NOT_OPEN'
})
return this
}

this._clear()
this[kOperations] = []
_del (key, options) {}

return this
}
clear () {
if (this[kStatus] !== 'open') {
throw new ModuleError('Batch is not open: cannot call clear() after write() or close()', {
code: 'LEVEL_BATCH_NOT_OPEN'
})
}

AbstractChainedBatch.prototype._clear = function () {}

AbstractChainedBatch.prototype.write = function (options, callback) {
callback = getCallback(options, callback)
callback = fromCallback(callback, kPromise)
options = getOptions(options)

if (this[kStatus] !== 'open') {
this.nextTick(callback, new ModuleError('Batch is not open: cannot call write() after write() or close()', {
code: 'LEVEL_BATCH_NOT_OPEN'
}))
} else if (this.length === 0) {
this.close(callback)
} else {
this[kStatus] = 'writing'
this._write(options, (err) => {
this[kStatus] = 'closing'
this[kCloseCallbacks].push(() => callback(err))

// Emit after setting 'closing' status, because event may trigger a
// db close which in turn triggers (idempotently) closing this batch.
if (!err) this.db.emit('batch', this[kOperations])

this._close(this[kFinishClose])
})
this._clear()
this[kOperations] = []

return this
}

return callback[kPromise]
}
_clear () {}

write (options, callback) {
callback = getCallback(options, callback)
callback = fromCallback(callback, kPromise)
options = getOptions(options)

if (this[kStatus] !== 'open') {
this.nextTick(callback, new ModuleError('Batch is not open: cannot call write() after write() or close()', {
code: 'LEVEL_BATCH_NOT_OPEN'
}))
} else if (this.length === 0) {
this.close(callback)
} else {
this[kStatus] = 'writing'
this._write(options, (err) => {
this[kStatus] = 'closing'
this[kCloseCallbacks].push(() => callback(err))

// Emit after setting 'closing' status, because event may trigger a
// db close which in turn triggers (idempotently) closing this batch.
if (!err) this.db.emit('batch', this[kOperations])

this._close(this[kFinishClose])
})
}

return callback[kPromise]
}

AbstractChainedBatch.prototype._write = function (options, callback) {}
_write (options, callback) {}

AbstractChainedBatch.prototype.close = function (callback) {
callback = fromCallback(callback, kPromise)
close (callback) {
callback = fromCallback(callback, kPromise)

if (this[kStatus] === 'closing') {
this[kCloseCallbacks].push(callback)
} else if (this[kStatus] === 'closed') {
this.nextTick(callback)
} else {
this[kCloseCallbacks].push(callback)
if (this[kStatus] === 'closing') {
this[kCloseCallbacks].push(callback)
} else if (this[kStatus] === 'closed') {
this.nextTick(callback)
} else {
this[kCloseCallbacks].push(callback)

if (this[kStatus] !== 'writing') {
this[kStatus] = 'closing'
this._close(this[kFinishClose])
if (this[kStatus] !== 'writing') {
this[kStatus] = 'closing'
this._close(this[kFinishClose])
}
}
}

return callback[kPromise]
}
return callback[kPromise]
}

AbstractChainedBatch.prototype._close = function (callback) {
this.nextTick(callback)
}
_close (callback) {
this.nextTick(callback)
}

AbstractChainedBatch.prototype[kFinishClose] = function () {
this[kStatus] = 'closed'
this.db.detachResource(this)
[kFinishClose] () {
this[kStatus] = 'closed'
this.db.detachResource(this)

const callbacks = this[kCloseCallbacks]
this[kCloseCallbacks] = []
const callbacks = this[kCloseCallbacks]
this[kCloseCallbacks] = []

for (const cb of callbacks) {
cb()
for (const cb of callbacks) {
cb()
}
}
}

Expand Down
Loading

0 comments on commit df94011

Please sign in to comment.