summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)?;