From aabc1b64c72cce5ed11d46ab5d774f265e4305af Mon Sep 17 00:00:00 2001 From: Davy VERSTAPPEN Date: Wed, 3 Jul 2013 08:23:45 +0200 Subject: [PATCH] Support optimized "/* ping */" requests. --- src/main/java/org/mariadb/jdbc/MySQLStatement.java | 47 +++++++++++++++--- src/main/java/org/mariadb/jdbc/PingResultSet.java | 22 +++++++++ .../common/queryresults/PingQueryResult.java | 32 +++++++++++++ .../common/queryresults/ResultSetType.java | 2 +- .../org/mariadb/jdbc/CommentedPingQueryTest.java | 56 ++++++++++++++++++++++ 5 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/mariadb/jdbc/PingResultSet.java create mode 100644 src/main/java/org/mariadb/jdbc/internal/common/queryresults/PingQueryResult.java create mode 100644 src/test/java/org/mariadb/jdbc/CommentedPingQueryTest.java diff --git a/src/main/java/org/mariadb/jdbc/MySQLStatement.java b/src/main/java/org/mariadb/jdbc/MySQLStatement.java index 6bc3405..9ed4daf 100644 --- a/src/main/java/org/mariadb/jdbc/MySQLStatement.java +++ b/src/main/java/org/mariadb/jdbc/MySQLStatement.java @@ -55,6 +55,7 @@ import org.mariadb.jdbc.internal.common.Utils; import org.mariadb.jdbc.internal.common.query.MySQLQuery; import org.mariadb.jdbc.internal.common.query.Query; import org.mariadb.jdbc.internal.common.queryresults.ModifyQueryResult; +import org.mariadb.jdbc.internal.common.queryresults.PingQueryResult; import org.mariadb.jdbc.internal.common.queryresults.QueryResult; import org.mariadb.jdbc.internal.common.queryresults.ResultSetType; import org.mariadb.jdbc.internal.mysql.MySQLProtocol; @@ -331,7 +332,31 @@ public class MySQLStatement implements Statement { * @throws SQLException */ public boolean execute(String queryString) throws SQLException { - return execute(stringToQuery(queryString)); + if (isOptimizedPingQuery(queryString)) { + return ping(); + } else { + return execute(stringToQuery(queryString)); + } + } + + protected boolean isOptimizedPingQuery(String queryString) { + return queryString.startsWith("/* ping */"); + } + + protected boolean ping() throws SQLException { + try { + this.queryResult = null; + synchronized (protocol) { + boolean result = protocol.ping(); + if (result) { + queryResult = new PingQueryResult(); + } + return result; + } + } catch (QueryException e) { + SQLExceptionMapper.throwException(e, this.connection, this); + return false; + } } /** @@ -354,10 +379,14 @@ public class MySQLStatement implements Statement { * @throws SQLException if something went wrong */ public ResultSet executeQuery(String queryString) throws SQLException { - return executeQuery(stringToQuery(queryString)); + if (isOptimizedPingQuery(queryString)) { + ping(); + return getResultSet(); + } else { + return executeQuery(stringToQuery(queryString)); + } } - /** * Releases this Statement object's database and JDBC resources immediately instead of waiting for this * to happen when it is automatically closed. It is generally good practice to release resources as soon as you are @@ -889,10 +918,16 @@ public class MySQLStatement implements Statement { public ResultSet getResultSet() throws SQLException { - if (queryResult == null || queryResult.getResultSetType() != ResultSetType.SELECT) { - return null; /* Result is an update count, or there are no more results */ + if (queryResult == null) { + return null; } - return new MySQLResultSet(queryResult,this,protocol); + switch (queryResult.getResultSetType()) { + case SELECT: + return new MySQLResultSet(queryResult,this,protocol); + case PING: + return new PingResultSet(); + } + return null; } public int getUpdateCount() throws SQLException { diff --git a/src/main/java/org/mariadb/jdbc/PingResultSet.java b/src/main/java/org/mariadb/jdbc/PingResultSet.java new file mode 100644 index 0000000..f8d3a83 --- /dev/null +++ b/src/main/java/org/mariadb/jdbc/PingResultSet.java @@ -0,0 +1,22 @@ +package org.mariadb.jdbc; + +import java.sql.SQLException; + +public class PingResultSet extends MySQLResultSet { + + private boolean nextCalled = false; + + protected PingResultSet() { + } + + @Override + public boolean next() throws SQLException { + if (nextCalled) { + return false; + } else { + nextCalled = true; + return true; + } + } + +} diff --git a/src/main/java/org/mariadb/jdbc/internal/common/queryresults/PingQueryResult.java b/src/main/java/org/mariadb/jdbc/internal/common/queryresults/PingQueryResult.java new file mode 100644 index 0000000..124d8d6 --- /dev/null +++ b/src/main/java/org/mariadb/jdbc/internal/common/queryresults/PingQueryResult.java @@ -0,0 +1,32 @@ +package org.mariadb.jdbc.internal.common.queryresults; + +import org.mariadb.jdbc.internal.common.ColumnInformation; + +public class PingQueryResult extends QueryResult { + + @Override + public ResultSetType getResultSetType() { + return ResultSetType.PING; + } + + @Override + public short getWarnings() { + return 0; + } + + @Override + public String getMessage() { + return null; + } + + @Override + public ColumnInformation[] getColumnInformation() { + return new ColumnInformation[0]; + } + + @Override + public int getRows() { + return 1; + } + +} diff --git a/src/main/java/org/mariadb/jdbc/internal/common/queryresults/ResultSetType.java b/src/main/java/org/mariadb/jdbc/internal/common/queryresults/ResultSetType.java index 098f442..6c4bc38 100644 --- a/src/main/java/org/mariadb/jdbc/internal/common/queryresults/ResultSetType.java +++ b/src/main/java/org/mariadb/jdbc/internal/common/queryresults/ResultSetType.java @@ -51,5 +51,5 @@ package org.mariadb.jdbc.internal.common.queryresults; public enum ResultSetType { - MODIFY, SELECT, GENERATED + MODIFY, SELECT, GENERATED, PING } diff --git a/src/test/java/org/mariadb/jdbc/CommentedPingQueryTest.java b/src/test/java/org/mariadb/jdbc/CommentedPingQueryTest.java new file mode 100644 index 0000000..9267eb7 --- /dev/null +++ b/src/test/java/org/mariadb/jdbc/CommentedPingQueryTest.java @@ -0,0 +1,56 @@ +package org.mariadb.jdbc; + +import org.junit.Test; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import static org.junit.Assert.*; + + +// TODO add tests that check the per-connection ping counter +public class CommentedPingQueryTest extends BaseTest { + + @Test + public void testExecuteQuery() throws SQLException { + Statement statement = connection.createStatement(); + assertPingResultSet(statement.executeQuery("/* ping */")); + } + + @Test + public void testNormalStatement() throws SQLException { + Statement statement = connection.createStatement(); + boolean hasResult = statement.execute("/* ping */"); + assertTrue(hasResult); + assertPingResultSet(statement.getResultSet()); + } + + // TODO also implement for PreparedStatement? +// @Test +// public void testPreparedStatement() throws SQLException { +// PreparedStatement statement = connection.prepareStatement("/* ping */"); +// boolean hasResult = statement.execute(); +// assertTrue(hasResult); +// assertPingResultSet(statement.getResultSet()); +// } + + private void assertPingResultSet(ResultSet resultSet) throws SQLException { + assertNotNull(resultSet); + try { + assertEquals(1, countRows(resultSet)); + } finally { + resultSet.close(); + } + } + + private int countRows(ResultSet resultSet) throws SQLException { + int count = 0; + while (resultSet.next()) { + count++; + } + return count; + } + +} -- 1.8.2.1