echoes/backend/src/main.rs

109 lines
3.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// main.rs
/**
* 主程序入口提供数据库连接和相关API接口。
*
* 接口:
* - GET /api/install: 测试数据库连接
* - GET /api/sql: 执行SQL查询并返回结果
*/
mod config; // 配置模块
mod database;
mod secret;
use chrono::Duration;
// 数据库模块
use database::relational; // 引入关系型数据库
use once_cell::sync::Lazy; // 用于延迟初始化
use rocket::{get, http::Status, launch, response::status, routes, serde::json::Json}; // 引入Rocket框架相关功能
use std::sync::Arc;
// 引入Arc用于线程安全的引用计数
use tokio::sync::Mutex; // 引入Mutex用于异步锁
// 全局数据库连接变量
static DB: Lazy<Arc<Mutex<Option<relational::Database>>>> = Lazy::new(|| Arc::new(Mutex::new(None)));
/**
* 初始化数据库连接
*/
async fn init_db(database: config::SqlConfig) -> Result<(), Box<dyn std::error::Error>> {
let database = relational::Database::init(database).await?; // 初始化数据库
*DB.lock().await = Some(database); // 保存数据库实例
Ok(())
}
/**
* 获取数据库的引用
*/
async fn get_db() -> Result<relational::Database, Box<dyn std::error::Error>> {
DB.lock()
.await
.clone()
.ok_or_else(|| "Database not initialized".into()) // 返回错误信息
}
/**
* 测试数据库接口
*/
#[get("/sql")]
async fn ssql() -> Result<Json<Vec<std::collections::HashMap<String, String>>>, status::Custom<String>> {
let db = get_db().await.map_err(|e| {
status::Custom(
Status::InternalServerError,
format!("Database error: {}", e), // 数据库错误信息
)
})?;
let query_result = db
.get_db()
.query("SELECT * FROM info".to_string())
.await
.map_err(|e| status::Custom(Status::InternalServerError, format!("Query error: {}", e)))?;
Ok(Json(query_result)) // 返回查询结果
}
/**
* 数据库安装接口
*/
#[get("/install")]
async fn install() -> status::Custom<String> {
get_db()
.await
.map(|_| status::Custom(Status::Ok, "Database connected successfully".into())) // 连接成功
.unwrap_or_else(|e| {
status::Custom(
Status::InternalServerError,
format!("Failed to connect: {}", e), // 连接失败信息
)
})
}
#[get("/system")]
async fn token_system() -> Result<status::Custom<String>, status::Custom<String>> {
// 创建 Claims
let claims = secret::CustomClaims {
user_id: String::from("system"),
device_ua: String::from("system"),
};
// 生成JWT
let token = secret::generate_jwt(claims,Duration::seconds(1))
.map_err(|e| status::Custom(Status::InternalServerError, format!("JWT generation failed: {}", e)))?;
Ok(status::Custom(Status::Ok, token))
}
/**
* 启动Rocket应用
*/
#[launch]
async fn rocket() -> _ {
let config = config::Config::read().expect("Failed to read config"); // 读取配置
init_db(config.sql_config)
.await
.expect("Failed to connect to database"); // 初始化数据库连接
rocket::build()
.mount("/", routes![install, ssql]) // 挂载API路由
.mount("/auth/token", routes![token_system])
}