Skip to content

Commit

Permalink
Merge pull request #139 from 0xYakuza/main
Browse files Browse the repository at this point in the history
Filters update
  • Loading branch information
al-abd authored Nov 22, 2023
2 parents 41ce316 + 7e284a6 commit 1a4954d
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 74 deletions.
50 changes: 1 addition & 49 deletions src/filter.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,5 @@
use serde::{Deserialize, Serialize};

/// Sort (SortBy)
#[derive(Deserialize, Serialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum Sort {
/// Sort by number
Number,

/// Sort by Name
/// Returns sorted T
Name,
}

impl Default for Sort {
fn default() -> Self {
Self::Number
}
}

/// Order the result list by ASC or DESC
#[derive(Deserialize, Serialize, Clone)]
#[serde(rename_all = "lowercase")]
Expand All @@ -35,38 +17,8 @@ impl Default for Order {
}
}

/// Possible Filters for Database Table
/// This list may change in future updates
#[derive(Deserialize, Serialize)]
pub struct BaseFilters {
pub sort: Option<Sort>,
pub order: Option<Order>,

pub from: Option<u64>,
pub to: Option<u64>,
}

impl Filters for BaseFilters {
fn sort(&self) -> Option<Sort> {
self.sort.clone()
}

fn order(&self) -> Option<Order> {
self.order.clone()
}

fn from(&self) -> Option<u64> {
self.from
}

fn to(&self) -> Option<u64> {
self.to
}
}

