use crate::postgres::PostgresSnapshot;
use crate::sqlite::SQLiteSnapshot;
use drizzle_types::Dialect;
#[derive(Clone, Debug)]
pub enum Snapshot {
Sqlite(SQLiteSnapshot),
Postgres(PostgresSnapshot),
}
impl Snapshot {
#[must_use]
pub const fn dialect(&self) -> Dialect {
match self {
Self::Sqlite(_) => Dialect::SQLite,
Self::Postgres(_) => Dialect::PostgreSQL,
}
}
pub fn save(&self, path: &std::path::Path) -> std::io::Result<()> {
match self {
Self::Sqlite(s) => s.save(path),
Self::Postgres(s) => s.save(path),
}
}
pub fn load(path: &std::path::Path, dialect: Dialect) -> std::io::Result<Self> {
match dialect {
Dialect::SQLite => Ok(Self::Sqlite(SQLiteSnapshot::load(path)?)),
Dialect::PostgreSQL => Ok(Self::Postgres(PostgresSnapshot::load(path)?)),
Dialect::MySQL => Err(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"MySQL snapshots not yet supported",
)),
}
}
#[must_use]
pub fn empty(dialect: Dialect) -> Self {
match dialect {
Dialect::SQLite => Self::Sqlite(SQLiteSnapshot::new()),
Dialect::PostgreSQL => Self::Postgres(PostgresSnapshot::new()),
Dialect::MySQL => {
panic!("MySQL not yet supported")
}
}
}
#[must_use]
pub const fn is_empty(&self) -> bool {
match self {
Self::Sqlite(s) => s.is_empty(),
Self::Postgres(s) => s.ddl.is_empty(),
}
}
#[must_use]
pub fn id(&self) -> &str {
match self {
Self::Sqlite(s) => &s.id,
Self::Postgres(s) => &s.id,
}
}
#[must_use]
pub fn prev_ids(&self) -> &[String] {
match self {
Self::Sqlite(s) => &s.prev_ids,
Self::Postgres(s) => &s.prev_ids,
}
}
pub fn set_prev_ids(&mut self, prev_ids: Vec<String>) {
match self {
Self::Sqlite(s) => s.prev_ids = prev_ids,
Self::Postgres(s) => s.prev_ids = prev_ids,
}
}
#[must_use]
pub const fn as_sqlite(&self) -> Option<&SQLiteSnapshot> {
match self {
Self::Sqlite(s) => Some(s),
Self::Postgres(_) => None,
}
}
#[must_use]
pub const fn as_postgres(&self) -> Option<&PostgresSnapshot> {
match self {
Self::Postgres(s) => Some(s),
Self::Sqlite(_) => None,
}
}
}
pub trait Schema: Default + Sized {
fn dialect(&self) -> Dialect;
fn to_snapshot(&self) -> Snapshot;
fn schema_name(&self) -> Option<&'static str> {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty_snapshot_sqlite() {
let snapshot = Snapshot::empty(Dialect::SQLite);
assert!(snapshot.is_empty());
assert_eq!(snapshot.dialect(), Dialect::SQLite);
}
#[test]
fn test_empty_snapshot_postgres() {
let snapshot = Snapshot::empty(Dialect::PostgreSQL);
assert!(snapshot.is_empty());
assert_eq!(snapshot.dialect(), Dialect::PostgreSQL);
}
}