зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
442dabe5bc
Коммит
3ef9e50dd0
|
@ -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"]
|
||||
|
|
|
@ -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",
|
||||
|
|
16
Cargo.toml
16
Cargo.toml
|
@ -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}
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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))?;
|
||||
|
|
|
@ -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}
|
|
@ -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}
|
|
@ -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!("-------------------------");
|
||||
|
|
|
@ -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,
|
||||
&.advertiser,
|
||||
amp.block_id,
|
||||
&.iab_category,
|
||||
&.impression_url,
|
||||
&.click_url,
|
||||
&.icon_id,
|
||||
))?;
|
||||
self.0
|
||||
.execute((
|
||||
suggestion_id,
|
||||
&.advertiser,
|
||||
amp.block_id,
|
||||
&.iab_category,
|
||||
&.impression_url,
|
||||
&.click_url,
|
||||
&.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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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}
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче