diff --git a/Cargo.toml b/Cargo.toml index 2260939..1699701 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ ring-compat = { version = "^0.8", features = [ "signature", "rand_core", ], optional = true } -sqlx = { version = "^0.8", features = ["sqlite", "runtime-tokio"], optional = true } +sqlx = { version = "^0.8", features = ["sqlite"], optional = true } tauri = { version = "2", features = ["config-toml"], optional = true } tauri-plugin-fs = { version = "2", optional = true } tauri-plugin-opener = { version = "2", optional = true } diff --git a/Tauri.toml b/Tauri.toml index 2a12b6b..8780e66 100644 --- a/Tauri.toml +++ b/Tauri.toml @@ -1,5 +1,5 @@ "$schema" = "https://schema.tauri.app/config/2" -identifier = "de.hessensagtnein.darmstadt.buchhaltung" +identifier = "de.mathebau.bkbh" productName = "Nein!" version = "0.1.0" diff --git a/gen/android/app/build.gradle.kts b/gen/android/app/build.gradle.kts index 86e6c7e..397ab02 100644 --- a/gen/android/app/build.gradle.kts +++ b/gen/android/app/build.gradle.kts @@ -16,10 +16,10 @@ val tauriProperties = Properties().apply { android { compileSdk = 34 - namespace = "de.hessensagtnein.darmstadt.buchhaltung" + namespace = "de.mathebau.bkbh" defaultConfig { manifestPlaceholders["usesCleartextTraffic"] = "false" - applicationId = "de.hessensagtnein.darmstadt.buchhaltung" + applicationId = "de.mathebau.bkbh" minSdk = 24 targetSdk = 34 versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt() diff --git a/migrations/0000_init.sql b/migrations/0000_init.sql deleted file mode 100644 index 1aa1325..0000000 --- a/migrations/0000_init.sql +++ /dev/null @@ -1,29 +0,0 @@ -CREATE TABLE `swap` ( - `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - `acc` INTEGER NOT NULL, - `voucher` INTEGER NOT NULL, - `storno` INTEGER NOT NULL, - `timestamp` INTEGER NOT NULL -); - -CREATE TABLE `voucher_type` ( - `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - `store` INTEGER NOT NULL, - `value` INTEGER NOT NULL, - UNIQUE (`store`, `value`) -); - -CREATE TABLE `inventory` ( - `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - `acc` INTEGER NOT NULL, - `cash` INTEGER NOT NULL, - `timestamp` INTEGER NOT NULL, - UNIQUE (`acc`, `timestamp`) -); - -CREATE TABLE `voucher_inventory` ( - `inventory` INTEGER NOT NULL, - `voucher` INTEGER NOT NULL, - `count` INTEGER NOT NULL, - PRIMARY KEY (`inventory`, `voucher`) -); diff --git a/src/lib.rs b/src/lib.rs index 32bb1c4..ef98862 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,6 +25,7 @@ pub fn run() { }) .invoke_handler(tauri::generate_handler![ server::swap, + server::count, server::inventory, server::data_door::pull_data, server::data_door::push_data, diff --git a/src/server/app_state.rs b/src/server/app_state.rs index 0814efa..a67f163 100644 --- a/src/server/app_state.rs +++ b/src/server/app_state.rs @@ -12,7 +12,7 @@ pub struct AppState { impl AppState { pub fn new() -> Self { - todo!(); + todo!() let db = unimplemented!(); let mut rng = rand::thread_rng(); let last_sync = i64::MIN; diff --git a/src/server/mod.rs b/src/server/mod.rs index f852268..715c3f3 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -11,10 +11,6 @@ pub mod data_door; use app_state::AppState; -struct Id { - id: i64, -} - fn parse_inventory(data: HashMap) -> Result { let a = data.get("cafe-inventory-acc").ok_or(())?; let acc: Account = Account::try_from(a.as_ref())?; @@ -28,13 +24,11 @@ fn parse_inventory(data: HashMap) -> Result { None => (), Some(c) => { let c = if c == "" { "0" } else { c }; - let Ok(count): Result = c.parse() else { + let Ok(count) = c.parse() else { println!("Invalid count '{}' for '{}' in inventory data.", c, s); continue; }; - let value = 50_00; - let voucher = VoucherType { store, value }; - let v = (voucher, count); + let v = VoucherInventory { store, count }; vouchers.push(v); } } @@ -42,28 +36,6 @@ fn parse_inventory(data: HashMap) -> Result { unimplemented!() } -pub async fn voucher_id(v: VoucherType, db: &mut Connection) -> Result { - sqlx::query!( - "INSERT OR IGNORE INTO voucher_type(store, value) VALUES (?1, ?2)", - v.store, - v.value, - ) - .execute(&mut *db) - .await - .map_err(|e| println!("{:?}", e))?; - let id = sqlx::query_as!( - Id, - "SELECT id FROM voucher_type WHERE store = ?1 AND value = ?2", - v.store, - v.value, - ) - .fetch_one(db) - .await - .map_err(|e| println!("{:?}", e))? - .id; - Ok(id) -} - #[tauri::command] pub async fn inventory( data: HashMap, @@ -71,37 +43,13 @@ pub async fn inventory( ) -> Result<(), ()> { println!("{:?}", data); let now = Utc::now().timestamp(); - let mut state = state.lock().await; + let state = state.lock().await; let inv = parse_inventory(data)?; - sqlx::query!( - "INSERT INTO inventory(acc, cash, timestamp) VALUES (?1, ?2, ?3)", - inv.acc, - inv.cash, - now, - ) - .execute(&mut state.db) - .await - .map_err(|e| println!("{:?}", e))?; - let inventory = sqlx::query_as!( - Id, - "SELECT id FROM inventory WHERE acc = ?1 AND timestamp = ?2", - inv.acc, - now, - ) - .fetch_one(&mut state.db) - .await - .map_err(|e| println!("{:?}", e))? - .id; - for (v, count) in inv.vouchers { - let voucher = voucher_id(v, &mut state.db).await?; - sqlx::query!( - "INSERT INTO voucher_inventory VALUES (?1, ?2, ?3)", - inventory, - voucher, - count, + for v in inv.vouchers { + state.db.execute( + "INSERT INTO voucher_inventory VALUES ()", + (inv.acc, v.store, v.count, now), ) - .execute(&mut state.db) - .await .map_err(|e| println!("{:?}", e))?; } Ok(()) @@ -113,21 +61,36 @@ pub async fn swap( acc: i64, state: State<'_, Mutex>, ) -> Result<(), ()> { - let timestamp = Utc::now().timestamp(); - let mut state = state.lock().await; - let id = i64::from_ne_bytes(state.id.to_ne_bytes()); - let value = 50_00; - let voucher = VoucherType{ store, value }; - let voucher_type = voucher_id(voucher, &mut state.db).await?; - sqlx::query!( - "INSERT INTO swap(acc, voucher, storno, timestamp) VALUES (?1, ?2, ?3, ?4)", - acc, - voucher_type, - false, - timestamp, + let state = state.lock().await; + state.db.execute( + "INSERT INTO swap VALUES (?1, ?2, ?3, ?4, ?5)", + ( + store, + acc, + i64::from_ne_bytes(state.id.to_ne_bytes()), + Utc::now().timestamp(), + false, + ), ) - .execute(&mut state.db) - .await .map_err(|e| println!("{:?}", e))?; Ok(()) } + +#[tauri::command] +pub async fn count(state: State<'_, Mutex>) -> Result { + let state = state.lock().await; + let mut stmt = + state.db.prepare_with("SELECT COUNT(*) FROM swap") + .map_err(|e| println!("{:?}", e))?; + let mut rows = stmt.query([]).map_err(|e| println!("{:?}", e))?; + let row = rows.next().map_err(|e| println!("{:?}", e))?; + let row = match row { + Some(r) => Ok(r), + None => { + println!("No rows"); + Err(()) + } + }?; + let cnt: u64 = row.get(0).map_err(|e| println!("{:?}", e))?; + Ok(cnt.to_string()) +} diff --git a/src/types/account.rs b/src/types/account.rs index e5f3cf7..8b89bb9 100644 --- a/src/types/account.rs +++ b/src/types/account.rs @@ -1,11 +1,10 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Copy, Debug, Serialize, Deserialize)] -#[cfg_attr(feature = "server", derive(sqlx::Type))] -#[cfg_attr(feature = "server", repr(i64))] +#[cfg_attr(features = "dep:sqlx", derive(sqlx::Type))] pub enum Account { - Sumpf = 1, - Heinersyndikat = 2, + Sumpf, + Heinersyndikat, } impl TryFrom<&str> for Account { @@ -37,4 +36,4 @@ impl std::fmt::Display for Account { } .fmt(f) } -} +} \ No newline at end of file diff --git a/src/types/cash.rs b/src/types/cash.rs index 870b953..d73255e 100644 --- a/src/types/cash.rs +++ b/src/types/cash.rs @@ -4,8 +4,6 @@ use serde::{Deserialize, Serialize}; /// measured as an integer multiple /// of 0.01 €. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr(feature = "server", derive(sqlx::Type))] -#[cfg_attr(feature = "server", sqlx(transparent))] pub struct Cash(i64); impl std::str::FromStr for Cash { @@ -22,4 +20,4 @@ impl std::str::FromStr for Cash { }; Ok(Cash(i * 100 + f)) } -} +} \ No newline at end of file diff --git a/src/types/mod.rs b/src/types/mod.rs index eaf0734..0fa5794 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -8,15 +8,15 @@ pub use store::Store; pub use account::Account; pub use cash::Cash; -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct VoucherType { - pub store: Store, - pub value: i64, -} - #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Inventory { pub acc: Account, pub cash: Cash, - pub vouchers: Vec<(VoucherType, i64)>, + pub vouchers: Vec, +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub struct VoucherInventory { + pub store: Store, + pub count: i64, } diff --git a/src/types/store.rs b/src/types/store.rs index 841ff94..2531000 100644 --- a/src/types/store.rs +++ b/src/types/store.rs @@ -2,14 +2,13 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[cfg_attr(feature = "server", derive(sqlx::Type))] -#[cfg_attr(feature = "server", repr(i64))] pub enum Store { - Aldi = 1, - Edeka = 2, - Dm = 3, - Lidl = 4, - Rewe = 5, - Tegut = 6, + Aldi, + Edeka, + Dm, + Lidl, + Rewe, + Tegut, } impl Into for &Store {