use sqlx::MySql; use sqlx::mysql::MySqlArguments; use sqlx::query::{Query, QueryAs, QueryScalar}; use sqlx::types::chrono::{NaiveDate, NaiveDateTime}; pub type DB = MySql; #[derive(Clone, Debug)] pub enum Value { Int8(i8), Uint8(u8), Int16(i16), Uint16(u16), Int32(i32), Uint32(u32), Int64(i64), Uint64(u64), VecU8(Vec), String(String), Bool(bool), Uuid(uuid::Uuid), NaiveDate(NaiveDate), NaiveDateTime(NaiveDateTime), } pub enum Updater<'a> { Set(&'a str, Value), Increment(&'a str, Value), Decrement(&'a str, Value), } #[deprecated(since = "0.1.0", note = "Please use Value instead")] pub type SqlValue = Value; macro_rules! bind_value { ($query:expr, $value: expr) => {{ let query = match $value { Value::Int8(v) => $query.bind(v), Value::Uint8(v) => $query.bind(v), Value::Int16(v) => $query.bind(v), Value::Uint16(v) => $query.bind(v), Value::Int32(v) => $query.bind(v), Value::Uint32(v) => $query.bind(v), Value::Int64(v) => $query.bind(v), Value::Uint64(v) => $query.bind(v), Value::VecU8(v) => $query.bind(v), Value::String(v) => $query.bind(v), Value::Bool(v) => $query.bind(v), Value::Uuid(v) => $query.bind(v), Value::NaiveDate(v) => $query.bind(v), Value::NaiveDateTime(v) => $query.bind(v), }; query }}; } pub fn bind_values<'q>(query: Query<'q, DB, MySqlArguments>, values: &'q [Value]) -> Query<'q, DB, MySqlArguments> { let mut query = query; for value in values { query = bind_value!(query, value); } query } pub fn bind_as_values<'q, O>(query: QueryAs<'q, DB, O, MySqlArguments>, values: &'q [Value]) -> QueryAs<'q, DB, O, MySqlArguments> { values.into_iter().fold(query, |query, value| { bind_value!(query, value) }) } pub fn bind_scalar_values<'q, O>(query: QueryScalar<'q, DB, O, MySqlArguments>, values: &'q [Value]) -> QueryScalar<'q, DB, O, MySqlArguments> { let mut query = query; for value in values { query = bind_value!(query, value); } query } #[inline] pub fn query_fields(fields: Vec<&str>) -> String { fields.iter().filter_map(|e| e.split(" ").next()) .collect::>().join(", ") } impl From for Value { fn from(value: String) -> Self { Value::String(value) } } impl From for Value { fn from(value: i32) -> Self { Value::Int32(value) } } impl From for Value { fn from(value: i64) -> Self { Value::Int64(value) } } impl From for Value { fn from(value: bool) -> Self { Value::Bool(value) } } impl From for Value { fn from(value: uuid::Uuid) -> Self { Value::Uuid(value) } } impl From<&str> for Value { fn from(value: &str) -> Self { Value::String(value.to_string()) } } impl From<&i32> for Value { fn from(value: &i32) -> Self { Value::Int32(*value) } } impl From<&i64> for Value { fn from(value: &i64) -> Self { Value::Int64(*value) } } impl From<&bool> for Value { fn from(value: &bool) -> Self { Value::Bool(*value) } } impl From<&uuid::Uuid> for Value { fn from(value: &uuid::Uuid) -> Self { Value::Uuid(*value) } } impl From for Value { fn from(value: NaiveDate) -> Self { Value::NaiveDate(value) } } impl From for Value { fn from(value: NaiveDateTime) -> Self { Value::NaiveDateTime(value) } } pub trait BindValues<'q> { type Output; fn bind_values(self, values: &'q [Value]) -> Self::Output; } impl<'q> BindValues<'q> for Query<'q, DB, MySqlArguments> { type Output = Query<'q, DB, MySqlArguments>; fn bind_values(self, values: &'q [Value]) -> Self::Output { let mut query = self; for value in values { query = bind_value!(query, value); } query } } impl<'q, O> BindValues<'q> for QueryAs<'q, DB, O, MySqlArguments> { type Output = QueryAs<'q, DB, O, MySqlArguments>; fn bind_values(self, values: &'q [Value]) -> Self::Output { values.into_iter().fold(self, |query, value| { bind_value!(query, value) }) } } impl<'q, O> BindValues<'q> for QueryScalar<'q, DB, O, MySqlArguments> { type Output = QueryScalar<'q, DB, O, MySqlArguments>; fn bind_values(self, values: &'q [Value]) -> Self::Output { let mut query = self; for value in values { query = bind_value!(query, value); } query } } #[macro_export] macro_rules! values { () => { vec![] }; ($x:expr) => { vec![<$crate::prelude::Value>::from($x)] }; ($($x:expr),+ $(,)?) => { vec![$(<$crate::prelude::Value>::from($x)),+] }; }