Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions tests/mssql/tests/all_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,24 @@ async fn should_be_able_to_write_mapquery_with_a_column_rename() {
eprintln!("SQL: {}", sql);
q.run(&conn).await.unwrap();
}

#[tokio::test]
async fn should_be_able_to_select_hourse_or_dog() {
use welds::query::clause::or;
let conn = get_conn().await;
use mssql_test::models::product::ProductSchema;

// verify pulling out lambda into variable
let clause = |x: ProductSchema| or(x.name.like("horse"), x.name.like("dog"));
let q = Product::all().where_col(clause);

eprintln!("SQL: {}", q.to_sql(Syntax::Sqlite));
let data = q.run(&conn).await.unwrap();
assert_eq!(data.len(), 2, "Expected horse and dog",);

// verify inline clause
let q2 = Product::all().where_col(|x| or(x.name.like("horse"), x.name.like("dog")));
eprintln!("SQL: {}", q2.to_sql(Syntax::Sqlite));
let data = q2.run(&conn).await.unwrap();
assert_eq!(data.len(), 2, "Expected horse and dog",);
}
23 changes: 23 additions & 0 deletions tests/mysql/tests/all_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,26 @@ fn should_be_able_to_write_a_custom_set() {
q.run(&conn).await.unwrap();
})
}

#[test]
fn should_be_able_to_select_hourse_or_dog() {
async_std::task::block_on(async {
use welds::query::clause::or;
let conn = get_conn().await;
use mysql_test::models::product::ProductSchema;

// verify pulling out lambda into variable
let clause = |x: ProductSchema| or(x.name.like("horse"), x.name.like("dog"));
let q = Product::all().where_col(clause);

eprintln!("SQL: {}", q.to_sql(Syntax::Mysql));
let data = q.run(&conn).await.unwrap();
assert_eq!(data.len(), 2, "Expected horse and dog",);

// verify inline clause
let q2 = Product::all().where_col(|x| or(x.name.like("horse"), x.name.like("dog")));
eprintln!("SQL: {}", q2.to_sql(Syntax::Mysql));
let data = q2.run(&conn).await.unwrap();
assert_eq!(data.len(), 2, "Expected horse and dog",);
})
}
23 changes: 23 additions & 0 deletions tests/postgres/tests/all_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,3 +786,26 @@ fn should_be_able_to_select_all_orders_with_there_products() {
assert_eq!(o3_products[0].product_id, 1);
})
}

#[test]
fn should_be_able_to_select_hourse_or_dog() {
async_std::task::block_on(async {
use welds::query::clause::or;
let conn = get_conn().await;
use postgres_test::models::product::ProductSchema;

// verify pulling out lambda into variable
let clause = |x: ProductSchema| or(x.name.like("horse"), x.name.like("dog"));
let q = Product::all().where_col(clause);

eprintln!("SQL: {}", q.to_sql(Syntax::Postgres));
let data = q.run(&conn).await.unwrap();
assert_eq!(data.len(), 2, "Expected horse and dog",);

// verify inline clause
let q2 = Product::all().where_col(|x| or(x.name.like("horse"), x.name.like("dog")));
eprintln!("SQL: {}", q2.to_sql(Syntax::Postgres));
let data = q2.run(&conn).await.unwrap();
assert_eq!(data.len(), 2, "Expected horse and dog",);
})
}
23 changes: 23 additions & 0 deletions tests/sqlite/tests/all_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,3 +606,26 @@ fn should_be_able_to_fetch_a_single_object() {
.unwrap();
})
}

