Repository navigation
Implement remote libSQL DDL support and refactor DDL builders - #4
Conversation
Enable `ALTER COLUMN` and foreign key mutations for remote Turso/sqld connections using the libSQL fork. Local SQLite connections continue to return a clear unsupported error. - Add `is_remote` check to `Client` to gate libSQL-specific features - Implement `get_alter_column_sql`, `get_create_foreign_key_sql`, and `drop_foreign_key` for remote backends - Update `.tabularium` capabilities for `alter_column` and `create_foreign_keys` - Update README and metadata handlers to align with host contracts - Ensure DDL responses return arrays of SQL strings
Refactor `src/handlers/ddl.rs` to implement SQL builders as pure functions that do not require database connections. Disable `create_foreign_keys` in `.tabularium` and return an unsupported error in `get_create_foreign_key_sql`, as the host protocol does not provide the column type necessary for libSQL's `ALTER COLUMN` rewrite. Update README and internal documentation to clarify the distinction between remote libSQL extensions and vanilla SQLite limitations.
Rename `is_primary_key` to `is_pk` and `column_default` to `default_value`, and remove the unused `comment` field. Add a test to verify the contract keys.
`create_foreign_keys` capability in `.tabularium`. Update the `get_create_foreign_key_sql` handler to receive and use connection params, and emit the libSQL `ALTER COLUMN` form. Add tests for the new foreign key builder and local unsupported error.
`resolve_backend` logic to use the raw URI when available, allowing it to be authoritative over decomposed host and password fields. Add tests covering `connection_uri` precedence, URL vs. local backend resolution, and token preservation. Update `.tabularium` capabilities to support `connection_uri` and `connection_uri_schemes`.
code to use the embedded libSQL fork instead of the rusqlite driver.
Changes:
- `Cargo.toml`: replace `rusqlite` with `libsql = { version = "0.9",
default-features = false, features = ["core"] }`, add `futures`,
update description to mention the fork, `core` feature, async/sync
bridge
- `src/client.rs`: switch to `libsql::Connection` and `libsql::Value`,
adapt all local connections, `open_local`, `local_query`,
`json_to_libsql`, `libsql_value_to_json`, and rename `is_remote`
comment
- `src/error.rs`: change `From<rusqlite::Error>` to
`From<libsql::Error>`
- `src/handlers/ddl.rs`: remove `require_remote` (local works through
fork), update docs for `get_create_foreign_key_sql`,
`drop_foreign_key`, and `drop_index`, update
`get_create_foreign_key_sql` test to use temp file
- `src/handlers/metadata.rs`: adjust formatting of a wrapped `connect`
call
- `src/rpc.rs`: rename test to describe local fork working through
`get_create_foreign_key_sql`
- `src/utils/values.rs`: update comment to say libsql (local) instead of
rusqlite (local)
@debba one thing I haven't included here is a fix to the justfile for the windows dev-install script but also for the other OS installation locations.
|
Review — PR #4Overall the PR is solid on the host-contract side (payload shapes, metadata key renames, URI scheme passthrough were all checked against the Confirmed bugs (should be fixed before merge)1. 2. FK add/drop strips 3. Dropping a composite FK reports success while doing nothing — 4. Changing a column's type/default/nullability destroys its existing FK — 5. Simultaneous rename + retype silently discards the retype —
Manifest icon doesn't resolve anywhere
Other findings
|
Thanks for this, it was a real issue, but I merged this TabularisDB/tabularis#258 in latest release, so probably won't work now :D |
Receipt - src/client.rs: 285-315 - platform-aware file: strip; Unix keeps / root, Windows keeps drive form. - src/client.rs:415-473 - strip unit tests + platform-split file-URI backend tests. - src/handlers/ddl.rs: 185-209 - get_alter_column_sql optional schema path when params present; pure builder fallback. - src/handlers/ddl.rs: 211-389 - ColumnRewrite merge old+new defs; rename+retype emits both statements; schema path preserves REFERENCES/ON UPDATE/DELETE. - src/handlers/ddl.rs: 393-500 - FK add/drop carry NOT NULL + DEFAULT via ColumnDef/column_def_sql. - src/handlers/ddl.rs:506-573 - composite FK drop returns error (fork has no DROP CONSTRAINT, per libsql docs); no more silent no-op. - src/handlers/ddl.rs tests - 12 new/updated (89 total pass).
Header scan stops at BEGIN; body keywords (e.g. audit trigger INSERTing into a log) no longer override the event.
Local files run the embedded libSQL fork, so retype, FK add/drop and constraint-preserving rewrites work everywhere; README previously claimed they were Turso-only.
|
@debba Addressed all feedback items.
Made the change but goal unmet. cargo tree -i futures shows libsql core feature hard-requires dep:futures (core = [..., "dep:futures", ...] in libsql 0.9.30). Facade still compiles; futures-executor was already in tree via libsql's facade. Swap = dependency accuracy only (we use one symbol, not the facade), no compile-time or tree savings. |
Fixed: Update installation paths |
|
@jonaspm You’re right, thanks for verifying it. Since |
|
Merging 🎉 |


Summary
Implements remote DDL support (ALTER COLUMN, foreign key mutations) for Turso/sqld connections via the libSQL fork, rewrites the client to use the embedded libSQL fork of SQLite (replacing the rusqlite driver), and lands a round of contract fixes to match the host's RpcDriver expectations.
Changes
libsqlcrate (corefeature, bundled) instead of rusqlite, so fork extensions (ALTER COLUMN, FK add/drop) work on local files and remote servers alike. No async runtime: bridged withfutures::executor::block_on.get_alter_column_sql,get_create_foreign_key_sql,drop_foreign_keynow work against remote backends, gated by a newis_remotecheck onClient(src/client.rs). The FK builder emits the libSQLALTER COLUMN col TO col <type> REFERENCES ...form, introspecting the column type viaPRAGMA table_info(host now passes connection params through for this method).src/handlers/ddl.rsrewritten as pure functions that don't require a connection; DDL responses consistently return arrays of SQL strings.is_primary_key→is_pk,column_default→default_value; unusedcommentfield removed. Test added to pin the contract keys.connection_urisupport — newConnectionParams.connection_urifield;resolve_backendnow treats the raw URI as authoritative over decomposed host/password fields, preserving auth tokens..tabulariumadvertisesconnection_uri/connection_uri_schemes. Tests cover precedence, backend resolution, and token preservation.get_triggersRPC method — new handler, enabled with the other metadata changes.null..tabulariumcapabilities —alter_column: true,create_foreign_keys: truekept in sync with actual behavior.Testing
cargo test(unit tests incl. new FK builder, local unsupported error, contract keys, connection URI resolution)cargo clippy --all-targets -- -D warningscargo fmt --all