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",