Change libimag{bookmark, entrylink} external linking

...to report newly created entries, so that we can re-use these new
entries in the library-using code (for example for ID reporting).

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
Matthias Beyer 2018-10-06 13:15:29 +02:00
parent 1e6d58bf4c
commit d1f087eb57
2 changed files with 48 additions and 15 deletions

View file

@ -34,6 +34,7 @@ use libimagstore::store::Store;
use libimagstore::store::Entry; use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
use libimagstore::storeid::IntoStoreId; use libimagstore::storeid::IntoStoreId;
use libimagstore::storeid::StoreId;
use libimagentrylink::external::ExternalLinker; use libimagentrylink::external::ExternalLinker;
use libimagentrylink::external::iter::UrlIter; use libimagentrylink::external::iter::UrlIter;
use libimagentrylink::internal::InternalLinker; use libimagentrylink::internal::InternalLinker;
@ -77,9 +78,9 @@ impl<'a> BookmarkCollectionStore<'a> for Store {
pub trait BookmarkCollection : Sized + InternalLinker + ExternalLinker { pub trait BookmarkCollection : Sized + InternalLinker + ExternalLinker {
fn links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>; fn links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>;
fn link_entries(&self) -> Result<Vec<StoreLink>>; fn link_entries(&self) -> Result<Vec<StoreLink>>;
fn add_link(&mut self, store: &Store, l: Link) -> Result<()>; fn add_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>>;
fn get_links_matching<'a>(&self, store: &'a Store, r: Regex) -> Result<LinksMatchingRegexIter<'a>>; fn get_links_matching<'a>(&self, store: &'a Store, r: Regex) -> Result<LinksMatchingRegexIter<'a>>;
fn remove_link(&mut self, store: &Store, l: Link) -> Result<()>; fn remove_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>>;
} }
impl BookmarkCollection for Entry { impl BookmarkCollection for Entry {
@ -93,7 +94,7 @@ impl BookmarkCollection for Entry {
self.get_internal_links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect()) self.get_internal_links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect())
} }
fn add_link(&mut self, store: &Store, l: Link) -> Result<()> { fn add_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>> {
use link::IntoUrl; use link::IntoUrl;
l.into_url().and_then(|url| self.add_external_link(store, url)) l.into_url().and_then(|url| self.add_external_link(store, url))
} }
@ -103,7 +104,7 @@ impl BookmarkCollection for Entry {
self.get_external_links(store).map(|iter| iter.matching_regex(r)) self.get_external_links(store).map(|iter| iter.matching_regex(r))
} }
fn remove_link(&mut self, store: &Store, l: Link) -> Result<()> { fn remove_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>> {
use link::IntoUrl; use link::IntoUrl;
l.into_url().and_then(|url| self.remove_external_link(store, url)) l.into_url().and_then(|url| self.remove_external_link(store, url))
} }

View file

@ -108,13 +108,13 @@ pub trait ExternalLinker : InternalLinker {
fn get_external_links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>; fn get_external_links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>;
/// Set the external links for the implementor object /// Set the external links for the implementor object
fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()>; fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<Vec<StoreId>>;
/// Add an external link to the implementor object /// Add an external link to the implementor object
fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()>; fn add_external_link(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>>;
/// Remove an external link from the implementor object /// Remove an external link from the implementor object
fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()>; fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>>;
} }
@ -322,13 +322,20 @@ impl ExternalLinker for Entry {
} }
/// Set the external links for the implementor object /// Set the external links for the implementor object
fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()> { ///
/// # Return Value
///
/// Returns the StoreIds which were newly created for the new external links, if there are more
/// external links than before.
/// If there are less external links than before, an empty vec![] is returned.
///
fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<Vec<StoreId>> {
// Take all the links, generate a SHA sum out of each one, filter out the already existing // Take all the links, generate a SHA sum out of each one, filter out the already existing
// store entries and store the other URIs in the header of one FileLockEntry each, in // store entries and store the other URIs in the header of one FileLockEntry each, in
// the path /link/external/<SHA of the URL> // the path /link/external/<SHA of the URL>
debug!("Iterating {} links = {:?}", links.len(), links); debug!("Iterating {} links = {:?}", links.len(), links);
for link in links { // for all links links.into_iter().map(|link| {
let hash = hex::encode(Sha1::digest(&link.as_str().as_bytes())); let hash = hex::encode(Sha1::digest(&link.as_str().as_bytes()));
let file_id = let file_id =
ModuleEntryPath::new(format!("external/{}", hash)).into_storeid() ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
@ -341,6 +348,8 @@ impl ExternalLinker for Entry {
debug!("Hash = '{:?}'", hash); debug!("Hash = '{:?}'", hash);
debug!("StoreId = '{:?}'", file_id); debug!("StoreId = '{:?}'", file_id);
let link_already_exists = store.get(file_id.clone())?.is_some();
// retrieve the file from the store, which implicitely creates the entry if it does not // retrieve the file from the store, which implicitely creates the entry if it does not
// exist // exist
let mut file = store let mut file = store
@ -375,13 +384,27 @@ impl ExternalLinker for Entry {
// then add an internal link to the new file or return an error if this fails // then add an internal link to the new file or return an error if this fails
let _ = self.add_internal_link(file.deref_mut())?; let _ = self.add_internal_link(file.deref_mut())?;
debug!("Error adding internal link"); debug!("Error adding internal link");
}
debug!("Ready iterating"); Ok((link_already_exists, file_id))
Ok(()) })
.filter_map(|res| match res {
Ok((exists, entry)) => if exists { Some(Ok(entry)) } else { None },
Err(e) => Some(Err(e))
})
.collect()
} }
/// Add an external link to the implementor object /// Add an external link to the implementor object
fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()> { ///
/// # Return Value
///
/// (See ExternalLinker::set_external_links())
///
/// Returns the StoreIds which were newly created for the new external links, if there are more
/// external links than before.
/// If there are less external links than before, an empty vec![] is returned.
///
fn add_external_link(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>> {
// get external links, add this one, save them // get external links, add this one, save them
debug!("Getting links"); debug!("Getting links");
self.get_external_links(store) self.get_external_links(store)
@ -396,7 +419,16 @@ impl ExternalLinker for Entry {
} }
/// Remove an external link from the implementor object /// Remove an external link from the implementor object
fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()> { ///
/// # Return Value
///
/// (See ExternalLinker::set_external_links())
///
/// Returns the StoreIds which were newly created for the new external links, if there are more
/// external links than before.
/// If there are less external links than before, an empty vec![] is returned.
///
fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>> {
// get external links, remove this one, save them // get external links, remove this one, save them
self.get_external_links(store) self.get_external_links(store)
.and_then(|links| { .and_then(|links| {