|
|
@@ -836,6 +836,70 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
.collect::<Vec<_>>())
|
|
|
}
|
|
|
|
|
|
+ async fn get_balance(
|
|
|
+ &self,
|
|
|
+ mint_url: Option<MintUrl>,
|
|
|
+ unit: Option<CurrencyUnit>,
|
|
|
+ states: Option<Vec<State>>,
|
|
|
+ ) -> Result<u64, Self::Err> {
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
+
|
|
|
+ let mut query_str = "SELECT COALESCE(SUM(amount), 0) as total FROM proof".to_string();
|
|
|
+ let mut where_clauses = Vec::new();
|
|
|
+ let states = states
|
|
|
+ .unwrap_or_default()
|
|
|
+ .into_iter()
|
|
|
+ .map(|x| x.to_string())
|
|
|
+ .collect::<Vec<_>>();
|
|
|
+
|
|
|
+ if mint_url.is_some() {
|
|
|
+ where_clauses.push("mint_url = :mint_url");
|
|
|
+ }
|
|
|
+ if unit.is_some() {
|
|
|
+ where_clauses.push("unit = :unit");
|
|
|
+ }
|
|
|
+ if !states.is_empty() {
|
|
|
+ where_clauses.push("state IN (:states)");
|
|
|
+ }
|
|
|
+
|
|
|
+ if !where_clauses.is_empty() {
|
|
|
+ query_str.push_str(" WHERE ");
|
|
|
+ query_str.push_str(&where_clauses.join(" AND "));
|
|
|
+ }
|
|
|
+
|
|
|
+ let mut q = query(&query_str)?;
|
|
|
+
|
|
|
+ if let Some(ref mint_url) = mint_url {
|
|
|
+ q = q.bind("mint_url", mint_url.to_string());
|
|
|
+ }
|
|
|
+ if let Some(ref unit) = unit {
|
|
|
+ q = q.bind("unit", unit.to_string());
|
|
|
+ }
|
|
|
+
|
|
|
+ if !states.is_empty() {
|
|
|
+ q = q.bind_vec("states", states);
|
|
|
+ }
|
|
|
+
|
|
|
+ let balance = q
|
|
|
+ .pluck(&*conn)
|
|
|
+ .await?
|
|
|
+ .map(|n| {
|
|
|
+ // SQLite SUM returns INTEGER which we need to convert to u64
|
|
|
+ match n {
|
|
|
+ crate::stmt::Column::Integer(i) => Ok(i as u64),
|
|
|
+ crate::stmt::Column::Real(f) => Ok(f as u64),
|
|
|
+ _ => Err(Error::Database(Box::new(std::io::Error::new(
|
|
|
+ std::io::ErrorKind::InvalidData,
|
|
|
+ "Invalid balance type",
|
|
|
+ )))),
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .transpose()?
|
|
|
+ .unwrap_or(0);
|
|
|
+
|
|
|
+ Ok(balance)
|
|
|
+ }
|
|
|
+
|
|
|
async fn update_proofs_state(&self, ys: Vec<PublicKey>, state: State) -> Result<(), Self::Err> {
|
|
|
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
query("UPDATE proof SET state = :state WHERE y IN (:ys)")?
|