Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions .tabularium
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
"name": "libsql",
"version": "0.1.0",
"kind": "driver",
"description": "libSQL / Turso driver. Connects to local libSQL/SQLite files and to remote Turso or sqld servers over the Hrana HTTP protocol.",
"description": "libSQL / Turso driver. Connects to local libSQL/SQLite files (embedded libSQL fork: ALTER COLUMN and foreign-key add/drop work locally) and to remote Turso or sqld servers over the Hrana HTTP protocol.",
"engine": "libsql",
"paradigms": [
"sql"
],
"icon": "sqlite",
"color": "#4ff8d2",
"default_username": "",
"executable": "libsql-plugin",
"capabilities": {
Expand All @@ -16,14 +18,21 @@
"file_based": false,
"folder_based": false,
"connection_string": true,
"connection_string_example": "libsql://my-db.turso.io?authToken=... (or a local path like /data/app.db)",
"connection_string_example": "libsql://my-db.turso.io?authToken=... (or a local file via file:///data/app.db)",
"connection_uri": true,
"connection_uri_schemes": [
"turso",
"wss",
"ws",
"file"
],
"identifier_quote": "\"",
"alter_primary_key": false,
"inline_pk": true,
"auto_increment_keyword": "AUTOINCREMENT",
"serial_type": "",
"alter_column": false,
"create_foreign_keys": false,
"alter_column": true,
"create_foreign_keys": true,
"no_connection_required": false,
"manage_tables": true,
"readonly": false,
Expand Down
11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ path = "src/main.rs"

[dependencies]
serde_json = "1"
# Local file backend: bundled SQLite, compiled from source -> no system lib
# needed, builds identically on Linux, macOS and Windows.
rusqlite = { version = "0.31", features = ["bundled"] }
# Local file backend: the libSQL fork of SQLite, bundled (compiled from source
# -> no system lib, builds identically on Linux, macOS and Windows). Using the
# fork gives local files the same ALTER COLUMN / FK-add extensions as remote
# Turso servers. The `core` feature is embedded-local only; the async API does
# all its work synchronously, so futures::executor::block_on bridges it
# without pulling in a tokio runtime.
libsql = { version = "0.9", default-features = false, features = ["core"] }
futures = "0.3"
# Remote backend: blocking HTTP client with pure-Rust rustls TLS (no OpenSSL),
# used to speak the Hrana-over-HTTP pipeline protocol to Turso / sqld.
ureq = { version = "2", features = ["json"] }
Expand Down
44 changes: 39 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,41 @@ libsql://my-db.turso.io?authToken=eyJ...
| Insert / update / delete rows (bound parameters) | ✅ |
| Schema snapshot + batch columns/FKs (ER diagram) | ✅ |
| `CREATE TABLE` SQL, add column, create/drop index | ✅ |
| Schemas, stored routines | ❌ (not a SQLite concept) |
| Alter column type, add/drop foreign key on existing table | ❌ (SQLite limitation — returns a clear error) |
| Schemas, stored routines | ❌ (not a SQLite concept — Turso has no stored procedures, and its multi-database model is separate databases, not schemas) |
| Rename column | ✅ everywhere (vanilla `RENAME COLUMN`) |
| Alter column type / default | ✅ remote Turso/sqld (libSQL `ALTER COLUMN` extension) / ⚠️ local files — the host calls the SQL builder without connection params, so the libSQL statement is generated unconditionally and local SQLite rejects it with its own parse error when the host runs it |
| Drop foreign key on existing table | ✅ remote Turso/sqld (has connection params) / ❌ local (clear error) |
| Add foreign key to existing table | ❌ (protocol limitation — see below) |

Identifiers are quoted ANSI-style (`"name"`). Booleans are stored as `0`/`1` and
BLOBs are returned base64-encoded.

### Turso-only schema changes

Remote Turso / sqld servers run the **libSQL fork** of SQLite, which adds
`ALTER TABLE ... ALTER COLUMN col TO col <type> [DEFAULT ...] [REFERENCES ...]`.
The plugin uses it to:

- change a column's type (and optionally its DEFAULT / NOT NULL),
- drop a foreign key from an existing column (the same statement without the
`REFERENCES` clause).

Local SQLite files cannot retype columns or touch existing foreign keys. The
driver reports a clear error for foreign-key drops; note that libSQL applies
constraint changes to newly inserted/updated rows only — existing rows are not
rewritten or revalidated — and foreign key *enforcement* requires
`PRAGMA foreign_keys=ON`.

> **Why "add foreign key to existing table" is unavailable:** the host calls
> the SQL preview builders with *no connection params*, and the libSQL
> `ALTER COLUMN` rewrite replaces the column's whole definition — so building
> the statement requires the column's declared type, which the host does not
> send (only its name) and the plugin has no connection to look up. The
> `.tabularium` capability is `create_foreign_keys: false`, so Tabularis hides
> the add-FK dialog. Define foreign keys in the `CREATE TABLE` statement
> instead. Dropping a foreign key does receive connection params and works on
> remote Turso/sqld.

## Build & test

Requires a Rust toolchain (and a C compiler for the bundled SQLite).
Expand Down Expand Up @@ -86,11 +115,16 @@ echo '{"jsonrpc":"2.0","method":"get_tables","params":{"params":{"database":"/tm
## Installing

`just dev-install` copies `libsql-plugin` and `.tabularium` into the Tabularis
plugins folder:
plugins folder (the location Tabularis actually scans — derived from
`ProjectDirs::from("com", "debba", "tabularis")`):

- **Linux:** `~/.local/share/tabularis/plugins/libsql/`
- **macOS:** `~/Library/Application Support/tabularis/plugins/libsql/`
- **Windows:** `%APPDATA%\tabularis\plugins\libsql\`
- **macOS:** `~/Library/Application Support/com.debba.tabularis/plugins/libsql/`
- **Windows:** `%APPDATA%\debba\tabularis\data\plugins\libsql\`

Note: the plugin guide's plain `%APPDATA%\tabularis\plugins` / macOS
`tabularis/plugins` paths are wrong — that folder holds app config, not
plugins; Tabularis scans the ProjectDirs path above.

Restart Tabularis (or toggle the plugin in Settings) and **libSQL** appears in
the Database Type list.
Expand Down
7 changes: 1 addition & 6 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,7 @@ dev-install: build

[windows]
dev-install: build
$dest = Join-Path $env:APPDATA "tabularis\plugins\libsql"
New-Item -ItemType Directory -Force -Path $dest | Out-Null
Copy-Item "target\debug\libsql-plugin.exe" $dest
Copy-Item ".tabularium" $dest
Write-Host "Installed to $dest"
Write-Host "Restart Tabularis (or toggle the plugin in Settings) to pick up changes."
$dest = Join-Path $env:APPDATA "tabularis\plugins\libsql"; New-Item -ItemType Directory -Force -Path $dest | Out-Null; Copy-Item "target\debug\libsql-plugin.exe" $dest; Copy-Item ".tabularium" $dest; Write-Host "Installed to $dest"; Write-Host "Restart Tabularis (or toggle the plugin in Settings) to pick up changes."

[linux]
uninstall:
Expand Down
Loading