Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PaginatorTrait and CountTrait for more constrains #306

Merged
merged 3 commits into from
Nov 10, 2021
Merged

Add PaginatorTrait and CountTrait for more constrains #306

merged 3 commits into from
Nov 10, 2021

Conversation

YoshieraHuang
Copy link
Contributor

When I build my web api using sea-orm, I want to constrain my select type to have paginate() method. So I added a PaginatorTrait and move the paginate() method to this trait. Meanwhile count() method of select type depends on paginate() method, but not all paginateable select has this method. So I added another CountTrait trait.

My use case of PaginatorTrait is like this:

// Data transfer object, aka dto
#[derive(Debug, Serialize)]
pub struct Paginated<T> {
    items: Vec<T>,
    page_size: usize,
    page_index: usize,
    num_pages: usize,
    num_items: usize,
    has_previous: bool,
    has_next: bool,
}

impl<T> Paginated<T>
{
    pub async fn query_with_map<'db, P, S, F>(
        db: &'db DatabaseConnection,
        paginate: P,
        page_size: usize,
        page_index: usize,
        predicate: F)
    -> Result<Self, DbErr>
    where
        P: PaginatorTrait<'db, DatabaseConnection, Selector = S>,
        S: SelectorTrait + 'db,
        F: FnMut(<S as SelectorTrait>::Item) -> T
    {
        let paginator = paginate.paginate(db, page_size);
        let original_items = paginator.fetch_page(page_index - 1).await?;
        let items = original_items.into_iter().map(predicate).collect();
        let num_pages = paginator.num_pages().await?;
        let num_items = paginator.num_items().await?;
        let has_previous = num_pages > 0 && page_index > 1;
        let has_next = num_pages > 0 && page_index < (num_pages - 1);
        Ok(Paginated {
            items,
            page_size,
            page_index,
            num_pages,
            num_items,
            has_previous,
            has_next
        })
    }
}

These traits may be used not so often but needed for me. It will be fine if this PR is merged.

By the way, if this PR will be merged, feel free to modify the docs and variable names, cause i'm not a native english speaker.

@tyt2y3
Copy link
Member

tyt2y3 commented Nov 9, 2021

Thank you so much for your contribution, again!
Can you point out which Struct has paginate but not count?
I think we should fix them indeed.

@YoshieraHuang
Copy link
Contributor Author

Thank you so much for your contribution, again! Can you point out which Struct has paginate but not count? I think we should fix them indeed.

Selector struct has paginate but not count. Select and SelectTwo have both method but in their paginate method, they are converted to Selector and then do pagination. SelectTwoMany does not have both since its pagination is not easy. I think implementing count for Selector is not bad. I will move count into PaginatorTrait.

@billy1624 billy1624 merged commit 0518199 into SeaQL:master Nov 10, 2021
@billy1624
Copy link
Member

OMG... I'm sorry didn't mean to merge this now

@tyt2y3
Copy link
Member

tyt2y3 commented Nov 10, 2021

Open a new PR or if it's minor just push onto master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants