New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

bun-sqlite-key-value

Package Overview
Dependencies
Maintainers
0
Versions
73
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bun-sqlite-key-value - npm Package Compare versions

Comparing version 1.0.1 to 1.1.1

test/index.test.ts

5

package.json
{
"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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc