From 77e3346d9ea1588549ccb90d0584f4dace9efbad Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Sat, 5 Nov 2016 15:11:17 +1300 Subject: [PATCH] Refactor - clean up CQueryPlan, CQueryPlanStats --- .../server/query/CQueryPlan.java | 55 ++++++------------- .../server/query/CQueryPlanStats.java | 14 ++--- .../avaje/ebeaninternal/server/util/Md5.java | 33 +++++++++++ .../ebeaninternal/server/util/Md5Test.java | 18 ++++++ 4 files changed, 76 insertions(+), 44 deletions(-) create mode 100644 src/main/java/com/avaje/ebeaninternal/server/util/Md5.java create mode 100644 src/test/java/com/avaje/ebeaninternal/server/util/Md5Test.java diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/CQueryPlan.java b/src/main/java/com/avaje/ebeaninternal/server/query/CQueryPlan.java index 6c490bf17..93cf4d102 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/CQueryPlan.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/CQueryPlan.java @@ -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(); } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/CQueryPlanStats.java b/src/main/java/com/avaje/ebeaninternal/server/query/CQueryPlanStats.java index 88389ed8a..a46162571 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/query/CQueryPlanStats.java +++ b/src/main/java/com/avaje/ebeaninternal/server/query/CQueryPlanStats.java @@ -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(); + 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 origins = getOrigins(reset); @@ -119,7 +119,7 @@ public final class CQueryPlanStats { return Collections.emptyList(); } - List list = new ArrayList(); + List list = new ArrayList<>(); for (Entry 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 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 origins) { this.queryPlan = queryPlan; diff --git a/src/main/java/com/avaje/ebeaninternal/server/util/Md5.java b/src/main/java/com/avaje/ebeaninternal/server/util/Md5.java new file mode 100644 index 000000000..448c4b239 --- /dev/null +++ b/src/main/java/com/avaje/ebeaninternal/server/util/Md5.java @@ -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(); + } + +} diff --git a/src/test/java/com/avaje/ebeaninternal/server/util/Md5Test.java b/src/test/java/com/avaje/ebeaninternal/server/util/Md5Test.java new file mode 100644 index 000000000..2d676d13a --- /dev/null +++ b/src/test/java/com/avaje/ebeaninternal/server/util/Md5Test.java @@ -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); + } + +} \ No newline at end of file