Add local CAS pin metadata

This commit is contained in:
Eric Wendland 2026-05-16 16:36:35 +02:00
commit 00471bcec0
9 changed files with 169 additions and 16 deletions

View file

@ -250,6 +250,43 @@ impl Store {
.map_err(StoreError::from)
}
pub fn pin_cas_object(&self, hash: &str) -> Result<(), StoreError> {
self.conn.execute(
"INSERT OR REPLACE INTO cas_pins(hash, pinned_at_ms) VALUES (?1, ?2)",
params![hash, now_ms()],
)?;
Ok(())
}
pub fn unpin_cas_object(&self, hash: &str) -> Result<(), StoreError> {
self.conn
.execute("DELETE FROM cas_pins WHERE hash = ?1", params![hash])?;
Ok(())
}
pub fn is_cas_object_pinned(&self, hash: &str) -> Result<bool, StoreError> {
let count: i64 = self.conn.query_row(
"SELECT COUNT(*) FROM cas_pins WHERE hash = ?1",
params![hash],
|row| row.get(0),
)?;
Ok(count > 0)
}
pub fn list_cas_pins(&self) -> Result<Vec<CasPin>, StoreError> {
let mut stmt = self
.conn
.prepare("SELECT hash, pinned_at_ms FROM cas_pins ORDER BY pinned_at_ms, hash")?;
let rows = stmt.query_map([], |row| {
Ok(CasPin {
hash: row.get(0)?,
pinned_at_ms: row.get(1)?,
})
})?;
rows.collect::<Result<Vec<_>, _>>()
.map_err(StoreError::from)
}
pub fn upsert_peer_card(&self, peer_card: &StoredPeerCard) -> Result<(), StoreError> {
self.conn.execute(
"INSERT OR REPLACE INTO peer_cards(peer_id, card_json, updated_at_ms) VALUES (?1, ?2, ?3)",
@ -523,6 +560,12 @@ pub struct CasObject {
pub path: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CasPin {
pub hash: String,
pub pinned_at_ms: i64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct StoredPeerCard {
pub peer_id: String,
@ -708,4 +751,18 @@ mod tests {
vec![first, second]
);
}
#[test]
fn cas_pins_roundtrip() {
let store = Store::open_memory().expect("open");
let hash = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
assert!(!store.is_cas_object_pinned(hash).expect("unpinned"));
store.pin_cas_object(hash).expect("pin");
assert!(store.is_cas_object_pinned(hash).expect("pinned"));
assert_eq!(store.list_cas_pins().expect("pins").len(), 1);
store.unpin_cas_object(hash).expect("unpin");
assert!(!store.is_cas_object_pinned(hash).expect("unpinned again"));
assert!(store.list_cas_pins().expect("pins").is_empty());
}
}