Skip to content

Commit

Permalink
touch() added.
Browse files Browse the repository at this point in the history
  • Loading branch information
gerold-penz committed Aug 11, 2024
1 parent fda97d4 commit e4eace0
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 3 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,45 @@ store.db.transaction(() => {
```


## Renew TTL

```typescript
touch(key: string, ttlMs?: number): boolean
```

Renews or deletes the TTL of the database row.
Returns `true` if the `key` exists.
Inspired by: https://docs.keydb.dev/docs/commands/#touch

### key

The key must be a string.

### ttlMs (optional)

"Time to live" in milliseconds. After this time,
the item becomes invalid and is deleted from the database
the next time it is accessed or when the application is started.
Uses the global `ttlMs` as default value.
Set the value to 0 if you want to delete the TTL.

### Example

```typescript
import { BunSqliteKeyValue } from "bun-sqlite-key-value"
const store = new BunSqliteKeyValue()
store.set("my-key", "my-value", 10000)
// Update TTL
store.touch("my-key", 10000) // --> true
// Delete TTL
store.touch("my-key", 0) // --> true
```


## Hash (Map Object) - Write Value
```typescript
hSet(key: string, field: string, value: any, ttlMs?: number)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bun-sqlite-key-value",
"version": "1.9.6",
"version": "1.9.7",
"author": {
"name": "Gerold Penz",
"email": "[email protected]",
Expand Down
14 changes: 12 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export class BunSqliteKeyValue {
private getRandomKeyStatement: Statement<Omit<Record, "value" | "expires">>
private getRandomItemStatement: Statement<Omit<Record, "expires">>
private renameStatement: Statement
private touchStatement: Statement


// - `filename`: The full path of the SQLite database to open.
Expand Down Expand Up @@ -149,6 +150,7 @@ export class BunSqliteKeyValue {
LIMIT 1
)`)
this.renameStatement = this.db.query("UPDATE items SET key = $newKey WHERE key = $oldKey")
this.touchStatement = this.db.query("UPDATE items SET expires = $expires WHERE key = $key")

// Delete expired items
this.deleteExpired()
Expand Down Expand Up @@ -605,9 +607,17 @@ export class BunSqliteKeyValue {
}


// ToDo: touch(key, ttlMs)
// Renews the TTL
// Renews or deletes the TTL of the database row.
// Returns `true` if the `key` exists.
// Inspired by: https://docs.keydb.dev/docs/commands/#touch
touch(key: string, ttlMs?: number): boolean {
let expires: number | undefined
ttlMs = ttlMs ?? this.ttlMs
if (ttlMs !== undefined && ttlMs > 0) {
expires = Date.now() + ttlMs
}
return this.touchStatement.run({key, expires}).changes === 1
}


// ToDo: ttl() milliseconds like pTtl()
Expand Down
45 changes: 45 additions & 0 deletions tests/memory.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, test } from "bun:test"
import { BunSqliteKeyValue } from "../src"
import { Statement } from "bun:sqlite"


const KEY_1: string = "test-key-1"
Expand Down Expand Up @@ -565,6 +566,50 @@ test("rename()", async () => {
})


test("touch()", async () => {
const store = new BunSqliteKeyValue()

store.set(KEY_1, STRING_VALUE_1, 30000)

const sqlStatement: Statement<{expires: number}> = store.db.prepare(
"SELECT expires FROM items WHERE key = $key"
)

// Reset TTL
expect(store.touch(KEY_1, 20000)).toBeTrue()
expect(sqlStatement.get(KEY_1)?.expires).toBeNumber()

// Key not found
expect(store.touch(KEY_2)).toBeFalse()

// Delete TTL
expect(store.touch(KEY_1)).toBeTrue()
expect(sqlStatement.get(KEY_1)?.expires).toBeNull()
})


test("touch() with global defined TTL", async () => {
const store = new BunSqliteKeyValue(":memory:", {ttlMs: 30000})

store.set(KEY_1, STRING_VALUE_1)

const sqlStatement: Statement<{expires: number}> = store.db.prepare(
"SELECT expires FROM items WHERE key = $key"
)

// Reset TTL
expect(store.touch(KEY_1)).toBeTrue()
expect(sqlStatement.get(KEY_1)?.expires).toBeNumber()

// Key not found
expect(store.touch(KEY_2)).toBeFalse()

// Delete TTL
expect(store.touch(KEY_1, 0)).toBeTrue()
expect(sqlStatement.get(KEY_1)?.expires).toBeNull()
})


test("hSet(), hGet()", async () => {
const store = new BunSqliteKeyValue()

Expand Down

0 comments on commit e4eace0

Please sign in to comment.