Verify genuine Google music constraints and separate metadata cache revisions
This commit is contained in:
1 parent
b002399217
commit
ce642f1594
7 files changed
+339
-12
No files matched your search
@@ -33,6 +33,7 @@ struct FilterKey {
|
||||
code_only: bool,
|
||||
media_artist: Option<String>,
|
||||
media_title: Option<String>,
|
||||
metadata_revision: i64,
|
||||
}
|
||||
|
||||
struct EligibilityCache {
|
||||
@@ -186,16 +187,18 @@ impl Store {
|
||||
}
|
||||
}
|
||||
initialization.execute_batch("CREATE TABLE IF NOT EXISTS semantic_media_errors(generation INTEGER NOT NULL REFERENCES semantic_generations(id) ON DELETE CASCADE,path TEXT NOT NULL,message TEXT NOT NULL,PRIMARY KEY(generation,path))")?;
|
||||
// Metadata-only writes change strict eligibility even when file bytes do not change.
|
||||
for (name, event, row) in [
|
||||
("insert", "INSERT", "new"),
|
||||
("update", "UPDATE", "new"),
|
||||
("delete", "DELETE", "old"),
|
||||
// Probe publication changes filter eligibility, not source discovery identity.
|
||||
// Keep its epoch separate so indexing does not invalidate its own corpus snapshot.
|
||||
initialization.execute_batch("CREATE TABLE IF NOT EXISTS semantic_media_metadata_revision(singleton INTEGER PRIMARY KEY CHECK(singleton=1), revision INTEGER NOT NULL);
|
||||
INSERT OR IGNORE INTO semantic_media_metadata_revision(singleton,revision) VALUES(1,0);")?;
|
||||
for (name, event) in [
|
||||
("insert", "INSERT"),
|
||||
("update", "UPDATE"),
|
||||
("delete", "DELETE"),
|
||||
] {
|
||||
initialization.execute_batch(&format!("CREATE TRIGGER IF NOT EXISTS semantic_media_metadata_{name} AFTER {event} ON media_metadata BEGIN
|
||||
UPDATE semantic_meta SET corpus_revision=corpus_revision+1 WHERE singleton=1;
|
||||
INSERT INTO semantic_dirty_paths(path,revision) VALUES({row}.path,(SELECT corpus_revision FROM semantic_meta WHERE singleton=1))
|
||||
ON CONFLICT(path) DO UPDATE SET revision=excluded.revision; END;"))?;
|
||||
initialization.execute_batch(&format!("DROP TRIGGER IF EXISTS semantic_media_metadata_{name};
|
||||
CREATE TRIGGER semantic_media_metadata_{name} AFTER {event} ON media_metadata BEGIN
|
||||
UPDATE semantic_media_metadata_revision SET revision=revision+1 WHERE singleton=1; END;"))?;
|
||||
}
|
||||
incremental::migrate(&initialization)?;
|
||||
initialization.commit()?;
|
||||
@@ -646,6 +649,19 @@ impl Store {
|
||||
.map(|ext| ext.trim_start_matches('.').to_ascii_lowercase());
|
||||
let min_size = options.min_size.map(i64::try_from).transpose()?;
|
||||
let max_size = options.max_size.map(i64::try_from).transpose()?;
|
||||
let metadata_revision = if options.media_artist.is_some()
|
||||
|| options.media_title.is_some()
|
||||
|| options.min_duration_ms.is_some()
|
||||
|| options.max_duration_ms.is_some()
|
||||
{
|
||||
snapshot.query_row(
|
||||
"SELECT revision FROM semantic_media_metadata_revision WHERE singleton=1",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let filter = FilterKey {
|
||||
folder,
|
||||
extension,
|
||||
@@ -667,6 +683,7 @@ impl Store {
|
||||
.as_deref()
|
||||
.map(searchi_core::normalize_media_field)
|
||||
.transpose()?,
|
||||
metadata_revision,
|
||||
};
|
||||
trace.end(filter_span, Default::default());
|
||||
let eligibility_span = trace.begin("semantic.eligibility", parent);
|
||||
@@ -1403,6 +1420,11 @@ mod tests {
|
||||
.len(),
|
||||
1
|
||||
);
|
||||
let corpus_before: i64 = store.connection.query_row(
|
||||
"SELECT corpus_revision FROM semantic_meta WHERE singleton=1",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
tags.insert("artist".into(), "Replacement".into());
|
||||
lexical.set_structured_media_metadata_at_revision(
|
||||
&path,
|
||||
@@ -1412,6 +1434,15 @@ mod tests {
|
||||
identity.modified_ns,
|
||||
revision,
|
||||
)?;
|
||||
let corpus_after: i64 = store.connection.query_row(
|
||||
"SELECT corpus_revision FROM semantic_meta WHERE singleton=1",
|
||||
[],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
assert_eq!(
|
||||
corpus_before, corpus_after,
|
||||
"Probe publication must not invalidate source discovery"
|
||||
);
|
||||
assert!(store
|
||||
.search(&vector, "metadata-filter-proof", 1, &options)?
|
||||
.is_empty());
|
||||
|
||||
Reference in new issue
Block a user