19
19
import static com .google .cloud .spanner .TransactionRunner .TransactionCallable ;
20
20
import static com .google .cloud .spanner .Type .StructField ;
21
21
22
+ import com .google .api .gax .longrunning .OperationFuture ;
22
23
import com .google .cloud .spanner .Database ;
23
24
import com .google .cloud .spanner .DatabaseAdminClient ;
24
25
import com .google .cloud .spanner .DatabaseClient ;
25
26
import com .google .cloud .spanner .DatabaseId ;
26
27
import com .google .cloud .spanner .Key ;
27
28
import com .google .cloud .spanner .KeySet ;
28
29
import com .google .cloud .spanner .Mutation ;
29
- import com .google .cloud .spanner .Operation ;
30
30
import com .google .cloud .spanner .ReadOnlyTransaction ;
31
31
import com .google .cloud .spanner .ResultSet ;
32
32
import com .google .cloud .spanner .Spanner ;
33
+ import com .google .cloud .spanner .SpannerException ;
34
+ import com .google .cloud .spanner .SpannerExceptionFactory ;
33
35
import com .google .cloud .spanner .SpannerOptions ;
34
36
import com .google .cloud .spanner .Statement ;
35
37
import com .google .cloud .spanner .Struct ;
42
44
import java .util .ArrayList ;
43
45
import java .util .Arrays ;
44
46
import java .util .List ;
47
+ import java .util .concurrent .ExecutionException ;
45
48
import java .util .concurrent .TimeUnit ;
46
49
47
50
/**
56
59
* <li>Writing data using a read-write transaction.
57
60
* <li>Using an index to read and execute SQL queries over data.
58
61
* <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/
59
64
* </ul>
60
65
*/
61
66
public class SpannerSample {
@@ -132,7 +137,7 @@ static class Performance {
132
137
133
138
// [START spanner_create_database]
134
139
static void createDatabase (DatabaseAdminClient dbAdminClient , DatabaseId id ) {
135
- Operation <Database , CreateDatabaseMetadata > op =
140
+ OperationFuture <Database , CreateDatabaseMetadata > op =
136
141
dbAdminClient .createDatabase (
137
142
id .getInstanceId ().getInstance (),
138
143
id .getDatabase (),
@@ -149,14 +154,24 @@ static void createDatabase(DatabaseAdminClient dbAdminClient, DatabaseId id) {
149
154
+ " AlbumTitle STRING(MAX)\n "
150
155
+ ") PRIMARY KEY (SingerId, AlbumId),\n "
151
156
+ " 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
+ }
154
169
}
155
170
// [END spanner_create_database]
156
171
157
172
// [START spanner_create_table_with_timestamp_column]
158
173
static void createTableWithTimestamp (DatabaseAdminClient dbAdminClient , DatabaseId id ) {
159
- Operation <Void , UpdateDatabaseDdlMetadata > op =
174
+ OperationFuture <Void , UpdateDatabaseDdlMetadata > op =
160
175
dbAdminClient .updateDatabaseDdl (
161
176
id .getInstanceId ().getInstance (),
162
177
id .getDatabase (),
@@ -170,8 +185,18 @@ static void createTableWithTimestamp(DatabaseAdminClient dbAdminClient, Database
170
185
+ ") PRIMARY KEY (SingerId, VenueId, EventDate),\n "
171
186
+ " INTERLEAVE IN PARENT Singers ON DELETE CASCADE" ),
172
187
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
+ }
175
200
}
176
201
// [END spanner_create_table_with_timestamp_column]
177
202
@@ -260,14 +285,25 @@ static void read(DatabaseClient dbClient) {
260
285
261
286
// [START spanner_add_column]
262
287
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
+ }
271
307
}
272
308
// [END spanner_add_column]
273
309
@@ -371,14 +407,25 @@ static void queryMarketingBudget(DatabaseClient dbClient) {
371
407
372
408
// [START spanner_create_index]
373
409
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
+ }
382
429
}
383
430
// [END spanner_create_index]
384
431
@@ -431,15 +478,27 @@ static void readUsingIndex(DatabaseClient dbClient) {
431
478
432
479
// [START spanner_create_storing_index]
433
480
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
+ }
443
502
}
444
503
// [END spanner_create_storing_index]
445
504
@@ -509,16 +568,27 @@ static void readStaleData(DatabaseClient dbClient) {
509
568
510
569
// [START spanner_add_timestamp_column]
511
570
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
+ }
522
592
}
523
593
// [END spanner_add_timestamp_column]
524
594
@@ -605,8 +675,8 @@ static void queryPerformancesTable(DatabaseClient dbClient) {
605
675
.singleUse ()
606
676
.executeQuery (
607
677
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" ));
610
680
while (resultSet .next ()) {
611
681
System .out .printf (
612
682
"%d %d %s %s %s\n " ,
0 commit comments