diff --git a/clirr-ignored-differences.xml b/clirr-ignored-differences.xml index e82c9929..547c9c44 100644 --- a/clirr-ignored-differences.xml +++ b/clirr-ignored-differences.xml @@ -108,4 +108,19 @@ com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection void setAutoBatchDmlUpdateCountVerification(boolean) + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + com.google.cloud.spanner.DatabaseClient getDatabaseClient() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + com.google.cloud.spanner.Spanner getSpanner() + + + 7012 + com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection + com.google.cloud.spanner.DatabaseId getDatabaseId() + diff --git a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcConnection.java b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcConnection.java index 122d4896..38430cf1 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcConnection.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/AbstractJdbcConnection.java @@ -16,6 +16,8 @@ package com.google.cloud.spanner.jdbc; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerException; @@ -68,6 +70,16 @@ abstract class AbstractJdbcConnection extends AbstractJdbcWrapper this.usesDirectExecutor = ConnectionOptionsHelper.usesDirectExecutor(options); } + @Override + public DatabaseId getDatabaseId() { + return this.options.getDatabaseId(); + } + + @Override + public DatabaseClient getDatabaseClient() { + return getSpannerConnection().getDatabaseClient(); + } + /** Return the corresponding {@link com.google.cloud.spanner.connection.Connection} */ com.google.cloud.spanner.connection.Connection getSpannerConnection() { return spanner; @@ -82,7 +94,8 @@ ConnectionOptions getConnectionOptions() { return options; } - Spanner getSpanner() { + @Override + public Spanner getSpanner() { return this.spanner.getSpanner(); } 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 b8491d12..359854c9 100644 --- a/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java +++ b/src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java @@ -20,10 +20,13 @@ import com.google.cloud.spanner.AbortedException; import com.google.cloud.spanner.CommitResponse; import com.google.cloud.spanner.CommitStats; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; import com.google.cloud.spanner.Dialect; import com.google.cloud.spanner.Mutation; import com.google.cloud.spanner.Options.QueryOption; import com.google.cloud.spanner.PartitionOptions; +import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.connection.AutocommitDmlMode; import com.google.cloud.spanner.connection.SavepointSupport; @@ -47,6 +50,28 @@ */ public interface CloudSpannerJdbcConnection extends Connection { + /** + * Returns the {@link DatabaseId} of the database that this {@link Connection} is connected to. + */ + default DatabaseId getDatabaseId() { + throw new UnsupportedOperationException(); + } + + /** + * Returns the underlying {@link DatabaseClient} that is used by this connection. Operations that + * are executed on the {@link DatabaseClient} that is returned has no impact on this {@link + * Connection}, e.g. starting a read/write transaction on the {@link DatabaseClient} will not + * start a transaction on this connection. + */ + default DatabaseClient getDatabaseClient() { + throw new UnsupportedOperationException(); + } + + /** Returns the underlying {@link Spanner} instance that is used by this connection. */ + default Spanner getSpanner() { + throw new UnsupportedOperationException(); + } + /** * Sets the transaction tag to use for the current transaction. This method may only be called * when in a transaction, and before the transaction is actually started, i.e. before any diff --git a/src/test/java/com/google/cloud/spanner/jdbc/DdlMockServerTest.java b/src/test/java/com/google/cloud/spanner/jdbc/DdlMockServerTest.java index 75f9d9ef..7bca2369 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/DdlMockServerTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/DdlMockServerTest.java @@ -24,15 +24,18 @@ import com.google.cloud.spanner.MockSpannerServiceImpl.StatementResult; import com.google.cloud.spanner.Statement; import com.google.cloud.spanner.connection.AbstractMockServerTest; +import com.google.common.collect.ImmutableList; import com.google.longrunning.Operation; import com.google.protobuf.Any; import com.google.protobuf.Empty; import com.google.rpc.Code; +import com.google.spanner.admin.database.v1.GetDatabaseDdlResponse; import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -50,6 +53,29 @@ private Connection createConnection(boolean autoCommit) throws SQLException { return DriverManager.getConnection(createUrl(autoCommit)); } + @Test + public void testGetDatabaseDdl() throws SQLException { + List expectedDdl = + ImmutableList.of( + "create table foo (id int64) primary key (id)", + "create table bar (id int64) primary key (id)"); + mockDatabaseAdmin.addResponse( + GetDatabaseDdlResponse.newBuilder().addAllStatements(expectedDdl).build()); + + try (Connection connection = createConnection(/* autoCommit = */ true)) { + CloudSpannerJdbcConnection spannerJdbcConnection = + connection.unwrap(CloudSpannerJdbcConnection.class); + List ddl = + spannerJdbcConnection + .getSpanner() + .getDatabaseAdminClient() + .getDatabaseDdl( + spannerJdbcConnection.getDatabaseId().getInstanceId().getInstance(), + spannerJdbcConnection.getDatabaseId().getDatabase()); + assertEquals(expectedDdl, ddl); + } + } + @Test public void testDdlInAutoCommitIsTrue_succeeds() throws SQLException { mockDatabaseAdmin.addResponse( diff --git a/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java b/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java index a54c179b..e0ea49f6 100644 --- a/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java +++ b/src/test/java/com/google/cloud/spanner/jdbc/JdbcConnectionTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -100,6 +101,16 @@ private ConnectionOptions mockOptions() { return options; } + @Test + public void testGetDatabaseClient() throws SQLException { + ConnectionOptions options = mockOptions(); + try (Connection connection = createConnection(options)) { + CloudSpannerJdbcConnection spannerJdbcConnection = + connection.unwrap(CloudSpannerJdbcConnection.class); + assertNotNull(spannerJdbcConnection.getDatabaseClient()); + } + } + @Test public void testAutoCommit() throws SQLException { ConnectionOptions options = mockOptions();