#[test]
fn should_be_able_to_select_hourse_or_dog() {
async_std::task::block_on(async {
use welds::query::clause::or;
let conn = get_conn().await;
use sqlite_test::models::product::ProductSchema;

// verify pulling out lambda into variable
let clause = |x: ProductSchema| or(x.name.like("horse"), x.name.like("dog"));
let q = Product::all().where_col(clause);

eprintln!("SQL: {}", q.to_sql(Syntax::Sqlite));
let data = q.run(&conn).await.unwrap();
assert_eq!(data.len(), 2, "Expected horse and dog",);

// verify inline clause
let q2 = Product::all().where_col(|x| or(x.name.like("horse"), x.name.like("dog")));
eprintln!("SQL: {}", q2.to_sql(Syntax::Sqlite));
let data = q2.run(&conn).await.unwrap();
assert_eq!(data.len(), 2, "Expected horse and dog",);
})
}
2 changes: 2 additions & 0 deletions welds-macros/src/blocks/define_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub(crate) fn write(info: &Info) -> TokenStream {

quote! {

#[derive(Copy,Clone)]
pub struct #name {
#(#fields),*
}
Expand Down Expand Up @@ -75,6 +76,7 @@ mod tests {
let code = ts.to_string();

let expected: &str = r#"
#[derive(Copy,Clone)]
pub struct MockSchema {
pub id: welds::query::clause::Numeric<i64>
}
Expand Down
24 changes: 12 additions & 12 deletions welds-macros/src/hook.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::errors::Result;
use proc_macro2::{TokenStream, TokenTree};
use quote::ToTokens;
use crate::errors::Result;
//use syn::Ident;
use syn::{MetaList, Path};

/// User has defined a Hook on the model
Expand Down Expand Up @@ -32,7 +31,7 @@ impl Hook {
.to_owned())
};

let list= &list.tokens.clone().into_iter().collect::<Vec<_>>();
let list = &list.tokens.clone().into_iter().collect::<Vec<_>>();
if list.len() > 5 {
return badformat();
}
Expand All @@ -41,15 +40,16 @@ impl Hook {

if list.len() == 5 {
match &list[3] {
TokenTree::Punct(punct)=>
if punct.as_char() != '=' {
return badformat();
TokenTree::Punct(punct) => {
if punct.as_char() != '=' {
return badformat();
}
}
_ => return badformat(),
}
match &list[2] {
TokenTree::Ident(ident)=> {
if ident.to_string() != "async" {
TokenTree::Ident(ident) => {
if *ident != "async" {
return badformat();
}
}
Expand All @@ -58,14 +58,14 @@ impl Hook {

match &list[4] {
TokenTree::Ident(ident) => {
if ident.to_string()=="true" {
if *ident == "true" {
is_async = true;
} else if ident.to_string()=="false" {
} else if *ident == "false" {
is_async = false;
} else {
return badformat();
}
},
}
_ => return badformat(),
}
}
Expand All @@ -77,7 +77,7 @@ impl Hook {
tokens
};

let callback: syn::Result<Path> =syn::parse2(token_stream);
let callback: syn::Result<Path> = syn::parse2(token_stream);

let callback = match callback {
Ok(path) => path,
Expand Down
2 changes: 1 addition & 1 deletion welds-macros/src/relation/basic.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::Relation;
use super::{read_as_ident, read_as_path, read_as_string};
use crate::errors::Result;
use syn::{Expr, Ident, Token};
use syn::{Expr, Ident};
use syn::MetaList;
use syn::parse::Parser;
use syn::punctuated::Punctuated;
Expand Down
2 changes: 1 addition & 1 deletion welds/src/query/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ where
FN: AsFieldName<V>,
{
let field = col(Default::default());
let colname = field.colname().to_string();
let colname = field.colname();
let params: ManualParam = params.into();
let c = clause::ClauseColManual {
col: Some(colname),
Expand Down
4 changes: 2 additions & 2 deletions welds/src/query/clause/assignment_adder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ where

fn clause(&self, syntax: Syntax, _alias: &str, next_params: &NextParam) -> Option<String> {
// build the column name
let colname = ColumnWriter::new(syntax).excape(&self.col);
let colname = ColumnWriter::new(syntax).excape(self.col);
let mut parts = vec![colname.as_str()];

// handle null clones
Expand Down Expand Up @@ -104,7 +104,7 @@ impl AssignmentAdder for AssignmentManual {
// build the column name
let mut parts = vec![];

let colname = ColumnWriter::new(syntax).excape(&self.col);
let colname = ColumnWriter::new(syntax).excape(self.col);
parts.push(colname);
parts.push(" = ( ".to_string());

Expand Down
16 changes: 9 additions & 7 deletions welds/src/query/clause/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,28 @@ use super::{AsFieldName, ClauseColVal, ClauseColValEqual, ClauseColValIn};
use std::marker::PhantomData;
use welds_connections::Param;

#[derive(Clone)]
pub struct Basic<T> {
col: String,
field: String,
col: &'static str,
field: &'static str,
_t: PhantomData<T>,
}

impl<T> AsFieldName<T> for Basic<T> {
fn colname(&self) -> &str {
self.col.as_str()
fn colname(&self) -> &'static str {
self.col
}
fn fieldname(&self) -> &str {
self.field.as_str()
fn fieldname(&self) -> &'static str {
self.field
}
}
impl<T:Clone> Copy for Basic<T> {}

impl<T> Basic<T>
where
T: 'static + Clone + Send + Sync,
{
pub fn new(col: impl Into<String>, field: impl Into<String>) -> Self {
pub fn new(col: &'static str, field: &'static str) -> Self {
Self {
col: col.into(),
field: field.into(),
Expand Down
16 changes: 9 additions & 7 deletions welds/src/query/clause/basicopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,30 @@ use crate::query::optional::Optional;
use std::marker::PhantomData;
use welds_connections::Param;

#[derive(Clone)]
pub struct BasicOpt<T> {
col: String,
field: String,
col: &'static str,
field: &'static str,
_t: PhantomData<T>,
}

impl<T> AsFieldName<T> for BasicOpt<T> {
fn colname(&self) -> &str {
self.col.as_str()
fn colname(&self) -> &'static str {
self.col
}
fn fieldname(&self) -> &str {
self.field.as_str()
fn fieldname(&self) -> &'static str {
self.field
}
}
impl<T:Clone> Copy for BasicOpt<T> {}

impl<T> AsOptField for BasicOpt<T> {}

impl<T> BasicOpt<T>
where
T: 'static + Clone + Send + Sync,
{
pub fn new(col: impl Into<String>, field: impl Into<String>) -> Self {
pub fn new(col: &'static str, field: &'static str) -> Self {
Self {
col: col.into(),
field: field.into(),
Expand Down
1 change: 1 addition & 0 deletions welds/src/query/clause/clause_adder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,4 @@ impl ClauseAdder for ClauseColManual {
Some(clause)
}
}

26 changes: 18 additions & 8 deletions welds/src/query/clause/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,54 @@ pub use clause_adder::ClauseAdder;

// trait used to write assignments in a sql statement
mod assignment_adder;

#[cfg(feature = "unstable-api")]
mod or_and;
#[cfg(feature = "unstable-api")]
pub use or_and::ClauseAdderAndOrExt;
#[cfg(feature = "unstable-api")]
pub use or_and::and;
#[cfg(feature = "unstable-api")]
pub use or_and::or;

pub use assignment_adder::AssignmentAdder;

pub struct ClauseColVal<T> {
pub null_clause: bool,
pub not_clause: bool,
pub col: String,
pub col: &'static str,
pub operator: &'static str,
pub val: Option<T>,
}

pub struct ClauseColValEqual<T> {
pub null_clause: bool,
pub not_clause: bool,
pub col: String,
pub col: &'static str,
pub operator: &'static str,
pub val: Option<T>,
}

pub struct ClauseColValIn<T> {
pub col: String,
pub col: &'static str,
pub operator: &'static str,
pub list: Vec<T>,
}

pub struct ClauseColValList<T> {
pub col: String,
pub col: &'static str,
pub operator: &'static str,
pub list: Vec<T>,
}

pub struct ClauseColManual {
pub(crate) col: Option<String>,
pub(crate) col: Option<&'static str>,
pub(crate) sql: String,
pub(crate) params: Vec<Box<dyn Param + Send + Sync>>,
}

pub struct AssignmentManual {
pub(crate) col: String,
pub(crate) col: &'static str,
pub(crate) sql: String,
pub(crate) params: Vec<Box<dyn Param + Send + Sync>>,
}
Expand All @@ -77,8 +87,8 @@ pub struct AssignmentManual {
// fieldname refers to what we want to get the column out as.
// for example: select id as ids from bla.
pub trait AsFieldName<T> {
fn colname(&self) -> &str;
fn fieldname(&self) -> &str;
fn colname(&self) -> &'static str;
fn fieldname(&self) -> &'static str;
}

// marker trait to make sure a field is nullable
Expand Down
Loading