use std::process::exit;
use json::{array, JsonValue, object};
use mysql::*;
use mysql::prelude::*;
use crate::orm::fields;
use crate::orm::fields::field::Field;
use crate::tools;
pub struct Mysql {
conn: PooledConn,
table: String,
database: String,
pub fields: JsonValue,
transaction: u32,
}
impl Mysql {
pub fn connect(dsn: String, database: String) -> Self {
let pool = Pool::new(dsn.as_str());
match pool {
Ok(e) => {
Self {
conn: e.get_conn().unwrap(),
fields: object! {},
table: String::new(),
database,
transaction: 0,
}
}
Err(_e) => {
println!("数据库连接错误:{}", _e);
exit(500)
}
}
}
pub fn fieldsinfo(&mut self, table: String) -> &mut Self {
self.table = table.clone();
let sql = format!("select * from information_schema.COLUMNS where TABLE_SCHEMA='{}' and table_name = '{}'", self.database, table);
let mut data = object! {};
self.conn.query_iter(sql).unwrap().for_each(|row| {
let r = row.unwrap();
let mut rows = object! {};
let name: String = r.get("COLUMN_NAME").unwrap();
let name = name.as_str().clone();
let comment: String = r.get("COLUMN_COMMENT").unwrap();
let sttr = tools::string::split(comment.clone(), "|");
let title = sttr[0].as_str().unwrap();
let mode = sttr[1].as_str().unwrap_or("string");
let length: Option<i32> = r.get("CHARACTER_MAXIMUM_LENGTH").unwrap();
let require = sttr[2].as_str().unwrap_or("").parse::<bool>().unwrap_or(false);
match mode {
"key" => {
let length = sttr[2].to_string().parse::<i32>().unwrap_or(0);
let auto = sttr[3].to_string().parse::<bool>().unwrap_or(false);
rows = fields::field::Key::field(name.clone(), title.clone(), length, auto.clone()).info();
}
"pass" => {
let def: String = r.get("COLUMN_DEFAULT").unwrap_or("".to_string());
let def = def.as_str().clone();
rows = fields::field::Str::pass(require.clone(), name.clone(), title.clone(), length.unwrap(), def.clone()).info();
}
"string" => {
let def: Option<String> = r.get("COLUMN_DEFAULT").unwrap();
let def = {
if def == None {
"".to_string()
} else {
let def: String = r.get("COLUMN_DEFAULT").unwrap_or("".to_string());
def
}
};
let def = def.as_str().clone();
rows = fields::field::Str::string(require.clone(), name.clone(), title.clone(), length.unwrap_or(20), def.clone()).info();
}
"datetime" => {
let def = sttr[3].as_str().unwrap_or("");
rows = fields::field::Date::datetime(require.clone(), name.clone(), title.clone(), def.clone()).info();
}
"timestamp" => {
let dec = sttr[3].as_str().unwrap_or("").parse::<i32>().unwrap_or(0);
let def = sttr[4].as_str().unwrap_or("").parse::<f64>().unwrap_or(0.0);
rows = fields::field::Timestamp::timestamp(require.clone(), name.clone(), title.clone(), dec.clone(), def.clone()).info();
}
"number" => {
let length = sttr[3].as_str().unwrap_or("").parse::<i32>().unwrap_or(0);
let dec = sttr[4].as_str().unwrap_or("").parse::<i32>().unwrap_or(0);
let def = sttr[5].as_str().unwrap_or("").parse::<f32>().unwrap_or(0.0);
rows = fields::field::Number::field(
require.clone(),
name.clone(),
title.clone(), length.clone(),
dec.clone(), def.clone()).info();
}
"file" => {
let length = sttr[3].as_str().unwrap_or("").parse::<i32>().unwrap_or(1);
let def = sttr[4].as_str().unwrap_or("");
rows = fields::field::File::field(
require.clone(),
name.clone(),
title.clone(),
length.clone(),
def.clone(),
).info();
}
"table" => {
let table = sttr[3].as_str().unwrap();
let fields = sttr[4].as_str().unwrap();
let api = sttr[5].as_str().unwrap_or("");
let def = sttr[6].as_str().unwrap_or("");
rows = fields::field::Table::field(
require.clone(),
name.clone(),
title.clone(),
table.clone(),
fields.clone(),
def.clone(),
api.clone()).info();
}
"text" => {
let def = sttr[2].as_str().unwrap_or("");
rows = fields::field::Text::field(
require.clone(),
name.clone(),
title.clone(),
def.clone(),
).info();
}
"select" => {
let option: Option<String> = r.get("COLUMN_TYPE").unwrap();
let option = option.unwrap();
let mut options = array![];
let multiple = sttr[3].as_str().unwrap_or("").parse::<bool>().unwrap_or(false);
let option = {
if tools::string::search(option.as_str(), "enum(") {
let option = option.trim_start_matches("enum('").trim_end_matches("')");
let option = tools::string::split(option.to_string(), "','");
option
} else {
let option = option.trim_start_matches("set('").trim_end_matches("')");
let option = tools::string::split(option.to_string(), "','");
option
}
};
for item in option.members() {
if item != "" {
options.push(item.clone()).unwrap();
}
}
let def = sttr[4].as_str().unwrap_or("");
rows = fields::field::Select::field(
require.clone(),
name.clone(),
title.clone(),
options.clone(),
multiple.clone(),
def.into(),
).info();
}
"switch" => {
let def = sttr[3].as_str().unwrap_or("").parse::<bool>().unwrap_or(false);
rows = fields::field::Switch::field(
require.clone(),
name.clone(),
title.clone(),
def.into(),
).info();
}
"year" => {
let def = {
let def: Option<String> = r.get("COLUMN_DEFAULT").unwrap();
if def == None {
"0000".to_string()
} else {
def.unwrap()
}
};
let def = def.as_str().clone();
rows = fields::field::Date::year(
require.clone(),
name.clone(),
title.clone(),
def.into(),
).info();
}
"date" => {
let def = {
let def: Option<String> = r.get("COLUMN_DEFAULT").unwrap();
if def == None {
"0000-01-01".to_string()
} else {
def.unwrap()
}
};
let def = def.as_str();
rows = fields::field::Date::date(
require.clone(),
name.clone(),
title.clone(),
def.into(),
).info();
}
"time" => {
let def: String = r.get("COLUMN_DEFAULT").unwrap_or("00:00:00".to_string());
let def = def.as_str();
rows = fields::field::Date::time(
require.clone(),
name.clone(),
title.clone(),
def.into(),
).info();
}
_ => {
println!("未知数据类型: {}", mode);
}
}
data[name.clone()] = rows.into();
});
self.fields[self.table.clone()] = data.into();
self
}
pub fn select(&mut self, sql: String, field_list: Vec<String>) -> JsonValue {
let res = self.conn.query_iter(sql.clone());
match res {
Ok(e) => {
let mut data = array![];
let mut fields = object! {};
e.for_each(|row| {
let r = row.unwrap();
if fields.is_empty() {
if field_list.len() > 0 {
for field in field_list.iter() {
fields[field] = self.fields[self.table.clone()][field].clone();
}
} else {
for (field, field_data) in self.fields[self.table.clone()].entries() {
fields[field.clone()] = field_data.clone();
}
}
}
let mut rows = object! {};
for (field, fields_data) in fields.entries() {
let mode = fields_data["mode"].as_str().unwrap();
match mode {
"key" => {
let dd: Option<String> = r.get(field);
rows[field] = dd.into();
}
"string" => {
let dd: Option<String> = r.get(field);
rows[field] = dd.into();
}
"pass" => {
let dd: Option<String> = r.get(field);
rows[field] = dd.into();
}
"file" => {
let dd: Option<String> = r.get(field);
rows[field] = dd.into();
}
"table" => {
let dd: Option<String> = r.get(field);
rows[field] = dd.into();
}
"text" => {
let dd: Option<String> = r.get(field).unwrap();
if dd == None {
rows[field] = "".into();
} else {
rows[field] = dd.into();
}
}
"select" => {
let dd: Option<String> = r.get(field);
rows[field] = dd.into();
}
"switch" => {
let dd: Option<bool> = r.get(field);
rows[field] = dd.into();
}
"timestamp" => {
let dd: Option<f64> = r.get(field);
rows[field] = dd.into();
}
"datetime" => {
let dd: Option<String> = r.get(field);
rows[field] = dd.into();
}
"number" => {
let dd: Option<f64> = r.get(field);
rows[field] = dd.into();
}
"float" => {
let dd: Option<f64> = r.get(field);
rows[field] = dd.into();
}
_ => {
println!("字段未定义 {} {}", mode.clone(), field.clone());
}
}
}
data.push(rows.clone()).expect("select 添加错误");
});
return data;
}
Err(_e) => {
println!("select 错误>>>{}", sql);
println!("select 错误>>>{}", _e);
return array![];
}
}
}
pub fn insert(&mut self, sql: String) -> JsonValue {
let ret = self.conn.exec_iter(sql.clone(), {});
match ret {
Ok(e) => {
JsonValue::from(e.affected_rows())
}
Err(e) => {
println!("insert 新增错误:{}", sql);
println!("insert 新增错误:{}", e);
JsonValue::from(0)
}
}
}
pub fn update(&mut self, sql: String) -> JsonValue {
let ret = self.conn.exec_iter(sql.clone(), {});
match ret {
Ok(e) => {
JsonValue::from(e.affected_rows())
}
Err(e) => {
println!("update 更新错误:{}", sql);
println!("update 更新错误:{}", e);
JsonValue::from(0)
}
}
}
pub fn delete(&mut self, sql: String) -> JsonValue {
let ret = self.conn.exec_iter(sql.clone(), {});
match ret {
Ok(e) => {
JsonValue::from(e.affected_rows())
}
Err(e) => {
println!("delete 删除错误:{}", sql);
println!("delete 删除错误:{}", e);
JsonValue::from(0)
}
}
}
fn _split(&mut self, data: &str) -> String {
let data = String::from(data);
let list: Vec<&str> = data.split(" as ").collect();
if list.len() == 1 {
return list[0].to_string();
}
return list[1].to_string();
}
pub fn aggregate_query(&mut self, mode: &str, sql: String, mut fields: Vec<String>) -> JsonValue {
for index in 0..fields.len() {
fields[index] = self._split(fields[index].as_str().clone());
}
let ret = self.conn.query_iter(sql.clone());
match ret {
Ok(e) => {
let mut list = array![];
e.for_each(|row| {
let r = row.unwrap();
let mut rows = object! {};
for index in 0..fields.len() {
match fields[index].as_str() {
"count" => {
let dd: Option<f64> = r.get(fields[index].as_str());
rows[fields[index].clone()] = dd.into();
}
_ => {
let dd: Option<f64> = r.get(fields[index].as_str());
rows[fields[index].clone()] = dd.into();
}
}
}
list.push(rows).unwrap();
});
if fields.len() == 1 {
return list[0][fields[0].clone()].clone();
}
match mode {
"count" => {
list[0].clone()
}
_ => {
list[0].clone()
}
}
}
Err(e) => {
println!("{} 错误 {}", mode, e);
if fields.len() == 1 {
return JsonValue::from(0);
}
return array![];
}
}
}
pub fn transaction(&mut self) -> bool {
if self.transaction > 0 {
self.transaction += 1;
return true;
}
let sql = "begin";
let res = self.conn.query_iter(sql.clone());
if res.is_ok() {
self.transaction = 1;
true
} else {
false
}
}
pub fn commit(&mut self) -> bool {
if self.transaction > 1 {
self.transaction -= 1;
return true;
}
let sql = "commit";
let res = self.conn.query_iter(sql.clone());
self.transaction = 0;
if res.is_ok() {
true
} else {
false
}
}
pub fn rollback(&mut self) -> bool {
let sql = "rollback";
let res = self.conn.query_iter(sql.clone());
self.transaction = 0;
if res.is_ok() {
true
} else {
false
}
}
pub fn query_table(&mut self, table: &str) -> bool {
let sql = format!("SHOW TABLES LIKE '{}'", table);
let res = self.conn.query_iter(sql.clone());
match res {
Ok(e) => {
let mut is = false;
e.for_each(|row| {
let r = row.unwrap();
let dd: Option<String> = r.get(format!("Tables_in_{} ({})", self.database, table).as_str());
if table == dd.unwrap() {
is = true
}
});
return is;
}
Err(e) => {
println!("{}", e);
return false;
}
}
}
pub fn create_table(&mut self, sql: &str) -> bool {
let res = self.conn.query_drop(sql.clone());
match res {
Ok(_e) => {
return true;
}
Err(e) => {
println!("{:?}", e.to_string());
return false;
}
}
}
pub fn delete_table(&mut self, sql: &str) -> bool {
let res = self.conn.query_drop(sql.clone());
match res {
Ok(_e) => {
return true;
}
Err(e) => {
println!("{:?}", e.to_string());
return false;
}
}
}
pub fn update_table(&mut self, sql: &str) -> bool {
let res = self.conn.query_drop(sql.clone());
match res {
Ok(_e) => {
return true;
}
Err(e) => {
println!("{:?}", e.to_string());
return false;
}
}
}
}