3
3
const {
4
4
Key, Errors, Adapter,
5
5
utils : {
6
- filter , map , take , sortAll
6
+ sortAll
7
7
}
8
8
} = require ( 'interface-datastore' )
9
+ const filter = require ( 'it-filter' )
10
+ const map = require ( 'it-map' )
11
+ const take = require ( 'it-take' )
9
12
10
13
/**
11
14
* @typedef {import('interface-datastore').Datastore } Datastore
12
15
* @typedef {import('interface-datastore').Pair } Pair
13
16
* @typedef {import('interface-datastore').Batch } Batch
14
17
* @typedef {import('interface-datastore').Query } Query
18
+ * @typedef {import('interface-datastore').KeyQuery } KeyQuery
15
19
* @typedef {import('interface-datastore').Options } QueryOptions
16
20
*/
17
21
@@ -159,41 +163,42 @@ class LevelDatastore extends Adapter {
159
163
160
164
/**
161
165
* @param {Query } q
162
- * @returns {AsyncIterable<Pair> }
163
166
*/
164
167
query ( q ) {
165
- let values = true
166
- if ( q . keysOnly != null ) {
167
- values = ! q . keysOnly
168
+ let it = this . _query ( {
169
+ values : true ,
170
+ prefix : q . prefix
171
+ } )
172
+
173
+ if ( Array . isArray ( q . filters ) ) {
174
+ it = q . filters . reduce ( ( it , f ) => filter ( it , f ) , it )
168
175
}
169
176
170
- const opts = {
171
- keys : true ,
172
- values : values ,
173
- keyAsBuffer : true
177
+ if ( Array . isArray ( q . orders ) ) {
178
+ it = q . orders . reduce ( ( it , f ) => sortAll ( it , f ) , it )
174
179
}
175
180
176
- // Let the db do the prefix matching
177
- if ( q . prefix != null ) {
178
- const prefix = q . prefix . toString ( )
179
- // Match keys greater than or equal to `prefix` and
180
- // @ts -ignore
181
- opts . gte = prefix
182
- // less than `prefix` + \xFF (hex escape sequence)
183
- // @ts -ignore
184
- opts . lt = prefix + '\xFF'
181
+ const { offset, limit } = q
182
+ if ( offset ) {
183
+ let i = 0
184
+ it = filter ( it , ( ) => i ++ >= offset )
185
185
}
186
186
187
- let it = levelIteratorToIterator (
188
- this . db . iterator ( opts )
189
- )
187
+ if ( limit ) {
188
+ it = take ( it , limit )
189
+ }
190
190
191
- it = map ( it , ( { key, value } ) => {
192
- if ( values ) {
193
- return { key, value }
194
- }
195
- return /** @type {Pair } */ ( { key } )
196
- } )
191
+ return it
192
+ }
193
+
194
+ /**
195
+ * @param {KeyQuery } q
196
+ */
197
+ queryKeys ( q ) {
198
+ let it = map ( this . _query ( {
199
+ values : false ,
200
+ prefix : q . prefix
201
+ } ) , ( { key } ) => key )
197
202
198
203
if ( Array . isArray ( q . filters ) ) {
199
204
it = q . filters . reduce ( ( it , f ) => filter ( it , f ) , it )
@@ -202,6 +207,7 @@ class LevelDatastore extends Adapter {
202
207
if ( Array . isArray ( q . orders ) ) {
203
208
it = q . orders . reduce ( ( it , f ) => sortAll ( it , f ) , it )
204
209
}
210
+
205
211
const { offset, limit } = q
206
212
if ( offset ) {
207
213
let i = 0
@@ -214,6 +220,33 @@ class LevelDatastore extends Adapter {
214
220
215
221
return it
216
222
}
223
+
224
+ /**
225
+ * @param {object } opts
226
+ * @param {boolean } opts.values
227
+ * @param {string } [opts.prefix]
228
+ * @returns {AsyncIterable<Pair> }
229
+ */
230
+ _query ( opts ) {
231
+ const iteratorOpts = {
232
+ keys : true ,
233
+ keyAsBuffer : true ,
234
+ values : opts . values
235
+ }
236
+
237
+ // Let the db do the prefix matching
238
+ if ( opts . prefix != null ) {
239
+ const prefix = opts . prefix . toString ( )
240
+ // Match keys greater than or equal to `prefix` and
241
+ // @ts -ignore
242
+ iteratorOpts . gte = prefix
243
+ // less than `prefix` + \xFF (hex escape sequence)
244
+ // @ts -ignore
245
+ iteratorOpts . lt = prefix + '\xFF'
246
+ }
247
+
248
+ return levelIteratorToIterator ( this . db . iterator ( iteratorOpts ) )
249
+ }
217
250
}
218
251
219
252
/**
0 commit comments