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
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
2 changes: 1 addition & 1 deletion examples/actix4_example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use actix_web::{

use listenfd::ListenFd;
use sea_orm::DatabaseConnection;
use sea_orm::{entity::*, query::*};
use sea_orm::{entity::*, query::*, PaginatorTrait};
use serde::{Deserialize, Serialize};
use std::env;
use tera::Tera;
Expand Down
2 changes: 1 addition & 1 deletion examples/actix_example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use actix_web::{
};
use listenfd::ListenFd;
use sea_orm::DatabaseConnection;
use sea_orm::{entity::*, query::*};
use sea_orm::{entity::*, query::*, PaginatorTrait};
use serde::{Deserialize, Serialize};
use std::env;
use tera::Tera;
Expand Down
2 changes: 1 addition & 1 deletion examples/axum_example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use axum::{
};
use flash::{get_flash_cookie, post_response, PostResponse};
use post::Entity as Post;
use sea_orm::{prelude::*, Database, QueryOrder, Set};
use sea_orm::{prelude::*, Database, QueryOrder, Set, PaginatorTrait};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use std::{env, net::SocketAddr};
Expand Down
2 changes: 1 addition & 1 deletion examples/basic/src/operation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use sea_orm::{entity::*, error::*, query::*, DbConn};
use sea_orm::{entity::*, error::*, DbConn};

pub async fn all_about_operation(db: &DbConn) -> Result<(), DbErr> {
insert_and_update(db).await?;
Expand Down
2 changes: 1 addition & 1 deletion examples/basic/src/select.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use sea_orm::{entity::*, error::*, query::*, DbConn, FromQueryResult};
use sea_orm::{entity::*, error::*, query::*, DbConn, FromQueryResult, PaginatorTrait};

pub async fn all_about_select(db: &DbConn) -> Result<(), DbErr> {
find_all(db).await?;
Expand Down
2 changes: 1 addition & 1 deletion examples/rocket_example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rocket::response::{Flash, Redirect};
use rocket::{Build, Request, Rocket};
use rocket_dyn_templates::{context, Template};

use sea_orm::{entity::*, query::*};
use sea_orm::{entity::*, query::*, PaginatorTrait};
use sea_orm_rocket::{Connection, Database};

mod pool;
Expand Down
74 changes: 71 additions & 3 deletions src/executor/paginator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{error::*, ConnectionTrait, DbBackend, SelectorTrait};
use crate::{ConnectionTrait, DbBackend, EntityTrait, FromQueryResult, Select, SelectModel, SelectTwo, SelectTwoModel, Selector, SelectorTrait, error::*};
use async_stream::stream;
use futures::Stream;
use sea_query::{Alias, Expr, SelectStatement};
Expand Down Expand Up @@ -95,7 +95,7 @@ where
///
/// ```rust
/// # #[cfg(feature = "mock")]
/// # use sea_orm::{error::*, MockDatabase, DbBackend};
/// # use sea_orm::{error::*, MockDatabase, DbBackend, PaginatorTrait};
/// # let owned_db = MockDatabase::new(DbBackend::Postgres).into_connection();
/// # let db = &owned_db;
/// # let _: Result<(), DbErr> = smol::block_on(async {
Expand Down Expand Up @@ -123,7 +123,7 @@ where
///
/// ```rust
/// # #[cfg(feature = "mock")]
/// # use sea_orm::{error::*, MockDatabase, DbBackend};
/// # use sea_orm::{error::*, MockDatabase, DbBackend, PaginatorTrait};
/// # let owned_db = MockDatabase::new(DbBackend::Postgres).into_connection();
/// # let db = &owned_db;
/// # let _: Result<(), DbErr> = smol::block_on(async {
Expand Down Expand Up @@ -155,12 +155,80 @@ where
}
}

#[async_trait::async_trait]
/// Used to enforce constraints on any type that wants to paginate results
pub trait PaginatorTrait<'db, C>
where
C: ConnectionTrait<'db>,
{
/// Select operation
type Selector: SelectorTrait + Send + Sync + 'db;

/// Paginate the result of a select operation.
fn paginate(self, db: &'db C, page_size: usize) -> Paginator<'db, C, Self::Selector>;

/// Perform a count on the paginated results
async fn count(self, db: &'db C) -> Result<usize, DbErr>
where
Self: Send + Sized
{
self.paginate(db, 1).num_items().await
}
}

impl<'db, C, S> PaginatorTrait<'db, C> for Selector<S>
where
C: ConnectionTrait<'db>,
S: SelectorTrait + Send + Sync + 'db,
{
type Selector = S;

fn paginate(self, db: &'db C, page_size: usize) -> Paginator<'db, C, S> {
Paginator {
query: self.query,
page: 0,
page_size,
db,
selector: PhantomData,
}
}
}

impl<'db, C, M, E> PaginatorTrait<'db, C> for Select<E>
where
C: ConnectionTrait<'db>,
E: EntityTrait<Model = M>,
M: FromQueryResult + Sized + Send + Sync + 'db,
{
type Selector = SelectModel<M>;

fn paginate(self, db: &'db C, page_size: usize) -> Paginator<'db, C, Self::Selector> {
self.into_model().paginate(db, page_size)
}
}

impl<'db, C, M, N, E, F> PaginatorTrait<'db, C> for SelectTwo<E, F>
where
C: ConnectionTrait<'db>,
E: EntityTrait<Model = M>,
F: EntityTrait<Model = N>,
M: FromQueryResult + Sized + Send + Sync + 'db,
N: FromQueryResult + Sized + Send + Sync + 'db,
{
type Selector = SelectTwoModel<M, N>;

fn paginate(self, db: &'db C, page_size: usize) -> Paginator<'db, C, Self::Selector> {
self.into_model().paginate(db, page_size)
}
}

#[cfg(test)]
#[cfg(feature = "mock")]
mod tests {
use crate::entity::prelude::*;
use crate::{tests_cfg::*, ConnectionTrait};
use crate::{DatabaseConnection, DbBackend, MockDatabase, Transaction};
use super::*;
use futures::TryStreamExt;
use sea_query::{Alias, Expr, SelectStatement, Value};

Expand Down
58 changes: 2 additions & 56 deletions src/executor/select.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
error::*, ConnectionTrait, EntityTrait, FromQueryResult, IdenStatic, Iterable, ModelTrait,
Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,
PrimaryKeyToColumn, QueryResult, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,
Statement, TryGetableMany,
};
use futures::{Stream, TryStreamExt};
Expand All @@ -17,7 +17,7 @@ pub struct Selector<S>
where
S: SelectorTrait,
{
query: SelectStatement,
pub(crate) query: SelectStatement,
selector: S,
}

Expand Down Expand Up @@ -276,26 +276,6 @@ where
{
self.into_model().stream(db).await
}

/// Paginate the results of a SELECT operation on a Model
pub fn paginate<'a, C>(
self,
db: &'a C,
page_size: usize,
) -> Paginator<'a, C, SelectModel<E::Model>>
where
C: ConnectionTrait<'a>,
{
self.into_model().paginate(db, page_size)
}

/// Perform a `COUNT` operation on a items on a Model using pagination
pub async fn count<'a, C>(self, db: &'a C) -> Result<usize, DbErr>
where
C: ConnectionTrait<'a>,
{
self.paginate(db, 1).num_items().await
}
}

impl<E, F> SelectTwo<E, F>
Expand Down Expand Up @@ -350,26 +330,6 @@ where
{
self.into_model().stream(db).await
}

/// Paginate the results of a select operation on two models
pub fn paginate<'a, C>(
self,
db: &'a C,
page_size: usize,
) -> Paginator<'a, C, SelectTwoModel<E::Model, F::Model>>
where
C: ConnectionTrait<'a>,
{
self.into_model().paginate(db, page_size)
}

/// Perform a count on the paginated results
pub async fn count<'a, C>(self, db: &'a C) -> Result<usize, DbErr>
where
C: ConnectionTrait<'a>,
{
self.paginate(db, 1).num_items().await
}
}

