Add PaginatorTrait and CountTrait
This commit is contained in:
parent
03d90d8630
commit
23498892b0
@ -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 async_stream::stream;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use sea_query::{Alias, Expr, SelectStatement};
|
use sea_query::{Alias, Expr, SelectStatement};
|
||||||
@ -95,7 +95,7 @@ where
|
|||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #[cfg(feature = "mock")]
|
/// # #[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 owned_db = MockDatabase::new(DbBackend::Postgres).into_connection();
|
||||||
/// # let db = &owned_db;
|
/// # let db = &owned_db;
|
||||||
/// # let _: Result<(), DbErr> = smol::block_on(async {
|
/// # let _: Result<(), DbErr> = smol::block_on(async {
|
||||||
@ -123,7 +123,7 @@ where
|
|||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #[cfg(feature = "mock")]
|
/// # #[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 owned_db = MockDatabase::new(DbBackend::Postgres).into_connection();
|
||||||
/// # let db = &owned_db;
|
/// # let db = &owned_db;
|
||||||
/// # let _: Result<(), DbErr> = smol::block_on(async {
|
/// # let _: Result<(), DbErr> = smol::block_on(async {
|
||||||
@ -155,12 +155,92 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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 + 'db;
|
||||||
|
|
||||||
|
/// Paginate the result of a select operation.
|
||||||
|
fn paginate(self, db: &'db C, page_size: usize) -> Paginator<'db, C, Self::Selector>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'db, C, S> PaginatorTrait<'db, C> for Selector<S>
|
||||||
|
where
|
||||||
|
C: ConnectionTrait<'db>,
|
||||||
|
S: SelectorTrait + '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 + '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 + 'db,
|
||||||
|
N: FromQueryResult + Sized + '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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to enforce constraints on any type that wants to count results using pagination.
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
pub trait CountTrait<'db, C>: PaginatorTrait<'db, C>
|
||||||
|
where
|
||||||
|
C: ConnectionTrait<'db>,
|
||||||
|
{
|
||||||
|
/// Perform a count on the paginated results
|
||||||
|
async fn count(self, db: &'db C) -> Result<usize, DbErr>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl<'db, C, P, S> CountTrait<'db, C> for P
|
||||||
|
where
|
||||||
|
C: ConnectionTrait<'db>,
|
||||||
|
P: PaginatorTrait<'db, C, Selector = S> + Send,
|
||||||
|
S: SelectorTrait + Send + Sync + 'db
|
||||||
|
{
|
||||||
|
async fn count(self, db:&'db C) -> Result<usize, DbErr> {
|
||||||
|
self.paginate(db, 1).num_items().await
|
||||||
|
}
|
||||||
|
}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::entity::prelude::*;
|
use crate::entity::prelude::*;
|
||||||
use crate::{tests_cfg::*, ConnectionTrait};
|
use crate::{tests_cfg::*, ConnectionTrait};
|
||||||
use crate::{DatabaseConnection, DbBackend, MockDatabase, Transaction};
|
use crate::{DatabaseConnection, DbBackend, MockDatabase, Transaction};
|
||||||
|
use super::*;
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use sea_query::{Alias, Expr, SelectStatement, Value};
|
use sea_query::{Alias, Expr, SelectStatement, Value};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::*, ConnectionTrait, EntityTrait, FromQueryResult, IdenStatic, Iterable, ModelTrait,
|
error::*, ConnectionTrait, EntityTrait, FromQueryResult, IdenStatic, Iterable, ModelTrait,
|
||||||
Paginator, PrimaryKeyToColumn, QueryResult, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,
|
PrimaryKeyToColumn, QueryResult, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,
|
||||||
Statement, TryGetableMany,
|
Statement, TryGetableMany,
|
||||||
};
|
};
|
||||||
use futures::{Stream, TryStreamExt};
|
use futures::{Stream, TryStreamExt};
|
||||||
@ -17,7 +17,7 @@ pub struct Selector<S>
|
|||||||
where
|
where
|
||||||
S: SelectorTrait,
|
S: SelectorTrait,
|
||||||
{
|
{
|
||||||
query: SelectStatement,
|
pub(crate) query: SelectStatement,
|
||||||
selector: S,
|
selector: S,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,26 +276,6 @@ where
|
|||||||
{
|
{
|
||||||
self.into_model().stream(db).await
|
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>
|
impl<E, F> SelectTwo<E, F>
|
||||||
@ -350,26 +330,6 @@ where
|
|||||||
{
|
{
|
||||||
self.into_model().stream(db).await
|
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>
|
impl<E, F> SelectTwoMany<E, F>
|
||||||
@ -499,20 +459,6 @@ where
|
|||||||
futures::future::ready(S::from_raw_query_result(row))
|
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>
|
impl<S> SelectorRaw<S>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
pub use super::*;
|
pub use super::*;
|
||||||
use rust_decimal_macros::dec;
|
use rust_decimal_macros::dec;
|
||||||
use sea_orm::DbErr;
|
use sea_orm::{DbErr, CountTrait};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub async fn test_update_cake(db: &DbConn) {
|
pub async fn test_update_cake(db: &DbConn) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user