use std::collections::HashMap;
use serde_json::Value;
use crate::error::Result;
use crate::sql_builder::SqlBuilder;
pub struct LegalityQuery<'a> {
conn: &'a crate::connection::Connection,
}
impl<'a> LegalityQuery<'a> {
pub fn new(conn: &'a crate::connection::Connection) -> Self {
Self { conn }
}
pub fn formats_for_card(&self, uuid: &str) -> Result<Vec<Value>> {
self.conn.ensure_views(&["card_legalities"])?;
let (sql, params) = SqlBuilder::new("card_legalities")
.where_eq("uuid", uuid)
.build();
let rows = self.conn.execute(&sql, ¶ms)?;
Ok(rows_to_values(rows))
}
pub fn is_legal(&self, uuid: &str, format: &str) -> Result<bool> {
self.conn.ensure_views(&["card_legalities"])?;
let (sql, params) = SqlBuilder::new("card_legalities")
.select(&["COUNT(*) AS cnt"])
.where_eq("uuid", uuid)
.where_eq("format", format)
.where_eq("status", "Legal")
.build();
let rows = self.conn.execute(&sql, ¶ms)?;
let cnt = rows
.first()
.and_then(|r| r.get("cnt"))
.and_then(|v| v.as_i64())
.unwrap_or(0);
Ok(cnt > 0)
}
pub fn legal_in(
&self,
format: &str,
limit: Option<usize>,
offset: Option<usize>,
) -> Result<Vec<Value>> {
self.status_query(format, "Legal", limit, offset)
}
pub fn banned_in(
&self,
format: &str,
limit: Option<usize>,
offset: Option<usize>,
) -> Result<Vec<Value>> {
self.status_query(format, "Banned", limit, offset)
}
pub fn restricted_in(
&self,
format: &str,
limit: Option<usize>,
offset: Option<usize>,
) -> Result<Vec<Value>> {
self.status_query(format, "Restricted", limit, offset)
}
pub fn suspended_in(
&self,
format: &str,
limit: Option<usize>,
offset: Option<usize>,
) -> Result<Vec<Value>> {
self.status_query(format, "Suspended", limit, offset)
}
pub fn not_legal_in(
&self,
format: &str,
limit: Option<usize>,
offset: Option<usize>,
) -> Result<Vec<Value>> {
self.status_query(format, "Not Legal", limit, offset)
}
fn status_query(
&self,
format: &str,
status: &str,
limit: Option<usize>,
offset: Option<usize>,
) -> Result<Vec<Value>> {
self.conn.ensure_views(&["cards", "card_legalities"])?;
let mut qb = SqlBuilder::new("cards c");
qb.join("JOIN card_legalities cl ON c.uuid = cl.uuid");
qb.where_eq("cl.format", format);
qb.where_eq("cl.status", status);
let limit = limit.unwrap_or(100);
let offset = offset.unwrap_or(0);
qb.limit(limit);
qb.offset(offset);
let (sql, params) = qb.build();
let rows = self.conn.execute(&sql, ¶ms)?;
Ok(rows_to_values(rows))
}
}
fn rows_to_values(rows: Vec<HashMap<String, Value>>) -> Vec<Value> {
rows.into_iter()
.map(|r| serde_json::to_value(r).unwrap_or(Value::Null))
.collect()
}