use std::collections::HashMap;
use serde_json::Value;
use crate::error::{MtgjsonError, Result};
use crate::sql_builder::SqlBuilder;
pub const KNOWN_ID_COLUMNS: &[&str] = &[
"cardKingdomEtchedId",
"cardKingdomFoilId",
"cardKingdomId",
"cardsphereId",
"cardsphereFoilId",
"mcmId",
"mcmMetaId",
"mtgArenaId",
"mtgjsonFoilVersionId",
"mtgjsonNonFoilVersionId",
"mtgjsonV4Id",
"mtgoFoilId",
"mtgoId",
"multiverseId",
"scryfallId",
"scryfallCardBackId",
"scryfallIllustrationId",
"scryfallOracleId",
"tcgplayerEtchedProductId",
"tcgplayerProductId",
];
pub struct IdentifierQuery<'a> {
conn: &'a crate::connection::Connection,
}
impl<'a> IdentifierQuery<'a> {
pub fn new(conn: &'a crate::connection::Connection) -> Self {
Self { conn }
}
pub fn find_by(&self, column: &str, value: &str) -> Result<Vec<Value>> {
if !KNOWN_ID_COLUMNS.contains(&column) {
return Err(MtgjsonError::InvalidArgument(format!(
"Unknown identifier column: '{}'. Valid columns: {:?}",
column, KNOWN_ID_COLUMNS
)));
}
self.conn.ensure_views(&["cards", "card_identifiers"])?;
let condition = format!("ci.{} = ?", column);
let (sql, params) = SqlBuilder::new("cards c")
.join("JOIN card_identifiers ci ON c.uuid = ci.uuid")
.where_clause(&condition, &[value])
.build();
let rows = self.conn.execute(&sql, ¶ms)?;
Ok(rows_to_values(rows))
}
pub fn get_identifiers(&self, uuid: &str) -> Result<Option<Value>> {
self.conn.ensure_views(&["card_identifiers"])?;
let (sql, params) = SqlBuilder::new("card_identifiers")
.where_eq("uuid", uuid)
.limit(1)
.build();
let rows = self.conn.execute(&sql, ¶ms)?;
Ok(rows
.into_iter()
.next()
.map(|r| serde_json::to_value(r).unwrap_or(Value::Null)))
}
pub fn find_by_card_kingdom_etched_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("cardKingdomEtchedId", value)
}
pub fn find_by_card_kingdom_foil_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("cardKingdomFoilId", value)
}
pub fn find_by_card_kingdom_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("cardKingdomId", value)
}
pub fn find_by_cardsphere_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("cardsphereId", value)
}
pub fn find_by_cardsphere_foil_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("cardsphereFoilId", value)
}
pub fn find_by_mcm_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("mcmId", value)
}
pub fn find_by_mcm_meta_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("mcmMetaId", value)
}
pub fn find_by_mtg_arena_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("mtgArenaId", value)
}
pub fn find_by_mtgjson_foil_version_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("mtgjsonFoilVersionId", value)
}
pub fn find_by_mtgjson_non_foil_version_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("mtgjsonNonFoilVersionId", value)
}
pub fn find_by_mtgjson_v4_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("mtgjsonV4Id", value)
}
pub fn find_by_mtgo_foil_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("mtgoFoilId", value)
}
pub fn find_by_mtgo_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("mtgoId", value)
}
pub fn find_by_multiverse_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("multiverseId", value)
}
pub fn find_by_scryfall_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("scryfallId", value)
}
pub fn find_by_scryfall_card_back_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("scryfallCardBackId", value)
}
pub fn find_by_scryfall_illustration_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("scryfallIllustrationId", value)
}
pub fn find_by_scryfall_oracle_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("scryfallOracleId", value)
}
pub fn find_by_tcgplayer_etched_product_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("tcgplayerEtchedProductId", value)
}
pub fn find_by_tcgplayer_product_id(&self, value: &str) -> Result<Vec<Value>> {
self.find_by("tcgplayerProductId", value)
}
}
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()
}