From 37218536c5bda33e27686875e3785acc1c7b38da Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Sun, 30 Jul 2023 16:55:44 +0200 Subject: [PATCH] feat(server): start api using CRUD operations --- Cargo.lock | 9 +++++---- server/Cargo.toml | 1 + server/src/api/mod.rs | 19 +++++++++++++++++++ server/src/cli.rs | 2 ++ server/src/db/entities/mod.rs | 5 +++++ server/src/db/entities/prelude.rs | 3 +++ server/src/db/entities/repo.rs | 18 ++++++++++++++++++ .../m20230730_000001_create_repo_tables.rs | 2 +- server/src/db/mod.rs | 3 ++- server/src/error.rs | 10 ++++++++++ server/src/main.rs | 3 +++ 11 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 server/src/api/mod.rs create mode 100644 server/src/db/entities/mod.rs create mode 100644 server/src/db/entities/prelude.rs create mode 100644 server/src/db/entities/repo.rs diff --git a/Cargo.lock b/Cargo.lock index 2abb492..7e82ecd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1629,6 +1629,7 @@ dependencies = [ "libarchive", "sea-orm", "sea-orm-migration", + "serde", "sha256", "tokio", "tokio-util", @@ -1965,18 +1966,18 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.171" +version = "1.0.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "60363bdd39a7be0266a520dab25fdc9241d2f987b08a01e01f0ec6d06a981348" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "f28482318d6641454cb273da158647922d1be6b5a2fcc6165cd89ebdd7ed576b" dependencies = [ "proc-macro2", "quote", diff --git a/server/Cargo.toml b/server/Cargo.toml index 13520fc..68a7c6b 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -13,6 +13,7 @@ futures = "0.3.28" libarchive = { path = "../libarchive" } sea-orm = { version = "0.12.1", features = ["sqlx-sqlite", "runtime-tokio-rustls", "macros"] } sea-orm-migration = "0.12.1" +serde = { version = "1.0.178", features = ["derive"] } sha256 = "1.1.4" tokio = { version = "1.29.1", features = ["full"] } tokio-util = { version = "0.7.8", features = ["io"] } diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs new file mode 100644 index 0000000..7f1824b --- /dev/null +++ b/server/src/api/mod.rs @@ -0,0 +1,19 @@ +use axum::Router; +use axum::extract::State; +use axum::routing::get; +use sea_orm::entity::EntityTrait; +use sea_orm::query::QueryOrder; +use axum::Json; + +use crate::db::entities::repo; + +pub fn router() -> Router { + Router::new() + .route("/repos", get(get_repos)) +} + +async fn get_repos(State(global): State) -> crate::Result>> { + let repos = repo::Entity::find().order_by_asc(repo::Column::Id).all(&global.db).await?; + + Ok(Json(repos)) +} diff --git a/server/src/cli.rs b/server/src/cli.rs index dfb8ba8..b109e2b 100644 --- a/server/src/cli.rs +++ b/server/src/cli.rs @@ -56,10 +56,12 @@ impl Cli { let global = Global { config, repo_manager: Arc::new(RwLock::new(repo_manager)), + db }; // build our application with a single route let app = Router::new() + .nest("/api", crate::api::router()) .merge(crate::repo::router()) .with_state(global) .layer(TraceLayer::new_for_http()); diff --git a/server/src/db/entities/mod.rs b/server/src/db/entities/mod.rs new file mode 100644 index 0000000..f1e964a --- /dev/null +++ b/server/src/db/entities/mod.rs @@ -0,0 +1,5 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 + +pub mod prelude; + +pub mod repo; diff --git a/server/src/db/entities/prelude.rs b/server/src/db/entities/prelude.rs new file mode 100644 index 0000000..8b651f8 --- /dev/null +++ b/server/src/db/entities/prelude.rs @@ -0,0 +1,3 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 + +pub use super::repo::Entity as Repo; diff --git a/server/src/db/entities/repo.rs b/server/src/db/entities/repo.rs new file mode 100644 index 0000000..0676a76 --- /dev/null +++ b/server/src/db/entities/repo.rs @@ -0,0 +1,18 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 + +use sea_orm::entity::prelude::*; +use serde::Serialize; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize)] +#[sea_orm(table_name = "repo")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub name: String, + pub description: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/server/src/db/migrator/m20230730_000001_create_repo_tables.rs b/server/src/db/migrator/m20230730_000001_create_repo_tables.rs index 4aa74e1..4c36ade 100644 --- a/server/src/db/migrator/m20230730_000001_create_repo_tables.rs +++ b/server/src/db/migrator/m20230730_000001_create_repo_tables.rs @@ -23,7 +23,7 @@ impl MigrationTrait for Migration { .auto_increment() .primary_key(), ) - .col(ColumnDef::new(Repo::Name).string().not_null()) + .col(ColumnDef::new(Repo::Name).string().not_null().unique_key()) .col(ColumnDef::new(Repo::Description).string()) .to_owned(), ) diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs index ee85b4a..e1ad0b9 100644 --- a/server/src/db/mod.rs +++ b/server/src/db/mod.rs @@ -1,4 +1,5 @@ mod migrator; +pub mod entities; use migrator::Migrator; use sea_orm::ConnectOptions; @@ -8,7 +9,7 @@ use sea_orm_migration::MigratorTrait; pub async fn init>( opt: C, ) -> Result { - let mut db = Database::connect(opt).await?; + let db = Database::connect(opt).await?; Migrator::refresh(&db).await?; diff --git a/server/src/error.rs b/server/src/error.rs index 0a7772f..0dca03c 100644 --- a/server/src/error.rs +++ b/server/src/error.rs @@ -11,6 +11,7 @@ pub enum ServerError { IO(io::Error), Axum(axum::Error), Status(StatusCode), + Db(sea_orm::DbErr), } impl fmt::Display for ServerError { @@ -19,6 +20,7 @@ impl fmt::Display for ServerError { ServerError::IO(err) => write!(fmt, "{}", err), ServerError::Axum(err) => write!(fmt, "{}", err), ServerError::Status(status) => write!(fmt, "{}", status), + ServerError::Db(err) => write!(fmt, "{}", err), } } } @@ -33,6 +35,8 @@ 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(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), } } } @@ -60,3 +64,9 @@ impl From for ServerError { Self::Status(status) } } + +impl From for ServerError { + fn from(err: sea_orm::DbErr) -> Self { + ServerError::Db(err) + } +} diff --git a/server/src/main.rs b/server/src/main.rs index 3cfaa5c..8884047 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -2,12 +2,14 @@ mod cli; mod db; mod error; mod repo; +mod api; use clap::Parser; pub use error::{Result, ServerError}; use repo::RepoGroupManager; use std::path::PathBuf; use std::sync::{Arc, RwLock}; +use sea_orm::DatabaseConnection; #[derive(Clone)] pub struct Config { @@ -19,6 +21,7 @@ pub struct Config { pub struct Global { config: Config, repo_manager: Arc>, + db: DatabaseConnection } #[tokio::main]