Skip to content
Shiny.NET

Database

NuGet package Shiny.AppDeviceBridge.Database

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).

Terminal window
dotnet add package Shiny.AppDeviceBridge.Database
builder.UseAppDeviceBridge(
bridge => bridge.AddDatabaseBridge(o => o.StatementTimeout = TimeSpan.FromSeconds(10)),
webApp => { /* … */ }
);
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/connections#

The database server connections the app's drivers serve. Empty when it registered none.

C#IDatabaseBridge.GetConnectionsAsyncTSDatabaseBridge.getConnections
Response
200 DatabaseConnection[]
DatabaseConnection · 4 fields
idstring
namestring
engineDatabaseEngineKind
databasestring | nullThe 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.GetDatabaseNamesAsyncTSDatabaseBridge.getDatabaseNames
Body
application/json · GetDatabaseNames
GetDatabaseNames · 1 field
connectionstring
Response
200 DatabaseNames
DatabaseNames · 2 fields
namesstring[]
errorstring | nullWhy 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.CreateAsyncTSDatabaseBridge.create
Body
application/json · CreateDatabase
CreateDatabase · 2 fields
rootstring
pathstring
Response
204 No content
Errors
409Conflict
POST/_bridge/database/schema#

The tables and views in a database, or why it could not be opened.

C#IDatabaseBridge.GetSchemaAsyncTSDatabaseBridge.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 | nullThe file's size, for a SQLite file; null for a server.
engineDatabaseEngineKind
serverVersionstringThe engine's own version string.
errorstring | nullWhy the database could not be opened at all — a file that is not a database, a server that is off.
defaultSchemastring | nullWhere 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.QueryAsyncTSDatabaseBridge.query
Body
application/json · RunDatabaseQuery
RunDatabaseQuery · 9 fields
sqlstring
maxRowsnumberThe cap on each result set, 1–100,000. Each result says whether it bit.
explainbooleanAsk how each statement would be answered rather than answering it, as a plan tree.
runIdstring | nullThe page's name for this run, so CancelDatabaseQuery can stop it.
recordbooleanWhether 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[]
rowsAffectednumberWhat every write in it changed, added up; -1 when nothing was a write.
elapsedMsnumber
errorstring | null
errorLinenumber | nullWhere the error was, counted in the text that was sent.
errorColumnnumber | null
planDatabasePlanNode[] | nullFor an Explain: the plan as a tree, or null where it could not be read as one.
cancelledbooleanStopped — by a cancel, or by the device's statement timeout.
schemaChangedbooleanWhether 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.CancelAsyncTSDatabaseBridge.cancel
Body
application/json · CancelDatabaseQuery
CancelDatabaseQuery · 1 field
runIdstring
Response
204 No content
POST/_bridge/database/rows#

One page of one table's rows, with the key that names each.

C#IDatabaseBridge.GetRowsAsyncTSDatabaseBridge.getRows
Body
application/json · GetDatabaseTableRows
GetDatabaseTableRows · 11 fields
tablestring
maxRowsnumberThe page size, 1–5,000.
offsetnumberWhere the page starts, in the order the sort gives. The key always ends the order, so pages are stable.
sortDatabaseSort[] | null
filtersDatabaseRowFilter[] | nullEvery one must hold.
searchstring | nullText 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[][]
truncatedbooleanTrue when there are rows after this page.
elapsedMsnumber
errorstring | null
offsetnumberThe 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.CountAsyncTSDatabaseBridge.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 | nullNull 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.GetTotalsAsyncTSDatabaseBridge.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.InsertRowAsyncTSDatabaseBridge.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[] | nullThe 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.UpdateRowAsyncTSDatabaseBridge.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[] | nullThe 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.DeleteRowsAsyncTSDatabaseBridge.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[] | nullThe 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.GetValueAsyncTSDatabaseBridge.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 | nullThe bytes of a binary value.
textstring | nullAny 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.PreviewDesignAsyncTSDatabaseBridge.previewDesign
Body
application/json · PreviewDatabaseDesign
PreviewDatabaseDesign · 5 fields
designDatabaseTableDesign
rootstring | null
pathstring | null
connectionstring | null
databasestring | null
Response
200 DatabaseDesignScript
DatabaseDesignScript · 3 fields
sqlstringThe 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 | nullWhy no script could be written.
POST/_bridge/database/object#

Drops or renames one object — or with preview, says what that would run.

