3
3
4
4
/* :: import type {Callback, Batch, Query, QueryResult, QueryEntry} from 'interface-datastore' */
5
5
6
- const pull = require ( 'pull-stream' )
7
6
const levelup = require ( 'levelup' )
8
-
9
- const asyncFilter = require ( 'interface-datastore' ) . utils . asyncFilter
10
- const asyncSort = require ( 'interface-datastore' ) . utils . asyncSort
11
- const Key = require ( 'interface-datastore' ) . Key
12
- const Errors = require ( 'interface-datastore' ) . Errors
7
+ const { Key, Errors, utils } = require ( 'interface-datastore' )
13
8
const encode = require ( 'encoding-down' )
9
+ const { promisify } = require ( 'util' )
10
+
11
+ const { filter, map, take, sortAll } = utils
14
12
15
13
/**
16
14
* A datastore backed by leveldb.
@@ -50,59 +48,53 @@ class LevelDatastore {
50
48
)
51
49
}
52
50
53
- open ( callback /* : Callback<void> */ ) /* : void */ {
54
- this . db . open ( ( err ) => {
55
- if ( err ) {
56
- return callback ( Errors . dbOpenFailedError ( err ) )
57
- }
58
- callback ( )
59
- } )
51
+ async open ( ) /* : Promise */ {
52
+ try {
53
+ await this . db . open ( )
54
+ } catch ( err ) {
55
+ throw Errors . dbOpenFailedError ( err )
56
+ }
60
57
}
61
58
62
- put ( key /* : Key */ , value /* : Buffer */ , callback /* : Callback<void> */ ) /* : void */ {
63
- this . db . put ( key . toString ( ) , value , ( err ) => {
64
- if ( err ) {
65
- return callback ( Errors . dbWriteFailedError ( err ) )
66
- }
67
- callback ( )
68
- } )
59
+ async put ( key /* : Key */ , value /* : Buffer */ ) /* : Promise */ {
60
+ try {
61
+ await this . db . put ( key . toString ( ) , value )
62
+ } catch ( err ) {
63
+ throw Errors . dbWriteFailedError ( err )
64
+ }
69
65
}
70
66
71
- get ( key /* : Key */ , callback /* : Callback<Buffer> */ ) /* : void */ {
72
- this . db . get ( key . toString ( ) , ( err , data ) => {
73
- if ( err ) {
74
- return callback ( Errors . notFoundError ( err ) )
75
- }
76
- callback ( null , data )
77
- } )
67
+ async get ( key /* : Key */ ) /* : Promise */ {
68
+ let data
69
+ try {
70
+ data = await this . db . get ( key . toString ( ) )
71
+ } catch ( err ) {
72
+ if ( err . notFound ) throw Errors . notFoundError ( err )
73
+ throw Errors . dbWriteFailedError ( err )
74
+ }
75
+ return data
78
76
}
79
77
80
- has ( key /* : Key */ , callback /* : Callback<bool> */ ) /* : void */ {
81
- this . db . get ( key . toString ( ) , ( err , res ) => {
82
- if ( err ) {
83
- if ( err . notFound ) {
84
- callback ( null , false )
85
- return
86
- }
87
- callback ( err )
88
- return
89
- }
90
-
91
- callback ( null , true )
92
- } )
78
+ async has ( key /* : Key */ ) /* : Promise<Boolean> */ {
79
+ try {
80
+ await this . db . get ( key . toString ( ) )
81
+ } catch ( err ) {
82
+ if ( err . notFound ) return false
83
+ throw err
84
+ }
85
+ return true
93
86
}
94
87
95
- delete ( key /* : Key */ , callback /* : Callback<void> */ ) /* : void */ {
96
- this . db . del ( key . toString ( ) , ( err ) => {
97
- if ( err ) {
98
- return callback ( Errors . dbDeleteFailedError ( err ) )
99
- }
100
- callback ( )
101
- } )
88
+ async delete ( key /* : Key */ ) /* : Promise */ {
89
+ try {
90
+ await this . db . del ( key . toString ( ) )
91
+ } catch ( err ) {
92
+ throw Errors . dbDeleteFailedError ( err )
93
+ }
102
94
}
103
95
104
- close ( callback /* : Callback<void> */ ) /* : void */ {
105
- this . db . close ( callback )
96
+ async close ( ) /* : Promise */ {
97
+ return this . db . close ( )
106
98
}
107
99
108
100
batch ( ) /* : Batch<Buffer> */ {
@@ -121,8 +113,8 @@ class LevelDatastore {
121
113
key : key . toString ( )
122
114
} )
123
115
} ,
124
- commit : ( callback /* : Callback<void> */ ) /* : void */ => {
125
- this . db . batch ( ops , callback )
116
+ commit : async ( ) /* : Promise */ => {
117
+ return this . db . batch ( ops )
126
118
}
127
119
}
128
120
}
@@ -133,70 +125,65 @@ class LevelDatastore {
133
125
values = ! q . keysOnly
134
126
}
135
127
136
- const iter = this . db . db . iterator ( {
137
- keys : true ,
138
- values : values ,
139
- keyAsBuffer : true
140
- } )
141
-
142
- const rawStream = ( end , cb ) => {
143
- if ( end ) {
144
- return iter . end ( ( err ) => {
145
- cb ( err || end )
146
- } )
147
- }
148
-
149
- iter . next ( ( err , key , value ) => {
150
- if ( err ) {
151
- return cb ( err )
152
- }
153
-
154
- if ( err == null && key == null && value == null ) {
155
- return iter . end ( ( err ) => {
156
- cb ( err || true )
157
- } )
158
- }
159
-
160
- const res /* : QueryEntry<Buffer> */ = {
161
- key : new Key ( key , false )
162
- }
163
-
164
- if ( values ) {
165
- res . value = Buffer . from ( value )
166
- }
167
-
168
- cb ( null , res )
128
+ let it = levelIteratorToIterator (
129
+ this . db . db . iterator ( {
130
+ keys : true ,
131
+ values : values ,
132
+ keyAsBuffer : true
169
133
} )
170
- }
134
+ )
171
135
172
- let tasks = [ rawStream ]
173
- let filters = [ ]
136
+ it = map ( it , ( { key, value } ) => {
137
+ const res /* : QueryEntry<Buffer> */ = { key : new Key ( key , false ) }
138
+ if ( values ) {
139
+ res . value = Buffer . from ( value )
140
+ }
141
+ return res
142
+ } )
174
143
175
144
if ( q . prefix != null ) {
176
- const prefix = q . prefix
177
- filters . push ( ( e , cb ) => cb ( null , e . key . toString ( ) . startsWith ( prefix ) ) )
145
+ it = filter ( it , e => e . key . toString ( ) . startsWith ( q . prefix ) )
178
146
}
179
147
180
- if ( q . filters != null ) {
181
- filters = filters . concat ( q . filters )
148
+ if ( Array . isArray ( q . filters ) ) {
149
+ it = q . filters . reduce ( ( it , f ) => filter ( it , f ) , it )
182
150
}
183
151
184
- tasks = tasks . concat ( filters . map ( f => asyncFilter ( f ) ) )
185
-
186
- if ( q . orders != null ) {
187
- tasks = tasks . concat ( q . orders . map ( o => asyncSort ( o ) ) )
152
+ if ( Array . isArray ( q . orders ) ) {
153
+ it = q . orders . reduce ( ( it , f ) => sortAll ( it , f ) , it )
188
154
}
189
155
190
156
if ( q . offset != null ) {
191
157
let i = 0
192
- tasks . push ( pull . filter ( ( ) => i ++ >= q . offset ) )
158
+ it = filter ( it , ( ) => i ++ >= q . offset )
193
159
}
194
160
195
161
if ( q . limit != null ) {
196
- tasks . push ( pull . take ( q . limit ) )
162
+ it = take ( it , q . limit )
197
163
}
198
164
199
- return pull . apply ( null , tasks )
165
+ return it
166
+ }
167
+ }
168
+
169
+ function levelIteratorToIterator ( li ) {
170
+ return {
171
+ next : ( ) => new Promise ( ( resolve , reject ) => {
172
+ li . next ( ( err , key , value ) => {
173
+ if ( err ) return reject ( err )
174
+ if ( key == null ) return resolve ( { done : true } )
175
+ resolve ( { done : false , value : { key, value } } )
176
+ } )
177
+ } ) ,
178
+ return : ( ) => new Promise ( ( resolve , reject ) => {
179
+ li . end ( err => {
180
+ if ( err ) return reject ( err )
181
+ resolve ( { done : true } )
182
+ } )
183
+ } ) ,
184
+ [ Symbol . asyncIterator ] ( ) {
185
+ return this
186
+ }
200
187
}
201
188
}
202
189
0 commit comments