use std::collections::BTreeMap;
use std::fmt::{Display, Formatter, Result as FormatResult};
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum Value<'c> {
Varchar(&'c str),
Bool(bool),
Tinyint(i8),
UnsignedTinyint(u8),
Smallint(i16),
UnsignedSmallint(u16),
Int(i32),
UnsignedInt(u32),
Bigint(i64),
UnsignedBigint(u64),
}
#[allow(unused_assignments)]
impl<'c> Value<'c> {
pub fn as_string(&self) -> String {
match *self {
Value::Varchar(v) => format!("'{}'", v),
Value::Bool(b) => if b {
"TRUE".to_string()
} else {
"FALSE".to_string()
},
Value::Tinyint(t) => format!("{}", t),
Value::UnsignedTinyint(ut) => format!("{}", ut),
Value::Smallint(s) => format!("{}", s),
Value::UnsignedSmallint(us) => format!("{}", us),
Value::Int(i) => format!("{}", i),
Value::UnsignedInt(ui) => format!("{}", ui),
Value::Bigint(bi) => format!("{}", bi),
Value::UnsignedBigint(ubi) => format!("{}", ubi),
}
}
}
impl<'c> Display for Value<'c> {
fn fmt(&self, f: &mut Formatter) -> FormatResult {
write!(f, "{}", self.as_string())
}
}
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum Condition {
And,
Or
}
impl Display for Condition {
fn fmt(&self, f: &mut Formatter) -> FormatResult {
match *self {
Condition::And => write!(f, "AND"),
Condition::Or => write!(f, "OR"),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum OrderBy<'b> {
Row(&'b str),
Expression(&'b str),
}
impl<'b> OrderBy<'b> {
pub fn as_string(&self) -> String {
match *self {
OrderBy::Row(r) => format!("ORDER BY {}", r),
OrderBy::Expression(e) => format!("ORDER BY {}", e),
}
}
}
impl<'b> Display for OrderBy<'b> {
fn fmt(&self, f: &mut Formatter) -> FormatResult {
write!(f, "{}", self.as_string())
}
}
#[derive(Debug)]
pub struct WhereClause<'a, 'b> {
tbl: &'a str,
cond: Value<'b>,
how: Condition,
}
impl<'a, 'b> WhereClause<'a, 'b> {
pub fn new(table: &'a str, cond: Value<'b>, how: Option<Condition>) -> WhereClause<'a, 'b> {
if let Some(c) = how {
WhereClause {
tbl: table,
cond: cond,
how: c
}
} else {
WhereClause {
tbl: table,
cond: cond,
how: Condition::And,
}
}
}
pub fn as_string(&self) -> String {
format!("{} {} = {}", self.how, self.tbl, self.cond)
}
pub fn as_string_no_cond_with_prefix(&self) -> String {
format!("WHERE {} = {}", self.tbl, self.cond)
}
pub fn as_string_no_cond(&self) -> String {
format!("{} = {}", self.tbl, self.cond)
}
}
impl<'a, 'b> Display for WhereClause<'a, 'b> {
fn fmt(&self, f: &mut Formatter) -> FormatResult {
write!(f, "{}", self.as_string())
}
}
#[derive(Debug)]
pub struct SelectQuery<'a, 'c> {
select: Vec<&'a str>,
from: &'a str,
pub whre: Vec<WhereClause<'a, 'c>>,
limit: Option<usize>,
order_by: Option<OrderBy<'c>>
}
impl<'a, 'c> Display for SelectQuery<'a, 'c> {
fn fmt(&self, f: &mut Formatter) -> FormatResult {
write!(f, "{}", self.as_string())
}
}
#[allow(unused_assignments)]
impl<'a, 'c> SelectQuery<'a, 'c> {
pub fn select(rows: &[&'a str]) -> SelectQuery<'a, 'c> {
SelectQuery {
select: rows.to_vec(),
from: "",
whre: Vec::new(),
limit: None,
order_by: None,
}
}
pub fn from(mut self, t: &'a str) -> Self {
self.from = t;
self
}
pub fn limit(&mut self, l: usize) {
self.limit = Some(l);
}
pub fn has_limit(&self) -> bool {
if let Some(_) = self.limit {
return true;
}
false
}
pub fn get_limit(&self) -> Option<usize> {
self.limit
}
pub fn clear_limit(&mut self) {
self.limit = None;
}
pub fn order_by(&mut self, ob: OrderBy<'c>) {
self.order_by = Some(ob);
}
pub fn as_string(&self) -> String {
let mut res: String = String::new();
if !self.select.is_empty() {
res = format!("SELECT {}", self.select[0]);
if self.select.len() > 1 {
for s in self.select[1..].iter() {
res = format!("{}, {}", res, s);
}
}
}
if self.from.len() > 1 {
res = format!("{} FROM {}", res, self.from);
}
if !self.whre.is_empty() {
let c = &self.whre[0];
res = format!("{} {}", res, c.as_string_no_cond_with_prefix());
for clause in &self.whre[1..] {
res = format!("{} {}", res, clause);
}
}
if let Some(l) = self.limit {
res = format!("{} LIMIT {}", res, l);
}
if let Some(ref ob) = self.order_by {
res = format!("{} {}", res, ob);
}
res
}
}
#[derive(Debug)]
pub struct InsertQuery<'a> {
into: &'a str,
pub values: BTreeMap<&'a str, Value<'a>>,
}
impl<'a> Display for InsertQuery<'a> {
fn fmt(&self, f: &mut Formatter) -> FormatResult {
write!(f, "{}", self.as_string())
}
}
#[allow(unused_assignments)]
impl<'a> InsertQuery<'a> {
pub fn into(table: &'a str) -> InsertQuery<'a> {
InsertQuery {
into: table,
values: BTreeMap::new(),
}
}
pub fn as_string(&self) -> String {
let mut res = String::new();
let (mut vals, mut vals_list) = (String::new(), String::new());
res = format!("INSERT INTO {}", self.into);
if !self.values.is_empty() {
let mut keys = self.values.keys();
let key = keys.next().unwrap();
vals = format!("{}", key);
vals_list = format!("{}", self.values[key]);
for k in keys {
vals = format!("{}, {}", vals, k);
vals_list = format!("{}, {}", vals_list, self.values[k]);
}
}
format!("{}({}) VALUES({})", res, vals, vals_list)
}
}
#[derive(Debug)]
pub struct DeleteQuery<'a, 'c> {
from: &'a str,
pub whre: Vec<WhereClause<'a, 'c>>,
limit: Option<usize>,
order_by: Option<OrderBy<'c>>,
}
impl<'a, 'c> Display for DeleteQuery<'a, 'c> {
fn fmt(&self, f: &mut Formatter) -> FormatResult {
write!(f, "{}", self.as_string())
}
}
#[allow(unused_assignments)]
impl<'a, 'c> DeleteQuery<'a, 'c> {
pub fn from(table: &'a str) -> DeleteQuery {
DeleteQuery {
from: table,
whre: Vec::new(),
limit: None,
order_by: None,
}
}
pub fn limit(&mut self, limit: usize) {
self.limit = Some(limit);
}
pub fn get_limit(&self) -> Option<usize> {
self.limit
}
pub fn clear_limit(&mut self) {
self.limit = None;
}
pub fn order_by(&mut self, ob: OrderBy<'c>) {
self.order_by = Some(ob);
}
pub fn is_ordered(&self) -> bool {
if let Some(_) = self.order_by {
true
}
else {
false
}
}
pub fn clear_order_by(&mut self) {
self.order_by = None;
}
pub fn as_string(&self) -> String {
let mut res = String::new();
res = format!("DELETE FROM {}", self.from);
if !self.whre.is_empty() {
let c = &self.whre[0];
res = format!("{} {}", res, c.as_string_no_cond_with_prefix());
for clause in &self.whre[1..] {
res = format!("{} {}", res, clause);
}
}
if let Some(ref o) = self.order_by {
res = format!("{} {}", res, o);
}
if let Some(l) = self.limit {
res = format!("{} LIMIT {}", res, l);
}
res
}
}
#[derive(Debug)]
pub struct UpdateQuery<'a, 'c> {
update: &'a str,
pub set: BTreeMap<&'a str, Value<'c>>,
pub whre: Vec<WhereClause<'a, 'c>>,
limit: Option<usize>,
}
impl<'a, 'c> Display for UpdateQuery<'a, 'c> {
fn fmt(&self, f: &mut Formatter) -> FormatResult {
write!(f, "{}", self.as_string())
}
}
#[allow(unused_assignments)]
impl<'a, 'c> UpdateQuery<'a, 'c> {
pub fn update(table: &'a str) -> UpdateQuery {
UpdateQuery {
update: table,
set: BTreeMap::new(),
whre: Vec::new(),
limit: None,
}
}
pub fn limit(&mut self, l: usize) {
self.limit = Some(l);
}
pub fn has_limit(&self) -> bool {
if let Some(_) = self.limit {
return true;
}
false
}
pub fn get_limit(&self) -> Option<usize> {
self.limit
}
pub fn as_string(&self) -> String {
let mut res = String::new();
res = format!("UPDATE {}", self.update);
if !self.set.is_empty() {
let mut keys = self.set.keys();
let key = keys.next().unwrap();
res = format!("{} SET {} = {}", res, key, self.set[key]);
for k in keys {
res = format!("{}, {} = {}", res, k, self.set[k]);
}
}
if !self.whre.is_empty() {
let c = &self.whre[0];
res = format!("{} {}", res, c.as_string_no_cond_with_prefix());
for clause in &self.whre[1..] {
res = format!("{} {}", res, clause);
}
}
if let Some(l) = self.limit {
res = format!("{} LIMIT {}", res, l);
}
res
}
}