Expand description
Schema versioning and migration support for SqliteTaskStore.
This module provides a lightweight, forward-only migration runner that tracks
applied schema versions in a schema_versions table. Migrations are defined
as plain SQL strings and are executed inside transactions for atomicity.
§Concurrency
Each migration runs inside a BEGIN EXCLUSIVE transaction, which acquires
a database-level write lock before reading. This prevents concurrent
migration runners from both seeing the same version as unapplied and
attempting to apply it simultaneously.
§Built-in migrations
| Version | Description |
|---|---|
| 1 | Initial schema — tasks table with indexes on context_id and state |
| 2 | Add created_at column to tasks table |
| 3 | Add composite index on (context_id, state) for combined filter queries |
| 4 | Add (updated_at DESC, id DESC) index for list ordering |
| 5 | Add task_artifact_appends — the journal streaming appends are written to |
| 6 | Add idempotency_keys — the index client-supplied send keys are claimed in |
| 7 | Add task_events — the per-task log of what the agent emitted |
This table listed 1 to 3 while seven existed — the failure mode of a list maintained by hand beside one maintained by the compiler. The test below fails if the two stop agreeing on how many there are.
SQLite’s ALTER TABLE has no ADD CONSTRAINT, so a CHECK in a table’s
DDL reaches only databases built after it. task_events gained
CHECK (seq > 0) in 0.13 and migration 7 carries it — that migration
creates the table, sharing the constant with from_pool — but a database
that already ran migration 7 keeps the unconstrained table. Correcting it
means a full table rebuild for a constraint on values this crate does not
write. pg_migration’s version 6 does it on PostgreSQL, which has
ALTER TABLE ... ADD CONSTRAINT.
§Example
use a2a_protocol_server::store::migration::MigrationRunner;
use sqlx::sqlite::SqlitePoolOptions;
let pool = SqlitePoolOptions::new()
.connect("sqlite:tasks.db")
.await?;
let runner = MigrationRunner::new(pool);
let applied = runner.run_pending().await?;
println!("Applied migrations: {applied:?}");Structs§
- Migration
- A single schema migration.
- Migration
Runner - Runs schema migrations against a
SQLitedatabase.
Statics§
- BUILTIN_
MIGRATIONS - Built-in migrations for the
SqliteTaskStoreschema.