diff --git a/oab/src/api/app.rs b/oab/src/api/app.rs index c969406..c871598 100644 --- a/oab/src/api/app.rs +++ b/oab/src/api/app.rs @@ -11,18 +11,18 @@ use serde::{Deserialize, Serialize}; use crate::{ models::{self, app}, - Error, Result, CONFIG, + AppState, Error, Result, }; use chrono::NaiveDateTime; #[get("/app/{id}")] #[access_read("app")] -pub async fn get(id: web::Path) -> Result { +pub async fn get(id: web::Path, stat: web::Data) -> Result { let n = id.into_inner(); if !n.is_empty() { let s = sqlx::query_as::<_, app::Model>("select * from app where id = ?") .bind(n) - .fetch_one(CONFIG.sqlx()) + .fetch_one(stat.sqlx()) .await?; Ok(web::Json(s)) } else { @@ -52,11 +52,11 @@ pub struct App { #[get("/app/")] #[access_read("app")] -pub async fn list() -> Result { +pub async fn list(stat: web::Data) -> Result { let result = sqlx::query_as::<_, App>( "select app.id,app.created, app.updated, app.icon, app.name, app.des, app.user_count, app.hide,app.join_method, app.role_id, app.redirect, app.status, app_user.status as u_status from app left join app_user on app_user.user_id = ? && app_user.app_id = app.id", ).bind(_auth_token.id) - .fetch_all(CONFIG.sqlx()) + .fetch_all(stat.sqlx()) .await?; Ok(web::Json(result)) diff --git a/oab/src/api/appuser.rs b/oab/src/api/appuser.rs index 0824f5b..87de5ce 100644 --- a/oab/src/api/appuser.rs +++ b/oab/src/api/appuser.rs @@ -12,12 +12,15 @@ use tracing::info; use crate::{ models::{self, app_user}, - Error, Result, CONFIG, + AppState, Error, Result, }; #[get("/app/{aid}/user/{uid}")] #[access_read("app")] -pub async fn get(params: web::Path<(String, String)>) -> Result { +pub async fn get( + params: web::Path<(String, String)>, + stat: web::Data, +) -> Result { let (mut aid, mut uid) = params.into_inner(); if uid == "-" { uid = "".to_string(); @@ -35,7 +38,7 @@ pub async fn get(params: web::Path<(String, String)>) -> Result ) .bind(aid) .bind(uid) - .fetch_all(CONFIG.sqlx()) + .fetch_all(stat.sqlx()) .await?; Ok(web::Json(s)) } diff --git a/oab/src/api/user.rs b/oab/src/api/user.rs index d4bd9e9..de05e48 100644 --- a/oab/src/api/user.rs +++ b/oab/src/api/user.rs @@ -9,7 +9,7 @@ use std::fmt::Debug; use crate::{ models::{self, access, app, app_user, user, UserPlugin}, - AppState, Error, Result, CONFIG, + AppState, Error, Result, }; use actix_web::{delete, get, head, http, post, web, HttpResponse, Responder}; use base64; @@ -21,9 +21,9 @@ use tracing::info; #[get("/user/{id}")] #[access_read("user", id = "&id.clone()")] -pub async fn get(id: web::Path, data: web::Data) -> Result { +pub async fn get(id: web::Path, stat: web::Data) -> Result { let n = id.into_inner(); - let db = &data.db; + let db = stat.db(); if !n.is_empty() { let d: Option = models::entity::user::Entity::find_by_id(n).one(db).await?; @@ -35,26 +35,27 @@ pub async fn get(id: web::Path, data: web::Data) -> Result Result { - let result = sqlx::query!( - "select id,updated,created,username,nickname,email,icon,status, used, space from user", - ) - .map(|row| models::user::Model { - id: row.id, - created: row.created, - updated: row.updated, - username: row.username, - nickname: row.nickname, - email: row.email, - status: row.status, - used: row.used, - space: row.space, - icon: row.icon, - ..Default::default() - }) - .fetch_all(CONFIG.sqlx()) - .await?; - Ok(web::Json(result)) +pub async fn list(stat: web::Data) -> Result { + let res: Vec = user::Entity::find().all(stat.db()).await?; + // let result = sqlx::query!( + // "select id,updated,created,username,nickname,email,icon,status, used, space from user", + // ) + // .map(|row| models::user::Model { + // id: row.id, + // created: row.created, + // updated: row.updated, + // username: row.username, + // nickname: row.nickname, + // email: row.email, + // status: row.status, + // used: row.used, + // space: row.space, + // icon: row.icon, + // ..Default::default() + // }) + // .fetch_all(CONFIG.sqlx()) + // .await?; + Ok(web::Json(res)) } #[derive(Debug, Deserialize, Serialize)] @@ -67,9 +68,9 @@ pub struct LoginOpt { pub async fn login( q: web::Query, id: web::Path, - data: web::Data, + stat: web::Data, ) -> Result { - let db = &data.db; + let db = stat.db(); let id = id.into_inner(); let q = q.into_inner(); let filter = match q.typ { @@ -96,7 +97,7 @@ pub async fn login( u.check_pass(p)?; let au: Option = app_user::Entity::find() - .filter(app_user::Column::AppId.eq(&CONFIG.uuid)) + .filter(app_user::Column::AppId.eq(&stat.uuid)) .filter(app_user::Column::UserId.eq(&u.id)) .one(db) .await?; @@ -121,7 +122,7 @@ pub async fn login( } }, None => { - let app_obj: app::Model = app::Entity::find_by_id(CONFIG.uuid.clone()) + let app_obj: app::Model = app::Entity::find_by_id(stat.uuid.clone()) .one(db) .await? .unwrap(); @@ -143,7 +144,7 @@ values ( ?, ?, ? ) .bind(&app_obj.id) .bind(&u.id) .bind(&s) - .execute(CONFIG.sqlx()) + .execute(stat.sqlx()) .await?; match s { models::AUStatus::OK => 0, @@ -157,15 +158,15 @@ values ( ?, ?, ? ) "select access.name,access.rid,access.level from access, user_role, role WHERE user_role.user_id = ? && access.role_id=user_role.role_id && role.id=user_role.role_id && role.app_id = ?", ) .bind(&u.id) - .bind(CONFIG.uuid.clone()) - .fetch_all(CONFIG.sqlx()) + .bind(stat.uuid.clone()) + .fetch_all(stat.sqlx()) .await?; Ok(HttpResponse::build(http::StatusCode::OK) .insert_header(("auth_token", u.token(result).to_string()?)) .body("".to_string())) } else { Ok(HttpResponse::build(http::StatusCode::OK) - .insert_header(("data", "applying")) + .insert_header(("stat", "applying")) .body("".to_string())) } } @@ -177,14 +178,14 @@ pub struct RegisterOpt { } #[post("/user/")] -pub async fn register(q: web::Json) -> Result { +pub async fn register(q: web::Json, stat: web::Data) -> Result { let q = q.into_inner(); // let mut tx = dbtx().await; info!("{:#?}", q); let u: Option = sqlx::query_as::<_, models::user::Model>("select * from user where username = ?") .bind(q.username.clone()) - .fetch_optional(CONFIG.sqlx()) + .fetch_optional(stat.sqlx()) .await?; let u: models::user::Model = match u { Some(_) => return Err(Error::ArgDuplicated(format!("username: {}", q.username))), @@ -209,8 +210,8 @@ pub async fn register(q: web::Json) -> Result { } }; let oa: app::Model = sqlx::query_as::<_, app::Model>("select * from app where id = ?") - .bind(CONFIG.uuid.clone()) - .fetch_one(CONFIG.sqlx()) + .bind(stat.uuid.clone()) + .fetch_one(stat.sqlx()) .await?; let mut au = app_user::Model::default(); @@ -223,7 +224,7 @@ pub async fn register(q: web::Json) -> Result { } models::AppJoin::Applying => au.status = models::AUStatus::Applying as i32, } - let mut c = CONFIG.sqlx().begin().await?; + let mut c = stat.sqlx().begin().await?; // 创建用户 sqlx::query!( r#" diff --git a/oab/src/cfg.rs b/oab/src/cfg.rs index 11abff0..63be27c 100644 --- a/oab/src/cfg.rs +++ b/oab/src/cfg.rs @@ -25,9 +25,9 @@ lazy_static! { pub static ref CLI: AppCli = AppCli::new(); } -lazy_static! { - pub static ref CONFIG: ApplicationConfig = ApplicationConfig::new(); -} +// lazy_static! { +// pub static ref CONFIG: ApplicationConfig = ApplicationConfig::new(); +// } #[derive(Debug, Parser)] #[clap(name = "oab")] @@ -58,13 +58,14 @@ impl AppCli { } } -#[derive(Debug, Clone)] -pub struct AppState { +#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)] +pub struct ApplicationConfig { + #[serde(skip)] pub db: DatabaseConnection, } -#[derive(Debug, serde::Serialize, serde::Deserialize)] -pub struct ApplicationConfig { +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct AppState { pub uuid: String, pub key: String, pub debug: bool, @@ -82,10 +83,12 @@ pub struct ApplicationConfig { pub jwt_secret: Option, #[serde(skip)] - pub sqlx_pool: Option>, + pub _sqlx: Option>, + #[serde(skip)] + pub _db: Option, } -impl ApplicationConfig { +impl AppState { pub fn new() -> Self { let mut res = Self::defaut(); let mut f = match File::open(CLI.cfg.clone()) { @@ -126,29 +129,37 @@ impl ApplicationConfig { log_pack_compress: None, log_level: None, jwt_secret: None, - sqlx_pool: None, + _sqlx: None, + _db: None, } } pub fn save(&self) {} + + pub fn db(&self) -> &DatabaseConnection { + match &self._db { + Some(d) => d, + None => panic!("failed"), + } + } pub fn sqlx(&self) -> &sqlx::MySqlPool { - match &self.sqlx_pool { + match &self._sqlx { Some(d) => d, None => panic!("failed"), } } - fn connect_sqlx(&mut self) -> Result<()> { + + pub fn connect_sqlx(&mut self) -> Result<()> { let url = format!( "mysql://{}:{}@{}/{}", self.db_user, self.db_pass, self.db_url, self.db_name ); let p = MySqlPoolOptions::new() .max_connections(5) - .connect_lazy(&url) - .unwrap(); - self.sqlx_pool = Some(p); + .connect_lazy(&url)?; + self._sqlx = Some(p); Ok(()) } - pub async fn connect(&self) -> Result { + pub async fn connect(&mut self) -> Result<()> { let url = format!( "mysql://{}:{}@{}/{}", self.db_user, self.db_pass, self.db_url, self.db_name @@ -161,8 +172,9 @@ impl ApplicationConfig { .idle_timeout(Duration::from_secs(8)) .max_lifetime(Duration::from_secs(8)); - let db = Database::connect(opt).await?; - Ok(db) + self._db = Some(Database::connect(opt).await?); + + Ok(()) } } diff --git a/oab/src/lib.rs b/oab/src/lib.rs index 636cc0c..51d4d17 100644 --- a/oab/src/lib.rs +++ b/oab/src/lib.rs @@ -10,5 +10,5 @@ mod cfg; pub mod libs; pub mod models; mod result; -pub use cfg::{init_log, AppState, ApplicationConfig, Clis, CLI, CONFIG}; +pub use cfg::{init_log, AppState, ApplicationConfig, Clis, CLI}; pub use result::{Error, Result}; diff --git a/oab/src/main.rs b/oab/src/main.rs index 5a71b1a..08e5163 100644 --- a/oab/src/main.rs +++ b/oab/src/main.rs @@ -13,29 +13,31 @@ use actix_web::{ App, HttpServer, }; -use oab::{api, init_log, libs, models, AppState, Clis, Result, CLI, CONFIG}; +use oab::{api, init_log, libs, models, AppState, Clis, Result, CLI}; use tracing::{error, info, warn}; #[tokio::main] async fn main() -> Result<()> { init_log(); + let mut data = AppState::new(); + data.connect().await?; + data.connect_sqlx()?; if let Some(c) = &CLI.command { match c { Clis::Init => { - models::init().await; + models::init(data).await; return Ok(()); } _ => {} }; }; - web().await?; + web(data).await?; Ok(()) } -async fn web() -> Result<()> { - let db = CONFIG.connect().await?; - let data = AppState { db }; +async fn web(data: AppState) -> Result<()> { std::env::set_var("RUST_LOG", "info"); std::env::set_var("RUST_BACKTRACE", "1"); + let url = data.server_url.clone(); let serv = HttpServer::new(move || { let logger = middleware::Logger::default(); let json_config = web::JsonConfig::default() @@ -53,7 +55,7 @@ async fn web() -> Result<()> { let app = App::new(); app.wrap(logger) .wrap(middleware::Compress::default()) - .service(fs::Files::new("/media", CONFIG.media_path.clone()).show_files_listing()) + .service(fs::Files::new("/media", data.media_path.clone()).show_files_listing()) .service( web::scope("api") .app_data(web::Data::new(data.clone())) @@ -66,8 +68,8 @@ async fn web() -> Result<()> { .configure(api::routes), ) }); - info!("listen to {}", CONFIG.server_url); - serv.bind(CONFIG.server_url.clone())?.run().await?; + info!("listen to {}", url); + serv.bind(url)?.run().await?; Ok(()) } diff --git a/oab/src/models/mod.rs b/oab/src/models/mod.rs index 5dd903a..e75bf01 100644 --- a/oab/src/models/mod.rs +++ b/oab/src/models/mod.rs @@ -16,9 +16,9 @@ pub use app_plugin::{AUStatus, AppJoin}; pub use entity::{access, app, app_user, user}; pub use user_plugin::{AccessLevel, Token, UserPlugin}; -use crate::CONFIG; +use crate::AppState; -pub async fn init() { +pub async fn init(data: AppState) { info!("init database"); - sqlx::migrate!().run(CONFIG.sqlx()).await.unwrap(); + sqlx::migrate!().run(data.sqlx()).await.unwrap(); }