Refactor LevelDbFileBuilder to accept DS Entity (#599)

* Refactor LevelDbFileBuilder to accept DS Entity

Builder now can directly work with Datastore Entity objects.
No need to wrap data in ComparableEntity.
This commit is contained in:
Weimin Yu
2020-05-28 13:38:00 -04:00
committed by GitHub
parent 26fb5388a4
commit 2b794347e6
8 changed files with 155 additions and 107 deletions
@@ -39,16 +39,14 @@ class CompareDbBackups {
return;
}
ImmutableSet<ComparableEntity> entities1 =
RecordAccumulator.readDirectory(new File(args[0]), DATA_FILE_MATCHER)
.getComparableEntitySet();
ImmutableSet<ComparableEntity> entities2 =
RecordAccumulator.readDirectory(new File(args[1]), DATA_FILE_MATCHER)
.getComparableEntitySet();
ImmutableSet<EntityWrapper> entities1 =
RecordAccumulator.readDirectory(new File(args[0]), DATA_FILE_MATCHER).getEntityWrapperSet();
ImmutableSet<EntityWrapper> entities2 =
RecordAccumulator.readDirectory(new File(args[1]), DATA_FILE_MATCHER).getEntityWrapperSet();
// Calculate the entities added and removed.
SetView<ComparableEntity> added = Sets.difference(entities2, entities1);
SetView<ComparableEntity> removed = Sets.difference(entities1, entities2);
SetView<EntityWrapper> added = Sets.difference(entities2, entities1);
SetView<EntityWrapper> removed = Sets.difference(entities1, entities2);
printHeader(
String.format("First backup: %d records", entities1.size()),
@@ -56,14 +54,14 @@ class CompareDbBackups {
if (!removed.isEmpty()) {
printHeader(removed.size() + " records were removed:");
for (ComparableEntity entity : removed) {
for (EntityWrapper entity : removed) {
System.out.println(entity);
}
}
if (!added.isEmpty()) {
printHeader(added.size() + " records were added:");
for (ComparableEntity entity : added) {
for (EntityWrapper entity : added) {
System.out.println(entity);
}
}
@@ -15,20 +15,32 @@
package google.registry.tools;
import com.google.appengine.api.datastore.Entity;
import com.google.auto.value.AutoValue;
import com.google.common.base.Objects;
/** Wraps {@link Entity} to do hashCode/equals based on both the entity's key and its properties. */
final class ComparableEntity {
/**
* Wraps {@link Entity} for ease of processing in collections.
*
* <p>Note that the {@link #hashCode}/{@link #equals} methods are based on both the entity's key and
* its properties.
*/
final class EntityWrapper {
private static final String TEST_ENTITY_KIND = "TestEntity";
private final Entity entity;
ComparableEntity(Entity entity) {
EntityWrapper(Entity entity) {
this.entity = entity;
}
public Entity getEntity() {
return entity;
}
@Override
public boolean equals(Object that) {
if (that instanceof ComparableEntity) {
ComparableEntity thatEntity = (ComparableEntity) that;
if (that instanceof EntityWrapper) {
EntityWrapper thatEntity = (EntityWrapper) that;
return entity.equals(thatEntity.entity)
&& entity.getProperties().equals(thatEntity.entity.getProperties());
}
@@ -43,6 +55,26 @@ final class ComparableEntity {
@Override
public String toString() {
return "ComparableEntity(" + entity + ")";
return "EntityWrapper(" + entity + ")";
}
public static EntityWrapper from(int id, Property... properties) {
Entity entity = new Entity(TEST_ENTITY_KIND, id);
for (Property prop : properties) {
entity.setProperty(prop.name(), prop.value());
}
return new EntityWrapper(entity);
}
@AutoValue
abstract static class Property {
static Property create(String name, Object value) {
return new AutoValue_EntityWrapper_Property(name, value);
}
abstract String name();
abstract Object value();
}
}
@@ -48,14 +48,14 @@ class RecordAccumulator {
return new RecordAccumulator(builder.build());
}
/** Creates an entity set from the current set of raw records. */
ImmutableSet<ComparableEntity> getComparableEntitySet() {
ImmutableSet.Builder<ComparableEntity> builder = new ImmutableSet.Builder<>();
/** Creates an {@link EntityWrapper} set from the current set of raw records. */
ImmutableSet<EntityWrapper> getEntityWrapperSet() {
ImmutableSet.Builder<EntityWrapper> builder = new ImmutableSet.Builder<>();
for (byte[] rawRecord : records) {
// Parse the entity proto and create an Entity object from it.
EntityProto proto = new EntityProto();
proto.parseFrom(rawRecord);
ComparableEntity entity = new ComparableEntity(EntityTranslator.createFromPb(proto));
EntityWrapper entity = new EntityWrapper(EntityTranslator.createFromPb(proto));
builder.add(entity);
}