use json::Null;
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::fs;
#[cfg(any(feature = "db-mysql", feature = "db-sqlite", feature = "db-mssql"))]
use std::process::Command;
use std::sync::{Mutex};
use std::vec;

use crate::config::{Config, Connection};
#[cfg(feature = "db-mssql")]
use crate::types::mssql::Mssql;
#[cfg(feature = "db-mysql")]
use crate::types::mysql::Mysql;
#[cfg(feature = "db-pgsql")]
use crate::types::pgsql::Pgsql;
#[cfg(feature = "db-sqlite")]
use crate::types::sqlite::Sqlite;
use crate::types::{DbMode, TableOptions};
use crate::types::{Mode};
use json::object;
use json::JsonValue;
use log::{error, info};

pub mod config;
pub mod pools;
pub mod types;
pub mod fields;

lazy_static! {
    pub static ref DB: Mutex<HashMap<String,Db>> =Mutex::new(HashMap::new());
    static ref CONNECTION: Mutex<HashMap<String,Connection>> =Mutex::new(HashMap::new());
    static ref DEFAULT: Mutex<HashMap<usize,String>> =Mutex::new(HashMap::new());
    static ref TABLE_FIELDS: Mutex<HashMap<String,JsonValue>> =Mutex::new(HashMap::new());
}
#[derive(Clone)]
pub enum Db {
    #[cfg(feature = "db-mysql")]
    Mysql(Mysql),
    #[cfg(feature = "db-sqlite")]
    Sqlite(Sqlite),
    #[cfg(feature = "db-mssql")]
    Mssql(Mssql),
    #[cfg(feature = "db-pgsql")]
    Pgsql(Pgsql),
    None,
}

impl Db {
    pub fn load(path: &str) -> Result<Db, String> {
        let conf = fs::read_to_string(path);
        let t = match conf {
            Ok(str) => match json::parse(str.as_str()) {
                Ok(config) => Db::new(Config::from(config))?,
                Err(_) => Db::new(Config::create(path.parse().unwrap(), false))?,
            },
            Err(_) => Db::new(Config::create(path.parse().unwrap(), false))?,
        };
        Ok(t)
    }
    pub fn new(config: Config) -> Result<Db, String> {
        let connection = match config.connections.get(&*config.default) {
            None => return Err(format!("无此配置: {}", config.default)),
            Some(e) => e,
        };
        for (name, conn) in config.connections.clone() {
            if CONNECTION.lock().unwrap().get(&name).is_none() {
                CONNECTION.lock().unwrap().insert(name, conn);
            }
        }
        DEFAULT.lock().unwrap().insert(0, config.default.clone());
        let db = Db::setlist(connection.clone(), config.default.clone());
        match db {
            Ok(db) => {
                DB.lock().unwrap().insert(config.default.clone(), db);
                let r = DB.lock().unwrap().get(&*config.default.clone()).unwrap().clone();
                Ok(r)
            }
            Err(e) => Err(e),
        }
    }

