From 25627e166e9b2cc5749ec7f35c4ca8be72a47f16 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Sun, 30 Jul 2023 18:21:07 +0200 Subject: [PATCH] feat(server): example of pagination --- server/src/api/mod.rs | 30 ++++++++++++++++++++++-------- server/src/cli.rs | 4 ++-- server/src/db/mod.rs | 4 ++-- server/src/error.rs | 4 +++- server/src/main.rs | 6 +++--- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs index 7f1824b..982dc02 100644 --- a/server/src/api/mod.rs +++ b/server/src/api/mod.rs @@ -1,19 +1,33 @@ -use axum::Router; -use axum::extract::State; +use axum::extract::{Query, State}; use axum::routing::get; +use axum::Json; +use axum::Router; use sea_orm::entity::EntityTrait; use sea_orm::query::QueryOrder; -use axum::Json; +use sea_orm::PaginatorTrait; +use serde::Deserialize; use crate::db::entities::repo; -pub fn router() -> Router { - Router::new() - .route("/repos", get(get_repos)) +#[derive(Deserialize)] +pub struct Pagination { + page: Option, + per_page: Option, } -async fn get_repos(State(global): State) -> crate::Result>> { - let repos = repo::Entity::find().order_by_asc(repo::Column::Id).all(&global.db).await?; +pub fn router() -> Router { + Router::new().route("/repos", get(get_repos)) +} + +async fn get_repos( + State(global): State, + Query(params): Query, +) -> crate::Result>> { + let repos = repo::Entity::find() + .order_by_asc(repo::Column::Id) + .paginate(&global.db, params.per_page.unwrap_or(25)) + .fetch_page(params.page.unwrap_or(0)) + .await?; Ok(Json(repos)) } diff --git a/server/src/cli.rs b/server/src/cli.rs index b109e2b..90c368b 100644 --- a/server/src/cli.rs +++ b/server/src/cli.rs @@ -45,7 +45,7 @@ impl Cli { pub async fn run(&self) { self.init_tracing(); - let db = crate::db::init("sqlite://test.db?mode=rwc").await.unwrap(); + let db = crate::db::init("sqlite://test.db").await.unwrap(); let config = Config { repo_dir: self.repo_dir.clone(), @@ -56,7 +56,7 @@ impl Cli { let global = Global { config, repo_manager: Arc::new(RwLock::new(repo_manager)), - db + db, }; // build our application with a single route diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs index e1ad0b9..4e0e804 100644 --- a/server/src/db/mod.rs +++ b/server/src/db/mod.rs @@ -1,5 +1,5 @@ -mod migrator; pub mod entities; +mod migrator; use migrator::Migrator; use sea_orm::ConnectOptions; @@ -11,7 +11,7 @@ pub async fn init>( ) -> Result { let db = Database::connect(opt).await?; - Migrator::refresh(&db).await?; + Migrator::up(&db, None).await?; Ok(db) } diff --git a/server/src/error.rs b/server/src/error.rs index 0dca03c..8ff467a 100644 --- a/server/src/error.rs +++ b/server/src/error.rs @@ -35,7 +35,9 @@ impl IntoResponse for ServerError { ServerError::IO(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), ServerError::Axum(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), ServerError::Status(status) => status.into_response(), - ServerError::Db(sea_orm::DbErr::RecordNotFound(_)) => StatusCode::NOT_FOUND.into_response(), + ServerError::Db(sea_orm::DbErr::RecordNotFound(_)) => { + StatusCode::NOT_FOUND.into_response() + } ServerError::Db(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), } } diff --git a/server/src/main.rs b/server/src/main.rs index 8884047..a6d41b5 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,15 +1,15 @@ +mod api; mod cli; mod db; mod error; mod repo; -mod api; use clap::Parser; pub use error::{Result, ServerError}; use repo::RepoGroupManager; +use sea_orm::DatabaseConnection; use std::path::PathBuf; use std::sync::{Arc, RwLock}; -use sea_orm::DatabaseConnection; #[derive(Clone)] pub struct Config { @@ -21,7 +21,7 @@ pub struct Config { pub struct Global { config: Config, repo_manager: Arc>, - db: DatabaseConnection + db: DatabaseConnection, } #[tokio::main]