Skip to content

Commit

Permalink
lPush(), rPush()
Browse files Browse the repository at this point in the history
  • Loading branch information
gerold-penz committed Sep 2, 2024
1 parent 2ca5b07 commit 0667929
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 16 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ The ideas for the implementation come from
- [`get()`](#read-value)
- [`getSet()`](#read-and-write-value-in-one-step)
- [`getValues()`](#read-multiple-values)
- `getValuesSet()` --> Set with values
- `getValuesAsSet()` --> Set with values
- Write and Read Items
- [`setItems()`](#write-multiple-items)
- [`getItem()`](#read-item)
- [`getItems()`](#read-multiple-items)
- `getItemsObject()` --> Object with items
- `getItemsMap()` --> Map with items
- `getItemsAsObject()` --> Object with items
- `getItemsAsMap()` --> Map with items
- [Read and Write Binary Files (Images)](#read-and-write-binary-files-images)
- Keys
- [`has()`](#has-key)
Expand Down Expand Up @@ -73,8 +73,11 @@ The ideas for the implementation come from
- [`hGetFields()`](#hash-map-object---get-all-field-names)
- [`hGetValues()`](#hash-map-object---get-all-values)
- [`hDelete()`](#hash-map-object---delete-field)
- `hIncr()`
- `hDecr()`
- `hIncr()` --> Increments the value of a field.
- `hDecr()` --> Decrements the value of a field.
- List (Array Object)
- `lPush()` --> Insert values at the begin of the list.
- `rPush()` --> Insert values at the end of the list.
- Extended database topics
- [Multiple Databases](#multiple-databases)
- [Database Transactions](#database-transactions)
Expand Down
88 changes: 77 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,29 +367,41 @@ export class BunSqliteKeyValue {


// Get multiple items as object
getItemsObject<T = any>(startsWithOrKeys?: string | string[]): {[key: string]: T | undefined} | undefined {
getItemsAsObject<T = any>(startsWithOrKeys?: string | string[]): {[key: string]: T | undefined} | undefined {
const items = this.getItems(startsWithOrKeys)
if (!items) return
return Object.fromEntries(items.map(item => [item.key, item.value as T | undefined]))
}


// alias for getItemsAsObject()
getItemsObject = this.getItemsAsObject


// Get multiple items as Map()
getItemsMap<T = any>(startsWithOrKeys?: string | string[]): Map<string, T | undefined> | undefined {
getItemsAsMap<T = any>(startsWithOrKeys?: string | string[]): Map<string, T | undefined> | undefined {
const items = this.getItems(startsWithOrKeys)
if (!items) return
return new Map(items.map(item => [item.key, item.value as T | undefined]))
}


// Alias for getItemsAsMap()
getItemsMap = this.getItemsAsMap


// Get multiple values as Set()
getValuesSet<T = any>(startsWithOrKeys?: string | string[]): Set<T> | undefined {
getValuesAsSet<T = any>(startsWithOrKeys?: string | string[]): Set<T> | undefined {
const values = this.getValues(startsWithOrKeys)
if (!values) return
return new Set(values)
}


// Alias for getValuesAsSet()
getValuesSet = this.getValuesAsSet


// Checks if key exists
has(key: string): boolean {
const record = this.getKeyStatement.get({key})
Expand Down Expand Up @@ -827,6 +839,68 @@ export class BunSqliteKeyValue {
}


/**
* Array - Left Push
*
* @param {string} key
* @param {T} values
* @returns {number | undefined}
* New length of the list or `undefined` if the old value in the database is not an array.
*
* Inspired by: https://docs.keydb.dev/docs/commands/#lpush
*/
lPush<T = any>(key: string, ...values: T[]): number | undefined {
// @ts-ignore (Transaction returns number, not void.)
return this.db.transaction(() => {
const array = this.get<Array<T>>(key) ?? new Array<T>()
let newLength: number | undefined
try {
values.forEach((value) => {
newLength = array.unshift(value)
})
} catch (error: any) {
if (error.toString().includes("TypeError")) {
return
} else {
throw error
}
}
this.set<Array<T>>(key, array)
return newLength
}).immediate()
}


/**
* Array - Right Push
*
* @param {string} key
* @param {T} values
* @returns {number | undefined}
* New length of the list or `undefined` if the old value in the database is not an array.
*
* Inspired by: https://docs.keydb.dev/docs/commands/#rpush
*/
rPush<T = any>(key: string, ...values: T[]): number | undefined {
// @ts-ignore (Transaction returns number, not void.)
return this.db.transaction(() => {
const array = this.get<Array<T>>(key) ?? new Array<T>()
let newLength: number | undefined
try {
newLength = array.push(...values)
} catch (error: any) {
if (error.toString().includes("TypeError")) {
return
} else {
throw error
}
}
this.set<Array<T>>(key, array)
return newLength
}).immediate()
}


// ToDo: lIndex()
// Inspired by: https://docs.keydb.dev/docs/commands/#lindex

Expand All @@ -839,10 +913,6 @@ export class BunSqliteKeyValue {
// Inspired by: https://docs.keydb.dev/docs/commands/#lpop


// ToDo: lPush()
// Inspired by: https://docs.keydb.dev/docs/commands/#lpush


// ToDo: lRange()
// Inspired by: https://docs.keydb.dev/docs/commands/#lrange

Expand All @@ -863,10 +933,6 @@ export class BunSqliteKeyValue {
// Inspired by: https://docs.keydb.dev/docs/commands/#rpoplpush


// ToDo: rPush()
// Inspired by: https://docs.keydb.dev/docs/commands/#rpush


// ToDo: sAdd()
// Inspired by: https://docs.keydb.dev/docs/commands/#sadd

Expand Down
30 changes: 30 additions & 0 deletions tests/memory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,18 @@ test("Get items as Object", () => {
store.set<string>(KEY_2, STRING_VALUE_2)
store.set(KEY_3, null)

expect(store.getItemsAsObject([
KEY_1,
KEY_2,
KEY_3,
"unknown-key"
])).toEqual({
[KEY_1]: STRING_VALUE_1,
[KEY_2]: STRING_VALUE_2,
[KEY_3]: null,
"unknown-key": undefined
})

expect(store.getItemsObject([
KEY_1,
KEY_2,
Expand All @@ -341,6 +353,18 @@ test("Get items as Map", () => {
store.set<string>(KEY_2, STRING_VALUE_2)
store.set(KEY_3, null)

expect(store.getItemsAsMap([
KEY_1,
KEY_2,
KEY_3,
"unknown-key"
])).toEqual(new Map([
[KEY_1, STRING_VALUE_1],
[KEY_2, STRING_VALUE_2],
[KEY_3, null],
["unknown-key", undefined],
]))

expect(store.getItemsMap([
KEY_1,
KEY_2,
Expand All @@ -362,6 +386,12 @@ test("Get values as Set", () => {
store.set<string>(KEY_2, STRING_VALUE_2)
store.set(KEY_3, null)

expect(store.getValuesAsSet([
KEY_1, KEY_2, KEY_3, "unknown-key"
])).toEqual(new Set([
STRING_VALUE_1, STRING_VALUE_2, null, undefined
]))

expect(store.getValuesSet([
KEY_1, KEY_2, KEY_3, "unknown-key"
])).toEqual(new Set([
Expand Down

0 comments on commit 0667929

Please sign in to comment.