seaqs

A mini tool to convert a querystring into seaquery's condition.

Description

Let's say we have a user table and we want to provide a rest endpoint for some admin panel. With this crate we can define a filter struct and use it with seaquery(or seaorm, sqlx should work too).

```rust use serde::Deserialize; use seaquery::{Iden, Cond, Query, PostgresQueryBuilder}; use seaqs::{ApplyConds, ToCond, ToFieldCond, filters::*}; use serdequerystring::{from_str, de::ParseMode};

// It's part of the sea_query definition of a table.

[derive(Iden)]

enum User { Table, Id, Name, Age, Birthday, CreatedAt }

// And we define a filter struct like below

[derive(Deserialize)]

struct UserFilters<'a> { id: Option, name: Option>, age: Option, birthday: Option, created_at: Option, }

// Then we should impl the 'ToCond' trait, which should be done using a macro but there isn't one yet. impl<'a> ToCond for UserFilters<'a> { fn tocond(&self) -> Cond { let mut cond = Cond::all(); if let Some(id) = self.id.tocond(User::Id) { cond = cond.add(id) } if let Some(name) = self.name.tocond(User::Name) { cond = cond.add(name) } if let Some(age) = self.age.tocond(User::Age) { cond = cond.add(age) } if let Some(birthday) = self.birthday.tocond(User::Birthday) { cond = cond.add(birthday) } if let Some(createdat) = self.createdat.tocond(User::CreatedAt) { cond = cond.add(created_at) } cond } }

// I'm using serdequerystring here, but serdejson works too(whatever works with serdewith, works here) let filters = fromstr::( "age[lt]=50&age[gte]=20&name[contains]=John", ParseMode::Brackets, ) .unwrap();

// And create your query normally let q = Query::select() .column(User::Name) .from(User::Table) // Just use ApplyConds trait from seaqs .applyconds(&filters) // You shouldn't use tostring, it's just here for the test .to_string(PostgresQueryBuilder);

assert_eq!( q, r#"SELECT "name" FROM "user" WHERE "name" LIKE '%John%' AND ("age" >= 20 AND "age" < 50)"# );

// You can also use the provided QueryFilter to add sort/order/page/limit to your query. It's designed to work well with react-admin or similar admin panels.

use seaqs::{ApplyFilters, QueryFilter, Filter};

// You need to impl Filter for it to work impl<'a> Filter for UserFilters<'a> { const SORTABLEFIELDS: &'static [&'static str] = &["name", "age", "createdat"];

fn get_max_limit() -> i32 {
    100
}

}

// Notice that we need to use the filter key now. let filters = from_str::>( "filter[age][lt]=50&filter[age][gte]=20&filter[name][contains]=John&start=10&end=100&sort=age&order=DESC", ParseMode::Brackets, ) .unwrap();

// And create your query normally let q = Query::select() .column(User::Name) .from(User::Table) // Just use ApplyFilters trait from seaqs .applyfilters(&filters) // You shouldn't use tostring, it's just here for the test .to_string(PostgresQueryBuilder);

assert_eq!( q, r#"SELECT "name" FROM "user" WHERE "name" LIKE '%John%' AND ("age" >= 20 AND "age" < 50) ORDER BY "age" DESC LIMIT 90 OFFSET 10"# ) ```