Skip to content

Commit

Permalink
feat: add methods for unwrapping Spanner client (#1914)
Browse files Browse the repository at this point in the history
Adds methods for unwrapping the underlying DatabaseClient and Spanner
instance that is used by a JDBC connection.
  • Loading branch information
olavloite authored Feb 15, 2025
1 parent 4744c11 commit ee6082f
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
15 changes: 15 additions & 0 deletions clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,19 @@
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
<method>void setAutoBatchDmlUpdateCountVerification(boolean)</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
<method>com.google.cloud.spanner.DatabaseClient getDatabaseClient()</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
<method>com.google.cloud.spanner.Spanner getSpanner()</method>
</difference>
<difference>
<differenceType>7012</differenceType>
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
<method>com.google.cloud.spanner.DatabaseId getDatabaseId()</method>
</difference>
</differences>
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -82,7 +94,8 @@ ConnectionOptions getConnectionOptions() {
return options;
}

Spanner getSpanner() {
@Override
public Spanner getSpanner() {
return this.spanner.getSpanner();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
26 changes: 26 additions & 0 deletions src/test/java/com/google/cloud/spanner/jdbc/DdlMockServerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -50,6 +53,29 @@ private Connection createConnection(boolean autoCommit) throws SQLException {
return DriverManager.getConnection(createUrl(autoCommit));
}

@Test
public void testGetDatabaseDdl() throws SQLException {
List<String> 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<String> ddl =
spannerJdbcConnection
.getSpanner()
.getDatabaseAdminClient()
.getDatabaseDdl(
spannerJdbcConnection.getDatabaseId().getInstanceId().getInstance(),
spannerJdbcConnection.getDatabaseId().getDatabase());
assertEquals(expectedDdl, ddl);
}
}

@Test
public void testDdlInAutoCommitIsTrue_succeeds() throws SQLException {
mockDatabaseAdmin.addResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit ee6082f

Please sign in to comment.