diff --git a/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java b/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java
new file mode 100644
index 00000000000..fa23b6401b5
--- /dev/null
+++ b/samples/snippets/src/main/java/com/example/spanner/SpannerGraphSample.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright 2024 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;
+
+import com.google.cloud.Timestamp;
+import com.google.cloud.spanner.DatabaseClient;
+import com.google.cloud.spanner.DatabaseId;
+import com.google.cloud.spanner.Key;
+import com.google.cloud.spanner.KeyRange;
+import com.google.cloud.spanner.KeySet;
+import com.google.cloud.spanner.Mutation;
+import com.google.cloud.spanner.ResultSet;
+import com.google.cloud.spanner.Spanner;
+import com.google.cloud.spanner.SpannerException;
+import com.google.cloud.spanner.SpannerExceptionFactory;
+import com.google.cloud.spanner.SpannerOptions;
+import com.google.cloud.spanner.Statement;
+import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
+import com.google.spanner.admin.database.v1.CreateDatabaseRequest;
+import com.google.spanner.admin.database.v1.InstanceName;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Example code for using the Cloud Spanner API. This example demonstrates all the common property
+ * graph operations that can be done on Cloud Spanner. These are:
+ *
+ *
+ *
+ *
+ * - Creating a Cloud Spanner database with a property graph.
+ *
- Inserting data, updating and deleting data.
+ *
- Executing graph queries.
+ *
+ */
+public class SpannerGraphSample {
+
+ // [START spanner_insert_graph_data]
+ /** Class to contain sample Person data. */
+ static class Person {
+
+ final long id;
+ final String name;
+ final Timestamp birthday;
+ final String country;
+ final String city;
+
+ Person(long id, String name, Timestamp birthday, String country, String city) {
+ this.id = id;
+ this.name = name;
+ this.birthday = birthday;
+ this.country = country;
+ this.city = city;
+ }
+ }
+
+ /** Class to contain sample Account data. */
+ static class Account {
+
+ final long id;
+ final Timestamp createTime;
+ final boolean isBlocked;
+ final String nickName;
+
+ Account(long id, Timestamp createTime, boolean isBlocked, String nickName) {
+ this.id = id;
+ this.createTime = createTime;
+ this.isBlocked = isBlocked;
+ this.nickName = nickName;
+ }
+ }
+
+ /** Class to contain sample Transfer data. */
+ static class Transfer {
+
+ final long id;
+ final long toId;
+ final double amount;
+ final Timestamp createTime;
+ final String orderNumber;
+
+ Transfer(long id, long toId, double amount, Timestamp createTime, String orderNumber) {
+ this.id = id;
+ this.toId = toId;
+ this.amount = amount;
+ this.createTime = createTime;
+ this.orderNumber = orderNumber;
+ }
+ }
+
+ /** Class to contain sample Ownership data. */
+ static class Own {
+
+ final long id;
+ final long accountId;
+ final Timestamp createTime;
+
+ Own(long id, long accountId, Timestamp createTime) {
+ this.id = id;
+ this.accountId = accountId;
+ this.createTime = createTime;
+ }
+ }
+
+ // [END spanner_insert_graph_data]
+
+ // [START spanner_create_database_with_property_graph]
+ static void createDatabaseWithPropertyGraph(
+ DatabaseAdminClient dbAdminClient, InstanceName instanceName, String databaseId) {
+ CreateDatabaseRequest createDatabaseRequest =
+ CreateDatabaseRequest.newBuilder()
+ .setCreateStatement("CREATE DATABASE `" + databaseId + "`")
+ .setParent(instanceName.toString())
+ .addAllExtraStatements(
+ Arrays.asList(
+ "CREATE TABLE Person ("
+ + " id INT64 NOT NULL,"
+ + " name STRING(MAX),"
+ + " birthday TIMESTAMP,"
+ + " country STRING(MAX),"
+ + " city STRING(MAX),"
+ + ") PRIMARY KEY (id)",
+ "CREATE TABLE Account ("
+ + " id INT64 NOT NULL,"
+ + " create_time TIMESTAMP,"
+ + " is_blocked BOOL,"
+ + " nick_name STRING(MAX),"
+ + ") PRIMARY KEY (id)",
+ "CREATE TABLE PersonOwnAccount ("
+ + " id INT64 NOT NULL,"
+ + " account_id INT64 NOT NULL,"
+ + " create_time TIMESTAMP,"
+ + " FOREIGN KEY (account_id)"
+ + " REFERENCES Account (id)"
+ + ") PRIMARY KEY (id, account_id),"
+ + "INTERLEAVE IN PARENT Person ON DELETE CASCADE",
+ "CREATE TABLE AccountTransferAccount ("
+ + " id INT64 NOT NULL,"
+ + " to_id INT64 NOT NULL,"
+ + " amount FLOAT64,"
+ + " create_time TIMESTAMP NOT NULL OPTIONS"
+ + " (allow_commit_timestamp=true),"
+ + " order_number STRING(MAX),"
+ + " FOREIGN KEY (to_id) REFERENCES Account (id)"
+ + ") PRIMARY KEY (id, to_id, create_time),"
+ + "INTERLEAVE IN PARENT Account ON DELETE CASCADE",
+ "CREATE OR REPLACE PROPERTY GRAPH FinGraph "
+ + "NODE TABLES (Account, Person)"
+ + "EDGE TABLES ("
+ + " PersonOwnAccount"
+ + " SOURCE KEY(id) REFERENCES Person(id)"
+ + " DESTINATION KEY(account_id) REFERENCES Account(id)"
+ + " LABEL Owns,"
+ + " AccountTransferAccount"
+ + " SOURCE KEY(id) REFERENCES Account(id)"
+ + " DESTINATION KEY(to_id) REFERENCES Account(id)"
+ + " LABEL Transfers)"))
+ .build();
+ try {
+ // Initiate the request which returns an OperationFuture.
+ com.google.spanner.admin.database.v1.Database db =
+ dbAdminClient.createDatabaseAsync(createDatabaseRequest).get();
+ System.out.println("Created database [" + db.getName() + "]");
+ } catch (ExecutionException e) {
+ // If the operation failed during execution, expose the cause.
+ System.out.println("Encountered exception" + e.getCause());
+ throw (SpannerException) e.getCause();
+ } catch (InterruptedException e) {
+ // Throw when a thread is waiting, sleeping, or otherwise occupied,
+ // and the thread is interrupted, either before or during the activity.
+ throw SpannerExceptionFactory.propagateInterrupt(e);
+ }
+ }
+
+ // [END spanner_create_database_with_property_graph]
+
+ // [START spanner_insert_graph_data]
+ static final List ACCOUNTS =
+ Arrays.asList(
+ new Account(
+ 7, Timestamp.parseTimestamp("2020-01-10T06:22:20.12Z"), false, "Vacation Fund"),
+ new Account(
+ 16, Timestamp.parseTimestamp("2020-01-27T17:55:09.12Z"), true, "Vacation Fund"),
+ new Account(
+ 20, Timestamp.parseTimestamp("2020-02-18T05:44:20.12Z"), false, "Rainy Day Fund"));
+
+ static final List PERSONS =
+ Arrays.asList(
+ new Person(
+ 1,
+ "Alex",
+ Timestamp.parseTimestamp("1991-12-21T00:00:00.12Z"),
+ "Australia",
+ " Adelaide"),
+ new Person(
+ 2,
+ "Dana",
+ Timestamp.parseTimestamp("1980-10-31T00:00:00.12Z"),
+ "Czech_Republic",
+ "Moravia"),
+ new Person(
+ 3, "Lee", Timestamp.parseTimestamp("1986-12-07T00:00:00.12Z"), "India", "Kollam"));
+
+ static final List TRANSFERS =
+ Arrays.asList(
+ new Transfer(
+ 7, 16, 300.0, Timestamp.parseTimestamp("2020-08-29T15:28:58.12Z"), "304330008004315"),
+ new Transfer(
+ 7, 16, 100.0, Timestamp.parseTimestamp("2020-10-04T16:55:05.12Z"), "304120005529714"),
+ new Transfer(
+ 16,
+ 20,
+ 300.0,
+ Timestamp.parseTimestamp("2020-09-25T02:36:14.12Z"),
+ "103650009791820"),
+ new Transfer(
+ 20, 7, 500.0, Timestamp.parseTimestamp("2020-10-04T16:55:05.12Z"), "304120005529714"),
+ new Transfer(
+ 20,
+ 16,
+ 200.0,
+ Timestamp.parseTimestamp("2020-10-17T03:59:40.12Z"),
+ "302290001255747"));
+
+ static final List OWNERSHIPS =
+ Arrays.asList(
+ new Own(1, 7, Timestamp.parseTimestamp("2020-01-10T06:22:20.12Z")),
+ new Own(2, 20, Timestamp.parseTimestamp("2020-01-27T17:55:09.12Z")),
+ new Own(3, 16, Timestamp.parseTimestamp("2020-02-18T05:44:20.12Z")));
+
+ static void insertData(DatabaseClient dbClient) {
+ List mutations = new ArrayList<>();
+ for (Account account : ACCOUNTS) {
+ mutations.add(
+ Mutation.newInsertBuilder("Account")
+ .set("id")
+ .to(account.id)
+ .set("create_time")
+ .to(account.createTime)
+ .set("is_blocked")
+ .to(account.isBlocked)
+ .set("nick_name")
+ .to(account.nickName)
+ .build());
+ }
+ for (Person person : PERSONS) {
+ mutations.add(
+ Mutation.newInsertBuilder("Person")
+ .set("id")
+ .to(person.id)
+ .set("name")
+ .to(person.name)
+ .set("birthday")
+ .to(person.birthday)
+ .set("country")
+ .to(person.country)
+ .set("city")
+ .to(person.city)
+ .build());
+ }
+ for (Transfer transfer : TRANSFERS) {
+ mutations.add(
+ Mutation.newInsertBuilder("AccountTransferAccount")
+ .set("id")
+ .to(transfer.id)
+ .set("to_id")
+ .to(transfer.toId)
+ .set("amount")
+ .to(transfer.amount)
+ .set("create_time")
+ .to(transfer.createTime)
+ .set("order_number")
+ .to(transfer.orderNumber)
+ .build());
+ }
+ for (Own own : OWNERSHIPS) {
+ mutations.add(
+ Mutation.newInsertBuilder("PersonOwnAccount")
+ .set("id")
+ .to(own.id)
+ .set("account_id")
+ .to(own.accountId)
+ .set("create_time")
+ .to(own.createTime)
+ .build());
+ }
+
+ dbClient.write(mutations);
+ }
+
+ // [END spanner_insert_graph_data]
+
+ // [START spanner_insert_graph_data_with_dml]
+ static void insertUsingDml(DatabaseClient dbClient) {
+ dbClient
+ .readWriteTransaction()
+ .run(
+ transaction -> {
+ String sql =
+ "INSERT INTO Account (id, create_time, is_blocked) "
+ + " VALUES"
+ + " (1, CAST('2000-08-10 08:18:48.463959-07:52' AS TIMESTAMP), false),"
+ + " (2, CAST('2000-08-12 08:18:48.463959-07:52' AS TIMESTAMP), true)";
+ long rowCount = transaction.executeUpdate(Statement.of(sql));
+ System.out.printf("%d record(s) inserted into Account.\n", rowCount);
+ return null;
+ });
+
+ dbClient
+ .readWriteTransaction()
+ .run(
+ transaction -> {
+ String sql =
+ "INSERT INTO AccountTransferAccount (id, to_id, create_time, amount) "
+ + " VALUES"
+ + " (1, 2, PENDING_COMMIT_TIMESTAMP(), 100),"
+ + " (1, 1, PENDING_COMMIT_TIMESTAMP(), 200) ";
+ long rowCount = transaction.executeUpdate(Statement.of(sql));
+ System.out.printf("%d record(s) inserted into AccountTransferAccount.\n", rowCount);
+ return null;
+ });
+ }
+
+ // [END spanner_insert_graph_data_with_dml]
+
+ // [START spanner_update_graph_data_with_dml]
+ static void updateUsingDml(DatabaseClient dbClient) {
+ dbClient
+ .readWriteTransaction()
+ .run(
+ transaction -> {
+ String sql = "UPDATE Account SET is_blocked = false WHERE id = 2";
+ long rowCount = transaction.executeUpdate(Statement.of(sql));
+ System.out.printf("%d Account record(s) updated.\n", rowCount);
+ return null;
+ });
+
+ dbClient
+ .readWriteTransaction()
+ .run(
+ transaction -> {
+ String sql =
+ "UPDATE AccountTransferAccount SET amount = 300 WHERE id = 1 AND to_id = 2";
+ long rowCount = transaction.executeUpdate(Statement.of(sql));
+ System.out.printf("%d AccountTransferAccount record(s) updated.\n", rowCount);
+ return null;
+ });
+ }
+
+ // [END spanner_update_graph_data_with_dml]
+
+ // [START spanner_update_graph_data_with_graph_query_in_dml]
+ static void updateUsingGraphQueryInDml(DatabaseClient dbClient) {
+ dbClient
+ .readWriteTransaction()
+ .run(
+ transaction -> {
+ String sql =
+ "UPDATE Account SET is_blocked = true "
+ + "WHERE id IN {"
+ + " GRAPH FinGraph"
+ + " MATCH (a:Account WHERE a.id = 1)-[:TRANSFERS]->{1,2}(b:Account)"
+ + " RETURN b.id}";
+ long rowCount = transaction.executeUpdate(Statement.of(sql));
+ System.out.printf("%d Account record(s) updated.\n", rowCount);
+ return null;
+ });
+ }
+
+ // [END spanner_update_graph_data_with_graph_query_in_dml]
+
+ // [START spanner_query_graph_data]
+ static void query(DatabaseClient dbClient) {
+ try (ResultSet resultSet =
+ dbClient
+ .singleUse() // Execute a single query against Cloud Spanner.
+ .executeQuery(
+ Statement.of(
+ "Graph FinGraph MATCH"
+ + " (a:Person)-[o:Owns]->()-[t:Transfers]->()<-[p:Owns]-(b:Person)RETURN"
+ + " a.name AS sender, b.name AS receiver, t.amount, t.create_time AS"
+ + " transfer_at"))) {
+ while (resultSet.next()) {
+ System.out.printf(
+ "%s %s %f %s\n",
+ resultSet.getString(0),
+ resultSet.getString(1),
+ resultSet.getDouble(2),
+ resultSet.getTimestamp(3));
+ }
+ }
+ }
+
+ // [END spanner_query_graph_data]
+
+ // [START spanner_query_graph_data_with_parameter]
+ static void queryWithParameter(DatabaseClient dbClient) {
+ Statement statement =
+ Statement.newBuilder(
+ "Graph FinGraph MATCH"
+ + " (a:Person)-[o:Owns]->()-[t:Transfers]->()<-[p:Owns]-(b:Person) WHERE"
+ + " t.amount >= @min RETURN a.name AS sender, b.name AS receiver, t.amount,"
+ + " t.create_time AS transfer_at")
+ .bind("min")
+ .to(500)
+ .build();
+ try (ResultSet resultSet = dbClient.singleUse().executeQuery(statement)) {
+ while (resultSet.next()) {
+ System.out.printf(
+ "%s %s %f %s\n",
+ resultSet.getString("sender"),
+ resultSet.getString("receiver"),
+ resultSet.getDouble("amount"),
+ resultSet.getTimestamp("transfer_at"));
+ }
+ }
+ }
+
+ // [END spanner_query_graph_data_with_parameter]
+
+ // [START spanner_delete_graph_data_with_dml]
+ static void deleteUsingDml(DatabaseClient dbClient) {
+ dbClient
+ .readWriteTransaction()
+ .run(
+ transaction -> {
+ String sql = "DELETE FROM AccountTransferAccount WHERE id = 1 AND to_id = 2";
+ long rowCount = transaction.executeUpdate(Statement.of(sql));
+ System.out.printf("%d AccountTransferAccount record(s) deleted.\n", rowCount);
+ return null;
+ });
+
+ dbClient
+ .readWriteTransaction()
+ .run(
+ transaction -> {
+ String sql = "DELETE FROM Account WHERE id = 2";
+ long rowCount = transaction.executeUpdate(Statement.of(sql));
+ System.out.printf("%d Account record(s) deleted.\n", rowCount);
+ return null;
+ });
+ }
+
+ // [END spanner_delete_graph_data_with_dml]
+
+ // [START spanner_delete_graph_data]
+ static void deleteData(DatabaseClient dbClient) {
+ List mutations = new ArrayList<>();
+
+ // KeySet.Builder can be used to delete a specific set of rows.
+ // Delete the PersonOwnAccount rows with the key values (1,7) and (2,20).
+ mutations.add(
+ Mutation.delete(
+ "PersonOwnAccount",
+ KeySet.newBuilder().addKey(Key.of(1, 7)).addKey(Key.of(2, 20)).build()));
+
+ // KeyRange can be used to delete rows with a key in a specific range.
+ // Delete a range of rows where the key prefix is >=1 and <8
+ mutations.add(
+ Mutation.delete(
+ "AccountTransferAccount", KeySet.range(KeyRange.closedOpen(Key.of(1), Key.of(8)))));
+
+ // KeySet.all() can be used to delete all the rows in a table.
+ // Delete all Account rows, which will also delete the remaining
+ // AccountTransferAccount rows since it was defined with ON DELETE CASCADE.
+ mutations.add(Mutation.delete("Account", KeySet.all()));
+
+ // KeySet.all() can be used to delete all the rows in a table.
+ // Delete all Person rows, which will also delete the remaining
+ // PersonOwnAccount rows since it was defined with ON DELETE CASCADE.
+ mutations.add(Mutation.delete("Person", KeySet.all()));
+
+ dbClient.write(mutations);
+ System.out.printf("Records deleted.\n");
+ }
+
+ // [END spanner_delete_graph_data]
+
+ static void run(
+ DatabaseClient dbClient,
+ DatabaseAdminClient dbAdminClient,
+ String command,
+ DatabaseId database) {
+ switch (command) {
+ case "createdatabase":
+ createDatabaseWithPropertyGraph(
+ dbAdminClient,
+ InstanceName.of(
+ database.getInstanceId().getProject(), database.getInstanceId().getInstance()),
+ database.getDatabase());
+ break;
+ case "insert":
+ insertData(dbClient);
+ break;
+ case "insertusingdml":
+ insertUsingDml(dbClient);
+ break;
+ case "updateusingdml":
+ updateUsingDml(dbClient);
+ break;
+ case "updateusinggraphqueryindml":
+ updateUsingGraphQueryInDml(dbClient);
+ break;
+ case "query":
+ query(dbClient);
+ break;
+ case "querywithparameter":
+ queryWithParameter(dbClient);
+ break;
+ case "deleteusingdml":
+ deleteUsingDml(dbClient);
+ break;
+ case "delete":
+ deleteData(dbClient);
+ break;
+ default:
+ printUsageAndExit();
+ }
+ }
+
+ static void printUsageAndExit() {
+ System.err.println("Usage:");
+ System.err.println(" SpannerGraphExample ");
+ System.err.println("");
+ System.err.println("Examples:");
+ System.err.println(" SpannerGraphExample createdatabase my-instance example-db");
+ System.err.println(" SpannerGraphExample insert my-instance example-db");
+ System.err.println(" SpannerGraphExample insertusingdml my-instance example-db");
+ System.err.println(" SpannerGraphExample updateusingdml my-instance example-db");
+ System.err.println(" SpannerGraphExample updateusinggraphqueryindml my-instance example-db");
+ System.err.println(" SpannerGraphExample query my-instance example-db");
+ System.err.println(" SpannerGraphExample querywithparameter my-instance example-db");
+ System.err.println(" SpannerGraphExample deleteusingdml my-instance example-db");
+ System.err.println(" SpannerGraphExample delete my-instance example-db");
+ System.exit(1);
+ }
+
+ public static void main(String[] args) {
+ if (args.length != 3 && args.length != 4) {
+ printUsageAndExit();
+ }
+ SpannerOptions options = SpannerOptions.newBuilder().build();
+ Spanner spanner = options.getService();
+ DatabaseAdminClient dbAdminClient = null;
+ try {
+ final String command = args[0];
+ DatabaseId db = DatabaseId.of(options.getProjectId(), args[1], args[2]);
+ // This will return the default project id based on the environment.
+ String clientProject = spanner.getOptions().getProjectId();
+ if (!db.getInstanceId().getProject().equals(clientProject)) {
+ System.err.println(
+ "Invalid project specified. Project in the database id should match the"
+ + "project name set in the environment variable GOOGLE_CLOUD_PROJECT. Expected: "
+ + clientProject);
+ printUsageAndExit();
+ }
+
+ DatabaseClient dbClient = spanner.getDatabaseClient(db);
+ dbAdminClient = spanner.createDatabaseAdminClient();
+
+ run(dbClient, dbAdminClient, command, db);
+ } finally {
+ if (dbAdminClient != null) {
+ if (!dbAdminClient.isShutdown() || !dbAdminClient.isTerminated()) {
+ dbAdminClient.close();
+ }
+ }
+ spanner.close();
+ }
+ System.out.println("Closed client");
+ }
+}
diff --git a/samples/snippets/src/test/java/com/example/spanner/SpannerGraphSampleIT.java b/samples/snippets/src/test/java/com/example/spanner/SpannerGraphSampleIT.java
new file mode 100644
index 00000000000..6f778de49ab
--- /dev/null
+++ b/samples/snippets/src/test/java/com/example/spanner/SpannerGraphSampleIT.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2024 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;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.cloud.spanner.DatabaseId;
+import com.google.cloud.spanner.Spanner;
+import com.google.cloud.spanner.admin.database.v1.DatabaseAdminClient;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@code SpannerGraphSample} */
+@RunWith(JUnit4.class)
+@SuppressWarnings("checkstyle:abbreviationaswordinname")
+public class SpannerGraphSampleIT extends SampleTestBaseV2 {
+
+ private static final int DBID_LENGTH = 20;
+ // The instance needs to exist for tests to pass.
+ private static final String instanceId = System.getProperty("spanner.test.instance");
+ private static final String baseDbId = System.getProperty("spanner.sample.database");
+ static Spanner spanner;
+ static DatabaseAdminClient databaseAdminClient;
+
+ private String runSample(String command, String databaseId) throws Exception {
+ System.out.println("Running " + command + " on " + instanceId + ":" + databaseId);
+ PrintStream stdOut = System.out;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ PrintStream out = new PrintStream(bout);
+ System.setOut(out);
+ SpannerGraphSample.main(new String[] {command, instanceId, databaseId});
+ System.setOut(stdOut);
+ return bout.toString();
+ }
+
+ @Test
+ public void testSample() throws Exception {
+ String databaseId = idGenerator.generateDatabaseId();
+ assertThat(instanceId).isNotNull();
+ assertThat(databaseId).isNotNull();
+
+ System.out.println("Create database with property graph ...");
+ String out = runSample("createdatabase", databaseId);
+
+ DatabaseId dbId = DatabaseId.of(projectId, instanceId, databaseId);
+ assertThat(out).contains("Created database");
+ assertThat(out).contains(dbId.getName());
+
+ System.out.println("Insert some data ...");
+ out = runSample("insert", databaseId);
+
+ System.out.println("Insert more data using DML ...");
+ out = runSample("insertusingdml", databaseId);
+ assertThat(out).contains("2 record(s) inserted into Account.");
+ assertThat(out).contains("2 record(s) inserted into AccountTransferAccount.");
+
+ System.out.println("Update some data using DML ...");
+ out = runSample("updateusingdml", databaseId);
+ assertThat(out).contains("1 Account record(s) updated.");
+ assertThat(out).contains("1 AccountTransferAccount record(s) updated.");
+
+ System.out.println("Update some data using a graph query in DML ...");
+ out = runSample("updateusinggraphqueryindml", databaseId);
+ assertThat(out).contains("2 Account record(s) updated.");
+
+ System.out.println("Query the property graph ...");
+ out = runSample("query", databaseId);
+ assertThat(out).contains("Dana Alex 500.0");
+ assertThat(out).contains("Lee Dana 300.0");
+ assertThat(out).contains("Alex Lee 300.0");
+ assertThat(out).contains("Alex Lee 100.0");
+ assertThat(out).contains("Dana Lee 200.0");
+
+ System.out.println("Query the property graph with a parameter ...");
+ out = runSample("querywithparameter", databaseId);
+ assertThat(out).contains("Dana Alex 500.0");
+
+ System.out.println("Delete some data using DML ...");
+ out = runSample("deleteusingdml", databaseId);
+ assertThat(out).contains("1 Account record(s) deleted.");
+
+ System.out.println("Delete the remaining data in the database ...");
+ out = runSample("delete", databaseId);
+ assertThat(out).contains("Records deleted.");
+
+ System.out.println("Query the property graph ...");
+ out = runSample("query", databaseId);
+ assertThat(out).doesNotContain("Dana");
+ assertThat(out).doesNotContain("Alex");
+ assertThat(out).doesNotContain("Lee");
+ }
+}