use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::errors::Result;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SchemaSnapshot {
pub version_hash: String,
pub created_at: String,
pub tables: HashMap<String, TableSnapshot>,
pub views: HashMap<String, ViewSnapshot>,
pub functions: HashMap<String, FunctionSnapshot>,
pub types: HashMap<String, TypeSnapshot>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TableSnapshot {
pub name: String,
pub columns: Vec<ColumnSnapshot>,
pub primary_key: Option<PrimaryKeySnapshot>,
pub foreign_keys: Vec<ForeignKeySnapshot>,
pub unique_constraints: Vec<UniqueConstraintSnapshot>,
pub indexes: Vec<IndexSnapshot>,
pub check_constraints: Vec<CheckConstraintSnapshot>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ColumnSnapshot {
pub name: String,
pub data_type: String,
pub nullable: bool,
pub default_value: Option<String>,
pub auto_increment: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PrimaryKeySnapshot {
pub name: String,
pub columns: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ForeignKeySnapshot {
pub name: String,
pub columns: Vec<String>,
pub referenced_table: String,
pub referenced_columns: Vec<String>,
pub on_delete: Option<String>,
pub on_update: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct UniqueConstraintSnapshot {
pub name: String,
pub columns: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct IndexSnapshot {
pub name: String,
pub columns: Vec<String>,
pub unique: bool,
pub index_type: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CheckConstraintSnapshot {
pub name: String,
pub expression: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ViewSnapshot {
pub name: String,
pub definition: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FunctionSnapshot {
pub name: String,
pub signature: String,
pub body: String,
pub return_type: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TypeSnapshot {
pub name: String,
pub kind: String,
pub definition: String,
}
#[async_trait]
pub trait SnapshotStore: Send + Sync {
async fn store(&self, tenant: &crate::cli::TenantContext, snapshot: &SchemaSnapshot) -> Result<()>;
async fn get_latest(&self, tenant: &crate::cli::TenantContext) -> Result<Option<SchemaSnapshot>>;
async fn get_by_hash(
&self,
tenant: &crate::cli::TenantContext,
version_hash: &str,
) -> Result<Option<SchemaSnapshot>>;
async fn list(&self, tenant: &crate::cli::TenantContext) -> Result<Vec<SchemaSnapshot>>;
async fn compare(
&self,
tenant: &crate::cli::TenantContext,
hash_a: &str,
hash_b: &str,
) -> Result<crate::diff::SchemaDiff>;
}
pub fn calculate_version_hash(snapshot: &SchemaSnapshot) -> String {
format!("hash_{}", snapshot.tables.len())
}