The database bridge is a database client on the device. It opens SQLite files in the app’s
file roots where they are, so asking a 4 GB file for twenty rows costs twenty rows, not the
file. A page gets the schema, runs scripts with cancel and query plans, pages through a sorted, filtered and editable
datasheet, designs tables, moves CSV in and out, and keeps a query history. SQLite is the only engine that ships; any
other engine plugs in as a driver the app writes (see Other engines ).
dotnet add package Shiny.AppDeviceBridge.Database
builder. UseAppDeviceBridge (
bridge => bridge. AddDatabaseBridge ( o => o.StatementTimeout = TimeSpan. FromSeconds ( 10 )),
Client
C#
TypeScript
IDatabaseBridge
AddDatabaseBridgeClient()
DatabaseBridge
DatabaseBridgeOptions
Default
StatementTimeout
30 seconds
How long one SQLite statement may run before it is interrupted.
MaxHistory
500
How many queries the history keeps per database.
Every request names its database in one of two ways:
A SQLite file: root and path, exactly as the files bridge names a file. The
page can only open files it could already read and write. POST database/create makes a new, empty database
(409 exists if something is already at the path).
A connection: connection and an optional database, served by a driver the app registered .
GET database/connections lists them, and POST database/databases with { connection } lists the databases on
that connection’s server that its login may open (names, or error saying why the server could not be asked).
A request that names neither or both answers 400. An unknown root, or a connection no driver serves, answers 404.
A path with . or .. segments answers 400 invalid_path. A folder picked through Android’s Storage Access Framework
has no paths SQLite can open, so it answers 400.
Errors are answers. A statement that won’t parse, a constraint refusing a value, or a file that isn’t a
database comes back in the response’s error with a 200. Only a request the bridge can’t route fails.
Scripts: POST database/query runs one statement or a whole script. Every result set comes back, with each
statement’s row count and the line any error happened on. Each result set is capped at maxRows. explain: true
returns EXPLAIN QUERY PLAN as a tree and runs nothing. schemaChanged says whether to read the schema again.
Cancel: give a run a runId and POST database/query/cancel with it to stop the run. A statement that
passes StatementTimeout is interrupted too. Either way the answer has cancelled: true.
The datasheet: rows, rows/count and rows/totals page, sort, filter and search one table on the
device. Every column is checked against the schema, and every value is a parameter. Each row carries its key (SQLite’s
rowid). rows/insert, rows/update and rows/delete write by that key and answer with the row as it now stands.
A delete is all or nothing. A BLOB is shown as its length and first bytes, and value reads one whole.
Design: design/preview turns a table design into the DDL that makes it, including SQLite’s rebuild for
column changes, with notes on what it will do. Nothing runs until the page sends that script to query. object
drops or renames a table, view, index or trigger, or with preview: true says what it would run.
CSV: import/preview detects a CSV’s delimiter, header and column kinds. import reads it into a new or
existing table in one transaction: a refused line leaves the table as it was and reports the line. export writes a
table view or one statement’s answer as UTF-8 CSV with a byte-order mark to a file in a root. The CSV comes from
csvRoot/csvPath or from csvText the page already has.
History: every run is recorded per database, except record: false and Explain runs. A repeat of the last
statement is recorded once. history, history/clear, saved and saved/save read and keep it. It lives in the
app’s data directory, outside every file root.
Platforms: every head (Android, iOS, Mac Catalyst, macOS, Windows and Linux). Microsoft.Data.Sqlite carries
SQLite’s native library for each.
import { DatabaseBridge } from "@shinyorg/appdevicebridge" ;
const db = new DatabaseBridge ();
const where = { root: "data" , path: "shop.db" };
const schema = await db. getSchema (where);
const page = await db. getRows ({ ... where, table: "orders" , maxRows: 100 , sort: [{ column: "total" , descending: true }] });
const runId = crypto. randomUUID ();
const result = await db. query ({ ... where, sql: "SELECT city, count(*) FROM customers GROUP BY city" , runId });
if (result.error) console. warn ( `line ${ result . errorLine }: ${ result . error }` );
A driver implements IDatabaseDriver and serves the DatabaseConnectionTargets it recognises. The bridge resolves
each request, picks the first driver that serves it, and handles cancel, history and CSV itself. The driver keeps its
connections and their secrets. The page only sees the id, name and engine from GetConnectionsAsync, and the databases
a connection can open from GetDatabaseNamesAsync (the SQLite driver answers that with an error: a file is one
database).
bridge. AddDatabaseBridge ();
bridge.Services. AddDatabaseDriver < OracleDriver >();
RowView, SqlSpelling, QueryPlans, DatabaseCsv, TableDesigner.Wrong and TableDesigner.DesignOf are public, so
a driver writes its datasheet SQL and design checks the same way the SQLite driver does.
GET /_bridge/ database/connectionsThe database server connections the app's drivers serve. POST /_bridge/ database/databasesThe databases on a connection's server that its login may open, or why the server could not be asked. POST /_bridge/ database/createMakes a new, empty SQLite database. POST /_bridge/ database/schemaThe tables and views in a database, or why it could not be opened. POST /_bridge/ database/queryRuns SQL — every result set and every statement's outcome — or the error it failed with. POST /_bridge/ database/query/cancelStops a query started with that run id. POST /_bridge/ database/rowsOne page of one table's rows, with the key that names each. POST /_bridge/ database/rows/countHow many rows pass the filters and search. POST /_bridge/ database/rows/totalsAn aggregate per column over every row that passes the filters and search. POST /_bridge/ database/rows/insertAdds one record, and answers with it as it now stands. POST /_bridge/ database/rows/updateChanges cells of one record, and answers with it as it now stands. POST /_bridge/ database/rows/deleteDeletes records by key, all or none. POST /_bridge/ database/valueOne value in full — a BLOB as base64, up to 64MB. POST /_bridge/ database/design/previewThe DDL that would make a table what a design says. POST /_bridge/ database/objectDrops or renames one object — or with preview, says what that would run. POST /_bridge/ database/import/previewA first look at a CSV before importing it. POST /_bridge/ database/importReads a CSV into a table in one transaction. POST /_bridge/ database/exportWrites a table or a statement's answer to a CSV file in a file root. POST /_bridge/ database/historyThe queries run against a database, newest first. POST /_bridge/ database/history/clearForgets a database's query history. POST /_bridge/ database/savedThe queries saved against a database, by name. POST /_bridge/ database/saved/saveSaves a query under a name, or overwrites one. DELETE /_bridge/ database/saved/{id} Forgets a saved query. GET /_bridge/ database/connections# The database server connections the app's drivers serve. Empty when it registered none.
C# IDatabaseBridge.GetConnectionsAsyncTS DatabaseBridge.getConnections
Response 200 DatabaseConnection []DatabaseConnection · 4 fields idstring namestring engineDatabaseEngineKind databasestring | null The database it opens on when a request names none.
POST /_bridge/ database/databases# The databases on a connection's server that its login may open, or why the server could not be asked.
C# IDatabaseBridge.GetDatabaseNamesAsyncTS DatabaseBridge.getDatabaseNames
Body application/json · GetDatabaseNames GetDatabaseNames · 1 field Response 200 DatabaseNames DatabaseNames · 2 fields namesstring []errorstring | null Why the server could not be asked — it is off, the password is wrong.
POST /_bridge/ database/create# Makes a new, empty SQLite database. 409 when something is already at the path.
C# IDatabaseBridge.CreateAsyncTS DatabaseBridge.create
Body application/json · CreateDatabase CreateDatabase · 2 fields Response 204 No contentErrors 409 ConflictPOST /_bridge/ database/schema# The tables and views in a database, or why it could not be opened.
C# IDatabaseBridge.GetSchemaAsyncTS DatabaseBridge.getSchema
Body application/json · GetDatabaseSchema GetDatabaseSchema · 4 fields rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseSchema DatabaseSchema · 6 fields tablesDatabaseTable []Tables first, then views, each alphabetically. The engine's internal ones are left out. fileSizenumber | null The file's size, for a SQLite file; null for a server. engineDatabaseEngineKind serverVersionstring The engine's own version string. errorstring | null Why the database could not be opened at all — a file that is not a database, a server that is off. defaultSchemastring | null Where a table made without saying lands — dbo, public. Null on SQLite.
POST /_bridge/ database/query# Runs SQL — every result set and every statement's outcome — or the error it failed with.
C# IDatabaseBridge.QueryAsyncTS DatabaseBridge.query
Body application/json · RunDatabaseQuery RunDatabaseQuery · 9 fields sqlstring maxRowsnumber The cap on each result set, 1–100,000. Each result says whether it bit. explainboolean Ask how each statement would be answered rather than answering it, as a plan tree. runIdstring | null The page's name for this run, so CancelDatabaseQuery can stop it. recordboolean Whether this run goes into the database's query history. rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseScriptResult DatabaseScriptResult · 10 fields resultsDatabaseResultSet []messagesDatabaseMessage []rowsAffectednumber What every write in it changed, added up; -1 when nothing was a write. elapsedMsnumber errorstring | null errorLinenumber | null Where the error was, counted in the text that was sent. errorColumnnumber | null planDatabasePlanNode [] | null For an Explain: the plan as a tree, or null where it could not be read as one. cancelledboolean Stopped — by a cancel, or by the device's statement timeout. schemaChangedboolean Whether the script made, dropped or altered something, so the page reads the schema again.
POST /_bridge/ database/query/cancel# Stops a query started with that run id. Harmless when it has already finished.
C# IDatabaseBridge.CancelAsyncTS DatabaseBridge.cancel
Body application/json · CancelDatabaseQuery CancelDatabaseQuery · 1 field Response 204 No contentPOST /_bridge/ database/rows# One page of one table's rows, with the key that names each.
C# IDatabaseBridge.GetRowsAsyncTS DatabaseBridge.getRows
Body application/json · GetDatabaseTableRows GetDatabaseTableRows · 11 fields tablestring maxRowsnumber The page size, 1–5,000. offsetnumber Where the page starts, in the order the sort gives. The key always ends the order, so pages are stable. sortDatabaseSort [] | null filtersDatabaseRowFilter [] | null Every one must hold. searchstring | null Text to look for anywhere in a row, case-insensitively. schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseTableRows DatabaseTableRows · 7 fields columnsstring []rowKeysstring [][]Parallel to rows: each row's key, carried back untouched to edit or delete it. Empty when rows cannot be named. rowsstring [][]truncatedboolean True when there are rows after this page. elapsedMsnumber errorstring | null offsetnumber The request's, said back so a late answer can be placed.
POST /_bridge/ database/rows/count# How many rows pass the filters and search.
C# IDatabaseBridge.CountAsyncTS DatabaseBridge.count
Body application/json · CountDatabaseTableRows CountDatabaseTableRows · 8 fields tablestring filtersDatabaseRowFilter [] | null searchstring | null schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseRowCount DatabaseRowCount · 3 fields countnumber | null Null when it could not be counted. elapsedMsnumber errorstring | null
POST /_bridge/ database/rows/totals# An aggregate per column over every row that passes the filters and search.
C# IDatabaseBridge.GetTotalsAsyncTS DatabaseBridge.getTotals
Body application/json · GetDatabaseTotals GetDatabaseTotals · 9 fields tablestring totalsDatabaseTotal []filtersDatabaseRowFilter [] | null searchstring | null schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseTotals DatabaseTotals · 3 fields valuesstring []Parallel to the request's totals, each the engine's own text for it. elapsedMsnumber errorstring | null
POST /_bridge/ database/rows/insert# Adds one record, and answers with it as it now stands.
C# IDatabaseBridge.InsertRowAsyncTS DatabaseBridge.insertRow
Body application/json · InsertDatabaseRow InsertDatabaseRow · 7 fields tablestring valuesDatabaseCellEdit []schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseQueryResult DatabaseQueryResult · 7 fields columnsstring []rowsstring [][]rowsAffectednumber truncatedboolean elapsedMsnumber errorstring | null keystring [] | null The record's key after the write — the only way to name a record the engine numbered. Null when it could not be read back.
POST /_bridge/ database/rows/update# Changes cells of one record, and answers with it as it now stands.
C# IDatabaseBridge.UpdateRowAsyncTS DatabaseBridge.updateRow
Body application/json · UpdateDatabaseRow UpdateDatabaseRow · 8 fields tablestring keystring []The row's key exactly as rowKeys gave it. changesDatabaseCellEdit []schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseQueryResult DatabaseQueryResult · 7 fields columnsstring []rowsstring [][]rowsAffectednumber truncatedboolean elapsedMsnumber errorstring | null keystring [] | null The record's key after the write — the only way to name a record the engine numbered. Null when it could not be read back.
POST /_bridge/ database/rows/delete# Deletes records by key, all or none.
C# IDatabaseBridge.DeleteRowsAsyncTS DatabaseBridge.deleteRows
Body application/json · DeleteDatabaseRows DeleteDatabaseRows · 7 fields tablestring keysstring [][]schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseQueryResult DatabaseQueryResult · 7 fields columnsstring []rowsstring [][]rowsAffectednumber truncatedboolean elapsedMsnumber errorstring | null keystring [] | null The record's key after the write — the only way to name a record the engine numbered. Null when it could not be read back.
POST /_bridge/ database/value# One value in full — a BLOB as base64, up to 64MB.
C# IDatabaseBridge.GetValueAsyncTS DatabaseBridge.getValue
Body application/json · GetDatabaseValue GetDatabaseValue · 8 fields tablestring keystring []columnstring schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseValue DatabaseValue · 5 fields base64string | null The bytes of a binary value. textstring | null Any other value, as the engine's own text. lengthnumber isNullboolean errorstring | null
POST /_bridge/ database/design/preview# The DDL that would make a table what a design says. Nothing is run.
C# IDatabaseBridge.PreviewDesignAsyncTS DatabaseBridge.previewDesign
Body application/json · PreviewDatabaseDesign PreviewDatabaseDesign · 5 fields designDatabaseTableDesign rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseDesignScript DatabaseDesignScript · 3 fields sqlstring The script, or empty when there is nothing to do. notesstring []What a reader must know before running it — a rebuild, what cannot be kept. errorstring | null Why no script could be written.
POST /_bridge/ database/object# Drops or renames one object — or with preview, says what that would run.
C# IDatabaseBridge.ChangeObjectAsyncTS DatabaseBridge.changeObject
Body application/json · ChangeDatabaseObject ChangeDatabaseObject · 11 fields actionDatabaseObjectAction kindstring table, view, index or trigger.namestring newNamestring | null tablestring | null The table an index or trigger belongs to, where the engine's rename needs it. previewboolean schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseObjectResult DatabaseObjectResult · 2 fields sqlstring errorstring | null
POST /_bridge/ database/import/preview# A first look at a CSV before importing it.
C# IDatabaseBridge.PreviewImportAsyncTS DatabaseBridge.previewImport
Body application/json · PreviewDatabaseImport PreviewDatabaseImport · 10 fields csvRootstring | null csvPathstring | null csvTextstring | null delimiterstring | null Null to detect it. \t for a tab. hasHeaderboolean | null Null to detect it. sampleRowsnumber rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseImportPreview DatabaseImportPreview · 8 fields delimiterstring hasHeaderboolean columnsstring []A name for each column — the header's, or column1… without one. kindsDatabaseValueKind []What every sampled value in each column could be read as. suggestedTypesstring []The engine's type for each, for a new table. samplestring [][]rowsnumber How many data rows the whole file has. errorstring | null
POST /_bridge/ database/import# Reads a CSV into a table in one transaction.
C# IDatabaseBridge.ImportAsyncTS DatabaseBridge.import
Body application/json · ImportDatabaseCsv ImportDatabaseCsv · 14 fields tablestring createTableboolean columnsDatabaseImportColumn []delimiterstring hasHeaderboolean csvRootstring | null csvPathstring | null csvTextstring | null emptyIsNullboolean Whether an empty field is NULL rather than an empty string. schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseImportResult DatabaseImportResult · 4 fields rowsnumber elapsedMsnumber errorstring | null failedAtLinenumber | null The file's line the import stopped at, when it did.
POST /_bridge/ database/export# Writes a table or a statement's answer to a CSV file in a file root.
C# IDatabaseBridge.ExportAsyncTS DatabaseBridge.export
Body application/json · ExportDatabaseCsv ExportDatabaseCsv · 12 fields targetRootstring targetPathstring tablestring | null sqlstring | null filtersDatabaseRowFilter [] | null searchstring | null sortDatabaseSort [] | null schemastring | null rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseExportResult DatabaseExportResult · 4 fields pathstring | null Where it was written, in targetRoot. rowsnumber elapsedMsnumber errorstring | null
POST /_bridge/ database/history# The queries run against a database, newest first.
C# IDatabaseBridge.GetHistoryAsyncTS DatabaseBridge.getHistory
Body application/json · GetDatabaseHistory GetDatabaseHistory · 5 fields takenumber rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 DatabaseHistoryEntry []DatabaseHistoryEntry · 7 fields idstring sqlstring ranOnstring elapsedMsnumber rowsAffectednumber resultSetsnumber errorstring | null
POST /_bridge/ database/history/clear# Forgets a database's query history.
C# IDatabaseBridge.ClearHistoryAsyncTS DatabaseBridge.clearHistory
Body application/json · ClearDatabaseHistory ClearDatabaseHistory · 4 fields rootstring | null pathstring | null connectionstring | null databasestring | null
Response 204 No contentPOST /_bridge/ database/saved# The queries saved against a database, by name.
C# IDatabaseBridge.GetSavedQueriesAsyncTS DatabaseBridge.getSavedQueries
Body application/json · GetSavedDatabaseQueries GetSavedDatabaseQueries · 4 fields rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 SavedDatabaseQuery []SavedDatabaseQuery · 4 fields idstring namestring sqlstring savedOnstring
POST /_bridge/ database/saved/save# Saves a query under a name, or overwrites one.
C# IDatabaseBridge.SaveQueryAsyncTS DatabaseBridge.saveQuery
Body application/json · SaveDatabaseQuery SaveDatabaseQuery · 7 fields namestring sqlstring idstring | null Null for a new one; a saved one's id to overwrite or rename it. rootstring | null pathstring | null connectionstring | null databasestring | null
Response 200 SavedDatabaseQueryResult SavedDatabaseQueryResult · 2 fields querySavedDatabaseQuery | null refusalstring | null Why it was not saved, in a sentence for the form.
DELETE /_bridge/ database/saved/{id} # Forgets a saved query.
C# IDatabaseBridge.RemoveSavedQueryAsyncTS DatabaseBridge.removeSavedQuery
Parameter In Type idpath string required
Response 204 No content
JSON property names are camelCase and enums travel as their names. A ? marks a property the payload may omit;| null one that may be null.
DatabaseConnectionobject # A database server connection a driver serves, by the id requests name it with.
idstring namestring engineDatabaseEngineKind databasestring | null The database it opens on when a request names none.
What is on the other end of a request. SQLite ships with the bridge; the servers come from drivers an app registers.
"Sqlite""SqlServer""PostgreSql"
The databases on a connection's server that its login may open, for a picker.
namesstring []errorstring | null Why the server could not be asked — it is off, the password is wrong.
Writes a new, empty SQLite database — with the header a file needs before other tools will admit it is a database — at a path in a file root. Refused when something is already there.
The tables and views in a database, and the columns, indexes, keys, checks and triggers of each. No row counts: a count is a full scan on a table without a narrow index, so it is asked separately (CountDatabaseTableRows).
root?string | null path?string | null connection?string | null database?string | null
tablesDatabaseTable []Tables first, then views, each alphabetically. The engine's internal ones are left out. fileSizenumber | null The file's size, for a SQLite file; null for a server. engineDatabaseEngineKind serverVersionstring The engine's own version string. errorstring | null Why the database could not be opened at all — a file that is not a database, a server that is off. defaultSchemastring | null Where a table made without saying lands — dbo, public. Null on SQLite.
A table or a view.
namestring kindstring table or view.columnsDatabaseColumn []indexesDatabaseIndex []keyColumnsstring []The columns whose values name one row, and so whether a row can be edited at all: empty means it cannot. SQLite's is rowid, which a view and a WITHOUT ROWID table do not have; a server's is the primary key. schemastring | null A server's namespace — dbo, public. Null on SQLite. foreignKeysDatabaseForeignKey [] | null checksDatabaseCheck [] | null triggersstring [] | null The names of the triggers on it.
namestring typestring notNullboolean primaryKeyboolean defaultstring | null The column's default as the engine wrote it down — an expression, not a value. autoIncrementboolean Whether the engine numbers it; a column like this is left out of a new record. kindDatabaseValueKind
What sort of value a column holds, decided on the device from the engine's own type names, so the page can pick an editor and an alignment without knowing that bit, boolean and SQLite's BOOLEAN are one idea. The value itself still travels as the engine's own text.
"Text""LongText""Integer""Decimal""Boolean""Date""DateTime""DateTimeOffset""Time""Binary""Guid""Other"
namestring columnsstring []In index order. An expression index says (expression) for that position. uniqueboolean automaticboolean Made by the engine for a constraint rather than by CREATE INDEX; it cannot be dropped on its own. partialboolean It has a WHERE clause, so it covers only some of the rows.
DatabaseForeignKeyobject # namestring | null Null on SQLite, whose foreign keys have no names. columnsstring []referencedSchemastring | null referencedTablestring referencedColumnsstring []Parallel to columns; empty for a SQLite key that means the other table's primary key. onUpdatestring onDeletestring
namestring | null expressionstring
Runs SQL — one statement or a script — and answers with every result set it produced and what each statement said. This can write: it is a database client. What it cannot do on SQLite is leave the file it was opened on — ATTACH and load_extension are refused by SQLite's authorizer before a statement can run.
sqlstring maxRows?number The cap on each result set, 1–100,000. Each result says whether it bit. explain?boolean Ask how each statement would be answered rather than answering it, as a plan tree. runId?string | null The page's name for this run, so CancelDatabaseQuery can stop it. record?boolean Whether this run goes into the database's query history. root?string | null path?string | null connection?string | null database?string | null
DatabaseScriptResultobject # Everything a script produced: each result set, each statement's outcome, and how it ended.
resultsDatabaseResultSet []messagesDatabaseMessage []rowsAffectednumber What every write in it changed, added up; -1 when nothing was a write. elapsedMsnumber errorstring | null errorLinenumber | null Where the error was, counted in the text that was sent. errorColumnnumber | null planDatabasePlanNode [] | null For an Explain: the plan as a tree, or null where it could not be read as one. cancelledboolean Stopped — by a cancel, or by the device's statement timeout. schemaChangedboolean Whether the script made, dropped or altered something, so the page reads the schema again.
columnsstring []kindsDatabaseValueKind []Parallel to columns: how each is shown. rowsstring [][]truncatedboolean statementnumber Which statement of the script produced it, from zero. typesstring [] | null The engine's name for each column's type, where it gave one.
What a statement did, what the server printed, what failed.
kindDatabaseMessageKind textstring linenumber | null 1-based, in the text that was sent, where the engine said. columnnumber | null elapsedMsnumber
"Info""Rows""Error""Notice"
A step of a query plan, as a tree.
labelstring What the step is: SCAN orders, Hash Join. detailstring | null The numbers — estimated rows and cost — where the engine gave any. childrenDatabasePlanNode []
CancelDatabaseQueryobject # Stops a query started with that run id, if it is still running.
GetDatabaseTableRowsobject # One page of one table's rows, each with the key that names it. Paged, sorted and filtered on the device: every column a filter or sort names is checked against the table, and every value is a parameter.
tablestring maxRows?number The page size, 1–5,000. offset?number Where the page starts, in the order the sort gives. The key always ends the order, so pages are stable. sort?DatabaseSort [] | null filters?DatabaseRowFilter [] | null Every one must hold. search?string | null Text to look for anywhere in a row, case-insensitively. schema?string | null root?string | null path?string | null connection?string | null database?string | null
columnstring descending?boolean
DatabaseFilterOperatorenum # How a filter compares a column with its value. The comparisons read the value back through the column's own type; the text ones compare the column's text, case-insensitively.
"Equal""NotEqual""Contains""NotContains""StartsWith""EndsWith""Greater""GreaterOrEqual""Less""LessOrEqual""IsNull""IsNotNull"
columnsstring []rowKeysstring [][]Parallel to rows: each row's key, carried back untouched to edit or delete it. Empty when rows cannot be named. rowsstring [][]truncatedboolean True when there are rows after this page. elapsedMsnumber errorstring | null offsetnumber The request's, said back so a late answer can be placed.
CountDatabaseTableRowsobject # How many rows a table has under the same filters and search as a page — exact, and asked separately so the first page never waits on it.
tablestring filters?DatabaseRowFilter [] | null search?string | null schema?string | null root?string | null path?string | null connection?string | null database?string | null
countnumber | null Null when it could not be counted. elapsedMsnumber errorstring | null
A totals row — one aggregate per column, over every row the filters let through, worked out by the engine.
tablestring totalsDatabaseTotal []filters?DatabaseRowFilter [] | null search?string | null schema?string | null root?string | null path?string | null connection?string | null database?string | null
"Count""Sum""Average""Min""Max"
valuesstring []Parallel to the request's totals, each the engine's own text for it. elapsedMsnumber errorstring | null
Adds one record and answers with it as it stands afterwards — defaults, the number the engine gave it, whatever a trigger made of it. A column left out takes the table's default. The table and column names are checked against the schema and every value is a parameter.
tablestring valuesDatabaseCellEdit []schema?string | null root?string | null path?string | null connection?string | null database?string | null
columnstring valuestring | null Null is SQL NULL.
DatabaseQueryResultobject # What one write did. Every value is the engine's text; null stays null.
columnsstring []rowsstring [][]rowsAffectednumber truncatedboolean elapsedMsnumber errorstring | null keystring [] | null The record's key after the write — the only way to name a record the engine numbered. Null when it could not be read back.
Changes some cells of one record, named by its key, and answers with the record as it now stands.
tablestring keystring []The row's key exactly as rowKeys gave it. changesDatabaseCellEdit []schema?string | null root?string | null path?string | null connection?string | null database?string | null
DeleteDatabaseRowsobject # Deletes records, each named by its key — all of them or, when one is refused, none.
tablestring keysstring [][]schema?string | null root?string | null path?string | null connection?string | null database?string | null
One value in full — a BLOB the datasheet only describes as its length and first bytes.
tablestring keystring []columnstring schema?string | null root?string | null path?string | null connection?string | null database?string | null
base64string | null The bytes of a binary value. textstring | null Any other value, as the engine's own text. lengthnumber isNullboolean errorstring | null
PreviewDatabaseDesignobject # The DDL that would make a table what a design says, to be read before it is run. Applying it is running that text with RunDatabaseQuery, so what somebody approved is what runs.
designDatabaseTableDesign root?string | null path?string | null connection?string | null database?string | null
DatabaseTableDesignobject # A table as a designer wants it, compared by the device with the table as it is.
DatabaseColumnDesignobject # namestring typestring notNullboolean primaryKeyboolean default?string | null autoIncrement?boolean unique?boolean A single-column UNIQUE constraint. original?string | null What the column is called in the table as it stands, or null for one being added.
DatabaseIndexDesignobject # namestring columnsstring []uniqueboolean original?string | null The index's name as it stands, or null for one being added.
DatabaseForeignKeyDesignobject # namestring | null columnsstring []referencedSchemastring | null referencedTablestring referencedColumnsstring []onDelete?string onUpdate?string original?string | null The constraint's name as it stands — or, where keys have no names, any value for "was there".
DatabaseCheckDesignobject # namestring | null expressionstring original?string | null
DatabaseDesignScriptobject # sqlstring The script, or empty when there is nothing to do. notesstring []What a reader must know before running it — a rebuild, what cannot be kept. errorstring | null Why no script could be written.
ChangeDatabaseObjectobject # Drops or renames a table, view, index or trigger — or, with preview, only says what it would run.
actionDatabaseObjectAction kindstring table, view, index or trigger.namestring newName?string | null table?string | null The table an index or trigger belongs to, where the engine's rename needs it. preview?boolean schema?string | null root?string | null path?string | null connection?string | null database?string | null
DatabaseObjectActionenum # "Drop""Rename"
DatabaseObjectResultobject # sqlstring errorstring | null
PreviewDatabaseImportobject # A first look at a CSV: its delimiter, whether it has a header, what each column seems to be, and the engine's type for each. From a file in a file root (csvRoot and csvPath) or from text the page already has (csvText) — exactly one.
csvRoot?string | null csvPath?string | null csvText?string | null delimiter?string | null Null to detect it. \t for a tab. hasHeader?boolean | null Null to detect it. sampleRows?number root?string | null path?string | null connection?string | null database?string | null
DatabaseImportPreviewobject # delimiterstring hasHeaderboolean columnsstring []A name for each column — the header's, or column1… without one. kindsDatabaseValueKind []What every sampled value in each column could be read as. suggestedTypesstring []The engine's type for each, for a new table. samplestring [][]rowsnumber How many data rows the whole file has. errorstring | null
Reads a CSV into a table — a new one made to the mapping, or one that exists — in one transaction: an import that stops part way leaves the table as it was, with the line that stopped it in the answer.
tablestring createTableboolean columnsDatabaseImportColumn []delimiterstring hasHeaderboolean csvRoot?string | null csvPath?string | null csvText?string | null emptyIsNull?boolean Whether an empty field is NULL rather than an empty string. schema?string | null root?string | null path?string | null connection?string | null database?string | null
DatabaseImportColumnobject # sourcenumber The CSV column, from zero. targetstring The table's column it goes into. type?string | null For a new table, the column's type.
DatabaseImportResultobject # rowsnumber elapsedMsnumber errorstring | null failedAtLinenumber | null The file's line the import stopped at, when it did.
Writes a table — filtered and sorted as a datasheet shows it — or one statement's answer to a CSV file in a file root, streamed from the engine on the device. Exactly one of table and sql. The file is UTF-8 with a byte-order mark, so spreadsheets read it as UTF-8, and replaces anything already at the target.
targetRootstring targetPathstring table?string | null sql?string | null filters?DatabaseRowFilter [] | null search?string | null sort?DatabaseSort [] | null schema?string | null root?string | null path?string | null connection?string | null database?string | null
DatabaseExportResultobject # pathstring | null Where it was written, in targetRoot. rowsnumber elapsedMsnumber errorstring | null
GetDatabaseHistoryobject # The queries run against one database, newest first, as the device recorded them.
take?number root?string | null path?string | null connection?string | null database?string | null
DatabaseHistoryEntryobject # idstring sqlstring ranOnstring elapsedMsnumber rowsAffectednumber resultSetsnumber errorstring | null
ClearDatabaseHistoryobject # root?string | null path?string | null connection?string | null database?string | null
GetSavedDatabaseQueriesobject # The named queries saved against one database.
root?string | null path?string | null connection?string | null database?string | null
SavedDatabaseQueryobject # idstring namestring sqlstring savedOnstring
Saves a query under a name. Saving under a name the database already has overwrites that one.
namestring sqlstring id?string | null Null for a new one; a saved one's id to overwrite or rename it. root?string | null path?string | null connection?string | null database?string | null
SavedDatabaseQueryResultobject # querySavedDatabaseQuery | null refusalstring | null Why it was not saved, in a sentence for the form.
These routes sit under AppDeviceBridgePolicies.Bridges like every other bridge: callers on this device by default.
See Security .
The bridge can write: it is a database client, and query runs UPDATE, DELETE and DDL. It can’t leave the file it
opened. SQLite’s authorizer runs while each statement is prepared and refuses ATTACH, which also covers VACUUM INTO,
and load_extension. A query can’t open a file outside the file roots or load native code. The query history is
outside every root, so the page reaches it only through these routes.
A connection served by a driver is reached by its id alone. Whatever it needs to connect stays in the app, with the
driver.