feat(server): example of pagination

repo-db
Jef Roosens 2023-07-30 18:21:07 +02:00
parent 37218536c5
commit 25627e166e
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
5 changed files with 32 additions and 16 deletions

View File

@ -1,19 +1,33 @@
use axum::Router; use axum::extract::{Query, State};
use axum::extract::State;
use axum::routing::get; use axum::routing::get;
use axum::Json;
use axum::Router;
use sea_orm::entity::EntityTrait; use sea_orm::entity::EntityTrait;
use sea_orm::query::QueryOrder; use sea_orm::query::QueryOrder;
use axum::Json; use sea_orm::PaginatorTrait;
use serde::Deserialize;
use crate::db::entities::repo; use crate::db::entities::repo;
pub fn router() -> Router<crate::Global> { #[derive(Deserialize)]
Router::new() pub struct Pagination {
.route("/repos", get(get_repos)) page: Option<u64>,
per_page: Option<u64>,
} }
async fn get_repos(State(global): State<crate::Global>) -> crate::Result<Json<Vec<repo::Model>>> { pub fn router() -> Router<crate::Global> {
let repos = repo::Entity::find().order_by_asc(repo::Column::Id).all(&global.db).await?; Router::new().route("/repos", get(get_repos))
}
async fn get_repos(
State(global): State<crate::Global>,
Query(params): Query<Pagination>,
) -> crate::Result<Json<Vec<repo::Model>>> {
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)) Ok(Json(repos))
} }

View File

@ -45,7 +45,7 @@ impl Cli {
pub async fn run(&self) { pub async fn run(&self) {
self.init_tracing(); 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 { let config = Config {
repo_dir: self.repo_dir.clone(), repo_dir: self.repo_dir.clone(),
@ -56,7 +56,7 @@ impl Cli {
let global = Global { let global = Global {
config, config,
repo_manager: Arc::new(RwLock::new(repo_manager)), repo_manager: Arc::new(RwLock::new(repo_manager)),
db db,
}; };
// build our application with a single route // build our application with a single route

View File

@ -1,5 +1,5 @@
mod migrator;
pub mod entities; pub mod entities;
mod migrator;
use migrator::Migrator; use migrator::Migrator;
use sea_orm::ConnectOptions; use sea_orm::ConnectOptions;
@ -11,7 +11,7 @@ pub async fn init<C: Into<ConnectOptions>>(
) -> Result<sea_orm::DatabaseConnection, sea_orm::DbErr> { ) -> Result<sea_orm::DatabaseConnection, sea_orm::DbErr> {
let db = Database::connect(opt).await?; let db = Database::connect(opt).await?;
Migrator::refresh(&db).await?; Migrator::up(&db, None).await?;
Ok(db) Ok(db)
} }

View File

@ -35,7 +35,9 @@ impl IntoResponse for ServerError {
ServerError::IO(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), ServerError::IO(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
ServerError::Axum(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), ServerError::Axum(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
ServerError::Status(status) => status.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(), ServerError::Db(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
} }
} }

View File

@ -1,15 +1,15 @@
mod api;
mod cli; mod cli;
mod db; mod db;
mod error; mod error;
mod repo; mod repo;
mod api;
use clap::Parser; use clap::Parser;
pub use error::{Result, ServerError}; pub use error::{Result, ServerError};
use repo::RepoGroupManager; use repo::RepoGroupManager;
use sea_orm::DatabaseConnection;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use sea_orm::DatabaseConnection;
#[derive(Clone)] #[derive(Clone)]
pub struct Config { pub struct Config {
@ -21,7 +21,7 @@ pub struct Config {
pub struct Global { pub struct Global {
config: Config, config: Config,
repo_manager: Arc<RwLock<RepoGroupManager>>, repo_manager: Arc<RwLock<RepoGroupManager>>,
db: DatabaseConnection db: DatabaseConnection,
} }
#[tokio::main] #[tokio::main]