Switch DB crate
This commit is contained in:
parent
61105ccf37
commit
58206d41b5
9 changed files with 126 additions and 57 deletions
|
@ -47,7 +47,7 @@ ring-compat = { version = "^0.8", features = [
|
||||||
"signature",
|
"signature",
|
||||||
"rand_core",
|
"rand_core",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
sqlx = { version = "^0.8", features = ["sqlite"], optional = true }
|
sqlx = { version = "^0.8", features = ["sqlite", "runtime-tokio"], optional = true }
|
||||||
tauri = { version = "2", features = ["config-toml"], optional = true }
|
tauri = { version = "2", features = ["config-toml"], optional = true }
|
||||||
tauri-plugin-fs = { version = "2", optional = true }
|
tauri-plugin-fs = { version = "2", optional = true }
|
||||||
tauri-plugin-opener = { version = "2", optional = true }
|
tauri-plugin-opener = { version = "2", optional = true }
|
||||||
|
|
29
migrations/0000_init.sql
Normal file
29
migrations/0000_init.sql
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
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`)
|
||||||
|
);
|
|
@ -25,7 +25,6 @@ pub fn run() {
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
server::swap,
|
server::swap,
|
||||||
server::count,
|
|
||||||
server::inventory,
|
server::inventory,
|
||||||
server::data_door::pull_data,
|
server::data_door::pull_data,
|
||||||
server::data_door::push_data,
|
server::data_door::push_data,
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct AppState {
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
todo!()
|
todo!();
|
||||||
let db = unimplemented!();
|
let db = unimplemented!();
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let last_sync = i64::MIN;
|
let last_sync = i64::MIN;
|
||||||
|
|
|
@ -11,6 +11,10 @@ pub mod data_door;
|
||||||
|
|
||||||
use app_state::AppState;
|
use app_state::AppState;
|
||||||
|
|
||||||
|
struct Id {
|
||||||
|
id: i64,
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_inventory(data: HashMap<String, String>) -> Result<Inventory, ()> {
|
fn parse_inventory(data: HashMap<String, String>) -> Result<Inventory, ()> {
|
||||||
let a = data.get("cafe-inventory-acc").ok_or(())?;
|
let a = data.get("cafe-inventory-acc").ok_or(())?;
|
||||||
let acc: Account = Account::try_from(a.as_ref())?;
|
let acc: Account = Account::try_from(a.as_ref())?;
|
||||||
|
@ -24,11 +28,13 @@ fn parse_inventory(data: HashMap<String, String>) -> Result<Inventory, ()> {
|
||||||
None => (),
|
None => (),
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
let c = if c == "" { "0" } else { c };
|
let c = if c == "" { "0" } else { c };
|
||||||
let Ok(count) = c.parse() else {
|
let Ok(count): Result<i64, _> = c.parse() else {
|
||||||
println!("Invalid count '{}' for '{}' in inventory data.", c, s);
|
println!("Invalid count '{}' for '{}' in inventory data.", c, s);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let v = VoucherInventory { store, count };
|
let value = 50_00;
|
||||||
|
let voucher = VoucherType { store, value };
|
||||||
|
let v = (voucher, count);
|
||||||
vouchers.push(v);
|
vouchers.push(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +42,28 @@ fn parse_inventory(data: HashMap<String, String>) -> Result<Inventory, ()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn voucher_id(v: VoucherType, db: &mut Connection) -> Result<i64, ()> {
|
||||||
|
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]
|
#[tauri::command]
|
||||||
pub async fn inventory(
|
pub async fn inventory(
|
||||||
data: HashMap<String, String>,
|
data: HashMap<String, String>,
|
||||||
|
@ -43,13 +71,37 @@ pub async fn inventory(
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
println!("{:?}", data);
|
println!("{:?}", data);
|
||||||
let now = Utc::now().timestamp();
|
let now = Utc::now().timestamp();
|
||||||
let state = state.lock().await;
|
let mut state = state.lock().await;
|
||||||
let inv = parse_inventory(data)?;
|
let inv = parse_inventory(data)?;
|
||||||
for v in inv.vouchers {
|
sqlx::query!(
|
||||||
state.db.execute(
|
"INSERT INTO inventory(acc, cash, timestamp) VALUES (?1, ?2, ?3)",
|
||||||
"INSERT INTO voucher_inventory VALUES ()",
|
inv.acc,
|
||||||
(inv.acc, v.store, v.count, now),
|
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,
|
||||||
)
|
)
|
||||||
|
.execute(&mut state.db)
|
||||||
|
.await
|
||||||
.map_err(|e| println!("{:?}", e))?;
|
.map_err(|e| println!("{:?}", e))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -61,36 +113,21 @@ pub async fn swap(
|
||||||
acc: i64,
|
acc: i64,
|
||||||
state: State<'_, Mutex<AppState>>,
|
state: State<'_, Mutex<AppState>>,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let state = state.lock().await;
|
let timestamp = Utc::now().timestamp();
|
||||||
state.db.execute(
|
let mut state = state.lock().await;
|
||||||
"INSERT INTO swap VALUES (?1, ?2, ?3, ?4, ?5)",
|
let id = i64::from_ne_bytes(state.id.to_ne_bytes());
|
||||||
(
|
let value = 50_00;
|
||||||
store,
|
let voucher = VoucherType{ store, value };
|
||||||
acc,
|
let voucher_type = voucher_id(voucher, &mut state.db).await?;
|
||||||
i64::from_ne_bytes(state.id.to_ne_bytes()),
|
sqlx::query!(
|
||||||
Utc::now().timestamp(),
|
"INSERT INTO swap(acc, voucher, storno, timestamp) VALUES (?1, ?2, ?3, ?4)",
|
||||||
false,
|
acc,
|
||||||
),
|
voucher_type,
|
||||||
|
false,
|
||||||
|
timestamp,
|
||||||
)
|
)
|
||||||
|
.execute(&mut state.db)
|
||||||
|
.await
|
||||||
.map_err(|e| println!("{:?}", e))?;
|
.map_err(|e| println!("{:?}", e))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn count(state: State<'_, Mutex<AppState>>) -> Result<String, ()> {
|
|
||||||
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())
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
#[cfg_attr(features = "dep:sqlx", derive(sqlx::Type))]
|
#[cfg_attr(feature = "server", derive(sqlx::Type))]
|
||||||
|
#[cfg_attr(feature = "server", repr(i64))]
|
||||||
pub enum Account {
|
pub enum Account {
|
||||||
Sumpf,
|
Sumpf = 1,
|
||||||
Heinersyndikat,
|
Heinersyndikat = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&str> for Account {
|
impl TryFrom<&str> for Account {
|
||||||
|
@ -36,4 +37,4 @@ impl std::fmt::Display for Account {
|
||||||
}
|
}
|
||||||
.fmt(f)
|
.fmt(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ use serde::{Deserialize, Serialize};
|
||||||
/// measured as an integer multiple
|
/// measured as an integer multiple
|
||||||
/// of 0.01 €.
|
/// of 0.01 €.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
#[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);
|
pub struct Cash(i64);
|
||||||
|
|
||||||
impl std::str::FromStr for Cash {
|
impl std::str::FromStr for Cash {
|
||||||
|
@ -20,4 +22,4 @@ impl std::str::FromStr for Cash {
|
||||||
};
|
};
|
||||||
Ok(Cash(i * 100 + f))
|
Ok(Cash(i * 100 + f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,15 @@ pub use store::Store;
|
||||||
pub use account::Account;
|
pub use account::Account;
|
||||||
pub use cash::Cash;
|
pub use cash::Cash;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct VoucherType {
|
||||||
|
pub store: Store,
|
||||||
|
pub value: i64,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Inventory {
|
pub struct Inventory {
|
||||||
pub acc: Account,
|
pub acc: Account,
|
||||||
pub cash: Cash,
|
pub cash: Cash,
|
||||||
pub vouchers: Vec<VoucherInventory>,
|
pub vouchers: Vec<(VoucherType, i64)>,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
|
||||||
pub struct VoucherInventory {
|
|
||||||
pub store: Store,
|
|
||||||
pub count: i64,
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,14 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "server", derive(sqlx::Type))]
|
#[cfg_attr(feature = "server", derive(sqlx::Type))]
|
||||||
|
#[cfg_attr(feature = "server", repr(i64))]
|
||||||
pub enum Store {
|
pub enum Store {
|
||||||
Aldi,
|
Aldi = 1,
|
||||||
Edeka,
|
Edeka = 2,
|
||||||
Dm,
|
Dm = 3,
|
||||||
Lidl,
|
Lidl = 4,
|
||||||
Rewe,
|
Rewe = 5,
|
||||||
Tegut,
|
Tegut = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<String> for &Store {
|
impl Into<String> for &Store {
|
||||||
|
|
Loading…
Add table
Reference in a new issue