From a5b133af03085eea721e20b66eb5a52a12c4f74d Mon Sep 17 00:00:00 2001 From: dadaa Date: Thu, 16 May 2024 22:53:04 +0900 Subject: [PATCH 1/2] Supports icons dependent on theme --- components/suggest/src/rs.rs | 6 +- components/suggest/src/schema.rs | 6 +- components/suggest/src/store.rs | 201 ++++++++++++++++++------- components/suggest/src/suggest.udl | 6 +- components/suggest/src/suggestion.rs | 6 +- components/suggest/src/testing/data.rs | 25 ++- components/suggest/src/testing/mod.rs | 24 ++- components/suggest/src/yelp.rs | 74 ++++++--- 8 files changed, 258 insertions(+), 90 deletions(-) diff --git a/components/suggest/src/rs.rs b/components/suggest/src/rs.rs index 5e1f1cbed1..a116ff4afd 100644 --- a/components/suggest/src/rs.rs +++ b/components/suggest/src/rs.rs @@ -461,8 +461,10 @@ pub(crate) struct DownloadedYelpSuggestion { pub location_signs: Vec, #[serde(rename = "yelpModifiers")] pub yelp_modifiers: Vec, - #[serde(rename = "icon")] - pub icon_id: String, + #[serde(rename = "iconLightTheme")] + pub icon_light_theme_id: String, + #[serde(rename = "iconDarkTheme")] + pub icon_dark_theme_id: String, pub score: f64, } diff --git a/components/suggest/src/schema.rs b/components/suggest/src/schema.rs index 76a0deed39..8008eae94f 100644 --- a/components/suggest/src/schema.rs +++ b/components/suggest/src/schema.rs @@ -113,9 +113,11 @@ CREATE TABLE yelp_location_signs( ) WITHOUT ROWID; CREATE TABLE yelp_custom_details( - icon_id TEXT PRIMARY KEY, + icon_light_theme_id TEXT NOT NULL, + icon_dark_theme_id TEXT NOT NULL, score REAL NOT NULL, - record_id TEXT NOT NULL + record_id TEXT NOT NULL, + PRIMARY KEY (icon_light_theme_id, icon_dark_theme_id) ) WITHOUT ROWID; CREATE TABLE mdn_custom_details( diff --git a/components/suggest/src/store.rs b/components/suggest/src/store.rs index 7cb2879a26..59ebb11fd9 100644 --- a/components/suggest/src/store.rs +++ b/components/suggest/src/store.rs @@ -1259,12 +1259,12 @@ mod tests { json!([burnout_pocket(), multimatch_pocket(),]), ) .with_record("yelp-suggestions", "data-4", json!([ramen_yelp(),])) - .with_record("yeld-suggestions", "data-4", json!([ramen_yelp(),])) .with_record("mdn-suggestions", "data-5", json!([array_mdn(),])) .with_icon(good_place_eats_icon()) .with_icon(california_icon()) .with_icon(caltech_icon()) - .with_icon(yelp_favicon()) + .with_icon(yelp_light_theme_icon()) + .with_icon(yelp_dark_theme_icon()) .with_icon(multimatch_wiki_icon()), ); @@ -2758,68 +2758,165 @@ mod tests { fn query_no_yelp_icon_data() -> anyhow::Result<()> { before_each(); - let snapshot = Snapshot::with_records(json!([{ - "id": "data-1", - "type": "yelp-suggestions", - "last_modified": 15, - "attachment": { - "filename": "data-1.json", - "mimetype": "application/json", - "location": "data-1.json", - "hash": "", - "size": 0, - }, - }]))? - .with_data( - "data-1.json", - json!([ - { + let store = TestStore::new( + MockRemoteSettingsClient::default() + .with_record("yelp-suggestions", "data-1", json!([{ + "subjects": ["ramen"], + "preModifiers": [], + "postModifiers": [], + "locationSigns": [], + "yelpModifiers": [], + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", + "score": 0.5 + }])) + ); + + store.ingest(SuggestIngestionConstraints::default()); + + assert_eq!( + store.fetch_suggestions(SuggestionQuery::yelp("ramen")), + vec![ + Suggestion::Yelp { + title: "ramen".into(), + url: "https://www.yelp.com/search?find_desc=ramen".into(), + icon_light_theme: None, + icon_light_theme_mimetype: None, + icon_dark_theme: None, + icon_dark_theme_mimetype: None, + score: 0.5, + has_location_sign: false, + subject_exact_match: true, + location_param: "find_loc".into(), + } + ], + ); + Ok(()) + } + + #[test] + fn query_full_yelp_icon_data() -> anyhow::Result<()> { + before_each(); + + let store = TestStore::new( + MockRemoteSettingsClient::default() + .with_record("yelp-suggestions", "data-1", json!([{ "subjects": ["ramen"], "preModifiers": [], "postModifiers": [], "locationSigns": [], "yelpModifiers": [], "icon": "yelp-favicon", + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", "score": 0.5 - }, - ]), - )?; + }])) + .with_icon(yelp_favicon()) + .with_icon(yelp_light_theme_icon()) + .with_icon(yelp_dark_theme_icon()) + ); - let store = unique_test_store(SnapshotSettingsClient::with_snapshot(snapshot)); + store.ingest(SuggestIngestionConstraints::default()); - store.ingest(SuggestIngestionConstraints::default())?; + assert_eq!( + store.fetch_suggestions(SuggestionQuery::yelp("ramen")), + vec![ + Suggestion::Yelp { + title: "ramen".into(), + url: "https://www.yelp.com/search?find_desc=ramen".into(), + icon_light_theme: Some("yelp-light-theme-icon-data".into()), + icon_light_theme_mimetype: Some("image/svg+xml".into()), + icon_dark_theme: Some("yelp-dark-theme-icon-data".into()), + icon_dark_theme_mimetype: Some("image/svg+xml".into()), + score: 0.5, + has_location_sign: false, + subject_exact_match: true, + location_param: "find_loc".into(), + } + ], + ); + Ok(()) + } - let table = [( - "keyword = ramen; Yelp only", - SuggestionQuery { - keyword: "ramen".into(), - providers: vec![SuggestionProvider::Yelp], - limit: None, - }, - expect![[r#" - [ - Yelp { - url: "https://www.yelp.com/search?find_desc=ramen", - title: "ramen", - icon: None, - icon_mimetype: None, - score: 0.5, - has_location_sign: false, - subject_exact_match: true, - location_param: "find_loc", - }, - ] - "#]], - )]; + #[test] + fn query_only_light_theme_yelp_icon_data() -> anyhow::Result<()> { + before_each(); - for (what, query, expect) in table { - expect.assert_debug_eq( - &store - .query(query) - .with_context(|| format!("Couldn't query store for {}", what))?, - ); - } + let store = TestStore::new( + MockRemoteSettingsClient::default() + .with_record("yelp-suggestions", "data-1", json!([{ + "subjects": ["ramen"], + "preModifiers": [], + "postModifiers": [], + "locationSigns": [], + "yelpModifiers": [], + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", + "score": 0.5 + }])) + .with_icon(yelp_light_theme_icon()) + ); + + store.ingest(SuggestIngestionConstraints::default()); + + assert_eq!( + store.fetch_suggestions(SuggestionQuery::yelp("ramen")), + vec![ + Suggestion::Yelp { + title: "ramen".into(), + url: "https://www.yelp.com/search?find_desc=ramen".into(), + icon_light_theme: Some("yelp-light-theme-icon-data".into()), + icon_light_theme_mimetype: Some("image/svg+xml".into()), + icon_dark_theme: None, + icon_dark_theme_mimetype: None, + score: 0.5, + has_location_sign: false, + subject_exact_match: true, + location_param: "find_loc".into(), + } + ], + ); + Ok(()) + } + #[test] + fn query_only_dark_theme_yelp_icon_data() -> anyhow::Result<()> { + before_each(); + + let store = TestStore::new( + MockRemoteSettingsClient::default() + .with_record("yelp-suggestions", "data-1", json!([{ + "subjects": ["ramen"], + "preModifiers": [], + "postModifiers": [], + "locationSigns": [], + "yelpModifiers": [], + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", + "score": 0.5 + }])) + .with_icon(yelp_dark_theme_icon()) + ); + + store.ingest(SuggestIngestionConstraints::default()); + + assert_eq!( + store.fetch_suggestions(SuggestionQuery::yelp("ramen")), + vec![ + Suggestion::Yelp { + title: "ramen".into(), + url: "https://www.yelp.com/search?find_desc=ramen".into(), + icon_light_theme: None, + icon_light_theme_mimetype: None, + icon_dark_theme: Some("yelp-dark-theme-icon-data".into()), + icon_dark_theme_mimetype: Some("image/svg+xml".into()), + score: 0.5, + has_location_sign: false, + subject_exact_match: true, + location_param: "find_loc".into(), + } + ], + ); Ok(()) } diff --git a/components/suggest/src/suggest.udl b/components/suggest/src/suggest.udl index e359c5bfc5..80189c3383 100644 --- a/components/suggest/src/suggest.udl +++ b/components/suggest/src/suggest.udl @@ -79,8 +79,10 @@ interface Suggestion { Yelp( string url, string title, - sequence? icon, - string? icon_mimetype, + sequence? icon_light_theme, + string? icon_light_theme_mimetype, + sequence? icon_dark_theme, + string? icon_dark_theme_mimetype, f64 score, boolean has_location_sign, boolean subject_exact_match, diff --git a/components/suggest/src/suggestion.rs b/components/suggest/src/suggestion.rs index c0b45524c7..548457675c 100644 --- a/components/suggest/src/suggestion.rs +++ b/components/suggest/src/suggestion.rs @@ -65,8 +65,10 @@ pub enum Suggestion { Yelp { url: String, title: String, - icon: Option>, - icon_mimetype: Option, + icon_light_theme: Option>, + icon_light_theme_mimetype: Option, + icon_dark_theme: Option>, + icon_dark_theme_mimetype: Option, score: f64, has_location_sign: bool, subject_exact_match: bool, diff --git a/components/suggest/src/testing/data.rs b/components/suggest/src/testing/data.rs index 3524bb40f8..8854eb2e92 100644 --- a/components/suggest/src/testing/data.rs +++ b/components/suggest/src/testing/data.rs @@ -326,7 +326,8 @@ pub fn ramen_yelp() -> JsonValue { { "keyword": "near me", "needLocation": false }, ], "yelpModifiers": ["yelp", "yelp keyword"], - "icon": "yelp-favicon", + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", "score": 0.5 }) } @@ -335,8 +336,10 @@ pub fn ramen_suggestion(title: &str, url: &str) -> Suggestion { Suggestion::Yelp { title: title.into(), url: url.into(), - icon: Some("yelp-favicon-data".into()), - icon_mimetype: Some("image/svg+xml".into()), + icon_light_theme: Some("yelp-light-theme-icon-data".into()), + icon_light_theme_mimetype: Some("image/svg+xml".into()), + icon_dark_theme: Some("yelp-dark-theme-icon-data".into()), + icon_dark_theme_mimetype: Some("image/svg+xml".into()), score: 0.5, has_location_sign: true, subject_exact_match: true, @@ -352,6 +355,22 @@ pub fn yelp_favicon() -> MockIcon { } } +pub fn yelp_light_theme_icon() -> MockIcon { + MockIcon { + id: "yelp-light-theme-icon", + data: "yelp-light-theme-icon-data", + mimetype: "image/svg+xml", + } +} + +pub fn yelp_dark_theme_icon() -> MockIcon { + MockIcon { + id: "yelp-dark-theme-icon", + data: "yelp-dark-theme-icon-data", + mimetype: "image/svg+xml", + } +} + pub fn array_mdn() -> JsonValue { json!({ "description": "Javascript Array", diff --git a/components/suggest/src/testing/mod.rs b/components/suggest/src/testing/mod.rs index 35ca601548..bee60d561c 100644 --- a/components/suggest/src/testing/mod.rs +++ b/components/suggest/src/testing/mod.rs @@ -46,8 +46,10 @@ impl Suggestion { Self::Yelp { title, url, - icon, - icon_mimetype, + icon_light_theme, + icon_light_theme_mimetype, + icon_dark_theme, + icon_dark_theme_mimetype, score, subject_exact_match, location_param, @@ -55,8 +57,10 @@ impl Suggestion { } => Self::Yelp { title, url, - icon, - icon_mimetype, + icon_light_theme, + icon_light_theme_mimetype, + icon_dark_theme, + icon_dark_theme_mimetype, score, subject_exact_match, location_param, @@ -71,8 +75,10 @@ impl Suggestion { Self::Yelp { title, url, - icon, - icon_mimetype, + icon_light_theme, + icon_light_theme_mimetype, + icon_dark_theme, + icon_dark_theme_mimetype, score, has_location_sign, location_param, @@ -80,8 +86,10 @@ impl Suggestion { } => Self::Yelp { title, url, - icon, - icon_mimetype, + icon_light_theme, + icon_light_theme_mimetype, + icon_dark_theme, + icon_dark_theme_mimetype, score, subject_exact_match, location_param, diff --git a/components/suggest/src/yelp.rs b/components/suggest/src/yelp.rs index 0eb6c10d56..c215882de3 100644 --- a/components/suggest/src/yelp.rs +++ b/components/suggest/src/yelp.rs @@ -118,10 +118,11 @@ impl<'a> SuggestDao<'a> { self.scope.err_if_interrupted()?; self.conn.execute_cached( - "INSERT INTO yelp_custom_details(record_id, icon_id, score) VALUES(:record_id, :icon_id, :score)", + "INSERT INTO yelp_custom_details(record_id, icon_light_theme_id, icon_dark_theme_id, score) VALUES(:record_id, :icon_light_theme_id, :icon_dark_theme_id, :score)", named_params! { ":record_id": record_id.as_str(), - ":icon_id": suggestion.icon_id, + ":icon_light_theme_id": suggestion.icon_light_theme_id, + ":icon_dark_theme_id": suggestion.icon_dark_theme_id, ":score": suggestion.score, }, )?; @@ -147,7 +148,13 @@ impl<'a> SuggestDao<'a> { let Some((subject, subject_exact_match)) = self.find_subject(query_string)? else { return Ok(vec![]); }; - let (icon, icon_mimetype, score) = self.fetch_custom_details()?; + let ( + icon_light_theme, + icon_light_theme_mimetype, + icon_dark_theme, + icon_dark_theme_mimetype, + score, + ) = self.fetch_custom_details()?; let builder = SuggestionBuilder { subject: &subject, subject_exact_match, @@ -156,8 +163,10 @@ impl<'a> SuggestDao<'a> { location_sign: None, location: None, need_location: false, - icon, - icon_mimetype, + icon_light_theme, + icon_light_theme_mimetype, + icon_dark_theme, + icon_dark_theme_mimetype, score, }; return Ok(vec![builder.into()]); @@ -189,7 +198,13 @@ impl<'a> SuggestDao<'a> { return Ok(vec![]); }; - let (icon, icon_mimetype, score) = self.fetch_custom_details()?; + let ( + icon_light_theme, + icon_light_theme_mimetype, + icon_dark_theme, + icon_dark_theme_mimetype, + score, + ) = self.fetch_custom_details()?; let builder = SuggestionBuilder { subject: &subject, subject_exact_match, @@ -198,8 +213,10 @@ impl<'a> SuggestDao<'a> { location_sign, location, need_location, - icon, - icon_mimetype, + icon_light_theme, + icon_light_theme_mimetype, + icon_dark_theme, + icon_dark_theme_mimetype, score, }; Ok(vec![builder.into()]) @@ -208,8 +225,10 @@ impl<'a> SuggestDao<'a> { /// Fetch the custom details for Yelp suggestions. /// It returns the location tuple as follows: /// ( - /// Option>: Icon data. If not found, returns None. - /// Option: Mimetype of the icon data. If not found, returns None. + /// Option>: Icon data for light theme. If not found, returns None. + /// Option: Mimetype of the icon data for light theme. If not found, returns None. + /// Option>: Icon data for dark theme. If not found, returns None. + /// Option: Mimetype of the icon data for dark theme. If not found, returns None. /// f64: Reflects score field in the yelp_custom_details table. /// ) /// @@ -218,16 +237,27 @@ impl<'a> SuggestDao<'a> { /// on Remote Settings. The following query will perform a table scan against /// `yelp_custom_details` followed by an index search against `icons`, /// which should be fine since there is only one record in the first table. - fn fetch_custom_details(&self) -> Result<(Option>, Option, f64)> { + fn fetch_custom_details( + &self, + ) -> Result<( + Option>, + Option, + Option>, + Option, + f64, + )> { let result = self.conn.query_row_and_then_cachable( r#" SELECT - i.data, i.mimetype, y.score + light.data, light.mimetype, dark.data, dark.mimetype, y.score FROM yelp_custom_details y LEFT JOIN - icons i - ON y.icon_id = i.id + icons light + ON y.icon_light_theme_id = light.id + LEFT JOIN + icons dark + ON y.icon_dark_theme_id = dark.id LIMIT 1 "#, @@ -236,7 +266,9 @@ impl<'a> SuggestDao<'a> { Ok(( row.get::<_, Option>>(0)?, row.get::<_, Option>(1)?, - row.get::<_, f64>(2)?, + row.get::<_, Option>>(2)?, + row.get::<_, Option>(3)?, + row.get::<_, f64>(4)?, )) }, true, @@ -450,8 +482,10 @@ struct SuggestionBuilder<'a> { location_sign: Option, location: Option, need_location: bool, - icon: Option>, - icon_mimetype: Option, + icon_light_theme: Option>, + icon_light_theme_mimetype: Option, + icon_dark_theme: Option>, + icon_dark_theme_mimetype: Option, score: f64, } @@ -500,8 +534,10 @@ impl<'a> From> for Suggestion { Suggestion::Yelp { url, title, - icon: builder.icon, - icon_mimetype: builder.icon_mimetype, + icon_light_theme: builder.icon_light_theme, + icon_light_theme_mimetype: builder.icon_light_theme_mimetype, + icon_dark_theme: builder.icon_dark_theme, + icon_dark_theme_mimetype: builder.icon_dark_theme_mimetype, score: builder.score, has_location_sign: location_modifier.is_none() && builder.location_sign.is_some(), subject_exact_match: builder.subject_exact_match, From 1907a14c4945d16824d1461af6f61baf49c151f0 Mon Sep 17 00:00:00 2001 From: dadaa Date: Thu, 16 May 2024 23:50:26 +0900 Subject: [PATCH 2/2] Introduce suggestion icon struct --- components/suggest/src/db.rs | 30 +- components/suggest/src/lib.rs | 2 +- components/suggest/src/schema.rs | 54 ++- components/suggest/src/store.rs | 468 +++++++++++++------------ components/suggest/src/suggest.udl | 17 +- components/suggest/src/suggestion.rs | 18 +- components/suggest/src/testing/data.rs | 45 ++- components/suggest/src/testing/mod.rs | 8 - components/suggest/src/yelp.rs | 64 ++-- 9 files changed, 377 insertions(+), 329 deletions(-) diff --git a/components/suggest/src/db.rs b/components/suggest/src/db.rs index 4e12a87969..2be0b9db16 100644 --- a/components/suggest/src/db.rs +++ b/components/suggest/src/db.rs @@ -25,7 +25,7 @@ use crate::{ DownloadedWikipediaSuggestion, Record, SuggestRecordId, }, schema::{clear_database, SuggestConnectionInitializer}, - suggestion::{cook_raw_suggestion_url, AmpSuggestionType, Suggestion}, + suggestion::{cook_raw_suggestion_url, AmpSuggestionType, Suggestion, SuggestionIcon}, Result, SuggestionQuery, }; @@ -299,7 +299,7 @@ impl<'a> SuggestDao<'a> { amp.iab_category, amp.impression_url, amp.click_url, - i.data AS icon, + i.data AS icon_data, i.mimetype AS icon_mimetype FROM amp_custom_details amp @@ -315,6 +315,12 @@ impl<'a> SuggestDao<'a> { let cooked_url = cook_raw_suggestion_url(&raw_url); let raw_click_url = row.get::<_, String>("click_url")?; let cooked_click_url = cook_raw_suggestion_url(&raw_click_url); + let icon_data = row.get::<_, Option<_>>("icon_data")?; + let icon_mime_type = row.get::<_, Option<_>>("icon_mimetype")?; + let icon = icon_data.map(|data| SuggestionIcon { + data, + mime_type: icon_mime_type.unwrap_or_default(), + }); Ok(Suggestion::Amp { block_id: row.get("block_id")?, @@ -325,8 +331,7 @@ impl<'a> SuggestDao<'a> { raw_url, full_keyword: full_keyword_from_db .unwrap_or_else(|| full_keyword(keyword_lowercased, &keywords)), - icon: row.get("icon")?, - icon_mimetype: row.get("icon_mimetype")?, + icon, impression_url: row.get("impression_url")?, click_url: cooked_click_url, raw_click_url, @@ -378,7 +383,7 @@ impl<'a> SuggestDao<'a> { }, |row| row.get(0), )?; - let (icon, icon_mimetype) = self + let icon = self .conn .try_query_row( "SELECT i.data, i.mimetype @@ -390,21 +395,20 @@ impl<'a> SuggestDao<'a> { ":suggestion_id": suggestion_id }, |row| -> Result<_> { - Ok(( - row.get::<_, Option>>(0)?, - row.get::<_, Option>(1)?, - )) + Ok(Some(SuggestionIcon { + data: row.get::<_, Vec>(0)?, + mime_type: row.get::<_, String>(1)?, + })) }, true, )? - .unwrap_or((None, None)); + .unwrap_or(None); Ok(Suggestion::Wikipedia { title, url: raw_url, full_keyword: full_keyword(keyword_lowercased, &keywords), icon, - icon_mimetype, }) }, )?; @@ -986,7 +990,7 @@ impl<'a> SuggestDao<'a> { } /// Inserts or replaces an icon for a suggestion into the database. - pub fn put_icon(&mut self, icon_id: &str, data: &[u8], mimetype: &str) -> Result<()> { + pub fn put_icon(&mut self, icon_id: &str, data: &[u8], mime_type: &str) -> Result<()> { self.conn.execute( "INSERT OR REPLACE INTO icons( id, @@ -1001,7 +1005,7 @@ impl<'a> SuggestDao<'a> { named_params! { ":id": icon_id, ":data": data, - ":mimetype": mimetype, + ":mimetype": mime_type, }, )?; Ok(()) diff --git a/components/suggest/src/lib.rs b/components/suggest/src/lib.rs index 3a7403d6e8..4c8194c14b 100644 --- a/components/suggest/src/lib.rs +++ b/components/suggest/src/lib.rs @@ -26,7 +26,7 @@ pub use error::SuggestApiError; pub use provider::SuggestionProvider; pub use query::SuggestionQuery; pub use store::{InterruptKind, SuggestIngestionConstraints, SuggestStore, SuggestStoreBuilder}; -pub use suggestion::{raw_suggestion_url_matches, Suggestion}; +pub use suggestion::{raw_suggestion_url_matches, Suggestion, SuggestionIcon}; pub(crate) type Result = std::result::Result; pub type SuggestApiResult = std::result::Result; diff --git a/components/suggest/src/schema.rs b/components/suggest/src/schema.rs index 8008eae94f..b189808d38 100644 --- a/components/suggest/src/schema.rs +++ b/components/suggest/src/schema.rs @@ -15,7 +15,7 @@ use sql_support::open_database::{self, ConnectionInitializer}; /// [`SuggestConnectionInitializer::upgrade_from`]. /// a. If suggestions should be re-ingested after the migration, call `clear_database()` inside /// the migration. -pub const VERSION: u32 = 19; +pub const VERSION: u32 = 20; /// The current Suggest database schema. pub const SQL: &str = " @@ -195,6 +195,34 @@ CREATE TABLE IF NOT EXISTS dismissed_suggestions ( )?; Ok(()) } + 19 => { + let result = tx.query_row_and_then( + "SELECT icon_id FROM yelp_custom_details LIMIT 1", + (), + |row| row.get::<_, String>(0), + ); + + if let Ok(_) = result { + // As still old table, we chnage to new. + tx.execute_batch( + " +ALTER TABLE yelp_custom_details RENAME TO old_yelp_custom_details; +CREATE TABLE yelp_custom_details( + icon_light_theme_id TEXT NOT NULL, + icon_dark_theme_id TEXT NOT NULL, + score REAL NOT NULL, + record_id TEXT NOT NULL, + PRIMARY KEY (icon_light_theme_id, icon_dark_theme_id) +) WITHOUT ROWID; +INSERT INTO yelp_custom_details (icon_light_theme_id, icon_dark_theme_id, score, record_id) +SELECT icon_id, icon_id, score, record_id FROM old_yelp_custom_details; +DROP TABLE old_yelp_custom_details; + ", + )?; + } + + Ok(()) + } _ => Err(open_database::Error::IncompatibleVersion(version)), } } @@ -322,6 +350,8 @@ CREATE TABLE yelp_custom_details( record_id TEXT NOT NULL ) WITHOUT ROWID; +INSERT INTO yelp_custom_details(icon_id, score, record_id) VALUES ('yelp-icon', 0.5, 'yelp-record'); + CREATE TABLE mdn_custom_details( suggestion_id INTEGER PRIMARY KEY, description TEXT NOT NULL, @@ -340,5 +370,27 @@ PRAGMA user_version=16; let db_file = MigratedDatabaseFile::new(SuggestConnectionInitializer, V16_SCHEMA); db_file.run_all_upgrades(); db_file.assert_schema_matches_new_database(); + + // Test wether yelp_custom_details data inherits to new table. + let connection = db_file.open(); + let result: Result<(String, String, f64, String), crate::error::Error> = connection.query_row_and_then( + "SELECT icon_light_theme_id, icon_dark_theme_id, score, record_id FROM yelp_custom_details LIMIT 1", + (), + |row| Ok(( + row.get::<_, String>(0)?, + row.get::<_, String>(1)?, + row.get::<_, f64>(2)?, + row.get::<_, String>(3)? + )) + ); + + if let Ok((icon_light_theme_id, icon_dark_theme_id, score, record_id)) = result { + assert_eq!(icon_light_theme_id, "yelp-icon"); + assert_eq!(icon_dark_theme_id, "yelp-icon"); + assert_eq!(score, 0.5); + assert_eq!(record_id, "yelp-record"); + } else { + assert!(false); + } } } diff --git a/components/suggest/src/store.rs b/components/suggest/src/store.rs index 59ebb11fd9..ef6e34e09c 100644 --- a/components/suggest/src/store.rs +++ b/components/suggest/src/store.rs @@ -25,7 +25,7 @@ use crate::{ Client, Record, RecordRequest, SuggestAttachment, SuggestRecord, SuggestRecordId, SuggestRecordType, DEFAULT_RECORDS_TYPES, REMOTE_SETTINGS_COLLECTION, }, - Result, SuggestApiResult, Suggestion, SuggestionQuery, + Result, SuggestApiResult, Suggestion, SuggestionIcon, SuggestionQuery, }; /// Builder for [SuggestStore] @@ -1085,12 +1085,12 @@ mod tests { assert!(matches!( store.fetch_suggestions(SuggestionQuery::amp("lo")).as_slice(), - [ Suggestion::Amp { icon, .. } ] if *icon == Some("new-los-pollos-icon".as_bytes().to_vec()) + [ Suggestion::Amp { icon, .. } ] if *icon == Some(SuggestionIcon{data:"new-los-pollos-icon".into(), mime_type: "image/png".into()}) )); assert!(matches!( store.fetch_suggestions(SuggestionQuery::amp("la")).as_slice(), - [ Suggestion::Amp { icon, .. } ] if *icon == Some("new-good-place-eats-icon".as_bytes().to_vec()) + [ Suggestion::Amp { icon, .. } ] if *icon == Some(SuggestionIcon{data:"new-good-place-eats-icon".into(), mime_type: "image/gif".into()}) )); Ok(()) @@ -1200,8 +1200,9 @@ mod tests { assert!(matches!( store.fetch_suggestions(SuggestionQuery::amp("la")).as_slice(), [ - Suggestion::Amp { icon, icon_mimetype, .. } - ] if icon.is_none() && icon_mimetype.is_none(), + Suggestion::Amp { icon , .. } + ] if icon.is_none() + )); Ok(()) } @@ -1764,7 +1765,6 @@ mod tests { url: "https://www.lasagna.restaurant", raw_url: "https://www.lasagna.restaurant", icon: None, - icon_mimetype: None, full_keyword: "amp wiki match", block_id: 0, advertiser: "Good Place Eats", @@ -1778,23 +1778,23 @@ mod tests { title: "Multimatch", url: "https://wikipedia.org/Multimatch", icon: Some( - [ - 97, - 108, - 115, - 111, - 45, - 97, - 110, - 45, - 105, - 99, - 111, - 110, - ], - ), - icon_mimetype: Some( - "image/png", + SuggestionIcon { + data: [ + 97, + 108, + 115, + 111, + 45, + 97, + 110, + 45, + 105, + 99, + 111, + 110, + ], + mime_type: "image/png", + }, ), full_keyword: "amp wiki match", }, @@ -1803,7 +1803,6 @@ mod tests { url: "https://penne.biz", raw_url: "https://penne.biz", icon: None, - icon_mimetype: None, full_keyword: "amp wiki match", block_id: 0, advertiser: "Good Place Eats", @@ -1836,7 +1835,6 @@ mod tests { url: "https://www.lasagna.restaurant", raw_url: "https://www.lasagna.restaurant", icon: None, - icon_mimetype: None, full_keyword: "amp wiki match", block_id: 0, advertiser: "Good Place Eats", @@ -1850,23 +1848,23 @@ mod tests { title: "Multimatch", url: "https://wikipedia.org/Multimatch", icon: Some( - [ - 97, - 108, - 115, - 111, - 45, - 97, - 110, - 45, - 105, - 99, - 111, - 110, - ], - ), - icon_mimetype: Some( - "image/png", + SuggestionIcon { + data: [ + 97, + 108, + 115, + 111, + 45, + 97, + 110, + 45, + 105, + 99, + 111, + 110, + ], + mime_type: "image/png", + }, ), full_keyword: "amp wiki match", }, @@ -1897,23 +1895,23 @@ mod tests { title: "Multimatch", url: "https://wikipedia.org/Multimatch", icon: Some( - [ - 97, - 108, - 115, - 111, - 45, - 97, - 110, - 45, - 105, - 99, - 111, - 110, - ], - ), - icon_mimetype: Some( - "image/png", + SuggestionIcon { + data: [ + 97, + 108, + 115, + 111, + 45, + 97, + 110, + 45, + 105, + 99, + 111, + 110, + ], + mime_type: "image/png", + }, ), full_keyword: "pocket wiki match", }, @@ -2220,23 +2218,23 @@ mod tests { url: "https://www.lasagna.restaurant", raw_url: "https://www.lasagna.restaurant", icon: Some( - [ - 97, - 108, - 115, - 111, - 45, - 97, - 110, - 45, - 105, - 99, - 111, - 110, - ], - ), - icon_mimetype: Some( - "image/png", + SuggestionIcon { + data: [ + 97, + 108, + 115, + 111, + 45, + 97, + 110, + 45, + 105, + 99, + 111, + 110, + ], + mime_type: "image/png", + }, ), full_keyword: "lasagna", block_id: 0, @@ -2264,23 +2262,23 @@ mod tests { url: "https://www.lasagna.restaurant", raw_url: "https://www.lasagna.restaurant", icon: Some( - [ - 97, - 108, - 115, - 111, - 45, - 97, - 110, - 45, - 105, - 99, - 111, - 110, - ], - ), - icon_mimetype: Some( - "image/png", + SuggestionIcon { + data: [ + 97, + 108, + 115, + 111, + 45, + 97, + 110, + 45, + 105, + 99, + 111, + 110, + ], + mime_type: "image/png", + }, ), full_keyword: "lasagna", block_id: 0, @@ -2308,23 +2306,23 @@ mod tests { url: "https://www.lasagna.restaurant", raw_url: "https://www.lasagna.restaurant", icon: Some( - [ - 97, - 108, - 115, - 111, - 45, - 97, - 110, - 45, - 105, - 99, - 111, - 110, - ], - ), - icon_mimetype: Some( - "image/png", + SuggestionIcon { + data: [ + 97, + 108, + 115, + 111, + 45, + 97, + 110, + 45, + 105, + 99, + 111, + 110, + ], + mime_type: "image/png", + }, ), full_keyword: "lasagna", block_id: 0, @@ -2340,23 +2338,23 @@ mod tests { url: "https://www.lasagna.restaurant", raw_url: "https://www.lasagna.restaurant", icon: Some( - [ - 97, - 108, - 115, - 111, - 45, - 97, - 110, - 45, - 105, - 99, - 111, - 110, - ], - ), - icon_mimetype: Some( - "image/png", + SuggestionIcon { + data: [ + 97, + 108, + 115, + 111, + 45, + 97, + 110, + 45, + 105, + 99, + 111, + 110, + ], + mime_type: "image/png", + }, ), full_keyword: "lasagna", block_id: 0, @@ -2600,7 +2598,6 @@ mod tests { url: "https://www.lph-nm.biz", raw_url: "https://www.lph-nm.biz", icon: None, - icon_mimetype: None, full_keyword: "los", block_id: 0, advertiser: "Los Pollos Hermanos", @@ -2758,38 +2755,35 @@ mod tests { fn query_no_yelp_icon_data() -> anyhow::Result<()> { before_each(); - let store = TestStore::new( - MockRemoteSettingsClient::default() - .with_record("yelp-suggestions", "data-1", json!([{ - "subjects": ["ramen"], - "preModifiers": [], - "postModifiers": [], - "locationSigns": [], - "yelpModifiers": [], - "iconLightTheme": "yelp-light-theme-icon", - "iconDarkTheme": "yelp-dark-theme-icon", - "score": 0.5 - }])) - ); + let store = TestStore::new(MockRemoteSettingsClient::default().with_record( + "yelp-suggestions", + "data-1", + json!([{ + "subjects": ["ramen"], + "preModifiers": [], + "postModifiers": [], + "locationSigns": [], + "yelpModifiers": [], + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", + "score": 0.5 + }]), + )); store.ingest(SuggestIngestionConstraints::default()); assert_eq!( store.fetch_suggestions(SuggestionQuery::yelp("ramen")), - vec![ - Suggestion::Yelp { - title: "ramen".into(), - url: "https://www.yelp.com/search?find_desc=ramen".into(), - icon_light_theme: None, - icon_light_theme_mimetype: None, - icon_dark_theme: None, - icon_dark_theme_mimetype: None, - score: 0.5, - has_location_sign: false, - subject_exact_match: true, - location_param: "find_loc".into(), - } - ], + vec![Suggestion::Yelp { + title: "ramen".into(), + url: "https://www.yelp.com/search?find_desc=ramen".into(), + icon_light_theme: None, + icon_dark_theme: None, + score: 0.5, + has_location_sign: false, + subject_exact_match: true, + location_param: "find_loc".into(), + }], ); Ok(()) } @@ -2800,40 +2794,46 @@ mod tests { let store = TestStore::new( MockRemoteSettingsClient::default() - .with_record("yelp-suggestions", "data-1", json!([{ - "subjects": ["ramen"], - "preModifiers": [], - "postModifiers": [], - "locationSigns": [], - "yelpModifiers": [], - "icon": "yelp-favicon", - "iconLightTheme": "yelp-light-theme-icon", - "iconDarkTheme": "yelp-dark-theme-icon", - "score": 0.5 - }])) + .with_record( + "yelp-suggestions", + "data-1", + json!([{ + "subjects": ["ramen"], + "preModifiers": [], + "postModifiers": [], + "locationSigns": [], + "yelpModifiers": [], + "icon": "yelp-favicon", + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", + "score": 0.5 + }]), + ) .with_icon(yelp_favicon()) .with_icon(yelp_light_theme_icon()) - .with_icon(yelp_dark_theme_icon()) + .with_icon(yelp_dark_theme_icon()), ); store.ingest(SuggestIngestionConstraints::default()); assert_eq!( store.fetch_suggestions(SuggestionQuery::yelp("ramen")), - vec![ - Suggestion::Yelp { - title: "ramen".into(), - url: "https://www.yelp.com/search?find_desc=ramen".into(), - icon_light_theme: Some("yelp-light-theme-icon-data".into()), - icon_light_theme_mimetype: Some("image/svg+xml".into()), - icon_dark_theme: Some("yelp-dark-theme-icon-data".into()), - icon_dark_theme_mimetype: Some("image/svg+xml".into()), - score: 0.5, - has_location_sign: false, - subject_exact_match: true, - location_param: "find_loc".into(), - } - ], + vec![Suggestion::Yelp { + title: "ramen".into(), + url: "https://www.yelp.com/search?find_desc=ramen".into(), + icon_light_theme: Some(SuggestionIcon { + data: "yelp-light-theme-icon-data".into(), + mime_type: "image/svg+xml".into(), + }), + icon_dark_theme: Some(SuggestionIcon { + data: "yelp-dark-theme-icon-data".into(), + mime_type: "image/svg+xml".into(), + }), + score: 0.5, + has_location_sign: false, + subject_exact_match: true, + location_param: "find_loc".into(), + }], ); Ok(()) } @@ -2844,37 +2844,40 @@ mod tests { let store = TestStore::new( MockRemoteSettingsClient::default() - .with_record("yelp-suggestions", "data-1", json!([{ - "subjects": ["ramen"], - "preModifiers": [], - "postModifiers": [], - "locationSigns": [], - "yelpModifiers": [], - "iconLightTheme": "yelp-light-theme-icon", - "iconDarkTheme": "yelp-dark-theme-icon", - "score": 0.5 - }])) - .with_icon(yelp_light_theme_icon()) + .with_record( + "yelp-suggestions", + "data-1", + json!([{ + "subjects": ["ramen"], + "preModifiers": [], + "postModifiers": [], + "locationSigns": [], + "yelpModifiers": [], + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", + "score": 0.5 + }]), + ) + .with_icon(yelp_light_theme_icon()), ); store.ingest(SuggestIngestionConstraints::default()); assert_eq!( store.fetch_suggestions(SuggestionQuery::yelp("ramen")), - vec![ - Suggestion::Yelp { - title: "ramen".into(), - url: "https://www.yelp.com/search?find_desc=ramen".into(), - icon_light_theme: Some("yelp-light-theme-icon-data".into()), - icon_light_theme_mimetype: Some("image/svg+xml".into()), - icon_dark_theme: None, - icon_dark_theme_mimetype: None, - score: 0.5, - has_location_sign: false, - subject_exact_match: true, - location_param: "find_loc".into(), - } - ], + vec![Suggestion::Yelp { + title: "ramen".into(), + url: "https://www.yelp.com/search?find_desc=ramen".into(), + icon_light_theme: Some(SuggestionIcon { + data: "yelp-light-theme-icon-data".into(), + mime_type: "image/svg+xml".into(), + }), + icon_dark_theme: None, + score: 0.5, + has_location_sign: false, + subject_exact_match: true, + location_param: "find_loc".into(), + }], ); Ok(()) } @@ -2885,37 +2888,40 @@ mod tests { let store = TestStore::new( MockRemoteSettingsClient::default() - .with_record("yelp-suggestions", "data-1", json!([{ - "subjects": ["ramen"], - "preModifiers": [], - "postModifiers": [], - "locationSigns": [], - "yelpModifiers": [], - "iconLightTheme": "yelp-light-theme-icon", - "iconDarkTheme": "yelp-dark-theme-icon", - "score": 0.5 - }])) - .with_icon(yelp_dark_theme_icon()) + .with_record( + "yelp-suggestions", + "data-1", + json!([{ + "subjects": ["ramen"], + "preModifiers": [], + "postModifiers": [], + "locationSigns": [], + "yelpModifiers": [], + "iconLightTheme": "yelp-light-theme-icon", + "iconDarkTheme": "yelp-dark-theme-icon", + "score": 0.5 + }]), + ) + .with_icon(yelp_dark_theme_icon()), ); store.ingest(SuggestIngestionConstraints::default()); assert_eq!( store.fetch_suggestions(SuggestionQuery::yelp("ramen")), - vec![ - Suggestion::Yelp { - title: "ramen".into(), - url: "https://www.yelp.com/search?find_desc=ramen".into(), - icon_light_theme: None, - icon_light_theme_mimetype: None, - icon_dark_theme: Some("yelp-dark-theme-icon-data".into()), - icon_dark_theme_mimetype: Some("image/svg+xml".into()), - score: 0.5, - has_location_sign: false, - subject_exact_match: true, - location_param: "find_loc".into(), - } - ], + vec![Suggestion::Yelp { + title: "ramen".into(), + url: "https://www.yelp.com/search?find_desc=ramen".into(), + icon_light_theme: None, + icon_dark_theme: Some(SuggestionIcon { + data: "yelp-dark-theme-icon-data".into(), + mime_type: "image/svg+xml".into(), + }), + score: 0.5, + has_location_sign: false, + subject_exact_match: true, + location_param: "find_loc".into(), + }], ); Ok(()) } diff --git a/components/suggest/src/suggest.udl b/components/suggest/src/suggest.udl index 80189c3383..e4ffc6d0b8 100644 --- a/components/suggest/src/suggest.udl +++ b/components/suggest/src/suggest.udl @@ -25,6 +25,11 @@ interface SuggestApiError { Other(string reason); }; +dictionary SuggestionIcon { + sequence data; + string mime_type; +}; + enum SuggestionProvider { "Amp", "Pocket", @@ -42,8 +47,7 @@ interface Suggestion { string title, string url, string raw_url, - sequence? icon, - string? icon_mimetype, + SuggestionIcon? icon, string full_keyword, i64 block_id, string advertiser, @@ -62,8 +66,7 @@ interface Suggestion { Wikipedia( string title, string url, - sequence? icon, - string? icon_mimetype, + SuggestionIcon? icon, string full_keyword ); Amo( @@ -79,10 +82,8 @@ interface Suggestion { Yelp( string url, string title, - sequence? icon_light_theme, - string? icon_light_theme_mimetype, - sequence? icon_dark_theme, - string? icon_dark_theme_mimetype, + SuggestionIcon? icon_light_theme, + SuggestionIcon? icon_dark_theme, f64 score, boolean has_location_sign, boolean subject_exact_match, diff --git a/components/suggest/src/suggestion.rs b/components/suggest/src/suggestion.rs index 548457675c..0f885d7669 100644 --- a/components/suggest/src/suggestion.rs +++ b/components/suggest/src/suggestion.rs @@ -16,6 +16,12 @@ const TIMESTAMP_TEMPLATE: &str = "%YYYYMMDDHH%"; /// 2 bytes shorter than [`TIMESTAMP_TEMPLATE`]. const TIMESTAMP_LENGTH: usize = 10; +#[derive(Clone, Debug, PartialEq)] +pub struct SuggestionIcon { + pub data: Vec, + pub mime_type: String, +} + /// Suggestion Types for Amp pub(crate) enum AmpSuggestionType { Mobile, @@ -28,8 +34,7 @@ pub enum Suggestion { title: String, url: String, raw_url: String, - icon: Option>, - icon_mimetype: Option, + icon: Option, full_keyword: String, block_id: i64, advertiser: String, @@ -48,8 +53,7 @@ pub enum Suggestion { Wikipedia { title: String, url: String, - icon: Option>, - icon_mimetype: Option, + icon: Option, full_keyword: String, }, Amo { @@ -65,10 +69,8 @@ pub enum Suggestion { Yelp { url: String, title: String, - icon_light_theme: Option>, - icon_light_theme_mimetype: Option, - icon_dark_theme: Option>, - icon_dark_theme_mimetype: Option, + icon_light_theme: Option, + icon_dark_theme: Option, score: f64, has_location_sign: bool, subject_exact_match: bool, diff --git a/components/suggest/src/testing/data.rs b/components/suggest/src/testing/data.rs index 8854eb2e92..7db0a379d6 100644 --- a/components/suggest/src/testing/data.rs +++ b/components/suggest/src/testing/data.rs @@ -4,7 +4,7 @@ //! Test data that we use in many tests -use crate::{testing::MockIcon, Suggestion}; +use crate::{testing::MockIcon, Suggestion, SuggestionIcon}; use serde_json::json; use serde_json::Value as JsonValue; @@ -36,8 +36,10 @@ pub fn los_pollos_suggestion(full_keyword: &str) -> Suggestion { title: "Los Pollos Hermanos - Albuquerque".into(), url: "https://www.lph-nm.biz".into(), raw_url: "https://www.lph-nm.biz".into(), - icon: Some("los-pollos-icon-data".as_bytes().to_vec()), - icon_mimetype: Some("image/png".into()), + icon: Some(SuggestionIcon { + data: "los-pollos-icon-data".into(), + mime_type: "image/png".into(), + }), block_id: 100, advertiser: "Los Pollos Hermanos".into(), iab_category: "8 - Food & Drink".into(), @@ -76,8 +78,10 @@ pub fn good_place_eats_suggestion(full_keyword: &str) -> Suggestion { title: "Lasagna Come Out Tomorrow".into(), url: "https://www.lasagna.restaurant".into(), raw_url: "https://www.lasagna.restaurant".into(), - icon: Some("good-place-eats-icon-data".as_bytes().to_vec()), - icon_mimetype: Some("image/gif".into()), + icon: Some(SuggestionIcon { + data: "good-place-eats-icon-data".into(), + mime_type: "image/gif".into(), + }), full_keyword: full_keyword.into(), block_id: 101, advertiser: "Good Place Eats".into(), @@ -113,8 +117,10 @@ pub fn california_suggestion(full_keyword: &str) -> Suggestion { Suggestion::Wikipedia { title: "California".into(), url: "https://wikipedia.org/California".into(), - icon: Some("california-icon-data".as_bytes().to_vec()), - icon_mimetype: Some("image/png".into()), + icon: Some(SuggestionIcon { + data: "california-icon-data".into(), + mime_type: "image/png".into(), + }), full_keyword: full_keyword.into(), } } @@ -143,8 +149,10 @@ pub fn caltech_suggestion(full_keyword: &str) -> Suggestion { Suggestion::Wikipedia { title: "California Institute of Technology".into(), url: "https://wikipedia.org/California_Institute_of_Technology".into(), - icon: Some("caltech-icon-data".as_bytes().to_vec()), - icon_mimetype: Some("image/png".into()), + icon: Some(SuggestionIcon { + data: "caltech-icon-data".into(), + mime_type: "image/png".into(), + }), full_keyword: full_keyword.into(), } } @@ -170,7 +178,6 @@ pub fn a1a_suggestion(full_keyword: &str) -> Suggestion { url: "https://www.a1a-wash.biz".into(), raw_url: "https://www.a1a-wash.biz".into(), icon: None, - icon_mimetype: None, block_id: 300, advertiser: "A1A Car Wash".into(), iab_category: "2 - Auto".into(), @@ -336,10 +343,14 @@ pub fn ramen_suggestion(title: &str, url: &str) -> Suggestion { Suggestion::Yelp { title: title.into(), url: url.into(), - icon_light_theme: Some("yelp-light-theme-icon-data".into()), - icon_light_theme_mimetype: Some("image/svg+xml".into()), - icon_dark_theme: Some("yelp-dark-theme-icon-data".into()), - icon_dark_theme_mimetype: Some("image/svg+xml".into()), + icon_light_theme: Some(SuggestionIcon { + data: "yelp-light-theme-icon-data".into(), + mime_type: "image/svg+xml".into(), + }), + icon_dark_theme: Some(SuggestionIcon { + data: "yelp-dark-theme-icon-data".into(), + mime_type: "image/svg+xml".into(), + }), score: 0.5, has_location_sign: true, subject_exact_match: true, @@ -452,8 +463,10 @@ pub fn multimatch_wiki_suggestion() -> Suggestion { Suggestion::Wikipedia { title: "Multimatch".into(), url: "https://wikipedia.org/Multimatch".into(), - icon: Some("multimatch-wiki-icon-data".as_bytes().to_vec()), - icon_mimetype: Some("image/png".into()), + icon: Some(SuggestionIcon { + data: "multimatch-wiki-icon-data".into(), + mime_type: "image/png".into(), + }), full_keyword: "multimatch".into(), } } diff --git a/components/suggest/src/testing/mod.rs b/components/suggest/src/testing/mod.rs index bee60d561c..04f2d40705 100644 --- a/components/suggest/src/testing/mod.rs +++ b/components/suggest/src/testing/mod.rs @@ -47,9 +47,7 @@ impl Suggestion { title, url, icon_light_theme, - icon_light_theme_mimetype, icon_dark_theme, - icon_dark_theme_mimetype, score, subject_exact_match, location_param, @@ -58,9 +56,7 @@ impl Suggestion { title, url, icon_light_theme, - icon_light_theme_mimetype, icon_dark_theme, - icon_dark_theme_mimetype, score, subject_exact_match, location_param, @@ -76,9 +72,7 @@ impl Suggestion { title, url, icon_light_theme, - icon_light_theme_mimetype, icon_dark_theme, - icon_dark_theme_mimetype, score, has_location_sign, location_param, @@ -87,9 +81,7 @@ impl Suggestion { title, url, icon_light_theme, - icon_light_theme_mimetype, icon_dark_theme, - icon_dark_theme_mimetype, score, subject_exact_match, location_param, diff --git a/components/suggest/src/yelp.rs b/components/suggest/src/yelp.rs index c215882de3..9f70ff64fa 100644 --- a/components/suggest/src/yelp.rs +++ b/components/suggest/src/yelp.rs @@ -12,7 +12,7 @@ use crate::{ db::SuggestDao, provider::SuggestionProvider, rs::{DownloadedYelpSuggestion, SuggestRecordId}, - suggestion::Suggestion, + suggestion::{Suggestion, SuggestionIcon}, Result, SuggestionQuery, }; @@ -148,13 +148,7 @@ impl<'a> SuggestDao<'a> { let Some((subject, subject_exact_match)) = self.find_subject(query_string)? else { return Ok(vec![]); }; - let ( - icon_light_theme, - icon_light_theme_mimetype, - icon_dark_theme, - icon_dark_theme_mimetype, - score, - ) = self.fetch_custom_details()?; + let (icon_light_theme, icon_dark_theme, score) = self.fetch_custom_details()?; let builder = SuggestionBuilder { subject: &subject, subject_exact_match, @@ -164,9 +158,7 @@ impl<'a> SuggestDao<'a> { location: None, need_location: false, icon_light_theme, - icon_light_theme_mimetype, icon_dark_theme, - icon_dark_theme_mimetype, score, }; return Ok(vec![builder.into()]); @@ -198,13 +190,7 @@ impl<'a> SuggestDao<'a> { return Ok(vec![]); }; - let ( - icon_light_theme, - icon_light_theme_mimetype, - icon_dark_theme, - icon_dark_theme_mimetype, - score, - ) = self.fetch_custom_details()?; + let (icon_light_theme, icon_dark_theme, score) = self.fetch_custom_details()?; let builder = SuggestionBuilder { subject: &subject, subject_exact_match, @@ -214,9 +200,7 @@ impl<'a> SuggestDao<'a> { location, need_location, icon_light_theme, - icon_light_theme_mimetype, icon_dark_theme, - icon_dark_theme_mimetype, score, }; Ok(vec![builder.into()]) @@ -225,10 +209,8 @@ impl<'a> SuggestDao<'a> { /// Fetch the custom details for Yelp suggestions. /// It returns the location tuple as follows: /// ( - /// Option>: Icon data for light theme. If not found, returns None. - /// Option: Mimetype of the icon data for light theme. If not found, returns None. - /// Option>: Icon data for dark theme. If not found, returns None. - /// Option: Mimetype of the icon data for dark theme. If not found, returns None. + /// Option: Icon for light theme. If not found, returns None. + /// Option: Icon for dark theme. If not found, returns None. /// f64: Reflects score field in the yelp_custom_details table. /// ) /// @@ -239,13 +221,7 @@ impl<'a> SuggestDao<'a> { /// which should be fine since there is only one record in the first table. fn fetch_custom_details( &self, - ) -> Result<( - Option>, - Option, - Option>, - Option, - f64, - )> { + ) -> Result<(Option, Option, f64)> { let result = self.conn.query_row_and_then_cachable( r#" SELECT @@ -263,13 +239,19 @@ impl<'a> SuggestDao<'a> { "#, (), |row| -> Result<_> { - Ok(( - row.get::<_, Option>>(0)?, - row.get::<_, Option>(1)?, - row.get::<_, Option>>(2)?, - row.get::<_, Option>(3)?, - row.get::<_, f64>(4)?, - )) + let icon_data_light_theme = row.get::<_, Option>>(0)?; + let icon_mime_type_light_theme = row.get::<_, Option>(1)?; + let icon_light_theme = icon_data_light_theme.map(|data| SuggestionIcon { + data, + mime_type: icon_mime_type_light_theme.unwrap_or_default(), + }); + let icon_data_dark_theme = row.get::<_, Option>>(2)?; + let icon_mime_type_dark_theme = row.get::<_, Option>(3)?; + let icon_dark_theme = icon_data_dark_theme.map(|data| SuggestionIcon { + data, + mime_type: icon_mime_type_dark_theme.unwrap_or_default(), + }); + Ok((icon_light_theme, icon_dark_theme, row.get::<_, f64>(4)?)) }, true, )?; @@ -482,10 +464,8 @@ struct SuggestionBuilder<'a> { location_sign: Option, location: Option, need_location: bool, - icon_light_theme: Option>, - icon_light_theme_mimetype: Option, - icon_dark_theme: Option>, - icon_dark_theme_mimetype: Option, + icon_light_theme: Option, + icon_dark_theme: Option, score: f64, } @@ -535,9 +515,7 @@ impl<'a> From> for Suggestion { url, title, icon_light_theme: builder.icon_light_theme, - icon_light_theme_mimetype: builder.icon_light_theme_mimetype, icon_dark_theme: builder.icon_dark_theme, - icon_dark_theme_mimetype: builder.icon_dark_theme_mimetype, score: builder.score, has_location_sign: location_modifier.is_none() && builder.location_sign.is_some(), subject_exact_match: builder.subject_exact_match,