feat(labrinth): basic offset pagination for moderation reports and projects (#4063)

This commit is contained in:
Alejandro González
2025-07-26 14:32:35 +02:00
committed by GitHub
parent 6db1d66591
commit 358cf31c87
8 changed files with 46 additions and 28 deletions

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT id FROM reports\n WHERE closed = FALSE\n ORDER BY created ASC\n LIMIT $1;\n ",
"query": "\n SELECT id FROM reports\n WHERE closed = FALSE\n ORDER BY created ASC\n OFFSET $2\n LIMIT $1\n ",
"describe": {
"columns": [
{
@@ -11,6 +11,7 @@
],
"parameters": {
"Left": [
"Int8",
"Int8"
]
},
@@ -18,5 +19,5 @@
false
]
},
"hash": "29e171bd746ac5dc1fabae4c9f81c3d1df4e69c860b7d0f6a907377664199217"
"hash": "1aea0d5e6936b043cb7727b779d60598aa812c8ef0f5895fa740859321092a1c"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT id FROM reports\n WHERE closed = FALSE AND reporter = $1\n ORDER BY created ASC\n LIMIT $2;\n ",
"query": "\n SELECT id FROM reports\n WHERE closed = FALSE AND reporter = $1\n ORDER BY created ASC\n OFFSET $3\n LIMIT $2\n ",
"describe": {
"columns": [
{
@@ -11,6 +11,7 @@
],
"parameters": {
"Left": [
"Int8",
"Int8",
"Int8"
]
@@ -19,5 +20,5 @@
false
]
},
"hash": "f17a109913015a7a5ab847bb2e73794d6261a08d450de24b450222755e520881"
"hash": "be8a5dd2b71fdc279a6fa68fe5384da31afd91d4b480527e2dd8402aef36f12c"
}

View File

@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT id FROM mods\n WHERE status = $1\n ORDER BY queued ASC\n LIMIT $2;\n ",
"query": "\n SELECT id FROM mods\n WHERE status = $1\n ORDER BY queued ASC\n OFFSET $3\n LIMIT $2\n ",
"describe": {
"columns": [
{
@@ -12,6 +12,7 @@
"parameters": {
"Left": [
"Text",
"Int8",
"Int8"
]
},
@@ -19,5 +20,5 @@
false
]
},
"hash": "3baabc9f08401801fa290866888c540746fc50c1d79911f08f3322b605ce5c30"
"hash": "ccb0315ff52ea4402f53508334a7288fc9f8e77ffd7bce665441ff682384cbf9"
}

View File

@@ -0,0 +1 @@
CREATE INDEX reports_closed ON reports (closed);

View File

@@ -18,12 +18,14 @@ pub fn config(cfg: &mut web::ServiceConfig) {
}
#[derive(Deserialize)]
pub struct ResultCount {
pub struct ProjectsRequestOptions {
#[serde(default = "default_count")]
pub count: i16,
pub count: u16,
#[serde(default)]
pub offset: u32,
}
fn default_count() -> i16 {
fn default_count() -> u16 {
100
}
@@ -31,7 +33,7 @@ pub async fn get_projects(
req: HttpRequest,
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
count: web::Query<ResultCount>,
request_opts: web::Query<ProjectsRequestOptions>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
check_is_moderator_from_headers(
@@ -50,10 +52,12 @@ pub async fn get_projects(
SELECT id FROM mods
WHERE status = $1
ORDER BY queued ASC
LIMIT $2;
OFFSET $3
LIMIT $2
",
ProjectStatus::Processing.as_str(),
count.count as i64
request_opts.count as i64,
request_opts.offset as i64
)
.fetch(&**pool)
.map_ok(|m| database::models::DBProjectId(m.id))

View File

@@ -15,10 +15,10 @@ pub fn config(cfg: &mut web::ServiceConfig) {
#[derive(Deserialize)]
pub struct ResultCount {
#[serde(default = "default_count")]
pub count: i16,
pub count: u16,
}
fn default_count() -> i16 {
fn default_count() -> u16 {
100
}
@@ -34,7 +34,10 @@ pub async fn get_projects(
req,
pool.clone(),
redis.clone(),
web::Query(internal::moderation::ResultCount { count: count.count }),
web::Query(internal::moderation::ProjectsRequestOptions {
count: count.count,
offset: 0,
}),
session_queue,
)
.await

View File

@@ -43,12 +43,12 @@ pub async fn report_create(
#[derive(Deserialize)]
pub struct ReportsRequestOptions {
#[serde(default = "default_count")]
count: i16,
count: u16,
#[serde(default = "default_all")]
all: bool,
}
fn default_count() -> i16 {
fn default_count() -> u16 {
100
}
fn default_all() -> bool {
@@ -60,7 +60,7 @@ pub async fn reports(
req: HttpRequest,
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
count: web::Query<ReportsRequestOptions>,
request_opts: web::Query<ReportsRequestOptions>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
let response = v3::reports::reports(
@@ -68,8 +68,9 @@ pub async fn reports(
pool,
redis,
web::Query(v3::reports::ReportsRequestOptions {
count: count.count,
all: count.all,
count: request_opts.count,
offset: 0,
all: request_opts.all,
}),
session_queue,
)

View File

@@ -222,12 +222,14 @@ pub async fn report_create(
#[derive(Deserialize)]
pub struct ReportsRequestOptions {
#[serde(default = "default_count")]
pub count: i16,
pub count: u16,
#[serde(default)]
pub offset: u32,
#[serde(default = "default_all")]
pub all: bool,
}
fn default_count() -> i16 {
fn default_count() -> u16 {
100
}
fn default_all() -> bool {
@@ -238,7 +240,7 @@ pub async fn reports(
req: HttpRequest,
pool: web::Data<PgPool>,
redis: web::Data<RedisPool>,
count: web::Query<ReportsRequestOptions>,
request_opts: web::Query<ReportsRequestOptions>,
session_queue: web::Data<AuthQueue>,
) -> Result<HttpResponse, ApiError> {
let user = get_user_from_headers(
@@ -253,15 +255,17 @@ pub async fn reports(
use futures::stream::TryStreamExt;
let report_ids = if user.role.is_mod() && count.all {
let report_ids = if user.role.is_mod() && request_opts.all {
sqlx::query!(
"
SELECT id FROM reports
WHERE closed = FALSE
ORDER BY created ASC
LIMIT $1;
OFFSET $2
LIMIT $1
",
count.count as i64
request_opts.count as i64,
request_opts.offset as i64
)
.fetch(&**pool)
.map_ok(|m| crate::database::models::ids::DBReportId(m.id))
@@ -273,10 +277,12 @@ pub async fn reports(
SELECT id FROM reports
WHERE closed = FALSE AND reporter = $1
ORDER BY created ASC
LIMIT $2;
OFFSET $3
LIMIT $2
",
user.id.0 as i64,
count.count as i64
request_opts.count as i64,
request_opts.offset as i64
)
.fetch(&**pool)
.map_ok(|m| crate::database::models::ids::DBReportId(m.id))