    fn setlist(mut connection: Connection, default: String) -> Result<Db, String> {
        match connection.mode.str().as_str() {
            #[cfg(feature = "db-mysql")]
            "mysql" => match Mysql::connect(connection.clone(), default.clone()) {
                Ok(e) => Ok(Db::Mysql(e)),
                Err(e) => Err(e),
            },
            #[cfg(feature = "db-sqlite")]
            "sqlite" => match Sqlite::connect(connection.clone(), default.clone()) {
                Ok(e) => Ok(Db::Sqlite(e)),
                Err(e) => Err(e),
            },
            #[cfg(feature = "db-mssql")]
            "mssql" => match Mssql::connect(connection.clone(), default.clone()) {
                Ok(e) => Ok(Db::Mssql(e)),
                Err(e) => Err(e),
            },
            #[cfg(feature = "db-pgsql")]
            "pgsql" => match Pgsql::connect(connection.clone(), default.clone()) {
                Ok(e) => Ok(Db::Pgsql(e)),
                Err(e) => Err(e),
            },
            _ => Err("未匹配数据库".to_string()),
        }
    }
    pub fn get_config_default(&mut self) -> String {
        let default = DEFAULT.lock().unwrap();
        let default = default.get(&0).unwrap();
        default.clone()
    }
    pub fn get_config_list(&mut self) -> Vec<String> {
        let connections = CONNECTION.lock().unwrap().iter().map(|x| {
            x.0.clone()
        }).collect::<Vec<String>>();
        connections
    }
    pub fn connection(&mut self, name: &str) -> Db {
        let default = DEFAULT.lock().unwrap();
        let default = default.get(&0).unwrap();
        let connections = CONNECTION.lock().unwrap().clone();
        let name = {
            if name.is_empty() {
                default
            } else {
                name
            }
        };

        let dbmode = DB.lock().unwrap().get(name).is_none();
        if !dbmode {
            let db = DB.lock().unwrap().get(name).unwrap().clone();
            return db;
        }
        let connection = connections.get(name).unwrap().clone();
        let db = match Db::setlist(connection.clone(), name.to_string().clone()) {
            Ok(e) => e,
            Err(_) => DB.lock().unwrap().get(name).unwrap().clone(),
        };
        DB.lock().unwrap().insert(name.parse().unwrap(), db.clone());
        db
    }
    /// 增加配置
    pub fn connection_add(&mut self, config_name: &str, connection: Connection) -> Db {
        let default = DEFAULT.lock().unwrap();
        let default = default.get(&0).unwrap();
        let mut connections = CONNECTION.lock().unwrap().clone();
        let name = {
            if config_name.is_empty() {
                default.clone()
            } else {
                config_name.to_string()
            }
        }.clone();
        let dbmode = DB.lock().unwrap().get(&*name.clone()).is_none();
        if !dbmode {
            let db = DB.lock().unwrap().get(&*name.clone()).unwrap().clone();
            return db;
        } else {
            CONNECTION.lock().unwrap().insert(name.clone().to_string(), connection.clone());
            connections.insert(name.clone().to_string(), connection.clone());
        }

        let connection = connections.get(&*name.clone()).unwrap().clone();
        let db = match Db::setlist(connection.clone(), name.clone()) {
            Ok(e) => e,
            Err(_) => {
                let db = DB.lock().unwrap().get(&*name.clone()).unwrap().clone();
                return db;
            }
        };
        DB.lock().unwrap().insert((*name.clone()).parse().unwrap(), db.clone());
        db
    }

