SQLite extension library

SQLite extension library

SQLite extension library

Function

examples/extensions/sqlite is BT official SQLite file database extension library example. It retains SQLite connections within workers via the shared WASM extension, supporting chained SQL construction, parameter binding, transactions, concurrent reads, busy timeout, result caps, and object deallocation.

This extension is not built into the standard library. Before use, you need to compile the extension into module.wasm, then package it into .bts and install it into the project extensions/ directory. The official extension library installation can be used directly:

Syntax

sqlite_open

opens the SQLite database file and returns the Sqlite connection object.

Syntax

Parameters

ParametersTypeRequiredDefault valueDescription
pathStringYesNoneSQLite database file path. bindings uses the path_write role, and the path must be within the project root directory.
optionsObjectYes{}Connection configuration object.

options Field

FieldTypeRequiredDefaultRangeDescription
walBoolNofalsetrue or falseWhether to enable SQLite WAL logging mode. true will execute PRAGMA journal_mode = WAL, and the read and write concurrency experience is usually better, but -wal and -shm auxiliary files will appear next to the database. The single-script temporary database does not need to be enabled; it is recommended to enable it for web services, desktop applications, and long-running projects.
busy_timeout_msIntNo10000..=300000When the database is locked by other connections, the maximum number of milliseconds to wait before reporting an error. 1000 means waiting at most 1 second; 0 means no waiting. It only handles SQLite file lock waits, not SQL query execution timeouts.
max_rowsIntNo10001..=100000all() The maximum number of rows allowed to be returned at a time. If exceeded, an error will be reported to prevent a large amount of data from being read into the BT VM at one time. When you only want to fetch one page of data, it is recommended to add LIMIT to SQL yourself.
max_result_bytesIntNo41943041..=16777216The estimated upper bound in bytes for the results returned by one() and all(). Default is about 4MB, maximum is 16MB. It is used to protect resident process memory and avoid returning too many large texts or large BLOBs at one time.

Newbies can first pass {} and use the default value; when you know that the result set may be large, there will be concurrent reading and writing, or you want to limit memory usage, you can configure these fields as needed.

Return Value

TypeDescription
SqliteSQLite connection object, type(db) returns Sqlite.

Sqlite.query

Create a chained query object. query() only saves SQL and does not perform database operations.

Syntax

Parameters

ParameterTypeRequiredDefault valueDescription
sqlStringYesNoneSQL to be executed, use ? as parameter placeholder.

Return Value

TypeDescription
SqliteQueryChain query object, type(query) returns SqliteQuery.

SqliteQuery.bind

Append a common binding parameter. The binding value will correspond to the ? placeholder in SQL in the calling order.

Syntax

Parameters

ParametersTypeRequiredDefault valueDescription
valueAnyYesNoneBinding value. Supports null, Bool, Int, Float, String, Bytes; empty is not allowed.

Return Value

TypeDescription
SqliteQueryReturn the same query object to facilitate continued chain calls.

SqliteQuery.binds

Add multiple lines of batch binding parameters, only used for exec().

Syntax

Parameters

ParametersTypeRequiredDefault valueDescription
rowsArrayYesNoneTwo-dimensional array. Each row is a set of bound values; if the row element is not an array, it will be treated as a single-value row.

Return Value

TypeDescription
SqliteQueryReturn the same query object.

SqliteQuery.batch

Set batch size statistics for batch exec(). It is mainly used to be consistent with the batch writing method of the MySQL standard library.

SQLite currently executes these bind rows serially in the same transaction; batch(size) will affect batch_count and batch_size in the returned object, making it easier to migrate code and observe batch size.

Syntax

Parameters

ParametersTypeRequiredDefaultDescription
sizeIntYes0 when not calledBatch size. Less than 0 is processed as 0; 0 means using all bound rows as a batch.

Return Value

TypeDescription
SqliteQueryReturn the same query object.

SqliteQuery.workers

Set migration-compatible job count statistics. This method is to allow the code migrated from the MySQL standard library to retain similar writing methods.

