From 4447711b737ccd0f6db8ec29442f65d34732a361 Mon Sep 17 00:00:00 2001 From: Nithin Nayak Sujir Date: Mon, 27 Aug 2018 10:53:19 -0700 Subject: [PATCH 1/2] spanner: Add snippets for BatchClient and BatchReadOnlyTransaction --- .../com/google/cloud/spanner/BatchClient.java | 13 ++ .../spanner/BatchReadOnlyTransaction.java | 96 ++++++++++++ .../spanner/snippets/BatchClientSnippets.java | 138 ++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 google-cloud-examples/src/main/java/com/google/cloud/examples/spanner/snippets/BatchClientSnippets.java diff --git a/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchClient.java b/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchClient.java index 09b839e686dc..e038cfa6fa26 100644 --- a/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchClient.java +++ b/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchClient.java @@ -38,6 +38,12 @@ public interface BatchClient { * {@link BatchReadOnlyTransaction}. * * @param bound the timestamp bound at which to perform the read + * + * + *
{@code
+   * BatchReadOnlyTransaction txn = batchClient.batchReadOnlyTransaction(TimestampBound.strong());
+   * }
+ * */ BatchReadOnlyTransaction batchReadOnlyTransaction(TimestampBound bound); @@ -52,6 +58,13 @@ public interface BatchClient { * * @param batchTransactionId to re-initialize the transaction, re-using the timestamp for * successive read/query. + * + * + *
{@code
+   * BatchTransactionId txnId = my_txn.getBatchTransactionId();
+   * BatchReadOnlyTransaction txn = batchClient.batchReadOnlyTransaction(txnId);
+   * }
+ * */ BatchReadOnlyTransaction batchReadOnlyTransaction(BatchTransactionId batchTransactionId); } diff --git a/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchReadOnlyTransaction.java b/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchReadOnlyTransaction.java index 89d7719f889a..6371c456dc06 100644 --- a/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchReadOnlyTransaction.java +++ b/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/BatchReadOnlyTransaction.java @@ -54,6 +54,29 @@ public interface BatchReadOnlyTransaction extends ReadOnlyTransaction { * @param columns the columns to read * @param options the options to configure the read, supported values are * {@link Options#prefetchChunks()} + * + * + *
{@code
+   * final BatchReadOnlyTransaction txn =
+   *     batchClient.batchReadOnlyTransaction(TimestampBound.strong());
+   * List partitions =
+   *     txn.partitionRead(
+   *         PartitionOptions.getDefaultInstance(),
+   *         "Singers",
+   *         KeySet.all(),
+   *         Arrays.asList("SingerId", "FirstName", "LastName"));
+   * for (final Partition p : partitions) {
+   *   try (ResultSet results = txn.execute(p)) {
+   *     while (results.next()) {
+   *       long singerId = results.getLong(0);
+   *       String firstName = results.getString(1);
+   *       String lastName = results.getString(2);
+   *       System.out.println("P2 [" + singerId + "] " + firstName + " " + lastName);
+   *     }
+   *   }
+   * }
+   * }
+ * */ List partitionRead( PartitionOptions partitionOptions, @@ -76,6 +99,30 @@ List partitionRead( * rows are returned in the natural key order of the index. * @param columns the columns to read * @param options the options to configure the read + * + * + *
{@code
+   * final BatchReadOnlyTransaction txn =
+   *     batchClient.batchReadOnlyTransaction(TimestampBound.strong());
+   * List partitions =
+   *     txn.partitionReadUsingIndex(
+   *         PartitionOptions.getDefaultInstance(),
+   *         "Singers",
+   *         "SingerId",
+   *         KeySet.all(),
+   *         Arrays.asList("FirstName"));
+   * BatchTransactionId txnID = txn.getBatchTransactionId();
+   * int numRowsRead = 0;
+   * for (Partition p : partitions) {
+   *   BatchReadOnlyTransaction batchTxnOnEachWorker = batchClient.batchReadOnlyTransaction(txnID);
+   *   try (ResultSet results = batchTxnOnEachWorker.execute(p)) {
+   *     while (results.next()) {
+   *       System.out.println(results.getString(0));
+   *     }
+   *   }
+   * }
+   * }
+ * */ List partitionReadUsingIndex( PartitionOptions partitionOptions, @@ -95,6 +142,26 @@ List partitionReadUsingIndex( * @param partitionOptions configuration for size and count of partitions returned * @param statement the query statement to execute * @param options the options to configure the query + * + * + *
{@code
+   * final BatchReadOnlyTransaction txn =
+   *     batchClient.batchReadOnlyTransaction(TimestampBound.strong());
+   * List partitions = txn.partitionQuery(PartitionOptions.getDefaultInstance(),
+   *     Statement.of("SELECT SingerId, FirstName, LastName FROM Singers"));
+   *
+   * for (final Partition p : partitions) {
+   *   try (ResultSet results = txn.execute(p)) {
+   *     while (results.next()) {
+   *       long singerId = results.getLong(0);
+   *       String firstName = results.getString(1);
+   *       String lastName = results.getString(2);
+   *       System.out.println("[" + singerId + "] " + firstName + " " + lastName);
+   *     }
+   *   }
+   * }
+   * }
+ * */ List partitionQuery( PartitionOptions partitionOptions, Statement statement, QueryOption... options) @@ -103,12 +170,41 @@ List partitionQuery( /** * Execute the partition to return {@link ResultSet}. The result returned could be zero or more * rows. The row metadata may be absent if no rows are returned. + * + * + *
{@code
+   * final BatchReadOnlyTransaction txn =
+   *     batchClient.batchReadOnlyTransaction(TimestampBound.strong());
+   * List partitions = txn.partitionQuery(PartitionOptions.getDefaultInstance(),
+   *     Statement.of("SELECT SingerId, FirstName, LastName FROM Singers"));
+   *
+   * for (final Partition p : partitions) {
+   *   try (ResultSet results = txn.execute(p)) {
+   *     while (results.next()) {
+   *       long singerId = results.getLong(0);
+   *       String firstName = results.getString(1);
+   *       String lastName = results.getString(2);
+   *       System.out.println("[" + singerId + "] " + firstName + " " + lastName);
+   *     }
+   *   }
+   * }
+   * }
+ * + * */ ResultSet execute(Partition partition) throws SpannerException; /** * Returns a {@link BatchTransactionId} to be re-used across several machines/processes. This * BatchTransactionId guarantees the subsequent read/query to be executed at the same timestamp. + * + * + *
{@code
+   * BatchTransactionId txnId = my_txn.getBatchTransactionId();
+   * BatchReadOnlyTransaction txn = batchClient.batchReadOnlyTransaction(txnId);
+   * }
+ * + * */ BatchTransactionId getBatchTransactionId(); } diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/spanner/snippets/BatchClientSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/spanner/snippets/BatchClientSnippets.java new file mode 100644 index 000000000000..835a3f195140 --- /dev/null +++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/spanner/snippets/BatchClientSnippets.java @@ -0,0 +1,138 @@ +/* + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in spanner/BatchClient's javadoc. Any change + * to this file should be reflected in spanner/BatchClient's javadoc. + */ + +package com.google.cloud.examples.spanner.snippets; + +import com.google.cloud.spanner.BatchClient; +import com.google.cloud.spanner.BatchReadOnlyTransaction; +import com.google.cloud.spanner.BatchTransactionId; +import com.google.cloud.spanner.KeySet; +import com.google.cloud.spanner.Partition; +import com.google.cloud.spanner.PartitionOptions; +import com.google.cloud.spanner.ResultSet; +import com.google.cloud.spanner.Statement; +import com.google.cloud.spanner.TimestampBound; +import java.util.Arrays; +import java.util.List; + +/** + * This class contains snippets for {@link com.google.cloud.spanner.BatchClient} interface. + */ +public class BatchClientSnippets { + + private final BatchClient batchClient; + + public BatchClientSnippets(BatchClient batchClient) { + this.batchClient = batchClient; + } + + /** + * Example to do a batch strong read. + */ + BatchReadOnlyTransaction readStrong() { + // [START batch_client_strong_read] + BatchReadOnlyTransaction txn = batchClient.batchReadOnlyTransaction(TimestampBound.strong()); + // [END batch_client_strong_read] + return txn; + } + + /** + * Example to do a batch read with txn id. + */ + BatchReadOnlyTransaction readWithId(BatchReadOnlyTransaction my_txn) { + // [START batch_client_read_with_id] + BatchTransactionId txnId = my_txn.getBatchTransactionId(); + BatchReadOnlyTransaction txn = batchClient.batchReadOnlyTransaction(txnId); + // [END batch_client_read_with_id] + + return txn; + } + + void partitionQuery() { + // [START partition_query] + final BatchReadOnlyTransaction txn = + batchClient.batchReadOnlyTransaction(TimestampBound.strong()); + List partitions = txn.partitionQuery(PartitionOptions.getDefaultInstance(), + Statement.of("SELECT SingerId, FirstName, LastName FROM Singers")); + + for (final Partition p : partitions) { + try (ResultSet results = txn.execute(p)) { + while (results.next()) { + long singerId = results.getLong(0); + String firstName = results.getString(1); + String lastName = results.getString(2); + System.out.println("[" + singerId + "] " + firstName + " " + lastName); + } + } + } + // [END partition_query] + + } + + void partitionRead() { + // [START partition_read] + final BatchReadOnlyTransaction txn = + batchClient.batchReadOnlyTransaction(TimestampBound.strong()); + List partitions = + txn.partitionRead( + PartitionOptions.getDefaultInstance(), + "Singers", + KeySet.all(), + Arrays.asList("SingerId", "FirstName", "LastName")); + for (final Partition p : partitions) { + try (ResultSet results = txn.execute(p)) { + while (results.next()) { + long singerId = results.getLong(0); + String firstName = results.getString(1); + String lastName = results.getString(2); + System.out.println("P2 [" + singerId + "] " + firstName + " " + lastName); + } + } + } + // [END partition_read] + } + + void partitionReadUsingIndex() { + // [START partition_read_using_index] + final BatchReadOnlyTransaction txn = + batchClient.batchReadOnlyTransaction(TimestampBound.strong()); + List partitions = + txn.partitionReadUsingIndex( + PartitionOptions.getDefaultInstance(), + "Singers", + "SingerId", + KeySet.all(), + Arrays.asList("FirstName")); + BatchTransactionId txnID = txn.getBatchTransactionId(); + int numRowsRead = 0; + for (Partition p : partitions) { + BatchReadOnlyTransaction batchTxnOnEachWorker = batchClient.batchReadOnlyTransaction(txnID); + try (ResultSet results = batchTxnOnEachWorker.execute(p)) { + while (results.next()) { + System.out.println(results.getString(0)); + } + } + } + // [END partition_read_using_index] + } +} + From afb2b3b106985b6cb583db5f070230eba607bfcb Mon Sep 17 00:00:00 2001 From: Nithin Nayak Sujir Date: Tue, 28 Aug 2018 14:13:12 -0700 Subject: [PATCH 2/2] Add snippets to Spanner --- .../com/google/cloud/spanner/Spanner.java | 44 ++++++++++ .../spanner/snippets/SpannerSnippets.java | 88 +++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 google-cloud-examples/src/main/java/com/google/cloud/examples/spanner/snippets/SpannerSnippets.java diff --git a/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Spanner.java b/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Spanner.java index 51ec44b727bc..4f6cb1b901a6 100644 --- a/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Spanner.java +++ b/google-cloud-clients/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Spanner.java @@ -26,14 +26,45 @@ */ public interface Spanner extends Service { /** Returns a {@code DatabaseAdminClient} to do admin operations on Cloud Spanner databases. */ + /* + * + *
{@code
+   * SpannerOptions options = SpannerOptions.newBuilder().build();
+   * Spanner spanner = options.getService();
+   * DatabaseAdminClient dbAdminClient = spanner.getDatabaseAdminClient();
+   * }
+ * + */ DatabaseAdminClient getDatabaseAdminClient(); /** Returns an {@code InstanceAdminClient} to do admin operations on Cloud Spanner instances. */ + /* + * + *
{@code
+   * SpannerOptions options = SpannerOptions.newBuilder().build();
+   * Spanner spanner = options.getService();
+   * InstanceAdminClient instanceAdminClient = spanner.getInstanceAdminClient();
+   * }
+ * + */ InstanceAdminClient getInstanceAdminClient(); /** * Returns a {@code DatabaseClient} for the given database. It uses a pool of sessions to talk to * the database. + * + * + *
{@code
+   * SpannerOptions options = SpannerOptions.newBuilder().build();
+   * Spanner spanner = options.getService();
+   * final String project = "test-project";
+   * final String instance = "test-instance";
+   * final String database = "example-db";
+   * DatabaseId db =
+   *     DatabaseId.of("span-cloud-testing", "nsujir-ins", "example-db");
+   * DatabaseClient dbClient = spanner.getDatabaseClient(db);
+   * }
+ * */ DatabaseClient getDatabaseClient(DatabaseId db); @@ -45,6 +76,19 @@ public interface Spanner extends Service { * yet at the same snapshot. * *

For all other use cases, {@code DatabaseClient} is more appropriate and performant. + * + * + *

{@code
+   * SpannerOptions options = SpannerOptions.newBuilder().build();
+   * Spanner spanner = options.getService();
+   * final String project = "test-project";
+   * final String instance = "test-instance";
+   * final String database = "example-db";
+   * DatabaseId db =
+   *     DatabaseId.of("span-cloud-testing", "nsujir-ins", "example-db");
+   * BatchClient batchClient = spanner.getBatchClient(db);
+   * }
+ * */ BatchClient getBatchClient(DatabaseId db); diff --git a/google-cloud-examples/src/main/java/com/google/cloud/examples/spanner/snippets/SpannerSnippets.java b/google-cloud-examples/src/main/java/com/google/cloud/examples/spanner/snippets/SpannerSnippets.java new file mode 100644 index 000000000000..b57c9dc80433 --- /dev/null +++ b/google-cloud-examples/src/main/java/com/google/cloud/examples/spanner/snippets/SpannerSnippets.java @@ -0,0 +1,88 @@ +/* + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in spanner/Spanner's javadoc. Any change + * to this file should be reflected in spanner/Spanner's javadoc. + */ + +package com.google.cloud.examples.spanner.snippets; + +import com.google.cloud.spanner.BatchClient; +import com.google.cloud.spanner.DatabaseAdminClient; +import com.google.cloud.spanner.DatabaseClient; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.InstanceAdminClient; +import com.google.cloud.spanner.Spanner; +import com.google.cloud.spanner.SpannerOptions; + +/** + * This class contains snippets for {@link com.google.cloud.spanner.Spanner} interface. + */ +public class SpannerSnippets { + + DatabaseAdminClient getDatabaseAdminClient() { + // [START get_dbadmin_client] + SpannerOptions options = SpannerOptions.newBuilder().build(); + Spanner spanner = options.getService(); + DatabaseAdminClient dbAdminClient = spanner.getDatabaseAdminClient(); + // [END get_dbadmin_client] + + return dbAdminClient; + } + + DatabaseClient getDatabaseClient() { + // [START get_db_client] + SpannerOptions options = SpannerOptions.newBuilder().build(); + Spanner spanner = options.getService(); + final String project = "test-project"; + final String instance = "test-instance"; + final String database = "example-db"; + DatabaseId db = + DatabaseId.of("span-cloud-testing", "nsujir-ins", "example-db"); + DatabaseClient dbClient = spanner.getDatabaseClient(db); + // [END get_db_client] + + return dbClient; + } + + InstanceAdminClient getInstanceAdminClient() { + // [START get_instance_admin_client] + SpannerOptions options = SpannerOptions.newBuilder().build(); + Spanner spanner = options.getService(); + InstanceAdminClient instanceAdminClient = spanner.getInstanceAdminClient(); + // [END get_instance_admin_client] + + return instanceAdminClient; + } + + BatchClient getBatchClient() { + // [START get_batch_client] + SpannerOptions options = SpannerOptions.newBuilder().build(); + Spanner spanner = options.getService(); + final String project = "test-project"; + final String instance = "test-instance"; + final String database = "example-db"; + DatabaseId db = + DatabaseId.of("span-cloud-testing", "nsujir-ins", "example-db"); + BatchClient batchClient = spanner.getBatchClient(db); + // [END get_batch_client] + + return batchClient; + } +} +