Skip to content

Commit

Permalink
FEAT: add statements: filter, where, having, select
Browse files Browse the repository at this point in the history
  • Loading branch information
wuyuedefeng committed Sep 19, 2023
1 parent 134d06a commit 8647223
Show file tree
Hide file tree
Showing 17 changed files with 750 additions and 27 deletions.
17 changes: 9 additions & 8 deletions arel-macros/src/arel/arel_trait.rs
@@ -1,18 +1,19 @@
// fn _table_name() -> &'static str;
// fn _table_name() -> String;
pub(crate) fn impl_table_name(input: &crate::ItemInput) -> syn::Result<proc_macro2::TokenStream> {
let mut ret_token_stream = proc_macro2::TokenStream::new();
if let Some((table_name, _)) = input.get_args_path_value(vec![], "table_name", None)? {
ret_token_stream.extend(quote::quote!(
fn _table_name() -> &'static str {
#table_name
fn _table_name() -> String {
#table_name.into()
}
));
}
if ret_token_stream.is_empty() {
Err(syn::Error::new_spanned(&input.input, r#"Please set arel(table_name = "xxx")"#))
} else {
Ok(ret_token_stream)
}
// if ret_token_stream.is_empty() {
// Err(syn::Error::new_spanned(&input.input, r#"Please set arel(table_name = "xxx")"#))
// } else {
// Ok(ret_token_stream)
// }
Ok(ret_token_stream)
}
// fn _primary_keys() -> Vec<&'static str>;
pub(crate) fn impl_primary_keys(input: &crate::ItemInput) -> syn::Result<proc_macro2::TokenStream> {
Expand Down
2 changes: 1 addition & 1 deletion arel-macros/src/arel/mod.rs
Expand Up @@ -54,7 +54,7 @@ fn do_expand(input: &crate::ItemInput) -> syn::Result<proc_macro2::TokenStream>
}

impl #impl_generics arel::SuperArel for #model_name_ident #type_generics #where_clause {
// fn _table_name() -> &'static str;
// fn _table_name() -> String;
#arel_trait_impl_table_name
// fn _primary_keys() -> Vec<&'static str>;
#arel_trait_impl_primary_keys
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Expand Up @@ -7,21 +7,25 @@ compile_error!("feature `sqlite` and `postgres` shouldn't be enabled both.");
#[cfg(all(feature = "mysql", feature = "postgres"))]
compile_error!("feature `mysql` and `postgres` shouldn't be enabled both.");

pub mod statements;

pub mod db;
pub mod error;
pub mod manager;
pub mod prelude;
pub mod sql;
pub mod traits;
pub mod value;

pub use arel_macros::arel;
pub use arel_macros::{self, arel};
pub use bytes;
pub use chrono;
pub use serde_json;
pub use sqlx;

pub use bytes::Bytes;
pub use error::Error;
pub use manager::SelectManager;
pub use sql::Sql;
pub use value::{sub_value, Value};

Expand Down
3 changes: 3 additions & 0 deletions src/manager/mod.rs
@@ -0,0 +1,3 @@
pub mod select_manager;

pub use select_manager::SelectManager;
17 changes: 17 additions & 0 deletions src/manager/select_manager.rs
@@ -0,0 +1,17 @@
use crate::prelude::*;
use std::marker::PhantomData;
use std::ops::RangeBounds;

#[derive(Debug)]
pub struct SelectManager<M: crate::Arel> {
// select: crate::statements::select::Select<M>,
// join: Option<crate::statements::join::Join<M>>,
// r#where: Option<crate::statements::r#where::Where<M>>,
// group: Option<crate::statements::group::Group<M>>,
// having: Option<crate::statements::having::Having<M>>,
// order: Option<crate::statements::order::Order<M>>,
// limit: Option<crate::statements::limit::Limit>,
// offset: Option<crate::statements::offset::Offset>,
// lock: Option<crate::statements::lock::Lock>,
_marker: PhantomData<M>,
}
3 changes: 2 additions & 1 deletion src/prelude.rs
Expand Up @@ -2,5 +2,6 @@ pub use crate::sqlx::{self, Row};
pub use chrono;
pub use serde_json;

pub use crate::arel;
pub use crate::statements::ArelStatement;
pub use crate::{Arel, ArelAttributeFromRow, SuperArel};
pub use arel_macros::arel;
55 changes: 45 additions & 10 deletions src/sql/mod.rs
Expand Up @@ -3,7 +3,7 @@ mod query_builder;
use query_builder::QueryBuilder;
use std::ops::{Bound, RangeBounds};

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Sql {
pub raw_value: String,
pub bind_indexs: Vec<usize>,
Expand All @@ -20,6 +20,19 @@ impl Default for Sql {
}
}

impl TryFrom<Sql> for String {
type Error = crate::Error;
fn try_from(sql: Sql) -> Result<Self, Self::Error> {
sql.to_sql_string()
}
}

impl<T: ToString> From<T> for Sql {
fn from(value: T) -> Self {
Self::new(value)
}
}

impl Sql {
pub fn new<T: ToString>(value: T) -> Self {
Self {
Expand All @@ -38,6 +51,16 @@ impl Sql {
self.bind_values.push(bind_value.into());
self
}
pub fn push_binds<V: Into<crate::Value>>(&mut self, bind_values: Vec<V>, separated_str: &str) -> &mut Self {
let len = bind_values.len();
for (idx, bind_value) in bind_values.into_iter().enumerate() {
self.push_bind(bind_value);
if idx < len - 1 {
self.push_str(separated_str);
}
}
self
}
pub fn push_str_with_bind<T: AsRef<str>, V: Into<crate::Value>>(&mut self, raw_str: T, bind_value: V) -> &mut Self {
self.push_str(raw_str);
self.push_bind(bind_value);
Expand All @@ -50,7 +73,17 @@ impl Sql {
self.bind_values.extend(sql.bind_values);
self
}
pub fn to_debug_sql_string(&self) -> crate::Result<String> {
pub fn push_sqls(&mut self, sqls: Vec<Sql>, separated_str: &str) -> &mut Self {
let len = sqls.len();
for (idx, sql) in sqls.into_iter().enumerate() {
self.push_sql(sql);
if idx < len - 1 {
self.push_str(separated_str);
}
}
self
}
pub fn to_sql_string(&self) -> crate::Result<String> {
let query_builder: QueryBuilder = self.try_into()?;
Ok(query_builder.sql().to_string())
}
Expand All @@ -61,22 +94,22 @@ impl Sql {
///
/// ```
/// let sql = arel::Sql::range_sql("age", ..18).unwrap();
/// assert_eq!(sql.to_debug_sql_string().unwrap(), r#"age < 18"#);
/// assert_eq!(sql.to_sql_string().unwrap(), r#"age < 18"#);
///
/// let sql = arel::Sql::range_sql("age", ..=18).unwrap();
/// assert_eq!(sql.to_debug_sql_string().unwrap(), r#"age <= 18"#);
/// assert_eq!(sql.to_sql_string().unwrap(), r#"age <= 18"#);
///
/// let sql = arel::Sql::range_sql("age", 18..20).unwrap();
/// assert_eq!(sql.to_debug_sql_string().unwrap(), r#"age >= 18 AND age < 20"#);
/// assert_eq!(sql.to_sql_string().unwrap(), r#"age >= 18 AND age < 20"#);
///
/// let sql = arel::Sql::range_sql("age", 18..=20).unwrap();
/// assert_eq!(sql.to_debug_sql_string().unwrap(), r#"age BETWEEN 18 AND 20"#);
/// assert_eq!(sql.to_sql_string().unwrap(), r#"age BETWEEN 18 AND 20"#);
///
/// let sql = arel::Sql::range_sql("age", (std::ops::Bound::Excluded(18), std::ops::Bound::Included(20))).unwrap();
/// assert_eq!(sql.to_debug_sql_string().unwrap(), r#"age > 18 AND age <= 20"#);
/// assert_eq!(sql.to_sql_string().unwrap(), r#"age > 18 AND age <= 20"#);
///
/// let sql = arel::Sql::range_sql("age", 18..).unwrap();
/// assert_eq!(sql.to_debug_sql_string().unwrap(), r#"age >= 18"#);
/// assert_eq!(sql.to_sql_string().unwrap(), r#"age >= 18"#);
///
/// ```
pub fn range_sql<K: AsRef<str>, V: ToString, R: RangeBounds<V>>(key: K, range: R) -> Option<Sql> {
Expand Down Expand Up @@ -106,6 +139,8 @@ impl Sql {
}
}

impl Sql {}

#[cfg(test)]
mod tests {
use crate::sub_value::{ValueInt, ValueString};
Expand All @@ -125,8 +160,8 @@ mod tests {
sql3.push_sql(sql1).push_sql(sql2);

#[cfg(any(feature = "sqlite", feature = "mysql"))]
assert_eq!(sql3.to_debug_sql_string().unwrap(), r#"select * from users where users.id = ? and name = ?"#.to_owned());
assert_eq!(sql3.to_sql_string().unwrap(), r#"select * from users where users.id = ? and name = ?"#.to_owned());
#[cfg(any(feature = "postgres"))]
assert_eq!(sql3.to_debug_sql_string().unwrap(), r#"select * from users where users.id = $1 and name = $2"#.to_owned());
assert_eq!(sql3.to_sql_string().unwrap(), r#"select * from users where users.id = $1 and name = $2"#.to_owned());
}
}
18 changes: 18 additions & 0 deletions src/statements/filter/and_filter.rs
@@ -0,0 +1,18 @@
use super::ArelSubFilterStatement;

#[derive(Debug, Default)]
pub struct AndFilter {
pub(crate) sqls: Vec<crate::Sql>,
}

impl ArelSubFilterStatement for AndFilter {
fn sqls(&self) -> &Vec<crate::Sql> {
&self.sqls
}
fn sqls_mut(&mut self) -> &mut Vec<crate::Sql> {
&mut self.sqls
}
fn join_str(&self) -> &'static str {
" AND "
}
}

0 comments on commit 8647223

Please sign in to comment.