database-schema 0.2.0

A library to dump a database schema into a file in SQL format
Documentation
//! Implementation of the `sqlite` feature for the `sqlx` backend

pub(crate) const DEFAULT_CONNECTION_URL: &str = "sqlite::memory:";

pub(crate) async fn fetch_structure_sql<P: AsRef<std::path::Path>>(
    connection_url: &str,
    migrations_path: P,
) -> Result<String, sqlx::Error> {
    use sqlx::{migrate::Migrator, sqlite::SqliteConnectOptions, ConnectOptions};
    use std::str::FromStr;

    let mut conn = SqliteConnectOptions::from_str(connection_url)?
        .connect()
        .await?;

    let migrator = Migrator::new(migrations_path.as_ref()).await?;
    migrator.run(&mut conn).await?;
    fetch_structure(&mut conn).await
}

async fn fetch_structure(conn: &mut sqlx::sqlite::SqliteConnection) -> Result<String, sqlx::Error> {
    use sqlx::Row;
    let structure_dump = sqlx::query(super::SQLITE_SCHEMA_QUERY)
        .fetch_all(conn)
        .await?
        .iter()
        .map(|row| {
            let name = row.get::<String, _>(0);
            let r#type = row.get::<String, _>(1);
            let sql = row.get::<String, _>(2);
            format!("--\n--  Name: {name}; Type: {type}\n--\n{sql};\n")
        })
        .collect::<Vec<String>>()
        .join("\n");
    Ok(structure_dump)
}

#[cfg(test)]
mod tests {
    #[cfg(all(feature = "sqlx", feature = "sqlite"))]
    #[tokio::test]
    async fn test_fetch_structure_sql() -> Result<(), crate::error::Error> {
        let migrations_path = std::path::PathBuf::from("./fixtures/sqlx/sqlite/migrations");
        let structure =
            super::fetch_structure_sql(super::DEFAULT_CONNECTION_URL, migrations_path).await?;
        assert!(structure.contains("--\n--  Name: _sqlx_migrations; Type: table\n--\nCREATE TABLE _sqlx_migrations (\n    version BIGINT PRIMARY KEY,\n    description TEXT NOT NULL,\n    installed_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    success BOOLEAN NOT NULL,\n    checksum BLOB NOT NULL,\n    execution_time BIGINT NOT NULL\n);\n\n--\n--  Name: users; Type: table\n--\nCREATE TABLE users (\n  id TEXT PRIMARY KEY NOT NULL,\n  email TEXT NOT NULL,\n  created_at TEXT NOT NULL DEFAULT(datetime('now', 'utc'))\n);\n"));
        Ok(())
    }
}