npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@isdk/kvsqlite

v0.1.23

Published

SQlite(>=3.45.0) key/value store

Downloads

1,120

Readme

kvsqlite

SQlite(>=3.45.0) key/value store

KVSqlite Class

The KVSqlite class serves as an extension of the Database class from the better-sqlite3 library, tailored specifically for managing key-value pairs within a SQLite database. It introduces a structured way to interact with and manipulate these pairs, providing methods for creation, retrieval, update, and deletion operations. The class integrates several features and design choices that enhance its functionality and flexibility:

Interface and Type Definitions

  • IKVObjItem: Defines the structure of a single key-value pair object, which must have an _id property of type string and can contain additional properties of any type.
  • IKVSetOptions: Extends Database.Options from the better-sqlite3 library to include custom options specific to the KVSqlite class, such as id, location, collection, collections, and overwrite. These options allow for more granular control over database connection details, collection management, and data manipulation behavior.
  • IKVCollections: Represents a dictionary-like mapping where keys are collection names (strings) and values are instances of the KVSqliteCollection class.

Constructor

  • Accepts two parameters: filename (optional, either a string or Buffer) representing the path to the SQLite database file, and options (also optional) conforming to the IKVSetOptions interface.
  • Initializes a base super instance using the Database constructor with the given filename and options.
  • Sets the store id property based on the id option provided, if present.
  • If the database is not opened in read-only mode (!this.readonly), it creates one or more collections according to the collections and collection options, ensuring that the default collection named 'kv' always exists.

Collections Management

  • Maintains an internal collections property of type IKVCollections, which holds references to instantiated KVSqliteCollection objects corresponding to different named collections.
  • Offers a create method to instantiate a new KVSqliteCollection instance for a given name and store it in the collections map if it does not already exist.

Key-Value Pair Operations

  • Provides a set of CRUD (Create, Read, Update, Delete) methods acting on key-value pairs within specified collections:
    • set(obj: IKVObjItem, options?: IKVSetOptions): Inserts or updates a key-value pair (obj) in the collection specified by options.collection or the default collection 'kv'. Delegates the operation to the corresponding KVSqliteCollection.set() method.
    • get(_id: string, options?: IKVSetOptions): Retrieves a key-value pair identified by _id from the specified collection or the default collection. Returns the retrieved item wrapped in an IKVObjItem interface.
    • del(_id?: string, options?: IKVSetOptions): Deletes a key-value pair with the given _id from the specified collection or all items in the default collection if no _id is provided. Delegates the operation to the corresponding KVSqliteCollection.del() method.
    • isExists(_id: string, options?: IKVSetOptions): Checks whether a key-value pair with the given _id exists in the specified collection or the default collection. Returns a boolean indicating presence or absence.
    • count(query?: string, options?: IKVSetOptions): Counts the number of key-value pairs in the specified collection or the default collection, optionally applying a filter based on a LIKE query. Delegates the operation to the corresponding KVSqliteCollection.count() method.

In summary, the KVSqlite class provides a comprehensive and customizable interface for managing key-value pairs stored in a SQLite database. It leverages the underlying better-sqlite3 library while introducing specialized functionality through its own collection-oriented API, making it suitable for applications requiring a lightweight, persistent key-value storage solution with advanced querying capabilities.

KVSqliteCollection Class

The KVSqliteCollection class represents a container for managing a particular collection of key-value pairs within the KVSqlite database system. This class encapsulates the logic necessary for performing various operations on the collection, including adding, updating, retrieving, deleting, checking existence, and counting items. Key aspects of the KVSqliteCollection class are detailed below:

Internal State and Initialization

The KVSqliteCollection class maintains the following internal states:

  1. Name: A string variable received and stored via the constructor, representing the unique name of the collection. This serves as a crucial identifier distinguishing the current KVSqliteCollection instance from others.
  2. Database Reference: An instance reference to the KVSqlite class passed as a parameter to and stored in the constructor. This reference enables the KVSqliteCollection to interact directly with the underlying database context.
  3. Prepared Statements: Initializes a set of precompiled SQL statements encapsulating fundamental operations on the key-value pair collection, such as adding, updating, checking existence, fetching, deleting individual items, deleting all items, and counting items. Each precompiled statement is stored as a class property for efficient execution later. Specifically:
    • preAdd: Inserts a new key-value pair.
    • preUpdate: Updates an existing key-value pair.
    • preExists: Checks if a key-value pair with a specified _id exists.
    • preGet: Retrieves the value of a key-value pair based on its _id.
    • preDel: Deletes a key-value pair with a specified _id.
    • preDelAll: Deletes all key-value pairs in the collection.
    • preCount: Calculates the total number of key-value pairs in the collection.
    • preCountW: Counts key-value pairs matching a LIKE query condition.

