diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs index 800587f..2577718 100644 --- a/server/src/api/mod.rs +++ b/server/src/api/mod.rs @@ -1,5 +1,7 @@ mod pagination; +use sea_orm::{sea_query::IntoCondition, *}; + use axum::extract::{Path, Query, State}; use axum::routing::get; use axum::Json; @@ -7,7 +9,7 @@ use axum::Router; use pagination::PaginatedResponse; -use crate::db; +use crate::db::{self, *}; pub fn router() -> Router { Router::new() @@ -20,16 +22,27 @@ pub fn router() -> Router { async fn get_repos( State(global): State, Query(pagination): Query, + Query(filter): Query, ) -> crate::Result>> { - let (total_pages, repos) = global - .db - .repo - .page( - pagination.per_page.unwrap_or(25), - pagination.page.unwrap_or(1) - 1, - ) + let page = pagination.page.unwrap_or(1) - 1; + let per_page = pagination.per_page.unwrap_or(25); + + let paginator = Repo::find() + .filter(filter) + .order_by_asc(package::Column::Id) + .paginate(&global.db, pagination.per_page.unwrap_or(25)); + let items = paginator + .fetch_page(pagination.page.unwrap_or(1) - 1) .await?; - Ok(Json(pagination.res(total_pages, repos))) + let total_pages = paginator.num_pages().await?; + + Ok(Json(PaginatedResponse { + page, + per_page, + total_pages, + count: items.len(), + items, + })) } async fn get_single_repo( @@ -49,6 +62,7 @@ async fn get_single_repo( async fn get_packages( State(global): State, Query(pagination): Query, + Query(filter): Query, ) -> crate::Result>> { let (total_pages, pkgs) = global .db @@ -56,6 +70,7 @@ async fn get_packages( .page( pagination.per_page.unwrap_or(25), pagination.page.unwrap_or(1) - 1, + filter, ) .await?; diff --git a/server/src/api/pagination.rs b/server/src/api/pagination.rs index aa1e5cb..db1ffa0 100644 --- a/server/src/api/pagination.rs +++ b/server/src/api/pagination.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -pub const DEFAULT_PAGE: u64 = 0; +pub const DEFAULT_PAGE: u64 = 1; pub const DEFAULT_PER_PAGE: u64 = 25; #[derive(Deserialize)] diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs index 587052d..a7a7f66 100644 --- a/server/src/db/mod.rs +++ b/server/src/db/mod.rs @@ -1,7 +1,7 @@ mod conn; pub mod entities; mod migrator; -mod query; +pub mod query; use sea_orm::{ConnectOptions, Database, DatabaseConnection, DeriveActiveEnum, EnumIter}; use sea_orm_migration::MigratorTrait; @@ -14,6 +14,7 @@ type Result = std::result::Result; #[derive(EnumIter, DeriveActiveEnum, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] #[sea_orm(rs_type = "i32", db_type = "Integer")] +#[serde(rename_all = "lowercase")] pub enum PackageRelatedEnum { #[sea_orm(num_value = 0)] Conflicts, diff --git a/server/src/db/query/mod.rs b/server/src/db/query/mod.rs index a52cccf..32cc3c5 100644 --- a/server/src/db/query/mod.rs +++ b/server/src/db/query/mod.rs @@ -1,5 +1,5 @@ -mod package; -mod repo; +pub mod package; +pub mod repo; pub use package::PackageQuery; pub use repo::RepoQuery; diff --git a/server/src/db/query/package.rs b/server/src/db/query/package.rs index c977984..8649dea 100644 --- a/server/src/db/query/package.rs +++ b/server/src/db/query/package.rs @@ -1,4 +1,5 @@ -use sea_orm::*; +use sea_orm::{sea_query::IntoCondition, *}; +use serde::Deserialize; use crate::db::*; @@ -7,6 +8,25 @@ pub struct PackageQuery { conn: DatabaseConnection, } +#[derive(Deserialize)] +pub struct Filter { + repo: Option, + arch: Option, + name: Option, +} + +impl IntoCondition for Filter { + fn into_condition(self) -> Condition { + Condition::all() + .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.name + .map(|name| package::Column::Name.like(format!("%{}%", name))), + ) + } +} + impl PackageQuery { pub fn new(conn: DatabaseConnection) -> Self { Self { conn } @@ -16,8 +36,10 @@ impl PackageQuery { &self, per_page: u64, page: u64, + filter: Filter, ) -> super::Result<(u64, Vec)> { let paginator = Package::find() + .filter(filter) .order_by_asc(package::Column::Id) .paginate(&self.conn, per_page); let packages = paginator.fetch_page(page).await?; @@ -132,7 +154,10 @@ impl PackageQuery { package_id: Set(pkg_entry.id), r#type: Set(t), name: Set(s.to_string()), - })); + })) + .on_empty_do_nothing() + .exec(&self.conn) + .await?; PackageFile::insert_many(pkg.files.iter().map(|s| package_file::ActiveModel { package_id: Set(pkg_entry.id), diff --git a/server/src/db/query/repo.rs b/server/src/db/query/repo.rs index 5e54fdc..65177df 100644 --- a/server/src/db/query/repo.rs +++ b/server/src/db/query/repo.rs @@ -1,4 +1,4 @@ -use sea_orm::*; +use sea_orm::{sea_query::IntoCondition, *}; use crate::db::*; @@ -7,6 +7,17 @@ pub struct RepoQuery { conn: DatabaseConnection, } +#[derive(Deserialize)] +pub struct Filter { + name: Option, +} + +impl IntoCondition for Filter { + fn into_condition(self) -> Condition { + Condition::all().add_option(self.name.map(|name| package::Column::Name.like(name))) + } +} + impl RepoQuery { pub fn new(conn: DatabaseConnection) -> Self { Self { conn }