Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding samples for Jsonb data type #2147

Merged
merged 5 commits into from Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Expand Up @@ -49,7 +49,7 @@ If you are using Maven without BOM, add this to your dependencies:
If you are using Gradle 5.x or later, add this to your dependencies:

```Groovy
implementation platform('com.google.cloud:libraries-bom:26.1.3')
implementation platform('com.google.cloud:libraries-bom:26.1.4')

implementation 'com.google.cloud:google-cloud-spanner'
```
Expand Down Expand Up @@ -244,6 +244,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/
| Instance Operations | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/native-image/src/main/java/com/example/spanner/InstanceOperations.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/native-image/src/main/java/com/example/spanner/InstanceOperations.java) |
| Native Image Spanner Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/native-image/src/main/java/com/example/spanner/NativeImageSpannerSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/native-image/src/main/java/com/example/spanner/NativeImageSpannerSample.java) |
| Add Json Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AddJsonColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AddJsonColumnSample.java) |
| Add Jsonb Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AddJsonbColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AddJsonbColumnSample.java) |
| Add Numeric Column Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AddNumericColumnSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AddNumericColumnSample.java) |
| Async Dml Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AsyncDmlExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AsyncDmlExample.java) |
| Async Query Example | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/AsyncQueryExample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/AsyncQueryExample.java) |
Expand Down Expand Up @@ -282,6 +283,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/
| Pg Spanner Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/PgSpannerSample.java) |
| Query Information Schema Database Options Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/QueryInformationSchemaDatabaseOptionsSample.java) |
| Query With Json Parameter Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QueryWithJsonParameterSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/QueryWithJsonParameterSample.java) |
| Query With Jsonb Parameter Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QueryWithJsonbParameterSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/QueryWithJsonbParameterSample.java) |
| Query With Numeric Parameter Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QueryWithNumericParameterSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/QueryWithNumericParameterSample.java) |
| Quickstart Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/QuickstartSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/QuickstartSample.java) |
| Restore Backup With Encryption Key | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithEncryptionKey.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/RestoreBackupWithEncryptionKey.java) |
Expand All @@ -292,6 +294,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-spanner/tree/
| Update Database With Default Leader Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateDatabaseWithDefaultLeaderSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateDatabaseWithDefaultLeaderSample.java) |
| Update Instance Config Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateInstanceConfigSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateInstanceConfigSample.java) |
| Update Json Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateJsonDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateJsonDataSample.java) |
| Update Jsonb Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateJsonbDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateJsonbDataSample.java) |
| Update Numeric Data Sample | [source code](https://github.com/googleapis/java-spanner/blob/main/samples/snippets/src/main/java/com/example/spanner/UpdateNumericDataSample.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-spanner&page=editor&open_in_editor=samples/snippets/src/main/java/com/example/spanner/UpdateNumericDataSample.java) |


Expand Down
@@ -0,0 +1,57 @@
/*
* Copyright 2022 Google Inc.
*
* 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.
*/

package com.example.spanner;

// [START spanner_postgresql_jsonb_add_column]
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerOptions;
import com.google.common.collect.ImmutableList;
import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata;
import java.util.concurrent.ExecutionException;

class AddJsonbColumnSample {

static void addJsonbColumn() throws InterruptedException, ExecutionException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "my-project";
String instanceId = "my-instance";
String databaseId = "my-database";

try (Spanner spanner =
SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) {
DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();
addJsonbColumn(adminClient, instanceId, databaseId);
}
}

static void addJsonbColumn(DatabaseAdminClient adminClient, String instanceId, String databaseId)
throws InterruptedException, ExecutionException {
OperationFuture<Void, UpdateDatabaseDdlMetadata> operation =
adminClient.updateDatabaseDdl(
instanceId,
databaseId,
ImmutableList.of("ALTER TABLE Venues ADD COLUMN VenueDetails JSONB"),
null);
// Wait for the operation to finish.
// This will throw an ExecutionException if the operation fails.
operation.get();
System.out.printf("Successfully added column `VenueDetails`%n");
}
}
// [END spanner_postgresql_jsonb_add_column]
@@ -0,0 +1,64 @@
/*
* Copyright 2022 Google Inc.
*
* 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.
*/

package com.example.spanner;

// [START spanner_postgresql_jsonb_query_parameter]
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.Value;

class QueryWithJsonbParameterSample {

static void queryWithJsonbParameter() {
// TODO(developer): Replace these variables before running the sample.
String projectId = "my-project";
String instanceId = "my-instance";
String databaseId = "my-database";

try (Spanner spanner =
SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) {
DatabaseClient client =
spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
queryWithJsonbParameter(client);
}
}

static void queryWithJsonbParameter(DatabaseClient client) {
int rating = 2;
Statement statement =
Statement.newBuilder(
"SELECT VenueId, VenueDetails\n"
+ "FROM Venues\n"
+ "WHERE CAST(venuedetails ->> 'rating' "
+ "AS INTEGER) > $1")
.bind("p1")
.to(Value.int64(rating))
.build();
try (ResultSet resultSet = client.singleUse().executeQuery(statement)) {
while (resultSet.next()) {
System.out.printf(
"VenueId: %s, VenueDetails: %s%n",
resultSet.getLong("venueid"), resultSet.getPgJsonb("venuedetails"));
}
}
}
}
// [END spanner_postgresql_jsonb_query_parameter]
@@ -0,0 +1,75 @@
/*
* Copyright 2022 Google Inc.
*
* 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.
*/

