use std::collections::HashMap;
use std::fs;
use std::path::{PathBuf};
use json::{JsonValue, object};
#[derive(Clone, Debug)]
pub struct Config {
pub default: String,
pub connections: HashMap<String, Connection>,
}
impl Config {
pub fn default() -> Config {
let mut connections = HashMap::new();
connections.insert("mydbname".to_string(), Connection::default());
Self {
default: "mydbname".to_string(),
connections,
}
}
pub fn json(&mut self) -> JsonValue {
let mut data = object! {};
data["default"] = self.default.clone().into();
let mut connections = object! {};
for (name, connection) in self.connections.iter_mut() {
connections[name.clone()] = connection.json().clone();
}
data["connections"] = connections;
data
}
pub fn from(data: JsonValue) -> Config {
let default = data["default"].to_string();
let mut connections = HashMap::new();
for (key, value) in data["connections"].entries() {
let connection = Connection::default().from(value.clone()).clone();
connections.insert(key.to_string(), connection.clone());
}
Self {
default,
connections,
}
}
pub fn create(path: &str) -> JsonValue {
let config = Config::default().json();
let path_buf = PathBuf::from(path);
fs::create_dir_all(path.trim_end_matches(path_buf.file_name().unwrap().to_str().unwrap())).unwrap();
fs::write(path, config.to_string()).unwrap();
config
}
}
#[derive(Clone, Debug)]
pub enum Mode {
Mysql,
Mssql,
Sqlite,
None,
}
impl Mode {
pub fn str(&mut self) -> &'static str {
match self {
Mode::Mysql => "mysql",
Mode::Sqlite => "sqlite",
Mode::Mssql => "mssql",
Mode::None => ""
}
}
pub fn from(name: &str) -> Self {
match name {
"mysql" => Mode::Mysql,
"sqlite" => Mode::Sqlite,
"mssql" => Mode::Mssql,
_ => Mode::None
}
}
}
#[derive(Clone, Debug)]
pub struct Connection {
pub mode: Mode,
pub hostname: String,
pub hostport: String,
pub database: String,
pub username: String,
pub userpass: String,
pub params: Vec<String>,
pub charset: Charset,
pub prefix: String,
pub debug: bool,
pub backup_time: String,
pub backup_path: PathBuf,
pub backup_number: u8,
}
impl Connection {
pub fn default() -> Connection {
Self {
mode: Mode::Sqlite,
hostname: "".to_string(),
hostport: "".to_string(),
database: "".to_string(),
username: "".to_string(),
userpass: "".to_string(),
params: vec![],
charset: Charset::Utf8mb4,
prefix: "".to_string(),
debug: false,
backup_time: "".to_string(),
backup_path: Default::default(),
backup_number: 0,
}
}
pub fn json(&mut self) -> JsonValue {
object! {
mode: self.mode.str(),
hostname: self.hostname.clone(),
hostport: self.hostport.clone(),
database: self.database.clone(),
username: self.username.clone(),
userpass:self.userpass.clone(),
params: self.params.clone(),
charset: self.charset.str(),
prefix: self.prefix.clone(),
debug: self.debug.clone(),
backup_time: self.backup_time.to_string(),
backup_path: self.backup_path.as_path().to_str().unwrap(),
backup_number: self.backup_number,
}
}
pub fn from(&mut self, data: JsonValue) -> &mut Connection {
self.mode = Mode::from(data["mode"].as_str().unwrap());
self.hostname = data["hostname"].to_string();
self.hostport = data["hostport"].to_string();
self.database = data["database"].to_string();
self.username = data["username"].to_string();
self.userpass = data["userpass"].to_string();
self.params = data["params"].members().map(|x| x.to_string()).collect();
self.charset = Charset::from(data["charset"].as_str().unwrap_or("utf8mb4"));
self.prefix = data["prefix"].as_str().unwrap_or("").to_string();
self.debug = data["debug"].to_string().parse::<bool>().unwrap_or(false).into();
self.backup_time = data["backup_time"].to_string().into();
self.backup_path = PathBuf::from(data["backup_path"].to_string());
self.backup_number = data["backup_number"].to_string().parse::<u8>().unwrap_or(0).into();
self
}
pub fn get_dsn(self) -> String {
match self.mode {
Mode::Mysql => {
format!("mysql://{}:{}@{}:{}/{}", self.username, self.userpass, self.hostname, self.hostport, self.database)
}
Mode::Sqlite => {
let db_path = self.database.as_str();
let path_buf = PathBuf::from(db_path);
if !path_buf.is_file() && path_buf.file_name().is_some() {
fs::create_dir_all(db_path.trim_end_matches(path_buf.file_name().unwrap().to_str().unwrap())).unwrap();
}
format!("{}", path_buf.to_str().unwrap())
}
Mode::Mssql => format!("sqlsrv://{}:{}@{}:{}/{}", self.username, self.userpass, self.hostname, self.hostport, self.database),
Mode::None => "".to_string()
}
}
}
#[derive(Clone, Debug)]
pub enum Charset {
Utf8mb4,
Utf8,
None,
}
impl Charset {
pub fn from(str: &str) -> Charset {
match str {
"utf8" => Charset::Utf8,
"utf8mb4" => Charset::Utf8mb4,
_ => Charset::None
}
}
pub fn str(&mut self) -> &'static str {
match self {
Charset::Utf8 => "utf8",
Charset::Utf8mb4 => "utf8mb4",
Charset::None => ""
}
}
}