sqlite-level
Advanced tools
Comparing version
@@ -1,1 +0,97 @@ | ||
export * from "../src/index" | ||
/** | ||
Copyright 2023 Forestry.io Holdings, Inc. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
import { AbstractDatabaseOptions, AbstractIterator, AbstractKeyIterator, AbstractLevel, AbstractOpenOptions, AbstractValueIterator } from 'abstract-level'; | ||
import { NextCallback } from 'abstract-level/types/abstract-iterator'; | ||
import Database from 'better-sqlite3'; | ||
export type SqliteLevelOptions<K, V> = { | ||
filename: string; | ||
readOnly?: boolean; | ||
} & AbstractDatabaseOptions<K, V>; | ||
declare type BatchOperation = BatchPutOperation | BatchDelOperation; | ||
/** | ||
* A _put_ operation to be committed by a {@link SqliteLevel}. | ||
*/ | ||
declare interface BatchPutOperation { | ||
/** | ||
* Type of operation. | ||
*/ | ||
type: 'put'; | ||
/** | ||
* Key of the entry to be added to the database. | ||
*/ | ||
key: Buffer; | ||
/** | ||
* Value of the entry to be added to the database. | ||
*/ | ||
value: Buffer; | ||
} | ||
/** | ||
* A _del_ operation to be committed by a {@link SqliteLevel}. | ||
*/ | ||
declare interface BatchDelOperation { | ||
/** | ||
* Type of operation. | ||
*/ | ||
type: 'del'; | ||
/** | ||
* Key of the entry to be deleted from the database. | ||
*/ | ||
key: Buffer; | ||
} | ||
declare interface IteratorOptions<KDefault> { | ||
limit?: number; | ||
keyEncoding: string; | ||
valueEncoding: string; | ||
reverse: boolean; | ||
keys: boolean; | ||
values: boolean; | ||
gt?: KDefault; | ||
gte?: KDefault; | ||
lt?: KDefault; | ||
lte?: KDefault; | ||
} | ||
declare class SqliteIterator<KDefault, VDefault> extends AbstractIterator<SqliteLevel<KDefault, VDefault>, KDefault, VDefault> { | ||
private client; | ||
private iterator; | ||
constructor(db: SqliteLevel<KDefault, VDefault>, options: IteratorOptions<KDefault>, client: any); | ||
_next(callback: NextCallback<KDefault, VDefault>): Promise<void>; | ||
} | ||
declare class SqliteKeyIterator<KDefault, VDefault> extends AbstractKeyIterator<SqliteLevel<KDefault, VDefault>, KDefault> { | ||
private client; | ||
private iterator; | ||
constructor(db: SqliteLevel<KDefault, VDefault>, options: IteratorOptions<KDefault>, client: any); | ||
_next(callback: NextCallback<KDefault, VDefault>): Promise<void>; | ||
} | ||
declare class SqliteValueIterator<KDefault, VDefault> extends AbstractValueIterator<SqliteLevel<KDefault, VDefault>, KDefault, VDefault> { | ||
private client; | ||
private iterator; | ||
constructor(db: SqliteLevel<KDefault, VDefault>, options: IteratorOptions<KDefault>, client: any); | ||
_next(callback: NextCallback<KDefault, VDefault>): Promise<void>; | ||
} | ||
export declare class SqliteLevel<KDefault = string, VDefault = string> extends AbstractLevel<Buffer | Uint8Array | string, KDefault, VDefault> { | ||
db: Database.Database; | ||
private readOnly; | ||
constructor(options: SqliteLevelOptions<KDefault, VDefault>); | ||
get type(): string; | ||
_open(options: AbstractOpenOptions, callback: (error?: Error) => void): Promise<void>; | ||
_close(callback: (error?: Error) => void): Promise<void>; | ||
_get(key: Buffer, options: any, callback: (error?: Error, value?: Buffer) => void): Promise<void>; | ||
_put(key: Buffer, value: Buffer, options: any, callback: (error?: Error) => void): Promise<void>; | ||
_del(key: Buffer, options: any, callback: (error?: Error) => void): Promise<void>; | ||
_batch(batch: BatchOperation[], options: any, callback: (error?: Error) => void): Promise<void>; | ||
_clear(options: any, callback: (error?: Error) => void): Promise<void>; | ||
_iterator(options: IteratorOptions<KDefault>): SqliteIterator<KDefault, VDefault>; | ||
_keys(options: IteratorOptions<KDefault>): SqliteKeyIterator<KDefault, VDefault>; | ||
_values(options: IteratorOptions<KDefault>): SqliteValueIterator<KDefault, VDefault>; | ||
} | ||
export {}; |
@@ -9,6 +9,6 @@ (function(global, factory) { | ||
if (options.gt) { | ||
query += " WHERE key > ?"; | ||
query += ` WHERE key > ?`; | ||
params.push(options.gt); | ||
} else if (options.gte) { | ||
query += " WHERE key >= ?"; | ||
query += ` WHERE key >= ?`; | ||
params.push(options.gte); | ||
@@ -41,8 +41,9 @@ } | ||
} | ||
async _next() { | ||
async _next(callback) { | ||
const result = this.iterator.next(); | ||
if (!result.done) { | ||
return [result.value.key, result.value.value]; | ||
return this.db.nextTick(callback, null, result.value.key, result.value.value); | ||
} else { | ||
return this.db.nextTick(callback, null, void 0, void 0); | ||
} | ||
return void 0; | ||
} | ||
@@ -58,8 +59,9 @@ } | ||
} | ||
async _next() { | ||
async _next(callback) { | ||
const result = this.iterator.next(); | ||
if (!result.done) { | ||
return result.value.key; | ||
return this.db.nextTick(callback, null, result.value.key); | ||
} else { | ||
return this.db.nextTick(callback, null, void 0); | ||
} | ||
return void 0; | ||
} | ||
@@ -75,8 +77,9 @@ } | ||
} | ||
async _next() { | ||
async _next(callback) { | ||
const result = this.iterator.next(); | ||
if (!result.done) { | ||
return result.value.value; | ||
return this.db.nextTick(callback, null, result.value.value); | ||
} else { | ||
return this.db.nextTick(callback, null, void 0); | ||
} | ||
return void 0; | ||
} | ||
@@ -98,61 +101,102 @@ } | ||
} | ||
async _open(options) { | ||
async _open(options, callback) { | ||
this.db.exec("CREATE TABLE IF NOT EXISTS kv (key TEXT, value TEXT)"); | ||
this.nextTick(callback); | ||
} | ||
async _close() { | ||
async _close(callback) { | ||
this.db.close(); | ||
this.nextTick(callback); | ||
} | ||
async _get(key, options) { | ||
async _get(key, options, callback) { | ||
const stmt = this.db.prepare("SELECT value FROM kv WHERE key = ?"); | ||
const row = stmt.get(key.toString()); | ||
if (row) { | ||
return row.value; | ||
return this.nextTick(callback, null, row.value); | ||
} else { | ||
return this.nextTick( | ||
callback, | ||
new ModuleError(`Key ${key} was not found`, { | ||
code: "LEVEL_NOT_FOUND" | ||
}) | ||
); | ||
} | ||
throw new ModuleError(`Key ${key} was not found`, { | ||
code: "LEVEL_NOT_FOUND" | ||
}); | ||
} | ||
async _put(key, value, options) { | ||
async _put(key, value, options, callback) { | ||
if (this.readOnly) { | ||
throw new ModuleError("not authorized to write to branch", { | ||
code: "LEVEL_READ_ONLY" | ||
}); | ||
return this.nextTick( | ||
callback, | ||
new ModuleError("not authorized to write to branch", { | ||
code: "LEVEL_READ_ONLY" | ||
}) | ||
); | ||
} | ||
const stmt = this.db.prepare("INSERT INTO kv (key, value) VALUES (?, ?)"); | ||
stmt.run(key.toString(), value.toString()); | ||
this.nextTick(callback); | ||
} | ||
async _del(key, options) { | ||
async _del(key, options, callback) { | ||
if (this.readOnly) { | ||
throw new ModuleError("not authorized to write to branch", { | ||
code: "LEVEL_READ_ONLY" | ||
}); | ||
return this.nextTick( | ||
callback, | ||
new ModuleError("not authorized to write to branch", { | ||
code: "LEVEL_READ_ONLY" | ||
}) | ||
); | ||
} | ||
const stmt = this.db.prepare("DELETE FROM kv WHERE key = ?"); | ||
stmt.run(key.toString()); | ||
this.nextTick(callback); | ||
} | ||
async _batch(batch, options) { | ||
async _batch(batch, options, callback) { | ||
if (this.readOnly) { | ||
throw new ModuleError("not authorized to write to branch", { | ||
code: "LEVEL_READ_ONLY" | ||
}); | ||
return this.nextTick( | ||
callback, | ||
new ModuleError("not authorized to write to branch", { | ||
code: "LEVEL_READ_ONLY" | ||
}) | ||
); | ||
} | ||
const putStmt = this.db.prepare( | ||
"INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)" | ||
); | ||
const delStmt = this.db.prepare("DELETE FROM kv WHERE key = ?"); | ||
this.db.transaction(() => { | ||
for (const op of batch) { | ||
if (op.type === "put") { | ||
putStmt.run(op.key.toString(), op.value.toString()); | ||
} else if (op.type === "del") { | ||
delStmt.run(op.key.toString()); | ||
let batches = []; | ||
let curBatch = []; | ||
let curType = void 0; | ||
for (const op of batch) { | ||
if (curType === void 0) { | ||
curType = op.type; | ||
} else if (curType !== op.type) { | ||
if (curType === "put") { | ||
batches.push(`INSERT INTO kv (key, value) VALUES ${curBatch.join(",")}`); | ||
} else if (curType === "del") { | ||
batches.push(`DELETE FROM kv WHERE key IN (${curBatch.join(",")})`); | ||
} | ||
curBatch = []; | ||
curType = op.type; | ||
} | ||
})(); | ||
if (op.type === "put") { | ||
curBatch.push(`('${op.key.toString()}', '${op.value.toString()}')`); | ||
} else if (op.type === "del") { | ||
curBatch.push(`'${op.key.toString()}'`); | ||
} | ||
} | ||
if (curBatch.length > 0) { | ||
if (curType === "put") { | ||
batches.push(`INSERT INTO kv (key, value) VALUES ${curBatch.join(",")}`); | ||
} else if (curType === "del") { | ||
batches.push(`DELETE FROM kv WHERE key IN (${curBatch.join(",")})`); | ||
} | ||
} | ||
for (const batch2 of batches) { | ||
this.db.exec(batch2); | ||
} | ||
this.nextTick(callback); | ||
} | ||
async _clear(options) { | ||
async _clear(options, callback) { | ||
this.db.exec(`DELETE FROM kv WHERE key like '${options.gte}%'`); | ||
this.nextTick(callback); | ||
} | ||
_iterator(options) { | ||
return new SqliteIterator(this, options, this.db); | ||
return new SqliteIterator( | ||
this, | ||
options, | ||
this.db | ||
); | ||
} | ||
@@ -159,0 +203,0 @@ _keys(options) { |
{ | ||
"name": "sqlite-level", | ||
"description": "sqlite backed abstract-level database for Node.js", | ||
"version": "0.0.0-20240919015120", | ||
"version": "0.0.0-20240919041143", | ||
"main": "dist/index.js", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"license": "Apache-2.0", | ||
"exports": { | ||
".": { | ||
"require": "./dist/index.js", | ||
"import": "./dist/index.mjs" | ||
} | ||
}, | ||
"keywords": [ | ||
@@ -44,17 +37,14 @@ "level", | ||
"docs": "npx typedoc", | ||
"version": "pnpm exec changeset version", | ||
"version:snapshot": "pnpm exec changeset version --snapshot", | ||
"publish": "npm publish -r --no-git-checks --access public", | ||
"publish:beta": "npm publish -r --tag beta --no-git-checks --access public" | ||
"version": "pnpm exec changeset version" | ||
}, | ||
"dependencies": { | ||
"abstract-level": "^2.0.0", | ||
"better-sqlite3": "^11.3.0", | ||
"module-error": "^1.0.2" | ||
"module-error": "^1.0.2", | ||
"abstract-level": "^1.0.0", | ||
"better-sqlite3": "^11.3.0" | ||
}, | ||
"devDependencies": { | ||
"@changesets/cli": "2.27.8", | ||
"@tinacms/scripts": "^1.2.1", | ||
"@types/better-sqlite3": "^7.6.11", | ||
"@types/jest": "^ 29.5.13", | ||
"@changesets/cli": "2.27.8", | ||
"jest": "^29.7.0", | ||
@@ -61,0 +51,0 @@ "jest-environment-node": "^29.7.0", |
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
23112
29.46%305
85.98%1
Infinity%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
Updated