From ea653f70330811b9de6bb8d4b8340666c2c7a904 Mon Sep 17 00:00:00 2001 From: Jisha Abubaker Date: Mon, 28 Aug 2017 10:39:27 -0700 Subject: [PATCH] samples: Spanner stale read (#831) --- .../com/example/spanner/SpannerSample.java | 85 ++++++++++--------- .../example/spanner/QuickstartSampleIT.java | 5 +- .../com/example/spanner/SpannerSampleIT.java | 17 ++-- 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java b/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java index 176677b44f..7b83efb1d9 100644 --- a/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java +++ b/samples/snippets/src/main/java/com/example/spanner/SpannerSample.java @@ -16,47 +16,29 @@ package com.example.spanner; -// [START transaction_import] import static com.google.cloud.spanner.TransactionRunner.TransactionCallable; -// [END transaction_import] import com.google.cloud.spanner.Database; import com.google.cloud.spanner.DatabaseAdminClient; import com.google.cloud.spanner.DatabaseClient; import com.google.cloud.spanner.DatabaseId; -// [START transaction_import] import com.google.cloud.spanner.Key; -// [END transaction_import] -// [START read_import] import com.google.cloud.spanner.KeySet; -// [END read_import] -// [START write_import] import com.google.cloud.spanner.Mutation; -// [END write_import] import com.google.cloud.spanner.Operation; -// [START read_only_transaction_import] import com.google.cloud.spanner.ReadOnlyTransaction; -// [END read_only_transaction_import] -// [START query_import] import com.google.cloud.spanner.ResultSet; -// [END query_import] import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerOptions; -// [START query_import] import com.google.cloud.spanner.Statement; -// [END query_import] -// [START transaction_import] import com.google.cloud.spanner.Struct; +import com.google.cloud.spanner.TimestampBound; import com.google.cloud.spanner.TransactionContext; -// [END transaction_import] import com.google.spanner.admin.database.v1.CreateDatabaseMetadata; - -// [START write_import] - import java.util.ArrayList; -// [END write_import] import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; /** * Example code for using the Cloud Spanner API. This example demonstrates all the common @@ -67,11 +49,14 @@ *
  • Writing data using a read-write transaction. *
  • Using an index to read and execute SQL queries over data. * - * */ public class SpannerSample { - /** Class to contain singer sample data. */ + + /** + * Class to contain singer sample data. + */ static class Singer { + final long singerId; final String firstName; final String lastName; @@ -83,8 +68,11 @@ static class Singer { } } - /** Class to contain album sample data. */ + /** + * Class to contain album sample data. + */ static class Album { + final long singerId; final long albumId; final String albumTitle; @@ -116,22 +104,22 @@ static class Album { static void createDatabase(DatabaseAdminClient dbAdminClient, DatabaseId id) { Operation op = dbAdminClient - .createDatabase( - id.getInstanceId().getInstance(), - id.getDatabase(), - Arrays.asList( - "CREATE TABLE Singers (\n" - + " SingerId INT64 NOT NULL,\n" - + " FirstName STRING(1024),\n" - + " LastName STRING(1024),\n" - + " SingerInfo BYTES(MAX)\n" - + ") PRIMARY KEY (SingerId)", - "CREATE TABLE Albums (\n" - + " SingerId INT64 NOT NULL,\n" - + " AlbumId INT64 NOT NULL,\n" - + " AlbumTitle STRING(MAX)\n" - + ") PRIMARY KEY (SingerId, AlbumId),\n" - + " INTERLEAVE IN PARENT Singers ON DELETE CASCADE")); + .createDatabase( + id.getInstanceId().getInstance(), + id.getDatabase(), + Arrays.asList( + "CREATE TABLE Singers (\n" + + " SingerId INT64 NOT NULL,\n" + + " FirstName STRING(1024),\n" + + " LastName STRING(1024),\n" + + " SingerInfo BYTES(MAX)\n" + + ") PRIMARY KEY (SingerId)", + "CREATE TABLE Albums (\n" + + " SingerId INT64 NOT NULL,\n" + + " AlbumId INT64 NOT NULL,\n" + + " 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() + "]"); } @@ -413,6 +401,22 @@ static void readOnlyTransaction(DatabaseClient dbClient) { } // [END read_only_transaction] + // [START read_stale_data] + static void readStaleData(DatabaseClient dbClient) { + ResultSet resultSet = + dbClient + .singleUse(TimestampBound.ofExactStaleness(10, TimeUnit.SECONDS)) + .read("Albums", + KeySet.all(), + Arrays.asList("SingerId", "AlbumId", "MarketingBudget")); + while (resultSet.next()) { + System.out.printf( + "%d %d %s\n", resultSet.getLong(0), resultSet.getLong(1), + resultSet.isNull(2) ? "NULL" : resultSet.getLong("MarketingBudget")); + } + } + // [END read_stale_data] + static void run(DatabaseClient dbClient, DatabaseAdminClient dbAdminClient, String command, DatabaseId database) { switch (command) { @@ -458,6 +462,9 @@ static void run(DatabaseClient dbClient, DatabaseAdminClient dbAdminClient, Stri case "readonlytransaction": readOnlyTransaction(dbClient); break; + case "readstaledata": + readStaleData(dbClient); + break; default: printUsageAndExit(); } diff --git a/samples/snippets/src/test/java/com/example/spanner/QuickstartSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/QuickstartSampleIT.java index 15df8e810f..350f2b3d9a 100644 --- a/samples/snippets/src/test/java/com/example/spanner/QuickstartSampleIT.java +++ b/samples/snippets/src/test/java/com/example/spanner/QuickstartSampleIT.java @@ -18,15 +18,14 @@ import static com.google.common.truth.Truth.assertThat; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - /** * Tests for quickstart sample. */ diff --git a/samples/snippets/src/test/java/com/example/spanner/SpannerSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/SpannerSampleIT.java index fa1b9939a4..fd695426b8 100644 --- a/samples/snippets/src/test/java/com/example/spanner/SpannerSampleIT.java +++ b/samples/snippets/src/test/java/com/example/spanner/SpannerSampleIT.java @@ -23,15 +23,14 @@ import com.google.cloud.spanner.Spanner; import com.google.cloud.spanner.SpannerOptions; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - /** * Unit tests for {@code SpannerSample} */ @@ -43,6 +42,7 @@ public class SpannerSampleIT { private final String databaseId = System.getProperty("spanner.sample.database"); DatabaseId dbId; DatabaseAdminClient dbClient; + private long lastUpdateDataTimeInMillis; private String runSample(String command) throws Exception { PrintStream stdOut = System.out; @@ -83,12 +83,17 @@ public void testSample() throws Exception { out = runSample("query"); assertThat(out).contains("1 1 Total Junk"); - runSample("addmarketingbudget"); + + // wait for 10 seconds to elapse and then run an update, and query for stale data + lastUpdateDataTimeInMillis = System.currentTimeMillis(); + while (System.currentTimeMillis() < lastUpdateDataTimeInMillis + 11000) { + Thread.sleep(1000); + } runSample("update"); - + out = runSample("readstaledata"); + assertThat(out).contains("1 1 NULL"); runSample("writetransaction"); - out = runSample("querymarketingbudget"); assertThat(out).contains("1 1 300000"); assertThat(out).contains("2 2 300000");