From 835bce5dcbccd5a5d72766d69f7c540fdbd5fc54 Mon Sep 17 00:00:00 2001 From: wjsjwr Date: Wed, 25 Dec 2024 22:40:16 +0800 Subject: [PATCH] Insert transaction --- .../244cc0b1-ac8c-4e66-a440-fb727301f139.xml | 102 +++++++++++++--- .idea/workspace.xml | 46 ++++++-- bookkeeper/Cargo.lock | 110 +++++++++++++++--- bookkeeper/Cargo.toml | 2 + bookkeeper/Rocket.toml | 5 +- bookkeeper/entity/src/lib.rs | 6 +- bookkeeper/entity/src/prelude.rs | 3 +- bookkeeper/entity/src/transaction.rs | 29 +++++ bookkeeper/entity/src/user.rs | 7 +- .../src/m20220101_000001_create_table.rs | 74 +++++++++--- bookkeeper/src/main.rs | 98 ++++++++++++++-- 11 files changed, 405 insertions(+), 77 deletions(-) create mode 100644 bookkeeper/entity/src/transaction.rs diff --git a/.idea/dataSources/244cc0b1-ac8c-4e66-a440-fb727301f139.xml b/.idea/dataSources/244cc0b1-ac8c-4e66-a440-fb727301f139.xml index 074b31c..4c7c529 100644 --- a/.idea/dataSources/244cc0b1-ac8c-4e66-a440-fb727301f139.xml +++ b/.idea/dataSources/244cc0b1-ac8c-4e66-a440-fb727301f139.xml @@ -499,7 +499,7 @@ 1 - 2024-12-23.15:02:12 + 2024-12-25.12:45:04 R @@ -1597,75 +1597,141 @@ 1
- - +
+
+ 1 1 varchar|0s - + 1 2 bigint|0s - + version 1 1 - + version 1 sqlite_autoindex_seaql_migrations_1 - + 1 TEXT|0s - + 2 TEXT|0s - + 3 TEXT|0s - + 4 INT|0s - + 5 TEXT|0s - + 1 - + 2 - + 1 1 1 integer|0s - + 1 2 varchar|0s - + 1 3 varchar|0s - + + 1 + 4 + real|0s + + + 1 + 5 + integer|0s + + + 1 + 6 + real|0s + + + 1 + 7 + real|0s + + + 1 + 8 + real|0s + + + 1 + 9 + integer|0s + + + 1 + 10 + jsonb_text|0s + + + 1 + 11 + real|0s + + + 1 + 12 + real|0s + + + id + 1 + + + 1 + 1 + 1 + integer|0s + + + 1 + 2 + varchar|0s + + + 1 + 3 + varchar|0s + + 1 4 varchar|0s - + id 1 diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 6c8d2c7..3a08de5 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,5 +1,8 @@ + + @@ -7,12 +10,17 @@ - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bookkeeper/Cargo.lock b/bookkeeper/Cargo.lock index 41270cc..d757111 100644 --- a/bookkeeper/Cargo.lock +++ b/bookkeeper/Cargo.lock @@ -372,6 +372,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.6.0" @@ -423,7 +429,9 @@ dependencies = [ "entity", "migration", "rocket", + "rust_decimal", "sea-orm", + "sea-orm-rocket", ] [[package]] @@ -713,14 +721,34 @@ dependencies = [ "serde", ] +[[package]] +name = "devise" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c7580b072f1c8476148f16e0a0d5dedddab787da98d86c5082c5e9ed8ab595" +dependencies = [ + "devise_codegen 0.3.1", + "devise_core 0.3.1", +] + [[package]] name = "devise" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1d90b0c4c777a2cad215e3c7be59ac7c15adf45cf76317009b7d096d46f651d" dependencies = [ - "devise_codegen", - "devise_core", + "devise_codegen 0.4.2", + "devise_core 0.4.2", +] + +[[package]] +name = "devise_codegen" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123c73e7a6e51b05c75fe1a1b2f4e241399ea5740ed810b0e3e6cacd9db5e7b2" +dependencies = [ + "devise_core 0.3.1", + "quote", ] [[package]] @@ -729,19 +757,32 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867" dependencies = [ - "devise_core", + "devise_core 0.4.2", "quote", ] +[[package]] +name = "devise_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841ef46f4787d9097405cac4e70fb8644fc037b526e8c14054247c0263c400d0" +dependencies = [ + "bitflags 1.3.2", + "proc-macro2", + "proc-macro2-diagnostics 0.9.1", + "quote", + "syn 1.0.109", +] + [[package]] name = "devise_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" dependencies = [ - "bitflags", + "bitflags 2.6.0", "proc-macro2", - "proc-macro2-diagnostics", + "proc-macro2-diagnostics 0.10.1", "quote", "syn 2.0.90", ] @@ -1790,7 +1831,7 @@ dependencies = [ "heck 0.4.1", "itertools", "proc-macro2", - "proc-macro2-diagnostics", + "proc-macro2-diagnostics 0.10.1", "quote", "syn 2.0.90", ] @@ -1844,7 +1885,7 @@ checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" dependencies = [ "inlinable_string", "pear_codegen", - "yansi", + "yansi 1.0.1", ] [[package]] @@ -1854,7 +1895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" dependencies = [ "proc-macro2", - "proc-macro2-diagnostics", + "proc-macro2-diagnostics 0.10.1", "quote", "syn 2.0.90", ] @@ -1994,6 +2035,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", + "yansi 0.5.1", +] + [[package]] name = "proc-macro2-diagnostics" version = "0.10.1" @@ -2004,7 +2058,7 @@ dependencies = [ "quote", "syn 2.0.90", "version_check", - "yansi", + "yansi 1.0.1", ] [[package]] @@ -2078,7 +2132,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags", + "bitflags 2.6.0", ] [[package]] @@ -2233,7 +2287,7 @@ dependencies = [ "tokio-util", "ubyte", "version_check", - "yansi", + "yansi 1.0.1", ] [[package]] @@ -2242,7 +2296,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" dependencies = [ - "devise", + "devise 0.4.2", "glob", "indexmap", "proc-macro2", @@ -2328,7 +2382,7 @@ version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -2488,6 +2542,26 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "sea-orm-rocket" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1e2cd44db4886bcaee4271e895f7d25f41e4bd4c3dffa5b4a286667593c5bb" +dependencies = [ + "rocket", + "sea-orm-rocket-codegen", +] + +[[package]] +name = "sea-orm-rocket-codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd35bf98426401976aa90ed163a1cbe9228b6037e59489b25348691437860e1" +dependencies = [ + "devise 0.3.1", + "quote", +] + [[package]] name = "sea-query" version = "0.32.1" @@ -2844,7 +2918,7 @@ dependencies = [ "atoi", "base64", "bigdecimal", - "bitflags", + "bitflags 2.6.0", "byteorder", "bytes", "chrono", @@ -2891,7 +2965,7 @@ dependencies = [ "atoi", "base64", "bigdecimal", - "bitflags", + "bitflags 2.6.0", "byteorder", "chrono", "crc", @@ -3776,6 +3850,12 @@ dependencies = [ "tap", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + [[package]] name = "yansi" version = "1.0.1" diff --git a/bookkeeper/Cargo.toml b/bookkeeper/Cargo.toml index 63be32b..44ba169 100644 --- a/bookkeeper/Cargo.toml +++ b/bookkeeper/Cargo.toml @@ -8,6 +8,8 @@ chrono = "0.4.39" rocket = "0.5.1" migration = { path = "migration" } entity ={ path = "entity"} +rust_decimal = "1.36.0" +sea-orm-rocket = "0.5.4" [workspace] members = [".", "entity", "migration"] diff --git a/bookkeeper/Rocket.toml b/bookkeeper/Rocket.toml index 7c2c5ee..23d4a86 100644 --- a/bookkeeper/Rocket.toml +++ b/bookkeeper/Rocket.toml @@ -3,6 +3,9 @@ address = "0.0.0.0" limits = { form = "64 kB", json = "1 MiB" } +[default.databases.bookkeeper] +url = "sqlite://bookkeeper.db" + ## set only when compiled in debug mode, i.e, `cargo build` [debug] port = 8000 @@ -17,4 +20,4 @@ port = 9001 [release] port = 9999 ip_header = false -secret_key = "hPrYyЭRiMyµ5sBB1π+CMæ1køFsåqKvBiQJxBVHQk=" \ No newline at end of file +secret_key = "hPrYyЭRiMyµ5sBB1π+CMæ1køFsåqKvBiQJxBVHQk=" diff --git a/bookkeeper/entity/src/lib.rs b/bookkeeper/entity/src/lib.rs index 41a28b6..2a0200d 100644 --- a/bookkeeper/entity/src/lib.rs +++ b/bookkeeper/entity/src/lib.rs @@ -1,6 +1,6 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 -#[macro_use] -extern crate rocket; +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 pub mod prelude; + +pub mod transaction; pub mod user; diff --git a/bookkeeper/entity/src/prelude.rs b/bookkeeper/entity/src/prelude.rs index 4c7cdbd..c6dd630 100644 --- a/bookkeeper/entity/src/prelude.rs +++ b/bookkeeper/entity/src/prelude.rs @@ -1,3 +1,4 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 +pub use super::transaction::Entity as Transaction; pub use super::user::Entity as User; diff --git a/bookkeeper/entity/src/transaction.rs b/bookkeeper/entity/src/transaction.rs new file mode 100644 index 0000000..afe6490 --- /dev/null +++ b/bookkeeper/entity/src/transaction.rs @@ -0,0 +1,29 @@ +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "transaction")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub code: i32, + pub name: String, + pub date: Date, + pub buy: Decimal, + pub volume: i32, + pub net_buy: Decimal, + pub sell_date: Option, + pub sell: Option, + pub net_sell: Option, + pub sold_volume: Option, + #[sea_orm(column_type = "JsonBinary", nullable)] + pub split_pieces: Option, + pub gain: Option, + pub net_gain: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/bookkeeper/entity/src/user.rs b/bookkeeper/entity/src/user.rs index 78a2b53..a72ad08 100644 --- a/bookkeeper/entity/src/user.rs +++ b/bookkeeper/entity/src/user.rs @@ -1,9 +1,8 @@ -//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.0 -use rocket::serde::{Deserialize, Serialize}; +//! `SeaORM` Entity, @generated by sea-orm-codegen 1.1.2 + use sea_orm::entity::prelude::*; -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Deserialize, Serialize, FromForm)] -#[serde(crate = "rocket::serde")] +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] #[sea_orm(table_name = "user")] pub struct Model { #[sea_orm(primary_key)] diff --git a/bookkeeper/migration/src/m20220101_000001_create_table.rs b/bookkeeper/migration/src/m20220101_000001_create_table.rs index dec9ee5..9ef14b6 100644 --- a/bookkeeper/migration/src/m20220101_000001_create_table.rs +++ b/bookkeeper/migration/src/m20220101_000001_create_table.rs @@ -7,18 +7,41 @@ pub struct Migration; impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .create_table( - Table::create() - .table(User::Table) - .if_not_exists() - .col(pk_auto(User::Id)) - .col(string(User::Name)) - .col(string(User::Password)) - .col(string(User::SessionToken)) - .to_owned(), - ) - .await + manager.create_table( + Table::create() + .table(User::Table) + .if_not_exists() + .col(pk_auto(User::Id)) + .col(string(User::Name)) + .col(string(User::Password)) + .col(string(User::SessionToken)) + .to_owned(), + ) + .await?; + + manager.create_table( + Table::create() + .table(Transaction::Table) + .if_not_exists() + .col(pk_auto(Transaction::Id)) + .col(integer(Transaction::Code)) + .col(string(Transaction::Name)) + .col(date(Transaction::Date)) + .col(decimal(Transaction::Buy)) + .col(integer(Transaction::Volume)) + .col(decimal(Transaction::NetBuy)) + .col(date_null(Transaction::SellDate)) + .col(decimal_null(Transaction::Sell)) + .col(decimal_null(Transaction::NetSell)) + .col(integer_null(Transaction::SoldVolume)) + .col(json_binary_null(Transaction::SplitPieces)) + .col(decimal_null(Transaction::Gain)) + .col(decimal_null(Transaction::NetGain)) + .to_owned(), + ) + .await?; + + Ok(()) } async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { @@ -27,7 +50,13 @@ impl MigrationTrait for Migration { manager .drop_table(Table::drop().table(User::Table).to_owned()) - .await + .await?; + + manager + .drop_table(Table::drop().table(Transaction::Table).to_owned()) + .await?; + + Ok(()) } } @@ -39,3 +68,22 @@ enum User { Password, SessionToken, } + +#[derive(DeriveIden)] +enum Transaction { + Table, + Id, + Code, + Name, + Date, + Buy, + Volume, + NetBuy, + Sell, + SellDate, + NetSell, + SoldVolume, + SplitPieces, + Gain, + NetGain, +} \ No newline at end of file diff --git a/bookkeeper/src/main.rs b/bookkeeper/src/main.rs index 626cb1e..2baf91e 100644 --- a/bookkeeper/src/main.rs +++ b/bookkeeper/src/main.rs @@ -1,22 +1,98 @@ #[macro_use] extern crate rocket; +use std::str::FromStr; +use rocket::form::Form; +use rocket::response::{Flash, Redirect}; +use migration::{MigratorTrait}; +use sea_orm::ActiveValue::Set; +use sea_orm::{ActiveModelTrait, ConnectOptions, DatabaseConnection}; +use sea_orm_rocket::{rocket::figment::Figment, Config, Database, Connection}; +use std::time::Duration; +use chrono::{NaiveDate}; +use entity::transaction; +use rust_decimal::Decimal; +use rocket::{Build, Rocket}; +use rocket::fairing::{self, AdHoc}; + + +#[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 { + let config = figment.extract::().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!" } -use migration::{Migrator, MigratorTrait}; -use sea_orm::Database; +#[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 = "")] +async fn buy(trans_buy: Form>, conn: Connection<'_, Db>) -> Flash { + 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) -> fairing::Result { + let conn = &Db::fetch(&rocket).unwrap().conn; + let _ = migration::Migrator::up(conn, None).await; + Ok(rocket) +} #[launch] async fn rocket() -> _ { - let db = Database::connect("sqlite://bookkeeper.db") - .await - .expect("Failed to setup the database"); - Migrator::up(&db, None) - .await - .expect("Failed to run migrations for tests"); - - rocket::build().mount("/", routes![index]) -} \ No newline at end of file + rocket::build() + .attach(Db::init()) + .attach(AdHoc::try_on_ignite("Migrations", run_migrations)) + .mount("/", routes![index, buy]) +}