Skip to content

Commit e30c014

Browse files
authored
Update Leaderboard to use Batch DML. (#1358)
1 parent df5d11f commit e30c014

File tree

11 files changed

+415
-362
lines changed

11 files changed

+415
-362
lines changed

spanner/leaderboard/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ using the [Google Cloud Client Library for Java](https://github.com/GoogleCloudP
66

77
This sample requires [Java](https://www.java.com/en/download/) and [Maven](http://maven.apache.org/) for building the application.
88

9-
This sample includes extra directories `step5`, `step6`, and `step7` that contain partial versions of this sample application. These directories are intended to provide guidance as part of a separate Codelab walk-through where the application is built in the following stages
9+
This sample includes extra directories `step4`, `step5`, and `step6` that contain partial versions of this sample application. These directories are intended to provide guidance as part of a separate Codelab walk-through where the application is built in the following stages
1010
that correspond to the steps in Codelab:
1111

12-
* step5 - Create the sample database along with the tables Players and Scores.
13-
* step6 - Populate the Players and Scores tables with sample data.
14-
* step7 - Run sample queries including sorting the results by timestamp.
12+
* step4 - Create the sample database along with the tables Players and Scores.
13+
* step5 - Populate the Players and Scores tables with sample data.
14+
* step6 - Run sample queries including sorting the results by timestamp.
1515

1616
If you only want to run the complete sample refer to the application in the `complete` directory.
1717

spanner/leaderboard/complete/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<dependency>
3434
<groupId>com.google.cloud</groupId>
3535
<artifactId>google-cloud-bom</artifactId>
36-
<version>0.73.0-alpha</version>
36+
<version>0.83.0-alpha</version>
3737
<type>pom</type>
3838
<scope>import</scope>
3939
</dependency>

spanner/leaderboard/complete/src/main/java/com/google/codelabs/App.java

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
import java.time.LocalDateTime;
3838
import java.time.LocalTime;
3939
import java.time.ZoneOffset;
40+
import java.util.ArrayList;
4041
import java.util.Arrays;
42+
import java.util.List;
4143
import java.util.Random;
4244
import java.util.concurrent.ExecutionException;
4345
import java.util.concurrent.ThreadLocalRandom;
@@ -126,18 +128,24 @@ public Void run(TransactionContext transaction) throws Exception {
126128
numberOfPlayers = resultSet.getLong("PlayerCount");
127129
}
128130
// Insert 100 player records into the Players table.
131+
List<Statement> stmts = new ArrayList<Statement>();
129132
long randomId;
130133
for (int x = 1; x <= 100; x++) {
131134
numberOfPlayers++;
132135
randomId = (long) Math.floor(Math.random() * 9_000_000_000L) + 1_000_000_000L;
133-
transaction.buffer(
134-
Mutation.newInsertBuilder("Players")
135-
.set("PlayerId")
136-
.to(randomId)
137-
.set("PlayerName")
138-
.to("Player " + numberOfPlayers)
139-
.build());
136+
Statement statement =
137+
Statement
138+
.newBuilder(
139+
"INSERT INTO Players (PlayerId, PlayerName) "
140+
+ "VALUES (@PlayerId, @PlayerName) ")
141+
.bind("PlayerId")
142+
.to(randomId)
143+
.bind("PlayerName")
144+
.to("Player " + numberOfPlayers)
145+
.build();
146+
stmts.add(statement);
140147
}
148+
transaction.batchUpdate(stmts);
141149
return null;
142150
}
143151
});
@@ -168,6 +176,7 @@ public Void run(TransactionContext transaction) throws Exception {
168176
LocalDate startDate = LocalDate.of(startYear, startMonth, startDay);
169177
long start = startDate.toEpochDay();
170178
Random r = new Random();
179+
List<Statement> stmts = new ArrayList<Statement>();
171180
// Insert 4 score records into the Scores table
172181
// for each player in the Players table.
173182
for (int x = 1; x <= 4; x++) {
@@ -180,20 +189,24 @@ public Void run(TransactionContext transaction) throws Exception {
180189
r.nextInt(23), r.nextInt(59), r.nextInt(59), r.nextInt(9999));
181190
LocalDateTime randomDate = LocalDateTime.of(randomDayDate, randomTime);
182191
Instant randomInstant = randomDate.toInstant(ZoneOffset.UTC);
183-
transaction.buffer(
184-
Mutation.newInsertBuilder("Scores")
185-
.set("PlayerId")
186-
.to(playerId)
187-
.set("Score")
188-
.to(randomScore)
189-
.set("Timestamp")
190-
.to(randomInstant.toString())
191-
.build());
192+
Statement statement =
193+
Statement
194+
.newBuilder(
195+
"INSERT INTO Scores (PlayerId, Score, Timestamp) "
196+
+ "VALUES (@PlayerId, @Score, @Timestamp) ")
197+
.bind("PlayerId")
198+
.to(playerId)
199+
.bind("Score")
200+
.to(randomScore)
201+
.bind("Timestamp")
202+
.to(randomInstant.toString())
203+
.build();
204+
stmts.add(statement);
192205
}
206+
transaction.batchUpdate(stmts);
193207
return null;
194208
}
195209
});
196-
197210
}
198211
if (!playerRecordsFound) {
199212
System.out.println("Parameter 'scores' is invalid since "

spanner/leaderboard/complete/src/test/java/com/google/codelabs/AppTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,18 @@ public void testSample() throws Exception {
9999
out = runSample("insert", "scores");
100100
assertThat(out).contains("Done inserting score records");
101101

102+
out = runSample("insert", "scores");
103+
assertThat(out).contains("Done inserting score records");
104+
105+
out = runSample("insert", "scores");
106+
assertThat(out).contains("Done inserting score records");
107+
108+
out = runSample("insert", "scores");
109+
assertThat(out).contains("Done inserting score records");
110+
111+
out = runSample("insert", "scores");
112+
assertThat(out).contains("Done inserting score records");
113+
102114
// Query Top Ten Players of all time.
103115
out = runSample("query");
104116
assertThat(out).contains("PlayerId: ");

spanner/leaderboard/step7/pom.xml renamed to spanner/leaderboard/step4/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<maven.compiler.source>1.7</maven.compiler.source>
1818
<maven.compiler.target>1.7</maven.compiler.target>
1919
</properties>
20-
20+
2121
<!--
2222
The parent pom defines common style checks and testing strategies for our samples.
2323
Removing or replacing it should not affect the execution of the samples in anyway.
@@ -33,7 +33,7 @@
3333
<dependency>
3434
<groupId>com.google.cloud</groupId>
3535
<artifactId>google-cloud-bom</artifactId>
36-
<version>0.73.0-alpha</version>
36+
<version>0.83.0-alpha</version>
3737
<type>pom</type>
3838
<scope>import</scope>
3939
</dependency>
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.codelabs;
18+
19+
import com.google.api.gax.longrunning.OperationFuture;
20+
import com.google.cloud.spanner.Database;
21+
import com.google.cloud.spanner.DatabaseAdminClient;
22+
import com.google.cloud.spanner.DatabaseClient;
23+
import com.google.cloud.spanner.DatabaseId;
24+
import com.google.cloud.spanner.Spanner;
25+
import com.google.cloud.spanner.SpannerException;
26+
import com.google.cloud.spanner.SpannerExceptionFactory;
27+
import com.google.cloud.spanner.SpannerOptions;
28+
import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
29+
import java.util.Arrays;
30+
import java.util.concurrent.ExecutionException;
31+
32+
/**
33+
* Example code for using the Cloud Spanner API with the Google Cloud Java client library
34+
* to create a simple leaderboard.
35+
*
36+
* This example demonstrates:
37+
*
38+
* <p>
39+
*
40+
* <ul>
41+
* <li>Creating a Cloud Spanner database.
42+
* </ul>
43+
*/
44+
public class App {
45+
46+
static void create(DatabaseAdminClient dbAdminClient, DatabaseId db) {
47+
OperationFuture<Database, CreateDatabaseMetadata> op =
48+
dbAdminClient.createDatabase(
49+
db.getInstanceId().getInstance(),
50+
db.getDatabase(),
51+
Arrays.asList(
52+
"CREATE TABLE Players(\n"
53+
+ " PlayerId INT64 NOT NULL,\n"
54+
+ " PlayerName STRING(2048) NOT NULL\n"
55+
+ ") PRIMARY KEY(PlayerId)",
56+
"CREATE TABLE Scores(\n"
57+
+ " PlayerId INT64 NOT NULL,\n"
58+
+ " Score INT64 NOT NULL,\n"
59+
+ " Timestamp TIMESTAMP NOT NULL\n"
60+
+ " OPTIONS(allow_commit_timestamp=true)\n"
61+
+ ") PRIMARY KEY(PlayerId, Timestamp),\n"
62+
+ "INTERLEAVE IN PARENT Players ON DELETE NO ACTION"));
63+
try {
64+
// Initiate the request which returns an OperationFuture.
65+
Database dbOperation = op.get();
66+
System.out.println("Created database [" + dbOperation.getId() + "]");
67+
} catch (ExecutionException e) {
68+
// If the operation failed during execution, expose the cause.
69+
throw (SpannerException) e.getCause();
70+
} catch (InterruptedException e) {
71+
// Throw when a thread is waiting, sleeping, or otherwise occupied,
72+
// and the thread is interrupted, either before or during the activity.
73+
throw SpannerExceptionFactory.propagateInterrupt(e);
74+
}
75+
}
76+
77+
static void printUsageAndExit() {
78+
System.out.println("Leaderboard 1.0.0");
79+
System.out.println("Usage:");
80+
System.out.println(" java -jar leaderboard.jar "
81+
+ "<command> <instance_id> <database_id> [command_option]");
82+
System.out.println("");
83+
System.out.println("Examples:");
84+
System.out.println(" java -jar leaderboard.jar create my-instance example-db");
85+
System.out.println(" - Create a sample Cloud Spanner database along with "
86+
+ "sample tables in your project.\n");
87+
System.exit(1);
88+
}
89+
90+
public static void main(String[] args) throws Exception {
91+
if (!(args.length == 3 || args.length == 4)) {
92+
printUsageAndExit();
93+
}
94+
SpannerOptions options = SpannerOptions.newBuilder().build();
95+
Spanner spanner = options.getService();
96+
try {
97+
String command = args[0];
98+
DatabaseId db = DatabaseId.of(options.getProjectId(), args[1], args[2]);
99+
DatabaseClient dbClient = spanner.getDatabaseClient(db);
100+
DatabaseAdminClient dbAdminClient = spanner.getDatabaseAdminClient();
101+
switch (command) {
102+
case "create":
103+
create(dbAdminClient, db);
104+
break;
105+
default:
106+
printUsageAndExit();
107+
}
108+
} finally {
109+
spanner.close();
110+
}
111+
System.out.println("Closed client");
112+
}
113+
}

spanner/leaderboard/step5/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<dependency>
3434
<groupId>com.google.cloud</groupId>
3535
<artifactId>google-cloud-bom</artifactId>
36-
<version>0.73.0-alpha</version>
36+
<version>0.83.0-alpha</version>
3737
<type>pom</type>
3838
<scope>import</scope>
3939
</dependency>

0 commit comments

Comments
 (0)