# Backup and restore
Based on the [sqlite serialize](https://github.com/launchbadge/sqlx/tree/main/examples/sqlite/serialize) example.
Show how we can serialized (and save to disk) the content of the database
and then how we can restore the data from the serialized dump.
## Dependencies
Apparently this feature is not in the release version yet.
```
cargo add --git https://github.com/launchbadge/sqlx sqlx -F sqlite-deserialize -F sqlite -F runtime-tokio
```
[package]
name = "xserialize"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0.58"
sqlx = { git = "https://github.com/launchbadge/sqlx", version = "0.9.0-alpha.1", features = ["runtime-tokio", "sqlite", "sqlite-deserialize"] }
#sqlx = { version = "0.8.6", features = ["sqlite", "sqlite-deserialize", "runtime-tokio"] }
tokio = { version = "1.25.0", features = ["rt", "macros"] }
use sqlx::sqlite::SqliteOwnedBuf;
use sqlx::{Connection, SqliteConnection};
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
let command = get_command();
if command == "create" {
create().await?;
} else if command == "restore" {
restore().await?;
}
Ok(())
}
async fn create() -> anyhow::Result<()> {
let mut conn = SqliteConnection::connect("sqlite::memory:").await?;
sqlx::raw_sql(
"CREATE TABLE notes(id INTEGER PRIMARY KEY, body TEXT NOT NULL);
INSERT INTO notes(body) VALUES ('hello'), ('world');",
)
.execute(&mut conn)
.await?;
let snapshot: SqliteOwnedBuf = conn.serialize(None).await?;
let bytes: &[u8] = snapshot.as_ref();
std::fs::write("snapshot.db", bytes)?;
conn.close().await?;
Ok(())
}
async fn restore() -> anyhow::Result<()> {
let bytes = std::fs::read("snapshot.db")?;
let owned = SqliteOwnedBuf::try_from(bytes.as_slice())?;
let mut restored = SqliteConnection::connect("sqlite::memory:").await?;
restored.deserialize(None, owned, false).await?;
let rows = sqlx::query_as::<_, (i64, String)>("select id, body from notes order by id")
.fetch_all(&mut restored)
.await?;
assert_eq!(rows.len(), 2);
assert_eq!(rows[0].1, "hello");
assert_eq!(rows[1].1, "world");
Ok(())
}
fn get_command() -> String {
let args = std::env::args().collect::<Vec<_>>();
if args.len() != 2 {
eprintln!("Usage: {} [create|restore]", args[0]);
std::process::exit(1);
}
let command = &args[1];
if command != "create" && command != "restore" {
eprintln!("Invalid command: {}", command);
eprintln!("Usage: {} [create|restore]", args[0]);
std::process::exit(1);
}
command.to_string()
}