SQLite cannot write concurrently to the same connection like the MySQL connection pool; the current implementation will still execute serially within a transaction. In other words, workers(4) will not allow the same SQLite connection to write 4 SQL statements concurrently.

Syntax

Parameters

ParametersTypeRequiredDefaultRangeDescription
countIntYes1 when not called1..=4096Number of migration compatible jobs. If it is smaller than 1, it will be processed as 1, and if it is larger than 4096, it will be processed as 4096.

Return Value

TypeDescription
SqliteQueryReturn the same query object.

SqliteQuery.one

Execute the query and return the first row.

Syntax

Parameters

has no parameters.

Return Value

TypeDescription
Object/emptyReturn the object when the row is queried; return empty if there is no result. SQLite NULL returns BT null, BLOB returns BT Bytes.

SqliteQuery.all

Execute a query and return multiple rows.

Syntax

Parameters

has no parameters.

Return Value

TypeDescription
ArrayReturns an array of row objects, subject to max_rows and max_result_bytes limits.

SqliteQuery.exec

Execute SQL that does not require returning a result set. Ordinary bind() is executed once; binds() will be executed serially according to the bound rows in the SQLite transaction.

Syntax

Parameters

has no parameters.

Return Value

TypeDescription
ObjectReturns the SQL execution statistics object.

Execution result field

FieldTypeMust existDescription
totalIntYesThe number of bound rows processed by this execution. When ordinary bind() is executed, it is 1; when binds() is executed in batches, it is the number of bound array rows; when binds() is executed in batches, it is 0.
rows_affectedIntYesThe number of affected rows reported by SQLite. When executed in batches, the values are accumulated row by row.
last_insert_idIntYesSQLite last_insert_rowid() for the current connection.
batch_countIntYesNumber of batches calculated as batch(). The current execution of SQLite is still completed within a transaction.
batch_sizeIntYesThe batch size configured for the current query object; 0 when batch() is not called.
workersIntYesThe number of jobs after the current query object is configured and normalized. SQLite currently does not write concurrently to the same connection.

SqliteQuery.sql

Returns the debugging text of the current SQL.

Syntax

Parameters

has no parameters.

Return Value

TypeDescription
StringReturns the SQL preview text after rendering the binding value to the ? placeholder. This text is only used for debugging and does not participate in execution.

Sqlite.transaction

Execute multiple write statements serially in the same SQLite transaction.

Syntax

Parameters

ParametersTypeRequiredDefault valueDescription
statementsArrayYesNoneArray of transaction statements. The element can be a SQL string or a { sql, binds } object.

statements Object field

FieldTypeRequiredDefault valueDescription
sqlStringYesNoneSQL to be executed.
bindsArrayNo[]SQL parameter array. Supports null, Bool, Int, Float, String, Bytes; empty is not allowed.
paramsArrayNo[]Old field alias, it is recommended that new code use binds.

Return Value

TypeDescription
IntThe cumulative number of affected rows in the transaction.

close

Release the query object or database connection object.

Syntax

Parameters

has no parameters.

Return Value

TypeDescription
BoolSuccessful release returns true; the old handle becomes invalid after release.

Code Examples

Building bundled SQLite for

rusqlite requires a C compiler under the WASI target. Windows environment needs to install LLVM clang or WASI SDK first, and make sure clang is in PATH.

Notes

- The main usage of the SQLite extension is consistent with the MySQL standard library: first query(sql), then bind() or binds(), and finally call one(), all() or exec().

  • The number of extension method parameters is strictly verified by bindings.json; bind() only binds one value at a time and is called multiple times continuously when multiple parameters are required.
  • binds() only supports exec(), not one() and all().
  • workers() is the MySQL migration compatible interface; SQLite currently does not write to the same connection concurrently.
  • all() must set reasonable max_rows and max_result_bytes to prevent large results from entering the BT VM uncontrollably.
  • close() / SqliteQuery.close() should be called explicitly; bindings are marked lifecycle: "dispose" and the old handle will be invalidated after the call is successful.
  • busy_timeout_ms only handles SQLite lock waits, not SQL logical timeouts; the call_timeout_ms of shared workers is still responsible for the host ExtensionService.