feat: only return committed packages from the api

concurrent-repos
Jef Roosens 2024-06-19 22:07:30 +02:00
parent 730ae009b0
commit 76395afb10
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
6 changed files with 41 additions and 37 deletions

View File

@ -22,10 +22,10 @@ async fn get_repos(
Query(pagination): Query<pagination::Query>, Query(pagination): Query<pagination::Query>,
Query(filter): Query<db::query::repo::Filter>, Query(filter): Query<db::query::repo::Filter>,
) -> crate::Result<Json<PaginatedResponse<db::repo::Model>>> { ) -> crate::Result<Json<PaginatedResponse<db::repo::Model>>> {
let (total_pages, items) = let items =
db::query::repo::page(&global.db, pagination.per_page, pagination.page - 1, filter).await?; db::query::repo::page(&global.db, pagination.per_page, pagination.page - 1, filter).await?;
Ok(Json(pagination.res(total_pages, items))) Ok(Json(pagination.res(items)))
} }
async fn get_single_repo( async fn get_single_repo(
@ -44,11 +44,11 @@ async fn get_packages(
Query(pagination): Query<pagination::Query>, Query(pagination): Query<pagination::Query>,
Query(filter): Query<db::query::package::Filter>, Query(filter): Query<db::query::package::Filter>,
) -> crate::Result<Json<PaginatedResponse<db::package::Model>>> { ) -> crate::Result<Json<PaginatedResponse<db::package::Model>>> {
let (total_pages, pkgs) = let items =
db::query::package::page(&global.db, pagination.per_page, pagination.page - 1, filter) db::query::package::page(&global.db, pagination.per_page, pagination.page - 1, filter)
.await?; .await?;
Ok(Json(pagination.res(total_pages, pkgs))) Ok(Json(pagination.res(items)))
} }
async fn get_single_package( async fn get_single_package(

View File

@ -1,19 +1,19 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(default)]
pub struct Query { pub struct Query {
#[serde(default = "default_page")]
pub page: u64, pub page: u64,
#[serde(default = "default_per_page")]
pub per_page: u64, pub per_page: u64,
} }
impl Default for Query { fn default_page() -> u64 {
fn default() -> Self { 1
Query {
page: 1,
per_page: 25,
}
} }
fn default_per_page() -> u64 {
25
} }
#[derive(Serialize)] #[derive(Serialize)]
@ -23,21 +23,15 @@ where
{ {
pub page: u64, pub page: u64,
pub per_page: u64, pub per_page: u64,
pub total_pages: u64,
pub count: usize, pub count: usize,
pub items: Vec<T>, pub items: Vec<T>,
} }
impl Query { impl Query {
pub fn res<T: for<'de> Serialize>( pub fn res<T: for<'de> Serialize>(self, items: Vec<T>) -> PaginatedResponse<T> {
self,
total_pages: u64,
items: Vec<T>,
) -> PaginatedResponse<T> {
PaginatedResponse { PaginatedResponse {
page: self.page, page: self.page,
per_page: self.per_page, per_page: self.per_page,
total_pages,
count: items.len(), count: items.len(),
items, items,
} }

View File

@ -26,6 +26,7 @@ pub struct Model {
pub pgp_sig_size: Option<i64>, pub pgp_sig_size: Option<i64>,
pub sha256_sum: String, pub sha256_sum: String,
pub compression: String, pub compression: String,
#[serde(skip_serializing)]
pub state: PackageState, pub state: PackageState,
} }

View File

@ -21,15 +21,14 @@ pub async fn page(
per_page: u64, per_page: u64,
page: u64, page: u64,
filter: Filter, filter: Filter,
) -> Result<(u64, Vec<distro::Model>)> { ) -> Result<Vec<distro::Model>> {
let paginator = Distro::find() let paginator = Distro::find()
.filter(filter) .filter(filter)
.order_by_asc(distro::Column::Id) .order_by_asc(distro::Column::Id)
.paginate(conn, per_page); .paginate(conn, per_page);
let repos = paginator.fetch_page(page).await?; let repos = paginator.fetch_page(page).await?;
let total_pages = paginator.num_pages().await?;
Ok((total_pages, repos)) Ok(repos)
} }
pub async fn by_id(conn: &DbConn, id: i32) -> Result<Option<distro::Model>> { pub async fn by_id(conn: &DbConn, id: i32) -> Result<Option<distro::Model>> {

View File

@ -17,10 +17,7 @@ impl IntoCondition for Filter {
Condition::all() Condition::all()
.add_option(self.repo.map(|repo| package::Column::RepoId.eq(repo))) .add_option(self.repo.map(|repo| package::Column::RepoId.eq(repo)))
.add_option(self.arch.map(|arch| package::Column::Arch.eq(arch))) .add_option(self.arch.map(|arch| package::Column::Arch.eq(arch)))
.add_option( .add_option(self.name.map(|name| package::Column::Name.contains(name)))
self.name
.map(|name| package::Column::Name.like(format!("%{}%", name))),
)
} }
} }
@ -29,15 +26,29 @@ pub async fn page(
per_page: u64, per_page: u64,
page: u64, page: u64,
filter: Filter, filter: Filter,
) -> super::Result<(u64, Vec<package::Model>)> { ) -> crate::Result<Vec<package::Model>> {
let paginator = Package::find() let p2 = Alias::new("p2");
.filter(filter) let query = Query::select()
.order_by_asc(package::Column::Id) .columns(db::package::Column::iter().map(|c| (db::package::Entity, c)))
.paginate(conn, per_page); .from(db::package::Entity)
let packages = paginator.fetch_page(page).await?; .join_subquery(
let total_pages = paginator.num_pages().await?; JoinType::InnerJoin,
max_pkg_ids_query(true),
p2.clone(),
Expr::col((db::package::Entity, db::package::Column::Id))
.eq(Expr::col((p2.clone(), Alias::new("max_id")))),
)
.cond_where(filter)
.order_by((db::package::Entity, db::package::Column::Id), Order::Asc)
.to_owned();
let builder = conn.get_database_backend();
let sql = builder.build(&query);
Ok((total_pages, packages)) Ok(db::Package::find()
.from_raw_sql(sql)
.paginate(conn, per_page)
.fetch_page(page)
.await?)
} }
pub async fn by_id(conn: &DbConn, id: i32) -> Result<Option<package::Model>> { pub async fn by_id(conn: &DbConn, id: i32) -> Result<Option<package::Model>> {

View File

@ -21,15 +21,14 @@ pub async fn page(
per_page: u64, per_page: u64,
page: u64, page: u64,
filter: Filter, filter: Filter,
) -> Result<(u64, Vec<repo::Model>)> { ) -> Result<Vec<repo::Model>> {
let paginator = Repo::find() let paginator = Repo::find()
.filter(filter) .filter(filter)
.order_by_asc(repo::Column::Id) .order_by_asc(repo::Column::Id)
.paginate(conn, per_page); .paginate(conn, per_page);
let repos = paginator.fetch_page(page).await?; let repos = paginator.fetch_page(page).await?;
let total_pages = paginator.num_pages().await?;
Ok((total_pages, repos)) Ok(repos)
} }
pub async fn by_id(conn: &DbConn, id: i32) -> Result<Option<repo::Model>> { pub async fn by_id(conn: &DbConn, id: i32) -> Result<Option<repo::Model>> {