summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-02-06 18:03:49 +0200
committerLars Wirzenius <liw@liw.fi>2021-02-06 18:10:47 +0200
commit534ad38e3aae8354bd6ede94fe7b1b7259a598ec (patch)
tree5c2ebcb90c80dcb118d7c15ec7fe9aae17cff7f2
parent375d05a8492c391b229b65a8752c4151ffd5bb20 (diff)
downloadobnam2-534ad38e3aae8354bd6ede94fe7b1b7259a598ec.tar.gz
feat: method for listing ids of chunks from file data
This will be useful soon, to enable us to check how many chunks from file data there is in the repository, to check that an upcoming chunk size setting works. Also add an API call for returning the ids. Note that all of this is meant for testing only. It may be best to disable it in production builds, eventually.
-rw-r--r--src/bin/obnam-server.rs2
-rw-r--r--src/index.rs15
-rw-r--r--src/indexedstore.rs28
3 files changed, 44 insertions, 1 deletions
diff --git a/src/bin/obnam-server.rs b/src/bin/obnam-server.rs
index 19f2e99..0e9d4e6 100644
--- a/src/bin/obnam-server.rs
+++ b/src/bin/obnam-server.rs
@@ -188,6 +188,8 @@ pub async fn search_chunks(
}
if key == "generation" && value == "true" {
store.find_generations().expect("SQL lookup failed")
+ } else if key == "data" && value == "true" {
+ store.find_file_chunks().expect("SQL lookup failed")
} else if key == "sha256" {
store.find_by_sha256(value).expect("SQL lookup failed")
} else {
diff --git a/src/index.rs b/src/index.rs
index f7300da..9386e73 100644
--- a/src/index.rs
+++ b/src/index.rs
@@ -75,6 +75,10 @@ impl Index {
pub fn find_generations(&self) -> IndexResult<Vec<ChunkId>> {
sql::find_generations(&self.conn)
}
+
+ pub fn all_chunks(&self) -> IndexResult<Vec<ChunkId>> {
+ sql::find_chunk_ids(&self.conn)
+ }
}
#[cfg(test)]
@@ -243,6 +247,17 @@ mod sql {
Ok(ids)
}
+ pub fn find_chunk_ids(conn: &Connection) -> IndexResult<Vec<ChunkId>> {
+ let mut stmt = conn.prepare("SELECT id FROM chunks WHERE generation IS 0")?;
+ let iter = stmt.query_map(params![], |row| row_to_id(row))?;
+ let mut ids = vec![];
+ for x in iter {
+ let x = x?;
+ ids.push(x);
+ }
+ Ok(ids)
+ }
+
fn row_to_meta(row: &Row) -> rusqlite::Result<ChunkMeta> {
let sha256: String = row.get(row.column_index("sha256")?)?;
let generation: i32 = row.get(row.column_index("generation")?)?;
diff --git a/src/indexedstore.rs b/src/indexedstore.rs
index 3f347dd..f2d1831 100644
--- a/src/indexedstore.rs
+++ b/src/indexedstore.rs
@@ -1,8 +1,9 @@
-use crate::chunk::DataChunk;
+use crate::chunk::{DataChunk, GenerationChunk, GenerationChunkError};
use crate::chunkid::ChunkId;
use crate::chunkmeta::ChunkMeta;
use crate::index::{Index, IndexError};
use crate::store::{Store, StoreError};
+use std::collections::HashSet;
use std::path::Path;
/// A store for chunks and their metadata.
@@ -21,6 +22,9 @@ pub enum IndexedError {
#[error(transparent)]
IndexError(#[from] IndexError),
+ #[error(transparent)]
+ GenerationChunkError(#[from] GenerationChunkError),
+
/// An error from Store.
#[error(transparent)]
SqlError(#[from] StoreError),
@@ -64,6 +68,28 @@ impl IndexedStore {
Ok(self.index.find_generations()?)
}
+ pub fn find_file_chunks(&self) -> IndexedResult<Vec<ChunkId>> {
+ let gen_ids = self.find_generations()?;
+
+ let mut sql_chunks: HashSet<ChunkId> = HashSet::new();
+ for id in gen_ids {
+ let gen_chunk = self.store.load(&id)?;
+ let gen = GenerationChunk::from_data_chunk(&gen_chunk)?;
+ for sqlite_chunk_id in gen.chunk_ids() {
+ sql_chunks.insert(sqlite_chunk_id.clone());
+ }
+ }
+
+ let all_chunk_ids = self.index.all_chunks()?;
+ let file_chunks = all_chunk_ids
+ .iter()
+ .filter(|id| !sql_chunks.contains(id))
+ .map(|id| id.clone())
+ .collect();
+
+ Ok(file_chunks)
+ }
+
pub fn remove(&mut self, id: &ChunkId) -> IndexedResult<()> {
self.index.remove_meta(id)?;
self.store.delete(id)?;