C#IDatabaseBridge.ChangeObjectAsyncTSDatabaseBridge.changeObject
Body
application/json · ChangeDatabaseObject
ChangeDatabaseObject · 11 fields
actionDatabaseObjectAction
kindstringtable, view, index or trigger.
namestring
newNamestring | null
tablestring | nullThe 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.PreviewImportAsyncTSDatabaseBridge.previewImport
Body
application/json · PreviewDatabaseImport
PreviewDatabaseImport · 10 fields
csvRootstring | null
csvPathstring | null
csvTextstring | null
delimiterstring | nullNull to detect it. \t for a tab.
hasHeaderboolean | nullNull 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[][]
rowsnumberHow many data rows the whole file has.
errorstring | null
POST/_bridge/database/import#

Reads a CSV into a table in one transaction.

C#IDatabaseBridge.ImportAsyncTSDatabaseBridge.import
Body
application/json · ImportDatabaseCsv
ImportDatabaseCsv · 14 fields
tablestring
createTableboolean
columnsDatabaseImportColumn[]
delimiterstring
hasHeaderboolean
csvRootstring | null
csvPathstring | null
csvTextstring | null
emptyIsNullbooleanWhether 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 | nullThe 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.ExportAsyncTSDatabaseBridge.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 | nullWhere it was written, in targetRoot.
rowsnumber
elapsedMsnumber
errorstring | null
POST/_bridge/database/history#

The queries run against a database, newest first.

C#IDatabaseBridge.GetHistoryAsyncTSDatabaseBridge.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.ClearHistoryAsyncTSDatabaseBridge.clearHistory
Body
application/json · ClearDatabaseHistory
ClearDatabaseHistory · 4 fields
rootstring | null
pathstring | null
connectionstring | null
databasestring | null
Response
204 No content
POST/_bridge/database/saved#

The queries saved against a database, by name.

C#IDatabaseBridge.GetSavedQueriesAsyncTSDatabaseBridge.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.SaveQueryAsyncTSDatabaseBridge.saveQuery
Body
application/json · SaveDatabaseQuery
SaveDatabaseQuery · 7 fields
namestring
sqlstring
idstring | nullNull 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 | nullWhy it was not saved, in a sentence for the form.
DELETE/_bridge/database/saved/{id}#

Forgets a saved query.

C#IDatabaseBridge.RemoveSavedQueryAsyncTSDatabaseBridge.removeSavedQuery
ParameterInType
idpathstringrequired
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 | nullThe database it opens on when a request names none.
DatabaseEngineKindenum#

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"
GetDatabaseNamesobject#

The databases on a connection's server that its login may open, for a picker.

connectionstring
DatabaseNamesobject#
namesstring[]
errorstring | nullWhy the server could not be asked — it is off, the password is wrong.
CreateDatabaseobject#

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.

rootstring
pathstring
GetDatabaseSchemaobject#

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
DatabaseSchemaobject#
tablesDatabaseTable[]Tables first, then views, each alphabetically. The engine's internal ones are left out.
fileSizenumber | nullThe file's size, for a SQLite file; null for a server.
engineDatabaseEngineKind
serverVersionstringThe engine's own version string.
errorstring | nullWhy the database could not be opened at all — a file that is not a database, a server that is off.
defaultSchemastring | nullWhere a table made without saying lands — dbo, public. Null on SQLite.
DatabaseTableobject#

A table or a view.

namestring
kindstringtable 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 | nullA server's namespace — dbo, public. Null on SQLite.
foreignKeysDatabaseForeignKey[] | null
checksDatabaseCheck[] | null
triggersstring[] | nullThe names of the triggers on it.
DatabaseColumnobject#
namestring
typestring
notNullboolean
primaryKeyboolean
defaultstring | nullThe column's default as the engine wrote it down — an expression, not a value.
autoIncrementbooleanWhether the engine numbers it; a column like this is left out of a new record.
kindDatabaseValueKind
DatabaseValueKindenum#

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"
DatabaseIndexobject#
namestring
columnsstring[]In index order. An expression index says (expression) for that position.
uniqueboolean
automaticbooleanMade by the engine for a constraint rather than by CREATE INDEX; it cannot be dropped on its own.
partialbooleanIt has a WHERE clause, so it covers only some of the rows.
DatabaseForeignKeyobject#
namestring | nullNull 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
DatabaseCheckobject#
namestring | null
expressionstring
RunDatabaseQueryobject#

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?numberThe cap on each result set, 1–100,000. Each result says whether it bit.
explain?booleanAsk how each statement would be answered rather than answering it, as a plan tree.
runId?string | nullThe page's name for this run, so CancelDatabaseQuery can stop it.
record?booleanWhether 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[]
rowsAffectednumberWhat every write in it changed, added up; -1 when nothing was a write.
elapsedMsnumber
errorstring | null
errorLinenumber | nullWhere the error was, counted in the text that was sent.
errorColumnnumber | null
planDatabasePlanNode[] | nullFor an Explain: the plan as a tree, or null where it could not be read as one.
cancelledbooleanStopped — by a cancel, or by the device's statement timeout.
schemaChangedbooleanWhether the script made, dropped or altered something, so the page reads the schema again.
DatabaseResultSetobject#
columnsstring[]
kindsDatabaseValueKind[]Parallel to columns: how each is shown.
rowsstring[][]
truncatedboolean
statementnumberWhich statement of the script produced it, from zero.
typesstring[] | nullThe engine's name for each column's type, where it gave one.
DatabaseMessageobject#

