#406 - Remove diff "non flat mode" ... so diff going forward only supports flat mode

This commit is contained in:
Robin Bygrave
2015-09-03 14:29:03 +12:00
parent 54172aec6c
commit 088fcfb296
7 changed files with 42 additions and 168 deletions
@@ -359,7 +359,6 @@ public class ServerConfig {
private int queryCacheMaxIdleTime = 600;
private int queryCacheMaxTimeToLive = 60*60*6;
private Object objectMapper;
private boolean diffFlatMode = true;
/**
* Set to true if you want eq("someProperty", null) to generate 1=1 rather than "is null" sql expression.
@@ -2116,7 +2115,7 @@ public class ServerConfig {
changeLogIncludeInserts = p.getBoolean("changeLogIncludeInserts", changeLogIncludeInserts);
expressionEqualsWithNullAsNoop = p.getBoolean("expressionEqualsWithNullAsNoop", expressionEqualsWithNullAsNoop);
diffFlatMode = p.getBoolean("diffFlatMode", diffFlatMode);
asOfViewSuffix = p.get("asOfViewSuffix", asOfViewSuffix);
asOfSysPeriod = p.get("asOfSysPeriod", asOfSysPeriod);
historyTableSuffix = p.get("historyTableSuffix", historyTableSuffix);
@@ -2229,22 +2228,6 @@ public class ServerConfig {
this.objectMapper = objectMapper;
}
/**
* Return true if diff should return flat properties with dot notation rather than
* embedded beans or reference beans (when the associated bean id is different).
*/
public boolean isDiffFlatMode() {
return diffFlatMode;
}
/**
* Set to true if diff should return flat properties with dot notation rather than
* embedded beans or reference beans (when the associated bean id is different).
*/
public void setDiffFlatMode(boolean diffFlatMode) {
this.diffFlatMode = diffFlatMode;
}
/**
* Return true if eq("someProperty", null) should to generate "1=1" rather than "is null" sql expression.
*/
@@ -132,8 +132,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private final BeanDescriptorManager beanDescriptorManager;
private final DiffHelp diffHelp;
private final AutoFetchManager autoFetchManager;
private final ReadAuditPrepare readAuditPrepare;
@@ -217,7 +215,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
this.backgroundExecutor = config.getBackgroundExecutor();
this.serverName = serverConfig.getName();
this.diffHelp = new DiffHelp(serverConfig.isDiffFlatMode());
this.lazyLoadBatchSize = serverConfig.getLazyLoadBatchSize();
this.queryBatchSize = serverConfig.getQueryBatchSize();
this.cqueryEngine = config.getCQueryEngine();
@@ -578,7 +575,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
BeanDescriptor<?> desc = getBeanDescriptor(a.getClass());
return diffHelp.diff(a, b, desc);
return DiffHelp.diff(a, b, desc);
}
/**
@@ -1,14 +1,10 @@
package com.avaje.ebeaninternal.server.core;
import java.util.LinkedHashMap;
import java.util.Map;
import com.avaje.ebean.ValuePair;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
import com.avaje.ebeaninternal.util.ValueUtil;
import java.util.Map;
/**
* Helper to perform a diff given two beans of the same type.
@@ -18,10 +14,7 @@ import com.avaje.ebeaninternal.util.ValueUtil;
*/
public class DiffHelp {
private final boolean flatMode;
public DiffHelp(boolean flatMode) {
this.flatMode = flatMode;
private DiffHelp() {
}
/**
@@ -34,123 +27,26 @@ public class DiffHelp {
* This intentionally does not include as OneToMany or ManyToMany properties.
* </p>
*/
public Map<String, ValuePair> diff(Object newBean, Object oldBean, BeanDescriptor<?> desc) {
public static Map<String, ValuePair> diff(Object newBean, Object oldBean, BeanDescriptor<?> desc) {
if (!(newBean instanceof EntityBean)) {
throw new IllegalArgumentException("First bean expected to be an enhanced EntityBean? bean:"+newBean);
throw new IllegalArgumentException("First bean expected to be an enhanced EntityBean? bean:" + newBean);
}
if (oldBean != null) {
if (!(oldBean instanceof EntityBean)) {
throw new IllegalArgumentException("Second bean expected to be an enhanced EntityBean? bean:"+oldBean);
throw new IllegalArgumentException("Second bean expected to be an enhanced EntityBean? bean:" + oldBean);
}
if (!newBean.getClass().isAssignableFrom(oldBean.getClass())) {
throw new IllegalArgumentException("Second bean not assignable to the first bean?");
}
}
if (oldBean == null) {
return ((EntityBean) newBean)._ebean_getIntercept().getDirtyValues();
}
Map<String, ValuePair> map = new LinkedHashMap<String, ValuePair>();
diff(null, map, (EntityBean) newBean, (EntityBean) oldBean, desc);
return map;
}
public void diff(String prefix, Map<String, ValuePair> map, EntityBean newBean, EntityBean oldBean, BeanDescriptor<?> desc) {
if (flatMode) {
desc.diff(prefix, map, newBean, oldBean);
} else {
// check the simple properties
BeanProperty[] base = desc.propertiesBaseScalar();
for (int i = 0; i < base.length; i++) {
base[i].diff(prefix, map, newBean, oldBean);
}
diffAssocOne(prefix, newBean, oldBean, desc, map);
diffEmbedded(prefix, newBean, oldBean, desc, map);
if (oldBean == null) {
return ((EntityBean) newBean)._ebean_getIntercept().getDirtyValues();
}
}
/**
* Check the Embedded bean properties for differences.
* <p>
* If ANY of the properties are different then the whole Embedded bean is
* determined to be different as is added to the map.
* </p>
*/
private void diffEmbedded(String prefix, EntityBean newBean, EntityBean oldBean, BeanDescriptor<?> desc, Map<String, ValuePair> map) {
return desc.diff((EntityBean) newBean, (EntityBean) oldBean);
}
BeanPropertyAssocOne<?>[] emb = desc.propertiesEmbedded();
for (int i = 0; i < emb.length; i++) {
EntityBean newVal = (EntityBean)emb[i].getValue(newBean);
EntityBean oldVal = (EntityBean)emb[i].getValue(oldBean);
if (!isBothNull(newVal, oldVal)) {
String propName = (prefix == null) ? emb[i].getName() : prefix + emb[i].getName();
if (isDiffNull(newVal, oldVal)) {
// one of the embedded beans is null
if (flatMode) {
BeanDescriptor<?> embDesc = emb[i].getTargetDescriptor();
diff(propName, map, newVal, oldVal, embDesc);
} else {
map.put(propName, new ValuePair(newVal, oldVal));
}
} else {
// recursively diff into the embedded bean
BeanDescriptor<?> embDesc = emb[i].getTargetDescriptor();
diff(propName, map, newVal, oldVal, embDesc);
}
}
}
}
/**
* If the properties are different by null OR if the id value is different,
* then add the Assoc One bean to the map.
*/
private void diffAssocOne(String prefix, EntityBean newBean, EntityBean oldBean, BeanDescriptor<?> desc, Map<String, ValuePair> map) {
BeanPropertyAssocOne<?>[] ones = desc.propertiesOne();
for (int i = 0; i < ones.length; i++) {
Object newVal = ones[i].getValue(newBean);
Object oldVal = ones[i].getValue(oldBean);
if (!isBothNull(newVal, oldVal)) {
BeanDescriptor<?> oneDesc = ones[i].getTargetDescriptor();
Object newId = (newVal == null) ? null : oneDesc.getId((EntityBean)newVal);
Object oldId = (oldVal == null) ? null : oneDesc.getId((EntityBean)oldVal);
if (!ValueUtil.areEqual(newId, oldId)) {
String propName = (prefix == null) ? ones[i].getName() : prefix + ones[i].getName();
// the ids are different
if (flatMode) {
String idName = oneDesc.getIdProperty().getName();
map.put(propName + "." + idName, new ValuePair(newId, oldId));
} else {
map.put(propName, new ValuePair(newVal, oldVal));
}
}
}
}
}
private boolean isBothNull(Object newVal, Object oldVal) {
return newVal == null && oldVal == null;
}
private boolean isDiffNull(Object newVal, Object oldVal) {
if (newVal == null) {
return oldVal != null;
} else {
return oldVal == null;
}
}
}
@@ -2073,6 +2073,15 @@ public class BeanDescriptor<T> implements MetaBeanInfo, SpiBeanType<T> {
}
}
/**
* Return the diff comparing the bean values.
*/
public Map<String, ValuePair> diff(EntityBean newBean, EntityBean oldBean) {
Map<String, ValuePair> map = new LinkedHashMap<String, ValuePair>();
diff(null, map, newBean, oldBean);
return map;
}
/**
* Populate the diff for updates with flattened non-null property values.
*/
@@ -35,8 +35,6 @@ public class CQueryEngine {
private static final String T0 = "t0";
private final DiffHelp diffHelp = new DiffHelp(true);
private final boolean forwardOnlyHintOnFindIterate;
private final CQueryBuilder queryBuilder;
@@ -259,7 +257,7 @@ public class CQueryEngine {
private <T> void deriveVersionDiff(Version<T> current, Version<T> prior, BeanDescriptor<T> descriptor) {
Map<String, ValuePair> diff = diffHelp.diff(current.getBean(), prior.getBean(), descriptor);
Map<String, ValuePair> diff = DiffHelp.diff(current.getBean(), prior.getBean(), descriptor);
current.setDiff(diff);
}