Skip to content

Commit 14ae01c

Browse files
authored
docs: samples and tests for database Admin APIs. (#2775)
Adds samples and tests for auto-generated Database Admin APIs.
1 parent c8632f5 commit 14ae01c

40 files changed

+2515
-182
lines changed

README.md

Lines changed: 22 additions & 1 deletion
Large diffs are not rendered by default.

samples/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<groupId>com.google.cloud.samples</groupId>
2020
<artifactId>shared-configuration</artifactId>
2121
<version>1.2.0</version>
22+
<relativePath></relativePath>
2223
</parent>
2324

2425
<properties>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2022 Google Inc.
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.example.spanner.admin.generated;
18+
19+
// [START spanner_add_and_drop_database_role]
20+
21+
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
22+
import com.google.common.collect.ImmutableList;
23+
import com.google.spanner.admin.database.v1.DatabaseName;
24+
import java.io.IOException;
25+
import java.util.concurrent.ExecutionException;
26+
import java.util.concurrent.TimeUnit;
27+
import java.util.concurrent.TimeoutException;
28+
29+
public class AddAndDropDatabaseRole {
30+
31+
static void addAndDropDatabaseRole() throws IOException {
32+
// TODO(developer): Replace these variables before running the sample.
33+
String projectId = "my-project";
34+
String instanceId = "my-instance";
35+
String databaseId = "my-database";
36+
String parentRole = "parent_role";
37+
String childRole = "child_role";
38+
addAndDropDatabaseRole(projectId, instanceId, databaseId, parentRole, childRole);
39+
}
40+
41+
static void addAndDropDatabaseRole(
42+
String projectId, String instanceId, String databaseId, String parentRole, String childRole)
43+
throws IOException {
44+
final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create();
45+
try {
46+
System.out.println("Waiting for role create operation to complete...");
47+
databaseAdminClient.updateDatabaseDdlAsync(
48+
DatabaseName.of(projectId, instanceId, databaseId),
49+
ImmutableList.of(
50+
String.format("CREATE ROLE %s", parentRole),
51+
String.format("GRANT SELECT ON TABLE Albums TO ROLE %s", parentRole),
52+
String.format("CREATE ROLE %s", childRole),
53+
String.format("GRANT ROLE %s TO ROLE %s", parentRole, childRole)))
54+
.get(5, TimeUnit.MINUTES);
55+
System.out.printf(
56+
"Created roles %s and %s and granted privileges%n", parentRole, childRole);
57+
// Delete role and membership.
58+
System.out.println("Waiting for role revoke & drop operation to complete...");
59+
databaseAdminClient.updateDatabaseDdlAsync(
60+
DatabaseName.of(projectId, instanceId, databaseId),
61+
ImmutableList.of(
62+
String.format("REVOKE ROLE %s FROM ROLE %s", parentRole, childRole),
63+
String.format("DROP ROLE %s", childRole))).get(5, TimeUnit.MINUTES);
64+
System.out.printf("Revoked privileges and dropped role %s%n", childRole);
65+
} catch (ExecutionException | TimeoutException e) {
66+
System.out.printf(
67+
"Error: AddAndDropDatabaseRole failed with error message %s\n", e.getMessage());
68+
e.printStackTrace();
69+
} catch (InterruptedException e) {
70+
System.out.println(
71+
"Error: Waiting for AddAndDropDatabaseRole operation to finish was interrupted");
72+
}
73+
}
74+
}
75+
// [END spanner_add_and_drop_database_role]
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2021 Google Inc.
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.example.spanner.admin.generated;
18+
19+
// [START spanner_add_json_column]
20+
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
21+
import com.google.common.collect.ImmutableList;
22+
import com.google.spanner.admin.database.v1.DatabaseName;
23+
import java.io.IOException;
24+
import java.util.concurrent.ExecutionException;
25+
26+
class AddJsonColumnSample {
27+
28+
static void addJsonColumn() throws InterruptedException, ExecutionException, IOException {
29+
// TODO(developer): Replace these variables before running the sample.
30+
String projectId = "my-project";
31+
String instanceId = "my-instance";
32+
String databaseId = "my-database";
33+
34+
addJsonColumn(projectId, instanceId, databaseId);
35+
}
36+
37+
static void addJsonColumn(String projectId, String instanceId, String databaseId)
38+
throws InterruptedException, ExecutionException, IOException {
39+
final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create();
40+
41+
// Wait for the operation to finish.
42+
// This will throw an ExecutionException if the operation fails.
43+
databaseAdminClient.updateDatabaseDdlAsync(
44+
DatabaseName.of(projectId, instanceId, databaseId),
45+
ImmutableList.of("ALTER TABLE Venues ADD COLUMN VenueDetails JSON")).get();
46+
System.out.printf("Successfully added column `VenueDetails`%n");
47+
}
48+
}
49+
// [END spanner_add_json_column]
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2022 Google Inc.
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.example.spanner.admin.generated;
18+
19+
// [START spanner_postgresql_jsonb_add_column]
20+
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
21+
import com.google.common.collect.ImmutableList;
22+
import com.google.spanner.admin.database.v1.DatabaseName;
23+
import java.io.IOException;
24+
import java.util.concurrent.ExecutionException;
25+
26+
class AddJsonbColumnSample {
27+
28+
static void addJsonbColumn() throws InterruptedException, ExecutionException, IOException {
29+
// TODO(developer): Replace these variables before running the sample.
30+
String projectId = "my-project";
31+
String instanceId = "my-instance";
32+
String databaseId = "my-database";
33+
34+
addJsonbColumn(projectId, instanceId, databaseId);
35+
}
36+
37+
static void addJsonbColumn(String projectId, String instanceId, String databaseId)
38+
throws InterruptedException, ExecutionException, IOException {
39+
final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create();
40+
41+
// JSONB datatype is only supported with PostgreSQL-dialect databases.
42+
// Wait for the operation to finish.
43+
// This will throw an ExecutionException if the operation fails.
44+
databaseAdminClient.updateDatabaseDdlAsync(
45+
DatabaseName.of(projectId, instanceId, databaseId),
46+
ImmutableList.of("ALTER TABLE Venues ADD COLUMN VenueDetails JSONB")).get();
47+
System.out.printf("Successfully added column `VenueDetails`%n");
48+
}
49+
}
50+
// [END spanner_postgresql_jsonb_add_column]
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2020 Google Inc.
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.example.spanner.admin.generated;
18+
19+
// [START spanner_add_numeric_column]
20+
21+
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
22+
import com.google.common.collect.ImmutableList;
23+
import com.google.spanner.admin.database.v1.DatabaseName;
24+
import java.io.IOException;
25+
import java.util.concurrent.ExecutionException;
26+
27+
class AddNumericColumnSample {
28+
29+
static void addNumericColumn() throws InterruptedException, ExecutionException, IOException {
30+
// TODO(developer): Replace these variables before running the sample.
31+
String projectId = "my-project";
32+
String instanceId = "my-instance";
33+
String databaseId = "my-database";
34+
35+
addNumericColumn(projectId, instanceId, databaseId);
36+
}
37+
38+
static void addNumericColumn(String projectId, String instanceId, String databaseId)
39+
throws InterruptedException, ExecutionException, IOException {
40+
final DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create();
41+
42+
// Wait for the operation to finish.
43+
// This will throw an ExecutionException if the operation fails.
44+
databaseAdminClient.updateDatabaseDdlAsync(
45+
DatabaseName.of(projectId, instanceId, databaseId),
46+
ImmutableList.of("ALTER TABLE Venues ADD COLUMN Revenue NUMERIC")).get();
47+
System.out.printf("Successfully added column `Revenue`%n");
48+
}
49+
}
50+
// [END spanner_add_numeric_column]
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright 2023 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.example.spanner.admin.generated;
18+
19+
// [START spanner_alter_sequence]
20+
21+
import com.google.cloud.spanner.DatabaseClient;
22+
import com.google.cloud.spanner.DatabaseId;
23+
import com.google.cloud.spanner.ResultSet;
24+
import com.google.cloud.spanner.Spanner;
25+
import com.google.cloud.spanner.SpannerExceptionFactory;
26+
import com.google.cloud.spanner.SpannerOptions;
27+
import com.google.cloud.spanner.Statement;
28+
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
29+
import com.google.common.collect.ImmutableList;
30+
import com.google.spanner.admin.database.v1.DatabaseName;
31+
import java.io.IOException;
32+
import java.util.Objects;
33+
import java.util.concurrent.ExecutionException;
34+
import java.util.concurrent.TimeUnit;
35+
import java.util.concurrent.TimeoutException;
36+
37+
public class AlterSequenceSample {
38+
39+
static void alterSequence() throws IOException {
40+
// TODO(developer): Replace these variables before running the sample.
41+
final String projectId = "my-project";
42+
final String instanceId = "my-instance";
43+
final String databaseId = "my-database";
44+
alterSequence(projectId, instanceId, databaseId);
45+
}
46+
47+
static void alterSequence(String projectId, String instanceId, String databaseId)
48+
throws IOException {
49+
DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create();
50+
try (Spanner spanner =
51+
SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) {
52+
53+
databaseAdminClient
54+
.updateDatabaseDdlAsync(DatabaseName.of(projectId, instanceId, databaseId),
55+
ImmutableList.of(
56+
"ALTER SEQUENCE Seq SET OPTIONS "
57+
+ "(skip_range_min = 1000, skip_range_max = 5000000)"))
58+
.get(5, TimeUnit.MINUTES);
59+
60+
System.out.println(
61+
"Altered Seq sequence to skip an inclusive range between 1000 and 5000000");
62+
63+
final DatabaseClient dbClient =
64+
spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
65+
66+
Long insertCount =
67+
dbClient
68+
.readWriteTransaction()
69+
.run(
70+
transaction -> {
71+
try (ResultSet rs =
72+
transaction.executeQuery(
73+
Statement.of(
74+
"INSERT INTO Customers (CustomerName) VALUES "
75+
+ "('Lea'), ('Catalina'), ('Smith') "
76+
+ "THEN RETURN CustomerId"))) {
77+
while (rs.next()) {
78+
System.out.printf(
79+
"Inserted customer record with CustomerId: %d\n", rs.getLong(0));
80+
}
81+
return Objects.requireNonNull(rs.getStats()).getRowCountExact();
82+
}
83+
});
84+
System.out.printf("Number of customer records inserted is: %d\n", insertCount);
85+
} catch (ExecutionException e) {
86+
// If the operation failed during execution, expose the cause.
87+
throw SpannerExceptionFactory.asSpannerException(e.getCause());
88+
} catch (InterruptedException e) {
89+
// Throw when a thread is waiting, sleeping, or otherwise occupied,
90+
// and the thread is interrupted, either before or during the activity.
91+
throw SpannerExceptionFactory.propagateInterrupt(e);
92+
} catch (TimeoutException e) {
93+
// If the operation timed out propagate the timeout
94+
throw SpannerExceptionFactory.propagateTimeout(e);
95+
}
96+
}
97+
}
98+
// [END spanner_alter_sequence]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2023 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.example.spanner.admin.generated;
18+
19+
// [START spanner_alter_table_with_foreign_key_delete_cascade]
20+
21+
import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
22+
import com.google.common.collect.ImmutableList;
23+
import com.google.spanner.admin.database.v1.DatabaseName;
24+
import java.io.IOException;
25+
26+
class AlterTableWithForeignKeyDeleteCascadeSample {
27+
28+
static void alterForeignKeyDeleteCascadeConstraint() throws IOException {
29+
// TODO(developer): Replace these variables before running the sample.
30+
String projectId = "my-project";
31+
String instanceId = "my-instance";
32+
String databaseId = "my-database";
33+
34+
alterForeignKeyDeleteCascadeConstraint(projectId, instanceId, databaseId);
35+
}
36+
37+
static void alterForeignKeyDeleteCascadeConstraint(
38+
String projectId, String instanceId, String databaseId) throws IOException {
39+
DatabaseAdminClient databaseAdminClient = DatabaseAdminClient.create();
40+
41+
databaseAdminClient.updateDatabaseDdlAsync(DatabaseName.of(projectId, instanceId,
42+
databaseId),
43+
ImmutableList.of(
44+
"ALTER TABLE ShoppingCarts\n"
45+
+ " ADD CONSTRAINT FKShoppingCartsCustomerName\n"
46+
+ " FOREIGN KEY (CustomerName)\n"
47+
+ " REFERENCES Customers(CustomerName)\n"
48+
+ " ON DELETE CASCADE\n"));
49+
System.out.printf(
50+
String.format(
51+
"Altered ShoppingCarts table with FKShoppingCartsCustomerName\n"
52+
+ "foreign key constraint on database %s on instance %s",
53+
databaseId, instanceId));
54+
}
55+
}
56+
// [END spanner_alter_table_with_foreign_key_delete_cascade]

0 commit comments

Comments
 (0)