From 697837ce0ce646a9ca45a0afc3a2e1e368c712f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Knut=20Olav=20L=C3=B8ite?= Date: Sat, 5 Dec 2020 10:35:22 +0100 Subject: [PATCH] feat: expose more methods from Connection in JDBC (#255) * feat: expose more methods from Connection in JDBC More methods from the Connection API should be exposed in the Cloud Spanner JDBC Connection interface to make it easier to execute read-only transactions with specific timestamp bounds. Towards #253 * clirr: add ignored differences --- clirr-ignored-differences.xml | 52 +++++++++ .../jdbc/CloudSpannerJdbcConnection.java | 110 ++++++++++++++++++ .../cloud/spanner/jdbc/JdbcConnection.java | 63 ++++++++++ 3 files changed, 225 insertions(+) diff --git a/clirr-ignored-differences.xml b/clirr-ignored-differences.xml index cfa11365..7e243773 100644 --- a/clirr-ignored-differences.xml +++ b/clirr-ignored-differences.xml @@ -42,4 +42,56 @@ 8001 com/google/cloud/spanner/jdbc/UnitOfWork$UnitOfWorkState + + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + com.google.cloud.spanner.connection.AutocommitDmlMode getAutocommitDmlMode() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + java.lang.String getOptimizerVersion() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + com.google.cloud.spanner.TimestampBound getReadOnlyStaleness() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + com.google.cloud.spanner.connection.TransactionMode getTransactionMode() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + boolean isInTransaction() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + boolean isTransactionStarted() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + void setAutocommitDmlMode(com.google.cloud.spanner.connection.AutocommitDmlMode) + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + void setOptimizerVersion(java.lang.String) + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + void setReadOnlyStaleness(com.google.cloud.spanner.TimestampBound) + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + void setTransactionMode(com.google.cloud.spanner.connection.TransactionMode) + diff --git a/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java b/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java index dc52ca35..f13a64f5 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java @@ -19,6 +19,9 @@ import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.TimestampBound; +import com.google.cloud.spanner.connection.AutocommitDmlMode; +import com.google.cloud.spanner.connection.TransactionMode; import java.sql.Connection; import java.sql.SQLException; import java.sql.Timestamp; @@ -34,6 +37,113 @@ */ public interface CloudSpannerJdbcConnection extends Connection { + /** + * Sets the transaction mode to use for current transaction. This method may only be called when + * in a transaction, and before the transaction is actually started, i.e. before any statements + * have been executed in the transaction. + * + * @param transactionMode The transaction mode to use for the current transaction. + * + */ + void setTransactionMode(TransactionMode transactionMode) throws SQLException; + + /** + * @return the transaction mode of the current transaction. This method may only be called when + * the connection is in a transaction. + */ + TransactionMode getTransactionMode() throws SQLException; + + /** + * Sets the mode for executing DML statements in autocommit mode for this connection. This setting + * is only used when the connection is in autocommit mode, and may only be set while the + * transaction is in autocommit mode and not in a temporary transaction. The autocommit + * transaction mode is reset to its default value of {@link AutocommitDmlMode#TRANSACTIONAL} when + * autocommit mode is changed on the connection. + * + * @param mode The DML autocommit mode to use + * + */ + void setAutocommitDmlMode(AutocommitDmlMode mode) throws SQLException; + + /** + * @return the current {@link AutocommitDmlMode} setting for this connection. This method may only + * be called on a connection that is in autocommit mode and not while in a temporary + * transaction. + */ + AutocommitDmlMode getAutocommitDmlMode() throws SQLException; + + /** + * Sets the staleness to use for the current read-only transaction. This method may only be called + * when the transaction mode of the current transaction is {@link + * TransactionMode#READ_ONLY_TRANSACTION} and there is no transaction that has started, or when + * the connection is in read-only and autocommit mode. + * + * @param staleness The staleness to use for the current but not yet started read-only transaction + */ + void setReadOnlyStaleness(TimestampBound staleness) throws SQLException; + + /** + * @return the read-only staleness setting for the current read-only transaction. This method may + * only be called when the current transaction is a read-only transaction, or when the + * connection is in read-only and autocommit mode. + */ + TimestampBound getReadOnlyStaleness() throws SQLException; + + /** + * Sets the query optimizer version to use for this connection. + * + * @param optimizerVersion The query optimizer version to use. Must be a valid optimizer version + * number, the string LATEST or an empty string. The empty string will instruct + * the connection to use the optimizer version that is defined in the environment variable + * SPANNER_OPTIMIZER_VERSION. If no value is specified in the environment + * variable, the default query optimizer of Cloud Spanner is used. + */ + void setOptimizerVersion(String optimizerVersion) throws SQLException; + + /** + * Gets the current query optimizer version of this connection. + * + * @return The query optimizer version that is currently used by this connection. + */ + String getOptimizerVersion() throws SQLException; + + /** + * @return true if this connection has a transaction (that has not necessarily + * started). This method will only return false when the {@link Connection} is in autocommit + * mode and no explicit transaction has been started by calling {@link + * Connection#beginTransaction()}. If the {@link Connection} is not in autocommit mode, there + * will always be a transaction. + */ + boolean isInTransaction() throws SQLException; + + /** + * @return true if this connection has a transaction that has started. A transaction + * is automatically started by the first statement that is executed in the transaction. + */ + boolean isTransactionStarted() throws SQLException; + /** * @return the commit {@link Timestamp} of the last read/write transaction. If the last * transaction was not a read/write transaction, or a read/write transaction that did not diff --git a/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java b/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java index 4e231809..3d79c5ef 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java @@ -19,8 +19,11 @@ import com.google.api.client.util.Preconditions; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.SpannerException; +import com.google.cloud.spanner.TimestampBound; +import com.google.cloud.spanner.connection.AutocommitDmlMode; import com.google.cloud.spanner.connection.ConnectionOptions; import com.google.cloud.spanner.connection.StatementParser; +import com.google.cloud.spanner.connection.TransactionMode; import com.google.common.base.Function; import com.google.common.collect.Iterators; import java.sql.Array; @@ -74,6 +77,66 @@ public String nativeSQL(String sql) throws SQLException { .sqlWithNamedParameters; } + @Override + public void setTransactionMode(TransactionMode mode) throws SQLException { + checkClosed(); + getSpannerConnection().setTransactionMode(mode); + } + + @Override + public TransactionMode getTransactionMode() throws SQLException { + checkClosed(); + return getSpannerConnection().getTransactionMode(); + } + + @Override + public void setAutocommitDmlMode(AutocommitDmlMode mode) throws SQLException { + checkClosed(); + getSpannerConnection().setAutocommitDmlMode(mode); + } + + @Override + public AutocommitDmlMode getAutocommitDmlMode() throws SQLException { + checkClosed(); + return getSpannerConnection().getAutocommitDmlMode(); + } + + @Override + public void setReadOnlyStaleness(TimestampBound staleness) throws SQLException { + checkClosed(); + getSpannerConnection().setReadOnlyStaleness(staleness); + } + + @Override + public TimestampBound getReadOnlyStaleness() throws SQLException { + checkClosed(); + return getSpannerConnection().getReadOnlyStaleness(); + } + + @Override + public void setOptimizerVersion(String optimizerVersion) throws SQLException { + checkClosed(); + getSpannerConnection().setOptimizerVersion(optimizerVersion); + } + + @Override + public String getOptimizerVersion() throws SQLException { + checkClosed(); + return getSpannerConnection().getOptimizerVersion(); + } + + @Override + public boolean isInTransaction() throws SQLException { + checkClosed(); + return getSpannerConnection().isInTransaction(); + } + + @Override + public boolean isTransactionStarted() throws SQLException { + checkClosed(); + return getSpannerConnection().isTransactionStarted(); + } + @Override public void setAutoCommit(boolean autoCommit) throws SQLException { checkClosed();