From 8eb5f56f42e73e26c739731edc034d998fc00747 Mon Sep 17 00:00:00 2001 From: Redkale <8730487+redkale@users.noreply.github.com> Date: Tue, 14 Jan 2020 10:59:45 +0800 Subject: [PATCH] --- src/org/redkale/source/EntityCache.java | 227 +++++++++++++++--------- 1 file changed, 146 insertions(+), 81 deletions(-) diff --git a/src/org/redkale/source/EntityCache.java b/src/org/redkale/source/EntityCache.java index 0087cfa9c..9f17026f2 100644 --- a/src/org/redkale/source/EntityCache.java +++ b/src/org/redkale/source/EntityCache.java @@ -311,91 +311,156 @@ public final class EntityCache { } public Map queryColumnMap(final ColumnNode[] funcNodes, final String[] groupByColumns, FilterNode node) { - throw new UnsupportedOperationException("Not supported yet."); + final Predicate filter = node == null ? null : node.createPredicate(this); + Stream stream = this.list.stream(); + if (filter != null) stream = stream.filter(filter); + final Attribute[] attrs = new Attribute[groupByColumns.length]; + for (int i = 0; i < groupByColumns.length; i++) { + attrs[i] = info.getAttribute(groupByColumns[i]); + } + final Map valmap = new HashMap<>(); + Function func = t -> { + StringBuilder sb = new StringBuilder(); + final Serializable[] vals = new Serializable[attrs.length]; + for (int i = 0; i < attrs.length; i++) { + vals[i] = attrs[i].get(t); + sb.append((char) 20).append(vals[i]); + } + final String key = sb.toString(); + if (!valmap.containsKey(key)) valmap.put(key, vals); + return valmap.get(key); + }; + Map> listmap = stream.collect(Collectors.groupingBy(func)); + final Map rsmap = new HashMap<>(listmap.size()); + listmap.forEach((k, l) -> rsmap.put(k, queryColumnNumbers(l, funcNodes))); + return rsmap; + } + + private Number[] queryColumnNumbers(final List list, final ColumnNode[] funcNodes) { + if(true) throw new UnsupportedOperationException("Not supported yet."); + Number[] rs = new Number[funcNodes.length]; + for (int i = 0; i < rs.length; i++) { + rs[i] = queryColumnNumber(list, funcNodes[i]); + } + return rs; + } + + private Number queryColumnNumber(final List list, final ColumnNode funcNode) { + if (funcNode instanceof ColumnFuncNode) { + return queryColumnNumber(list, (ColumnFuncNode) funcNode); + } else if (funcNode instanceof ColumnNodeValue) { + return queryColumnNumber(list, (ColumnNodeValue) funcNode); + } else { + return null; + } + } + + private Number queryColumnNumber(final List list, final ColumnFuncNode funcNode) { + if (funcNode.getValue() instanceof String) { + final Attribute attr = info.getAttribute((String) funcNode.getValue()); + final Function attrFunc = x -> (Number) attr.get(x); + return getNumberResult(list, funcNode.getFunc(), null, attr.type(), attrFunc, (FilterNode) null); + } + Number num = null; + if (funcNode.getValue() instanceof ColumnFuncNode) { + num = queryColumnNumber(list, (ColumnFuncNode) funcNode.getValue()); + } else if (funcNode.getValue() instanceof ColumnNodeValue) { + num = queryColumnNumber(list, (ColumnNodeValue) funcNode.getValue()); + } + return num; + } + + private Number queryColumnNumber(final List list, final ColumnNodeValue nodeValue) { + return null; + } + + private Number getNumberResult(final Collection entityList, final FilterFunc func, final Number defResult, final Class attrType, final Function attrFunc, final FilterNode node) { + final Predicate filter = node == null ? null : node.createPredicate(this); + Stream stream = entityList.stream(); + if (filter != null) stream = stream.filter(filter); + switch (func) { + case AVG: + if (attrType == int.class || attrType == Integer.class || attrType == AtomicInteger.class) { + OptionalDouble rs = stream.mapToInt(x -> ((Number) attrFunc.apply(x)).intValue()).average(); + return rs.isPresent() ? (int) rs.getAsDouble() : defResult; + } else if (attrType == long.class || attrType == Long.class || attrType == AtomicLong.class) { + OptionalDouble rs = stream.mapToLong(x -> ((Number) attrFunc.apply(x)).longValue()).average(); + return rs.isPresent() ? (long) rs.getAsDouble() : defResult; + } else if (attrType == short.class || attrType == Short.class) { + OptionalDouble rs = stream.mapToInt(x -> ((Short) attrFunc.apply(x)).intValue()).average(); + return rs.isPresent() ? (short) rs.getAsDouble() : defResult; + } else if (attrType == float.class || attrType == Float.class) { + OptionalDouble rs = stream.mapToDouble(x -> ((Float) attrFunc.apply(x)).doubleValue()).average(); + return rs.isPresent() ? (float) rs.getAsDouble() : defResult; + } else if (attrType == double.class || attrType == Double.class) { + OptionalDouble rs = stream.mapToDouble(x -> (Double) attrFunc.apply(x)).average(); + return rs.isPresent() ? rs.getAsDouble() : defResult; + } + throw new RuntimeException("getNumberResult error(type:" + type + ", attr.type: " + attrType); + case COUNT: + return stream.count(); + case DISTINCTCOUNT: + return stream.map(x -> attrFunc.apply(x)).distinct().count(); + + case MAX: + if (attrType == int.class || attrType == Integer.class || attrType == AtomicInteger.class) { + OptionalInt rs = stream.mapToInt(x -> ((Number) attrFunc.apply(x)).intValue()).max(); + return rs.isPresent() ? rs.getAsInt() : defResult; + } else if (attrType == long.class || attrType == Long.class || attrType == AtomicLong.class) { + OptionalLong rs = stream.mapToLong(x -> ((Number) attrFunc.apply(x)).longValue()).max(); + return rs.isPresent() ? rs.getAsLong() : defResult; + } else if (attrType == short.class || attrType == Short.class) { + OptionalInt rs = stream.mapToInt(x -> ((Short) attrFunc.apply(x)).intValue()).max(); + return rs.isPresent() ? (short) rs.getAsInt() : defResult; + } else if (attrType == float.class || attrType == Float.class) { + OptionalDouble rs = stream.mapToDouble(x -> ((Float) attrFunc.apply(x)).doubleValue()).max(); + return rs.isPresent() ? (float) rs.getAsDouble() : defResult; + } else if (attrType == double.class || attrType == Double.class) { + OptionalDouble rs = stream.mapToDouble(x -> (Double) attrFunc.apply(x)).max(); + return rs.isPresent() ? rs.getAsDouble() : defResult; + } + throw new RuntimeException("getNumberResult error(type:" + type + ", attr.type: " + attrType); + + case MIN: + if (attrType == int.class || attrType == Integer.class || attrType == AtomicInteger.class) { + OptionalInt rs = stream.mapToInt(x -> ((Number) attrFunc.apply(x)).intValue()).min(); + return rs.isPresent() ? rs.getAsInt() : defResult; + } else if (attrType == long.class || attrType == Long.class || attrType == AtomicLong.class) { + OptionalLong rs = stream.mapToLong(x -> ((Number) attrFunc.apply(x)).longValue()).min(); + return rs.isPresent() ? rs.getAsLong() : defResult; + } else if (attrType == short.class || attrType == Short.class) { + OptionalInt rs = stream.mapToInt(x -> ((Short) attrFunc.apply(x)).intValue()).min(); + return rs.isPresent() ? (short) rs.getAsInt() : defResult; + } else if (attrType == float.class || attrType == Float.class) { + OptionalDouble rs = stream.mapToDouble(x -> ((Float) attrFunc.apply(x)).doubleValue()).min(); + return rs.isPresent() ? (float) rs.getAsDouble() : defResult; + } else if (attrType == double.class || attrType == Double.class) { + OptionalDouble rs = stream.mapToDouble(x -> (Double) attrFunc.apply(x)).min(); + return rs.isPresent() ? rs.getAsDouble() : defResult; + } + throw new RuntimeException("getNumberResult error(type:" + type + ", attr.type: " + attrType); + + case SUM: + if (attrType == int.class || attrType == Integer.class || attrType == AtomicInteger.class) { + return stream.mapToInt(x -> ((Number) attrFunc.apply(x)).intValue()).sum(); + } else if (attrType == long.class || attrType == Long.class || attrType == AtomicLong.class) { + return stream.mapToLong(x -> ((Number) attrFunc.apply(x)).longValue()).sum(); + } else if (attrType == short.class || attrType == Short.class) { + return (short) stream.mapToInt(x -> ((Short) attrFunc.apply(x)).intValue()).sum(); + } else if (attrType == float.class || attrType == Float.class) { + return (float) stream.mapToDouble(x -> ((Float) attrFunc.apply(x)).doubleValue()).sum(); + } else if (attrType == double.class || attrType == Double.class) { + return stream.mapToDouble(x -> (Double) attrFunc.apply(x)).sum(); + } + throw new RuntimeException("getNumberResult error(type:" + type + ", attr.type: " + attrType); + } + return defResult; } public Number getNumberResult(final FilterFunc func, final Number defResult, final String column, final FilterNode node) { final Attribute attr = column == null ? null : info.getAttribute(column); - final Predicate filter = node == null ? null : node.createPredicate(this); - Stream stream = this.list.stream(); - if (filter != null) stream = stream.filter(filter); - switch (func) { - case AVG: - if (attr.type() == int.class || attr.type() == Integer.class || attr.type() == AtomicInteger.class) { - OptionalDouble rs = stream.mapToInt(x -> ((Number) attr.get(x)).intValue()).average(); - return rs.isPresent() ? (int) rs.getAsDouble() : defResult; - } else if (attr.type() == long.class || attr.type() == Long.class || attr.type() == AtomicLong.class) { - OptionalDouble rs = stream.mapToLong(x -> ((Number) attr.get(x)).longValue()).average(); - return rs.isPresent() ? (long) rs.getAsDouble() : defResult; - } else if (attr.type() == short.class || attr.type() == Short.class) { - OptionalDouble rs = stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).average(); - return rs.isPresent() ? (short) rs.getAsDouble() : defResult; - } else if (attr.type() == float.class || attr.type() == Float.class) { - OptionalDouble rs = stream.mapToDouble(x -> ((Float) attr.get(x)).doubleValue()).average(); - return rs.isPresent() ? (float) rs.getAsDouble() : defResult; - } else if (attr.type() == double.class || attr.type() == Double.class) { - OptionalDouble rs = stream.mapToDouble(x -> (Double) attr.get(x)).average(); - return rs.isPresent() ? rs.getAsDouble() : defResult; - } - throw new RuntimeException("getNumberResult error(type:" + type + ", attr.declaringClass: " + attr.declaringClass() + ", attr.field: " + attr.field() + ", attr.type: " + attr.type()); - case COUNT: - return stream.count(); - case DISTINCTCOUNT: - return stream.map(x -> attr.get(x)).distinct().count(); - - case MAX: - if (attr.type() == int.class || attr.type() == Integer.class || attr.type() == AtomicInteger.class) { - OptionalInt rs = stream.mapToInt(x -> ((Number) attr.get(x)).intValue()).max(); - return rs.isPresent() ? rs.getAsInt() : defResult; - } else if (attr.type() == long.class || attr.type() == Long.class || attr.type() == AtomicLong.class) { - OptionalLong rs = stream.mapToLong(x -> ((Number) attr.get(x)).longValue()).max(); - return rs.isPresent() ? rs.getAsLong() : defResult; - } else if (attr.type() == short.class || attr.type() == Short.class) { - OptionalInt rs = stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).max(); - return rs.isPresent() ? (short) rs.getAsInt() : defResult; - } else if (attr.type() == float.class || attr.type() == Float.class) { - OptionalDouble rs = stream.mapToDouble(x -> ((Float) attr.get(x)).doubleValue()).max(); - return rs.isPresent() ? (float) rs.getAsDouble() : defResult; - } else if (attr.type() == double.class || attr.type() == Double.class) { - OptionalDouble rs = stream.mapToDouble(x -> (Double) attr.get(x)).max(); - return rs.isPresent() ? rs.getAsDouble() : defResult; - } - throw new RuntimeException("getNumberResult error(type:" + type + ", attr.declaringClass: " + attr.declaringClass() + ", attr.field: " + attr.field() + ", attr.type: " + attr.type()); - - case MIN: - if (attr.type() == int.class || attr.type() == Integer.class || attr.type() == AtomicInteger.class) { - OptionalInt rs = stream.mapToInt(x -> ((Number) attr.get(x)).intValue()).min(); - return rs.isPresent() ? rs.getAsInt() : defResult; - } else if (attr.type() == long.class || attr.type() == Long.class || attr.type() == AtomicLong.class) { - OptionalLong rs = stream.mapToLong(x -> ((Number) attr.get(x)).longValue()).min(); - return rs.isPresent() ? rs.getAsLong() : defResult; - } else if (attr.type() == short.class || attr.type() == Short.class) { - OptionalInt rs = stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).min(); - return rs.isPresent() ? (short) rs.getAsInt() : defResult; - } else if (attr.type() == float.class || attr.type() == Float.class) { - OptionalDouble rs = stream.mapToDouble(x -> ((Float) attr.get(x)).doubleValue()).min(); - return rs.isPresent() ? (float) rs.getAsDouble() : defResult; - } else if (attr.type() == double.class || attr.type() == Double.class) { - OptionalDouble rs = stream.mapToDouble(x -> (Double) attr.get(x)).min(); - return rs.isPresent() ? rs.getAsDouble() : defResult; - } - throw new RuntimeException("getNumberResult error(type:" + type + ", attr.declaringClass: " + attr.declaringClass() + ", attr.field: " + attr.field() + ", attr.type: " + attr.type()); - - case SUM: - if (attr.type() == int.class || attr.type() == Integer.class || attr.type() == AtomicInteger.class) { - return stream.mapToInt(x -> ((Number) attr.get(x)).intValue()).sum(); - } else if (attr.type() == long.class || attr.type() == Long.class || attr.type() == AtomicLong.class) { - return stream.mapToLong(x -> ((Number) attr.get(x)).longValue()).sum(); - } else if (attr.type() == short.class || attr.type() == Short.class) { - return (short) stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).sum(); - } else if (attr.type() == float.class || attr.type() == Float.class) { - return (float) stream.mapToDouble(x -> ((Float) attr.get(x)).doubleValue()).sum(); - } else if (attr.type() == double.class || attr.type() == Double.class) { - return stream.mapToDouble(x -> (Double) attr.get(x)).sum(); - } - throw new RuntimeException("getNumberResult error(type:" + type + ", attr.declaringClass: " + attr.declaringClass() + ", attr.field: " + attr.field() + ", attr.type: " + attr.type()); - } - return defResult; + final Function attrFunc = x -> (Number) attr.get(x); + return getNumberResult(this.list, func, defResult, attr.type(), attrFunc, node); } public Sheet querySheet(final SelectColumn selects, final Flipper flipper, final FilterNode node) {