Skip to content

Cap-go/capacitor-fast-sql

Repository files navigation

@capgo/capacitor-fast-sql

Capgo - Instant updates for capacitor

High-performance native SQLite plugin with HTTP server for efficient sync operations and IndexedDB replacement.

Why Fast SQL?

Traditional Capacitor plugins serialize data through the JavaScript bridge, which becomes inefficient with large datasets. Fast SQL solves this by establishing a local HTTP server for direct native communication, making it ideal for:

  • Local-first sync systems (CRDTs, operational transforms)
  • IndexedDB replacement on platforms with broken/limited implementations
  • Large dataset operations requiring high throughput
  • Batch operations with thousands of rows
  • Binary data storage (BLOBs, files)

Documentation

The most complete doc is available here: https://capgo.app/docs/plugins/fast-sql/

Install

npm install @capgo/capacitor-fast-sql
npx cap sync

Overview

This plugin provides direct native SQLite database access with a custom communication protocol inspired by capacitor-blob-writer. Instead of using Capacitor's standard bridge (which serializes data inefficiently), it establishes a local HTTP server for optimal performance with large datasets and sync operations.

Key Features

  • Custom HTTP Protocol: Bypasses Capacitor's bridge for up to 25x faster performance with large data
  • Direct Native SQLite: Full SQL support with transactions, batch operations, and binary data
  • Sync-Friendly: Designed for local sync systems (CRDTs, operational transforms, etc.)
  • IndexedDB Replacement: Provides reliable alternative to broken/limited IndexedDB implementations
  • Cross-Platform: iOS, Android, and Web (using sql.js + IndexedDB for persistence)

iOS Configuration

Add to your Info.plist if you encounter any issues:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

Android Configuration

Add to your AndroidManifest.xml if needed:

<application
    android:usesCleartextTraffic="true">
    ...
</application>

Usage

Basic Example

import { FastSQL } from '@capgo/capacitor-fast-sql';

// Connect to database
const db = await FastSQL.connect({ database: 'myapp' });

// Create table
await db.execute(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE
  )
