use std::path::Path;
use json::{JsonValue, object};
use crate::mode::Mode;
#[derive(Clone, Debug)]
pub enum Charset {
Utf8mb4,
Utf8,
}
impl Charset {
pub fn from(str: &str) -> Charset {
match str {
"utf8" => Charset::Utf8,
"utf8mb4" => Charset::Utf8mb4,
_ => Charset::Utf8mb4
}
}
}
#[derive(Clone)]
pub struct Config {
pub db_mode: Mode,
pub keyauto: bool,
pub hostname: String,
pub hostport: String,
pub database: String,
pub username: String,
pub userpass: String,
pub charset: String,
pub prefix: String,
pub params: Vec<String>,
pub debug: bool
}
impl Config {
pub fn get_dsn(self) -> String {
match self.db_mode {
Mode::Mysql => {
format!("mysql://{}:{}@{}:{}/{}", self.username, self.userpass, self.hostname, self.hostport, self.database)
}
Mode::Sqlite => {
let data = Path::new(self.hostname.as_str());
let data = data.join(format!("{}.db", self.database));
format!("{}", data.to_str().unwrap())
}
Mode::Mssql => {
format!("sqlsrv://{}:{}@{}:{}/{}", self.username, self.userpass, self.hostname, self.hostport, self.database)
}
}
}
}
#[derive(Clone)]
pub struct Params {
pub mode: Mode,
pub table: String,
pub where_and: Vec<String>,
pub where_or: Vec<String>,
pub page: i32,
pub limit: i32,
pub fields: JsonValue,
pub top: String,
pub order: JsonValue,
pub group: JsonValue,
pub distinct: bool,
pub json: JsonValue,
}
impl Params {
pub fn default(mode: Mode) -> Self {
Self {
mode,
table: "".to_string(),
where_and: vec![],
where_or: vec![],
page: -1,
limit: 10,
fields: object! {},
top: String::new(),
order: object! {},
group: object! {},
distinct: false,
json: object! {},
}
}
pub fn where_sql(&mut self) -> String {
let mut where_sql = String::new();
let mut where_or_sql = String::new();
for item in self.where_or.iter() {
where_or_sql = format!("{} OR {}", where_or_sql, item);
}
for item in self.where_and.iter() {
where_sql = format!("{} AND {}", where_sql, item);
}
if where_sql != "" {
where_sql = where_sql.trim_start_matches(" AND ").parse().unwrap();
where_sql = format!("WHERE {}", where_sql);
}
if where_or_sql != "" {
where_or_sql = where_or_sql.trim_start_matches(" OR ").parse().unwrap();
if where_sql == "" {
return format!("WHERE {}", where_or_sql);
} else {
return format!("{} OR {}", where_sql, where_or_sql);
}
}
where_sql
}
pub fn page_limit_sql(&mut self) -> String {
if self.page == -1 {
return format!("");
}
match self.mode {
Mode::Mysql => {
return format!("LIMIT {} OFFSET {}", self.page, self.page * self.limit);
}
Mode::Sqlite => {
return format!("LIMIT {} OFFSET {}", self.limit, self.page * self.limit - self.limit);
}
Mode::Mssql => {
return format!("");
}
}
}
pub fn fields(&mut self) -> String {
let mut fields = String::new();
for (_, value) in self.fields.entries() {
fields = format!("{},{}", fields, value);
}
if fields == "" {
fields = "*".into();
} else {
fields = fields.trim_start_matches(",").into();
}
match self.mode {
Mode::Mysql => {
return format!("{}", fields);
}
Mode::Sqlite => {
return format!("{}", fields);
}
Mode::Mssql => {
return format!("{}", fields);
}
}
}
pub fn top(&mut self) -> String {
match self.mode {
Mode::Mysql | Mode::Sqlite => {
return format!("");
}
Mode::Mssql => {
return format!("{}", self.top);
}
}
}
pub fn order(&mut self) -> String {
let mut sql = String::new();
for (field, item) in self.order.entries() {
sql = format!("{} {} {},", sql, field, item);
}
if sql != "" {
sql = format!("ORDER BY {}", sql);
sql = sql.trim_end_matches(",").parse().unwrap();
}
return sql;
}
pub fn group(&mut self) -> String {
let mut sql = String::new();
for (field, _) in self.group.entries() {
sql = format!("{} {},", sql, field);
}
if sql != "" {
sql = format!("GROUP BY {}", sql);
sql = sql.trim_end_matches(",").parse().unwrap();
}
return sql;
}
pub fn distinct(&self) -> String {
if self.distinct {
return "DISTINCT".to_string();
} else {
return "".to_string();
}
}
pub fn select_sql(&mut self) -> String {
return format!("SELECT {} {} {} FROM {} {} {} {} {}", self.distinct(), self.top(), self.fields(), self.table.clone(), self.where_sql(), self.group(), self.order(), self.page_limit_sql());
}
}