109 lines
3.0 KiB
JavaScript
Raw Normal View History

'use strict'
const { AbstractIterator, AbstractKeyIterator, AbstractValueIterator } = require('../abstract-iterator')
const ModuleError = require('module-error')
const kNut = Symbol('nut')
const kUndefer = Symbol('undefer')
const kFactory = Symbol('factory')
class DeferredIterator extends AbstractIterator {
constructor (db, options) {
super(db, options)
this[kNut] = null
this[kFactory] = () => db.iterator(options)
this.db.defer(() => this[kUndefer]())
}
}
class DeferredKeyIterator extends AbstractKeyIterator {
constructor (db, options) {
super(db, options)
this[kNut] = null
this[kFactory] = () => db.keys(options)
this.db.defer(() => this[kUndefer]())
}
}
class DeferredValueIterator extends AbstractValueIterator {
constructor (db, options) {
super(db, options)
this[kNut] = null
this[kFactory] = () => db.values(options)
this.db.defer(() => this[kUndefer]())
}
}
for (const Iterator of [DeferredIterator, DeferredKeyIterator, DeferredValueIterator]) {
Iterator.prototype[kUndefer] = function () {
if (this.db.status === 'open') {
this[kNut] = this[kFactory]()
}
}
Iterator.prototype._next = function (callback) {
if (this[kNut] !== null) {
this[kNut].next(callback)
} else if (this.db.status === 'opening') {
this.db.defer(() => this._next(callback))
} else {
this.nextTick(callback, new ModuleError('Iterator is not open: cannot call next() after close()', {
code: 'LEVEL_ITERATOR_NOT_OPEN'
}))
}
}
Iterator.prototype._nextv = function (size, options, callback) {
if (this[kNut] !== null) {
this[kNut].nextv(size, options, callback)
} else if (this.db.status === 'opening') {
this.db.defer(() => this._nextv(size, options, callback))
} else {
this.nextTick(callback, new ModuleError('Iterator is not open: cannot call nextv() after close()', {
code: 'LEVEL_ITERATOR_NOT_OPEN'
}))
}
}
Iterator.prototype._all = function (options, callback) {
if (this[kNut] !== null) {
this[kNut].all(callback)
} else if (this.db.status === 'opening') {
this.db.defer(() => this._all(options, callback))
} else {
this.nextTick(callback, new ModuleError('Iterator is not open: cannot call all() after close()', {
code: 'LEVEL_ITERATOR_NOT_OPEN'
}))
}
}
Iterator.prototype._seek = function (target, options) {
if (this[kNut] !== null) {
// TODO: explain why we need _seek() rather than seek() here
this[kNut]._seek(target, options)
} else if (this.db.status === 'opening') {
this.db.defer(() => this._seek(target, options))
}
}
Iterator.prototype._close = function (callback) {
if (this[kNut] !== null) {
this[kNut].close(callback)
} else if (this.db.status === 'opening') {
this.db.defer(() => this._close(callback))
} else {
this.nextTick(callback)
}
}
}
exports.DeferredIterator = DeferredIterator
exports.DeferredKeyIterator = DeferredKeyIterator
exports.DeferredValueIterator = DeferredValueIterator