When removing a key that does exist then an updated GitDbBranch is returned
This commit is contained in:
parent
50a304a941
commit
d6f8bcbc0f
5 changed files with 160 additions and 5 deletions
|
@ -46,7 +46,7 @@ public interface GitDBBranch {
|
|||
* @param key the key to place the value under
|
||||
* @param value the value (must be Serializable)
|
||||
* @return an updated branch containing the new key/value
|
||||
* @throws IOException if there was an error writing the value
|
||||
* @throws IOException if there was an error writing the key/value
|
||||
*/
|
||||
GitDBBranch put(String key, String value) throws IOException;
|
||||
|
||||
|
@ -55,6 +55,7 @@ public interface GitDBBranch {
|
|||
*
|
||||
* @param key the key to remove
|
||||
* @return an updated branch without the key, or the original if the key was not found
|
||||
* @throws IOException if there was an error removing the key/value
|
||||
*/
|
||||
GitDBBranch remove(String key);
|
||||
GitDBBranch remove(String key) throws IOException;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,17 @@ class GitDBBranchImpl implements GitDBBranch {
|
|||
}
|
||||
|
||||
@Override
|
||||
public GitDBBranch remove(final String key) {
|
||||
public GitDBBranch remove(final String key) throws IOException {
|
||||
final Optional<ObjectId> newTree = gitDBRepo.removeKey(branchRef, KEY_PREFIX + key);
|
||||
if (newTree.isPresent()) {
|
||||
final Ref newBranch =
|
||||
gitDBRepo.writeCommit(
|
||||
branchRef, newTree.get(),
|
||||
commitMessageForRemove(key),
|
||||
userName,
|
||||
userEmailAddress);
|
||||
return select(newBranch, gitDBRepo, userName, userEmailAddress);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -93,4 +103,8 @@ class GitDBBranchImpl implements GitDBBranch {
|
|||
return String.format("Add key [%s] = [%s]", key, value);
|
||||
}
|
||||
|
||||
private String commitMessageForRemove(final String key) {
|
||||
return String.format("Remove Key [%s]", key);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class GitDBRepo {
|
|||
private final ValueWriter valueWriter;
|
||||
private final KeyWriter keyWriter;
|
||||
private final CommitWriter commitWriter;
|
||||
private final KeyRemover keyRemover;
|
||||
|
||||
/**
|
||||
* Creates a new instance of this class.
|
||||
|
@ -52,6 +53,7 @@ class GitDBRepo {
|
|||
valueWriter = new ValueWriter(repository);
|
||||
keyWriter = new KeyWriter(repository);
|
||||
commitWriter = new CommitWriter(repository);
|
||||
keyRemover = new KeyRemover(repository);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,11 +159,11 @@ class GitDBRepo {
|
|||
/**
|
||||
* Add the key/value to the repo, returning the tree containing the update.
|
||||
*
|
||||
* <p>N.B. this creates a tree that has not been committed remains unaware of the update.</p>
|
||||
* <p>N.B. this creates a tree that has not been committed, the branch remains unaware of the update.</p>
|
||||
*
|
||||
* @param branchRef the branch to start from
|
||||
* @param key the key to place the value under
|
||||
* @param value the value (must be Serializable)
|
||||
* @param value the value
|
||||
* @return the id of the updated tree containing the update
|
||||
* @throws IOException if there was an error writing the value
|
||||
*/
|
||||
|
@ -210,4 +212,19 @@ class GitDBRepo {
|
|||
) throws IOException {
|
||||
return commitWriter.write(treeId, ObjectId.zeroId(), initMessage, initUser, initEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the key from the branch, returning the tree containing the update.
|
||||
*
|
||||
* <p>N.B. this creates a tree that has not been committed, the branch remains unaware of the update.</p>
|
||||
*
|
||||
* @param branchRef the branch to start from
|
||||
* @param key the key to place the value under
|
||||
* @return an Optional containing the id of the updated tree containing the update, if the key was found, or an
|
||||
* empty Optional if there key was not found, the there was no changes made
|
||||
* @throws IOException if there was an error writing the value
|
||||
*/
|
||||
Optional<ObjectId> removeKey(final Ref branchRef, final String key) throws IOException {
|
||||
return keyRemover.remove(branchRef, key);
|
||||
}
|
||||
}
|
||||
|
|
113
src/main/java/net/kemitix/gitdb/impl/KeyRemover.java
Normal file
113
src/main/java/net/kemitix/gitdb/impl/KeyRemover.java
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Paul Campbell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies
|
||||
or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
||||
AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package net.kemitix.gitdb.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.TreeFormatter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Remove Key from the Git Repository.
|
||||
*
|
||||
* @author Paul Campbell (pcampbell@kemitix.net)
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
class KeyRemover {
|
||||
|
||||
private final Repository repository;
|
||||
|
||||
/**
|
||||
* Sets the boolean to true if the key matches a NamedRevBlob's name.
|
||||
*
|
||||
* @param key the key to match
|
||||
* @param removed the boolean to update
|
||||
* @return a Consumer
|
||||
*/
|
||||
private static Consumer<GitTreeReader.NamedRevBlob> flagIfFound(final String key, final AtomicBoolean removed) {
|
||||
return nvb -> {
|
||||
if (nvb.getName().equals(key)) {
|
||||
removed.set(true);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to exclude named blobs where the name matches the key.
|
||||
*
|
||||
* @param key the key to match
|
||||
* @return a Predicate
|
||||
*/
|
||||
private static Predicate<GitTreeReader.NamedRevBlob> isNotKey(final String key) {
|
||||
return item -> !item.getName().equals(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the named value blob to the tree formatter.
|
||||
*
|
||||
* @param treeFormatter the tree formatter to add to
|
||||
* @return a Consumer
|
||||
*/
|
||||
private static Consumer<GitTreeReader.NamedRevBlob> addToTree(final TreeFormatter treeFormatter) {
|
||||
return item -> treeFormatter.append(item.getName(), item.getRevBlob());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a key from the repository.
|
||||
*
|
||||
* @param branchRef the branch to update
|
||||
* @param key the key to remove
|
||||
* @return the id of the updated tree
|
||||
* @throws IOException if there is an error writing the value
|
||||
*/
|
||||
Optional<ObjectId> remove(final Ref branchRef, final String key) throws IOException {
|
||||
final TreeFormatter treeFormatter = new TreeFormatter();
|
||||
final AtomicBoolean removed = new AtomicBoolean(false);
|
||||
new GitTreeReader(repository)
|
||||
.stream(branchRef)
|
||||
.peek(flagIfFound(key, removed))
|
||||
.filter(isNotKey(key))
|
||||
.forEach(addToTree(treeFormatter));
|
||||
if (removed.get()) {
|
||||
return Optional.of(insertTree(treeFormatter));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a tree into the repo, returning its id.
|
||||
*
|
||||
* @param treeFormatter the formatter containing the proposed tree's data.
|
||||
* @return the name of the tree object.
|
||||
* @throws IOException the object could not be stored.
|
||||
*/
|
||||
private ObjectId insertTree(final TreeFormatter treeFormatter) throws IOException {
|
||||
return repository.getObjectDatabase().newInserter().insert(treeFormatter);
|
||||
}
|
||||
}
|
|
@ -249,6 +249,16 @@ class GitDBTest implements WithAssertions {
|
|||
}
|
||||
|
||||
// When removing a key that does exist then a GitDbBranch is returned
|
||||
@Test
|
||||
void removeKey_whenExists_thenReturnUpdatedBranch() throws IOException {
|
||||
//given
|
||||
final GitDBBranch originalBranch = gitDBBranch().put("key-name", "value");
|
||||
//when
|
||||
final GitDBBranch updatedBranch = originalBranch.remove("key-name");
|
||||
//then
|
||||
assertThat(updatedBranch).isNotSameAs(originalBranch);
|
||||
}
|
||||
|
||||
// When removing a key that does exist then original GitDbBranch can still find it
|
||||
// When removing a key that does exist then the updated GitDbBranch can't find it
|
||||
|
||||
|
|
Loading…
Reference in a new issue