df-plugin 0.1.5

This is an Plugin
Documentation
use std::{env, fs};
use std::fs::File;
use std::io::Write;
use std::path::Path;
use df_cache::Cache;
use df_db::db::{ModeDb};
use df_kafka::Kafka;
use json::{JsonValue, object};
use crate::tests::test::test::TestAction;
use crate::tests::test::TestModel;
use crate::tests::TestPlugin;

pub mod tests;

/// 内部插件入口
pub fn plugins(name: &str) -> Box<dyn Plugin> {
    match name {
        _ => Box::new(TestPlugin {})
    }
}

/// 内部模型入口
pub fn models(name: &str) -> Box<dyn Model> {
    match name {
        _ => Box::new(TestModel {})
    }
}

/// 内部动作入口
pub fn actions(name: &str) -> Box<dyn Action> {
    match name {
        _ => Box::new(TestAction { model: TestModel {} })
    }
}


/// 插件
pub trait Plugin {
    fn model(&mut self, name: &str) -> Box<dyn Model>;
}

/// 模型
pub trait Model {
    /// 版本号
    fn version(&mut self) -> String {
        return "0.0.1".to_string();
    }
    /// 数据库表名称
    fn table(&mut self) -> String;
    /// 模型名称
    fn title(&mut self) -> String;
    /// 字段列表
    fn fields(&mut self) -> JsonValue;

    /// 数据库唯一约束
    fn unique(&mut self) -> Vec<String> {
        return vec![];
    }
    /// 查询索引
    fn index(&mut self) -> Vec<Vec<String>> {
        return vec![];
    }
    /// 主键
    fn primary_key(&mut self) -> String {
        return "id".to_string();
    }
    /// 自动ID值
    fn auto(&mut self) -> bool {
        return false;
    }
    /// 创建安装json
    fn json(&mut self) -> ModelTable {
        ModelTable {
            version: self.version(),
            table: self.table(),
            title: self.title(),
            primary_key: self.primary_key(),
            auto: self.auto(),
            unique: self.unique(),
            index: self.index(),
            fields: self.fields(),
        }
    }
    /// 创建安装文件
    fn create_json_file(&mut self, path: &str) -> bool {
        let json = self.json();
        let o = Path::new(path);
        if !o.is_dir() {
            fs::create_dir(path).unwrap();
        }
        env::set_current_dir(path).unwrap();
        let dir = env::current_dir().unwrap();
        let version = self.version();
        let version = version.replace(".", "_");
        let dir = dir.join(format!("{}_{}.json", self.table(), version));
        let mut f = File::create(dir.to_str().unwrap()).unwrap();
        match f.write_all(json.to_string().as_bytes()) {
            Ok(_) => true,
            Err(_) => false
        }
    }
    /// 模型动作
    fn action(&mut self, name: &str) -> Box<dyn Action>;
}

/// 动作
pub trait Action {
    /// 标题
    fn title(&mut self) -> String;
    /// api名称
    fn name(&mut self) -> String;
    /// 是否使用密钥
    fn token(&mut self) -> bool { true }
    /// 扩展 db cache kafka
    fn extend(&mut self) -> Vec<&str> {
        vec![]
    }
    /// 请求参数入口
    fn params(&mut self) -> JsonValue { object! {} }
    /// 检测
    fn _check(&mut self, mut request: JsonValue) -> (bool, String, JsonValue) {
        let params = self.params();
        let mut new_request = object! {};
        for (key, field) in params.entries() {
            if request[key].is_empty() && field["require"].as_bool().unwrap() {
                return (false, format!("缺少参数 {}:{}", key, field["title"]), request);
            }
            if request[key].is_empty() && !field["require"].as_bool().unwrap() {
                request[key] = field["def"].clone().into()
            }
            new_request[key] = request[key].clone();
        }
        return (true, format!("验证通过"), new_request);
    }
    /// 执行参数入口
    fn run(&mut self, header: JsonValue, request: JsonValue, db: Db) -> Response {
        let (state, msg, request) = self._check(request.clone());
        if !state {
            return self.fail(-1, request, msg.as_str().clone());
        }
        return self.index(header, request, db);
    }
    fn index(&mut self, header: JsonValue, request: JsonValue, db: Db) -> Response;
    fn success(&mut self, code: i32, data: JsonValue, msg: &str) -> Response {
        Response {
            code,
            data,
            msg: msg.to_string(),
        }
    }
    fn fail(&mut self, code: i32, data: JsonValue, msg: &str) -> Response {
        Response {
            code,
            data,
            msg: msg.to_string(),
        }
    }
}

/// 集合工具
pub struct Db {
    db: ModeDb,
    cache: Cache,
    kafka: Kafka,
}

pub struct Response {
    code: i32,
    data: JsonValue,
    msg: String,
}

impl Response {
    pub fn to_json(self) -> JsonValue {
        let mut res = object! {};
        res["code"] = self.code.into();
        res["data"] = self.data.into();
        res["msg"] = self.msg.into();
        res
    }
    pub fn success(code: i32, data: JsonValue, msg: &str) -> Self {
        Self {
            code,
            data,
            msg: msg.to_string(),
        }
    }

    pub fn fail(code: i32, data: JsonValue, msg: &str) -> Self {
        Self {
            code,
            data,
            msg: msg.to_string(),
        }
    }
}

/// 模型数据库字段模型
pub struct ModelTable {
    pub version: String,
    pub table: String,
    pub title: String,
    pub primary_key: String,
    pub auto: bool,
    pub unique: Vec<String>,
    pub index: Vec<Vec<String>>,
    pub fields: JsonValue,
}

impl ModelTable {
    pub fn to_string(self) -> String {
        let data = object! {
            version:self.version,
            table:self.table,
            title:self.title,
            primary_key:self.primary_key,
            auto:self.auto,
            unique:self.unique,
            index:self.index,
            fields:self.fields
        };
        data.to_string()
    }
    pub fn parse(mut data: JsonValue) -> ModelTable {
        let mut unique = vec![];
        for item in 0..data["unique"].len() {
            let str = data["unique"][item].clone();
            unique.push(str.to_string());
        }
        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.len() > 0 {
                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(),
            auto: data["auto"].as_bool().unwrap(),
            unique,
            index,
            fields: data["fields"].clone(),
        }
    }
}