Skip to content

Commit

Permalink
#102 WIP migrations
Browse files Browse the repository at this point in the history
  • Loading branch information
joepio committed Apr 15, 2022
1 parent b5bc904 commit b46eae5
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
15 changes: 6 additions & 9 deletions lib/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use self::query_index::{
update_indexed_member, watch_collection, IndexAtom, QueryFilter, END_CHAR,
};

mod migrations;
mod query_index;
#[cfg(test)]
pub mod test;
Expand All @@ -47,7 +48,7 @@ pub struct Db {
/// Try not to use this directly, but use the Trees.
db: sled::Db,
default_agent: Arc<Mutex<Option<crate::agents::Agent>>>,
/// Stores all resources. The Key is the Subject as a string, the value a [PropVals]. Both must be serialized using bincode.
/// Stores all resources. The Key is the Subject as a `string.as_bytes()`, the value a [PropVals]. Propvals must be serialized using [bincode].
resources: sled::Tree,
/// Index for all AtommicURLs, indexed by their Value. Used to speed up TPF queries. See [key_for_reference_index]
reference_index: sled::Tree,
Expand Down Expand Up @@ -107,20 +108,17 @@ impl Db {
#[instrument(skip(self))]
fn set_propvals(&self, subject: &str, propvals: &PropVals) -> AtomicResult<()> {
let resource_bin = bincode::serialize(propvals)?;
let subject_bin = bincode::serialize(subject)?;
self.resources.insert(subject_bin, resource_bin)?;
self.resources.insert(subject.as_bytes(), resource_bin)?;
Ok(())
}

/// Finds resource by Subject, return PropVals HashMap
/// Deals with the binary API of Sled
#[instrument(skip(self))]
fn get_propvals(&self, subject: &str) -> AtomicResult<PropVals> {
let subject_binary = bincode::serialize(subject)
.map_err(|e| format!("Can't serialize {}: {}", subject, e))?;
let propval_maybe = self
.resources
.get(subject_binary)
.get(subject.as_bytes())
.map_err(|e| format!("Can't open {} from store: {}", subject, e))?;
match propval_maybe.as_ref() {
Some(binpropval) => {
Expand Down Expand Up @@ -473,7 +471,7 @@ impl Storelike for Db {
.expect("No self URL set, is required in DB");
for item in self.resources.into_iter() {
let (subject, resource_bin) = item.expect(DB_CORRUPT_MSG);
let subject: String = bincode::deserialize(&subject).expect(DB_CORRUPT_MSG);
let subject: String = String::from_utf8_lossy(&subject).to_string();
if !include_external && !subject.starts_with(&self_url) {
continue;
}
Expand Down Expand Up @@ -508,8 +506,7 @@ impl Storelike for Db {
let remove_atom = crate::Atom::new(subject.into(), prop.clone(), val.clone());
self.remove_atom_from_index(&remove_atom, &resource)?;
}
let binary_subject = bincode::serialize(subject)?;
let _found = self.resources.remove(&binary_subject)?;
let _found = self.resources.remove(&subject.as_bytes())?;
} else {
return Err(format!(
"Resource {} could not be deleted, because it was not found in the store.",
Expand Down
20 changes: 20 additions & 0 deletions lib/src/db/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*!
# Migrations
Whenever the schema of the database changes, a newer version will not be able to read an older database.
Therefore, we need migrations to convert the old schema to the new one.
*/

use crate::{errors::AtomicResult, Db};

// Change the subjects from `bincode` to `.as_bytes()`
fn v0_to_v1(store: &mut Db) -> AtomicResult<()> {
let new = store.db.open_tree("resources_new")?;
for item in store.resources.into_iter() {
let (subject, resource_bin) = item.expect("Unable to perform migration");
let subject: String =
bincode::deserialize(&subject).expect("Unable to deserialize subject");
new.insert(subject.as_bytes(), resource_bin)?;
}
Ok(())
}

0 comments on commit b46eae5

Please sign in to comment.