What a statement did, what the server printed, what failed.

kindDatabaseMessageKind
textstring
linenumber | null1-based, in the text that was sent, where the engine said.
columnnumber | null
elapsedMsnumber
DatabaseMessageKindenum#
"Info""Rows""Error""Notice"
DatabasePlanNodeobject#

A step of a query plan, as a tree.

labelstringWhat the step is: SCAN orders, Hash Join.
detailstring | nullThe 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.

runIdstring
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?numberThe page size, 1–5,000.
offset?numberWhere the page starts, in the order the sort gives. The key always ends the order, so pages are stable.
sort?DatabaseSort[] | null
filters?DatabaseRowFilter[] | nullEvery one must hold.
search?string | nullText to look for anywhere in a row, case-insensitively.
schema?string | null
root?string | null
path?string | null
connection?string | null
database?string | null
DatabaseSortobject#
columnstring
descending?boolean
DatabaseRowFilterobject#
columnstring
operatorDatabaseFilterOperator
value?string | nullIgnored by IsNull and IsNotNull.
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"
DatabaseTableRowsobject#
columnsstring[]
rowKeysstring[][]Parallel to rows: each row's key, carried back untouched to edit or delete it. Empty when rows cannot be named.
rowsstring[][]
truncatedbooleanTrue when there are rows after this page.
elapsedMsnumber
errorstring | null
offsetnumberThe 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
DatabaseRowCountobject#
countnumber | nullNull when it could not be counted.
elapsedMsnumber
errorstring | null
GetDatabaseTotalsobject#

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
DatabaseAggregateenum#
"Count""Sum""Average""Min""Max"
DatabaseTotalsobject#
valuesstring[]Parallel to the request's totals, each the engine's own text for it.
elapsedMsnumber
errorstring | null
InsertDatabaseRowobject#

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
DatabaseCellEditobject#
columnstring
valuestring | nullNull 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[] | nullThe record's key after the write — the only way to name a record the engine numbered. Null when it could not be read back.
UpdateDatabaseRowobject#

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
GetDatabaseValueobject#

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
DatabaseValueobject#
base64string | nullThe bytes of a binary value.
textstring | nullAny 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
DatabaseColumnDesignobject#
namestring
typestring
notNullboolean
primaryKeyboolean
default?string | null
autoIncrement?boolean
unique?booleanA single-column UNIQUE constraint.
original?string | nullWhat the column is called in the table as it stands, or null for one being added.
DatabaseIndexDesignobject#
namestring
columnsstring[]
uniqueboolean
original?string | nullThe 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 | nullThe 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#
sqlstringThe 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 | nullWhy 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
kindstringtable, view, index or trigger.
namestring
newName?string | null
table?string | nullThe 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 | nullNull to detect it. \t for a tab.
hasHeader?boolean | nullNull 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[][]
rowsnumberHow many data rows the whole file has.
errorstring | null
ImportDatabaseCsvobject#

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?booleanWhether 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#
sourcenumberThe CSV column, from zero.
targetstringThe table's column it goes into.
type?string | nullFor a new table, the column's type.
DatabaseImportResultobject#
rowsnumber
elapsedMsnumber
errorstring | null
failedAtLinenumber | nullThe file's line the import stopped at, when it did.
ExportDatabaseCsvobject#

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 | nullWhere 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
SaveDatabaseQueryobject#

Saves a query under a name. Saving under a name the database already has overwrites that one.

namestring
sqlstring
id?string | nullNull 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 | nullWhy 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.