use crate::errors::{Result, WeldsError};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use welds::Syntax;
mod table;
pub use table::Table;
mod column;
pub use column::Column;
pub(crate) fn read(path: &PathBuf) -> Result<Config> {
let yaml_str =
std::fs::read_to_string(path).map_err(|_| WeldsError::ReadError(path.clone()))?;
let config: std::result::Result<Config, serde_yaml::Error> = serde_yaml::from_str(&yaml_str);
match config {
Err(_err) => Err(WeldsError::ConfigReadError(path.clone())),
Ok(config) => Ok(config),
}
}
pub(crate) fn write(path: &PathBuf, config: &Config) -> Result<()> {
let yaml = serde_yaml::to_string(config).map_err(|_| WeldsError::ConfigWrite)?;
std::fs::write(path, yaml.as_bytes())?;
Ok(())
}
#[derive(Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct Config {
pub tables: Vec<Table>,
}
impl Config {
pub(crate) fn remove_missing(&mut self, tables: &[welds::detect::TableDef]) {
let idents: Vec<_> = tables.iter().map(|x| x.ident()).collect();
self.tables
.retain(|x| x.manual_update || idents.contains(&&x.ident()));
}
pub(crate) fn add_update(&mut self, provider: DbProvider, tables: &[welds::detect::TableDef]) {
let mut to_add = Vec::default();
for t in tables {
let existing = self.tables.iter_mut().find(|x| &x.ident() == t.ident());
match existing {
Some(existing) => existing.update_from(t, provider),
None => to_add.push(Table::new(t, provider)),
}
}
self.tables.append(&mut to_add);
}
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Relation {
pub schema: Option<String>, pub tablename: String, pub foreign_key: String, }
impl From<&welds::detect::RelationDef> for Relation {
fn from(value: &welds::detect::RelationDef) -> Self {
Relation {
schema: value.other_table().schema().map(|x| x.to_owned()),
tablename: value.other_table().name().to_owned(),
foreign_key: value.foreign_key().to_owned(),
}
}
}
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize, Clone, Copy)]
pub enum DbProvider {
Postgres,
Mysql,
Mssql,
Sqlite,
}
impl From<Syntax> for DbProvider {
fn from(syntax: Syntax) -> Self {
match syntax {
Syntax::Mysql => DbProvider::Mysql,
Syntax::Postgres => DbProvider::Postgres,
Syntax::Mssql => DbProvider::Mssql,
Syntax::Sqlite => DbProvider::Sqlite,
}
}
}
impl From<DbProvider> for Syntax {
fn from(provider: DbProvider) -> Syntax {
match provider {
DbProvider::Mysql => Syntax::Mysql,
DbProvider::Postgres => Syntax::Postgres,
DbProvider::Mssql => Syntax::Mssql,
DbProvider::Sqlite => Syntax::Sqlite,
}
}
}