1919import static com .google .cloud .spanner .TransactionRunner .TransactionCallable ;
2020import static com .google .cloud .spanner .Type .StructField ;
2121
22+ import com .google .api .gax .longrunning .OperationFuture ;
2223import com .google .cloud .spanner .Database ;
2324import com .google .cloud .spanner .DatabaseAdminClient ;
2425import com .google .cloud .spanner .DatabaseClient ;
2526import com .google .cloud .spanner .DatabaseId ;
2627import com .google .cloud .spanner .Key ;
2728import com .google .cloud .spanner .KeySet ;
2829import com .google .cloud .spanner .Mutation ;
29- import com .google .cloud .spanner .Operation ;
3030import com .google .cloud .spanner .ReadOnlyTransaction ;
3131import com .google .cloud .spanner .ResultSet ;
3232import com .google .cloud .spanner .Spanner ;
33+ import com .google .cloud .spanner .SpannerException ;
34+ import com .google .cloud .spanner .SpannerExceptionFactory ;
3335import com .google .cloud .spanner .SpannerOptions ;
3436import com .google .cloud .spanner .Statement ;
3537import com .google .cloud .spanner .Struct ;
4244import java .util .ArrayList ;
4345import java .util .Arrays ;
4446import java .util .List ;
47+ import java .util .concurrent .ExecutionException ;
4548import java .util .concurrent .TimeUnit ;
4649
4750/**
5659 * <li>Writing data using a read-write transaction.
5760 * <li>Using an index to read and execute SQL queries over data.
5861 * <li>Using commit timestamp for tracking when a record was last updated.
62+ * <li>Using Google API Extensions for Java to make thread-safe requests via
63+ * long-running operations. http://googleapis.github.io/gax-java/
5964 * </ul>
6065 */
6166public class SpannerSample {
@@ -132,7 +137,7 @@ static class Performance {
132137
133138 // [START spanner_create_database]
134139 static void createDatabase (DatabaseAdminClient dbAdminClient , DatabaseId id ) {
135- Operation <Database , CreateDatabaseMetadata > op =
140+ OperationFuture <Database , CreateDatabaseMetadata > op =
136141 dbAdminClient .createDatabase (
137142 id .getInstanceId ().getInstance (),
138143 id .getDatabase (),
@@ -149,14 +154,24 @@ static void createDatabase(DatabaseAdminClient dbAdminClient, DatabaseId id) {
149154 + " AlbumTitle STRING(MAX)\n "
150155 + ") PRIMARY KEY (SingerId, AlbumId),\n "
151156 + " INTERLEAVE IN PARENT Singers ON DELETE CASCADE" ));
152- Database db = op .waitFor ().getResult ();
153- System .out .println ("Created database [" + db .getId () + "]" );
157+ try {
158+ // Initiate the request which returns an OperationFuture.
159+ Database db = op .get ();
160+ System .out .println ("Created database [" + db .getId () + "]" );
161+ } catch (ExecutionException e ) {
162+ // If the operation failed during execution, expose the cause.
163+ throw (SpannerException ) e .getCause ();
164+ } catch (InterruptedException e ) {
165+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
166+ // and the thread is interrupted, either before or during the activity.
167+ throw SpannerExceptionFactory .propagateInterrupt (e );
168+ }
154169 }
155170 // [END spanner_create_database]
156171
157172 // [START spanner_create_table_with_timestamp_column]
158173 static void createTableWithTimestamp (DatabaseAdminClient dbAdminClient , DatabaseId id ) {
159- Operation <Void , UpdateDatabaseDdlMetadata > op =
174+ OperationFuture <Void , UpdateDatabaseDdlMetadata > op =
160175 dbAdminClient .updateDatabaseDdl (
161176 id .getInstanceId ().getInstance (),
162177 id .getDatabase (),
@@ -170,8 +185,18 @@ static void createTableWithTimestamp(DatabaseAdminClient dbAdminClient, Database
170185 + ") PRIMARY KEY (SingerId, VenueId, EventDate),\n "
171186 + " INTERLEAVE IN PARENT Singers ON DELETE CASCADE" ),
172187 null );
173- op .waitFor ().getResult ();
174- System .out .println ("Created Performances table in database: [" + id + "]" );
188+ try {
189+ // Initiate the request which returns an OperationFuture.
190+ op .get ();
191+ System .out .println ("Created Performances table in database: [" + id + "]" );
192+ } catch (ExecutionException e ) {
193+ // If the operation failed during execution, expose the cause.
194+ throw (SpannerException ) e .getCause ();
195+ } catch (InterruptedException e ) {
196+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
197+ // and the thread is interrupted, either before or during the activity.
198+ throw SpannerExceptionFactory .propagateInterrupt (e );
199+ }
175200 }
176201 // [END spanner_create_table_with_timestamp_column]
177202
@@ -260,14 +285,25 @@ static void read(DatabaseClient dbClient) {
260285
261286 // [START spanner_add_column]
262287 static void addMarketingBudget (DatabaseAdminClient adminClient , DatabaseId dbId ) {
263- adminClient
264- .updateDatabaseDdl (
265- dbId .getInstanceId ().getInstance (),
266- dbId .getDatabase (),
267- Arrays .asList ("ALTER TABLE Albums ADD COLUMN MarketingBudget INT64" ),
268- null )
269- .waitFor ();
270- System .out .println ("Added MarketingBudget column" );
288+ OperationFuture <Void , UpdateDatabaseDdlMetadata > op =
289+ adminClient
290+ .updateDatabaseDdl (
291+ dbId .getInstanceId ().getInstance (),
292+ dbId .getDatabase (),
293+ Arrays .asList ("ALTER TABLE Albums ADD COLUMN MarketingBudget INT64" ),
294+ null );
295+ try {
296+ // Initiate the request which returns an OperationFuture.
297+ op .get ();
298+ System .out .println ("Added MarketingBudget column" );
299+ } catch (ExecutionException e ) {
300+ // If the operation failed during execution, expose the cause.
301+ throw (SpannerException ) e .getCause ();
302+ } catch (InterruptedException e ) {
303+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
304+ // and the thread is interrupted, either before or during the activity.
305+ throw SpannerExceptionFactory .propagateInterrupt (e );
306+ }
271307 }
272308 // [END spanner_add_column]
273309
@@ -371,14 +407,25 @@ static void queryMarketingBudget(DatabaseClient dbClient) {
371407
372408 // [START spanner_create_index]
373409 static void addIndex (DatabaseAdminClient adminClient , DatabaseId dbId ) {
374- adminClient
375- .updateDatabaseDdl (
376- dbId .getInstanceId ().getInstance (),
377- dbId .getDatabase (),
378- Arrays .asList ("CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)" ),
379- null )
380- .waitFor ();
381- System .out .println ("Added AlbumsByAlbumTitle index" );
410+ OperationFuture <Void , UpdateDatabaseDdlMetadata > op =
411+ adminClient
412+ .updateDatabaseDdl (
413+ dbId .getInstanceId ().getInstance (),
414+ dbId .getDatabase (),
415+ Arrays .asList ("CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)" ),
416+ null );
417+ try {
418+ // Initiate the request which returns an OperationFuture.
419+ op .get ();
420+ System .out .println ("Added AlbumsByAlbumTitle index" );
421+ } catch (ExecutionException e ) {
422+ // If the operation failed during execution, expose the cause.
423+ throw (SpannerException ) e .getCause ();
424+ } catch (InterruptedException e ) {
425+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
426+ // and the thread is interrupted, either before or during the activity.
427+ throw SpannerExceptionFactory .propagateInterrupt (e );
428+ }
382429 }
383430 // [END spanner_create_index]
384431
@@ -431,15 +478,27 @@ static void readUsingIndex(DatabaseClient dbClient) {
431478
432479 // [START spanner_create_storing_index]
433480 static void addStoringIndex (DatabaseAdminClient adminClient , DatabaseId dbId ) {
434- adminClient
435- .updateDatabaseDdl (
436- dbId .getInstanceId ().getInstance (),
437- dbId .getDatabase (),
438- Arrays .asList (
439- "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)" ),
440- null )
441- .waitFor ();
442- System .out .println ("Added AlbumsByAlbumTitle2 index" );
481+ OperationFuture <Void , UpdateDatabaseDdlMetadata > op =
482+ adminClient
483+ .updateDatabaseDdl (
484+ dbId .getInstanceId ().getInstance (),
485+ dbId .getDatabase (),
486+ Arrays .asList (
487+ "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) "
488+ + "STORING (MarketingBudget)" ),
489+ null );
490+ try {
491+ // Initiate the request which returns an OperationFuture.
492+ op .get ();
493+ System .out .println ("Added AlbumsByAlbumTitle2 index" );
494+ } catch (ExecutionException e ) {
495+ // If the operation failed during execution, expose the cause.
496+ throw (SpannerException ) e .getCause ();
497+ } catch (InterruptedException e ) {
498+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
499+ // and the thread is interrupted, either before or during the activity.
500+ throw SpannerExceptionFactory .propagateInterrupt (e );
501+ }
443502 }
444503 // [END spanner_create_storing_index]
445504
@@ -509,16 +568,27 @@ static void readStaleData(DatabaseClient dbClient) {
509568
510569 // [START spanner_add_timestamp_column]
511570 static void addCommitTimestamp (DatabaseAdminClient adminClient , DatabaseId dbId ) {
512- adminClient
513- .updateDatabaseDdl (
514- dbId .getInstanceId ().getInstance (),
515- dbId .getDatabase (),
516- Arrays .asList (
517- "ALTER TABLE Albums ADD COLUMN LastUpdateTime TIMESTAMP "
518- + "OPTIONS (allow_commit_timestamp=true)" ),
519- null )
520- .waitFor ();
521- System .out .println ("Added LastUpdateTime as a commit timestamp column in Albums table." );
571+ OperationFuture <Void , UpdateDatabaseDdlMetadata > op =
572+ adminClient
573+ .updateDatabaseDdl (
574+ dbId .getInstanceId ().getInstance (),
575+ dbId .getDatabase (),
576+ Arrays .asList (
577+ "ALTER TABLE Albums ADD COLUMN LastUpdateTime TIMESTAMP "
578+ + "OPTIONS (allow_commit_timestamp=true)" ),
579+ null );
580+ try {
581+ // Initiate the request which returns an OperationFuture.
582+ op .get ();
583+ System .out .println ("Added LastUpdateTime as a commit timestamp column in Albums table." );
584+ } catch (ExecutionException e ) {
585+ // If the operation failed during execution, expose the cause.
586+ throw (SpannerException ) e .getCause ();
587+ } catch (InterruptedException e ) {
588+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
589+ // and the thread is interrupted, either before or during the activity.
590+ throw SpannerExceptionFactory .propagateInterrupt (e );
591+ }
522592 }
523593 // [END spanner_add_timestamp_column]
524594
@@ -605,8 +675,8 @@ static void queryPerformancesTable(DatabaseClient dbClient) {
605675 .singleUse ()
606676 .executeQuery (
607677 Statement .of (
608- "SELECT SingerId, VenueId, EventDate, Revenue, LastUpdateTime FROM Performances "
609- + " ORDER BY LastUpdateTime DESC" ));
678+ "SELECT SingerId, VenueId, EventDate, Revenue, LastUpdateTime "
679+ + "FROM Performances ORDER BY LastUpdateTime DESC" ));
610680 while (resultSet .next ()) {
611681 System .out .printf (
612682 "%d %d %s %s %s\n " ,
0 commit comments