    /// 具体功能
    pub fn table_create(&mut self, options: TableOptions) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.table_create(options),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.table_create(options),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(_) => JsonValue::from(false),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.table_create(options),
            _ => JsonValue::from(false),
        }
    }
    pub fn table_update(&mut self, options: TableOptions) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.table_update(options),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.table_update(options),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(_) => JsonValue::from(false),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.table_update(options),
            _ => JsonValue::from(false),
        }
    }
    pub fn table_info(&mut self, table: &str) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.table_info(table),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.table_info(table),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.table_info(table),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.table_info(table),
            _ => object! {},
        }
    }
    pub fn table_is_exist(&mut self, name: &str) -> bool {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.table_is_exist(name),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.table_is_exist(name),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.table_is_exist(name),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.table_is_exist(name),
            _ => false,
        }
    }
    pub fn table(&mut self, name: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.table(name);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.table(name);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.table(name);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.table(name);
            }
            _ => {}
        };
        self
    }

    pub fn change_table(&mut self, name: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.change_table(name);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.change_table(name);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.change_table(name);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.change_table(name);
            }
            _ => {}
        };
        self
    }

    pub fn autoinc(&mut self) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.autoinc();
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.autoinc();
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.autoinc();
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.autoinc();
            }
            _ => {}
        };
        self
    }

    pub fn fetch_sql(&mut self) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.fetch_sql();
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.fetch_sql();
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.fetch_sql();
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.fetch_sql();
            }
            _ => {}
        };
        self
    }
    /// 排序
    ///
    /// * field 排序字段
    /// * by 排序方法 true 降序 false 升序
    pub fn order(&mut self, field: &str, by: bool) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.order(field, by);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.order(field, by);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.order(field, by);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.order(field, by);
            }
            _ => {}
        }
        self
    }

    pub fn group(&mut self, field: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.group(field);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.group(field);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.group(field);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.group(field);
            }
            _ => {}
        }
        self
    }

    pub fn distinct(&mut self) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.distinct();
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.distinct();
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.distinct();
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.distinct();
            }
            _ => {}
        }
        self
    }

    pub fn json(&mut self, field: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.json(field);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.json(field);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.json(field);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.json(field);
            }
            _ => {}
        }
        self
    }
    /// 坐标系
    pub fn location(&mut self, field: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.location(field);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.location(field);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.location(field);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.location(field);
            }
            _ => {}
        }
        self
    }

    pub fn column(&mut self, field: &str) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.column(field),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.column(field),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.column(field),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.column(field),
            _ => object! {},
        }
    }

    pub fn where_and(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self {
        if field.contains("|") {
            let fields: Vec<&str> = field.split("|").collect();
            for field in fields.iter() {
                self.where_or(field.to_string().as_str(), compare, value.clone());
            }
            return self;
        }
        let compare = compare.to_lowercase();
        let compare = compare.replace(" ", "");
        let compare = compare.as_str();

        let value = match &value {
            JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
            JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
            JsonValue::Array(arr) => {
                JsonValue::Array(
                    arr.iter().map(|v| match v {
                        JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
                        JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
                        _ => v.clone(),
                    }).collect()
                )
            }
            JsonValue::Object(obj) => {
                let mut new_obj = object::Object::new();
                for (k, v) in obj.iter() {
                    let vv = match v {
                        JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
                        JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
                        _ => v.clone(),
                    };
                    new_obj.insert(k, vv);
                }
                JsonValue::Object(new_obj)
            }
            _ => value.clone(),
        };
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.where_and(field, compare, value);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.where_and(field, compare, value);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.where_and(field, compare, value);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.where_and(field, compare, value);
            }
            _ => {}
        };
        self
    }

    pub fn where_or(&mut self, field: &str, compare: &str, value: JsonValue) -> &mut Self {
        if field.contains("|") {
            let fields: Vec<&str> = field.split("|").collect();
            for field in fields.iter() {
                self.where_or(field.to_string().as_str(), compare, value.clone());
            }
            return self;
        }
        let compare = compare.to_lowercase();
        let compare = compare.replace(" ", "");
        let compare = compare.as_str();

        let value = match &value {
            JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
            JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
            JsonValue::Array(arr) => {
                JsonValue::Array(
                    arr.iter().map(|v| match v {
                        JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
                        JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
                        _ => v.clone(),
                    }).collect()
                )
            }
            JsonValue::Object(obj) => {
                let mut new_obj = object::Object::new();
                for (k, v) in obj.iter() {
                    let vv = match v {
                        JsonValue::Short(s) => JsonValue::String(s.as_str().replace("'", "''")),
                        JsonValue::String(s) => JsonValue::String(s.replace("'", "''")),
                        _ => v.clone(),
                    };
                    new_obj.insert(k, vv);
                }
                JsonValue::Object(new_obj)
            }
            _ => value.clone(),
        };
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.where_or(field, compare, value);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.where_or(field, compare, value);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.where_or(field, compare, value);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.where_or(field, compare, value);
            }
            _ => {}
        };
        self
    }
    pub fn where_column(&mut self, field_a: &str, compare: &str, field_b: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.where_column(field_a, compare, field_b);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.where_column(field_a, compare, field_b);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.where_column(field_a, compare, field_b);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.where_column(field_a, compare, field_b);
            }
            _ => {}
        };
        self
    }
    pub fn update_column(&mut self, field_a: &str, compare: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.update_column(field_a, compare);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.update_column(field_a, compare);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.update_column(field_a, compare);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.update_column(field_a, compare);
            }
            _ => {}
        };
        self
    }
    pub fn count(&mut self) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.count(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.count(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.count(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.count(),
            _ => JsonValue::from(0),
        }
    }
    pub fn max(&mut self, field: &str) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.max(field),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.max(field),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.max(field),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.max(field),
            _ => object! {},
        }
    }

    pub fn min(&mut self, field: &str) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.min(field),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.min(field),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.min(field),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.min(field),
            _ => object! {},
        }
    }

    pub fn sum(&mut self, field: &str) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.sum(field),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.sum(field),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.sum(field),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.sum(field),
            _ => object! {},
        }
    }

    pub fn avg(&mut self, field: &str) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.avg(field),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.avg(field),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.avg(field),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.avg(field),
            _ => object! {},
        }
    }

    pub fn select(&mut self) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.select(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.select(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.select(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.select(),
            _ => object! {},
        }
    }

    pub fn find(&mut self) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.find(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.find(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.find(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.find(),
            _ => object! {},
        }
    }

    pub fn value(&mut self, field: &str) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.value(field),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.value(field),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.value(field),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.value(field),
            _ => Null,
        }
    }

    pub fn insert(&mut self, data: JsonValue) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.insert(data.clone()),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.insert(data.clone()),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.insert(data.clone()),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.insert(data.clone()),
            _ => JsonValue::from(""),
        }
    }

    pub fn insert_all(&mut self, data: JsonValue) -> JsonValue {
        let data = if data.is_object() {
            JsonValue::from(vec![data])
        } else {
            data
        };
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.insert_all(data.clone()),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.insert_all(data.clone()),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.insert_all(data.clone()),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.insert_all(data.clone()),
            _ => object! {},
        }
    }

    pub fn page(&mut self, mut page: i32, limit: i32) -> &mut Self {
        if page <= 0 {
            page = 1;
        }
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.page(page, limit);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.page(page, limit);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.page(page, limit);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.page(page, limit);
            }
            _ => {}
        };
        self
    }

    pub fn update(&mut self, data: JsonValue) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.update(data.clone()),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.update(data.clone()),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.update(data.clone()),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.update(data.clone()),
            _ => JsonValue::from(0),
        }
    }

    pub fn update_all(&mut self, data: JsonValue) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.update_all(data.clone()),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.update_all(data.clone()),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.update_all(data.clone()),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.update_all(data.clone()),
            _ => JsonValue::from(0),
        }
    }

    pub fn get_connection(&mut self) -> Connection {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.connection.clone(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.connection.clone(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.connection.clone(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.connection.clone(),
            _ => Connection::new(""),
        }
    }
    pub fn database_tables(&mut self) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.database_tables(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.database_tables(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.database_tables(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.database_tables(),
            _ => JsonValue::Array(vec![]),
        }
    }
    pub fn database_create(&mut self, name: &str) -> bool {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.database_create(name),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.database_create(name),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.database_create(name),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.database_create(name),
            _ => false,
        }
    }
    pub fn backups(&mut self, filename: &str) -> bool {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                // 定义要执行的命令
                match Command::new("mysqldump").arg("-u").arg(db.connection.username.clone()).arg("-p").arg(db.connection.userpass.clone()).arg(db.connection.database.clone()).arg(">").arg(filename).output() {
                    Ok(output) => {
                        if output.status.success() {
                            // 将备份写入文件
                            info!("数据库备份完成！");
                            return true;
                        }
                        true
                    }
                    Err(e) => {
                        // 打印错误信息
                        error!("mysqldump 命令执行失败：{e}");
                        false
                    }
                }
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(_db) => false,
            #[cfg(feature = "db-mssql")]
            Db::Mssql(_db) => false,
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(_db) => false,
            _ => false,
        }
    }

    pub fn delete(&mut self) -> JsonValue {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.delete(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.delete(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.delete(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.delete(),
            _ => JsonValue::from(0),
        }
    }
    pub fn field(&mut self, name: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.field(name);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.field(name);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.field(name);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.field(name);
            }
            _ => {}
        };
        self
    }
    pub fn hidden(&mut self, name: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.hidden(name);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.hidden(name);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.hidden(name);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.hidden(name);
            }
            _ => {}
        };
        self
    }

    pub fn transaction(&mut self) -> bool {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.transaction(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.transaction(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.transaction(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.transaction(),
            _ => false,
        }
    }

    pub fn commit(&mut self) -> bool {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.commit(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.commit(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.commit(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.commit(),
            _ => false,
        }
    }

    pub fn rollback(&mut self) -> bool {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.rollback(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.rollback(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.rollback(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.rollback(),
            _ => false,
        }
    }

    pub fn sql(&mut self, sql: &str) -> Result<JsonValue, String> {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.sql(sql),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.sql(sql),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.sql(sql),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.sql(sql),
            _ => Err("".to_string()),
        }
    }

    pub fn sql_execute(&mut self, sql: &str) -> Result<JsonValue, String> {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.sql_execute(sql),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.sql_execute(sql),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.sql_execute(sql),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.sql_execute(sql),
            _ => Err("".to_string()),
        }
    }

    /// 自增
    pub fn inc(&mut self, field: &str, num: f64) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.inc(field, num);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.inc(field, num);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.inc(field, num);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.inc(field, num);
            }
            _ => {}
        }
        self
    }
    /// 自减
    pub fn dec(&mut self, field: &str, num: f64) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.dec(field, num);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.dec(field, num);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.dec(field, num);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.dec(field, num);
            }
            _ => {}
        }
        self
    }

    pub fn buildsql(&mut self) -> String {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => db.buildsql(),
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => db.buildsql(),
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => db.buildsql(),
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => db.buildsql(),
            _ => "".to_string(),
        }
    }
    pub fn join_fields(&mut self, fields: Vec<&str>) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.join_fields(fields);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.join_fields(fields);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.join_fields(fields);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.join_fields(fields);
            }
            _ => {}
        }
        self
    }
    /// 连接
    ///
    /// * main_table 主表表名
    /// * main_fields 主表字段名
    /// * right_table 关联主表名
    /// * right_fields 关联字段名
    pub fn join(&mut self, main_table: &str, main_fields: &str, right_table: &str, right_fields: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.join(main_table, main_fields, right_table, right_fields);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.join(main_table, main_fields, right_table, right_fields);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.join(main_table, main_fields, right_table, right_fields);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.join(main_table, main_fields, right_table, right_fields);
            }
            _ => {}
        }
        self
    }

    /// 内连接--用来取交集
    ///
    /// * table 链表表名
    /// * main_fields 主表字段
    /// * second_fields 附表关联字段
    pub fn join_inner(&mut self, table: &str, main_fields: &str, second_fields: &str) -> &mut Self {
        match self {
            #[cfg(feature = "db-mysql")]
            Db::Mysql(db) => {
                db.join_inner(table, main_fields, second_fields);
            }
            #[cfg(feature = "db-sqlite")]
            Db::Sqlite(db) => {
                db.join_inner(table, main_fields, second_fields);
            }
            #[cfg(feature = "db-mssql")]
            Db::Mssql(db) => {
                db.join_inner(table, main_fields, second_fields);
            }
            #[cfg(feature = "db-pgsql")]
            Db::Pgsql(db) => {
                db.join_inner(table, main_fields, second_fields);
            }
            _ => {}
        }
        self
    }
}