During the KVSqliteCollection class construction, the following initialization steps occur:

  1. Table Creation: If the associated KVSqlite instance is not in read-only mode, the constructor calls the createTableSql function to generate a SQL statement for creating the table and executes it using db.prepare().run(). This ensures that a table with the same name as the current collection is created in the database and has the expected structure for storing key-value pair data.
  2. Prepared Statements Initialization: The constructor proceeds to initialize all precompiled SQL statements. Each statement is dynamically constructed based on the collection name, ensuring it operates on the correct table. These statements are created using db.prepare() and assigned to their corresponding class properties. As a result, when executing operations like inserts, updates, or queries, precompiled statements can be invoked directly, enhancing efficiency and mitigating potential SQL injection risks.

The KVSqliteCollection class holds an exclusive collection name, a reference to the associated database, and a set of precompiled SQL statements in its internal state. During construction, it first ensures that a database table corresponding to the collection name is created, followed by initializing all precompiled statements to efficiently handle subsequent key-value pair operations. This design enables the KVSqliteCollection to function as an independent and efficient unit managing a specific key-value pair collection within the KVSqlite database.

Prepared Statements

To optimize performance and reduce repetitive parsing overhead, the KVSqliteCollection class declares and initializes a series of SQLite prepared statements at construction time. These statements correspond to common database operations relevant to managing key-value pairs, such as inserting, updating, checking existence, fetching, deleting individual items, deleting all items, and counting items. Each statement is bound to a specific property (e.g., preAdd, preUpdate, preExists, etc.) and is constructed using the provided name and appropriate SQL syntax. Prepared statements enable efficient execution of these operations throughout the lifetime of the KVSqliteCollection instance.

Key-Value Pair Operations On a Collection

  • Setting Items: The _set method is responsible for handling the insertion or update of a key-value pair. It accepts an IKVObjItem (obj) and optional IKVSetOptions (options). Internally, it extracts the _id from the input object, removes it temporarily, and then checks if a record with the same _id already exists in the collection. If it does, the method determines whether to overwrite the existing record entirely (options.overwrite === true) or merge the new properties into the existing record (options.overwrite !== false). In both cases, the updated record is serialized as JSON and passed to the appropriate prepared statement (preUpdate or preAdd) for execution against the database.
  • Getting Items: The get method retrieves a single key-value pair by its _id. It uses the preGet prepared statement to execute a SELECT query, deserializes the returned JSON value, adds the _id back to the result, and returns the reconstructed IKVObjItem.
  • Deleting Items: The del method supports deleting a specific key-value pair by its _id or removing all items from the collection when no _id is provided. It invokes the corresponding prepared statements (preDel or preDelAll) accordingly.
  • Checking Existence: The isExists method queries the database using the preExists prepared statement to determine if a key-value pair with the given _id exists in the collection. It returns a boolean result.
  • Counting Items: The count method allows for counting the number of items in the collection, optionally filtering by a LIKE query when provided. It utilizes the preCount or preCountW prepared statements based on the presence of a query parameter.

Transaction Support

Although not directly mentioned, the set method wraps the call to _set within a transaction provided by the parent KVSqlite instance. This ensures atomicity for the insert/update operation, guarding against partial updates or inconsistent state in case of failures during the transaction.

In summary, the KVSqliteCollection class serves as a dedicated manager for a specific collection of key-value pairs within the KVSqlite database system. It handles the low-level database interactions via prepared statements, provides a clean API for CRUD operations on key-value pairs, and ensures data consistency through transactional support. By maintaining a mapping of KVSqliteCollection instances within the KVSqlite class, multiple collections can be efficiently managed and accessed within the same SQLite database.

Index Support

  • createIndex(indexName: string, fields: string|string[]): The createIndex method allows creating an index for the val object. It uses SQLite's CREATE INDEX statement to create the index and records the index name for future query use.
    • Example: collection.createIndex('name', 'name')
    • Use EXPLAIN QUERY PLAN SELECT * FROM ... to check if the index is used.
  • search(query: string, options?: {size?: number, page?:number = 0}): The search method allows searching the contents of the val object.
    • query: The content to search for, e.g., val->>'$.name' = 'something'
  • Added createdAt/updatedAt fields to the val object (with indexed).