mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1297 - ENH: Add DtoQuery ... such that we can map native SQL queries automatically into "DTO beans"
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package io.ebeaninternal.server.profile;
|
||||
|
||||
import io.ebeaninternal.metric.MetricFactory;
|
||||
import io.ebeaninternal.metric.QueryPlanCollector;
|
||||
import io.ebeaninternal.metric.QueryPlanMetric;
|
||||
import io.ebeaninternal.metric.TimedMetric;
|
||||
import io.ebeaninternal.metric.TimedMetricMap;
|
||||
|
||||
@@ -18,4 +20,14 @@ public class DMetricFactory implements MetricFactory {
|
||||
public TimedMetric createTimedMetric(String name) {
|
||||
return new DTimedMetric(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryPlanMetric createQueryPlanMetric(Class<?> type, String label, String sql) {
|
||||
return new DQueryPlanMetric(new DQueryPlanMeta(type, label, sql), createTimedMetric(label));
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryPlanCollector createCollector(boolean reset) {
|
||||
return new DQueryPlanCollector(reset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.ebeaninternal.server.profile;
|
||||
|
||||
import io.ebean.meta.MetaQueryMetric;
|
||||
import io.ebeaninternal.metric.QueryPlanCollector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class DQueryPlanCollector implements QueryPlanCollector {
|
||||
|
||||
private final boolean reset;
|
||||
|
||||
private final List<MetaQueryMetric> list = new ArrayList<>();
|
||||
|
||||
DQueryPlanCollector(boolean reset) {
|
||||
this.reset = reset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReset() {
|
||||
return reset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(MetaQueryMetric stats) {
|
||||
list.add(stats);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetaQueryMetric> complete() {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package io.ebeaninternal.server.profile;
|
||||
|
||||
class DQueryPlanMeta {
|
||||
|
||||
private final Class<?> type;
|
||||
private final String label;
|
||||
private final String sql;
|
||||
|
||||
DQueryPlanMeta(Class<?> type, String label, String sql) {
|
||||
this.type = type;
|
||||
this.label = label;
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "type:" + type + " label:" + label;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package io.ebeaninternal.server.profile;
|
||||
|
||||
import io.ebean.meta.MetaQueryMetric;
|
||||
import io.ebeaninternal.metric.QueryPlanCollector;
|
||||
import io.ebeaninternal.metric.QueryPlanMetric;
|
||||
import io.ebeaninternal.metric.TimedMetric;
|
||||
import io.ebeaninternal.metric.TimedMetricStats;
|
||||
|
||||
class DQueryPlanMetric implements QueryPlanMetric {
|
||||
|
||||
private final DQueryPlanMeta meta;
|
||||
private final TimedMetric metric;
|
||||
|
||||
DQueryPlanMetric(DQueryPlanMeta meta, TimedMetric metric) {
|
||||
this.meta = meta;
|
||||
this.metric = metric;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collect(QueryPlanCollector collector) {
|
||||
TimedMetricStats stats = metric.collect(collector.isReset());
|
||||
if (stats != null) {
|
||||
collector.add(new Stats(meta, stats));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimedMetric getMetric() {
|
||||
return metric;
|
||||
}
|
||||
|
||||
private static class Stats implements MetaQueryMetric {
|
||||
|
||||
private final DQueryPlanMeta meta;
|
||||
private final TimedMetricStats stats;
|
||||
|
||||
private Stats(DQueryPlanMeta meta, TimedMetricStats stats) {
|
||||
this.meta = meta;
|
||||
this.stats = stats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return meta +" "+ stats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType() {
|
||||
return meta.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return meta.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSql() {
|
||||
return meta.getSql();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return stats.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocation() {
|
||||
return stats.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStartTime() {
|
||||
return stats.getStartTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCount() {
|
||||
return stats.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotal() {
|
||||
return stats.getTotal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMax() {
|
||||
return stats.getMax();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMean() {
|
||||
return stats.getMean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBeanCount() {
|
||||
return stats.getBeanCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,9 @@ class DTimeMetricStats implements TimedMetricStats {
|
||||
|
||||
private final long max;
|
||||
|
||||
DTimeMetricStats(String name, long collectionStart, long count, long total, long max) {
|
||||
private final long beanCount;
|
||||
|
||||
DTimeMetricStats(String name, long collectionStart, long count, long total, long max, long beanCount) {
|
||||
this.name = name;
|
||||
this.startTime = collectionStart;
|
||||
this.count = count;
|
||||
@@ -27,6 +29,7 @@ class DTimeMetricStats implements TimedMetricStats {
|
||||
// collection is racy so sanitize the max value if it has not been set
|
||||
// this most likely would happen when count = 1 so max = mean
|
||||
this.max = max != Long.MIN_VALUE ? max : (count < 1 ? 0 : Math.round(total / count));
|
||||
this.beanCount = beanCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,7 +43,8 @@ class DTimeMetricStats implements TimedMetricStats {
|
||||
}
|
||||
sb.append("count:").append(count)
|
||||
.append(" total:").append(total)
|
||||
.append(" max:").append(max);
|
||||
.append(" max:").append(max)
|
||||
.append(" beanCount:").append(beanCount);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -99,4 +103,8 @@ class DTimeMetricStats implements TimedMetricStats {
|
||||
return (count < 1) ? 0L : Math.round((double)(total / count));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBeanCount() {
|
||||
return beanCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,17 @@ import java.util.concurrent.atomic.LongAdder;
|
||||
*/
|
||||
class DTimedMetric implements TimedMetric {
|
||||
|
||||
protected final String name;
|
||||
private final String name;
|
||||
|
||||
protected final LongAdder count = new LongAdder();
|
||||
private final LongAdder beanCount = new LongAdder();
|
||||
|
||||
protected final LongAdder total = new LongAdder();
|
||||
private final LongAdder count = new LongAdder();
|
||||
|
||||
protected final LongAccumulator max = new LongAccumulator(Math::max, Long.MIN_VALUE);
|
||||
private final LongAdder total = new LongAdder();
|
||||
|
||||
protected final AtomicLong startTime = new AtomicLong(System.currentTimeMillis());
|
||||
private final LongAccumulator max = new LongAccumulator(Math::max, Long.MIN_VALUE);
|
||||
|
||||
private final AtomicLong startTime = new AtomicLong(System.currentTimeMillis());
|
||||
|
||||
DTimedMetric(String name) {
|
||||
this.name = name;
|
||||
@@ -41,6 +43,12 @@ class DTimedMetric implements TimedMetric {
|
||||
max.accumulate(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(long micros, long beans) {
|
||||
add(micros);
|
||||
beanCount.add(beans);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return count.sum() == 0;
|
||||
@@ -75,14 +83,15 @@ class DTimedMetric implements TimedMetric {
|
||||
if (reset) {
|
||||
// Note these values are not guaranteed to be consistent wrt each other
|
||||
// but should be reasonably consistent (small time between count and total)
|
||||
final long beans = beanCount.sumThenReset();
|
||||
final long maxVal = max.getThenReset();
|
||||
final long totalVal = total.sumThenReset();
|
||||
final long countVal = count.sumThenReset();
|
||||
final long startTimeVal = startTime.getAndSet(System.currentTimeMillis());
|
||||
return new DTimeMetricStats(name, startTimeVal, countVal, totalVal, maxVal);
|
||||
return new DTimeMetricStats(name, startTimeVal, countVal, totalVal, maxVal, beans);
|
||||
|
||||
} else {
|
||||
return new DTimeMetricStats(name, startTime.get(), count.sum(), total.sum(), max.get());
|
||||
return new DTimeMetricStats(name, startTime.get(), count.sum(), total.sum(), max.get(), beanCount.sum());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,32 +105,4 @@ class DTimedMetric implements TimedMetric {
|
||||
total.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the start time.
|
||||
*/
|
||||
public long getStartTime() {
|
||||
return startTime.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of values.
|
||||
*/
|
||||
public long getCount() {
|
||||
return count.sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total of values.
|
||||
*/
|
||||
public long getTotal() {
|
||||
return total.sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the max value.
|
||||
*/
|
||||
public long getMax() {
|
||||
return max.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user