sqlx-record/src/value.rs

209 lines
4.8 KiB
Rust

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<u8>),
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::<Vec<_>>().join(", ")
}
impl From<String> for Value {
fn from(value: String) -> Self {
Value::String(value)
}
}
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<&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<NaiveDate> for Value {
fn from(value: NaiveDate) -> Self {
Value::NaiveDate(value)
}
}
impl From<NaiveDateTime> 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)),+]
};
}