Verify genuine Google music constraints and separate metadata cache revisions

This commit is contained in:
karl committed 2026-10-13 18:42:28 +02:00
1 parent b002399217
commit ce642f1594
7 files changed
+339 -12

No files matched your search

+40 -9
View File
@@ -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());