package com.googlecode.objectify.test;
import com.google.appengine.api.datastore.EmbeddedEntity;
import com.google.appengine.api.datastore.Entity;
import com.google.common.collect.Lists;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Cache;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.test.util.TestBase;
import org.testng.annotations.Test;
import java.util.Collections;
import java.util.List;
import static com.googlecode.objectify.test.util.TestObjectifyService.ds;
import static com.googlecode.objectify.test.util.TestObjectifyService.fact;
import static com.googlecode.objectify.test.util.TestObjectifyService.ofy;
/**
*/
public class EmbeddingFormatTests extends TestBase
{
/** */
public static class Inner {
String stuff;
public Inner() { }
public Inner(String stuff) {
this.stuff = stuff;
}
}
/** */
@com.googlecode.objectify.annotation.Entity
@Cache
public static class Outer {
@Id Long id;
Inner inner;
public Outer() { }
public Outer(Inner inner) {
this.inner = inner;
}
}
/** */
@Test
public void simpleOneLayerEmbedding() throws Exception {
fact().register(Outer.class);
Inner inner = new Inner("stuff");
Outer outer = new Outer(inner);
Key<Outer> key = ofy().save().entity(outer).now();
Entity entity = ds().get(key.getRaw());
EmbeddedEntity entityInner = (EmbeddedEntity)entity.getProperty("inner");
assert entityInner.getProperty("stuff").equals("stuff");
ofy().clear();
Outer fetched = ofy().load().key(key).now();
assert fetched.inner.stuff.equals(inner.stuff);
}
/** */
@com.googlecode.objectify.annotation.Entity
@Cache
public static class OuterWithList {
@Id Long id;
List<Inner> inner = Lists.newArrayList();
public OuterWithList() { }
}
/** */
@Test
public void embeddedList() throws Exception {
fact().register(OuterWithList.class);
OuterWithList outer = new OuterWithList();
outer.inner.add(new Inner("stuff0"));
outer.inner.add(new Inner("stuff1"));
Key<OuterWithList> key = ofy().save().entity(outer).now();
Entity entity = ds().get(key.getRaw());
@SuppressWarnings("unchecked")
List<EmbeddedEntity> entityInner = (List<EmbeddedEntity>)entity.getProperty("inner");
assert entityInner.size() == 2;
assert entityInner.get(0).getProperty("stuff").equals("stuff0");
assert entityInner.get(1).getProperty("stuff").equals("stuff1");
ofy().clear();
OuterWithList fetched = ofy().load().key(key).now();
assert fetched.inner.get(0).stuff.equals(outer.inner.get(0).stuff);
assert fetched.inner.get(1).stuff.equals(outer.inner.get(1).stuff);
}
/** */
@com.googlecode.objectify.annotation.Entity
@Cache
public static class HasEmbeddedEntity {
@Id Long id;
EmbeddedEntity normal;
public HasEmbeddedEntity() { }
}
/** */
@Test
public void normalEmbeddedEntityFieldWorksFine() throws Exception {
fact().register(HasEmbeddedEntity.class);
HasEmbeddedEntity h = new HasEmbeddedEntity();
h.normal = new EmbeddedEntity();
h.normal.setProperty("stuff", "stuff");
HasEmbeddedEntity fetched = ofy().saveClearLoad(h);
assert fetched.normal.getProperty("stuff").equals("stuff");
}
/** */
@com.googlecode.objectify.annotation.Entity
@Cache
public static class HasEmbeddedEntityList {
@Id Long id;
List<EmbeddedEntity> list = Lists.newArrayList();
public HasEmbeddedEntityList() { }
}
/** */
@Test
public void listEmbeddedEntityFieldWorksFine() throws Exception {
fact().register(HasEmbeddedEntityList.class);
HasEmbeddedEntityList h = new HasEmbeddedEntityList();
EmbeddedEntity emb0 = new EmbeddedEntity();
emb0.setProperty("stuff", "stuff0");
h.list.add(emb0);
HasEmbeddedEntityList fetched = ofy().saveClearLoad(h);
assert fetched.list.size() == 1;
assert fetched.list.get(0).getProperty("stuff").equals("stuff0");
}
/** */
public static class InnerIndexed {
@Index String stuff;
public InnerIndexed() { }
public InnerIndexed(String stuff) {
this.stuff = stuff;
}
}
/** */
@com.googlecode.objectify.annotation.Entity
@Cache
public static class OuterWithIndex {
@Id Long id;
InnerIndexed inner;
public OuterWithIndex() { }
public OuterWithIndex(InnerIndexed inner) {
this.inner = inner;
}
}
/** */
@Test
public void indexFormatIsCorrect() throws Exception {
fact().register(OuterWithIndex.class);
InnerIndexed inner = new InnerIndexed("stuff");
OuterWithIndex outer = new OuterWithIndex(inner);
Key<OuterWithIndex> key = ofy().save().entity(outer).now();
Entity entity = ds().get(key.getRaw());
assert entity.getProperties().size() == 2;
assert entity.getProperty("inner.stuff").equals(Collections.singletonList("stuff"));
assert !entity.isUnindexedProperty("inner.stuff");
ofy().clear();
OuterWithIndex fetched = ofy().load().type(OuterWithIndex.class).filter("inner.stuff", "stuff").iterator().next();
assert fetched.inner.stuff.equals(inner.stuff);
}
/** */
@Test
public void batchSaveDoesNotCrossContaminateIndexes() throws Exception {
fact().register(OuterWithIndex.class);
InnerIndexed inner0 = new InnerIndexed("stuff0");
OuterWithIndex outer0 = new OuterWithIndex(inner0);
InnerIndexed inner1 = new InnerIndexed("stuff1");
OuterWithIndex outer1 = new OuterWithIndex(inner1);
ofy().save().entities(outer0, outer1).now();
ofy().clear();
List<OuterWithIndex> fetched = ofy().load().type(OuterWithIndex.class).filter("inner.stuff", inner0.stuff).list();
assert fetched.size() == 1;
assert fetched.get(0).inner.stuff.equals(inner0.stuff);
}
}