This repository has been archived by the owner on Dec 2, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathdeferred-leveldown.js
132 lines (106 loc) · 3.78 KB
/
deferred-leveldown.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'use strict'
const { AbstractLevelDOWN } = require('abstract-leveldown')
const inherits = require('inherits')
const DeferredIterator = require('./deferred-iterator')
const DeferredChainedBatch = require('./deferred-chained-batch')
const getCallback = require('./util').getCallback
const deferrables = ['put', 'get', 'getMany', 'del', 'batch', 'clear']
const optionalDeferrables = ['approximateSize', 'compactRange']
const kInnerDb = Symbol('innerDb')
const kOperations = Symbol('operations')
const kPromise = Symbol('promise')
function DeferredLevelDOWN (db) {
AbstractLevelDOWN.call(this, db.supports || {})
// TODO (future major): remove this fallback; db must have manifest that
// declares approximateSize and compactRange in additionalMethods.
for (const m of optionalDeferrables) {
if (typeof db[m] === 'function' && !this.supports.additionalMethods[m]) {
this.supports.additionalMethods[m] = true
}
}
this[kInnerDb] = db
this[kOperations] = []
implement(this)
}
inherits(DeferredLevelDOWN, AbstractLevelDOWN)
DeferredLevelDOWN.prototype.type = 'deferred-leveldown'
// Backwards compatibility for reachdown and subleveldown
Object.defineProperty(DeferredLevelDOWN.prototype, '_db', {
enumerable: true,
get () {
return this[kInnerDb]
}
})
DeferredLevelDOWN.prototype._open = function (options, callback) {
const onopen = (err) => {
if (err || this[kInnerDb].status !== 'open') {
// TODO: reject scheduled operations
return callback(err || new Error('Database is not open'))
}
const operations = this[kOperations]
this[kOperations] = []
for (const op of operations) {
if (op.iterator) {
op.iterator.setDb(this[kInnerDb])
} else {
this[kInnerDb][op.method](...op.args)
}
}
/* istanbul ignore if: assertion */
if (this[kOperations].length > 0) {
throw new Error('Did not expect further operations')
}
callback()
}
if (this[kInnerDb].status === 'new' || this[kInnerDb].status === 'closed') {
this[kInnerDb].open(options, onopen)
} else {
this._nextTick(onopen)
}
}
DeferredLevelDOWN.prototype._close = function (callback) {
this[kInnerDb].close(callback)
}
DeferredLevelDOWN.prototype._isOperational = function () {
return this.status === 'opening'
}
function implement (self) {
const additionalMethods = Object.keys(self.supports.additionalMethods)
for (const method of deferrables.concat(additionalMethods)) {
// Override the public rather than private methods to cover cases where abstract-leveldown
// has a fast-path like on db.batch([]) which bypasses _batch() because the array is empty.
self[method] = function (...args) {
if (method === 'batch' && args.length === 0) {
return new DeferredChainedBatch(this)
} else if (this.status === 'open') {
return this[kInnerDb][method](...args)
}
const callback = getCallback(args, kPromise)
if (this.status === 'opening') {
this[kOperations].push({ method, args })
} else {
this._nextTick(callback, new Error('Database is not open'))
}
return callback[kPromise]
}
}
self.iterator = function (options) {
if (this.status === 'open') {
return this[kInnerDb].iterator(options)
} else if (this.status === 'opening') {
const iterator = new DeferredIterator(this, options)
this[kOperations].push({ iterator })
return iterator
} else {
throw new Error('Database is not open')
}
}
for (const method of deferrables.concat(['iterator'])) {
self['_' + method] = function () {
/* istanbul ignore next: assertion */
throw new Error('Did not expect private method to be called: ' + method)
}
}
}
module.exports = DeferredLevelDOWN
module.exports.DeferredIterator = DeferredIterator