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
25 changes: 15 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@

`.` minor | `+` Addition | `^` improvement | `!` Change | `*` Refactor

## 2024-11-15 - `0.4.1-WIP`

- `^` Update `sea-query` and `rustsqlite` to version `0.32`
- `!` Remove `cast_column_as` from filter, it's now on field

## 2024-09-23 - `0.4.0`

- `.` update to sea-query-rusqlite 0.6
- `.` add rustfmt.toml
- `^` Update sea-query version `0.31
- `^` Update sea-query version `0.31`
- `+` Add CaseInsensitive for StringOpVals (`StartsWithCt` .. )
- `+` Add ILIKE for postgres (case-insensitive LIKE)

Expand All @@ -23,7 +28,7 @@
- Traits:
- Now: `SqliteFromRow`, before: `FromSqliteRow`
- Now: `fn sqlite_from_row`, before: `fn from_sqlite_row...`
- derive:
- derive:
- Now: `SqliteFromValue`, before: `FromSqliteRow`
- Now: `SqliteFromValue`, before: `FromSqliteValue`
- Now: `ToSqliteValue`, before: `SqliteToValue`
Expand All @@ -36,7 +41,7 @@
- `.` update to v0.4.0-rc.5
- `^` sea-query - impl IdenStatic for SIden (and SIden: Clone + Copy)

## 2024-04-18 - `0.4.0-rc.4`
## 2024-04-18 - `0.4.0-rc.4`

- SEE: Major refactor/cleanup (see [v0.3.x to v0.4.x document](MIGRATION-v03x-v04x.md)
- `+` ToSqliteValue - added ToSqliteValue for simple enum and single tuple struct
Expand All @@ -47,7 +52,7 @@
- `!` filter - rename context_path to rel
- `^` SeaField - add new_concrete

## 2024-03-07 - `0.4.0-rc.2`
## 2024-03-07 - `0.4.0-rc.2`

- `!` Major refactor/cleanup (see [v0.3.x to v0.4.x document](MIGRATION-v03x-v04x.md)

Expand All @@ -62,7 +67,7 @@

- `!` Rename FromSqliteRow::from_rusqlite_row to FromSqliteRow::from_sqlite_row)
- `!` Change sqlite::FromRow to FromSqliteRow
- `+` FromSqliteValue for enum
- `+` FromSqliteValue for enum
- `+` Add `field::FieldEnum` derive to implement to seaqueryvalue for simple enum (also some code relayout)

## 2024-01-29 - `0.3.8`
Expand All @@ -72,8 +77,8 @@
## 2024-01-22 - `0.3.7`

- `+` `cast_as` to `filter`
- `!` Potential API break for user using `FieldNode` struct constructor (e.g., `FieldNode {...}`). New property `options: FieldNodeOptions`. Use `options: FieldNodeOptions::default()`.
- Using the `FieldNode::new(...)` functions and every other interface should be unchanged.
- `!` Potential API break for user using `FieldNode` struct constructor (e.g., `FieldNode {...}`). New property `options: FieldNodeOptions`. Use `options: FieldNodeOptions::default()`.
- Using the `FieldNode::new(...)` functions and every other interface should be unchanged.

## 2024-01-20 - `0.3.6`

Expand Down Expand Up @@ -118,7 +123,7 @@

## 2023-04-04 - `0.1.0`

- `!` - Major refactoring from `0.0.5`.
- `!` - Major refactoring from `0.0.5`.
- `!` - Moved from raw `Vec..` to specialized type `FilterGroups` and `FilterGroup`.
- `!` - Rename all of the `[Type]OpVal` to `OpVal[Type]` with full num type description.
- `+` - Implemented lot of `From` traits.
- `!` - Rename all of the `[Type]OpVal` to `OpVal[Type]` with full num type description.
- `+` - Implemented lot of `From` traits.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ rusqlite = { workspace = true, optional = true }

[workspace.dependencies]
sea-query = { version = "0.32", features = ["thread-safe"] }
rusqlite = { version = "0.31" }
rusqlite = { version = "0.32" }

[dev-dependencies]
serde_with = "3"
rusqlite = {version = "0.31", features = ["bundled"]}
sea-query-rusqlite = {version = "0.6"}
rusqlite = {version = "0.32", features = ["bundled"]}
sea-query-rusqlite = {version = "0.7"}

7 changes: 7 additions & 0 deletions modql-macros/src/derives_filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,16 @@ pub fn derive_filter_nodes_inner(input: TokenStream) -> TokenStream {
} else {
quote! { None }
};

let quote_filter_node_options_cast_column_as = if let Some(cast_column_as) = modql_field_attr.cast_column_as {
quote! { Some(#cast_column_as.to_string()) }
} else {
quote! { None }
};
props_filter_node_options.push(quote! {
modql::filter::FilterNodeOptions {
cast_as: #quote_filter_node_options_cast_as,
cast_column_as: #quote_filter_node_options_cast_column_as,
}
});

Expand Down
6 changes: 5 additions & 1 deletion modql-macros/src/derives_filter/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct MoqlFilterFieldAttr {
pub to_sea_condition_fn: Option<String>,
pub to_sea_value_fn: Option<String>,
pub cast_as: Option<String>,
pub cast_column_as: Option<String>,
}

pub fn get_filter_field_attr(field: &Field) -> Result<MoqlFilterFieldAttr, syn::Error> {
Expand All @@ -17,7 +18,7 @@ pub fn get_filter_field_attr(field: &Field) -> Result<MoqlFilterFieldAttr, syn::
let mut to_sea_condition_fn: Option<String> = None;
let mut to_sea_value_fn: Option<String> = None;
let mut cast_as: Option<String> = None;

let mut cast_column_as: Option<String> = None;
if let Some(attribute) = attribute {
let nested = attribute.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?;

Expand All @@ -33,6 +34,8 @@ pub fn get_filter_field_attr(field: &Field) -> Result<MoqlFilterFieldAttr, syn::
cast_as = get_meta_value_string(nv);
} else if nv.path.is_ident("rel") {
rel = get_meta_value_string(nv);
} else if nv.path.is_ident("cast_column_as") {
cast_column_as = get_meta_value_string(nv);
}
}

Expand All @@ -50,5 +53,6 @@ pub fn get_filter_field_attr(field: &Field) -> Result<MoqlFilterFieldAttr, syn::
to_sea_condition_fn,
to_sea_value_fn,
cast_as,
cast_column_as,
})
}
1 change: 1 addition & 0 deletions src/filter/nodes/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub trait IntoFilterNodes {
#[derive(Debug, Clone, Default)]
pub struct FilterNodeOptions {
pub cast_as: Option<String>, // for db casting. e.g., Will be applied to sea-query value.
pub cast_column_as: Option<String>, // for db casting. e.g., Will be applied to sea-query column.
}

#[derive(Debug, Clone)]
Expand Down
11 changes: 7 additions & 4 deletions src/filter/ops/op_val_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ mod json {
mod with_sea_query {
use super::*;
use crate::filter::{sea_is_col_value_null, FilterNodeOptions, SeaResult};
use crate::into_node_value_expr;
use crate::{into_node_column_expr, into_node_value_expr};
use sea_query::{BinOper, ColumnRef, Condition, ConditionExpression, Expr, Func, SimpleExpr};

#[cfg(feature = "with-ilike")]
Expand All @@ -215,19 +215,22 @@ mod with_sea_query {
) -> SeaResult<ConditionExpression> {
let binary_fn = |op: BinOper, v: String| {
let vxpr = into_node_value_expr(v, node_options);
ConditionExpression::SimpleExpr(SimpleExpr::binary(col.clone().into(), op, vxpr))
let column = into_node_column_expr(col.clone(), node_options);
ConditionExpression::SimpleExpr(SimpleExpr::binary(column.into(), op, vxpr))
};

#[cfg(feature = "with-ilike")]
let pg_binary_fn = |op: PgBinOper, v: String| {
let vxpr = into_node_value_expr(v, node_options);
ConditionExpression::SimpleExpr(SimpleExpr::binary(col.clone().into(), BinOper::PgOperator(op), vxpr))
let column = into_node_column_expr(col.clone(), node_options);
ConditionExpression::SimpleExpr(SimpleExpr::binary(column.into(), BinOper::PgOperator(op), vxpr))
};

let binaries_fn = |op: BinOper, v: Vec<String>| {
let vxpr_list: Vec<SimpleExpr> = v.into_iter().map(|v| into_node_value_expr(v, node_options)).collect();
let vxpr = SimpleExpr::Tuple(vxpr_list);
ConditionExpression::SimpleExpr(SimpleExpr::binary(col.clone().into(), op, vxpr))
let column = into_node_column_expr(col.clone(), node_options);
ConditionExpression::SimpleExpr(SimpleExpr::binary(column.into(), op, vxpr))
};

let cond_any_of_fn = |op: BinOper, values: Vec<String>, val_prefix: &str, val_suffix: &str| {
Expand Down
16 changes: 5 additions & 11 deletions src/filter/ops/op_val_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ mod json {
mod with_sea_query {
use super::*;
use crate::filter::{sea_is_col_value_null, FilterNodeOptions, SeaResult, ToSeaValueFnHolder};
use crate::into_node_value_expr;
use crate::{into_node_column_expr, into_node_value_expr};
use sea_query::{BinOper, ColumnRef, ConditionExpression, SimpleExpr};

impl OpValValue {
Expand All @@ -104,11 +104,8 @@ mod with_sea_query {
let sea_value = to_sea_value.call(json_value)?;

let vxpr = into_node_value_expr(sea_value, node_options);
Ok(ConditionExpression::SimpleExpr(SimpleExpr::binary(
col.clone().into(),
op,
vxpr,
)))
let column = into_node_column_expr(col.clone(), node_options);
Ok(ConditionExpression::SimpleExpr(SimpleExpr::binary(column.into(), op,vxpr)))
};

// -- CondExpr builder for single value
Expand All @@ -125,11 +122,8 @@ mod with_sea_query {
let vxpr = SimpleExpr::Tuple(vxpr_list);

// -- Return the condition expression
Ok(ConditionExpression::SimpleExpr(SimpleExpr::binary(
col.clone().into(),
op,
vxpr,
)))
let column = into_node_column_expr(col.clone(), node_options);
Ok(ConditionExpression::SimpleExpr(SimpleExpr::binary(column.into(), op, vxpr)))
};

let cond = match self {
Expand Down
11 changes: 10 additions & 1 deletion src/sea_utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::filter::FilterNodeOptions;
use sea_query::{Iden, IdenStatic, SimpleExpr, Value};
use sea_query::{ColumnRef, Iden, IdenStatic, SimpleExpr, Value};

/// String sea-query `Iden` wrapper
#[derive(Debug)]
Expand Down Expand Up @@ -44,3 +44,12 @@ where
}
vxpr
}

pub fn into_node_column_expr(col: ColumnRef, node_options: &FilterNodeOptions) -> SimpleExpr {
let Some(cast_column_as) = &node_options.cast_column_as else {
// If no cast is needed, wrap the ColumnRef as a SimpleExpr
return SimpleExpr::Column(col);
};

SimpleExpr::Column(col).cast_as(StringIden(cast_column_as.to_string()))
}
3 changes: 2 additions & 1 deletion tests/test_expand_filter_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct ProjectFilter {
#[modql(rel = "task_tbl")]
pub struct TaskFilter {
id: Option<OpValsInt64>,
#[modql(cast_column_as = "text")]
title: Option<OpValsString>,
#[modql(rel = "foo_rel")]
label: Option<OpValsString>,
Expand All @@ -44,7 +45,7 @@ fn test_expand_filter_nodes_filter_rel() -> Result<()> {

// -- Check
assert!(
sql.contains(r#"WHERE "task_tbl"."id" = ? AND "task_tbl"."title" = ? AND "foo_rel"."label" = ?"#),
sql.contains(r#"WHERE "task_tbl"."id" = ? AND CAST("task_tbl"."title" AS text) = ? AND "foo_rel"."label" = ?"#),
"Incorrect where statment"
);

Expand Down