/// 模型数据库字段模型
#[derive(Clone, Debug)]
pub struct Table {
    pub version: String,
    pub table: String,
    pub title: String,
    pub primary_key: String,
    pub unique: Vec<String>,
    pub index: Vec<Vec<String>>,
    pub fields: JsonValue,
    pub partition: bool,
    pub partition_columns: JsonValue,
}

impl Table {
    pub fn to_str(self) -> String {
        let data = object! {
            version:self.version,
            table:self.table,
            title:self.title,
            primary_key:self.primary_key,
            unique:self.unique,
            index:self.index,
            fields:self.fields,
            partition:self.partition,
            partition_columns:self.partition_columns,
        };
        data.to_string()
    }
    pub fn parse(mut data: JsonValue) -> Table {
        let mut unique = vec![];
        for item in 0..data["unique"].len() {
            let str = data["unique"][item].clone().to_string();
            unique.push(str);
        }
        let mut index = vec![];
        for item in data["index"].members_mut() {
            let mut row = vec![];
            for col in item.members_mut() {
                row.push(col.to_string());
            }
            if !row.is_empty() {
                index.push(row);
            }
        }
        Self {
            version: data["version"].to_string(),
            table: data["table"].to_string(),
            title: data["title"].to_string(),
            primary_key: data["primary_key"].to_string(),
            unique,
            index,
            fields: data["fields"].clone(),
            partition: data["partition"].as_bool().unwrap_or(false),
            partition_columns: data["partition_columns"].clone(),
        }
    }
}