impl<E, F> SelectTwoMany<E, F>
Expand Down Expand Up @@ -499,20 +459,6 @@ where
futures::future::ready(S::from_raw_query_result(row))
})))
}

/// Paginate the result of a select operation on a Model
pub fn paginate<'a, C>(self, db: &'a C, page_size: usize) -> Paginator<'a, C, S>
where
C: ConnectionTrait<'a>,
{
Paginator {
query: self.query,
page: 0,
page_size,
db,
selector: PhantomData,
}
}
}

impl<S> SelectorRaw<S>
Expand Down
2 changes: 1 addition & 1 deletion tests/basic.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub mod common;

pub use sea_orm::{entity::*, error::*, query::*, sea_query, tests_cfg::*, Database, DbConn};
pub use sea_orm::{entity::*, error::*, query::*, sea_query, tests_cfg::*, Database, DbConn, PaginatorTrait};

// cargo test --features sqlx-sqlite,runtime-async-std-native-tls --test basic
#[sea_orm_macros::test]
Expand Down
2 changes: 1 addition & 1 deletion tests/crud/updates.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use super::*;
use rust_decimal_macros::dec;
use sea_orm::DbErr;
use sea_orm::{DbErr, PaginatorTrait};
use uuid::Uuid;

pub async fn test_update_cake(db: &DbConn) {
Expand Down