Skip to content

Commit

Permalink
Adding distinct to query fix
Browse files Browse the repository at this point in the history
  • Loading branch information
aarrsseni committed Dec 6, 2017
1 parent d0a760e commit d90c467
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 39 deletions.
51 changes: 49 additions & 2 deletions cayenne-server/src/main/java/org/apache/cayenne/DataRow.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@

package org.apache.cayenne;

import java.util.HashMap;
import java.util.Map;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.cayenne.map.DbRelationship;
Expand Down Expand Up @@ -149,4 +148,52 @@ public String getEntityName() {
public void setEntityName(String entityName) {
this.entityName = entityName;
}

public int hashCode() {
int h = 0;
for (Entry<String, Object> curr : entrySet()) {
if (curr.getValue() instanceof byte[]) {
h += Objects.hashCode(curr.getKey()) ^ Arrays.hashCode((byte[]) curr.getValue());
} else {
h += curr.hashCode();
}
}
return h;
}

public boolean equals(Object o) {
if (o == this)
return true;

if (!(o instanceof Map))
return false;
Map<?,?> m = (Map<?,?>) o;
if (m.size() != size())
return false;

try {
for (Entry<String, Object> e : entrySet()) {
String key = e.getKey();
Object value = e.getValue();
if (value == null) {
if (!(m.get(key) == null && m.containsKey(key)))
return false;
} else {
if (e.getValue() instanceof byte[] && m.get(key) instanceof byte[]) {
if (!Arrays.equals((byte[]) value, (byte[]) m.get(key))) {
return false;
}
} else {
if (!value.equals(m.get(key)))
return false;
}
}

}
} catch (ClassCastException | NullPointerException unused) {
return false;
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,7 @@
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.util.ResultIteratorIterator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.*;

/**
* A ResultIterator that does in-memory filtering of rows to return only
Expand Down Expand Up @@ -144,13 +137,20 @@ private void checkNextUniqueRow() {
while (delegate.hasNextRow()) {
T next = delegate.nextRow();

if (fetchedIds.add(next)) {
if (isUnique(next)) {
this.nextDataRow = next;
break;
}
}
}

private boolean isUnique(T next) {
if(next instanceof Object[]){
return fetchedIds.add(new ObjectArrayWrapper((Object[]) next));
}
return fetchedIds.add(next);
}

private void checkNextRowWithUniqueId() {
nextDataRow = null;
while (delegate.hasNextRow()) {
Expand All @@ -165,11 +165,37 @@ private void checkNextRowWithUniqueId() {
id.put(pk.getName(), ((DataRow)next).get(pk.getName()));
}

if (fetchedIds.add(id)) {
if (isUnique((T) id)) {
this.nextDataRow = next;
break;
}
}
}

class ObjectArrayWrapper{
private Object[] objects;

ObjectArrayWrapper(Object[] objects){
this.objects = objects;
}

Object[] getObjects(){
return objects;
}

public int hashCode(){
return Arrays.deepHashCode(objects);
}

public boolean equals(Object o){
if (o == this)
return true;

if (!(o instanceof DistinctResultIterator.ObjectArrayWrapper))
return false;

return Arrays.deepEquals(this.getObjects(),((ObjectArrayWrapper)o).getObjects());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ <T> List<ColumnDescriptor> appendOverriddenColumns(List<ColumnDescriptor> column
int type = getJdbcTypeForProperty(property);
ColumnDescriptor descriptor;
if(property.getType() != null) {
descriptor = new ColumnDescriptor(builder.toString(), type, property.getType().getName());
descriptor = new ColumnDescriptor(builder.toString(), type, property.getType().getCanonicalName());
} else {
descriptor = new ColumnDescriptor(builder.toString(), type);
}
Expand Down
52 changes: 51 additions & 1 deletion cayenne-server/src/test/java/org/apache/cayenne/DataRowTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.*;

public class DataRowTest {

Expand All @@ -35,4 +35,54 @@ public void testVersion() throws Exception {
assertFalse(s3.getVersion() == s1.getVersion());
}

@Test
public void testEquals(){
DataRow d1 = new DataRow(1);
d1.put("FIELD", "test".getBytes());

assertTrue(d1.equals(d1));

DataRow d2 = new DataRow(1);
d2.put("FIELD", "test".getBytes());

assertTrue(d1.equals(d2));
assertTrue(d2.equals(d1));

DataRow d3 = new DataRow(1);
d3.put("FIELD", "test".getBytes());

assertTrue(d2.equals(d3));
assertTrue(d1.equals(d3));

assertFalse(d1.equals(null));

DataRow d4 = new DataRow(1);
d4.put("FIELD1", "test".getBytes());

for(int i = 0; i < 5; i++) {
assertFalse(d3.equals(d4));
}

DataRow d5 = new DataRow(1);
d5.put("FIELD", "test1".getBytes());

DataRow d6 = new DataRow(1);
d6.put("FIELD", "test".getBytes());

assertFalse(d5.equals(d6));
}

@Test
public void testHashCode(){
DataRow d1 = new DataRow(1);
d1.put("FIELD", "test".getBytes());

assertEquals(d1.hashCode(), d1.hashCode());

DataRow d2 = new DataRow(1);
d2.put("FIELD", "test".getBytes());

assertTrue(d1.equals(d2));
assertEquals(d1.hashCode(), d2.hashCode());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.ObjectSelect;
import org.apache.cayenne.query.SQLTemplate;
import org.apache.cayenne.query.SelectQuery;
import org.apache.cayenne.query.*;
import org.apache.cayenne.test.jdbc.DBHelper;
import org.apache.cayenne.test.jdbc.TableHelper;
import org.apache.cayenne.testdo.lob.ClobTestEntity;
Expand Down Expand Up @@ -96,28 +94,6 @@ public void testColumnSelect_DistinctResultIterator() throws Exception {
@Test
public void testAddingDistinctToQuery() throws Exception{
if (accessStackAdapter.supportsLobs()){
// DistEntity obj = context.newObject(DistEntity.class);
// obj.setName("ABC");
// obj.setField("test".getBytes());
// DistEntity obj2 = context.newObject(DistEntity.class);
// obj2.setName("ABC1");
// obj2.setField("test".getBytes());
//
// DistEntityRel objRel1 = context.newObject(DistEntityRel.class);
// objRel1.setNum(5);
// DistEntityRel objRel2 = context.newObject(DistEntityRel.class);
// objRel2.setNum(6);
// DistEntityRel objRel3 = context.newObject(DistEntityRel.class);
// objRel3.setNum(7);
// DistEntityRel objRel4 = context.newObject(DistEntityRel.class);
// objRel4.setNum(5);
//
// obj.addToDistRel(objRel1);
// obj.addToDistRel(objRel2);
// obj.addToDistRel(objRel3);
// obj2.addToDistRel(objRel4);

// context.commitChanges();

TableHelper tDistEntity = new TableHelper(dbHelper, "DIST_ENTITY");
tDistEntity.setColumns("ID", "NAME", "FIELD");
Expand All @@ -141,7 +117,9 @@ public void testAddingDistinctToQuery() throws Exception{
ObjectContext objectContext = serverRuntime.newContext();

SQLTemplate select = new SQLTemplate(DistEntity.class, "SELECT t0.FIELD, t0.NAME, t0.ID FROM DIST_ENTITY t0 JOIN DIST_ENTITY_REL t1 ON (t0.ID = t1.DIST_ID) WHERE (t1.NUM > 0) AND (t0.NAME LIKE 'dist_entity1')");
select.setColumnNamesCapitalization(CapsStrategy.UPPER);
List<DistEntity> list1 = objectContext.performQuery(select);

assertEquals(4, list1.size());

List<DistEntity> list2 = ObjectSelect.query(DistEntity.class)
Expand All @@ -150,6 +128,27 @@ public void testAddingDistinctToQuery() throws Exception{
.select(objectContext);

assertEquals(1,list2.size());

EJBQLQuery query1 = new EJBQLQuery("select d FROM DistEntity d JOIN d.distRel r where d.name='dist_entity1' and r.num>0");
List<DistEntity> list3 = context.performQuery(query1);

assertEquals(4,list3.size());

List<String> list4 = ObjectSelect
.columnQuery(DistEntity.class, DistEntity.NAME)
.where(DistEntity.DIST_REL.dot(DistEntityRel.NUM).gt(0))
.and(DistEntity.NAME.eq("dist_entity1"))
.select(context);

assertEquals(1,list4.size());

List<Object[]> list5 = ObjectSelect
.columnQuery(DistEntity.class, DistEntity.NAME, DistEntity.FIELD)
.where(DistEntity.DIST_REL.dot(DistEntityRel.NUM).gt(0))
.and(DistEntity.NAME.eq("dist_entity1"))
.select(context);

assertEquals(1,list5.size());
}
}

Expand Down

0 comments on commit d90c467

Please sign in to comment.