pub trait Filters {
fn sort(&self) -> Option<Sort>;
fn sort(&self) -> Option<String>;
fn order(&self) -> Option<Order>;
fn from(&self) -> Option<u64>;
fn to(&self) -> Option<u64>;
Expand Down
103 changes: 92 additions & 11 deletions src/models_filter.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::schema::quran_surahs::{table as quran_surahs_table, BoxedQuery};
use crate::models::{QuranMushaf, QuranSurah, Translation};
use crate::schema::mushafs::{table as quran_mushafs_table, BoxedQuery as MushafBoxedQuery};
use crate::schema::quran_surahs::{table as quran_surahs_table, BoxedQuery as SurahBoxedQuery};
use crate::schema::translations::{table as translations_table, BoxedQuery as TranslationBoxedQuery};
use crate::{
error::RouterError,
filter::{Filter, Filters, Order, Sort},
models::QuranSurah,
filter::{Filter, Filters, Order},
};
use diesel::pg::Pg;
use diesel::{prelude::*, query_dsl::methods::BoxedDsl};
Expand All @@ -25,25 +27,104 @@ use diesel::{prelude::*, query_dsl::methods::BoxedDsl};
//
// Also there is a macro simular for what we want in macros.rs file
impl Filter for QuranSurah {
type Output = Result<BoxedQuery<'static, Pg>, RouterError>;
type Output = Result<SurahBoxedQuery<'static, Pg>, RouterError>;

fn filter(filters: Box<dyn Filters>) -> Self::Output {
use crate::schema::quran_surahs::dsl::*;

let mut _query = quran_surahs_table.into_boxed();

_query = match filters.sort().unwrap_or_default() {
Sort::Name => match filters.order().unwrap_or_default() {
Order::Asc => quran_surahs.order(name.asc()).internal_into_boxed(),
Order::Desc => quran_surahs.order(name.desc()).internal_into_boxed(),
_query = match filters.sort() {
Some(sort_str) => match sort_str.as_str() {
"name" => Ok(match filters.order().unwrap_or_default() {
Order::Asc => quran_surahs.order(name.asc()).internal_into_boxed(),
Order::Desc => quran_surahs.order(name.desc()).internal_into_boxed(),
}),

"number" => Ok(match filters.order().unwrap_or_default() {
Order::Asc => quran_surahs.order(number.asc()).internal_into_boxed(),
Order::Desc => quran_surahs.order(number.desc()).internal_into_boxed(),
}),

value => Err(RouterError::BadRequest(format!(
"Sort value {} is not possible!",
value
))),
},

Sort::Number => match filters.order().unwrap_or_default() {
Order::Asc => quran_surahs.order(number.asc()).internal_into_boxed(),
Order::Desc => quran_surahs.order(number.desc()).internal_into_boxed(),
None => Ok(quran_surahs.internal_into_boxed()),
}?;

_query = match filters.to() {
Some(limit) => _query
.limit(limit as i64)
.offset(filters.from().unwrap_or_default() as i64),
None => _query.offset(filters.from().unwrap_or_default() as i64),
};

Ok(_query)
}
}

impl Filter for QuranMushaf {
type Output = Result<MushafBoxedQuery<'static, Pg>, RouterError>;

fn filter(filters: Box<dyn Filters>) -> Self::Output {
use crate::schema::mushafs::dsl::*;

let mut _query = quran_mushafs_table.into_boxed();

_query = match filters.sort() {
Some(sort_str) => match sort_str.as_str() {
"name" => Ok(match filters.order().unwrap_or_default() {
Order::Asc => mushafs.order(name.asc()).internal_into_boxed(),
Order::Desc => mushafs.order(name.desc()).internal_into_boxed(),
}),

value => Err(RouterError::BadRequest(format!(
"Sort value {} is not possible!",
value
))),
},

None => Ok(mushafs.internal_into_boxed()),
}?;

_query = match filters.to() {
Some(limit) => _query
.limit(limit as i64)
.offset(filters.from().unwrap_or_default() as i64),
None => _query.offset(filters.from().unwrap_or_default() as i64),
};

Ok(_query)
}
}

impl Filter for Translation {
type Output = Result<TranslationBoxedQuery<'static, Pg>, RouterError>;

fn filter(filters: Box<dyn Filters>) -> Self::Output {
use crate::schema::translations::dsl::*;

let mut _query = translations_table.into_boxed();

_query = match filters.sort() {
Some(sort_str) => match sort_str.as_str() {
"createTime" => Ok(match filters.order().unwrap_or_default() {
Order::Asc => translations.order(created_at.asc()).internal_into_boxed(),
Order::Desc => translations.order(created_at.desc()).internal_into_boxed(),
}),

value => Err(RouterError::BadRequest(format!(
"Sort value {} is not possible!",
value
))),
},

None => Ok(translations.internal_into_boxed()),
}?;

_query = match filters.to() {
Some(limit) => _query
.limit(limit as i64)
Expand Down
29 changes: 29 additions & 0 deletions src/routers/quran/mushaf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,39 @@ pub mod mushaf_view;

use serde::Deserialize;

use crate::filter::{Order, Filters};

#[derive(Deserialize)]
pub struct SimpleMushaf {
short_name: String,
name: String,
source: String,
bismillah_text: Option<String>,
}

#[derive(Deserialize)]
pub struct MushafListQuery {
sort: Option<String>,
order: Option<Order>,

from: Option<u64>,
to: Option<u64>,
}

impl Filters for MushafListQuery {
fn sort(&self) -> Option<String> {
self.sort.clone()
}

fn order(&self) -> Option<Order> {
self.order.clone()
}

fn from(&self) -> Option<u64> {
self.from
}

fn to(&self) -> Option<u64> {
self.to
}
}
13 changes: 9 additions & 4 deletions src/routers/quran/mushaf/mushaf_list.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
use crate::error::RouterError;
use crate::filter::Filter;
use crate::models::QuranMushaf;
use crate::DbPool;
use actix_web::web;
use diesel::prelude::*;

/// Get the lists of mushafs
pub async fn mushaf_list(pool: web::Data<DbPool>) -> Result<web::Json<Vec<QuranMushaf>>, RouterError> {
use crate::schema::mushafs::dsl::*;
use super::MushafListQuery;

/// Get the lists of mushafs
pub async fn mushaf_list(
pool: web::Data<DbPool>,
web::Query(query): web::Query<MushafListQuery>,
) -> Result<web::Json<Vec<QuranMushaf>>, RouterError> {
web::block(move || {
let mut conn = pool.get().unwrap();

// Get the list of mushafs from the database
let quran_mushafs = mushafs.load::<QuranMushaf>(&mut conn)?;
let quran_mushafs =
QuranMushaf::filter(Box::from(query))?.load::<QuranMushaf>(&mut conn)?;

Ok(web::Json(quran_mushafs))
})
Expand Down
6 changes: 3 additions & 3 deletions src/routers/quran/surah/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod surah_list;
pub mod surah_view;

use crate::{
filter::{Filters, Order, Sort},
filter::{Filters, Order},
models::QuranWord,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -71,15 +71,15 @@ pub struct GetSurahQuery {
pub struct SurahListQuery {
mushaf: String,

sort: Option<Sort>,
sort: Option<String>,
order: Option<Order>,

from: Option<u64>,
to: Option<u64>,
}

impl Filters for SurahListQuery {
fn sort(&self) -> Option<Sort> {
fn sort(&self) -> Option<String> {
self.sort.clone()
}

Expand Down
40 changes: 36 additions & 4 deletions src/routers/translation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
pub mod translation_add;
pub mod translation_delete;
pub mod translation_view;
pub mod translation_list;
pub mod translation_edit;
pub mod translation_list;
pub mod translation_text_delete;
pub mod translation_text_modify;
pub mod translation_text_view;
pub mod translation_text_delete;
pub mod translation_view;

use serde::{Serialize, Deserialize};
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::filter::{Filters, Order};

#[derive(Serialize, Deserialize)]
pub struct SimpleTranslation {
pub translator_account_uuid: Option<Uuid>,
Expand All @@ -24,3 +26,33 @@ pub struct SimpleTranslationText {
pub ayah_uuid: Uuid,
pub text: String,
}

#[derive(Serialize, Deserialize)]
pub struct TranslationListQuery {
mushaf: String,
master_account: Option<Uuid>,

sort: Option<String>,
order: Option<Order>,

from: Option<u64>,
to: Option<u64>,
}

impl Filters for TranslationListQuery {
fn sort(&self) -> Option<String> {
self.sort.clone()
}

fn order(&self) -> Option<Order> {
self.order.clone()
}

fn from(&self) -> Option<u64> {
self.from
}

fn to(&self) -> Option<u64> {
self.to
}
}
9 changes: 6 additions & 3 deletions src/routers/translation/translation_list.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
use crate::error::RouterError;
use crate::filter::Filter;
use crate::models::Translation;
use crate::DbPool;
use actix_web::web;
use diesel::prelude::*;

use super::TranslationListQuery;

/// Returns the list of translations
pub async fn translation_list(
pool: web::Data<DbPool>,
web::Query(query): web::Query<TranslationListQuery>,
) -> Result<web::Json<Vec<Translation>>, RouterError> {
use crate::schema::translations::dsl::*;

let result = web::block(move || {
let mut conn = pool.get().unwrap();

// Get the list of translations from the database
let translations_list = translations.load::<Translation>(&mut conn)?;
let translations_list =
Translation::filter(Box::from(query))?.load::<Translation>(&mut conn)?;

Ok(web::Json(translations_list))
})
Expand Down

0 comments on commit 1a4954d

Please sign in to comment.