diff --git a/src/com/wentch/redkale/source/DataDefaultSource.java b/src/com/wentch/redkale/source/DataDefaultSource.java index 66a2d3b8e..e128ed17b 100644 --- a/src/com/wentch/redkale/source/DataDefaultSource.java +++ b/src/com/wentch/redkale/source/DataDefaultSource.java @@ -1407,6 +1407,7 @@ public final class DataDefaultSource implements DataSource, Nameable { if (readcache && cache != null) { Predicate filter = node == null ? null : node.createFilterPredicate(info, bean); if (node == null || node.isJoinAllCached()) { + if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " cache query predicate = " + filter); Sheet sheet = cache.querySheet(selects, filter, flipper, FilterNode.createFilterComparator(info, flipper)); if (!sheet.isEmpty() || info.isVirtualEntity() || cache.isFullLoaded()) return sheet; } diff --git a/src/com/wentch/redkale/source/FilterBeanNode.java b/src/com/wentch/redkale/source/FilterBeanNode.java index 3bd2fadd6..a001197f3 100644 --- a/src/com/wentch/redkale/source/FilterBeanNode.java +++ b/src/com/wentch/redkale/source/FilterBeanNode.java @@ -238,7 +238,8 @@ final class FilterBeanNode extends FilterNode { } private Predicate createFilterPredicate(final boolean first, final EntityInfo info, FilterBean bean) { - if ((this.joinSQL == null && first) || this.foreignEntity == null) return super.createFilterPredicate(info, bean); + //if ((this.joinSQL == null && first) || this.foreignEntity == null) return super.createFilterPredicate(info, bean); + if (this.foreignEntity == null) return super.createFilterPredicate(info, bean); final Map foreign = new HashMap<>(); Predicate result = null; putForeignPredicate(foreign, bean); @@ -248,7 +249,31 @@ final class FilterBeanNode extends FilterNode { if (node.foreignEntity == null) { Predicate f = node.createFilterPredicate(false, info, bean); if (f == null) continue; - result = (result == null) ? f : (signand ? result.and(f) : result.or(f)); + final Predicate one = result; + final Predicate two = f; + result = (result == null) ? f : (signand ? new Predicate() { + + @Override + public boolean test(T t) { + return one.test(t) && two.test(t); + } + + @Override + public String toString() { + return "(" + one + " AND " + two + ")"; + } + } : new Predicate() { + + @Override + public boolean test(T t) { + return one.test(t) || two.test(t); + } + + @Override + public String toString() { + return "(" + one + " OR " + two + ")"; + } + }); } else { putForeignPredicate(foreign, bean); } @@ -256,16 +281,49 @@ final class FilterBeanNode extends FilterNode { } if (foreign.isEmpty()) return result; final Attribute foreignAttr = this.foreignAttribute; - for (Map.Entry en : foreign.entrySet()) { + for (final Map.Entry en : foreign.entrySet()) { Attribute mainIdAttr = info.getPrimary(); final EntityCache cache = en.getKey().getCache(); final Predicate p = en.getValue(); - Predicate f = (T t) -> { - Serializable key = mainIdAttr.get(t); - Predicate k = (e) -> key.equals(foreignAttr.get(e)); - return cache.exists(k.and(p)); + Predicate f = new Predicate() { + + @Override + public boolean test(T t) { + Serializable key = mainIdAttr.get(t); + Predicate k = (e) -> key.equals(foreignAttr.get(e)); + return cache.exists(k.and(p)); + } + + @Override + public String toString() { + return "(" + mainIdAttr.field() + " = " + en.getKey().getType().getSimpleName() + "." + foreignAttr.field() + " AND " + p + ")"; + } }; - result = (result == null) ? f : (signand ? result.and(f) : result.or(f)); + final Predicate one = result; + final Predicate two = f; + result = (result == null) ? f : (signand ? new Predicate() { + + @Override + public boolean test(T t) { + return one.test(t) && two.test(t); + } + + @Override + public String toString() { + return "(" + one + " AND " + two + ")"; + } + } : new Predicate() { + + @Override + public boolean test(T t) { + return one.test(t) || two.test(t); + } + + @Override + public String toString() { + return "(" + one + " OR " + two + ")"; + } + }); } return result; } diff --git a/src/com/wentch/redkale/source/FilterNode.java b/src/com/wentch/redkale/source/FilterNode.java index a99081b6e..6841bcebe 100644 --- a/src/com/wentch/redkale/source/FilterNode.java +++ b/src/com/wentch/redkale/source/FilterNode.java @@ -227,7 +227,31 @@ public class FilterNode { for (FilterNode node : this.nodes) { Predicate f = node.createFilterPredicate(info, bean); if (f == null) continue; - filter = (filter == null) ? f : (signand ? filter.and(f) : filter.or(f)); + final Predicate one = filter; + final Predicate two = f; + filter = (filter == null) ? f : (signand ? new Predicate() { + + @Override + public boolean test(T t) { + return one.test(t) && two.test(t); + } + + @Override + public String toString() { + return "(" + one + " AND " + two + ")"; + } + } : new Predicate() { + + @Override + public boolean test(T t) { + return one.test(t) || two.test(t); + } + + @Override + public String toString() { + return "(" + one + " OR " + two + ")"; + } + }); } return filter; } @@ -252,88 +276,327 @@ public class FilterNode { } final Serializable val = val0; switch (express) { - case EQUAL: return (T t) -> val.equals(attr.get(t)); - case NOTEQUAL: return (T t) -> !val.equals(attr.get(t)); - case GREATERTHAN: return (T t) -> ((Number) attr.get(t)).longValue() > ((Number) val).longValue(); - case LESSTHAN: return (T t) -> ((Number) attr.get(t)).longValue() < ((Number) val).longValue(); - case GREATERTHANOREQUALTO: return (T t) -> ((Number) attr.get(t)).longValue() >= ((Number) val).longValue(); - case LESSTHANOREQUALTO: return (T t) -> ((Number) attr.get(t)).longValue() <= ((Number) val).longValue(); - case ISNULL: return (T t) -> attr.get(t) == null; - case ISNOTNULL: return (T t) -> attr.get(t) != null; - case OPAND: return (T t) -> (((Number) attr.get(t)).longValue() & ((Number) val).longValue()) > 0; - case OPOR: return (T t) -> (((Number) attr.get(t)).longValue() | ((Number) val).longValue()) > 0; - case OPANDNO: return (T t) -> (((Number) attr.get(t)).longValue() & ((Number) val).longValue()) == 0; + case EQUAL: return new Predicate() { + + @Override + public boolean test(T t) { + return val.equals(attr.get(t)); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } + }; + case NOTEQUAL: return new Predicate() { + + @Override + public boolean test(T t) { + return !val.equals(attr.get(t)); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } + }; + case GREATERTHAN: return new Predicate() { + + @Override + public boolean test(T t) { + return ((Number) attr.get(t)).longValue() > ((Number) val).longValue(); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } + }; + case LESSTHAN: return new Predicate() { + + @Override + public boolean test(T t) { + return ((Number) attr.get(t)).longValue() < ((Number) val).longValue(); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } + }; + case GREATERTHANOREQUALTO: return new Predicate() { + + @Override + public boolean test(T t) { + return ((Number) attr.get(t)).longValue() >= ((Number) val).longValue(); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } + }; + case LESSTHANOREQUALTO: return new Predicate() { + + @Override + public boolean test(T t) { + return ((Number) attr.get(t)).longValue() <= ((Number) val).longValue(); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } + }; + case ISNULL: return new Predicate() { + + @Override + public boolean test(T t) { + return attr.get(t) == null; + } + + @Override + public String toString() { + return attr.field() + " = null"; + } + }; + case ISNOTNULL: return new Predicate() { + + @Override + public boolean test(T t) { + return attr.get(t) != null; + } + + @Override + public String toString() { + return attr.field() + " != null"; + } + }; + case OPAND: return new Predicate() { + + @Override + public boolean test(T t) { + return (((Number) attr.get(t)).longValue() & ((Number) val).longValue()) > 0; + } + + @Override + public String toString() { + return attr.field() + " & " + val + " > 0"; + } + }; + case OPOR: return new Predicate() { + + @Override + public boolean test(T t) { + return (((Number) attr.get(t)).longValue() | ((Number) val).longValue()) > 0; + } + + @Override + public String toString() { + return attr.field() + " | " + val + " > 0"; + } + }; + case OPANDNO: return new Predicate() { + + @Override + public boolean test(T t) { + return (((Number) attr.get(t)).longValue() & ((Number) val).longValue()) == 0; + } + + @Override + public String toString() { + return attr.field() + " & " + val + " = 0"; + } + }; case LIKE: - return (T t) -> { - Object rs = attr.get(t); - return rs != null && rs.toString().contains(val.toString()); + return new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + return rs != null && rs.toString().contains(val.toString()); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } }; case NOTLIKE: - return (T t) -> { - Object rs = attr.get(t); - return rs == null || !rs.toString().contains(val.toString()); + return new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + return rs == null || !rs.toString().contains(val.toString()); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } }; case BETWEEN: case NOTBETWEEN: Range range = (Range) val; final Comparable min = range.getMin(); final Comparable max = range.getMax(); - Predicate p = (T t) -> { - Comparable rs = (Comparable) attr.get(t); - if (rs == null) return false; - if (min != null && min.compareTo(rs) >= 0) return false; - return !(max != null && max.compareTo(rs) <= 0); + if (express == BETWEEN) return new Predicate() { + + @Override + public boolean test(T t) { + Comparable rs = (Comparable) attr.get(t); + if (rs == null) return false; + if (min != null && min.compareTo(rs) >= 0) return false; + return !(max != null && max.compareTo(rs) <= 0); + } + + @Override + public String toString() { + return attr.field() + " BETWEEN " + min + " AND " + max; + } }; - if (express == NOTBETWEEN) p = p.negate(); - return p; + if (express == NOTBETWEEN) return new Predicate() { + + @Override + public boolean test(T t) { + Comparable rs = (Comparable) attr.get(t); + if (rs == null) return true; + if (min != null && min.compareTo(rs) >= 0) return true; + return (max != null && max.compareTo(rs) <= 0); + } + + @Override + public String toString() { + return attr.field() + " NOT BETWEEN " + min + " AND " + max; + } + }; + return null; case IN: case NOTIN: Predicate filter; if (val instanceof Collection) { - filter = (T t) -> { - Object rs = attr.get(t); - return rs != null && ((Collection) val).contains(rs); + filter = new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + return rs != null && ((Collection) val).contains(rs); + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + val; + } }; } else { Class type = val.getClass(); if (type == int[].class) { - filter = (T t) -> { - Object rs = attr.get(t); - if (rs == null) return false; - return Arrays.binarySearch((int[]) val, (int) rs) >= 0; + filter = new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + if (rs == null) return false; + return Arrays.binarySearch((int[]) val, (int) rs) >= 0; + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((int[]) val); + } }; } else if (type == short[].class) { - filter = (T t) -> { - Object rs = attr.get(t); - if (rs == null) return false; - return Arrays.binarySearch((short[]) val, (short) rs) >= 0; + filter = new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + if (rs == null) return false; + return Arrays.binarySearch((short[]) val, (short) rs) >= 0; + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((short[]) val); + } }; } else if (type == long[].class) { - filter = (T t) -> { - Object rs = attr.get(t); - if (rs == null) return false; - return Arrays.binarySearch((long[]) val, (long) rs) >= 0; + filter = new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + if (rs == null) return false; + return Arrays.binarySearch((long[]) val, (long) rs) >= 0; + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((long[]) val); + } }; } else if (type == float[].class) { - filter = (T t) -> { - Object rs = attr.get(t); - if (rs == null) return false; - return Arrays.binarySearch((float[]) val, (float) rs) >= 0; + filter = new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + if (rs == null) return false; + return Arrays.binarySearch((float[]) val, (float) rs) >= 0; + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((float[]) val); + } }; } else if (type == double[].class) { - filter = (T t) -> { - Object rs = attr.get(t); - if (rs == null) return false; - return Arrays.binarySearch((double[]) val, (double) rs) >= 0; + filter = new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + if (rs == null) return false; + return Arrays.binarySearch((double[]) val, (double) rs) >= 0; + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((double[]) val); + } }; } else { - filter = (T t) -> { - Object rs = attr.get(t); - return rs != null && Arrays.binarySearch((Object[]) val, rs) > -1; + filter = new Predicate() { + + @Override + public boolean test(T t) { + Object rs = attr.get(t); + return rs != null && Arrays.binarySearch((Object[]) val, rs) >= 0; + } + + @Override + public String toString() { + return attr.field() + ' ' + express.value() + ' ' + Arrays.toString((Object[]) val); + } }; } } - if (express == NOTIN) filter = filter.negate(); + if (express == NOTIN) { + final Predicate filter2 = filter; + filter = new Predicate() { + + @Override + public boolean test(T t) { + return !filter2.test(t); + } + + @Override + public String toString() { + return filter2.toString(); + } + }; + } return filter; } return null;