diff --git a/spanner/cloud-client/pom.xml b/spanner/cloud-client/pom.xml
index 687a5077991..d7f71c67fc9 100644
--- a/spanner/cloud-client/pom.xml
+++ b/spanner/cloud-client/pom.xml
@@ -42,7 +42,7 @@ limitations under the License.
com.google.cloud
google-cloud-bom
- 0.66.0-alpha
+ 0.70.0-alpha
pom
import
diff --git a/spanner/cloud-client/src/main/java/com/example/spanner/SpannerSample.java b/spanner/cloud-client/src/main/java/com/example/spanner/SpannerSample.java
index a849df70887..c686118422a 100644
--- a/spanner/cloud-client/src/main/java/com/example/spanner/SpannerSample.java
+++ b/spanner/cloud-client/src/main/java/com/example/spanner/SpannerSample.java
@@ -19,6 +19,7 @@
import static com.google.cloud.spanner.TransactionRunner.TransactionCallable;
import static com.google.cloud.spanner.Type.StructField;
+import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseClient;
@@ -26,10 +27,11 @@
import com.google.cloud.spanner.Key;
import com.google.cloud.spanner.KeySet;
import com.google.cloud.spanner.Mutation;
-import com.google.cloud.spanner.Operation;
import com.google.cloud.spanner.ReadOnlyTransaction;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.Spanner;
+import com.google.cloud.spanner.SpannerException;
+import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.Struct;
@@ -42,6 +44,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
@@ -56,6 +59,8 @@
*
Writing data using a read-write transaction.
* Using an index to read and execute SQL queries over data.
* Using commit timestamp for tracking when a record was last updated.
+ * Using Google API Extensions for Java to make thread-safe requests via
+ * long-running operations. http://googleapis.github.io/gax-java/
*
*/
public class SpannerSample {
@@ -132,7 +137,7 @@ static class Performance {
// [START spanner_create_database]
static void createDatabase(DatabaseAdminClient dbAdminClient, DatabaseId id) {
- Operation op =
+ OperationFuture op =
dbAdminClient.createDatabase(
id.getInstanceId().getInstance(),
id.getDatabase(),
@@ -149,14 +154,24 @@ static void createDatabase(DatabaseAdminClient dbAdminClient, DatabaseId id) {
+ " AlbumTitle STRING(MAX)\n"
+ ") PRIMARY KEY (SingerId, AlbumId),\n"
+ " INTERLEAVE IN PARENT Singers ON DELETE CASCADE"));
- Database db = op.waitFor().getResult();
- System.out.println("Created database [" + db.getId() + "]");
+ try {
+ // Initiate the request which returns an OperationFuture.
+ Database db = op.get();
+ System.out.println("Created database [" + db.getId() + "]");
+ } catch (ExecutionException e) {
+ // If the operation failed during execution, expose the cause.
+ throw (SpannerException) e.getCause();
+ } catch (InterruptedException e) {
+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
+ // and the thread is interrupted, either before or during the activity.
+ throw SpannerExceptionFactory.propagateInterrupt(e);
+ }
}
// [END spanner_create_database]
// [START spanner_create_table_with_timestamp_column]
static void createTableWithTimestamp(DatabaseAdminClient dbAdminClient, DatabaseId id) {
- Operation op =
+ OperationFuture op =
dbAdminClient.updateDatabaseDdl(
id.getInstanceId().getInstance(),
id.getDatabase(),
@@ -170,8 +185,18 @@ static void createTableWithTimestamp(DatabaseAdminClient dbAdminClient, Database
+ ") PRIMARY KEY (SingerId, VenueId, EventDate),\n"
+ " INTERLEAVE IN PARENT Singers ON DELETE CASCADE"),
null);
- op.waitFor().getResult();
- System.out.println("Created Performances table in database: [" + id + "]");
+ try {
+ // Initiate the request which returns an OperationFuture.
+ op.get();
+ System.out.println("Created Performances table in database: [" + id + "]");
+ } catch (ExecutionException e) {
+ // If the operation failed during execution, expose the cause.
+ throw (SpannerException) e.getCause();
+ } catch (InterruptedException e) {
+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
+ // and the thread is interrupted, either before or during the activity.
+ throw SpannerExceptionFactory.propagateInterrupt(e);
+ }
}
// [END spanner_create_table_with_timestamp_column]
@@ -260,14 +285,25 @@ static void read(DatabaseClient dbClient) {
// [START spanner_add_column]
static void addMarketingBudget(DatabaseAdminClient adminClient, DatabaseId dbId) {
- adminClient
- .updateDatabaseDdl(
- dbId.getInstanceId().getInstance(),
- dbId.getDatabase(),
- Arrays.asList("ALTER TABLE Albums ADD COLUMN MarketingBudget INT64"),
- null)
- .waitFor();
- System.out.println("Added MarketingBudget column");
+ OperationFuture op =
+ adminClient
+ .updateDatabaseDdl(
+ dbId.getInstanceId().getInstance(),
+ dbId.getDatabase(),
+ Arrays.asList("ALTER TABLE Albums ADD COLUMN MarketingBudget INT64"),
+ null);
+ try {
+ // Initiate the request which returns an OperationFuture.
+ op.get();
+ System.out.println("Added MarketingBudget column");
+ } catch (ExecutionException e) {
+ // If the operation failed during execution, expose the cause.
+ throw (SpannerException) e.getCause();
+ } catch (InterruptedException e) {
+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
+ // and the thread is interrupted, either before or during the activity.
+ throw SpannerExceptionFactory.propagateInterrupt(e);
+ }
}
// [END spanner_add_column]
@@ -371,14 +407,25 @@ static void queryMarketingBudget(DatabaseClient dbClient) {
// [START spanner_create_index]
static void addIndex(DatabaseAdminClient adminClient, DatabaseId dbId) {
- adminClient
- .updateDatabaseDdl(
- dbId.getInstanceId().getInstance(),
- dbId.getDatabase(),
- Arrays.asList("CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)"),
- null)
- .waitFor();
- System.out.println("Added AlbumsByAlbumTitle index");
+ OperationFuture op =
+ adminClient
+ .updateDatabaseDdl(
+ dbId.getInstanceId().getInstance(),
+ dbId.getDatabase(),
+ Arrays.asList("CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)"),
+ null);
+ try {
+ // Initiate the request which returns an OperationFuture.
+ op.get();
+ System.out.println("Added AlbumsByAlbumTitle index");
+ } catch (ExecutionException e) {
+ // If the operation failed during execution, expose the cause.
+ throw (SpannerException) e.getCause();
+ } catch (InterruptedException e) {
+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
+ // and the thread is interrupted, either before or during the activity.
+ throw SpannerExceptionFactory.propagateInterrupt(e);
+ }
}
// [END spanner_create_index]
@@ -431,15 +478,27 @@ static void readUsingIndex(DatabaseClient dbClient) {
// [START spanner_create_storing_index]
static void addStoringIndex(DatabaseAdminClient adminClient, DatabaseId dbId) {
- adminClient
- .updateDatabaseDdl(
- dbId.getInstanceId().getInstance(),
- dbId.getDatabase(),
- Arrays.asList(
- "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)"),
- null)
- .waitFor();
- System.out.println("Added AlbumsByAlbumTitle2 index");
+ OperationFuture op =
+ adminClient
+ .updateDatabaseDdl(
+ dbId.getInstanceId().getInstance(),
+ dbId.getDatabase(),
+ Arrays.asList(
+ "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) "
+ + "STORING (MarketingBudget)"),
+ null);
+ try {
+ // Initiate the request which returns an OperationFuture.
+ op.get();
+ System.out.println("Added AlbumsByAlbumTitle2 index");
+ } catch (ExecutionException e) {
+ // If the operation failed during execution, expose the cause.
+ throw (SpannerException) e.getCause();
+ } catch (InterruptedException e) {
+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
+ // and the thread is interrupted, either before or during the activity.
+ throw SpannerExceptionFactory.propagateInterrupt(e);
+ }
}
// [END spanner_create_storing_index]
@@ -509,16 +568,27 @@ static void readStaleData(DatabaseClient dbClient) {
// [START spanner_add_timestamp_column]
static void addCommitTimestamp(DatabaseAdminClient adminClient, DatabaseId dbId) {
- adminClient
- .updateDatabaseDdl(
- dbId.getInstanceId().getInstance(),
- dbId.getDatabase(),
- Arrays.asList(
- "ALTER TABLE Albums ADD COLUMN LastUpdateTime TIMESTAMP "
- + "OPTIONS (allow_commit_timestamp=true)"),
- null)
- .waitFor();
- System.out.println("Added LastUpdateTime as a commit timestamp column in Albums table.");
+ OperationFuture op =
+ adminClient
+ .updateDatabaseDdl(
+ dbId.getInstanceId().getInstance(),
+ dbId.getDatabase(),
+ Arrays.asList(
+ "ALTER TABLE Albums ADD COLUMN LastUpdateTime TIMESTAMP "
+ + "OPTIONS (allow_commit_timestamp=true)"),
+ null);
+ try {
+ // Initiate the request which returns an OperationFuture.
+ op.get();
+ System.out.println("Added LastUpdateTime as a commit timestamp column in Albums table.");
+ } catch (ExecutionException e) {
+ // If the operation failed during execution, expose the cause.
+ throw (SpannerException) e.getCause();
+ } catch (InterruptedException e) {
+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
+ // and the thread is interrupted, either before or during the activity.
+ throw SpannerExceptionFactory.propagateInterrupt(e);
+ }
}
// [END spanner_add_timestamp_column]
@@ -605,8 +675,8 @@ static void queryPerformancesTable(DatabaseClient dbClient) {
.singleUse()
.executeQuery(
Statement.of(
- "SELECT SingerId, VenueId, EventDate, Revenue, LastUpdateTime FROM Performances"
- + " ORDER BY LastUpdateTime DESC"));
+ "SELECT SingerId, VenueId, EventDate, Revenue, LastUpdateTime "
+ + "FROM Performances ORDER BY LastUpdateTime DESC"));
while (resultSet.next()) {
System.out.printf(
"%d %d %s %s %s\n",