Bug 1880183 - Vendor the latest Application Services. r=bdk

This version includes the new
`SuggestStoreBuilder#remoteSettingsBucketName()` API.

This commit also makes the chrome JS-exposed `SuggestStoreBuilder`
methods synchronous.

Differential Revision: https://phabricator.services.mozilla.com/D201774
This commit is contained in:
Lina Butler 2024-06-20 23:01:41 +00:00
Родитель 442dabe5bc
Коммит 3ef9e50dd0
29 изменённых файлов: 731 добавлений и 276 удалений

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

@ -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=3ca067683c7546e34bc8cdbe820fbe8e4089939a"]
[source."git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"]
git = "https://github.com/mozilla/application-services"
rev = "3ca067683c7546e34bc8cdbe820fbe8e4089939a"
rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
replace-with = "vendored-sources"
[source."git+https://github.com/mozilla/audioipc?rev=3495905752a4263827f5d43737f9ca3ed0243ce0"]

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

@ -1709,7 +1709,7 @@ dependencies = [
[[package]]
name = "error-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"error-support-macros",
"lazy_static",
@ -1721,7 +1721,7 @@ dependencies = [
[[package]]
name = "error-support-macros"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"proc-macro2",
"quote",
@ -3002,7 +3002,7 @@ dependencies = [
[[package]]
name = "interrupt-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"lazy_static",
"parking_lot",
@ -4193,7 +4193,7 @@ dependencies = [
[[package]]
name = "nss_build_common"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
[[package]]
name = "nsstring"
@ -4867,7 +4867,7 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "relevancy"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"anyhow",
"base64 0.21.3",
@ -4890,7 +4890,7 @@ dependencies = [
[[package]]
name = "remote_settings"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"parking_lot",
"serde",
@ -5425,7 +5425,7 @@ dependencies = [
[[package]]
name = "sql-support"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"ffi-support",
"interrupt-support",
@ -5607,12 +5607,14 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "suggest"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"anyhow",
"chrono",
"error-support",
"extend",
"interrupt-support",
"log",
"once_cell",
"parking_lot",
"remote_settings",
@ -5656,7 +5658,7 @@ dependencies = [
[[package]]
name = "sync-guid"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"base64 0.21.3",
"rand",
@ -5667,7 +5669,7 @@ dependencies = [
[[package]]
name = "sync15"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"anyhow",
"error-support",
@ -5698,7 +5700,7 @@ dependencies = [
[[package]]
name = "tabs"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"anyhow",
"error-support",
@ -6032,7 +6034,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "types"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"rusqlite",
"serde",
@ -6402,7 +6404,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "viaduct"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"ffi-support",
"log",
@ -6550,7 +6552,7 @@ dependencies = [
[[package]]
name = "webext-storage"
version = "0.1.0"
source = "git+https://github.com/mozilla/application-services?rev=3ca067683c7546e34bc8cdbe820fbe8e4089939a#3ca067683c7546e34bc8cdbe820fbe8e4089939a"
source = "git+https://github.com/mozilla/application-services?rev=46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151#46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151"
dependencies = [
"anyhow",
"error-support",

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

@ -221,14 +221,14 @@ 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 = "3ca067683c7546e34bc8cdbe820fbe8e4089939a" }
relevancy = { git = "https://github.com/mozilla/application-services", rev = "3ca067683c7546e34bc8cdbe820fbe8e4089939a" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "3ca067683c7546e34bc8cdbe820fbe8e4089939a" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "3ca067683c7546e34bc8cdbe820fbe8e4089939a" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "3ca067683c7546e34bc8cdbe820fbe8e4089939a" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "3ca067683c7546e34bc8cdbe820fbe8e4089939a" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "3ca067683c7546e34bc8cdbe820fbe8e4089939a" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "3ca067683c7546e34bc8cdbe820fbe8e4089939a" }
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151" }
relevancy = { git = "https://github.com/mozilla/application-services", rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151" }
sql-support = { git = "https://github.com/mozilla/application-services", rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151" }
suggest = { git = "https://github.com/mozilla/application-services", rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151" }
sync15 = { git = "https://github.com/mozilla/application-services", rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151" }
tabs = { git = "https://github.com/mozilla/application-services", rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151" }
viaduct = { git = "https://github.com/mozilla/application-services", rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151" }
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "46acbeb2cee2fb7f024b6ff5943bdfdb6cc53151" }
# 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" }

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

@ -1 +1 @@
{"files":{"Cargo.toml":"970c64cc4ed32fddac6b8cc2a83e7eb4e57aa249b8034d2d67cb56efa8475522","build.rs":"a562bfe527d21c4e8a1a44b892defa83cdff141ec5dd51ed6f3862330e50ddd7","src/bin/generate-test-data.rs":"7f1c9dc445418c7627f89d1f2aa8e550d0f85b3d1f05edb7c378ab9441714f1f","src/db.rs":"7ca5688c42d44ad6e5320208257d131c5c744be47a1cfe3e1380147abf2aadc3","src/error.rs":"bda332098f9759e4250c725b09d82704ba03c9ad87dc761414fa21f40220acf5","src/ingest.rs":"58bb3ed984aa5a9becb405793832e578586be744d3c4a1c411fdfb7ff48c55dd","src/interest.rs":"68b77eb1eb8511b846b36b5dddc02e8578e26421c5ba28ac7abab86c03ca2255","src/lib.rs":"5ed2d6829b1b537425936bcbfd32b74312dc5fd8a17a09a3a7c1ab45e85f396c","src/relevancy.udl":"9f463bbc2a7ef28358ffbfe832e62ddd6127888c484576466c759b127a55c4b2","src/rs.rs":"5803bf8deac969b2e1fc3ea0faeb592604b5e90524a2f4469565702b30c49da6","src/schema.rs":"f782c712f10c4f1af2f9e1424d6b52f59a2bacfcc452a8feb763f36478f5dd5d","src/url_hash.rs":"2e908316fb70923644d1990dbf470d69ce2f5e99b0c5c3d95ec691590be8ffa5","test-data":"1ef2cd092d59e7e126cd4a514af983d449ed9f9c98708702fd237464a76c2b5e"},"package":null}
{"files":{"Cargo.toml":"970c64cc4ed32fddac6b8cc2a83e7eb4e57aa249b8034d2d67cb56efa8475522","build.rs":"a562bfe527d21c4e8a1a44b892defa83cdff141ec5dd51ed6f3862330e50ddd7","src/bin/generate-test-data.rs":"7f1c9dc445418c7627f89d1f2aa8e550d0f85b3d1f05edb7c378ab9441714f1f","src/db.rs":"84fa47dc54f113769ce9ec6f827c8813abed61d5e5fc82404816266703a5c668","src/error.rs":"bda332098f9759e4250c725b09d82704ba03c9ad87dc761414fa21f40220acf5","src/ingest.rs":"58bb3ed984aa5a9becb405793832e578586be744d3c4a1c411fdfb7ff48c55dd","src/interest.rs":"73baa578b40b96d13899016b14087c9ac37b754c1311e2798b1d09c719447751","src/lib.rs":"214fdbeb25e0753ef132245e6892d77cad0ddd87c96d9bdd7f3427bc5d11091e","src/relevancy.udl":"9f463bbc2a7ef28358ffbfe832e62ddd6127888c484576466c759b127a55c4b2","src/rs.rs":"5803bf8deac969b2e1fc3ea0faeb592604b5e90524a2f4469565702b30c49da6","src/schema.rs":"919f4d1d3654bad966c5ce93ac157dc17cac2f35e7b8c2efc471b9af562555db","src/url_hash.rs":"2e908316fb70923644d1990dbf470d69ce2f5e99b0c5c3d95ec691590be8ffa5","test-data":"1ef2cd092d59e7e126cd4a514af983d449ed9f9c98708702fd237464a76c2b5e"},"package":null}

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

@ -4,6 +4,7 @@
*/
use crate::{
interest::InterestVectorKind,
schema::RelevancyConnectionInitializer,
url_hash::{hash_url, UrlHash},
Interest, InterestVector, Result,
@ -135,4 +136,97 @@ impl<'a> RelevancyDao<'a> {
.conn
.query_one("SELECT NOT EXISTS (SELECT 1 FROM url_interest)")?)
}
/// Update the frecency user interest vector based on a new measurement.
///
/// Right now this completely replaces the interest vector with the new data. At some point,
/// we may switch to incrementally updating it instead.
pub fn update_frecency_user_interest_vector(&self, interests: &InterestVector) -> Result<()> {
let mut stmt = self.conn.prepare(
"
INSERT OR REPLACE INTO user_interest(kind, interest_code, count)
VALUES (?, ?, ?)
",
)?;
for (interest, count) in interests.as_vec() {
stmt.execute((InterestVectorKind::Frecency, interest, count))?;
}
Ok(())
}
pub fn get_frecency_user_interest_vector(&self) -> Result<InterestVector> {
let mut stmt = self
.conn
.prepare("SELECT interest_code, count FROM user_interest WHERE kind = ?")?;
let mut interest_vec = InterestVector::default();
let rows = stmt.query_and_then((InterestVectorKind::Frecency,), |row| {
crate::Result::Ok((
Interest::try_from(row.get::<_, u32>(0)?)?,
row.get::<_, u32>(1)?,
))
})?;
for row in rows {
let (interest_code, count) = row?;
interest_vec.set(interest_code, count);
}
Ok(interest_vec)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_store_frecency_user_interest_vector() {
let db = RelevancyDb::new_for_test();
// Initially the interest vector should be blank
assert_eq!(
db.read_write(|dao| dao.get_frecency_user_interest_vector())
.unwrap(),
InterestVector::default()
);
let interest_vec = InterestVector {
animals: 2,
autos: 1,
news: 5,
..InterestVector::default()
};
db.read_write(|dao| dao.update_frecency_user_interest_vector(&interest_vec))
.unwrap();
assert_eq!(
db.read_write(|dao| dao.get_frecency_user_interest_vector())
.unwrap(),
interest_vec,
);
}
#[test]
fn test_update_frecency_user_interest_vector() {
let db = RelevancyDb::new_for_test();
let interest_vec1 = InterestVector {
animals: 2,
autos: 1,
news: 5,
..InterestVector::default()
};
let interest_vec2 = InterestVector {
animals: 1,
career: 3,
..InterestVector::default()
};
// Update the first interest vec, then the second one
db.read_write(|dao| dao.update_frecency_user_interest_vector(&interest_vec1))
.unwrap();
db.read_write(|dao| dao.update_frecency_user_interest_vector(&interest_vec2))
.unwrap();
// The current behavior is the second one should replace the first
assert_eq!(
db.read_write(|dao| dao.get_frecency_user_interest_vector())
.unwrap(),
interest_vec2,
);
}
}

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

@ -3,6 +3,33 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use crate::Error;
use rusqlite::{types::ToSqlOutput, ToSql};
/// Different kinds of interest vectors that we store for the user
///
/// The aspiration is to add more kinds and store more kinds of interest vectors, e.g.:
/// - Full history existence -- does a URL appear anywhere in the user's history?
/// - Open tabs -- does a URL appear in the user's open tabs?
/// - Bookmarks -- does a URL appear in the user's bookmarks
#[derive(Debug, Clone, Copy)]
#[repr(u32)]
pub enum InterestVectorKind {
// Calculated by checking the URLs in the user's frecency list against the topsite domains,
// categorized using Tranco.
Frecency = 1,
}
impl InterestVectorKind {
pub fn as_raw(&self) -> u32 {
*self as u32
}
}
impl ToSql for InterestVectorKind {
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::from(self.as_raw()))
}
}
/// List of possible interests for a domain. Domains can have be associated with one or multiple
/// interests. `Inconclusive` is used for domains in the user's top sites that we can't classify
@ -106,6 +133,16 @@ impl Interest {
Self::Travel,
]
}
pub fn as_raw(&self) -> u32 {
*self as u32
}
}
impl ToSql for Interest {
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::from(self.as_raw()))
}
}
/// Vector storing a count value for each interest
@ -162,6 +199,68 @@ impl InterestVector {
]
}
pub fn set(&mut self, interest: Interest, count: u32) {
match interest {
Interest::Inconclusive => {
self.inconclusive = count;
}
Interest::Animals => {
self.animals = count;
}
Interest::Arts => {
self.arts = count;
}
Interest::Autos => {
self.autos = count;
}
Interest::Business => {
self.business = count;
}
Interest::Career => {
self.career = count;
}
Interest::Education => {
self.education = count;
}
Interest::Fashion => {
self.fashion = count;
}
Interest::Finance => {
self.finance = count;
}
Interest::Food => {
self.food = count;
}
Interest::Government => {
self.government = count;
}
Interest::Hobbies => {
self.hobbies = count;
}
Interest::Home => {
self.home = count;
}
Interest::News => {
self.news = count;
}
Interest::RealEstate => {
self.real_estate = count;
}
Interest::Society => {
self.society = count;
}
Interest::Sports => {
self.sports = count;
}
Interest::Tech => {
self.tech = count;
}
Interest::Travel => {
self.travel = count;
}
}
}
pub fn summary(&self) -> String {
let mut interests: Vec<_> = self
.as_vec()

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

@ -64,12 +64,13 @@ impl RelevancyStore {
#[handle_error(Error)]
pub fn ingest(&self, top_urls_by_frecency: Vec<String>) -> ApiResult<InterestVector> {
ingest::ensure_interest_data_populated(&self.db)?;
self.classify(top_urls_by_frecency)
let interest_vec = self.classify(top_urls_by_frecency)?;
self.db
.read_write(|dao| dao.update_frecency_user_interest_vector(&interest_vec))?;
Ok(interest_vec)
}
pub fn classify(&self, top_urls_by_frecency: Vec<String>) -> Result<InterestVector> {
// For experimentation purposes we are going to return an interest vector.
// Eventually we would want to store this data in the DB and incrementally update it.
let mut interest_vector = InterestVector::default();
for url in top_urls_by_frecency {
let interest_count = self.db.read(|dao| dao.get_url_interest_vector(&url))?;

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

@ -13,7 +13,7 @@ use sql_support::open_database::{self, ConnectionInitializer};
/// 1. Bump this version.
/// 2. Add a migration from the old version to the new version in
/// [`RelevancyConnectionInitializer::upgrade_from`].
pub const VERSION: u32 = 13;
pub const VERSION: u32 = 14;
/// The current database schema.
pub const SQL: &str = "
@ -22,6 +22,14 @@ pub const SQL: &str = "
interest_code INTEGER NOT NULL,
PRIMARY KEY (url_hash, interest_code)
) WITHOUT ROWID;
-- Stores user interest vectors. The `kind` field stores the raw code from the `InterestVectorKind` enum.
CREATE TABLE user_interest(
kind INTEGER NOT NULL,
interest_code INTEGER NOT NULL,
count INTEGER NOT NULL,
PRIMARY KEY (kind, interest_code)
) WITHOUT ROWID;
";
/// Initializes an SQLite connection to the Relevancy database, performing
@ -47,7 +55,52 @@ impl ConnectionInitializer for RelevancyConnectionInitializer {
Ok(db.execute_batch(SQL)?)
}
fn upgrade_from(&self, _db: &Transaction<'_>, version: u32) -> open_database::Result<()> {
Err(open_database::Error::IncompatibleVersion(version))
fn upgrade_from(&self, tx: &Transaction<'_>, version: u32) -> open_database::Result<()> {
match version {
// Upgrades 1-12 are missing because we started with version 13, because of a
// copy-and-paste error.
13 => {
tx.execute(
"
CREATE TABLE user_interest(
kind INTEGER NOT NULL,
interest_code INTEGER NOT NULL,
count INTEGER NOT NULL,
PRIMARY KEY (kind, interest_code)
) WITHOUT ROWID;
",
(),
)?;
Ok(())
}
_ => Err(open_database::Error::IncompatibleVersion(version)),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use sql_support::open_database::test_utils::MigratedDatabaseFile;
/// The first database schema we used
pub const V1_SCHEMA: &str = "
CREATE TABLE url_interest(
url_hash BLOB NOT NULL,
interest_code INTEGER NOT NULL,
PRIMARY KEY (url_hash, interest_code)
) WITHOUT ROWID;
PRAGMA user_version=13;
";
/// Test running all schema upgrades
///
/// If an upgrade fails, then this test will fail with a panic.
#[test]
fn test_all_upgrades() {
let db_file = MigratedDatabaseFile::new(RelevancyConnectionInitializer, V1_SCHEMA);
db_file.run_all_upgrades();
db_file.assert_schema_matches_new_database();
}
}

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

@ -1 +1 @@
{"files":{"Cargo.toml":"1029f571c66d33c4dfc5e9fc55287a780329ce183f5d2b672de79737155c4227","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/client.rs":"666ef6536a81b107cdd6047b56ffb53a052c0a615b1fa827e630892c0e528a5d","src/config.rs":"52a209256acd8b1fada2b91e9d9f669df0ee6e9609baad7ec34a2111ed2a6541","src/error.rs":"4bb15cd7f6ebc438119f36291ab0eb951fe2fb05e166445817cb05aa89397000","src/lib.rs":"655559b1b0f09ad221ceba462ace73d9216a6551d70062126ffc8a085d8b89bb","src/remote_settings.udl":"1ffeb10385e4db63606cda79bb59e77170af1d2ca0028da8ab2c4d7622969734","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null}
{"files":{"Cargo.toml":"b7ce43b44cab449291d711602e00307ef113e85d220990123756fdf46d345bbf","build.rs":"4326f03729cf8f1673e4228e6dc111de1ea4d8bcc06351f7ae563efb2613f866","src/client.rs":"289bd72c901d99eebbf9d6f559456ca05a4f23b1570ccba2d206284a9dec7d65","src/config.rs":"52a209256acd8b1fada2b91e9d9f669df0ee6e9609baad7ec34a2111ed2a6541","src/error.rs":"4bb15cd7f6ebc438119f36291ab0eb951fe2fb05e166445817cb05aa89397000","src/lib.rs":"655559b1b0f09ad221ceba462ace73d9216a6551d70062126ffc8a085d8b89bb","src/remote_settings.udl":"1ffeb10385e4db63606cda79bb59e77170af1d2ca0028da8ab2c4d7622969734","uniffi.toml":"f8ec8dc593e0d501c2e9e40368ec93ec33b1edd8608e29495e0a54b63144e880"},"package":null}

4
third_party/rust/remote_settings/Cargo.toml поставляемый
Просмотреть файл

@ -42,6 +42,10 @@ path = "../viaduct"
expect-test = "1.4"
mockito = "0.31"
[dev-dependencies.serde_json]
version = "1"
features = ["preserve_order"]
[dev-dependencies.viaduct-reqwest]
path = "../support/viaduct-reqwest"

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

@ -777,15 +777,15 @@ mod test {
},
),
fields: {
"title": String(
"jpg-attachment",
),
"content": String(
"content",
),
"schema": Number(
1677694447771,
),
"title": String(
"jpg-attachment",
),
},
},
RemoteSettingsRecord {
@ -802,15 +802,15 @@ mod test {
},
),
fields: {
"title": String(
"with-attachment",
),
"content": String(
"content",
),
"schema": Number(
1677694447771,
),
"title": String(
"with-attachment",
),
},
},
RemoteSettingsRecord {
@ -819,15 +819,15 @@ mod test {
deleted: false,
attachment: None,
fields: {
"title": String(
"no-attachment",
),
"content": String(
"content",
),
"schema": Number(
1677694447771,
),
"title": String(
"no-attachment",
),
},
},
RemoteSettingsRecord {
@ -928,15 +928,15 @@ mod test {
},
),
fields: {
"title": String(
"jpg-attachment",
),
"content": String(
"content",
),
"schema": Number(
1677694447771,
),
"title": String(
"jpg-attachment",
),
},
},
RemoteSettingsRecord {
@ -953,15 +953,15 @@ mod test {
},
),
fields: {
"title": String(
"with-attachment",
),
"content": String(
"content",
),
"schema": Number(
1677694447771,
),
"title": String(
"with-attachment",
),
},
},
RemoteSettingsRecord {
@ -970,15 +970,15 @@ mod test {
deleted: false,
attachment: None,
fields: {
"title": String(
"no-attachment",
),
"content": String(
"content",
),
"schema": Number(
1677694447771,
),
"title": String(
"no-attachment",
),
},
},
RemoteSettingsRecord {

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

@ -1 +1 @@
{"files":{"Cargo.toml":"6765229acc1f06326b3ede93379d78d119aa78679567baf0bf7bdb5ec310522f","src/conn_ext.rs":"d4eddf906ecf5d45b8cf9e858751cc22e644e652f04560237f8de748a33d56f6","src/debug_tools.rs":"bece2bc3d35379b81ea2f942a0a3e909e0ab0553656505904745548eacaf402a","src/each_chunk.rs":"e900a4ebadad31b0a87cb8d7c3ed5aeb7325d4d380ae1d9174eff62c78facdcc","src/lazy.rs":"a96b4f4ec572538b49cdfa8fee981dcf5143a5f51163fb8a573d3ac128df70f9","src/lib.rs":"b2c120db4928c3e4abdd96405fd4c1016255699bdbc38c8cd60dbd3431fc0a12","src/maybe_cached.rs":"0b18425595055883a98807fbd62ff27a79c18af34e7cb3439f8c3438463ef2dd","src/open_database.rs":"1de254e20df724f74be6c6d3bd54c77c9dd8eb009ef0a33c2e0a15da8f5c2aa3","src/repeat.rs":"b4c5ff5d083afba7f9f153f54aba2e6859b78b85c82d48dbd6bd58f67da9e6b9"},"package":null}
{"files":{"Cargo.toml":"6765229acc1f06326b3ede93379d78d119aa78679567baf0bf7bdb5ec310522f","src/conn_ext.rs":"d4eddf906ecf5d45b8cf9e858751cc22e644e652f04560237f8de748a33d56f6","src/debug_tools.rs":"bece2bc3d35379b81ea2f942a0a3e909e0ab0553656505904745548eacaf402a","src/each_chunk.rs":"e900a4ebadad31b0a87cb8d7c3ed5aeb7325d4d380ae1d9174eff62c78facdcc","src/lazy.rs":"a96b4f4ec572538b49cdfa8fee981dcf5143a5f51163fb8a573d3ac128df70f9","src/lib.rs":"b2c120db4928c3e4abdd96405fd4c1016255699bdbc38c8cd60dbd3431fc0a12","src/maybe_cached.rs":"0b18425595055883a98807fbd62ff27a79c18af34e7cb3439f8c3438463ef2dd","src/open_database.rs":"c8e46d682da499e1b9ab0fd7f8a21f6140d1f9520b40b21cb7bd3f542e3d5f3e","src/repeat.rs":"b4c5ff5d083afba7f9f153f54aba2e6859b78b85c82d48dbd6bd58f67da9e6b9"},"package":null}

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

@ -423,6 +423,7 @@ pub mod test_utils {
pub fn assert_schema_matches_new_database(&self) {
let db = self.open();
let new_db = open_memory_database(&self.connection_initializer).unwrap();
let table_names = get_table_names(&db);
let new_db_table_names = get_table_names(&new_db);
let extra_tables = Vec::from_iter(table_names.difference(&new_db_table_names));
@ -433,7 +434,6 @@ pub mod test_utils {
if !new_db_extra_tables.is_empty() {
panic!("Extra tables only present in new database: {new_db_extra_tables:?}");
}
for table_name in table_names {
assert_eq!(
get_table_sql(&db, &table_name),
@ -441,6 +441,24 @@ pub mod test_utils {
"sql differs for table: {table_name}",
);
}
let index_names = get_index_names(&db);
let new_db_index_names = get_index_names(&new_db);
let extra_index = Vec::from_iter(index_names.difference(&new_db_index_names));
if !extra_index.is_empty() {
panic!("Extra indexes not present in new database: {extra_index:?}");
}
let new_db_extra_index = Vec::from_iter(new_db_index_names.difference(&index_names));
if !new_db_extra_index.is_empty() {
panic!("Extra indexes only present in new database: {new_db_extra_index:?}");
}
for index_name in index_names {
assert_eq!(
get_index_sql(&db, &index_name),
get_index_sql(&new_db, &index_name),
"sql differs for index: {index_name}",
);
}
}
pub fn open(&self) -> Connection {
@ -467,6 +485,26 @@ pub mod test_utils {
)
.unwrap()
}
fn get_index_names(conn: &Connection) -> HashSet<String> {
conn.query_rows_and_then(
"SELECT name FROM sqlite_master WHERE type='index'",
(),
|row| row.get(0),
)
.unwrap()
.into_iter()
.collect()
}
fn get_index_sql(conn: &Connection, index_name: &str) -> String {
conn.query_row_and_then(
"SELECT sql FROM sqlite_master WHERE name = ? AND type='index'",
(&index_name,),
|row| row.get::<_, String>(0),
)
.unwrap()
}
}
#[cfg(test)]

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

@ -1 +1 @@
{"files":{"Cargo.toml":"b2d2fb29d7408dd736650935a89627490c25ef813a5244ecd1bd9dad30e32b78","README.md":"dd0c0d3fc180f2021d81ea5804895f661cb4fe45b87fe5b1ebf8aa756988e867","benches/benchmark_all.rs":"c2343c9197b6d9ccb0798d7701b1b0d2569d494dd31a975d21d7ec6f26e32879","build.rs":"78780c5cccfe22c3ff4198624b9e188559c437c3e6fa1c8bb66548eee6aa66bf","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"b65f3d53323c827ca55cc02442b63a137c783530cc93225a90b02bc4e9790d0f","src/benchmarks/ingest.rs":"8cce7a9162bc1080e58e7f18a27c64f74cb45598fa33d3c2579f30e9b0414d50","src/benchmarks/mod.rs":"fe1898ba4d783213525da10d92858ee84cebfd22749bad7aeb461d338fe5504a","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"d40c6e83d8b5faa32c66110803ca9e78611d43507e9d3f1e191a93a7773c37b3","src/db.rs":"f2c986a8255e8359ddabd70b3dbab50713d092f3e5dfe85581a60f24655c1686","src/error.rs":"d5e0ec57aefc19d3e0230bb8832ca6fa603a18feabfc3a3e0f06ac940cc4e45e","src/keyword.rs":"988d0ab021c0df19cfd3c519df7d37f606bf984cd14d0efca4e5a7aff88344dd","src/lib.rs":"73887af023e223188f874d43ddf601784c93e9388a7adece79818d559a3366a1","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"92eb1a9fa7d6814efe47fc3e7447e46bf6c0320d6fbef0d9170c46eab0e272ab","src/query.rs":"1084548b9dc0587322f08741e07db9413e9fa231166593bdbf47e562d31799a3","src/rs.rs":"0eabd6108fd1316265def15f9d232b2f70a72126019891bf4f52f5a8c6f72d1a","src/schema.rs":"88ff3ae6b652fa5a5cff4dc504d11a7fc33f1b2ee9716b970f646d9f9ca90ab7","src/store.rs":"f47de3b4da2677bdca8edd1b017f1580b9985f36d2d86b904e1058893c9f3445","src/suggest.udl":"4bfd70767a204dc58081be5d70ca96480b04b9acb741e6d2d8394362677f119d","src/suggestion.rs":"f31227779d13d1b03a622e08a417ceba4afb161885a01c2bc87a6a652b5e8be5","src/testing/client.rs":"855c14a2a5c5d9a33521c44dbb0d89f5ff531c5d125fb62d6491190c4c887df0","src/testing/data.rs":"dcd24d24997fe4f8c472f5b754a9a2b90b83e2632b4f13a77499e23441a6dea1","src/testing/mod.rs":"308c9e0f479b3d8ca6c206853842e42ce07721161f3dcc23b7018a7e4d687b03","src/yelp.rs":"bc036ff71b438d53ce8811acd8d650d83ef03faeea476f5b659b403c1e64ff2b","uniffi.toml":"f26317442ddb5b3281245bef6e60ffcb78bb95d29fe4a351a56dbb88d4ec8aab"},"package":null}
{"files":{"Cargo.toml":"2279f807917db93aa1cb91d7ff1b44e28fe43c160d83eed9a231a8e1b11f913f","README.md":"dd0c0d3fc180f2021d81ea5804895f661cb4fe45b87fe5b1ebf8aa756988e867","benches/benchmark_all.rs":"dd15df10d2561e7fdd669e86ef4343c04153682ee5a3943d1de0a54ccf577ac8","build.rs":"78780c5cccfe22c3ff4198624b9e188559c437c3e6fa1c8bb66548eee6aa66bf","src/benchmarks/README.md":"ccee8dbddba8762d0453fa855bd6984137b224b8c019f3dd8e86a3c303f51d71","src/benchmarks/client.rs":"b65f3d53323c827ca55cc02442b63a137c783530cc93225a90b02bc4e9790d0f","src/benchmarks/ingest.rs":"dbaf687213eb28ba9c10a30082fbce823375a91efa215db6d01ac26004478876","src/benchmarks/mod.rs":"fe1898ba4d783213525da10d92858ee84cebfd22749bad7aeb461d338fe5504a","src/bin/debug_ingestion_sizes.rs":"ce6e810be7b3fc19e826d75b622b82cfab5a1a99397a6d0833c2c4eebff2d364","src/config.rs":"d40c6e83d8b5faa32c66110803ca9e78611d43507e9d3f1e191a93a7773c37b3","src/db.rs":"455691edb2e3af8c0a7ca05e3bf4f974b6ba49a362247348d3754ad99da358d3","src/error.rs":"5209d1d6d0fd3b155e2198813db47f12e9217978c4a28086b9fe93fc738b64af","src/keyword.rs":"988d0ab021c0df19cfd3c519df7d37f606bf984cd14d0efca4e5a7aff88344dd","src/lib.rs":"73887af023e223188f874d43ddf601784c93e9388a7adece79818d559a3366a1","src/pocket.rs":"1316668840ec9b4ea886223921dc9d3b5a1731d1a5206c0b1089f2a6c45c1b7b","src/provider.rs":"92eb1a9fa7d6814efe47fc3e7447e46bf6c0320d6fbef0d9170c46eab0e272ab","src/query.rs":"1084548b9dc0587322f08741e07db9413e9fa231166593bdbf47e562d31799a3","src/rs.rs":"0eabd6108fd1316265def15f9d232b2f70a72126019891bf4f52f5a8c6f72d1a","src/schema.rs":"8c963db3e047828c81619128430c47a4beee3a48fd5b72700f364e90dc2e96d1","src/store.rs":"36c461c7091314f336c59ea8d5f2132c21cdad44637dd7e6039b0245090ee511","src/suggest.udl":"f47c0f1021ed78118950a6830e943c9c16be22189b982a747ced930f0aec7b3a","src/suggestion.rs":"f31227779d13d1b03a622e08a417ceba4afb161885a01c2bc87a6a652b5e8be5","src/testing/client.rs":"855c14a2a5c5d9a33521c44dbb0d89f5ff531c5d125fb62d6491190c4c887df0","src/testing/data.rs":"dcd24d24997fe4f8c472f5b754a9a2b90b83e2632b4f13a77499e23441a6dea1","src/testing/mod.rs":"308c9e0f479b3d8ca6c206853842e42ce07721161f3dcc23b7018a7e4d687b03","src/yelp.rs":"bc036ff71b438d53ce8811acd8d650d83ef03faeea476f5b659b403c1e64ff2b","uniffi.toml":"f26317442ddb5b3281245bef6e60ffcb78bb95d29fe4a351a56dbb88d4ec8aab"},"package":null}

2
third_party/rust/suggest/Cargo.toml поставляемый
Просмотреть файл

@ -33,6 +33,8 @@ required-features = ["benchmark_api"]
[dependencies]
anyhow = "1.0"
chrono = "0.4"
extend = "1.1"
log = "0.4"
once_cell = "1.5"
parking_lot = ">=0.11,<=0.12"
serde_json = "1"

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

@ -8,7 +8,7 @@ pub fn ingest_single_provider(c: &mut Criterion) {
// 100s to run which feels like too long. `ingest-amp-mobile` also would take a around 50s.
group.sample_size(10);
for (name, benchmark) in ingest::all_benchmarks() {
group.bench_function(format!("ingest-{name}"), |b| {
group.bench_function(name.to_string(), |b| {
b.iter_batched(
|| benchmark.generate_input(),
|input| benchmark.benchmarked_code(input),

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

@ -19,10 +19,11 @@ pub struct IngestBenchmark {
temp_dir: tempfile::TempDir,
client: RemoteSettingsBenchmarkClient,
record_type: SuggestRecordType,
reingest: bool,
}
impl IngestBenchmark {
pub fn new(record_type: SuggestRecordType) -> Self {
pub fn new(record_type: SuggestRecordType, reingest: bool) -> Self {
let temp_dir = tempfile::tempdir().unwrap();
let store = SuggestStoreInner::new(
temp_dir.path().join("warmup.sqlite"),
@ -33,6 +34,7 @@ impl IngestBenchmark {
client: RemoteSettingsBenchmarkClient::from(store.into_settings_client()),
temp_dir,
record_type,
reingest,
}
}
}
@ -52,6 +54,9 @@ impl BenchmarkWithInput for IngestBenchmark {
));
let store = SuggestStoreInner::new(data_path, self.client.clone());
store.ensure_db_initialized();
if self.reingest {
store.force_reingest(self.record_type);
}
InputType(store)
}
@ -64,23 +69,77 @@ impl BenchmarkWithInput for IngestBenchmark {
/// Get IngestBenchmark instances for all record types
pub fn all_benchmarks() -> Vec<(&'static str, IngestBenchmark)> {
vec![
("icon", IngestBenchmark::new(SuggestRecordType::Icon)),
(
"amp-wikipedia",
IngestBenchmark::new(SuggestRecordType::AmpWikipedia),
),
("amo", IngestBenchmark::new(SuggestRecordType::Amo)),
("pocket", IngestBenchmark::new(SuggestRecordType::Pocket)),
("yelp", IngestBenchmark::new(SuggestRecordType::Yelp)),
("mdn", IngestBenchmark::new(SuggestRecordType::Mdn)),
("weather", IngestBenchmark::new(SuggestRecordType::Weather)),
(
"global-config",
IngestBenchmark::new(SuggestRecordType::GlobalConfig),
"ingest-icon",
IngestBenchmark::new(SuggestRecordType::Icon, false),
),
(
"amp-mobile",
IngestBenchmark::new(SuggestRecordType::AmpMobile),
"ingest-amp-wikipedia",
IngestBenchmark::new(SuggestRecordType::AmpWikipedia, false),
),
(
"ingest-amo",
IngestBenchmark::new(SuggestRecordType::Amo, false),
),
(
"ingest-pocket",
IngestBenchmark::new(SuggestRecordType::Pocket, false),
),
(
"ingest-yelp",
IngestBenchmark::new(SuggestRecordType::Yelp, false),
),
(
"ingest-mdn",
IngestBenchmark::new(SuggestRecordType::Mdn, false),
),
(
"ingest-weather",
IngestBenchmark::new(SuggestRecordType::Weather, false),
),
(
"ingest-global-config",
IngestBenchmark::new(SuggestRecordType::GlobalConfig, false),
),
(
"ingest-amp-mobile",
IngestBenchmark::new(SuggestRecordType::AmpMobile, false),
),
(
"ingest-again-icon",
IngestBenchmark::new(SuggestRecordType::Icon, true),
),
(
"ingest-again-amp-wikipedia",
IngestBenchmark::new(SuggestRecordType::AmpWikipedia, true),
),
(
"ingest-again-amo",
IngestBenchmark::new(SuggestRecordType::Amo, true),
),
(
"ingest-again-pocket",
IngestBenchmark::new(SuggestRecordType::Pocket, true),
),
(
"ingest-again-yelp",
IngestBenchmark::new(SuggestRecordType::Yelp, true),
),
(
"ingest-again-mdn",
IngestBenchmark::new(SuggestRecordType::Mdn, true),
),
(
"ingest-again-weather",
IngestBenchmark::new(SuggestRecordType::Weather, true),
),
(
"ingest-again-global-config",
IngestBenchmark::new(SuggestRecordType::GlobalConfig, true),
),
(
"ingest-again-amp-mobile",
IngestBenchmark::new(SuggestRecordType::AmpMobile, true),
),
]
}
@ -95,6 +154,7 @@ pub fn print_debug_ingestion_sizes() {
.ingest(SuggestIngestionConstraints::default())
.unwrap();
let table_row_counts = store.table_row_counts();
let db_size = store.db_size();
let client = store.into_settings_client();
let total_attachment_size: usize = client
.get_records_responses
@ -112,6 +172,7 @@ pub fn print_debug_ingestion_sizes() {
"Total attachment size: {}kb",
(total_attachment_size + 500) / 1000
);
println!("Total database size: {}kb", (db_size + 500) / 1000);
println!();
println!("Database table row counts");
println!("-------------------------");

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

@ -16,6 +16,7 @@ use sql_support::{open_database::open_database_with_flags, ConnExt};
use crate::{
config::{SuggestGlobalConfig, SuggestProviderConfig},
error::RusqliteResultExt,
keyword::full_keyword,
pocket::{split_keyword, KeywordConfidence},
provider::SuggestionProvider,
@ -679,6 +680,8 @@ impl<'a> SuggestDao<'a> {
suggestions: &[DownloadedAmoSuggestion],
) -> Result<()> {
let mut suggestion_insert = SuggestionInsertStatement::new(self.conn)?;
let mut amo_insert = AmoInsertStatement::new(self.conn)?;
let mut prefix_keyword_insert = PrefixKeywordInsertStatement::new(self.conn)?;
for suggestion in suggestions {
self.scope.err_if_interrupted()?;
let suggestion_id = suggestion_insert.execute(
@ -688,53 +691,15 @@ impl<'a> SuggestDao<'a> {
suggestion.score,
SuggestionProvider::Amo,
)?;
self.conn.execute(
"INSERT INTO amo_custom_details(
suggestion_id,
description,
guid,
icon_url,
rating,
number_of_ratings
)
VALUES(
:suggestion_id,
:description,
:guid,
:icon_url,
:rating,
:number_of_ratings
)",
named_params! {
":suggestion_id": suggestion_id,
":description": suggestion.description,
":guid": suggestion.guid,
":icon_url": suggestion.icon_url,
":rating": suggestion.rating,
":number_of_ratings": suggestion.number_of_ratings
},
)?;
amo_insert.execute(suggestion_id, suggestion)?;
for (index, keyword) in suggestion.keywords.iter().enumerate() {
let (keyword_prefix, keyword_suffix) = split_keyword(keyword);
self.conn.execute(
"INSERT INTO prefix_keywords(
keyword_prefix,
keyword_suffix,
suggestion_id,
rank
)
VALUES(
:keyword_prefix,
:keyword_suffix,
:suggestion_id,
:rank
)",
named_params! {
":keyword_prefix": keyword_prefix,
":keyword_suffix": keyword_suffix,
":rank": index,
":suggestion_id": suggestion_id,
},
prefix_keyword_insert.execute(
suggestion_id,
None,
keyword_prefix,
keyword_suffix,
index,
)?;
}
}
@ -843,6 +808,7 @@ impl<'a> SuggestDao<'a> {
suggestions: &[DownloadedPocketSuggestion],
) -> Result<()> {
let mut suggestion_insert = SuggestionInsertStatement::new(self.conn)?;
let mut prefix_keyword_insert = PrefixKeywordInsertStatement::new(self.conn)?;
for suggestion in suggestions {
self.scope.err_if_interrupted()?;
let suggestion_id = suggestion_insert.execute(
@ -866,28 +832,12 @@ impl<'a> SuggestDao<'a> {
)
{
let (keyword_prefix, keyword_suffix) = split_keyword(keyword);
self.conn.execute(
"INSERT INTO prefix_keywords(
keyword_prefix,
keyword_suffix,
confidence,
rank,
suggestion_id
)
VALUES(
:keyword_prefix,
:keyword_suffix,
:confidence,
:rank,
:suggestion_id
)",
named_params! {
":keyword_prefix": keyword_prefix,
":keyword_suffix": keyword_suffix,
":confidence": confidence,
":rank": rank,
":suggestion_id": suggestion_id,
},
prefix_keyword_insert.execute(
suggestion_id,
Some(confidence as u8),
keyword_prefix,
keyword_suffix,
rank,
)?;
}
}
@ -902,6 +852,8 @@ impl<'a> SuggestDao<'a> {
suggestions: &[DownloadedMdnSuggestion],
) -> Result<()> {
let mut suggestion_insert = SuggestionInsertStatement::new(self.conn)?;
let mut mdn_insert = MdnInsertStatement::new(self.conn)?;
let mut prefix_keyword_insert = PrefixKeywordInsertStatement::new(self.conn)?;
for suggestion in suggestions {
self.scope.err_if_interrupted()?;
let suggestion_id = suggestion_insert.execute(
@ -911,41 +863,15 @@ impl<'a> SuggestDao<'a> {
suggestion.score,
SuggestionProvider::Mdn,
)?;
self.conn.execute_cached(
"INSERT INTO mdn_custom_details(
suggestion_id,
description
)
VALUES(
:suggestion_id,
:description
)",
named_params! {
":suggestion_id": suggestion_id,
":description": suggestion.description,
},
)?;
mdn_insert.execute(suggestion_id, suggestion)?;
for (index, keyword) in suggestion.keywords.iter().enumerate() {
let (keyword_prefix, keyword_suffix) = split_keyword(keyword);
self.conn.execute_cached(
"INSERT INTO prefix_keywords(
keyword_prefix,
keyword_suffix,
suggestion_id,
rank
)
VALUES(
:keyword_prefix,
:keyword_suffix,
:suggestion_id,
:rank
)",
named_params! {
":keyword_prefix": keyword_prefix,
":keyword_suffix": keyword_suffix,
":rank": index,
":suggestion_id": suggestion_id,
},
prefix_keyword_insert.execute(
suggestion_id,
None,
keyword_prefix,
keyword_suffix,
index,
)?;
}
}
@ -959,6 +885,7 @@ impl<'a> SuggestDao<'a> {
data: &DownloadedWeatherData,
) -> Result<()> {
let mut suggestion_insert = SuggestionInsertStatement::new(self.conn)?;
let mut keyword_insert = KeywordInsertStatement::new(self.conn)?;
self.scope.err_if_interrupted()?;
let suggestion_id = suggestion_insert.execute(
record_id,
@ -968,15 +895,7 @@ impl<'a> SuggestDao<'a> {
SuggestionProvider::Weather,
)?;
for (index, keyword) in data.weather.keywords.iter().enumerate() {
self.conn.execute(
"INSERT INTO keywords(keyword, suggestion_id, rank)
VALUES(:keyword, :suggestion_id, :rank)",
named_params! {
":keyword": keyword,
":suggestion_id": suggestion_id,
":rank": index,
},
)?;
keyword_insert.execute(suggestion_id, keyword, None, index)?;
}
self.put_provider_config(
SuggestionProvider::Weather,
@ -1026,6 +945,18 @@ impl<'a> SuggestDao<'a> {
/// Deletes all suggestions associated with a Remote Settings record from
/// the database.
pub fn drop_suggestions(&mut self, record_id: &SuggestRecordId) -> Result<()> {
self.conn.execute_cached(
"DELETE FROM keywords WHERE suggestion_id IN (SELECT id from suggestions WHERE record_id = :record_id)",
named_params! { ":record_id": record_id.as_str() },
)?;
self.conn.execute_cached(
"DELETE FROM full_keywords WHERE suggestion_id IN (SELECT id from suggestions WHERE record_id = :record_id)",
named_params! { ":record_id": record_id.as_str() },
)?;
self.conn.execute_cached(
"DELETE FROM prefix_keywords WHERE suggestion_id IN (SELECT id from suggestions WHERE record_id = :record_id)",
named_params! { ":record_id": record_id.as_str() },
)?;
self.conn.execute_cached(
"DELETE FROM suggestions WHERE record_id = :record_id",
named_params! { ":record_id": record_id.as_str() },
@ -1081,6 +1012,18 @@ impl<'a> SuggestDao<'a> {
Ok(())
}
#[cfg(feature = "benchmark_api")]
/// Clears the value for a metadata key.
///
/// This is currently only used for the benchmarks.
pub fn clear_meta(&mut self, key: &str) -> Result<()> {
self.conn.execute_cached(
"DELETE FROM meta WHERE key = :key",
named_params! { ":key": key },
)?;
Ok(())
}
/// Updates the last ingest timestamp if the given last modified time is
/// newer than the existing one recorded.
pub fn put_last_ingest_if_newer(
@ -1220,10 +1163,12 @@ impl<'conn> SuggestionInsertStatement<'conn> {
score: f64,
provider: SuggestionProvider,
) -> Result<i64> {
Ok(self.0.query_row(
(record_id.as_str(), title, url, score, provider as u8),
|row| row.get(0),
)?)
self.0
.query_row(
(record_id.as_str(), title, url, score, provider as u8),
|row| row.get(0),
)
.with_context("suggestion insert")
}
}
@ -1247,15 +1192,17 @@ impl<'conn> AmpInsertStatement<'conn> {
}
fn execute(&mut self, suggestion_id: i64, amp: &DownloadedAmpSuggestion) -> Result<()> {
self.0.execute((
suggestion_id,
&amp.advertiser,
amp.block_id,
&amp.iab_category,
&amp.impression_url,
&amp.click_url,
&amp.icon_id,
))?;
self.0
.execute((
suggestion_id,
&amp.advertiser,
amp.block_id,
&amp.iab_category,
&amp.impression_url,
&amp.click_url,
&amp.icon_id,
))
.with_context("amp insert")?;
Ok(())
}
}
@ -1279,7 +1226,64 @@ impl<'conn> WikipediaInsertStatement<'conn> {
suggestion_id: i64,
wikipedia: &DownloadedWikipediaSuggestion,
) -> Result<()> {
self.0.execute((suggestion_id, &wikipedia.icon_id))?;
self.0
.execute((suggestion_id, &wikipedia.icon_id))
.with_context("wikipedia insert")?;
Ok(())
}
}
struct AmoInsertStatement<'conn>(rusqlite::Statement<'conn>);
impl<'conn> AmoInsertStatement<'conn> {
fn new(conn: &'conn Connection) -> Result<Self> {
Ok(Self(conn.prepare(
"INSERT INTO amo_custom_details(
suggestion_id,
description,
guid,
icon_url,
rating,
number_of_ratings
)
VALUES(?, ?, ?, ?, ?, ?)
",
)?))
}
fn execute(&mut self, suggestion_id: i64, amo: &DownloadedAmoSuggestion) -> Result<()> {
self.0
.execute((
suggestion_id,
&amo.description,
&amo.guid,
&amo.icon_url,
&amo.rating,
amo.number_of_ratings,
))
.with_context("amo insert")?;
Ok(())
}
}
struct MdnInsertStatement<'conn>(rusqlite::Statement<'conn>);
impl<'conn> MdnInsertStatement<'conn> {
fn new(conn: &'conn Connection) -> Result<Self> {
Ok(Self(conn.prepare(
"INSERT INTO mdn_custom_details(
suggestion_id,
description
)
VALUES(?, ?)
",
)?))
}
fn execute(&mut self, suggestion_id: i64, mdn: &DownloadedMdnSuggestion) -> Result<()> {
self.0
.execute((suggestion_id, &mdn.description))
.with_context("mdn insert")?;
Ok(())
}
}
@ -1308,7 +1312,46 @@ impl<'conn> KeywordInsertStatement<'conn> {
rank: usize,
) -> Result<()> {
self.0
.execute((suggestion_id, keyword, full_keyword_id, rank))?;
.execute((suggestion_id, keyword, full_keyword_id, rank))
.with_context("keyword insert")?;
Ok(())
}
}
struct PrefixKeywordInsertStatement<'conn>(rusqlite::Statement<'conn>);
impl<'conn> PrefixKeywordInsertStatement<'conn> {
fn new(conn: &'conn Connection) -> Result<Self> {
Ok(Self(conn.prepare(
"INSERT INTO prefix_keywords(
suggestion_id,
confidence,
keyword_prefix,
keyword_suffix,
rank
)
VALUES(?, ?, ?, ?, ?)
",
)?))
}
fn execute(
&mut self,
suggestion_id: i64,
confidence: Option<u8>,
keyword_prefix: &str,
keyword_suffix: &str,
rank: usize,
) -> Result<()> {
self.0
.execute((
suggestion_id,
confidence.unwrap_or(0),
keyword_prefix,
keyword_suffix,
rank,
))
.with_context("prefix keyword insert")?;
Ok(())
}
}

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

@ -14,8 +14,11 @@ pub enum Error {
#[error("Error opening database: {0}")]
OpenDatabase(#[from] sql_support::open_database::Error),
#[error("Error executing SQL: {0}")]
Sql(#[from] rusqlite::Error),
#[error("Error executing SQL: {inner} (context: {context})")]
Sql {
inner: rusqlite::Error,
context: String,
},
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
@ -33,6 +36,29 @@ pub enum Error {
SuggestStoreBuilder(String),
}
impl Error {
fn sql(e: rusqlite::Error, context: impl Into<String>) -> Self {
Self::Sql {
inner: e,
context: context.into(),
}
}
}
impl From<rusqlite::Error> for Error {
fn from(e: rusqlite::Error) -> Self {
Self::sql(e, "<none>")
}
}
#[extend::ext(name=RusqliteResultExt)]
pub impl<T> Result<T, rusqlite::Error> {
// Convert an rusqlite::Error to our error type, with a context value
fn with_context(self, context: &str) -> Result<T, Error> {
self.map_err(|e| Error::sql(e, context))
}
}
/// The error type for all Suggest component operations. These errors are
/// exposed to your application, which should handle them as needed.
#[derive(Debug, thiserror::Error)]

49
third_party/rust/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 = "
@ -26,17 +26,16 @@ CREATE TABLE meta(
CREATE TABLE keywords(
keyword TEXT NOT NULL,
suggestion_id INTEGER NOT NULL REFERENCES suggestions(id) ON DELETE CASCADE,
full_keyword_id INTEGER NULL REFERENCES full_keywords(id) ON DELETE SET NULL,
suggestion_id INTEGER NOT NULL,
full_keyword_id INTEGER NULL,
rank INTEGER NOT NULL,
PRIMARY KEY (keyword, suggestion_id)
) WITHOUT ROWID;
-- full keywords are what we display to the user when a (partial) keyword matches
-- The FK to suggestion_id makes it so full keywords get deleted when the parent suggestion is deleted.
CREATE TABLE full_keywords(
id INTEGER PRIMARY KEY,
suggestion_id INTEGER NOT NULL REFERENCES suggestions(id) ON DELETE CASCADE,
suggestion_id INTEGER NOT NULL,
full_keyword TEXT NOT NULL
);
@ -45,7 +44,7 @@ CREATE TABLE prefix_keywords(
keyword_suffix TEXT NOT NULL DEFAULT '',
confidence INTEGER NOT NULL DEFAULT 0,
rank INTEGER NOT NULL,
suggestion_id INTEGER NOT NULL REFERENCES suggestions(id) ON DELETE CASCADE,
suggestion_id INTEGER NOT NULL,
PRIMARY KEY (keyword_prefix, keyword_suffix, suggestion_id)
) WITHOUT ROWID;
@ -193,6 +192,41 @@ CREATE TABLE IF NOT EXISTS dismissed_suggestions (
)?;
Ok(())
}
19 => {
// Clear the database since we're going to be dropping the keywords table and
// re-creating it
clear_database(tx)?;
tx.execute_batch(
"
-- Recreate the various keywords table to drop the foreign keys.
DROP TABLE keywords;
DROP TABLE full_keywords;
DROP TABLE prefix_keywords;
CREATE TABLE keywords(
keyword TEXT NOT NULL,
suggestion_id INTEGER NOT NULL,
full_keyword_id INTEGER NULL,
rank INTEGER NOT NULL,
PRIMARY KEY (keyword, suggestion_id)
) WITHOUT ROWID;
CREATE TABLE full_keywords(
id INTEGER PRIMARY KEY,
suggestion_id INTEGER NOT NULL,
full_keyword TEXT NOT NULL
);
CREATE TABLE prefix_keywords(
keyword_prefix TEXT NOT NULL,
keyword_suffix TEXT NOT NULL DEFAULT '',
confidence INTEGER NOT NULL DEFAULT 0,
rank INTEGER NOT NULL,
suggestion_id INTEGER NOT NULL,
PRIMARY KEY (keyword_prefix, keyword_suffix, suggestion_id)
) WITHOUT ROWID;
CREATE UNIQUE INDEX keywords_suggestion_id_rank ON keywords(suggestion_id, rank);
",
)?;
Ok(())
}
_ => Err(open_database::Error::IncompatibleVersion(version)),
}
}
@ -203,6 +237,9 @@ pub fn clear_database(db: &Connection) -> rusqlite::Result<()> {
db.execute_batch(
"
DELETE FROM meta;
DELETE FROM keywords;
DELETE FROM full_keywords;
DELETE FROM prefix_keywords;
DELETE FROM suggestions;
DELETE FROM icons;
DELETE FROM yelp_subjects;

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

@ -9,7 +9,7 @@ use std::{
sync::Arc,
};
use error_support::handle_error;
use error_support::{breadcrumb, handle_error};
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use remote_settings::{self, RemoteSettingsConfig, RemoteSettingsServer};
@ -38,7 +38,7 @@ pub struct SuggestStoreBuilder(Mutex<SuggestStoreBuilderInner>);
struct SuggestStoreBuilderInner {
data_path: Option<String>,
remote_settings_server: Option<RemoteSettingsServer>,
remote_settings_config: Option<RemoteSettingsConfig>,
remote_settings_bucket_name: Option<String>,
}
impl Default for SuggestStoreBuilder {
@ -62,13 +62,13 @@ impl SuggestStoreBuilder {
self
}
pub fn remote_settings_config(self: Arc<Self>, config: RemoteSettingsConfig) -> Arc<Self> {
self.0.lock().remote_settings_config = Some(config);
pub fn remote_settings_server(self: Arc<Self>, server: RemoteSettingsServer) -> Arc<Self> {
self.0.lock().remote_settings_server = Some(server);
self
}
pub fn remote_settings_server(self: Arc<Self>, server: RemoteSettingsServer) -> Arc<Self> {
self.0.lock().remote_settings_server = Some(server);
pub fn remote_settings_bucket_name(self: Arc<Self>, bucket_name: String) -> Arc<Self> {
self.0.lock().remote_settings_bucket_name = Some(bucket_name);
self
}
@ -79,27 +79,12 @@ impl SuggestStoreBuilder {
.data_path
.clone()
.ok_or_else(|| Error::SuggestStoreBuilder("data_path not specified".to_owned()))?;
let remote_settings_config = match (
inner.remote_settings_server.as_ref(),
inner.remote_settings_config.as_ref(),
) {
(Some(server), None) => RemoteSettingsConfig {
server: Some(server.clone()),
server_url: None,
bucket_name: None,
collection_name: REMOTE_SETTINGS_COLLECTION.into(),
},
(None, Some(remote_settings_config)) => remote_settings_config.clone(),
(None, None) => RemoteSettingsConfig {
server: None,
server_url: None,
bucket_name: None,
collection_name: REMOTE_SETTINGS_COLLECTION.into(),
},
(Some(_), Some(_)) => Err(Error::SuggestStoreBuilder(
"can't specify both `remote_settings_server` and `remote_settings_config`"
.to_owned(),
))?,
let remote_settings_config = RemoteSettingsConfig {
server: inner.remote_settings_server.clone(),
bucket_name: inner.remote_settings_bucket_name.clone(),
server_url: None,
collection_name: REMOTE_SETTINGS_COLLECTION.into(),
};
let settings_client = remote_settings::Client::new(remote_settings_config)?;
Ok(Arc::new(SuggestStore {
@ -336,6 +321,7 @@ where
S: Client,
{
pub fn ingest(&self, constraints: SuggestIngestionConstraints) -> Result<()> {
breadcrumb!("Ingestion starting");
let writer = &self.dbs()?.writer;
if constraints.empty_only && !writer.read(|dao| dao.suggestions_table_empty())? {
return Ok(());
@ -355,10 +341,12 @@ where
// Handle ingestion inside single write scope
let mut write_scope = writer.write_scope()?;
for ingest_record_type in ingest_record_types {
breadcrumb!("Ingesting {ingest_record_type}");
write_scope
.write(|dao| self.ingest_records_by_type(ingest_record_type, dao, &constraints))?;
write_scope.err_if_interrupted()?;
}
breadcrumb!("Ingestion complete");
Ok(())
}
@ -574,10 +562,21 @@ where
self.dbs().unwrap();
}
pub fn force_reingest(&self, ingest_record_type: SuggestRecordType) {
// To force a re-ingestion, we're going to ingest all records then forget the last
// ingestion time.
self.benchmark_ingest_records_by_type(ingest_record_type);
let writer = &self.dbs().unwrap().writer;
writer
.write(|dao| dao.clear_meta(ingest_record_type.last_ingest_meta_key().as_str()))
.unwrap();
}
pub fn benchmark_ingest_records_by_type(&self, ingest_record_type: SuggestRecordType) {
let writer = &self.dbs().unwrap().writer;
writer
.write(|dao| {
dao.clear_meta(ingest_record_type.last_ingest_meta_key().as_str())?;
self.ingest_records_by_type(
ingest_record_type,
dao,
@ -612,6 +611,15 @@ where
table_names_with_counts.sort_by(|a, b| (b.1.cmp(&a.1)));
table_names_with_counts
}
pub fn db_size(&self) -> usize {
use sql_support::ConnExt;
let reader = &self.dbs().unwrap().reader;
let conn = reader.conn.lock();
conn.query_one("SELECT page_size * page_count FROM pragma_page_count(), pragma_page_size()")
.unwrap()
}
}
/// Holds a store's open connections to the Suggest database.

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

@ -178,9 +178,8 @@ interface SuggestStoreBuilder {
[Self=ByArc]
SuggestStoreBuilder remote_settings_server(RemoteSettingsServer server);
// Deprecated: Use `remote_settings_server()` instead.
[Self=ByArc]
SuggestStoreBuilder remote_settings_config(RemoteSettingsConfig config);
SuggestStoreBuilder remote_settings_bucket_name(string bucket_name);
[Throws=SuggestApiError]
SuggestStore build();

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

@ -1 +1 @@
{"files":{"Cargo.toml":"5129b4a9a3c9074f32271928b342e236378d92a8c040370ca38aeb577b58ba05","README.md":"821cac7eb5b963fc3f3fe21dd890427ab2bbf335cb25cbae89b713b3350687c5","build.rs":"92f7d380f3d8fab1e6d80276915af57192e276321d132a5f800ea4520e9cb469","sql/create_schema.sql":"a17311a407ec10e033886b7125da4c8b84bc6d761f6b28edc9594de430e1d964","sql/create_sync_temp_tables.sql":"860ede362c94feb47d85522553fa2852f9bdb9f9b025d6438dd5dee3d4acd527","sql/tests/create_schema_v1.sql":"77cf0c90eaac3e1aea626537147e1b8ec349b68d6076c92fa7ae402aac613050","src/api.rs":"6fe362e4f437def2ad2249de385cca8f0d1d5d67679240351e9f57523fefe5e7","src/db.rs":"04ef67021b6aad7552a268397c7323302c4f619b3fb07fb140132beb8b37f8b5","src/error.rs":"8587813be8e2a7f5efad4216a5c4686554ed44e98cf94bfd9c2f2c9adc8e9a11","src/ffi.rs":"f66a81393bebe7a4b7e7960cb426df106ff1f02bfebcaa6e335b4b8b56c5c936","src/lib.rs":"ab25e7c6ea67fb905fe6dad866c0d2c462b1e93bcff283db947513aeabbb2d73","src/migration.rs":"8d92f82b2ba38e1039fd054c8c75078a6b896a0d3cdc1a52571456b25a32c9c3","src/schema.rs":"d8dd8f66cad71e3e369722734e0d5d16fd9423d5f6a5abba1854a27e1e814724","src/store.rs":"d208689c46fb97cd2c60a0c610ba1998a7132fb50fffa2eefa1d6b169b7c34f0","src/sync/bridge.rs":"996de05beb2904f84b3cbfc9ef85c4844078fdb4867d9068390d496156bee614","src/sync/incoming.rs":"dd77c64e2ade4f39cba258decab6d3db8ad0b5f513aa018efbd56b9869a021d9","src/sync/mod.rs":"05da064e1bc2cc449c806a534842da92d8d4b24a919f2dff2e88dc69f3e926a5","src/sync/outgoing.rs":"dacb77b956f2546fd60a89367927a199d9b662b17201d0781145f7405b61fdce","src/sync/sync_tests.rs":"f3846ca7e463315ba9788826613b987ddcff7b21672ff257a98769ee94f4191a","src/webext-storage.udl":"0341d431ba837cf64ea210ef6157010c6664a0b5a194e89acb0414938636b391","uniffi.toml":"beeec89c2f877eb89be0090dc304dbc7c74e787385e7459bad78c6165bb66791"},"package":null}
{"files":{"Cargo.toml":"14914aa0f47377f379f26cde5111d13620ac6ce588285e9791b14b196e0e408b","README.md":"821cac7eb5b963fc3f3fe21dd890427ab2bbf335cb25cbae89b713b3350687c5","build.rs":"92f7d380f3d8fab1e6d80276915af57192e276321d132a5f800ea4520e9cb469","sql/create_schema.sql":"a17311a407ec10e033886b7125da4c8b84bc6d761f6b28edc9594de430e1d964","sql/create_sync_temp_tables.sql":"860ede362c94feb47d85522553fa2852f9bdb9f9b025d6438dd5dee3d4acd527","sql/tests/create_schema_v1.sql":"77cf0c90eaac3e1aea626537147e1b8ec349b68d6076c92fa7ae402aac613050","src/api.rs":"b3f0ff950178d006e443ddbeec4513e0acaa8894211053cfdfc1de104b9fb6ab","src/db.rs":"04ef67021b6aad7552a268397c7323302c4f619b3fb07fb140132beb8b37f8b5","src/error.rs":"8587813be8e2a7f5efad4216a5c4686554ed44e98cf94bfd9c2f2c9adc8e9a11","src/ffi.rs":"f66a81393bebe7a4b7e7960cb426df106ff1f02bfebcaa6e335b4b8b56c5c936","src/lib.rs":"ab25e7c6ea67fb905fe6dad866c0d2c462b1e93bcff283db947513aeabbb2d73","src/migration.rs":"8d92f82b2ba38e1039fd054c8c75078a6b896a0d3cdc1a52571456b25a32c9c3","src/schema.rs":"d8dd8f66cad71e3e369722734e0d5d16fd9423d5f6a5abba1854a27e1e814724","src/store.rs":"d208689c46fb97cd2c60a0c610ba1998a7132fb50fffa2eefa1d6b169b7c34f0","src/sync/bridge.rs":"996de05beb2904f84b3cbfc9ef85c4844078fdb4867d9068390d496156bee614","src/sync/incoming.rs":"dd77c64e2ade4f39cba258decab6d3db8ad0b5f513aa018efbd56b9869a021d9","src/sync/mod.rs":"05da064e1bc2cc449c806a534842da92d8d4b24a919f2dff2e88dc69f3e926a5","src/sync/outgoing.rs":"dacb77b956f2546fd60a89367927a199d9b662b17201d0781145f7405b61fdce","src/sync/sync_tests.rs":"bc9845312c7b08c5efd892979f61e9385b553f872a6c5d78600f4587b14421f5","src/webext-storage.udl":"0341d431ba837cf64ea210ef6157010c6664a0b5a194e89acb0414938636b391","uniffi.toml":"beeec89c2f877eb89be0090dc304dbc7c74e787385e7459bad78c6165bb66791"},"package":null}

4
third_party/rust/webext-storage/Cargo.toml поставляемый
Просмотреть файл

@ -71,6 +71,10 @@ tempfile = "3"
version = "0.10"
default-features = false
[dev-dependencies.serde_json]
version = "1"
features = ["preserve_order"]
[dev-dependencies.sql-support]
path = "../support/sql"

2
third_party/rust/webext-storage/src/api.rs поставляемый
Просмотреть файл

@ -516,8 +516,8 @@ mod tests {
assert_eq!(
clear(&tx, ext_id)?,
make_changes(&[
("foo", Some(json!({"sub-object": "sub-value"})), None),
("other", Some(json!("also new")), None),
("foo", Some(json!({"sub-object": "sub-value"})), None),
]),
);
assert_eq!(get(&tx, ext_id, JsonValue::Null)?, json!({}));

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

@ -378,7 +378,7 @@ fn test_merged_incoming() -> Result<()> {
check_finished_with(
&tx,
"ext-id",
json!({"key1": "key1-new", "key2": "key2-incoming"}),
json!({"key2": "key2-incoming", "key1": "key1-new"}),
)?;
Ok(())
}

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

@ -705,39 +705,30 @@ export class SuggestStoreBuilder {
this[uniffiObjectPtr] = opts[constructUniffiObject];
}
/**
* An async constructor for SuggestStoreBuilder.
* A constructor for SuggestStoreBuilder.
*
* @returns {Promise<SuggestStoreBuilder>}: A promise that resolves
* to a newly constructed SuggestStoreBuilder
* @returns { SuggestStoreBuilder }
*/
static init() {
const liftResult = (result) => FfiConverterTypeSuggestStoreBuilder.lift(result);
const liftError = null;
const functionCall = () => {
return UniFFIScaffolding.callAsync(
return UniFFIScaffolding.callSync(
23, // suggest:uniffi_suggest_fn_constructor_suggeststorebuilder_new
)
}
try {
return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
} catch (error) {
return Promise.reject(error)
}}
return handleRustResult(functionCall(), liftResult, liftError);}
build() {
const liftResult = (result) => FfiConverterTypeSuggestStore.lift(result);
const liftError = (data) => FfiConverterTypeSuggestApiError.lift(data);
const functionCall = () => {
return UniFFIScaffolding.callAsync(
return UniFFIScaffolding.callSync(
24, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_build
FfiConverterTypeSuggestStoreBuilder.lower(this),
)
}
try {
return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
} catch (error) {
return Promise.reject(error)
}
return handleRustResult(functionCall(), liftResult, liftError);
}
cachePath(path) {
@ -777,42 +768,34 @@ export class SuggestStoreBuilder {
}
throw e;
}
return UniFFIScaffolding.callAsync(
return UniFFIScaffolding.callSync(
26, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_data_path
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterString.lower(path),
)
}
try {
return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
} catch (error) {
return Promise.reject(error)
}
return handleRustResult(functionCall(), liftResult, liftError);
}
remoteSettingsConfig(config) {
remoteSettingsBucketName(bucketName) {
const liftResult = (result) => FfiConverterTypeSuggestStoreBuilder.lift(result);
const liftError = null;
const functionCall = () => {
try {
FfiConverterTypeRemoteSettingsConfig.checkType(config)
FfiConverterString.checkType(bucketName)
} catch (e) {
if (e instanceof UniFFITypeError) {
e.addItemDescriptionPart("config");
e.addItemDescriptionPart("bucketName");
}
throw e;
}
return UniFFIScaffolding.callAsync(
27, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_config
return UniFFIScaffolding.callSync(
27, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterTypeRemoteSettingsConfig.lower(config),
FfiConverterString.lower(bucketName),
)
}
try {
return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
} catch (error) {
return Promise.reject(error)
}
return handleRustResult(functionCall(), liftResult, liftError);
}
remoteSettingsServer(server) {
@ -827,17 +810,13 @@ export class SuggestStoreBuilder {
}
throw e;
}
return UniFFIScaffolding.callAsync(
return UniFFIScaffolding.callSync(
28, // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server
FfiConverterTypeSuggestStoreBuilder.lower(this),
FfiConverterTypeRemoteSettingsServer.lower(server),
)
}
try {
return functionCall().then((result) => handleRustResult(result, liftResult, liftError));
} catch (error) {
return Promise.reject(error)
}
return handleRustResult(functionCall(), liftResult, liftError);
}
}

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

@ -27,6 +27,11 @@ main = [
"raw_suggestion_url_matches",
"SuggestStore",
"SuggestStore.interrupt",
"SuggestStoreBuilder",
"SuggestStoreBuilder.data_path",
"SuggestStoreBuilder.remote_settings_bucket_name",
"SuggestStoreBuilder.remote_settings_server",
"SuggestStoreBuilder.build",
]
[relevancy]

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

@ -55,7 +55,7 @@ extern "C" {
void * uniffi_suggest_fn_method_suggeststorebuilder_build(void *, RustCallStatus*);
void * uniffi_suggest_fn_method_suggeststorebuilder_cache_path(void *, RustBuffer, RustCallStatus*);
void * uniffi_suggest_fn_method_suggeststorebuilder_data_path(void *, RustBuffer, RustCallStatus*);
void * uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_config(void *, RustBuffer, RustCallStatus*);
void * uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name(void *, RustBuffer, RustCallStatus*);
void * uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server(void *, RustBuffer, RustCallStatus*);
int8_t uniffi_suggest_fn_func_raw_suggestion_url_matches(RustBuffer, RustBuffer, RustCallStatus*);
void * uniffi_tabs_fn_clone_remotecommandstore(void *, RustCallStatus*);
@ -248,9 +248,9 @@ Maybe<already_AddRefed<Promise>> UniFFICallAsync(const GlobalObject& aGlobal, ui
using CallHandler = ScaffoldingCallHandler<ScaffoldingObjectConverter<&kSuggestSuggestStoreBuilderPointerType>, ScaffoldingObjectConverter<&kSuggestSuggestStoreBuilderPointerType>, ScaffoldingConverter<RustBuffer>>;
return Some(CallHandler::CallAsync(uniffi_suggest_fn_method_suggeststorebuilder_data_path, aGlobal, aArgs, "uniffi_suggest_fn_method_suggeststorebuilder_data_path: "_ns, aError));
}
case 27: { // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_config
case 27: { // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name
using CallHandler = ScaffoldingCallHandler<ScaffoldingObjectConverter<&kSuggestSuggestStoreBuilderPointerType>, ScaffoldingObjectConverter<&kSuggestSuggestStoreBuilderPointerType>, ScaffoldingConverter<RustBuffer>>;
return Some(CallHandler::CallAsync(uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_config, aGlobal, aArgs, "uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_config: "_ns, aError));
return Some(CallHandler::CallAsync(uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name, aGlobal, aArgs, "uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name: "_ns, aError));
}
case 28: { // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server
using CallHandler = ScaffoldingCallHandler<ScaffoldingObjectConverter<&kSuggestSuggestStoreBuilderPointerType>, ScaffoldingObjectConverter<&kSuggestSuggestStoreBuilderPointerType>, ScaffoldingConverter<RustBuffer>>;
@ -509,9 +509,9 @@ bool UniFFICallSync(const GlobalObject& aGlobal, uint64_t aId, const Sequence<Un
CallHandler::CallSync(uniffi_suggest_fn_method_suggeststorebuilder_data_path, aGlobal, aArgs, aReturnValue, "uniffi_suggest_fn_method_suggeststorebuilder_data_path: "_ns, aError);
return true;
}
case 27: { // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_config
case 27: { // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name
using CallHandler = ScaffoldingCallHandler<ScaffoldingObjectConverter<&kSuggestSuggestStoreBuilderPointerType>, ScaffoldingObjectConverter<&kSuggestSuggestStoreBuilderPointerType>, ScaffoldingConverter<RustBuffer>>;
CallHandler::CallSync(uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_config, aGlobal, aArgs, aReturnValue, "uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_config: "_ns, aError);
CallHandler::CallSync(uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name, aGlobal, aArgs, aReturnValue, "uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_bucket_name: "_ns, aError);
return true;
}
case 28: { // suggest:uniffi_suggest_fn_method_suggeststorebuilder_remote_settings_server