finance-consumer/bookkeeper/src/main.rs
2024-12-25 22:44:12 +08:00

97 lines
2.8 KiB
Rust

#[macro_use]
extern crate rocket;
use chrono::NaiveDate;
use entity::transaction;
use migration::MigratorTrait;
use rocket::fairing::{self, AdHoc};
use rocket::form::Form;
use rocket::response::{Flash, Redirect};
use rocket::{Build, Rocket};
use rust_decimal::Decimal;
use sea_orm::ActiveValue::Set;
use sea_orm::{ActiveModelTrait, ConnectOptions, DatabaseConnection};
use sea_orm_rocket::{rocket::figment::Figment, Config, Connection, Database};
use std::str::FromStr;
use std::time::Duration;
#[derive(sea_orm_rocket::Database, Debug)]
#[database("bookkeeper")]
struct Db(SeaOrmPool);
#[derive(Debug, Clone)]
struct SeaOrmPool {
conn: DatabaseConnection,
}
#[async_trait]
impl sea_orm_rocket::Pool for SeaOrmPool {
type Connection = DatabaseConnection;
type Error = sea_orm::DbErr;
async fn init(figment: &Figment) -> Result<Self, Self::Error> {
let config = figment.extract::<Config>().unwrap();
let mut options: ConnectOptions = config.url.into();
options
.max_connections(config.max_connections as u32)
.min_connections(config.min_connections.unwrap_or_default())
.connect_timeout(Duration::from_secs(config.connect_timeout))
.sqlx_logging(config.sqlx_logging);
if let Some(idle_timeout) = config.idle_timeout {
options.idle_timeout(Duration::from_secs(idle_timeout));
}
let conn = sea_orm::Database::connect(options).await?;
Ok(SeaOrmPool { conn })
}
fn borrow(&self) -> &Self::Connection {
&self.conn
}
}
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
#[derive(FromForm)]
struct TransBuy<'r> {
code: usize,
name: &'r str,
buy: &'r str,
volume: usize,
net_buy: &'r str,
date: &'r str,
}
#[post("/buy", data = "<trans_buy>")]
async fn buy(trans_buy: Form<TransBuy<'_>>, conn: Connection<'_, Db>) -> Flash<Redirect> {
let record = transaction::ActiveModel {
code: Set(trans_buy.code as i32),
name: Set(trans_buy.name.to_string()),
buy: Set(Decimal::from_str(trans_buy.buy).unwrap()),
volume: Set(trans_buy.volume as i32),
net_buy: Set(Decimal::from_str(trans_buy.net_buy).unwrap()),
date: Set(NaiveDate::parse_from_str(trans_buy.date, "%Y-%m-%d").unwrap()),
..Default::default()
};
record.insert(conn.into_inner()).await.unwrap();
Flash::success(Redirect::to("/"), "OK!")
}
async fn run_migrations(rocket: Rocket<Build>) -> fairing::Result {
let conn = &Db::fetch(&rocket).unwrap().conn;
let _ = migration::Migrator::up(conn, None).await;
Ok(rocket)
}
#[launch]
async fn rocket() -> _ {
rocket::build()
.attach(Db::init())
.attach(AdHoc::try_on_ignite("Migrations", run_migrations))
.mount("/", routes![index, buy])
}