use crate::map_schema::{Column, Table, Schema, Database, Root};
use tokio::sync::Mutex;
pub use crate::config::ConfigClient;
use crate::client_builder::ClientBuilder;
use mssql_client::{Client, Config, Ready};
use anyhow::{Ok, Result};
const SCHEMA: &str =include_str!("../querys/sql_schema.sql");
pub struct ClientSql{
client:Mutex<Client<Ready>>,
}
impl ClientSql {
pub async fn new<'a>(cfg: &ConfigClient<'a>)->Result<Self>{
let connect =format!("Server={};User Id={};Password={};TrustServerCertificate=true", cfg.host, cfg.user, cfg.password);
let config= Config::from_connection_string(&connect)?;
let client=Client::connect(config).await?;
Ok(Self{client: Mutex::new(client),})
}
pub fn builder<'a>() -> ClientBuilder<'a> {
ClientBuilder::new()
}
pub async fn get_schema(&self)->Result<Root>{
let mut client = self.client.lock().await;
let rows=client.query(SCHEMA, &[]).await?;
let mut root = Root{
databases:std::collections::BTreeMap::new(),
};
for result in rows{
let row= result?;
let db: String= row.get(0)?;
let schema_name: String= row.get(1)?;
let table_name: String= row.get(2)?;
let column=Column{
name:row.get(3)?,
data_type:row.get(4)?,
};
let database=root.databases.entry(db).or_insert(Database { schemas: std::collections::BTreeMap::new(), });
let schema = database.schemas.entry(schema_name).or_insert(Schema { tables: std::collections::BTreeMap::new(), });
let table = schema.tables.entry(table_name).or_insert(Table { coluns: Vec::new(), });
table.coluns.push(column);
}
let toml = toml::to_string_pretty(&root)?;
std::fs::write("schema.toml", toml)?;
Ok(root)
}
}