use pylon_core::schema::SchemaDescriptor;
use crate::error::{Error, Result};
pub(crate) async fn fetch(pool: &pylon_pgcon::PgPool) -> Result<SchemaDescriptor> {
let snapshot_json = pylon_core::migrate::read_schema_snapshot(pool)
.await
.map_err(|e| match e {
pylon_core::migrate::MigrateError::Db(e) => Error::Db(e),
other => {
unreachable!("read_schema_snapshot only ever fails on the database: {other}")
}
})?
.ok_or(Error::NoSchemaSnapshot)?;
Ok(serde_json::from_str(&snapshot_json)?)
}
#[cfg(test)]
mod tests {
use super::*;
fn test_dsn() -> String {
std::env::var("PYLON_PGCON_TEST_DSN").expect("PYLON_PGCON_TEST_DSN must be set to run live-Postgres tests")
}
async fn test_pool() -> pylon_pgcon::PgPool {
let pool = pylon_pgcon::PgPool::connect(&test_dsn(), 5).await.unwrap();
pool.batch_execute("CREATE SCHEMA IF NOT EXISTS _pylon").await.unwrap();
pylon_core::migrate::ensure_internal_schema(&pool).await.unwrap();
pool
}
#[tokio::test]
#[ignore = "requires a live Postgres via PYLON_PGCON_TEST_DSN"]
async fn fetches_a_valid_snapshot() {
let pool = test_pool().await;
let previous = pylon_core::migrate::read_schema_snapshot(&pool).await.unwrap();
let snapshot = serde_json::to_string(&SchemaDescriptor::default()).unwrap();
pylon_core::migrate::write_schema_snapshot(&pool, &snapshot)
.await
.unwrap();
assert!(fetch(&pool).await.is_ok());
match previous {
Some(prior) => pylon_core::migrate::write_schema_snapshot(&pool, &prior).await.unwrap(),
None => pool.batch_execute(r#"DELETE FROM _pylon."Schema""#).await.unwrap(),
}
}
#[tokio::test]
#[ignore = "requires a live Postgres via PYLON_PGCON_TEST_DSN"]
async fn missing_snapshot_is_a_clear_error() {
let pool = test_pool().await;
let previous = pylon_core::migrate::read_schema_snapshot(&pool).await.unwrap();
pool.batch_execute(r#"DELETE FROM _pylon."Schema""#).await.unwrap();
assert!(matches!(fetch(&pool).await, Err(Error::NoSchemaSnapshot)));
if let Some(prior) = previous {
pylon_core::migrate::write_schema_snapshot(&pool, &prior).await.unwrap();
}
}
}