feat: some experimentation with api filtering
parent
e684cfb84e
commit
e1642d939b
|
@ -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<crate::Global> {
|
||||
Router::new()
|
||||
|
@ -20,16 +22,27 @@ pub fn router() -> Router<crate::Global> {
|
|||
async fn get_repos(
|
||||
State(global): State<crate::Global>,
|
||||
Query(pagination): Query<pagination::Query>,
|
||||
Query(filter): Query<db::query::repo::Filter>,
|
||||
) -> crate::Result<Json<PaginatedResponse<db::repo::Model>>> {
|
||||
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<crate::Global>,
|
||||
Query(pagination): Query<pagination::Query>,
|
||||
Query(filter): Query<db::query::package::Filter>,
|
||||
) -> crate::Result<Json<PaginatedResponse<db::package::Model>>> {
|
||||
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?;
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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<T> = std::result::Result<T, sea_orm::DbErr>;
|
|||
|
||||
#[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,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
mod package;
|
||||
mod repo;
|
||||
pub mod package;
|
||||
pub mod repo;
|
||||
|
||||
pub use package::PackageQuery;
|
||||
pub use repo::RepoQuery;
|
||||
|
|
|
@ -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<i32>,
|
||||
arch: Option<String>,
|
||||
name: Option<String>,
|
||||
}
|
||||
|
||||
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<package::Model>)> {
|
||||
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),
|
||||
|
|
|
@ -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<String>,
|
||||
}
|
||||
|
||||
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 }
|
||||
|
|
Loading…
Reference in New Issue