mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 06:12:43 +00:00
Refactor - clean up CQueryPlan, CQueryPlanStats
This commit is contained in:
@@ -11,10 +11,10 @@ import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
import com.avaje.ebeaninternal.server.type.DataReader;
|
||||
import com.avaje.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
import com.avaje.ebeaninternal.server.type.RsetDataReader;
|
||||
import com.avaje.ebeaninternal.server.util.Md5;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@@ -80,38 +80,32 @@ public class CQueryPlan {
|
||||
/**
|
||||
* Create a query plan based on a OrmQueryRequest.
|
||||
*/
|
||||
public CQueryPlan(OrmQueryRequest<?> request, SqlLimitResponse sqlRes, SqlTree sqlTree, boolean rawSql, String logWhereSql) {
|
||||
CQueryPlan(OrmQueryRequest<?> request, SqlLimitResponse sqlRes, SqlTree sqlTree, boolean rawSql, String logWhereSql) {
|
||||
|
||||
this.server = request.getServer();
|
||||
this.dataTimeZone = server.getDataTimeZone();
|
||||
this.beanType = request.getBeanDescriptor().getBeanType();
|
||||
this.stats = new CQueryPlanStats(this, server.isCollectQueryOrigins());
|
||||
this.planKey = request.getQueryPlanKey();
|
||||
this.autoTuned = request.getQuery().isAutoTuned();
|
||||
this.asOfTableCount = request.getQuery().getAsOfTableCount();
|
||||
if (sqlRes != null) {
|
||||
this.sql = sqlRes.getSql();
|
||||
this.rowNumberIncluded = sqlRes.isIncludesRowNumberColumn();
|
||||
} else {
|
||||
this.sql = null;
|
||||
this.rowNumberIncluded = false;
|
||||
}
|
||||
this.sql = sqlRes.getSql();
|
||||
this.rowNumberIncluded = sqlRes.isIncludesRowNumberColumn();
|
||||
this.sqlTree = sqlTree;
|
||||
this.rawSql = rawSql;
|
||||
this.logWhereSql = logWhereSql;
|
||||
this.encryptedProps = sqlTree.getEncryptedProps();
|
||||
this.stats = new CQueryPlanStats(this, server.isCollectQueryOrigins());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a query plan for a raw sql query.
|
||||
*/
|
||||
public CQueryPlan(OrmQueryRequest<?> request, String sql, SqlTree sqlTree,
|
||||
CQueryPlan(OrmQueryRequest<?> request, String sql, SqlTree sqlTree,
|
||||
boolean rawSql, boolean rowNumberIncluded, String logWhereSql) {
|
||||
|
||||
this.server = request.getServer();
|
||||
this.dataTimeZone = server.getDataTimeZone();
|
||||
this.beanType = request.getBeanDescriptor().getBeanType();
|
||||
this.stats = new CQueryPlanStats(this, server.isCollectQueryOrigins());
|
||||
this.planKey = buildPlanKey(sql, rawSql, rowNumberIncluded, logWhereSql);
|
||||
this.autoTuned = false;
|
||||
this.asOfTableCount = 0;
|
||||
@@ -121,6 +115,7 @@ public class CQueryPlan {
|
||||
this.rowNumberIncluded = rowNumberIncluded;
|
||||
this.logWhereSql = logWhereSql;
|
||||
this.encryptedProps = sqlTree.getEncryptedProps();
|
||||
this.stats = new CQueryPlanStats(this, server.isCollectQueryOrigins());
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +139,7 @@ public class CQueryPlan {
|
||||
/**
|
||||
* Bind keys for encrypted properties if necessary returning the DataBind.
|
||||
*/
|
||||
public DataBind bindEncryptedProperties(PreparedStatement stmt, Connection conn) throws SQLException {
|
||||
DataBind bindEncryptedProperties(PreparedStatement stmt, Connection conn) throws SQLException {
|
||||
DataBind dataBind = new DataBind(dataTimeZone, stmt, conn);
|
||||
if (encryptedProps != null) {
|
||||
for (int i = 0; i < encryptedProps.length; i++) {
|
||||
@@ -155,22 +150,22 @@ public class CQueryPlan {
|
||||
return dataBind;
|
||||
}
|
||||
|
||||
public int getAsOfTableCount() {
|
||||
int getAsOfTableCount() {
|
||||
return asOfTableCount;
|
||||
}
|
||||
|
||||
public boolean isAutoTuned() {
|
||||
boolean isAutoTuned() {
|
||||
return autoTuned;
|
||||
}
|
||||
|
||||
public CQueryPlanKey getPlanKey() {
|
||||
CQueryPlanKey getPlanKey() {
|
||||
return planKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a key used in audit logging to identify the query.
|
||||
*/
|
||||
public String getAuditQueryKey() {
|
||||
String getAuditQueryKey() {
|
||||
if (auditQueryHash == null) {
|
||||
// volatile object assignment (so happy for multithreaded access)
|
||||
auditQueryHash = calcAuditQueryKey();
|
||||
@@ -188,32 +183,18 @@ public class CQueryPlan {
|
||||
*/
|
||||
private String getSqlMd5Hash() {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] digest = md.digest(sql.getBytes("UTF-8"));
|
||||
return digestToHex(digest);
|
||||
return Md5.hash(sql);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to MD5 hash the rawSql query", e);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the digest into a hex value.
|
||||
*/
|
||||
private String digestToHex(byte[] digest) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < digest.length; i++) {
|
||||
sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public SqlTree getSqlTree() {
|
||||
SqlTree getSqlTree() {
|
||||
return sqlTree;
|
||||
}
|
||||
|
||||
@@ -221,11 +202,11 @@ public class CQueryPlan {
|
||||
return rawSql;
|
||||
}
|
||||
|
||||
public boolean isRowNumberIncluded() {
|
||||
boolean isRowNumberIncluded() {
|
||||
return rowNumberIncluded;
|
||||
}
|
||||
|
||||
public String getLogWhereSql() {
|
||||
String getLogWhereSql() {
|
||||
return logWhereSql;
|
||||
}
|
||||
|
||||
@@ -239,7 +220,7 @@ public class CQueryPlan {
|
||||
/**
|
||||
* Register an execution time against this query plan;
|
||||
*/
|
||||
public void executionTime(long loadedBeanCount, long timeMicros, ObjectGraphNode objectGraphNode) {
|
||||
void executionTime(long loadedBeanCount, long timeMicros, ObjectGraphNode objectGraphNode) {
|
||||
|
||||
stats.add(loadedBeanCount, timeMicros, objectGraphNode);
|
||||
if (objectGraphNode != null) {
|
||||
@@ -266,7 +247,7 @@ public class CQueryPlan {
|
||||
return stats.getLastQueryTime();
|
||||
}
|
||||
|
||||
public BeanProperty getSingleProperty() {
|
||||
BeanProperty getSingleProperty() {
|
||||
return sqlTree.getRootNode().getSingleProperty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ public final class CQueryPlanStats {
|
||||
/**
|
||||
* Construct for a given query plan.
|
||||
*/
|
||||
public CQueryPlanStats(CQueryPlan queryPlan, boolean collectQueryOrigins) {
|
||||
CQueryPlanStats(CQueryPlan queryPlan, boolean collectQueryOrigins) {
|
||||
|
||||
this.queryPlan = queryPlan;
|
||||
this.origins = !collectQueryOrigins ? null : new ConcurrentHashMap<ObjectGraphNode, LongAdder>();
|
||||
this.origins = !collectQueryOrigins ? null : new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,14 +92,14 @@ public final class CQueryPlanStats {
|
||||
/**
|
||||
* Return the last time this query was executed.
|
||||
*/
|
||||
public long getLastQueryTime() {
|
||||
long getLastQueryTime() {
|
||||
return lastQueryTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Snapshot of the query execution statistics potentially resetting the internal counters.
|
||||
*/
|
||||
public Snapshot getSnapshot(boolean reset) {
|
||||
Snapshot getSnapshot(boolean reset) {
|
||||
|
||||
List<MetaQueryPlanOriginCount> origins = getOrigins(reset);
|
||||
|
||||
@@ -119,7 +119,7 @@ public final class CQueryPlanStats {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<MetaQueryPlanOriginCount> list = new ArrayList<MetaQueryPlanOriginCount>();
|
||||
List<MetaQueryPlanOriginCount> list = new ArrayList<>();
|
||||
|
||||
for (Entry<ObjectGraphNode, LongAdder> entry : origins.entrySet()) {
|
||||
if (reset) {
|
||||
@@ -138,7 +138,7 @@ public final class CQueryPlanStats {
|
||||
private final ObjectGraphNode objectGraphNode;
|
||||
private final long count;
|
||||
|
||||
public OriginSnapshot(ObjectGraphNode objectGraphNode, long count) {
|
||||
OriginSnapshot(ObjectGraphNode objectGraphNode, long count) {
|
||||
this.objectGraphNode = objectGraphNode;
|
||||
this.count = count;
|
||||
}
|
||||
@@ -172,7 +172,7 @@ public final class CQueryPlanStats {
|
||||
private final long lastQueryTime;
|
||||
private final List<MetaQueryPlanOriginCount> origins;
|
||||
|
||||
public Snapshot(CQueryPlan queryPlan, long count, long totalTime, long totalBeans, long maxTime, long startTime, long lastQueryTime,
|
||||
Snapshot(CQueryPlan queryPlan, long count, long totalTime, long totalBeans, long maxTime, long startTime, long lastQueryTime,
|
||||
List<MetaQueryPlanOriginCount> origins) {
|
||||
|
||||
this.queryPlan = queryPlan;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.avaje.ebeaninternal.server.util;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class Md5 {
|
||||
|
||||
/**
|
||||
* Return the MD5 hash of the underlying sql.
|
||||
*/
|
||||
public static String hash(String content) {
|
||||
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] digest = md.digest(content.getBytes("UTF-8"));
|
||||
return digestToHex(digest);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("MD5 hashing failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the digest into a hex value.
|
||||
*/
|
||||
private static String digestToHex(byte[] digest) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < digest.length; i++) {
|
||||
sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.avaje.ebeaninternal.server.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class Md5Test {
|
||||
|
||||
@Test
|
||||
public void hash() throws Exception {
|
||||
|
||||
String content = "some random content we wish to hash";
|
||||
String hash1 = Md5.hash(content);
|
||||
String hash2 = Md5.hash(content);
|
||||
assertEquals(hash1, hash2);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user