Skip to content

Commit dc40b69

Browse files
committed
feat: allow an easier use of limit/offset
1 parent a321f0a commit dc40b69

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

src/executor/limiter.rs

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
use crate::{
2+
ConnectionTrait, DbErr, EntityTrait, FromQueryResult, Paginator, PaginatorTrait, QuerySelect,
3+
Select, SelectModel, SelectTwo, SelectTwoMany, SelectTwoModel, Selector, SelectorTrait,
4+
};
5+
use std::num::NonZeroU64;
6+
7+
#[derive(Debug)]
8+
pub struct Limiter<'db, C, S>
9+
where
10+
C: ConnectionTrait,
11+
S: SelectorTrait + 'db,
12+
{
13+
db: &'db C,
14+
selector: Selector<S>,
15+
paginator: Paginator<'db, C, S>,
16+
}
17+
18+
impl<'db, C, S> Limiter<'db, C, S>
19+
where
20+
C: ConnectionTrait,
21+
S: SelectorTrait + 'db,
22+
{
23+
pub async fn fetch(self) -> Result<Vec<S::Item>, DbErr> {
24+
self.selector.all(self.db).await
25+
}
26+
27+
pub async fn total(&self) -> Result<u64, DbErr> {
28+
self.paginator.num_items().await
29+
}
30+
}
31+
32+
pub trait LimiterTrait<'db, C>
33+
where
34+
C: ConnectionTrait,
35+
{
36+
type Selector: SelectorTrait + 'db;
37+
38+
fn limiting(self, db: &'db C, offset: u64, limit: u64) -> Limiter<'db, C, Self::Selector>;
39+
}
40+
41+
impl<'db, C, M, E> LimiterTrait<'db, C> for Select<E>
42+
where
43+
C: ConnectionTrait,
44+
E: EntityTrait<Model = M>,
45+
M: FromQueryResult + Sized + Send + Sync + 'db,
46+
{
47+
type Selector = SelectModel<M>;
48+
49+
fn limiting(self, db: &'db C, offset: u64, limit: u64) -> Limiter<'db, C, Self::Selector> {
50+
let selector = self
51+
.clone()
52+
.limit(NonZeroU64::new(limit).map(|limit| limit.get()))
53+
.offset(NonZeroU64::new(offset).map(|offset| offset.get()))
54+
.into_model();
55+
56+
Limiter {
57+
db,
58+
paginator: self.clone().paginate(db, 1),
59+
selector,
60+
}
61+
}
62+
}
63+
64+
impl<'db, C, M1, M2, E1, E2> LimiterTrait<'db, C> for SelectTwo<E1, E2>
65+
where
66+
C: ConnectionTrait,
67+
E1: EntityTrait<Model = M1>,
68+
E2: EntityTrait<Model = M2>,
69+
M1: FromQueryResult + Sized + Send + Sync + 'db,
70+
M2: FromQueryResult + Sized + Send + Sync + 'db,
71+
{
72+
type Selector = SelectTwoModel<M1, M2>;
73+
74+
fn limiting(self, db: &'db C, offset: u64, limit: u64) -> Limiter<'db, C, Self::Selector> {
75+
let selector = self
76+
.clone()
77+
.limit(NonZeroU64::new(limit).map(|limit| limit.get()))
78+
.offset(NonZeroU64::new(offset).map(|offset| offset.get()))
79+
.into_model();
80+
81+
Limiter {
82+
db,
83+
paginator: self.clone().paginate(db, 1),
84+
selector,
85+
}
86+
}
87+
}

src/executor/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod cursor;
22
mod delete;
33
mod execute;
44
mod insert;
5+
mod limiter;
56
mod paginator;
67
mod query;
78
mod select;
@@ -11,6 +12,7 @@ pub use cursor::*;
1112
pub use delete::*;
1213
pub use execute::*;
1314
pub use insert::*;
15+
pub use limiter::*;
1416
pub use paginator::*;
1517
pub use query::*;
1618
pub use select::*;

0 commit comments

Comments
 (0)