bun-sqlite-key-value
Advanced tools
Comparing version 1.0.1 to 1.1.1
{ | ||
"name": "bun-sqlite-key-value", | ||
"description": "A key-value store with SQLite that uses bun:sqlite and v8 as a fast Json replacement.", | ||
"version": "1.0.1", | ||
"version": "1.1.1", | ||
"author": "Gerold Penz<gerold@gp-softwaretechnik.at>", | ||
@@ -32,3 +32,4 @@ "module": "src/index.ts", | ||
"Database", | ||
"TypeScript" | ||
"TypeScript", | ||
"Cache" | ||
], | ||
@@ -35,0 +36,0 @@ "license": "MIT", |
149
src/index.ts
@@ -5,20 +5,33 @@ import { Database, Statement } from "bun:sqlite" | ||
const getNow = () => new Date().getTime() / 1000 | ||
// Returns current time as milliseconds since 1970-01-01T00:00:00Z. | ||
const getNow = () => new Date().getTime() | ||
export interface Item<T> { | ||
key: string | ||
value: T | ||
} | ||
export class BunSqliteKeyValue { | ||
private db: Database | ||
db: Database | ||
private deleteExpiredStatement: Statement | ||
private getStatement: Statement | ||
private getAllStatement: Statement | ||
private getAllStartsWithStatement: Statement | ||
private setStatement: Statement | ||
private deleteStatement: Statement | ||
private clearStatement: Statement | ||
private countStatement: Statement | ||
private setItemStatement: Statement | ||
private getItemStatement: Statement | ||
private getAllItemsStatement: Statement | ||
private getItemsStatement: Statement | ||
constructor(path: string = ":memory:") { | ||
// @param filename: The full path of the SQLite database to open. | ||
// Pass an empty string (`""`) or `":memory:"` or undefined for an in-memory database. | ||
// @param options: defaults to `{readwrite: true, create: true}`. | ||
// If a number, then it's treated as `SQLITE_OPEN_*` constant flags. | ||
constructor(filename?: string, options?: Object | number) { | ||
// Open database | ||
this.db = new Database(path) | ||
this.db = new Database(filename, options) | ||
@@ -29,10 +42,13 @@ // Create table and index | ||
// Prepare statements | ||
// Prepare cached statements | ||
this.getAllItemsStatement = this.db.query("SELECT key, value, expires FROM items") | ||
this.clearStatement = this.db.query("DELETE FROM items") | ||
this.countStatement = this.db.query("SELECT COUNT(*) AS count FROM items") | ||
// Prepare dynamic statements | ||
this.deleteExpiredStatement = this.db.prepare("DELETE FROM items WHERE expires < $now") | ||
this.setStatement = this.db.prepare("INSERT INTO items (key, value, expires) VALUES ($key, $value, $expires)") | ||
this.getStatement = this.db.prepare("SELECT value, expires FROM items WHERE key = $key") | ||
this.getAllStatement = this.db.prepare("SELECT key, value, expires FROM items") | ||
this.getAllStartsWithStatement = this.db.prepare("SELECT key, value, expires FROM items WHERE key LIKE $startsWith") | ||
this.setItemStatement = this.db.prepare("INSERT OR REPLACE INTO items (key, value, expires) VALUES ($key, $value, $expires)") | ||
this.getItemStatement = this.db.prepare("SELECT value, expires FROM items WHERE key = $key") | ||
this.getItemsStatement = this.db.prepare("SELECT key, value, expires FROM items WHERE key LIKE $startsWith") | ||
this.deleteStatement = this.db.prepare("DELETE FROM items WHERE key = $key") | ||
this.clearStatement = this.db.prepare("DELETE FROM items") | ||
@@ -43,3 +59,4 @@ // Delete expired items | ||
// Delete all expired records | ||
deleteExpired() { | ||
@@ -50,10 +67,38 @@ this.deleteExpiredStatement.run({$now: getNow()}) | ||
set<T = any>(key: string, value: T, expires?: number) { | ||
const serialized = serialize(value) | ||
this.setStatement.run({$key: key, $value: serialized, $expires: expires}) | ||
delete(key: string) { | ||
this.deleteStatement.run({$key: key}) | ||
} | ||
get<T = any>(key: string): {key: string, value: T} | undefined { | ||
const record = this.getStatement.get({$key: key}) | ||
// Delete all items | ||
clear() { | ||
this.clearStatement.run() | ||
} | ||
// Returns the number of all items, including those that have already expired. | ||
// First delete the expired items with `deleteExpired()` | ||
// if you want to get the number of items that have not yet expired. | ||
getCount(): number { | ||
return (this.countStatement.get() as {count: number}).count | ||
} | ||
// @param ttlMs: Time to live in milliseconds | ||
setValue<T = any>(key: string, value: T, ttlMs?: number) { | ||
let $expires: number | undefined | ||
if (ttlMs) { | ||
$expires = getNow() + ttlMs | ||
} | ||
const $value = serialize(value) | ||
this.setItemStatement.run({$key: key, $value, $expires}) | ||
} | ||
// Alias for `setValue` | ||
set = this.setValue | ||
getItem<T = any>(key: string): Item<T> | undefined { | ||
const record = this.getItemStatement.get({$key: key}) | ||
if (!record) return | ||
@@ -74,7 +119,16 @@ const {value, expires} = record as {value: any, expires: number | undefined | null} | ||
getAll<T = any>(): {key: string, value: T}[] | undefined { | ||
const records = this.getAllStatement.all() | ||
getValue<T = any>(key: string): T | undefined { | ||
return this.getItem<T>(key)?.value || undefined | ||
} | ||
// Alias for getValue | ||
get = this.getValue | ||
getAllItems<T = any>(): Item<T>[] | undefined { | ||
const records = this.getAllItemsStatement.all() | ||
if (!records) return | ||
const now = getNow() | ||
const result: {key: string, value: T}[] = [] | ||
const result: Item<T>[] = [] | ||
for (const record of records) { | ||
@@ -97,7 +151,12 @@ const {key, value, expires} = record as {key: string, value: any, expires: number | undefined | null} | ||
getAllStartsWith<T = any>(keyStartsWith: string): {key: string, value: T}[] | undefined { | ||
const records = this.getAllStartsWithStatement.all({$keyStartsWith: keyStartsWith + "%"}) | ||
getAllValues<T = any>(): T[] | undefined { | ||
return this.getAllItems<T>()?.map((result) => result.value) || undefined | ||
} | ||
getItems<T = any>(startsWith: string): Item<T>[] | undefined { | ||
const records = this.getItemsStatement.all({$startsWith: startsWith + "%"}) | ||
if (!records) return | ||
const now = new Date().getTime() / 1000 | ||
const result: {key: string, value: T}[] = [] | ||
const now = getNow() | ||
const result: Item<T>[] = [] | ||
for (const record of records) { | ||
@@ -120,39 +179,7 @@ const {key, value, expires} = record as {key: string, value: any, expires: number | undefined | null} | ||
delete(key: string) { | ||
this.deleteStatement.run({$key: key}) | ||
getValues<T = any>(keyStartsWith: string): T[] | undefined { | ||
return this.getItems<T>(keyStartsWith)?.map((result) => result.value) | ||
} | ||
clear() { | ||
this.clearStatement.run() | ||
} | ||
close(throwOnError?: boolean) { | ||
this.db.close(throwOnError) | ||
} | ||
} | ||
// const countries = new BunSqliteKeyValue("countries.sqlite") | ||
// countries.set<string>("Österreich", "Tirol") | ||
// countries.get<string>("Österreich") | ||
// countries.deleteExpired() | ||
// countries.getAll<string>() | ||
// countries.getAllStartsWith("austria:") | ||
// countries.getAllStartsWith("children:gerold_penz") | ||
// countries.close() | ||
// | ||
// | ||
// const districts = new BunSqliteKeyValue("districts.sqlite") | ||
// districts.set<string>("Österreich", "Tirol") | ||
// districts.get<string>("Österreich") | ||
// districts.deleteExpired() | ||
// districts.getAll<string>() | ||
// districts.getAllStartsWith("austria:") | ||
// districts.getAllStartsWith("children:gerold_penz") | ||
// districts.close() | ||
// |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
14920
312
1