Add async driver for Turso behind turso feature#424
Closed
dahankzter wants to merge 3 commits intorust-db:mainfrom
Closed
Add async driver for Turso behind turso feature#424dahankzter wants to merge 3 commits intorust-db:mainfrom
turso feature#424dahankzter wants to merge 3 commits intorust-db:mainfrom
Conversation
Turso is a pure-Rust SQLite rewrite with its own async parser/executor, wire-compatible with SQLite on disk but not always with rusqlite at runtime (e.g. Turso's internal FTS tables use a `CREATE INDEX ... USING fts` form that rusqlite's parser rejects). This driver implements `AsyncTransaction` and `AsyncQuery<Vec<Migration>>` for `turso::Connection` and is gated behind a new `turso` feature on both `refinery-core` and `refinery`. Transactions are driven via string- based `BEGIN IMMEDIATE` / `COMMIT` / `ROLLBACK` since the 0.6.0-pre series does not expose `Connection::transaction()`, and migration bodies are dispatched through `execute_batch` so Turso's own tokenizer handles multi-statement files and embedded-semicolon comments. Integration tests mirror the tokio-postgres layout and include regressions for two classic hand-rolled-runner bugs that refinery's driver-delegated splitting prevents: a leading `--` comment line preceding a statement, and a `;` inside a comment body.
- Mark the turso module doc example as \`ignore\` — it references \`refinery::embed_migrations\`, which \`refinery-core\` cannot import (circular dep), so it was failing the doctest run. - Add a narrowly-scoped exception in deny.toml for \`libloading\`'s ISC license, which is pulled in transitively by the turso feature through antithesis_sdk / clang-sys / turso_core. ISC is OSI-approved and functionally equivalent to MIT for redistribution; the workspace-wide allow list is intentionally unchanged.
Member
|
Hi, this is a duplicate, see #415 (comment) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add async driver for Turso
This adds a
tursofeature torefinery-core/refinerythat implementsAsyncTransactionandAsyncQuery<Vec<Migration>>forturso::Connection, so refinery can drivemigrations against Turso databases.
Why a dedicated driver (not
rusqlitereuse)Turso is wire-compatible with SQLite on disk but ships its own parser and
executor. In particular, Turso's internal FTS tables are created with a
CREATE INDEX ... USING ftsform that rusqlite's parser rejects when aconsumer later opens the same file through rusqlite. Giving Turso users a
first-class driver — that speaks Turso's own API end-to-end — avoids that
class of cross-parser surprise.
What's in the PR
refinery_core/src/drivers/turso.rs—AsyncTransaction,AsyncQuery<Vec<Migration>>, blanketAsyncMigrateforturso::Connection, plus a thinErrornewtype wrappingturso::Error.refinery_core/src/drivers/mod.rsand re-export inrefinery_core/src/lib.rs.tursofeature + optional dep onrefinery-coreandrefinery.Version spec is intentionally a range (
">=0.6.0-pre.18, <0.7")because Turso is still in its 0.6 prerelease series and Cargo's
SemVer rules on prereleases mean a pinned
0.6.0-pre.Nwould lockconsumers out of newer pre-releases — the range lets downstream
users pick their own Turso.
refinery/tests/turso.rsmirroring therusqlite/tokio-postgres layout. 21 tests total — the full set of
tests/rusqlite.rsscenarios that are applicable to an async-onlydriver (sync-only
_itervariants and theConfig/CLI-wired testsare the only ones skipped, to keep this PR narrow). Includes two
regression tests for hand-rolled-runner bug classes that refinery's
driver-delegated batch execution naturally prevents: a leading
--comment line before a
CREATE TABLE, and a;inside a commentbody.
LIMBO_DISABLE_FILE_LOCK=1for multi-process scenarios — Tursotakes an exclusive file lock on
Builder::buildby default.Implementation notes
BEGIN IMMEDIATE/COMMIT/ROLLBACKstrings throughConnection::execute, because the0.6.0-pre line does not expose
Connection::transaction(). On afailed statement inside a batch,
ROLLBACKis fired best-effortbefore the original error is returned.
Connection::execute_batchso Turso's own tokenizer handlesstatement boundaries,
--comment lines, and;characters insidecomment bodies — refinery itself does no splitting.
spawn_blocking; mirrors thetokio_postgresdriver shape.
turso::Erroralready implsstd::error::Error + Send + Sync, so the in-crateErrortype is athin newtype (
"turso error: {source}"display,source()chains).Testing
All pass.
cargo buildwith the default feature set is unaffected.Note on
cargo clippy --all-targets:maincurrently has pre-existingunused import: barrel::backend::… as Sqlwarnings in every driver'sintegration-test file whenever the matching feature is disabled. This PR
inherits that pattern (so the warning on
turso.rswhen the feature isoff matches the one on
rusqlite.rswhenrusqliteis off). Happy toaddress that across drivers as a follow-up if you'd like.
Out of scope (deliberate)
Transaction/Queryimpl — Turso is async-only upstream.ConfigDbType/with_connection_async!/ CLI wiring — consumersconstruct a
turso::Connectionthemselves and pass it torun_async, same contract as the other async drivers.Builder::new_remote— kept the API surfaceminimal so the driver stays stable across the 0.6.0-pre series.