package er.neo4jadaptor.test;
import junit.framework.TestCase;
import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.eocontrol.EOFetchSpecification;
import com.webobjects.eocontrol.EOQualifier;
import com.webobjects.eocontrol.EOSortOrdering;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSTimestamp;
import er.extensions.eof.ERXEC;
import er.extensions.eof.ERXEOControlUtilities;
import er.extensions.eof.ERXQ;
import er.neo4jadaptor.test.eo.FirstEntity;
import er.neo4jadaptor.test.eo.Join;
import er.neo4jadaptor.test.eo.SecondEntity;
import er.neo4jadaptor.test.eo.ThirdEntity;
import er.neo4jadaptor.test.tools.Tools;
public class Neo4JAdaptorTest extends TestCase {
private EOEditingContext ec;
@Override
public void setUp() {
Tools.ensureInitialized();
Tools.cleanup();
ec = ERXEC.newEditingContext();
}
@SuppressWarnings("unchecked")
private <T> NSArray<T> fetch(String entityName, EOQualifier qualifier) {
EOFetchSpecification fs = new EOFetchSpecification(entityName, qualifier, null);
return ec.objectsWithFetchSpecification(fs);
}
@SuppressWarnings("unchecked")
private <T> NSArray<T> fetch(String entityName, EOQualifier qualifier, NSArray<EOSortOrdering> sortOrdering) {
EOFetchSpecification fs = new EOFetchSpecification(entityName, qualifier, sortOrdering);
return ec.objectsWithFetchSpecification(fs);
}
private <T> NSArray<T> fetchAll(String entityName, NSArray<EOSortOrdering> sortOrdering) {
return fetch(entityName, null, sortOrdering);
}
private <T> NSArray<T> fetchAll(String entityName) {
return fetch(entityName, null, null);
}
private String path(String ... keys) {
StringBuilder b = new StringBuilder();
for (int i=0; i<keys.length; i++) {
if (i > 0) {
b.append('.');
}
b.append(keys[i]);
}
return b.toString();
}
public void test01_insert() {
FirstEntity row = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity fetchedRow;
NSTimestamp ts = new NSTimestamp();
row.setText("aaa");
row.setBool(true);
row.setNumber(123);
row.setTimestamp(ts);
ec.saveChanges();
NSArray<FirstEntity> results = fetchAll(FirstEntity.ENTITY_NAME);
assertEquals("Expecting only one row", 1, results.count());
fetchedRow = results.get(0);
assertEquals(row.text(), fetchedRow.text());
assertEquals(row.bool(), fetchedRow.bool());
assertEquals(row.number(), fetchedRow.number());
assertEquals(row.timestamp(), fetchedRow.timestamp());
}
public void test02_update() {
FirstEntity row = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row.setText("aaa");
ec.saveChanges();
row.setText("bbb");
ec.saveChanges();
ec.invalidateAllObjects();
results = fetchAll(FirstEntity.ENTITY_NAME);
assertEquals(1, results.count());
assertEquals("bbb", results.get(0).text());
}
public void test03_textSearchOnRowInsertion() {
FirstEntity row = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row.setText("aaa");
ec.saveChanges();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.equals(FirstEntity.TEXT_KEY, "aaa"));
// if it fails then probably Lucene index hasn't been updated
assertEquals(1, results.count());
assertEquals(row, results.get(0));
}
public void test04_textSearchOnRowUpdate() {
FirstEntity row = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row.setText("aaa");
ec.saveChanges();
row.setText("bbb");
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.equals(FirstEntity.TEXT_KEY, "aaa"));
// if it fails then probably Lucene index hasn't been updated
assertEquals("Succeeded to search for 'aaa', but shouldn't", 0, results.count());
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.equals(FirstEntity.TEXT_KEY, "bbb"));
// if it fails then probably Lucene index hasn't been updated
assertEquals(1, results.count());
assertEquals("bbb", results.get(0).text());
}
public void test05_queryingNulls() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row1.setText(null);
row2.setText("abc");
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.isNull(FirstEntity.TEXT_KEY));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
assertNull(results.get(0).text());
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.isNotNull(FirstEntity.TEXT_KEY));
assertEquals(1, results.count());
assertEquals(row2, results.get(0));
// test if clearing value will work correctly
row2.setText(null);
ec.saveChanges();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.isNull(FirstEntity.TEXT_KEY));
assertEquals(2, results.count());
}
public void test06_queryingTextValues() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row1.setText("aaa");
row2.setText("abc");
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.equals(FirstEntity.TEXT_KEY, "aaa"));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThan(FirstEntity.TEXT_KEY, "aaa"));
assertEquals(1, results.count());
assertEquals(row2, results.get(0));
// now verify handling quote characters
row1.setText("a\"b");
ec.saveChanges();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.equals(FirstEntity.TEXT_KEY, "a\"b"));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
}
public void test07_queryingTextValuesLikeOperator() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row1.setText("aaa");
row2.setText("Aaa");
ec.saveChanges();
ec.invalidateAllObjects();
// case sensitive
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.like(FirstEntity.TEXT_KEY, "aa*"));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.like(FirstEntity.TEXT_KEY, "Aa*"));
assertEquals(1, results.count());
assertEquals(row2, results.get(0));
// case insensitive
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.likeInsensitive(FirstEntity.TEXT_KEY, "AA*"));
assertEquals(2, results.count());
}
public void test08_queryingTextValuesAsciiLikeOperator() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row1.setText("aóa");
row2.setText("Aóa");
ec.saveChanges();
ec.invalidateAllObjects();
// case sensitive
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.matches(FirstEntity.TEXT_KEY, "a.+a"));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.matches(FirstEntity.TEXT_KEY, "A[oó]a"));
assertEquals(1, results.count());
assertEquals(row2, results.get(0));
}
public void test09_queryingBooleanValues() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row1.setBool(true);
row2.setBool(false);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.isTrue(FirstEntity.BOOL_KEY));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.isFalse(FirstEntity.BOOL_KEY));
assertEquals(1, results.count());
assertEquals(row2, results.get(0));
}
public void test10_queryingIntegerValues() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row1.setNumber(19);
row2.setNumber(2);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThan(FirstEntity.NUMBER_KEY, 10));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThan(FirstEntity.NUMBER_KEY, 19));
assertEquals(0, results.count());
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThanOrEqualTo(FirstEntity.NUMBER_KEY, 19));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThanOrEqualTo(FirstEntity.NUMBER_KEY, 20));
assertEquals(0, results.count());
}
public void test11_queryingTimestampValues() throws InterruptedException {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSTimestamp ts1;
NSTimestamp ts2;
NSArray<FirstEntity> results;
ts1 = new NSTimestamp();
Thread.sleep(3);
ts2 = new NSTimestamp();
row1.setTimestamp(ts1);
row2.setTimestamp(ts2);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.equals(FirstEntity.TIMESTAMP_KEY, ts1));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThan(FirstEntity.TIMESTAMP_KEY, ts1));
assertEquals(1, results.count());
assertEquals(row2, results.get(0));
}
public void test12_storingRelationships() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
NSArray<FirstEntity> results;
NSArray<SecondEntity> results2;
row1.setSecondEntityRelationship(row2);
row1.setText("r1");
row2.setNumber(17);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetchAll(FirstEntity.ENTITY_NAME);
assertEquals(1, results.count());
assertEquals(row2, results.get(0).secondEntity());
assertEquals(1, row2.firstEntities().count());
results2 = fetchAll(SecondEntity.ENTITY_NAME);
assertEquals(1, results.count());
assertEquals(1, results2.get(0).firstEntities().count());
assertEquals(row1, results2.get(0).firstEntities().get(0));
}
public void test13_updatingRelationships() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity row2a = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
SecondEntity row2b = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
NSArray<FirstEntity> results;
row1.setSecondEntityRelationship(row2a);
row1.setText("r1");
row2a.setNumber(17);
row2b.setNumber(20);
ec.saveChanges();
assertEquals(1, row2a.firstEntities().count());
// perform updates
row1.setSecondEntityRelationship(row2b);
ec.saveChanges();
ec.invalidateAllObjects();
assertEquals(0, row2a.firstEntities().count());
// start n=node:types("type:FirstEntity"), n_secondEntityId=node(4) match n-[?]->x, n-[:secondEntityId]->n_secondEntityId where 1=1 return n.id
assertEquals(1, row2b.firstEntities().count());
results = fetchAll(FirstEntity.ENTITY_NAME);
assertEquals(1, results.count());
assertEquals(row2b, results.get(0).secondEntity());
}
public void test14_queryingSimpleAttributesByToOneRelationships() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
NSArray<FirstEntity> results;
row1.setSecondEntityRelationship(row2);
row2.setNumber(17);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.equals(path(FirstEntity.SECOND_ENTITY_KEY, SecondEntity.NUMBER_KEY), 17));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
}
public void test15_queryingEOObjectsByToOneRelationships() {
FirstEntity row1a = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
@SuppressWarnings("unused")
FirstEntity row1b = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
ThirdEntity row3 = ERXEOControlUtilities.createAndInsertObject(ec, ThirdEntity.class);
// NSArray<FirstEntity> results;
NSArray<ThirdEntity> results3;
row1a.setSecondEntityRelationship(row2);
row2.setThirdEntityRelationship(row3);
row3.setFirstEntityRelationship(row1a);
ec.saveChanges();
ec.invalidateAllObjects();
results3 = fetch(ThirdEntity.ENTITY_NAME, ERXQ.equals(path(ThirdEntity.FIRST_ENTITY_KEY, FirstEntity.SECOND_ENTITY_KEY), row2));
assertEquals(1, results3.count());
assertEquals(row3, results3.get(0));
}
public void test16_queryingSimpleAttributesByOneToManyRelationships() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
NSArray<SecondEntity> results;
row1.setText("aaa");
row1.setSecondEntityRelationship(row2);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(SecondEntity.ENTITY_NAME, ERXQ.equals(path(SecondEntity.FIRST_ENTITIES_KEY, FirstEntity.TEXT_KEY), "aaa"));
assertEquals(1, results.count());
assertEquals(row2, results.get(0));
}
public void test17_queryingEOObjectsByOneToManyRelationships() {
FirstEntity row1a = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
@SuppressWarnings("unused")
FirstEntity row1b = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
NSArray<FirstEntity> results;
row1a.setSecondEntityRelationship(row2);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME,
ERXQ.equals(path(FirstEntity.SECOND_ENTITY_KEY, SecondEntity.FIRST_ENTITIES_KEY), row1a));
assertEquals(1, results.count());
results = fetch(FirstEntity.ENTITY_NAME,
ERXQ.equals(path(FirstEntity.SECOND_ENTITY_KEY, SecondEntity.FIRST_ENTITIES_KEY, FirstEntity.SECOND_ENTITY_KEY, SecondEntity.FIRST_ENTITIES_KEY), row1a));
assertEquals(1, results.count());
}
public void test18_deleting() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
NSArray<SecondEntity> results;
row1.setSecondEntityRelationship(row2);
ec.saveChanges();
ec.deleteObject(row1);
ec.saveChanges();
ec.invalidateAllObjects();
assertEquals(0, row2.firstEntities().size());
results = fetchAll(FirstEntity.ENTITY_NAME);
assertEquals(0, results.count());
}
public void test20_queryNullRelationshipValue() {
FirstEntity row1a = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row1b = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
NSArray<FirstEntity> results;
row1b.setSecondEntityRelationship(row2);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.equals(FirstEntity.SECOND_ENTITY_KEY, null));
assertEquals(1, results.count());
assertEquals(row1a, results.get(0));
}
public void test21_insertJoinEntity_explicit() {
FirstEntity first = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity second = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
// explicit create Join row
Join join = ERXEOControlUtilities.createAndInsertObject(ec, Join.class);
join.setFirstEntityRelationship(first);
join.setSecondEntityRelationship(second);
ec.saveChanges();
ec.invalidateAllObjects();
NSArray<FirstEntity> results = fetchAll(FirstEntity.ENTITY_NAME);
assertEquals("Expecting only one row", 1, results.count());
first = results.get(0);
assertEquals(1, first.joins().count());
assertEquals(second, first.joins().get(0).secondEntity());
NSArray<SecondEntity> results2 = fetchAll(SecondEntity.ENTITY_NAME);
assertEquals("Expecting only one row", 1, results2.count());
second = results2.get(0);
assertEquals(1, second.joins().count());
assertEquals(first, second.joins().get(0).firstEntity());
}
public void test22_insertJoinEntity_implicit() {
FirstEntity first = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity second = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
// implicit create Join row
first.addToJoins_secondEntityRelationship(second);
ec.saveChanges();
ec.invalidateAllObjects();
NSArray<FirstEntity> results = fetchAll(FirstEntity.ENTITY_NAME);
assertEquals("Expecting only one row", 1, results.count());
first = results.get(0);
assertEquals(1, first.joins().count());
assertEquals(second, first.joins().get(0).secondEntity());
NSArray<SecondEntity> results2 = fetchAll(SecondEntity.ENTITY_NAME);
assertEquals("Expecting only one row", 1, results2.count());
second = results2.get(0);
assertEquals(1, second.joins().count());
assertEquals(first, second.joins().get(0).firstEntity());
}
public void test23_insertFlattenedManyToManyRelationship() {
FirstEntity first = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity second = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
first.addToJoins_secondEntityRelationship(second);
ec.saveChanges();
ec.invalidateAllObjects();
NSArray<SecondEntity> results2 = fetchAll(SecondEntity.ENTITY_NAME);
assertEquals("Expecting only one row", 1, results2.count());
second = results2.get(0);
assertEquals(1, second.joins_firstEntity().count());
assertEquals(first, second.joins_firstEntity().get(0));
NSArray<FirstEntity> results = fetchAll(FirstEntity.ENTITY_NAME);
assertEquals("Expecting only one row", 1, results.count());
first = results.get(0);
assertEquals(1, first.joins_secondEntity().count());
assertEquals(second, first.joins_secondEntity().get(0));
}
public void test24_flattenedKeyPathAccess() {
FirstEntity first = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity second = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
ThirdEntity third = ERXEOControlUtilities.createAndInsertObject(ec, ThirdEntity.class);
Join join = ERXEOControlUtilities.createAndInsertObject(ec, Join.class);
NSArray<?> results;
join.setFirstEntityRelationship(first);
join.setSecondEntityRelationship(second);
first.setSecondEntityRelationship(second);
second.setThirdEntityRelationship(third);
third.setFirstEntityRelationship(first);
// add some fake objects
ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
ERXEOControlUtilities.createAndInsertObject(ec, ThirdEntity.class);
ec.saveChanges();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.isNotNull(path(FirstEntity.JOINS_SECOND_ENTITY_KEY, SecondEntity.THIRD_ENTITY_KEY)));
assertEquals(1, results.count());
assertEquals(first, results.get(0));
results = fetch(ThirdEntity.ENTITY_NAME, ERXQ.isNotNull(path(ThirdEntity.FIRST_ENTITY_KEY, FirstEntity.JOINS_SECOND_ENTITY_KEY)));
assertEquals(1, results.count());
assertEquals(third, results.get(0));
}
public void test25_sortOrdering() {
for (int i=0; i<20; i++) {
FirstEntity first = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
first.setNumber((int) (Math.random() * 100));
}
// add one with null number value
ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
ec.saveChanges();
// fetch in descending order
results = fetchAll(
FirstEntity.ENTITY_NAME,
new NSArray<>(EOSortOrdering.sortOrderingWithKey(FirstEntity.NUMBER_KEY, EOSortOrdering.CompareDescending))
);
Integer previous = Integer.MAX_VALUE;
for (FirstEntity fe : results) {
if (previous == null) {
assertNull(fe.number());
} else {
assertTrue(fe.number() == null || previous >= fe.number());
previous = fe.number();
}
}
// fetch in ascending order
results = fetchAll(
FirstEntity.ENTITY_NAME,
new NSArray<>(EOSortOrdering.sortOrderingWithKey(FirstEntity.NUMBER_KEY, EOSortOrdering.CompareAscending))
);
previous = Integer.MIN_VALUE;
for (FirstEntity fe : results) {
if (previous == null) {
assertNull(fe.number());
} else {
assertTrue(fe.number() == null || previous <= fe.number());
previous = fe.number();
}
}
}
public void test26_lockingOnUpdateUponRelationshipUpdate() {
FirstEntity first = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
ec.saveChanges();
SecondEntity second = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
first.setSecondEntityRelationship(second);
ec.saveChanges();
first.setText("asdasd");
// when FirstEntity.secondEntityId is used for locking then it sometimes fails here
ec.saveChanges();
}
public void test27_updatingToManyRelationships() {
FirstEntity first = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class); // Event
SecondEntity second = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class); // Programme
first.setSecondEntityRelationship(second); // event.setProgramme(programme)
ec.saveChanges();
ec.forgetObject(second);
second = (SecondEntity) fetchAll(SecondEntity.ENTITY_NAME).get(0);
assertFalse(second.firstEntities().isEmpty()); // programme.events().isEmpty()
}
public void test28_deletingJoinRelationship() {
FirstEntity first = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity second = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
// explicit create Join row
Join join = ERXEOControlUtilities.createAndInsertObject(ec, Join.class);
join.setFirstEntityRelationship(first);
join.setSecondEntityRelationship(second);
ec.saveChanges();
ec.invalidateAllObjects();
NSArray<Join> results = fetchAll(Join.ENTITY_NAME);
assertEquals("Expecting only one row", 1, results.count());
join = results.get(0);
ec.deleteObject(join);
ec.saveChanges();
// ensure there's no relationship between First and Second anymore
NSArray<FirstEntity> results2 = fetchAll(FirstEntity.ENTITY_NAME);
first = results2.get(0);
assertEquals(0, first.joins().count());
assertTrue(first.joins_secondEntity().isEmpty());
}
// tests discovered bug
public void test29_flattenedRelationship() {
FirstEntity f0 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity s1 = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
s1.addToFirstEntitiesRelationship(f0);
Join j2 = ERXEOControlUtilities.createAndInsertObject(ec, Join.class);
j2.setSecondEntityRelationship(s1);
FirstEntity f3 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
j2.setFirstEntityRelationship(f3);
ThirdEntity t4 = ERXEOControlUtilities.createAndInsertObject(ec, ThirdEntity.class);
t4.setFirstEntityRelationship(f3);
ec.saveChanges();
ec.invalidateAllObjects();
// basic stuff, not using any flattened relationship
assertEquals(1, t4.firstEntity().joins().get(0).secondEntity().firstEntities().size());
assertEquals(1, t4.firstEntity().joins_secondEntity().size());
assertEquals(1, t4.firstEntity().joins_secondEntity_firstEntities().size());
// problematic parts
assertEquals(1, t4.firstEntity_joins().size());
assertEquals(1, t4.firstEntity_joins_secondEntity().size());
assertEquals(1, t4.firstEntity_joins_secondEntity_firstEntities().size());
}
public void test30_queryingFloatValues() {
FirstEntity row1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity row2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
NSArray<FirstEntity> results;
row1.setFloatNumber(19f);
row2.setFloatNumber(2f);
ec.saveChanges();
ec.invalidateAllObjects();
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThan(FirstEntity.FLOAT_NUMBER_KEY, 10f));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThan(FirstEntity.FLOAT_NUMBER_KEY, 19f));
assertEquals(0, results.count());
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThanOrEqualTo(FirstEntity.FLOAT_NUMBER_KEY, 19f));
assertEquals(1, results.count());
assertEquals(row1, results.get(0));
results = fetch(FirstEntity.ENTITY_NAME, ERXQ.greaterThanOrEqualTo(FirstEntity.FLOAT_NUMBER_KEY, 20f));
assertEquals(0, results.count());
}
/**
* Test for bug discovered when fetching using AND qualifier with foreign key equality check and less than comparison
*/
public void test31_byPrimaryKeyFilterTest() {
FirstEntity f1 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
FirstEntity f2 = ERXEOControlUtilities.createAndInsertObject(ec, FirstEntity.class);
SecondEntity s = ERXEOControlUtilities.createAndInsertObject(ec, SecondEntity.class);
NSArray<FirstEntity> results;
f1.setNumber(1);
// 2 is not used
f2.setNumber(3);
f1.setSecondEntityRelationship(s);
f2.setSecondEntityRelationship(s);
ec.saveChanges();
results = fetch(
FirstEntity.ENTITY_NAME,
ERXQ.and(
ERXQ.equals(FirstEntity.SECOND_ENTITY_KEY, s),
ERXQ.greaterThan(FirstEntity.NUMBER_KEY, 1)
)
);
assertEquals(1, results.size());
}
}