`);

// Insert data
const result = await db.run(
  'INSERT INTO users (name, email) VALUES (?, ?)',
  ['John Doe', 'john@example.com']
);
console.log('Inserted row ID:', result.insertId);

// Query data
const users = await db.query('SELECT * FROM users WHERE name LIKE ?', ['John%']);
console.log('Users:', users);

// Close connection
await FastSQL.disconnect('myapp');

Transaction Example

const db = await FastSQL.connect({ database: 'myapp' });

try {
  await db.transaction(async (tx) => {
    await tx.run('INSERT INTO accounts (name, balance) VALUES (?, ?)', ['Alice', 1000]);
    await tx.run('INSERT INTO accounts (name, balance) VALUES (?, ?)', ['Bob', 500]);
    await tx.run('UPDATE accounts SET balance = balance - 100 WHERE name = ?', ['Alice']);
    await tx.run('UPDATE accounts SET balance = balance + 100 WHERE name = ?', ['Bob']);
  });
  console.log('Transaction successful!');
} catch (error) {
  console.error('Transaction failed:', error);
}

Batch Operations

const db = await FastSQL.connect({ database: 'myapp' });

const results = await db.executeBatch([
  { statement: 'INSERT INTO logs (message) VALUES (?)', params: ['Log 1'] },
  { statement: 'INSERT INTO logs (message) VALUES (?)', params: ['Log 2'] },
  { statement: 'INSERT INTO logs (message) VALUES (?)', params: ['Log 3'] },
]);

API

Fast SQL Plugin for high-performance SQLite database access.

This plugin uses a custom HTTP-based protocol for efficient data transfer, bypassing Capacitor's standard bridge for better performance with sync operations.

connect(...)

connect(options: SQLConnectionOptions) => Promise<{ port: number; token: string; database: string; }>

Initialize the database connection and start the HTTP server.

Param Type Description
options SQLConnectionOptions - Connection options

Returns: Promise<{ port: number; token: string; database: string; }>

Since: 0.0.1


disconnect(...)

disconnect(options: { database: string; }) => Promise<void>

Close database connection and stop the HTTP server.

Param Type Description
options { database: string; } - Database name to close

Since: 0.0.1


getServerInfo(...)

getServerInfo(options: { database: string; }) => Promise<{ port: number; token: string; }>

Get the HTTP server port and token for direct communication.

Param Type Description
options { database: string; } - Database name

Returns: Promise<{ port: number; token: string; }>

Since: 0.0.1


execute(...)

execute(options: { database: string; statement: string; params?: SQLValue[]; }) => Promise<SQLResult>

Execute a SQL query via Capacitor bridge (for simple queries). For better performance with large datasets, use the HTTP protocol directly via SQLConnection class.

Param Type Description
options { database: string; statement: string; params?: SQLValue[]; } - Query parameters

Returns: Promise<SQLResult>

Since: 0.0.1


beginTransaction(...)

beginTransaction(options: { database: string; isolationLevel?: IsolationLevel; }) => Promise<void>

Begin a database transaction.

Param Type Description
options { database: string; isolationLevel?: IsolationLevel; } - Transaction options

Since: 0.0.1


commitTransaction(...)

commitTransaction(options: { database: string; }) => Promise<void>

Commit the current transaction.

Param Type Description
options { database: string; } - Database name

Since: 0.0.1


rollbackTransaction(...)

rollbackTransaction(options: { database: string; }) => Promise<void>

Rollback the current transaction.

Param Type Description
options { database: string; } - Database name

Since: 0.0.1


getPluginVersion()

getPluginVersion() => Promise<{ version: string; }>

Get the native Capacitor plugin version.

Returns: Promise<{ version: string; }>

Since: 0.0.1


Interfaces

SQLConnectionOptions

Database connection options

Prop Type Description
database string Database name (file will be created in app data directory)
encrypted boolean Enable encryption (iOS/Android only)
encryptionKey string Encryption key (required if encrypted is true)
readOnly boolean Read-only mode

SQLResult

Result of a SQL query execution

Prop Type Description
rows SQLRow[] Rows returned by the query (for SELECT statements)
rowsAffected number Number of rows affected by the query (for INSERT/UPDATE/DELETE)
insertId number ID of the last inserted row (for INSERT statements with auto-increment)

SQLRow

SQL row result - values indexed by column name

Uint8Array

A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.

Prop Type Description
BYTES_PER_ELEMENT number The size in bytes of each element in the array.
buffer ArrayBufferLike The ArrayBuffer instance referenced by the array.
byteLength number The length in bytes of the array.
byteOffset number The offset in bytes of the array.
length number The length of the array.
Method Signature Description
copyWithin (target: number, start: number, end?: number | undefined) => this Returns the this object after copying a section of the array identified by start and end to the same array starting at position target
every (predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any) => boolean Determines whether all the members of an array satisfy the specified test.
fill (value: number, start?: number | undefined, end?: number | undefined) => this Returns the this object after filling the section identified by start and end with value
filter (predicate: (value: number, index: number, array: Uint8Array) => any, thisArg?: any) => Uint8Array Returns the elements of an array that meet the condition specified in a callback function.
find (predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any) => number | undefined Returns the value of the first element in the array where predicate is true, and undefined otherwise.
findIndex (predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any) => number Returns the index of the first element in the array where predicate is true, and -1 otherwise.
forEach (callbackfn: (value: number, index: number, array: Uint8Array) => void, thisArg?: any) => void Performs the specified action for each element in an array.
indexOf (searchElement: number, fromIndex?: number | undefined) => number Returns the index of the first occurrence of a value in an array.
join (separator?: string | undefined) => string Adds all the elements of an array separated by the specified separator string.
lastIndexOf (searchElement: number, fromIndex?: number | undefined) => number Returns the index of the last occurrence of a value in an array.
map (callbackfn: (value: number, index: number, array: Uint8Array) => number, thisArg?: any) => Uint8Array Calls a defined callback function on each element of an array, and returns an array that contains the results.
reduce (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number) => number Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
reduce (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number) => number
reduce <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U) => U Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
reduceRight (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number) => number Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
reduceRight (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number) => number
reduceRight <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U) => U Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
reverse () => Uint8Array Reverses the elements in an Array.
set (array: ArrayLike<number>, offset?: number | undefined) => void Sets a value or an array of values.
slice (start?: number | undefined, end?: number | undefined) => Uint8Array Returns a section of an array.
some (predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any) => boolean Determines whether the specified callback function returns true for any element of an array.
sort (compareFn?: ((a: number, b: number) => number) | undefined) => this Sorts an array.
subarray (begin?: number | undefined, end?: number | undefined) => Uint8Array Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements at begin, inclusive, up to end, exclusive.
toLocaleString () => string Converts a number to a string by using the current locale.
toString () => string Returns a string representation of an array.
valueOf () => Uint8Array Returns the primitive value of the specified object.

ArrayLike

Prop Type
length number

ArrayBufferTypes

Allowed ArrayBuffer types for the buffer of an ArrayBufferView and related Typed Arrays.

Prop Type
ArrayBuffer ArrayBuffer

ArrayBuffer

Represents a raw buffer of binary data, which is used to store data for the different typed arrays. ArrayBuffers cannot be read from or written to directly, but can be passed to a typed array or DataView Object to interpret the raw buffer as needed.

Prop Type Description
byteLength number Read-only. The length of the ArrayBuffer (in bytes).
Method Signature Description
slice (begin: number, end?: number | undefined) => ArrayBuffer Returns a section of an ArrayBuffer.

Type Aliases

SQLValue

SQL value types supported by the plugin

string | number | boolean | null | Uint8Array

ArrayBufferLike

ArrayBufferTypes[keyof ArrayBufferTypes]

Enums

IsolationLevel

Members Value
ReadUncommitted 'READ UNCOMMITTED'
ReadCommitted 'READ COMMITTED'
RepeatableRead 'REPEATABLE READ'
Serializable 'SERIALIZABLE'

About

Capacitor plugin to connect to local SQL with fast protocole

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors 2

  •  
  •