rovenue/cache/
virtual_currencies.rs1use std::collections::BTreeMap;
2use std::sync::Arc;
3
4use rusqlite::params;
5
6use super::store::CacheStore;
7use crate::error::RovenueResult;
8
9pub struct VirtualCurrencyRepo {
12 store: Arc<CacheStore>,
13}
14
15impl VirtualCurrencyRepo {
16 pub fn new(store: Arc<CacheStore>) -> Self {
17 Self { store }
18 }
19
20 pub fn get_all(&self, user_scope: &str) -> RovenueResult<BTreeMap<String, i64>> {
22 self.store.with_conn(|c| {
23 let mut stmt = c.prepare(
24 "SELECT code, balance FROM virtual_currency_balance WHERE user_scope = ?1 ORDER BY code",
25 )?;
26 let mut rows = stmt.query(params![user_scope])?;
27 let mut out = BTreeMap::new();
28 while let Some(r) = rows.next()? {
29 let code: String = r.get(0)?;
30 let balance: i64 = r.get(1)?;
31 out.insert(code, balance);
32 }
33 Ok(out)
34 })
35 }
36
37 pub fn get(&self, user_scope: &str, code: &str) -> RovenueResult<Option<i64>> {
39 self.store.with_conn(|c| {
40 let mut stmt = c.prepare(
41 "SELECT balance FROM virtual_currency_balance WHERE user_scope = ?1 AND code = ?2",
42 )?;
43 let mut rows = stmt.query(params![user_scope, code])?;
44 if let Some(r) = rows.next()? {
45 Ok(Some(r.get::<_, i64>(0)?))
46 } else {
47 Ok(None)
48 }
49 })
50 }
51
52 pub fn upsert_all(
55 &self,
56 user_scope: &str,
57 balances: &BTreeMap<String, i64>,
58 updated_at_ms: u64,
59 ) -> RovenueResult<()> {
60 self.store.with_conn(|c| {
61 c.execute(
63 "DELETE FROM virtual_currency_balance WHERE user_scope = ?1",
64 params![user_scope],
65 )?;
66 for (code, balance) in balances {
67 c.execute(
68 "INSERT INTO virtual_currency_balance (user_scope, code, balance, updated_at_ms)
69 VALUES (?1, ?2, ?3, ?4)",
70 params![user_scope, code, balance, updated_at_ms as i64],
71 )?;
72 }
73 Ok(())
74 })
75 }
76}