Bug 1879614: Vendor application-services into mozilla-central r=adw,nanj

Differential Revision: https://phabricator.services.mozilla.com/D201779
This commit is contained in:
Daisuke Akatsuka 2024-02-15 02:35:47 +00:00
Родитель 48f6c9ab94
Коммит 5b315967ea
17 изменённых файлов: 1496 добавлений и 337 удалений

Просмотреть файл

@ -60,9 +60,9 @@ git = "https://github.com/mozilla-spidermonkey/jsparagus"
rev = "61f399c53a641ebd3077c1f39f054f6d396a633c"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063"]
[source."git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7"]
git = "https://github.com/mozilla/application-services"
rev = "41367fda038268843a87c459698691f33f0d9063"
rev = "0b241a66c0722290b3a42366378b3f97d8c268d7"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/audioipc?rev=596bdb7fbb5745ea415726e16bd497e6c850a540"]

24
Cargo.lock сгенерированный
Просмотреть файл

@ -1585,7 +1585,7 @@ dependencies = [
[[package]]
name = "error-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"error-support-macros",
"lazy_static",
@ -1597,7 +1597,7 @@ dependencies = [
[[package]]
name = "error-support-macros"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"proc-macro2",
"quote",
@ -2855,7 +2855,7 @@ dependencies = [
[[package]]
name = "interrupt-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"lazy_static",
"parking_lot",
@ -4038,7 +4038,7 @@ dependencies = [
[[package]]
name = "nss_build_common"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
[[package]]
name = "nsstring"
@ -4708,7 +4708,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "remote_settings"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"parking_lot",
"serde",
@ -5231,7 +5231,7 @@ dependencies = [
[[package]]
name = "sql-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"ffi-support",
"interrupt-support",
@ -5412,7 +5412,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "suggest"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"anyhow",
"chrono",
@ -5461,7 +5461,7 @@ dependencies = [
[[package]]
name = "sync-guid"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"base64 0.21.3",
"rand",
@ -5472,7 +5472,7 @@ dependencies = [
[[package]]
name = "sync15"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"anyhow",
"error-support",
@ -5504,7 +5504,7 @@ dependencies = [
[[package]]
name = "tabs"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"anyhow",
"error-support",
@ -6154,7 +6154,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "viaduct"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"ffi-support",
"log",
@ -6300,7 +6300,7 @@ dependencies = [
[[package]]
name = "webext-storage"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=41367fda038268843a87c459698691f33f0d9063#41367fda038268843a87c459698691f33f0d9063"
source = "git+https://github.com/mozilla/application-services?rev=0b241a66c0722290b3a42366378b3f97d8c268d7#0b241a66c0722290b3a42366378b3f97d8c268d7"
dependencies = [
"anyhow",
"error-support",

Просмотреть файл

@ -206,13 +206,13 @@ warp = { git = "https://github.com/seanmonstar/warp", rev = "9d081461ae1167eb321
malloc_size_of_derive = { path = "xpcom/rust/malloc_size_of_derive" }
# application-services overrides to make updating them all simpler.
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "41367fda038268843a87c459698691f33f0d9063" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "41367fda038268843a87c459698691f33f0d9063" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "41367fda038268843a87c459698691f33f0d9063" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "41367fda038268843a87c459698691f33f0d9063" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "41367fda038268843a87c459698691f33f0d9063" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "41367fda038268843a87c459698691f33f0d9063" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "41367fda038268843a87c459698691f33f0d9063" }
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "0b241a66c0722290b3a42366378b3f97d8c268d7" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "0b241a66c0722290b3a42366378b3f97d8c268d7" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "0b241a66c0722290b3a42366378b3f97d8c268d7" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "0b241a66c0722290b3a42366378b3f97d8c268d7" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "0b241a66c0722290b3a42366378b3f97d8c268d7" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "0b241a66c0722290b3a42366378b3f97d8c268d7" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "0b241a66c0722290b3a42366378b3f97d8c268d7" }
# Patch mio 0.8.8 to use windows-sys 0.52 (backport https://github.com/tokio-rs/mio/commit/eea9e3e0c469480e5c59c01e6c3c7e5fd88f0848)
mio_0_8 = { package = "mio", git = "https://github.com/glandium/mio", rev = "9a2ef335c366044ffe73b1c4acabe50a1daefe05" }

Просмотреть файл

@ -14,6 +14,7 @@ const REMOTE_SETTINGS_RECORDS = [
postModifiers: ["delivery"],
locationSigns: [{ keyword: "in", needLocation: true }],
yelpModifiers: [],
icon: "1234",
},
},
];

Просмотреть файл

@ -15,6 +15,7 @@ const REMOTE_SETTINGS_RECORDS = [
postModifiers: ["delivery"],
locationSigns: [{ keyword: "in", needLocation: true }],
yelpModifiers: [],
icon: "1234",
},
},
];
@ -301,6 +302,7 @@ function makeExpectedResult(expected) {
url,
title: expected.title,
displayUrl,
icon: null,
},
};
}

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"4fa89b0606fe8ec8ac8c479b8b9adf33d0c936b09fa5af108ded74139ace37fb","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/client.rs":"3d87162e6913a81cc6f5178a7ca791e262d0d029e7dedf3df4fe2f66e5501185","src/config.rs":"7bb678addfae3b4ed5f2892d32263e5b33cc05e5a12a250f664150e78211f94a","src/error.rs":"192ca42af7c6b882f3129378c23b45dab8a0d2b179e23a8813a335ffd56b21dc","src/lib.rs":"416e99894e152f6cea7418ad2fabfd94bc3d907efd9f33fbd2a83fb99452b2df","src/remote_settings.udl":"2e71491ad3894d17e5bde0663d9490bfea6294d99cdbe9d67a36137faeedc593","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null}
{"files":{"Cargo.toml":"4fa89b0606fe8ec8ac8c479b8b9adf33d0c936b09fa5af108ded74139ace37fb","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/client.rs":"fb3f2cd47460e5ae07a5e8d61b358d588d14075bd9dd6b6e818e1af74abd5dba","src/config.rs":"7bb678addfae3b4ed5f2892d32263e5b33cc05e5a12a250f664150e78211f94a","src/error.rs":"192ca42af7c6b882f3129378c23b45dab8a0d2b179e23a8813a335ffd56b21dc","src/lib.rs":"416e99894e152f6cea7418ad2fabfd94bc3d907efd9f33fbd2a83fb99452b2df","src/remote_settings.udl":"2e71491ad3894d17e5bde0663d9490bfea6294d99cdbe9d67a36137faeedc593","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null}

Просмотреть файл

@ -155,7 +155,10 @@ impl Client {
if resp.is_success() {
Ok(resp)
} else {
Err(RemoteSettingsError::ResponseError(resp.text().to_string()))
Err(RemoteSettingsError::ResponseError(format!(
"status code: {}",
resp.status
)))
}
}

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"4aa81cff67e67b08ba3348c1acddaa5aee887df3c35006754c9cda4273a94458","README.md":"8d7457893194e255b87e5a2667ee25c87bd470f5338d7078506f866a67a3fdbd","build.rs":"78780c5cccfe22c3ff4198624b9e188559c437c3e6fa1c8bb66548eee6aa66bf","src/config.rs":"03630b2219b6674e332a1f96f44db74def17f985c850a800299b815fa72241c2","src/db.rs":"208916c915f29fa2fd8725f635822d63ac86023ea0eb2050a92d4c7fbc9f6697","src/error.rs":"f563210a6c050d98ec85e0f6d9401e7373bfb816e865e8edabbabb23d848ba13","src/keyword.rs":"988d0ab021c0df19cfd3c519df7d37f606bf984cd14d0efca4e5a7aff88344dd","src/lib.rs":"65a035dbfb17e2d2d9f237ad52dc03982ae28c70e3dcf3d96cc9f2d7af79efe3","src/pocket.rs":"c4dda43390d1c39dc795933596b3c1e4e282932cac6c69da53c6e05d39e9ef29","src/provider.rs":"3fe8f90d77586f5ff683374f24df026110bfaaab128fd4503d2c695eed71d4fe","src/rs.rs":"038e954eaeaa6898a2edb4d29728233a6286ac818b42028da1ba5c1b03a3efc0","src/schema.rs":"f7995c1cdd98c642e4497b5f3d0881a3ab6ac4f086172142c195adb0934b93de","src/store.rs":"b868b2853beba800cf43183f2b629a4024e435fa9617dcd751480ee89f8fe12f","src/suggest.udl":"9b82f97afb49d94a82cad3a9d44a25e8cab3b998b018ea9c3467b170b795e65b","src/suggestion.rs":"355f01b8a82a55a506e0a4c7d26dcf6d059802f84df3789309f5e0f42b80d793","src/yelp.rs":"2844e639bdf163fc23ba6e463495f47ec8d9c617de4754b49a58aa16d6ea39f5","uniffi.toml":"f26317442ddb5b3281245bef6e60ffcb78bb95d29fe4a351a56dbb88d4ec8aab"},"package":null}
{"files":{"Cargo.toml":"4aa81cff67e67b08ba3348c1acddaa5aee887df3c35006754c9cda4273a94458","README.md":"8d7457893194e255b87e5a2667ee25c87bd470f5338d7078506f866a67a3fdbd","build.rs":"78780c5cccfe22c3ff4198624b9e188559c437c3e6fa1c8bb66548eee6aa66bf","src/config.rs":"03630b2219b6674e332a1f96f44db74def17f985c850a800299b815fa72241c2","src/db.rs":"d373ad097edac2bbcc6e1b14f51c21b6e2cab2289d27667332798c9cde4dcbef","src/error.rs":"f563210a6c050d98ec85e0f6d9401e7373bfb816e865e8edabbabb23d848ba13","src/keyword.rs":"988d0ab021c0df19cfd3c519df7d37f606bf984cd14d0efca4e5a7aff88344dd","src/lib.rs":"65a035dbfb17e2d2d9f237ad52dc03982ae28c70e3dcf3d96cc9f2d7af79efe3","src/pocket.rs":"c4dda43390d1c39dc795933596b3c1e4e282932cac6c69da53c6e05d39e9ef29","src/provider.rs":"4fe662587efc5a80d000c217ce124506c6800293c50ff460ef95e9e659c764b9","src/rs.rs":"5dc41f6fac152b9f87d77a6b97b30377403d089649c35f6550460494d79246d0","src/schema.rs":"4c7264cd70050fbc1f711c80727ca65f7103d0e06d9247eacc5cc42b965bcd6f","src/store.rs":"77e1b8580fbd5e725a20d8da721e420306a762331046cb46faa4cee239ebe946","src/suggest.udl":"7dcc48cadcac44f67830d320b1e964e59d389b935107f18a066e5b30275073e7","src/suggestion.rs":"5994710ddefbcb4589e25b7b89854344b58bfb6754e13d0aa0549a8c188a0899","src/yelp.rs":"8f90146f5b32ea04b7506cae217c5025d532337ac9acd977866f110979559101","uniffi.toml":"f26317442ddb5b3281245bef6e60ffcb78bb95d29fe4a351a56dbb88d4ec8aab"},"package":null}

471
third_party/rust/suggest/src/db.rs поставляемый
Просмотреть файл

@ -21,12 +21,13 @@ use crate::{
pocket::{split_keyword, KeywordConfidence},
provider::SuggestionProvider,
rs::{
DownloadedAmoSuggestion, DownloadedAmpWikipediaSuggestion, DownloadedMdnSuggestion,
DownloadedPocketSuggestion, DownloadedWeatherData, SuggestRecordId,
DownloadedAmoSuggestion, DownloadedAmpSuggestion, DownloadedAmpWikipediaSuggestion,
DownloadedMdnSuggestion, DownloadedPocketSuggestion, DownloadedWeatherData,
SuggestRecordId,
},
schema::{SuggestConnectionInitializer, VERSION},
store::{UnparsableRecord, UnparsableRecords},
suggestion::{cook_raw_suggestion_url, Suggestion},
suggestion::{cook_raw_suggestion_url, AmpSuggestionType, Suggestion},
Result, SuggestionQuery,
};
@ -186,7 +187,12 @@ impl<'a> SuggestDao<'a> {
.iter()
.try_fold(vec![], |mut acc, provider| {
let suggestions = match provider {
SuggestionProvider::Amp => self.fetch_amp_suggestions(query),
SuggestionProvider::Amp => {
self.fetch_amp_suggestions(query, AmpSuggestionType::Desktop)
}
SuggestionProvider::AmpMobile => {
self.fetch_amp_suggestions(query, AmpSuggestionType::Mobile)
}
SuggestionProvider::Wikipedia => self.fetch_wikipedia_suggestions(query),
SuggestionProvider::Amo => self.fetch_amo_suggestions(query),
SuggestionProvider::Pocket => self.fetch_pocket_suggestions(query),
@ -207,28 +213,56 @@ impl<'a> SuggestDao<'a> {
}
/// Fetches Suggestions of type Amp provider that match the given query
pub fn fetch_amp_suggestions(&self, query: &SuggestionQuery) -> Result<Vec<Suggestion>> {
pub fn fetch_amp_suggestions(
&self,
query: &SuggestionQuery,
suggestion_type: AmpSuggestionType,
) -> Result<Vec<Suggestion>> {
let keyword_lowercased = &query.keyword.to_lowercase();
let provider = match suggestion_type {
AmpSuggestionType::Mobile => SuggestionProvider::AmpMobile,
AmpSuggestionType::Desktop => SuggestionProvider::Amp,
};
let suggestions = self.conn.query_rows_and_then_cached(
"SELECT s.id, k.rank, s.title, s.url, s.provider, s.score
FROM suggestions s
JOIN keywords k ON k.suggestion_id = s.id
WHERE s.provider = :provider AND
k.keyword = :keyword",
named_params! {
r#"
SELECT
s.id,
k.rank,
s.title,
s.url,
s.provider,
s.score
FROM
suggestions s
JOIN
keywords k
ON k.suggestion_id = s.id
WHERE
s.provider = :provider
AND k.keyword = :keyword
"#,
named_params! {
":keyword": keyword_lowercased,
":provider": SuggestionProvider::Amp
":provider": provider
},
|row| -> Result<Suggestion>{
|row| -> Result<Suggestion> {
let suggestion_id: i64 = row.get("id")?;
let title = row.get("title")?;
let raw_url = row.get::<_, String>("url")?;
let score = row.get::<_, f64>("score")?;
let keywords: Vec<String> = self.conn.query_rows_and_then_cached(
"SELECT keyword FROM keywords
WHERE suggestion_id = :suggestion_id AND rank >= :rank
ORDER BY rank ASC",
r#"
SELECT
keyword
FROM
keywords
WHERE
suggestion_id = :suggestion_id
AND rank >= :rank
ORDER BY
rank ASC
"#,
named_params! {
":suggestion_id": suggestion_id,
":rank": row.get::<_, i64>("rank")?,
@ -236,10 +270,19 @@ impl<'a> SuggestDao<'a> {
|row| row.get(0),
)?;
self.conn.query_row_and_then(
"SELECT amp.advertiser, amp.block_id, amp.iab_category, amp.impression_url, amp.click_url,
(SELECT i.data FROM icons i WHERE i.id = amp.icon_id) AS icon
FROM amp_custom_details amp
WHERE amp.suggestion_id = :suggestion_id",
r#"
SELECT
amp.advertiser,
amp.block_id,
amp.iab_category,
amp.impression_url,
amp.click_url,
(SELECT i.data FROM icons i WHERE i.id = amp.icon_id) AS icon
FROM
amp_custom_details amp
WHERE
amp.suggestion_id = :suggestion_id
"#,
named_params! {
":suggestion_id": suggestion_id
},
@ -247,6 +290,7 @@ 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);
Ok(Suggestion::Amp {
block_id: row.get("block_id")?,
advertiser: row.get("advertiser")?,
@ -261,10 +305,10 @@ impl<'a> SuggestDao<'a> {
raw_click_url,
score,
})
}
},
)
}
)?;
},
)?;
Ok(suggestions)
}
@ -272,11 +316,21 @@ impl<'a> SuggestDao<'a> {
pub fn fetch_wikipedia_suggestions(&self, query: &SuggestionQuery) -> Result<Vec<Suggestion>> {
let keyword_lowercased = &query.keyword.to_lowercase();
let suggestions = self.conn.query_rows_and_then_cached(
"SELECT s.id, k.rank, s.title, s.url
FROM suggestions s
JOIN keywords k ON k.suggestion_id = s.id
WHERE s.provider = :provider AND
k.keyword = :keyword",
r#"
SELECT
s.id,
k.rank,
s.title,
s.url
FROM
suggestions s
JOIN
keywords k
ON k.suggestion_id = s.id
WHERE
s.provider = :provider
AND k.keyword = :keyword
"#,
named_params! {
":keyword": keyword_lowercased,
":provider": SuggestionProvider::Wikipedia
@ -322,47 +376,87 @@ impl<'a> SuggestDao<'a> {
let keyword_lowercased = &query.keyword.to_lowercase();
let (keyword_prefix, keyword_suffix) = split_keyword(keyword_lowercased);
let suggestions_limit = &query.limit.unwrap_or(-1);
let suggestions = self.conn.query_rows_and_then_cached(
"SELECT s.id, k.rank, s.title, s.url, s.provider, s.score, k.confidence, k.keyword_suffix
FROM suggestions s
JOIN prefix_keywords k ON k.suggestion_id = s.id
WHERE k.keyword_prefix = :keyword_prefix AND s.provider = :provider
ORDER by s.score DESC
LIMIT :suggestions_limit",
named_params! {
":keyword_prefix": keyword_prefix,
":provider": SuggestionProvider::Amo,
":suggestions_limit": suggestions_limit,
},
|row| -> Result<Option<Suggestion>>{
let suggestion_id: i64 = row.get("id")?;
let title = row.get("title")?;
let raw_url = row.get::<_, String>("url")?;
let score = row.get::<_, f64>("score")?;
let suggestions = self
.conn
.query_rows_and_then_cached(
r#"
SELECT
s.id,
MAX(k.rank) AS rank,
s.title,
s.url,
s.provider,
s.score,
k.keyword_suffix
FROM
suggestions s
JOIN
prefix_keywords k
ON k.suggestion_id = s.id
WHERE
k.keyword_prefix = :keyword_prefix
AND (k.keyword_suffix BETWEEN :keyword_suffix AND :keyword_suffix || x'FFFF')
AND s.provider = :provider
GROUP BY
s.id
ORDER BY
s.score DESC,
rank DESC
LIMIT
:suggestions_limit
"#,
named_params! {
":keyword_prefix": keyword_prefix,
":keyword_suffix": keyword_suffix,
":provider": SuggestionProvider::Amo,
":suggestions_limit": suggestions_limit,
},
|row| -> Result<Option<Suggestion>> {
let suggestion_id: i64 = row.get("id")?;
let title = row.get("title")?;
let raw_url = row.get::<_, String>("url")?;
let score = row.get::<_, f64>("score")?;
let full_suffix = row.get::<_, String>("keyword_suffix")?;
full_suffix.starts_with(keyword_suffix).then(||
self.conn.query_row_and_then(
"SELECT amo.description, amo.guid, amo.rating, amo.icon_url, amo.number_of_ratings
FROM amo_custom_details amo
WHERE amo.suggestion_id = :suggestion_id",
named_params! {
":suggestion_id": suggestion_id
},
|row| {
Ok(Suggestion::Amo {
title,
url: raw_url,
icon_url: row.get("icon_url")?,
description: row.get("description")?,
rating: row.get("rating")?,
number_of_ratings: row.get("number_of_ratings")?,
guid: row.get("guid")?,
score,
let full_suffix = row.get::<_, String>("keyword_suffix")?;
full_suffix
.starts_with(keyword_suffix)
.then(|| {
self.conn.query_row_and_then(
r#"
SELECT
amo.description,
amo.guid,
amo.rating,
amo.icon_url,
amo.number_of_ratings
FROM
amo_custom_details amo
WHERE
amo.suggestion_id = :suggestion_id
"#,
named_params! {
":suggestion_id": suggestion_id
},
|row| {
Ok(Suggestion::Amo {
title,
url: raw_url,
icon_url: row.get("icon_url")?,
description: row.get("description")?,
rating: row.get("rating")?,
number_of_ratings: row.get("number_of_ratings")?,
guid: row.get("guid")?,
score,
})
},
)
})
})).transpose()
}
)?.into_iter().flatten().collect();
.transpose()
},
)?
.into_iter()
.flatten()
.collect();
Ok(suggestions)
}
@ -370,44 +464,71 @@ impl<'a> SuggestDao<'a> {
pub fn fetch_pocket_suggestions(&self, query: &SuggestionQuery) -> Result<Vec<Suggestion>> {
let keyword_lowercased = &query.keyword.to_lowercase();
let (keyword_prefix, keyword_suffix) = split_keyword(keyword_lowercased);
let suggestions_limit = &query.limit.unwrap_or(-1);
let suggestions = self.conn.query_rows_and_then_cached(
"SELECT s.id, k.rank, s.title, s.url, s.provider, s.score, k.confidence, k.keyword_suffix
FROM suggestions s
JOIN prefix_keywords k ON k.suggestion_id = s.id
WHERE k.keyword_prefix = :keyword_prefix AND s.provider = :provider
ORDER BY s.score DESC
LIMIT :suggestions_limit",
named_params! {
":keyword_prefix": keyword_prefix,
":provider": SuggestionProvider::Pocket,
":suggestions_limit": suggestions_limit,
},
|row| -> Result<Option<Suggestion>>{
let title = row.get("title")?;
let raw_url = row.get::<_, String>("url")?;
let score = row.get::<_, f64>("score")?;
let confidence = row.get("confidence")?;
let full_suffix = row.get::<_, String>("keyword_suffix")?;
let suffixes_match = match confidence {
KeywordConfidence::Low => full_suffix.starts_with(keyword_suffix),
KeywordConfidence::High => full_suffix == keyword_suffix,
};
if suffixes_match {
Ok(Some(Suggestion::Pocket {
title,
url: raw_url,
score,
is_top_pick: matches!(
confidence,
KeywordConfidence::High)
}))
} else {
Ok(None)
}
}
)?.into_iter().flatten().collect();
let suggestions = self
.conn
.query_rows_and_then_cached(
r#"
SELECT
s.id,
MAX(k.rank) AS rank,
s.title,
s.url,
s.provider,
s.score,
k.confidence,
k.keyword_suffix
FROM
suggestions s
JOIN
prefix_keywords k
ON k.suggestion_id = s.id
WHERE
k.keyword_prefix = :keyword_prefix
AND (k.keyword_suffix BETWEEN :keyword_suffix AND :keyword_suffix || x'FFFF')
AND s.provider = :provider
GROUP BY
s.id,
k.confidence
ORDER BY
s.score DESC,
rank DESC
"#,
named_params! {
":keyword_prefix": keyword_prefix,
":keyword_suffix": keyword_suffix,
":provider": SuggestionProvider::Pocket,
},
|row| -> Result<Option<Suggestion>> {
let title = row.get("title")?;
let raw_url = row.get::<_, String>("url")?;
let score = row.get::<_, f64>("score")?;
let confidence = row.get("confidence")?;
let full_suffix = row.get::<_, String>("keyword_suffix")?;
let suffixes_match = match confidence {
KeywordConfidence::Low => full_suffix.starts_with(keyword_suffix),
KeywordConfidence::High => full_suffix == keyword_suffix,
};
if suffixes_match {
Ok(Some(Suggestion::Pocket {
title,
url: raw_url,
score,
is_top_pick: matches!(confidence, KeywordConfidence::High),
}))
} else {
Ok(None)
}
},
)?
.into_iter()
.flatten()
.take(
query
.limit
.and_then(|limit| usize::try_from(limit).ok())
.unwrap_or(usize::MAX),
)
.collect();
Ok(suggestions)
}
@ -421,21 +542,33 @@ impl<'a> SuggestDao<'a> {
.query_rows_and_then_cached(
r#"
SELECT
s.id, s.title, s.url, s.provider, s.score, k.keyword_suffix
s.id,
MAX(k.rank) AS rank,
s.title,
s.url,
s.provider,
s.score,
k.keyword_suffix
FROM
suggestions s
suggestions s
JOIN
prefix_keywords k ON k.suggestion_id = s.id
prefix_keywords k
ON k.suggestion_id = s.id
WHERE
k.keyword_prefix = :keyword_prefix
AND
s.provider = :provider
k.keyword_prefix = :keyword_prefix
AND (k.keyword_suffix BETWEEN :keyword_suffix AND :keyword_suffix || x'FFFF')
AND s.provider = :provider
GROUP BY
s.id
ORDER BY
s.score DESC
LIMIT :suggestions_limit
s.score DESC,
rank DESC
LIMIT
:suggestions_limit
"#,
named_params! {
":keyword_prefix": keyword_prefix,
":keyword_suffix": keyword_suffix,
":provider": SuggestionProvider::Mdn,
":suggestions_limit": suggestions_limit,
},
@ -492,10 +625,18 @@ impl<'a> SuggestDao<'a> {
let keyword_lowercased = &query.keyword.trim().to_lowercase();
let suggestions = self.conn.query_rows_and_then_cached(
"SELECT s.score
FROM suggestions s
JOIN keywords k ON k.suggestion_id = s.id
WHERE s.provider = :provider AND (k.keyword BETWEEN :keyword AND :keyword || X'FFFF')",
r#"
SELECT
s.score
FROM
suggestions s
JOIN
keywords k
ON k.suggestion_id = s.id
WHERE
s.provider = :provider
AND (k.keyword BETWEEN :keyword AND :keyword || X'FFFF')
"#,
named_params! {
":keyword": keyword_lowercased,
":provider": SuggestionProvider::Weather
@ -610,6 +751,7 @@ impl<'a> SuggestDao<'a> {
self.scope.err_if_interrupted()?;
let common_details = suggestion.common_details();
let provider = suggestion.provider();
let suggestion_id: i64 = self.conn.query_row_and_then_cachable(
&format!(
"INSERT INTO suggestions(
@ -710,6 +852,97 @@ impl<'a> SuggestDao<'a> {
Ok(())
}
/// Inserts all suggestions from a downloaded AMP-Mobile attachment into
/// the database.
pub fn insert_amp_mobile_suggestions(
&mut self,
record_id: &SuggestRecordId,
suggestions: &[DownloadedAmpSuggestion],
) -> Result<()> {
for suggestion in suggestions {
self.scope.err_if_interrupted()?;
let common_details = &suggestion.common_details;
let suggestion_id: i64 = self.conn.query_row_and_then_cachable(
&format!(
"INSERT INTO suggestions(
record_id,
provider,
title,
url,
score
)
VALUES(
:record_id,
{},
:title,
:url,
:score
)
RETURNING id",
SuggestionProvider::AmpMobile as u8
),
named_params! {
":record_id": record_id.as_str(),
":title": common_details.title,
":url": common_details.url,
":score": common_details.score.unwrap_or(DEFAULT_SUGGESTION_SCORE)
},
|row| row.get(0),
true,
)?;
self.conn.execute(
"INSERT INTO amp_custom_details(
suggestion_id,
advertiser,
block_id,
iab_category,
impression_url,
click_url,
icon_id
)
VALUES(
:suggestion_id,
:advertiser,
:block_id,
:iab_category,
:impression_url,
:click_url,
:icon_id
)",
named_params! {
":suggestion_id": suggestion_id,
":advertiser": suggestion.advertiser,
":block_id": suggestion.block_id,
":iab_category": suggestion.iab_category,
":impression_url": suggestion.impression_url,
":click_url": suggestion.click_url,
":icon_id": suggestion.icon_id,
},
)?;
for (index, keyword) in common_details.keywords.iter().enumerate() {
self.conn.execute(
"INSERT INTO keywords(
keyword,
suggestion_id,
rank
)
VALUES(
:keyword,
:suggestion_id,
:rank
)",
named_params! {
":keyword": keyword,
":rank": index,
":suggestion_id": suggestion_id,
},
)?;
}
}
Ok(())
}
/// Inserts all suggestions from a downloaded Pocket attachment into
/// the database.
pub fn insert_pocket_suggestions(
@ -945,6 +1178,10 @@ impl<'a> SuggestDao<'a> {
"DELETE FROM yelp_location_signs WHERE record_id = :record_id",
named_params! { ":record_id": record_id.as_str() },
)?;
self.conn.execute_cached(
"DELETE FROM yelp_custom_details WHERE record_id = :record_id",
named_params! { ":record_id": record_id.as_str() },
)?;
Ok(())
}

1
third_party/rust/suggest/src/provider.rs поставляемый
Просмотреть файл

@ -19,6 +19,7 @@ pub enum SuggestionProvider {
Yelp = 5,
Mdn = 6,
Weather = 7,
AmpMobile = 8,
}
impl FromSql for SuggestionProvider {

4
third_party/rust/suggest/src/rs.rs поставляемый
Просмотреть файл

@ -98,6 +98,8 @@ pub(crate) enum SuggestRecord {
Weather(DownloadedWeatherData),
#[serde(rename = "configuration")]
GlobalConfig(DownloadedGlobalConfig),
#[serde(rename = "amp-mobile-suggestions")]
AmpMobile,
}
/// Represents either a single value, or a list of values. This is used to
@ -294,6 +296,8 @@ pub(crate) struct DownloadedYelpSuggestion {
pub location_signs: Vec<DownloadedYelpLocationSign>,
#[serde(rename = "yelpModifiers")]
pub yelp_modifiers: Vec<String>,
#[serde(rename = "icon")]
pub icon_id: String,
}
/// An MDN suggestion to ingest from an attachment

23
third_party/rust/suggest/src/schema.rs поставляемый
Просмотреть файл

@ -6,8 +6,16 @@
use rusqlite::{Connection, Transaction};
use sql_support::open_database::{self, ConnectionInitializer};
pub const VERSION: u32 = 12;
/// The current database schema version.
///
/// For any changes to the schema [`SQL`], please make sure to:
///
/// 1. Bump this version.
/// 2. Add a migration from the old version to the new version in
/// [`SuggestConnectionInitializer::upgrade_from`].
pub const VERSION: u32 = 13;
/// The current Suggest database schema.
pub const SQL: &str = "
CREATE TABLE meta(
key TEXT PRIMARY KEY,
@ -92,6 +100,11 @@ pub const SQL: &str = "
record_id TEXT NOT NULL
) WITHOUT ROWID;
CREATE TABLE yelp_custom_details(
icon_id TEXT PRIMARY KEY,
record_id TEXT NOT NULL
) WITHOUT ROWID;
CREATE TABLE mdn_custom_details(
suggestion_id INTEGER PRIMARY KEY,
description TEXT NOT NULL,
@ -127,10 +140,10 @@ impl ConnectionInitializer for SuggestConnectionInitializer {
fn upgrade_from(&self, _db: &Transaction<'_>, version: u32) -> open_database::Result<()> {
match version {
1..=11 => {
// These schema versions were used during development, and never
// shipped in any applications. Treat these databases as
// corrupt, so that they'll be replaced.
1..=12 => {
// Treat databases with these older schema versions as corrupt,
// so that they'll be replaced by a fresh, empty database with
// the current schema.
Err(open_database::Error::Corrupt)
}
_ => Err(open_database::Error::IncompatibleVersion(version)),

1164
third_party/rust/suggest/src/store.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

4
third_party/rust/suggest/src/suggest.udl поставляемый
Просмотреть файл

@ -30,6 +30,7 @@ enum SuggestionProvider {
"Yelp",
"Mdn",
"Weather",
"AmpMobile",
};
[Enum]
@ -73,7 +74,8 @@ interface Suggestion {
Yelp(
string url,
string title,
boolean is_top_pick
boolean subject_exact_match,
sequence<u8>? icon
);
Mdn(
string title,

8
third_party/rust/suggest/src/suggestion.rs поставляемый
Просмотреть файл

@ -16,6 +16,11 @@ const TIMESTAMP_TEMPLATE: &str = "%YYYYMMDDHH%";
/// 2 bytes shorter than [`TIMESTAMP_TEMPLATE`].
const TIMESTAMP_LENGTH: usize = 10;
/// Suggestion Types for Amp
pub(crate) enum AmpSuggestionType {
Mobile,
Desktop,
}
/// A suggestion from the database to show in the address bar.
#[derive(Clone, Debug, PartialEq)]
pub enum Suggestion {
@ -58,7 +63,8 @@ pub enum Suggestion {
Yelp {
url: String,
title: String,
is_top_pick: bool,
subject_exact_match: bool,
icon: Option<Vec<u8>>,
},
Mdn {
title: String,

80
third_party/rust/suggest/src/yelp.rs поставляемый
Просмотреть файл

@ -47,8 +47,8 @@ const MAX_QUERY_LENGTH: usize = 150;
/// "keyword=:modifier" (please see is_modifier()), define this how many words we should check.
const MAX_MODIFIER_WORDS_NUMBER: usize = 2;
/// The threshold that enables prefix-match.
const PREFIX_MATCH_THRESHOLD: usize = 6;
/// At least this many characters must be typed for a subject to be matched.
const SUBJECT_PREFIX_MATCH_THRESHOLD: usize = 2;
impl<'a> SuggestDao<'a> {
/// Inserts the suggestions for Yelp attachment into the database.
@ -116,6 +116,15 @@ impl<'a> SuggestDao<'a> {
)?;
}
self.scope.err_if_interrupted()?;
self.conn.execute_cached(
"INSERT INTO yelp_custom_details(record_id, icon_id) VALUES(:record_id, :icon_id)",
named_params! {
":record_id": record_id.as_str(),
":icon_id": suggestion.icon_id
},
)?;
Ok(())
}
@ -134,6 +143,7 @@ impl<'a> SuggestDao<'a> {
let Some((subject, subject_exact_match)) = self.find_subject(query_string)? else {
return Ok(vec![]);
};
let icon = self.fetch_icon()?;
let builder = SuggestionBuilder {
subject: &subject,
subject_exact_match,
@ -142,14 +152,13 @@ impl<'a> SuggestDao<'a> {
location_sign: None,
location: None,
need_location: false,
pre_yelp_modifier: None,
post_yelp_modifier: None,
icon,
};
return Ok(vec![builder.into()]);
}
// Find the yelp keyword modifier and remove them from the query.
let (query_without_yelp_modifiers, pre_yelp_modifier, post_yelp_modifier) =
let (query_without_yelp_modifiers, _, _) =
self.find_modifiers(query_string, Modifier::Yelp, Modifier::Yelp)?;
// Find the location sign and the location.
@ -173,6 +182,8 @@ impl<'a> SuggestDao<'a> {
let Some((subject, subject_exact_match)) = self.find_subject(&subject_candidate)? else {
return Ok(vec![]);
};
let icon = self.fetch_icon()?;
let builder = SuggestionBuilder {
subject: &subject,
subject_exact_match,
@ -181,12 +192,36 @@ impl<'a> SuggestDao<'a> {
location_sign,
location,
need_location,
pre_yelp_modifier,
post_yelp_modifier,
icon,
};
Ok(vec![builder.into()])
}
/// Fetch the icon for Yelp suggestions.
///
/// Note that there should be only one record in `yelp_custom_details`
/// as all the Yelp assets are stored in the attachment of a single record
/// 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_icon(&self) -> Result<Option<Vec<u8>>> {
Ok(self.conn.try_query_one(
r#"
SELECT
i.data
FROM
yelp_custom_details y
JOIN
icons i
ON y.icon_id = i.id
LIMIT
1
"#,
(),
true,
)?)
}
/// Find the location information from the given query string.
/// It returns the location tuple as follows:
/// (
@ -312,9 +347,9 @@ impl<'a> SuggestDao<'a> {
return Ok(None);
}
// If the length of subject candidate is less than PREFIX_MATCH_THRESHOLD,
// should exact match.
if candidate.len() < PREFIX_MATCH_THRESHOLD {
// If the length of subject candidate is less than
// SUBJECT_PREFIX_MATCH_THRESHOLD, should exact match.
if candidate.len() < SUBJECT_PREFIX_MATCH_THRESHOLD {
return Ok(if self.is_subject(candidate)? {
Some((candidate.to_string(), true))
} else {
@ -325,7 +360,11 @@ impl<'a> SuggestDao<'a> {
// Otherwise, apply prefix-match.
Ok(
match self.conn.query_row_and_then_cachable(
"SELECT keyword FROM yelp_subjects WHERE keyword BETWEEN :candidate AND :candidate || x'FFFF' ORDER BY LENGTH(keyword) ASC LIMIT 1",
"SELECT keyword
FROM yelp_subjects
WHERE keyword BETWEEN :candidate AND :candidate || x'FFFF'
ORDER BY LENGTH(keyword) ASC, keyword ASC
LIMIT 1",
named_params! {
":candidate": candidate.to_lowercase(),
},
@ -334,10 +373,13 @@ impl<'a> SuggestDao<'a> {
) {
Ok(keyword) => {
debug_assert!(candidate.len() <= keyword.len());
Some((format!("{}{}", candidate, &keyword[candidate.len()..]), candidate.len() == keyword.len()))
},
Err(_) => None
}
Some((
format!("{}{}", candidate, &keyword[candidate.len()..]),
candidate.len() == keyword.len(),
))
}
Err(_) => None,
},
)
}
@ -385,8 +427,7 @@ struct SuggestionBuilder<'a> {
location_sign: Option<String>,
location: Option<String>,
need_location: bool,
pre_yelp_modifier: Option<String>,
post_yelp_modifier: Option<String>,
icon: Option<Vec<u8>>,
}
impl<'a> From<SuggestionBuilder<'a>> for Suggestion {
@ -419,13 +460,11 @@ impl<'a> From<SuggestionBuilder<'a>> for Suggestion {
url.push_str(&parameters.finish());
let title = [
builder.pre_yelp_modifier.as_deref(),
builder.pre_modifier.as_deref(),
Some(builder.subject),
builder.post_modifier.as_deref(),
builder.location_sign.as_deref(),
builder.location.as_deref(),
builder.post_yelp_modifier.as_deref(),
]
.iter()
.flatten()
@ -436,7 +475,8 @@ impl<'a> From<SuggestionBuilder<'a>> for Suggestion {
Suggestion::Yelp {
url,
title,
is_top_pick: builder.subject_exact_match,
subject_exact_match: builder.subject_exact_match,
icon: builder.icon,
}
}
}

Просмотреть файл

@ -1252,12 +1252,14 @@ Suggestion.Yelp = class extends Suggestion{
constructor(
url,
title,
isTopPick
subjectExactMatch,
icon
) {
super();
this.url = url;
this.title = title;
this.isTopPick = isTopPick;
this.subjectExactMatch = subjectExactMatch;
this.icon = icon;
}
}
Suggestion.Mdn = class extends Suggestion{
@ -1331,7 +1333,8 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer {
return new Suggestion.Yelp(
FfiConverterString.read(dataStream),
FfiConverterString.read(dataStream),
FfiConverterBool.read(dataStream)
FfiConverterBool.read(dataStream),
FfiConverterOptionalSequenceu8.read(dataStream)
);
case 6:
return new Suggestion.Mdn(
@ -1398,7 +1401,8 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer {
dataStream.writeInt32(5);
FfiConverterString.write(dataStream, value.url);
FfiConverterString.write(dataStream, value.title);
FfiConverterBool.write(dataStream, value.isTopPick);
FfiConverterBool.write(dataStream, value.subjectExactMatch);
FfiConverterOptionalSequenceu8.write(dataStream, value.icon);
return;
}
if (value instanceof Suggestion.Mdn) {
@ -1463,7 +1467,8 @@ export class FfiConverterTypeSuggestion extends FfiConverterArrayBuffer {
if (value instanceof Suggestion.Yelp) {
totalSize += FfiConverterString.computeSize(value.url);
totalSize += FfiConverterString.computeSize(value.title);
totalSize += FfiConverterBool.computeSize(value.isTopPick);
totalSize += FfiConverterBool.computeSize(value.subjectExactMatch);
totalSize += FfiConverterOptionalSequenceu8.computeSize(value.icon);
return totalSize;
}
if (value instanceof Suggestion.Mdn) {
@ -1497,6 +1502,7 @@ export const SuggestionProvider = {
YELP: 5,
MDN: 6,
WEATHER: 7,
AMP_MOBILE: 8,
};
Object.freeze(SuggestionProvider);
@ -1518,6 +1524,8 @@ export class FfiConverterTypeSuggestionProvider extends FfiConverterArrayBuffer
return SuggestionProvider.MDN
case 7:
return SuggestionProvider.WEATHER
case 8:
return SuggestionProvider.AMP_MOBILE
default:
return new Error("Unknown SuggestionProvider variant");
}
@ -1552,6 +1560,10 @@ export class FfiConverterTypeSuggestionProvider extends FfiConverterArrayBuffer
dataStream.writeInt32(7);
return;
}
if (value === SuggestionProvider.AMP_MOBILE) {
dataStream.writeInt32(8);
return;
}
return new Error("Unknown SuggestionProvider variant");
}
@ -1560,7 +1572,7 @@ export class FfiConverterTypeSuggestionProvider extends FfiConverterArrayBuffer
}
static checkType(value) {
if (!Number.isInteger(value) || value < 1 || value > 7) {
if (!Number.isInteger(value) || value < 1 || value > 8) {
throw new UniFFITypeError(`${value} is not a valid value for SuggestionProvider`);
}
}