package com.example.spanner;

// [START spanner_postgresql_jsonb_update_data]
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.Mutation;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Value;
import com.google.common.collect.ImmutableList;

class UpdateJsonbDataSample {

static void updateJsonbData() {
// TODO(developer): Replace these variables before running the sample.
String projectId = "my-project";
String instanceId = "my-instance";
String databaseId = "my-database";

try (Spanner spanner =
SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) {
DatabaseClient client =
spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
updateJsonbData(client);
}
}

rajatbhatta marked this conversation as resolved.
Show resolved Hide resolved
static void updateJsonbData(DatabaseClient client) {
client.write(
ImmutableList.of(
Mutation.newInsertOrUpdateBuilder("Venues")
.set("VenueId")
.to(4L)
.set("VenueDetails")
.to(
Value.pgJsonb(
"[{\"name\":\"room 1\",\"open\":true},"
+ "{\"name\":\"room 2\",\"open\":false}]"))
.build(),
Mutation.newInsertOrUpdateBuilder("Venues")
.set("VenueId")
.to(19L)
.set("VenueDetails")
.to(Value.pgJsonb("{\"rating\":9,\"open\":true}"))
.build(),
Mutation.newInsertOrUpdateBuilder("Venues")
.set("VenueId")
.to(42L)
.set("VenueDetails")
.to(
Value.pgJsonb(
"{\"name\":null,"
+ "\"open\":{\"Monday\":true,\"Tuesday\":false},"
+ "\"tags\":[\"large\",\"airy\"]}"))
.build()));
System.out.println("Venues successfully updated");
}
}
// [END spanner_postgresql_jsonb_update_data]
Expand Up @@ -28,6 +28,7 @@
import com.google.cloud.spanner.Mutation;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Value;
import com.google.common.collect.ImmutableList;
import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata;
import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -99,6 +100,7 @@ public static void createTestDatabase() throws Exception {
"CREATE TABLE Venues ("
+ "VenueId bigint NOT NULL,"
+ "Revenue NUMERIC,"
+ "VenueDetails JSONB,"
rajatbhatta marked this conversation as resolved.
Show resolved Hide resolved
+ "PRIMARY KEY (VenueId))"),
null).get();
}
Expand Down Expand Up @@ -206,4 +208,79 @@ public void queryWithNumericParameter_shouldReturnResults() {
runExample(() -> PgQueryWithNumericParameterSample.queryWithNumericParameter(client));
assertThat(out).contains("4 35000");
}

@Test
public void addJsonbColumn_shouldSuccessfullyAddColumn()
throws InterruptedException, ExecutionException {
OperationFuture<Void, UpdateDatabaseDdlMetadata> operation =
spanner
.getDatabaseAdminClient()
.updateDatabaseDdl(
instanceId,
databaseId,
ImmutableList.of("ALTER TABLE Venues DROP COLUMN VenueDetails"),
null);
operation.get();
String out =
runExample(
() -> {
try {
AddJsonbColumnSample.addJsonbColumn(
spanner.getDatabaseAdminClient(), instanceId, databaseId);
} catch (ExecutionException e) {
System.out.printf(
"Adding column `VenueDetails` failed: %s%n", e.getCause().getMessage());
} catch (InterruptedException e) {
System.out.printf("Adding column `VenueDetails` was interrupted%n");
}
});
assertThat(out).contains("Successfully added column `VenueDetails`");
}

@Test
public void updateJsonbData_shouldWriteData() {
String projectId = spanner.getOptions().getProjectId();
String out =
runExample(
() ->
UpdateJsonbDataSample.updateJsonbData(
spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId))));
assertThat(out).contains("Venues successfully updated");
}

@Test
public void queryWithJsonbParameter_shouldReturnResults() {
String projectId = spanner.getOptions().getProjectId();
DatabaseClient client =
spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
client.write(
ImmutableList.of(
Mutation.newInsertOrUpdateBuilder("Venues")
.set("VenueId")
.to(4L)
.set("VenueDetails")
.to(
Value.pgJsonb(
"[{\"name\":\"room 1\",\"open\":true},"
+ "{\"name\":\"room 2\",\"open\":false}]"))
.build(),
Mutation.newInsertOrUpdateBuilder("Venues")
.set("VenueId")
.to(19L)
.set("VenueDetails")
.to(Value.pgJsonb("{\"rating\":9,\"open\":true}"))
.build(),
Mutation.newInsertOrUpdateBuilder("Venues")
.set("VenueId")
.to(42L)
.set("VenueDetails")
.to(
Value.pgJsonb(
"{\"name\":null,"
+ "\"open\":{\"Monday\":true,\"Tuesday\":false},"
+ "\"tags\":[\"large\",\"airy\"]}"))
.build()));
String out = runExample(() -> QueryWithJsonbParameterSample.queryWithJsonbParameter(client));
assertThat(out).contains("VenueId: 19, VenueDetails: {\"open\": true, \"rating\": 9}");
}
}