diff options
| author | Jesper Jensen <jesper@jnsn.dev> | 2026-02-09 17:50:36 +0100 |
|---|---|---|
| committer | Jesper Jensen <jesper@jnsn.dev> | 2026-02-09 17:50:36 +0100 |
| commit | 284165f2000ec9ad5ac0c47128ce12eae1c734ef (patch) | |
| tree | 94d1280fe83bfbe6f0a77c2c779c92652f9de52c /src/updater.rs | |
| parent | f5dd11f8b3eb9b3285fa8c58d611e2dd46d35fda (diff) | |
Nicer database interface
Right now I'm just doing loops, we we can add some batch stuff here
later
Diffstat (limited to 'src/updater.rs')
| -rw-r--r-- | src/updater.rs | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/src/updater.rs b/src/updater.rs index 9f04710..7ab6483 100644 --- a/src/updater.rs +++ b/src/updater.rs @@ -1,6 +1,6 @@ use crate::version::{VersionPattern, CompareOutcome}; use crate::docker::DockerRef; -use crate::db::{Db, Image}; +use crate::db::{Db, Image, Tag}; use crate::registry::Registries; use crate::metrics; use chrono::{DateTime, Utc}; @@ -59,21 +59,25 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil match reg.get_tags(&expired.registry, &expired.image) { Some(mut fetched_tags) => { fetched_tags.sort(); + let mut to_delete: Vec<i64> = vec![]; + let mut to_insert: Vec<Tag> = vec![]; let mut existing = cached_tags.iter().peekable(); for t in &fetched_tags { - while existing.peek().is_some_and(|e| *e < t) { + while existing.peek().is_some_and(|e| e.tag.as_str() < t.as_str()) { let gone = existing.next().unwrap(); - db.delete_tag(expired.id, gone); + to_delete.push(gone.id); } - if existing.peek() == Some(&t) { + if existing.peek().is_some_and(|e| e.tag.as_str() == t.as_str()) { existing.next(); } else { - db.insert_tag(expired.id, t); + to_insert.push(Tag { id: 0, image_id: expired.id, tag: t.clone(), digest: None }); } } for gone in existing { - db.delete_tag(expired.id, gone); + to_delete.push(gone.id); } + db.delete_tags(&to_delete); + db.insert_tags(&mut to_insert); let new_expires_at = *now + cache_max_age; db.set_expires_at(expired.id, &new_expires_at); } @@ -117,12 +121,12 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil let mut current = VersionPattern::parse(&tag_str); let mut new_tag = None; - for candidate_str in &tags { - let candidate = VersionPattern::parse(&candidate_str); - match current.compare(&candidate) { + for candidate in &tags { + let candidate_pattern = VersionPattern::parse(&candidate.tag); + match current.compare(&candidate_pattern) { CompareOutcome::Higher => { - new_tag = Some(candidate_str.clone()); - current = candidate; + new_tag = Some(candidate.tag.clone()); + current = candidate_pattern; }, CompareOutcome::Lower => {}, CompareOutcome::Incompatible => {}, @@ -143,7 +147,7 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil if let Some(ref digest) = img.digest { let tag_for_digest = tag.as_deref().unwrap_or("latest"); let cached_digest = if image_record.expires_at > *now { - db.get_tag_digest(image_record.id, tag_for_digest) + tags.iter().find(|t| t.tag == tag_for_digest).and_then(|t| t.digest.clone()) } else { None }; @@ -153,7 +157,10 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil None => { match reg.get_digest(&image_record.registry, &image_record.image, tag_for_digest) { Some(fetched) => { - db.update_tag_digest(image_record.id, tag_for_digest, &fetched); + if let Some(mut tag_record) = tags.iter().find(|t| t.tag == tag_for_digest).cloned() { + tag_record.digest = Some(fetched.clone()); + db.update_tags(&[tag_record]); + } Ok(fetched) } None => Err(format!("digest not found for {}:{}", image_record.image, tag_for_digest)), @@ -210,8 +217,10 @@ mod tests { let past_expiry = now - chrono::Duration::days(1); let mut img = Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: past_expiry }; db.insert_image(&mut img); - db.insert_tag(img.id, "1.20"); - db.insert_tag(img.id, "1.21"); + db.insert_tags(&mut [ + Tag { id: 0, image_id: img.id, tag: "1.20".into(), digest: None }, + Tag { id: 0, image_id: img.id, tag: "1.21".into(), digest: None }, + ]); let files = vec![FileInput { path: "/test".into(), @@ -221,7 +230,8 @@ mod tests { let mut outcomes = vec![]; update_images(&now, &db, ®, &files, &mut outcomes); - assert_eq!(db.get_tags_sorted(img.id), vec!["1.21", "1.22"]); + let tags: Vec<String> = db.get_tags_sorted(img.id).into_iter().map(|t| t.tag).collect(); + assert_eq!(tags, vec!["1.21", "1.22"]); let got = db.get_image("registry.hub.docker.com", "nginx").unwrap(); assert!(got.expires_at > now); } @@ -236,7 +246,7 @@ mod tests { let future_expiry = now + chrono::Duration::minutes(30); let mut img = Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: future_expiry }; db.insert_image(&mut img); - db.insert_tag(img.id, "1.21"); + db.insert_tags(&mut [Tag { id: 0, image_id: img.id, tag: "1.21".into(), digest: None }]); let files = vec![FileInput { path: "/test".into(), @@ -344,8 +354,7 @@ mod tests { let future_expiry = now + chrono::Duration::minutes(30); let mut img = Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: future_expiry }; db.insert_image(&mut img); - db.insert_tag(img.id, "1.21"); - db.update_tag_digest(img.id, "1.21", "sha256:0000000000000000000000000000000000000000000000000000000000000003"); + db.insert_tags(&mut [Tag { id: 0, image_id: img.id, tag: "1.21".into(), digest: Some("sha256:0000000000000000000000000000000000000000000000000000000000000003".into()) }]); let files = vec![FileInput { path: "/test".into(), @@ -578,8 +587,7 @@ mod tests { let past_expiry = now - chrono::Duration::days(1); let mut img = Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: past_expiry }; db.insert_image(&mut img); - db.insert_tag(img.id, "1.21"); - db.update_tag_digest(img.id, "1.21", "sha256:0000000000000000000000000000000000000000000000000000000000000003"); + db.insert_tags(&mut [Tag { id: 0, image_id: img.id, tag: "1.21".into(), digest: Some("sha256:0000000000000000000000000000000000000000000000000000000000000003".into()) }]); let files = vec![FileInput { path: "/test".into(), @@ -614,7 +622,8 @@ mod tests { assert!(outcomes[0].is_err()); assert!(db.get_image("registry.hub.docker.com", "redis").is_some()); // Redis tags ARE populated (cache refresh happens before processing), but no patches are produced - assert_eq!(db.get_tags_sorted(2), vec!["6.0", "6.2"]); + let tags: Vec<String> = db.get_tags_sorted(2).into_iter().map(|t| t.tag).collect(); + assert_eq!(tags, vec!["6.0", "6.2"]); } #[test] |
