mtgjson_sdk/queries/
identifiers.rs1use std::collections::HashMap;
7
8use serde_json::Value;
9
10use crate::error::{MtgjsonError, Result};
11use crate::sql_builder::SqlBuilder;
12
13pub const KNOWN_ID_COLUMNS: &[&str] = &[
19 "cardKingdomEtchedId",
20 "cardKingdomFoilId",
21 "cardKingdomId",
22 "cardsphereId",
23 "cardsphereFoilId",
24 "mcmId",
25 "mcmMetaId",
26 "mtgArenaId",
27 "mtgjsonFoilVersionId",
28 "mtgjsonNonFoilVersionId",
29 "mtgjsonV4Id",
30 "mtgoFoilId",
31 "mtgoId",
32 "multiverseId",
33 "scryfallId",
34 "scryfallCardBackId",
35 "scryfallIllustrationId",
36 "scryfallOracleId",
37 "tcgplayerEtchedProductId",
38 "tcgplayerProductId",
39];
40
41pub struct IdentifierQuery<'a> {
47 conn: &'a crate::connection::Connection,
48}
49
50impl<'a> IdentifierQuery<'a> {
51 pub fn new(conn: &'a crate::connection::Connection) -> Self {
53 Self { conn }
54 }
55
56 pub fn find_by(&self, column: &str, value: &str) -> Result<Vec<Value>> {
62 if !KNOWN_ID_COLUMNS.contains(&column) {
63 return Err(MtgjsonError::InvalidArgument(format!(
64 "Unknown identifier column: '{}'. Valid columns: {:?}",
65 column, KNOWN_ID_COLUMNS
66 )));
67 }
68
69 self.conn.ensure_views(&["cards", "card_identifiers"])?;
70
71 let condition = format!("ci.{} = ?", column);
72 let (sql, params) = SqlBuilder::new("cards c")
73 .join("JOIN card_identifiers ci ON c.uuid = ci.uuid")
74 .where_clause(&condition, &[value])
75 .build();
76
77 let rows = self.conn.execute(&sql, ¶ms)?;
78 Ok(rows_to_values(rows))
79 }
80
81 pub fn get_identifiers(&self, uuid: &str) -> Result<Option<Value>> {
85 self.conn.ensure_views(&["card_identifiers"])?;
86
87 let (sql, params) = SqlBuilder::new("card_identifiers")
88 .where_eq("uuid", uuid)
89 .limit(1)
90 .build();
91
92 let rows = self.conn.execute(&sql, ¶ms)?;
93 Ok(rows
94 .into_iter()
95 .next()
96 .map(|r| serde_json::to_value(r).unwrap_or(Value::Null)))
97 }
98
99 pub fn find_by_card_kingdom_etched_id(&self, value: &str) -> Result<Vec<Value>> {
103 self.find_by("cardKingdomEtchedId", value)
104 }
105
106 pub fn find_by_card_kingdom_foil_id(&self, value: &str) -> Result<Vec<Value>> {
108 self.find_by("cardKingdomFoilId", value)
109 }
110
111 pub fn find_by_card_kingdom_id(&self, value: &str) -> Result<Vec<Value>> {
113 self.find_by("cardKingdomId", value)
114 }
115
116 pub fn find_by_cardsphere_id(&self, value: &str) -> Result<Vec<Value>> {
118 self.find_by("cardsphereId", value)
119 }
120
121 pub fn find_by_cardsphere_foil_id(&self, value: &str) -> Result<Vec<Value>> {
123 self.find_by("cardsphereFoilId", value)
124 }
125
126 pub fn find_by_mcm_id(&self, value: &str) -> Result<Vec<Value>> {
128 self.find_by("mcmId", value)
129 }
130
131 pub fn find_by_mcm_meta_id(&self, value: &str) -> Result<Vec<Value>> {
133 self.find_by("mcmMetaId", value)
134 }
135
136 pub fn find_by_mtg_arena_id(&self, value: &str) -> Result<Vec<Value>> {
138 self.find_by("mtgArenaId", value)
139 }
140
141 pub fn find_by_mtgjson_foil_version_id(&self, value: &str) -> Result<Vec<Value>> {
143 self.find_by("mtgjsonFoilVersionId", value)
144 }
145
146 pub fn find_by_mtgjson_non_foil_version_id(&self, value: &str) -> Result<Vec<Value>> {
148 self.find_by("mtgjsonNonFoilVersionId", value)
149 }
150
151 pub fn find_by_mtgjson_v4_id(&self, value: &str) -> Result<Vec<Value>> {
153 self.find_by("mtgjsonV4Id", value)
154 }
155
156 pub fn find_by_mtgo_foil_id(&self, value: &str) -> Result<Vec<Value>> {
158 self.find_by("mtgoFoilId", value)
159 }
160
161 pub fn find_by_mtgo_id(&self, value: &str) -> Result<Vec<Value>> {
163 self.find_by("mtgoId", value)
164 }
165
166 pub fn find_by_multiverse_id(&self, value: &str) -> Result<Vec<Value>> {
168 self.find_by("multiverseId", value)
169 }
170
171 pub fn find_by_scryfall_id(&self, value: &str) -> Result<Vec<Value>> {
173 self.find_by("scryfallId", value)
174 }
175
176 pub fn find_by_scryfall_card_back_id(&self, value: &str) -> Result<Vec<Value>> {
178 self.find_by("scryfallCardBackId", value)
179 }
180
181 pub fn find_by_scryfall_illustration_id(&self, value: &str) -> Result<Vec<Value>> {
183 self.find_by("scryfallIllustrationId", value)
184 }
185
186 pub fn find_by_scryfall_oracle_id(&self, value: &str) -> Result<Vec<Value>> {
188 self.find_by("scryfallOracleId", value)
189 }
190
191 pub fn find_by_tcgplayer_etched_product_id(&self, value: &str) -> Result<Vec<Value>> {
193 self.find_by("tcgplayerEtchedProductId", value)
194 }
195
196 pub fn find_by_tcgplayer_product_id(&self, value: &str) -> Result<Vec<Value>> {
198 self.find_by("tcgplayerProductId", value)
199 }
200}
201
202fn rows_to_values(rows: Vec<HashMap<String, Value>>) -> Vec<Value> {
207 rows.into_iter()
208 .map(|r| serde_json::to_value(r).unwrap_or(Value::Null))
209 .collect()
210}