Skip to content

Commit a021176

Browse files
committed
Add getSync() method
Category: addition
1 parent c35ab16 commit a021176

File tree

3 files changed

+83
-4
lines changed

3 files changed

+83
-4
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ Get a value from the database by `key`. The optional `options` object may contai
158158

159159
Returns a promise for the value. If the `key` was not found then the value will be `undefined`.
160160

161+
### `db.getSync(key[, options])`
162+
163+
Synchronously get a value from the database by `key`. This blocks the event loop but can be significantly faster than `db.get()`. Options are the same. Returns the value, or `undefined` if not found.
164+
161165
### `db.getMany(keys[, options])`
162166

163167
Get multiple values from the database by an array of `keys`. The optional `options` object may contain:
@@ -1509,6 +1513,12 @@ If the database indicates support of snapshots via `db.supports.implicitSnapshot
15091513

15101514
The default `_get()` returns a promise for an `undefined` value. It must be overridden.
15111515

1516+
### `db._getSync(key, options)`
1517+
1518+
Synchronously get a value by `key`. Receives the same options as `db._get()`. Must return a value, or `undefined` if not found.
1519+
1520+
The default `_getSync()` throws a [`LEVEL_NOT_SUPPORTED`](#level_not_supported) error. It should be overridden but support of `_getSync()` is currently opt-in. Set `manifest.getSync` to `true` in order to enable tests.
1521+
15121522
### `db._getMany(keys, options)`
15131523

15141524
Get multiple values by an array of `keys`. The `options` object will always have the following properties: `keyEncoding` and `valueEncoding`. Must return a promise. If an error occurs, reject the promise. Otherwise resolve the promise with an array of values. If a key does not exist, set the relevant value to `undefined`.

abstract-level.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,73 @@ class AbstractLevel extends EventEmitter {
351351
return undefined
352352
}
353353

354+
getSync (key, options) {
355+
if (this.status !== 'open') {
356+
throw new ModuleError('Database is not open', {
357+
code: 'LEVEL_DATABASE_NOT_OPEN'
358+
})
359+
}
360+
361+
this._assertValidKey(key)
362+
363+
// Fast-path for default options (known encoding, no cloning, no snapshot)
364+
if (options == null) {
365+
const encodedKey = this.#keyEncoding.encode(key)
366+
const mappedKey = this.prefixKey(encodedKey, this.#keyEncoding.format, true)
367+
const value = this._getSync(mappedKey, this.#defaultOptions.entryFormat)
368+
369+
try {
370+
return value !== undefined ? this.#valueEncoding.decode(value) : undefined
371+
} catch (err) {
372+
throw new ModuleError('Could not decode value', {
373+
code: 'LEVEL_DECODE_ERROR',
374+
cause: err
375+
})
376+
}
377+
}
378+
379+
const snapshot = options.snapshot
380+
const keyEncoding = this.keyEncoding(options.keyEncoding)
381+
const valueEncoding = this.valueEncoding(options.valueEncoding)
382+
const keyFormat = keyEncoding.format
383+
const valueFormat = valueEncoding.format
384+
385+
// Forward encoding options. Avoid cloning if possible.
386+
if (options.keyEncoding !== keyFormat || options.valueEncoding !== valueFormat) {
387+
options = { ...options, keyEncoding: keyFormat, valueEncoding: valueFormat }
388+
}
389+
390+
const encodedKey = keyEncoding.encode(key)
391+
const mappedKey = this.prefixKey(encodedKey, keyFormat, true)
392+
393+
let value
394+
395+
// Keep snapshot open during operation
396+
snapshot?.ref()
397+
398+
try {
399+
value = this._getSync(mappedKey, options)
400+
} finally {
401+
// Release snapshot
402+
snapshot?.unref()
403+
}
404+
405+
try {
406+
return value !== undefined ? valueEncoding.decode(value) : undefined
407+
} catch (err) {
408+
throw new ModuleError('Could not decode value', {
409+
code: 'LEVEL_DECODE_ERROR',
410+
cause: err
411+
})
412+
}
413+
}
414+
415+
async _getSync (key, options) {
416+
throw new ModuleError('Database does not support getSync()', {
417+
code: 'LEVEL_NOT_SUPPORTED'
418+
})
419+
}
420+
354421
async getMany (keys, options) {
355422
options = getOptions(options, this.#defaultOptions.entry)
356423

types/abstract-level.d.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ declare class AbstractLevel<TFormat, KDefault = string, VDefault = string>
7878
* Get a value from the database by {@link key}.
7979
*/
8080
get (key: KDefault): Promise<VDefault | undefined>
81+
get<K = KDefault, V = VDefault> (key: K, options: AbstractGetOptions<K, V>): Promise<V | undefined>
8182

82-
get<K = KDefault, V = VDefault> (
83-
key: K,
84-
options: AbstractGetOptions<K, V>
85-
): Promise<V | undefined>
83+
/**
84+
* Synchronously get a value from the database by {@link key}.
85+
*/
86+
getSync (key: KDefault): VDefault | undefined
87+
getSync<K = KDefault, V = VDefault> (key: K, options: AbstractGetOptions<K, V>): V | undefined
8688

8789
/**
8890
* Get multiple values from the database by an array of {@link keys}.

0 commit comments

Comments
 (0)