{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/comments/128861385","pull_request_review_id":51585807,"id":128861385,"diff_hunk":"@@ -0,0 +1,989 @@\n+﻿/*\r\n+ * Copyright (c) 2017 Google Inc.\r\n+ *\r\n+ * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\r\n+ * use this file except in compliance with the License. You may obtain a copy of\r\n+ * the License at\r\n+ *\r\n+ * http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\r\n+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r\n+ * License for the specific language governing permissions and limitations under\r\n+ * the License.\r\n+ */\r\n+\r\n+using System;\r\n+using System.Threading.Tasks;\r\n+using Google.Cloud.Spanner.Data;\r\n+using CommandLine;\r\n+using System.Transactions;\r\n+using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;\r\n+\r\n+namespace GoogleCloudSamples.Spanner\r\n+{\r\n+    [Verb(\"createDatabase\", HelpText = \"Create a Cloud Spanner database in your project.\")]\r\n+    class CreateDatabaseOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when creating Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the database will be created.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database to create.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"createSampleDatabase\", HelpText = \"Create a sample Cloud Spanner database along with sample tables in your project.\")]\r\n+    class CreateSampleDatabaseOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when creating Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample database will be created.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the sample database to create.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"createTable\", HelpText = \"Create a table in your project's Cloud Spanner database.\")]\r\n+    class CreateTableOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when creating Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the table will be created.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the table will be created.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+        [Value(3, HelpText = \"The name of the table to create.\", Required = true)]\r\n+        public string tableName { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"insertSampleData\", HelpText = \"Insert sample data into sample Cloud Spanner database table.\")]\r\n+    class InsertSampleDataOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample data will be inserted.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample data will be inserted.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"querySampleData\", HelpText = \"Query sample data from sample Cloud Spanner database table.\")]\r\n+    class QuerySampleDataOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample data resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample data resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"addIndex\", HelpText = \"Add an index to the sample Cloud Spanner database table.\")]\r\n+    class AddIndexOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample data resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample data resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"addStoringIndex\", HelpText = \"Add a storing index to the sample Cloud Spanner database table.\")]\r\n+    class AddStoringIndexOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample data resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample data resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"queryDataWithIndex\", HelpText = \"Query the sample Cloud Spanner database table using an index.\")]\r\n+    class QueryDataWithIndexOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample data resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample data resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+        [Value(3, HelpText = \"The start of the title index.\", Required = false)]\r\n+        public string startTitle { get; set; }\r\n+        [Value(4, HelpText = \"The end of the title index.\", Required = false)]\r\n+        public string endTitle { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"queryDataWithStoringIndex\", HelpText = \"Query the sample Cloud Spanner database table using an storing index.\")]\r\n+    class QueryDataWithStoringIndexOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample data resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample data resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+        [Value(3, HelpText = \"The start of the title index.\", Required = false)]\r\n+        public string startTitle { get; set; }\r\n+        [Value(4, HelpText = \"The end of the title index.\", Required = false)]\r\n+        public string endTitle { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"addColumn\", HelpText = \"Add a column to the sample Cloud Spanner database table.\")]\r\n+    class AddColumnOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample database resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample database resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"writeDataToNewColumn\", HelpText = \"Write data to a newly added column in the sample Cloud Spanner database table.\")]\r\n+    class WriteDataToNewColumnOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample database resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample database resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"queryNewColumn\", HelpText = \"Query data from a newly added column in the sample Cloud Spanner database table.\")]\r\n+    class QueryNewColumnOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample database resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample database resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"queryDataWithTransaction\", HelpText = \"Query the sample Cloud Spanner database table using a transaction.\")]\r\n+    class QueryDataWithTransactionOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample database resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample database resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    [Verb(\"readWriteWithTransaction\", HelpText = \"Update data in the sample Cloud Spanner database table using a read-write transaction.\")]\r\n+    class ReadWriteWithTransactionOptions\r\n+    {\r\n+        [Value(0, HelpText = \"The project ID of the project to use when managing Cloud Spanner resources.\", Required = true)]\r\n+        public string projectId { get; set; }\r\n+        [Value(1, HelpText = \"The ID of the instance where the sample database resides.\", Required = true)]\r\n+        public string instanceId { get; set; }\r\n+        [Value(2, HelpText = \"The ID of the database where the sample database resides.\", Required = true)]\r\n+        public string databaseId { get; set; }\r\n+    }\r\n+\r\n+    public class Program\r\n+    {\r\n+        public static async Task CreateSampleDatabaseAsync(\r\n+            string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START create_database]\r\n+            // Initialize request connection string for database creation.\r\n+            string connectionString =\r\n+                $\"Data Source=projects/{projectId}/instances/{instanceId}\";\r\n+            // Make the request.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                string createStatement = $\"CREATE DATABASE `{databaseId}`\";\r\n+                var cmd = connection.CreateDdlCommand(createStatement);\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+            }\r\n+            // Update connection string with Database ID for table creation.\r\n+            connectionString = connectionString + $\"/databases/{databaseId}\";\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                // Define create table statement for table #1.\r\n+                string createTableStatement =\r\n+               @\"CREATE TABLE Singers (\r\n+                     SingerId INT64 NOT NULL,\r\n+                     FirstName    STRING(1024),\r\n+                     LastName STRING(1024),\r\n+                     ComposerInfo   BYTES(MAX)\r\n+                 ) PRIMARY KEY (SingerId)\";\r\n+                // Make the request.\r\n+                var cmd = connection.CreateDdlCommand(createTableStatement);\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                // Define create table statement for table #2.\r\n+                createTableStatement =\r\n+                @\"CREATE TABLE Albums (\r\n+                     SingerId     INT64 NOT NULL,\r\n+                     AlbumId      INT64 NOT NULL,\r\n+                     AlbumTitle   STRING(MAX)\r\n+                 ) PRIMARY KEY (SingerId, AlbumId),\r\n+                 INTERLEAVE IN PARENT Singers ON DELETE CASCADE\";\r\n+                // Make the request.\r\n+                cmd = connection.CreateDdlCommand(createTableStatement);\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+            }\r\n+            return;\r\n+            // [END create_database]\r\n+        }\r\n+\r\n+        public static async Task AddIndexAsync(\r\n+            string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START create_index]\r\n+            // Initialize request argument(s).\r\n+            string connectionString =\r\n+                $\"Data Source=projects/{projectId}/instances/\"\r\n+                + $\"{instanceId}/databases/{databaseId}\";\r\n+            string createStatement =\r\n+                $\"CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)\";\r\n+            // Make the request.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                var createCmd = connection.CreateDdlCommand(createStatement);\r\n+                await createCmd.ExecuteNonQueryAsync();\r\n+            }\r\n+            Console.WriteLine(\"Added the AlbumsByAlbumTitle index.\");\r\n+            return;\r\n+            // [END create_index]\r\n+        }\r\n+\r\n+        public static async Task AddStoringIndexAsync(\r\n+    string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START create_storing_index]\r\n+            // Initialize request argument(s).\r\n+            string connectionString =\r\n+                $\"Data Source=projects/{projectId}/instances/\"\r\n+                + $\"{instanceId}/databases/{databaseId}\";\r\n+            string createStatement =\r\n+                $\"CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) \"\r\n+                + \"STORING (MarketingBudget)\";\r\n+            // Make the request.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                var createCmd = connection.CreateDdlCommand(createStatement);\r\n+                await createCmd.ExecuteNonQueryAsync();\r\n+            }\r\n+            return;\r\n+            // [END create_storing_index]\r\n+        }\r\n+\r\n+        public static async Task AddColumnAsync(\r\n+    string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START add_column]\r\n+            // Initialize request argument(s).\r\n+            string connectionString =\r\n+                $\"Data Source=projects/{projectId}/instances/\"\r\n+                + $\"{instanceId}/databases/{databaseId}\";\r\n+            string createStatement =\r\n+                $\"ALTER TABLE Albums ADD COLUMN MarketingBudget INT64\";\r\n+            // Make the request.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                var createCmd = connection.CreateDdlCommand(createStatement);\r\n+                await createCmd.ExecuteNonQueryAsync();\r\n+            }\r\n+            Console.WriteLine(\"Added the MarketingBudget column.\");\r\n+            return;\r\n+            // [END add_column]\r\n+        }\r\n+\r\n+        public static async Task QuerySampleDataAsync(\r\n+            string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START query_data]\r\n+            string connectionString =\r\n+            $\"Data Source=projects/{projectId}/instances/\"\r\n+            + $\"{instanceId}/databases/{databaseId}\";\r\n+            // Create connection to Cloud Spanner.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                var cmd = connection.CreateSelectCommand(\r\n+                    \"SELECT SingerId, AlbumId, AlbumTitle FROM Albums\");\r\n+                using (var reader = await cmd.ExecuteReaderAsync())\r\n+                {\r\n+                    while (await reader.ReadAsync())\r\n+                    {\r\n+                        Console.WriteLine($\"SingerId : {reader[\"SingerId\"]} \"\r\n+                        + $\"AlbumId : {reader[\"AlbumId\"]} \"\r\n+                        + $\"AlbumTitle : {reader[\"AlbumTitle\"]}\");\r\n+                    }\r\n+                }\r\n+            }\r\n+            return;\r\n+            // [END query_data]\r\n+        }\r\n+\r\n+\r\n+        public static async Task QueryDataWithIndexAsync(\r\n+            string projectId, string instanceId, string databaseId,\r\n+            string startTitle = \"Aardvark\", string endTitle = \"Goo\")\r\n+        {\r\n+            Console.WriteLine(\"Running QueryDataWithIndex...\");\r\n+            // [START query_data_with_index]\r\n+            // [START read_data_with_index]\r\n+            string connectionString =\r\n+            $\"Data Source=projects/{projectId}/instances/{instanceId}\"\r\n+            + $\"/databases/{databaseId}\";\r\n+            // Create connection to Cloud Spanner.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                var cmd = connection.CreateSelectCommand(\r\n+                    \"SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums@ \"\r\n+                    + \"{FORCE_INDEX=AlbumsByAlbumTitle} \"\r\n+                    + $\"WHERE AlbumTitle >= '{startTitle}' \"\r\n+                    + $\"AND AlbumTitle < '{endTitle}'\");\r\n+                using (var reader = await cmd.ExecuteReaderAsync())\r\n+                {\r\n+                    while (await reader.ReadAsync())\r\n+                    {\r\n+                        Console.WriteLine($\"AlbumId : {reader[\"AlbumId\"]} \"\r\n+                        + $\"AlbumTitle : {reader[\"AlbumTitle\"]} \"\r\n+                        + $\"MarketingBudget : {reader[\"MarketingBudget\"]}\");\r\n+                    }\r\n+                }\r\n+            }\r\n+            return;\r\n+            // [END read_data_with_index]\r\n+            // [END query_data_with_index]\r\n+        }\r\n+\r\n+        public static async Task QueryDataWithStoringIndexAsync(\r\n+            string projectId, string instanceId, string databaseId,\r\n+            string startTitle = \"Aardvark\", string endTitle = \"Goo\")\r\n+        {\r\n+            // [START read_data_with_storing_index]\r\n+            string connectionString =\r\n+            $\"Data Source=projects/{projectId}/instances/{instanceId}\"\r\n+            + $\"/databases/{databaseId}\";\r\n+            // Create connection to Cloud Spanner.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                var cmd = connection.CreateSelectCommand(\r\n+                    \"SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums@ \"\r\n+                    + \"{FORCE_INDEX=AlbumsByAlbumTitle2} \"\r\n+                    + $\"WHERE AlbumTitle >= '{startTitle}' \"\r\n+                    + $\"AND AlbumTitle < '{endTitle}'\");\r\n+                using (var reader = await cmd.ExecuteReaderAsync())\r\n+                {\r\n+                    while (await reader.ReadAsync())\r\n+                    {\r\n+                        Console.WriteLine($\"AlbumId : {reader[\"AlbumId\"]} \"\r\n+                        + $\"AlbumTitle : {reader[\"AlbumTitle\"]} \"\r\n+                        + $\"MarketingBudget : {reader[\"MarketingBudget\"]}\");\r\n+                    }\r\n+                }\r\n+            }\r\n+            return;\r\n+            // [END read_data_with_storing_index]\r\n+        }\r\n+\r\n+        public static async Task QueryDataWithTransactionAsync(\r\n+    string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START read_only_transaction]\r\n+            string connectionString =\r\n+            $\"Data Source=projects/{projectId}/instances/{instanceId}\"\r\n+            + $\"/databases/{databaseId}\";\r\n+            // Gets a transaction object that captures the database state\r\n+            // at a specific point in time.\r\n+            using (TransactionScope scope = new TransactionScope(\r\n+                TransactionScopeAsyncFlowOption.Enabled))\r\n+            {\r\n+                // Create connection to Cloud Spanner.\r\n+                var connection = new SpannerConnection(\r\n+                    connectionString);\r\n+                // Open connection as read only within the scope \r\n+                // of the current transaction.\r\n+                connection.OpenAsReadOnly();\r\n+                using (connection)\r\n+                {\r\n+                    var cmd = connection.CreateSelectCommand(\r\n+                        \"SELECT SingerId, AlbumId, AlbumTitle FROM Albums\");\r\n+                    // Read #1.\r\n+                    using (var reader = await cmd.ExecuteReaderAsync())\r\n+                    {\r\n+                        while (await reader.ReadAsync())\r\n+                        {\r\n+                            Console.WriteLine(\r\n+                                $\"SingerId : {reader[\"SingerId\"]}\"\r\n+                                + $\" AlbumId : {reader[\"AlbumId\"]}\"\r\n+                                + $\" AlbumTitle : {reader[\"AlbumTitle\"]}\");\r\n+                        }\r\n+                    }\r\n+                    // Read #2. Even if changes occur in-between the reads, \r\n+                    // the transaction ensures that Read #1 and Read #2 \r\n+                    // return the same data.\r\n+                    using (var reader = await cmd.ExecuteReaderAsync())\r\n+                    {\r\n+                        while (await reader.ReadAsync())\r\n+                        {\r\n+                            Console.WriteLine(\r\n+                                $\"SingerId : {reader[\"SingerId\"]}\"\r\n+                                + $\" AlbumId : {reader[\"AlbumId\"]}\"\r\n+                                + $\" AlbumTitle : {reader[\"AlbumTitle\"]}\");\r\n+                        }\r\n+                    }\r\n+                }\r\n+                //scope.Complete();\r\n+                return;\r\n+                // [END read_only_transaction]\r\n+                // TODO - Unncomment the above line containing scope.Complete().\r\n+                // A pending client library update will enable this.\r\n+            }\r\n+        }\r\n+\r\n+        public static async Task WriteDataToNewColumnAsync(\r\n+    string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START update_data]\r\n+            string connectionString =\r\n+            $\"Data Source=projects/{projectId}/instances/{instanceId}\"\r\n+            + $\"/databases/{databaseId}\";\r\n+            // Create connection to Cloud Spanner.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                var cmd = connection.CreateUpdateCommand(\"Albums\",\r\n+                    new SpannerParameterCollection {\r\n+                        {\"SingerId\", SpannerDbType.Int64},\r\n+                        {\"AlbumId\", SpannerDbType.Int64},\r\n+                        {\"MarketingBudget\", SpannerDbType.Int64},\r\n+                    });\r\n+                var cmdLookup =\r\n+                    connection.CreateSelectCommand(\"SELECT * FROM Albums\");\r\n+                using (var reader = await cmdLookup.ExecuteReaderAsync())\r\n+                {\r\n+                    while (await reader.ReadAsync())\r\n+                    {\r\n+                        if (reader.GetInt64(0) == 1 && reader.GetInt64(1) == 1)\r\n+                        {\r\n+                            cmd.Parameters[\"SingerId\"].Value =\r\n+                                reader.GetInt64(0);\r\n+                            cmd.Parameters[\"AlbumId\"].Value =\r\n+                                reader.GetInt64(1);\r\n+                            cmd.Parameters[\"MarketingBudget\"].Value = 100000;\r\n+                            await cmd.ExecuteNonQueryAsync();\r\n+                        }\r\n+                        if (reader.GetInt64(0) == 2 && reader.GetInt64(1) == 2)\r\n+                        {\r\n+                            cmd.Parameters[\"SingerId\"].Value =\r\n+                                reader.GetInt64(0);\r\n+                            cmd.Parameters[\"AlbumId\"].Value =\r\n+                                reader.GetInt64(1);\r\n+                            cmd.Parameters[\"MarketingBudget\"].Value = 500000;\r\n+                            await cmd.ExecuteNonQueryAsync();\r\n+                        }\r\n+                    }\r\n+                }\r\n+            }\r\n+            Console.WriteLine(\"Updated data.\");\r\n+            return;\r\n+            // [END update_data]\r\n+        }\r\n+\r\n+        public static async Task QueryNewColumnAsync(\r\n+            string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START query_data_with_new_column]\r\n+            string connectionString =\r\n+            $\"Data Source=projects/{projectId}/instances/{instanceId}\"\r\n+            + $\"/databases/{databaseId}\";\r\n+            // Create connection to Cloud Spanner.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                var cmd =\r\n+                    connection.CreateSelectCommand(\"SELECT * FROM Albums\");\r\n+                using (var reader = await cmd.ExecuteReaderAsync())\r\n+                {\r\n+                    while (await reader.ReadAsync())\r\n+                    {\r\n+                        Console.WriteLine($\"SingerId : {reader[\"SingerId\"]} \"\r\n+                        + $\"AlbumId : {reader[\"AlbumId\"]} \"\r\n+                        + $\"MarketingBudget : {reader[\"MarketingBudget\"]}\");\r\n+                    }\r\n+                }\r\n+            }\r\n+            return;\r\n+            // [END query_data_with_new_column]\r\n+        }\r\n+\r\n+        internal class CustomTransientErrorDetectionStrategy\r\n+            : ITransientErrorDetectionStrategy\r\n+        {\r\n+            public bool IsTransient(Exception ex)\r\n+            {\r\n+                if (ex.IsTransientSpannerFault())\r\n+                    return true;\r\n+                return false;\r\n+            }\r\n+        }\r\n+\r\n+        public static async Task ReadWriteWithTransactionAsync(\r\n+            string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START read_write_transaction]\r\n+            // This sample transfers 200,000 from the MarketingBudget \r\n+            // field of the second Album to the first Album. Make sure to run\r\n+            // the addColumn and writeDataToNewColumn samples first,\r\n+            // in that order.\r\n+\r\n+            string connectionString =\r\n+            $\"Data Source=projects/{projectId}/instances/{instanceId}\"\r\n+            + $\"/databases/{databaseId}\";\r\n+\r\n+            using (TransactionScope scope = new TransactionScope(\r\n+                TransactionScopeAsyncFlowOption.Enabled))\r\n+            {\r\n+                decimal transferAmount = 200000;\r\n+                decimal minimumAmountToTransfer = 300000;\r\n+                decimal secondBudget = 0;\r\n+                decimal firstBudget = 0;\r\n+\r\n+                // Create connection to Cloud Spanner.\r\n+                using (var connection =\r\n+                    new SpannerConnection(connectionString))\r\n+                {\r\n+                    // Create statement to select the second album's data.\r\n+                    var cmdLookup = connection.CreateSelectCommand(\r\n+                    \"SELECT * FROM Albums WHERE SingerId = 2 AND AlbumId = 2\");\r\n+                    // Excecute the select query.\r\n+                    using (var reader = await cmdLookup.ExecuteReaderAsync())\r\n+                    {\r\n+                        while (await reader.ReadAsync())\r\n+                        {\r\n+                            // Read the second album's budget.\r\n+                            secondBudget =\r\n+                                decimal.Parse(reader[\"MarketingBudget\"]\r\n+                                    .ToString());\r\n+                            // Confirm second Album has > 300,000 and if not\r\n+                            // raise an exception. Raising an exception will \r\n+                            // automatically roll back the transaction.\r\n+                            if (secondBudget < minimumAmountToTransfer)\r\n+                            {\r\n+                                throw new Exception(\"The second album's \"\r\n+                                    + $\"budget {secondBudget} \"\r\n+                                    + \"is less than the minimum required \"\r\n+                                    + \"amount to transfer.\");\r\n+                            }\r\n+                        }\r\n+                    }\r\n+                    // Read the first album's budget.\r\n+                    cmdLookup = connection.CreateSelectCommand(\r\n+                    \"SELECT * FROM Albums WHERE SingerId = 1 and AlbumId = 1\");\r\n+                    using (var reader = await cmdLookup.ExecuteReaderAsync())\r\n+                    {\r\n+                        while (await reader.ReadAsync())\r\n+                        {\r\n+                            firstBudget =\r\n+                                decimal.Parse(reader[\"MarketingBudget\"]\r\n+                                    .ToString());\r\n+                        }\r\n+                    }\r\n+\r\n+                    // Specify update command parameters.\r\n+                    var cmd = connection.CreateUpdateCommand(\"Albums\",\r\n+                        new SpannerParameterCollection {\r\n+                        {\"SingerId\", SpannerDbType.Int64},\r\n+                        {\"AlbumId\", SpannerDbType.Int64},\r\n+                        {\"MarketingBudget\", SpannerDbType.Int64},\r\n+                    });\r\n+                    // Update second album to remove the transfer amount.\r\n+                    secondBudget = secondBudget - transferAmount;\r\n+                    cmd.Parameters[\"SingerId\"].Value = 2;\r\n+                    cmd.Parameters[\"AlbumId\"].Value = 2;\r\n+                    cmd.Parameters[\"MarketingBudget\"].Value = secondBudget;\r\n+                    await cmd.ExecuteNonQueryAsync();\r\n+                    // Update first album to add the transfer amount.\r\n+                    firstBudget = firstBudget + transferAmount;\r\n+                    cmd.Parameters[\"SingerId\"].Value = 1;\r\n+                    cmd.Parameters[\"AlbumId\"].Value = 1;\r\n+                    cmd.Parameters[\"MarketingBudget\"].Value = firstBudget;\r\n+                    await cmd.ExecuteNonQueryAsync();\r\n+                    scope.Complete();\r\n+                    // Yield Task thread back to the current context.\r\n+                    await Task.Yield();\r\n+                    Console.WriteLine(\"Transaction complete.\");\r\n+                    return;\r\n+                    // [END read_write_transaction]\r\n+                    // TODO - Remove the above Task.Yield() statement. \r\n+                    // A pending client library update will not require this\r\n+                    // for transactions.\r\n+                }\r\n+            }\r\n+        }\r\n+\r\n+        public static async Task InsertSampleDataAsync(\r\n+            string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START insert_data]\r\n+            string connectionString =\r\n+            $\"Data Source=projects/{projectId}/instances/{instanceId}\"\r\n+            + $\"/databases/{databaseId}\";\r\n+            // Create connection to Cloud Spanner.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                // Insert rows into the Singers table.\r\n+                var cmd = connection.CreateInsertCommand(\"Singers\",\r\n+                    new SpannerParameterCollection {\r\n+                        {\"SingerId\", SpannerDbType.Int64},\r\n+                        {\"FirstName\", SpannerDbType.String},\r\n+                        {\"LastName\", SpannerDbType.String}\r\n+                    });\r\n+                // Insert first row\r\n+                cmd.Parameters[\"SingerId\"].Value = 1;\r\n+                cmd.Parameters[\"FirstName\"].Value = \"Summerian\";\r\n+                cmd.Parameters[\"LastName\"].Value = \" Chanter\";\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                // Insert second row\r\n+                cmd.Parameters[\"SingerId\"].Value = 2;\r\n+                cmd.Parameters[\"FirstName\"].Value = \"African\";\r\n+                cmd.Parameters[\"LastName\"].Value = \"Artist\";\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                // Insert third row\r\n+                cmd.Parameters[\"SingerId\"].Value = 3;\r\n+                cmd.Parameters[\"FirstName\"].Value = \"Indigenous\";\r\n+                cmd.Parameters[\"LastName\"].Value = \"Star\";\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                // Insert rows into the Albums table.\r\n+                cmd = connection.CreateInsertCommand(\"Albums\",\r\n+                    new SpannerParameterCollection {\r\n+                        {\"SingerId\", SpannerDbType.Int64},\r\n+                        {\"AlbumId\", SpannerDbType.Int64},\r\n+                        {\"AlbumTitle\", SpannerDbType.String}\r\n+                    });\r\n+                // Insert first row.\r\n+                cmd.Parameters[\"SingerId\"].Value = 1;\r\n+                cmd.Parameters[\"AlbumId\"].Value = 1;\r\n+                cmd.Parameters[\"AlbumTitle\"].Value = \"Good Hurrian Songs\";\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                // Insert second row.\r\n+                cmd.Parameters[\"SingerId\"].Value = 1;\r\n+                cmd.Parameters[\"AlbumId\"].Value = 2;\r\n+                cmd.Parameters[\"AlbumTitle\"].Value = \"Cuneiform Chorus\";\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                // Insert third row.\r\n+                cmd.Parameters[\"SingerId\"].Value = 2;\r\n+                cmd.Parameters[\"AlbumId\"].Value = 1;\r\n+                cmd.Parameters[\"AlbumTitle\"].Value = \"Zany Mbira Music\";\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                // Insert fourth row.\r\n+                cmd.Parameters[\"SingerId\"].Value = 2;\r\n+                cmd.Parameters[\"AlbumId\"].Value = 2;\r\n+                cmd.Parameters[\"AlbumTitle\"].Value = \"Ambient Sistrum Sirens\";\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                // Insert fifth row.\r\n+                cmd.Parameters[\"SingerId\"].Value = 2;\r\n+                cmd.Parameters[\"AlbumId\"].Value = 3;\r\n+                cmd.Parameters[\"AlbumTitle\"].Value = \"Congo Carols\";\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+                Console.WriteLine(\"Inserted data.\");\r\n+                return;\r\n+            }\r\n+            // [END insert_data]\r\n+        }\r\n+\r\n+        public static async Task CreateDatabaseAsync(\r\n+            string projectId, string instanceId, string databaseId)\r\n+        {\r\n+            // [START create_custom_database]\r\n+            // Initialize request connection string for database creation.\r\n+            string connectionString =\r\n+                $\"Data Source=projects/{projectId}/instances/{instanceId}\";\r\n+            // Make the request.\r\n+            using (var connection = new SpannerConnection(connectionString))\r\n+            {\r\n+                string createStatement = $\"CREATE DATABASE `{databaseId}`\";\r\n+                var cmd = connection.CreateDdlCommand(createStatement);\r\n+                await cmd.ExecuteNonQueryAsync();\r\n+            }\r\n+            return;\r\n+            // [END create_custom_database]\r\n+        }\r\n+\r\n+        public static object CreateSampleDatabase(string projectId,\r\n+    string instanceId, string databaseId)\r\n+        {\r\n+            var response = Task.Run(async () =>\r\n+                await CreateSampleDatabaseAsync(\r\n+                    projectId, instanceId, databaseId));\r\n+            Console.WriteLine(\"Waiting for operation to complete...\");\r\n+            Task.WaitAll(response);\r\n+            Console.WriteLine($\"Operation status: {response.Status}\");\r\n+            Console.WriteLine($\"Created sample database {databaseId} on \"\r\n+                + $\"instance {instanceId}\");\r\n+            return 0;\r\n+        }\r\n+\r\n+        public static object InsertSampleData(string projectId,\r\n+string instanceId, string databaseId)\r\n+        {\r\n+            var response = Task.Run(async () => await InsertSampleDataAsync(\r\n+                projectId, instanceId, databaseId));\r\n+            Console.WriteLine(\"Waiting for operation to complete...\");\r\n+            Task.WaitAll(response);\r\n+            Console.WriteLine($\"Operation status: {response.Status}\");\r\n+            return 0;\r\n+        }\r\n+\r\n+        public static object QuerySampleData(string projectId,\r\n+string instanceId, string databaseId)\r\n+        {\r\n+            var response = Task.Run(async () => await QuerySampleDataAsync(\r\n+                projectId, instanceId, databaseId));\r\n+            Console.WriteLine(\"Waiting for operation to complete...\");\r\n+            Task.WaitAll(response);\r\n+            Console.WriteLine($\"Operation status: {response.Status}\");\r\n+            return 0;\r\n+        }\r\n+\r\n+        public static object QueryDataWithIndex(string projectId,\r\n+            string instanceId, string databaseId,\r\n+            string startTitle, string endTitle)\r\n+        {\r\n+            var response = new Task(() => { });\r\n+            // Call method QueryDataWithIndexAsync() based on whether \r\n+            // user provided startTitle and endTitle values are empty or null.\r\n+            if (string.IsNullOrEmpty(startTitle))\r\n+            {\r\n+                // startTitle not provided, exclude startTitle and endTitle from \r\n+                // method call to use default values for both.\r\n+                response = Task.Run(async () => await QueryDataWithIndexAsync(\r\n+                        projectId, instanceId, databaseId));\r\n+            }\r\n+            else if (!string.IsNullOrEmpty(startTitle)\r\n+                && string.IsNullOrEmpty(endTitle))\r\n+            {\r\n+                // Only startTitle provided, show message that user must \r\n+                // provide both startTitle and endTitle or exclude them \r\n+                // from their command.\r\n+                Console.WriteLine(\"Please provide values for both the start \"\r\n+                    + \"of the title index and the end of the title index.\");\r\n+                Console.WriteLine(\"Or you can exclude both to run the \"\r\n+                    + \"query with default values.\");\r\n+                return 0;\r\n+            }\r\n+            else if (!string.IsNullOrEmpty(startTitle)\r\n+                && !string.IsNullOrEmpty(endTitle))\r\n+            {\r\n+                // Both startTitle and endTitle provided, include them both in\r\n+                // the method call to QueryDataWithIndexAsync.\r\n+                response = Task.Run(async () => await QueryDataWithIndexAsync(\r\n+                        projectId, instanceId, databaseId,\r\n+                        startTitle, endTitle));\r\n+            }\r\n+            Console.WriteLine(\"Waiting for operation to complete...\");\r\n+            Task.WaitAll(response);\r\n+            Console.WriteLine($\"Operation status: {response.Status}\");\r\n+            return 0;\r\n+        }\r\n+\r\n+        public static object CreateDatabase(string projectId,\r\n+            string instanceId, string databaseId)\r\n+        {\r\n+            var response = Task.Run(async () => await CreateDatabaseAsync(\r\n+                projectId, instanceId, databaseId));\r\n+            Console.WriteLine(\"Waiting for operation to complete...\");\r\n+            Task.WaitAll(response);\r\n+            Console.WriteLine($\"Response status: {response.Status}\");\r\n+            Console.WriteLine($\"Created database {databaseId} on instance \"\r\n+                + $\"{instanceId}\");\r\n+            return 0;\r\n+        }\r\n+\r\n+        public static object AddIndex(string projectId,\r\n+    string instanceId, string databaseId)\r\n+        {\r\n+            var response = Task.Run(async () =>\r\n+            await AddIndexAsync(\r\n+                projectId, instanceId, databaseId));\r\n+            Console.WriteLine(\"Waiting for operation to complete...\");\r\n+            Task.WaitAll(response);\r\n+            Console.WriteLine($\"Response status: {response.Status}\");\r\n+            return 0;\r\n+        }\r\n+        public static object AddStoringIndex(string projectId,\r\n+string instanceId, string databaseId)\r\n+        {\r\n+            var response = Task.Run(async () =>\r\n+            await AddStoringIndexAsync(\r\n+                projectId, instanceId, databaseId));\r\n+            Console.WriteLine(\"Waiting for operation to complete...\");\r\n+            Task.WaitAll(response);\r\n+            Console.WriteLine($\"Response status: {response.Status}\");\r\n+            return 0;\r\n+        }\r\n+\r\n+        public static object QueryDataWithStoringIndex(string projectId,\r\n+            string instanceId, string databaseId, string startTitle, string endTitle)\r\n+        {\r\n+            var response = new Task(() => { });\r","path":"spanner/api/Program.cs","position":846,"original_position":828,"commit_id":"018936fc0491b01ccbace6b83c46fd7a94b3ce65","original_commit_id":"ef3734df842bb1d704d410f97bacf5bf61563133","user":{"login":"jsimonweb","id":2709164,"avatar_url":"https://avatars1.githubusercontent.com/u/2709164?v=4","gravatar_id":"","url":"https://api.github.com/users/jsimonweb","html_url":"https://github.com/jsimonweb","followers_url":"https://api.github.com/users/jsimonweb/followers","following_url":"https://api.github.com/users/jsimonweb/following{/other_user}","gists_url":"https://api.github.com/users/jsimonweb/gists{/gist_id}","starred_url":"https://api.github.com/users/jsimonweb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsimonweb/subscriptions","organizations_url":"https://api.github.com/users/jsimonweb/orgs","repos_url":"https://api.github.com/users/jsimonweb/repos","events_url":"https://api.github.com/users/jsimonweb/events{/privacy}","received_events_url":"https://api.github.com/users/jsimonweb/received_events","type":"User","site_admin":false},"body":"Sticking with older approach for creating Tasks. TODO: revisit this in a future update.","created_at":"2017-07-21T21:06:11Z","updated_at":"2017-07-21T21:06:11Z","html_url":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples/pull/288#discussion_r128861385","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/288","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/comments/128861385"},"html":{"href":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples/pull/288#discussion_r128861385"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/288"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/288","id":130915617,"html_url":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples/pull/288","diff_url":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples/pull/288.diff","patch_url":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples/pull/288.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/issues/288","number":288,"state":"open","locked":false,"title":"Add Spanner sample","user":{"login":"jsimonweb","id":2709164,"avatar_url":"https://avatars1.githubusercontent.com/u/2709164?v=4","gravatar_id":"","url":"https://api.github.com/users/jsimonweb","html_url":"https://github.com/jsimonweb","followers_url":"https://api.github.com/users/jsimonweb/followers","following_url":"https://api.github.com/users/jsimonweb/following{/other_user}","gists_url":"https://api.github.com/users/jsimonweb/gists{/gist_id}","starred_url":"https://api.github.com/users/jsimonweb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsimonweb/subscriptions","organizations_url":"https://api.github.com/users/jsimonweb/orgs","repos_url":"https://api.github.com/users/jsimonweb/repos","events_url":"https://api.github.com/users/jsimonweb/events{/privacy}","received_events_url":"https://api.github.com/users/jsimonweb/received_events","type":"User","site_admin":false},"body":"","created_at":"2017-07-17T18:02:35Z","updated_at":"2017-07-21T21:06:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"757230f88e62cd8f38e3dfe0b68614de893d32cd","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/288/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/288/comments","review_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/issues/288/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/statuses/018936fc0491b01ccbace6b83c46fd7a94b3ce65","head":{"label":"jsimonweb:addSpanner","ref":"addSpanner","sha":"018936fc0491b01ccbace6b83c46fd7a94b3ce65","user":{"login":"jsimonweb","id":2709164,"avatar_url":"https://avatars1.githubusercontent.com/u/2709164?v=4","gravatar_id":"","url":"https://api.github.com/users/jsimonweb","html_url":"https://github.com/jsimonweb","followers_url":"https://api.github.com/users/jsimonweb/followers","following_url":"https://api.github.com/users/jsimonweb/following{/other_user}","gists_url":"https://api.github.com/users/jsimonweb/gists{/gist_id}","starred_url":"https://api.github.com/users/jsimonweb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsimonweb/subscriptions","organizations_url":"https://api.github.com/users/jsimonweb/orgs","repos_url":"https://api.github.com/users/jsimonweb/repos","events_url":"https://api.github.com/users/jsimonweb/events{/privacy}","received_events_url":"https://api.github.com/users/jsimonweb/received_events","type":"User","site_admin":false},"repo":{"id":47431932,"name":"csharp-docs-samples","full_name":"jsimonweb/csharp-docs-samples","owner":{"login":"jsimonweb","id":2709164,"avatar_url":"https://avatars1.githubusercontent.com/u/2709164?v=4","gravatar_id":"","url":"https://api.github.com/users/jsimonweb","html_url":"https://github.com/jsimonweb","followers_url":"https://api.github.com/users/jsimonweb/followers","following_url":"https://api.github.com/users/jsimonweb/following{/other_user}","gists_url":"https://api.github.com/users/jsimonweb/gists{/gist_id}","starred_url":"https://api.github.com/users/jsimonweb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsimonweb/subscriptions","organizations_url":"https://api.github.com/users/jsimonweb/orgs","repos_url":"https://api.github.com/users/jsimonweb/repos","events_url":"https://api.github.com/users/jsimonweb/events{/privacy}","received_events_url":"https://api.github.com/users/jsimonweb/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jsimonweb/csharp-docs-samples","description":null,"fork":true,"url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples","forks_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/forks","keys_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/teams","hooks_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/hooks","issue_events_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/issues/events{/number}","events_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/events","assignees_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/assignees{/user}","branches_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/branches{/branch}","tags_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/tags","blobs_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/git/refs{/sha}","trees_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/statuses/{sha}","languages_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/languages","stargazers_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/stargazers","contributors_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/contributors","subscribers_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/subscribers","subscription_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/subscription","commits_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/commits{/sha}","git_commits_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/git/commits{/sha}","comments_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/comments{/number}","issue_comment_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/issues/comments{/number}","contents_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/contents/{+path}","compare_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/merges","archive_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/downloads","issues_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/issues{/number}","pulls_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/pulls{/number}","milestones_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/milestones{/number}","notifications_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/labels{/name}","releases_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/releases{/id}","deployments_url":"https://api.github.com/repos/jsimonweb/csharp-docs-samples/deployments","created_at":"2015-12-04T22:27:38Z","updated_at":"2016-05-24T20:24:48Z","pushed_at":"2017-07-21T20:59:18Z","git_url":"git://github.com/jsimonweb/csharp-docs-samples.git","ssh_url":"git@github.com:jsimonweb/csharp-docs-samples.git","clone_url":"https://github.com/jsimonweb/csharp-docs-samples.git","svn_url":"https://github.com/jsimonweb/csharp-docs-samples","homepage":null,"size":4758,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"GoogleCloudPlatform:master","ref":"master","sha":"e9675d4a243292879b75d05eab78145c274f903c","user":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars0.githubusercontent.com/u/2810941?v=4","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"repo":{"id":43513481,"name":"dotnet-docs-samples","full_name":"GoogleCloudPlatform/dotnet-docs-samples","owner":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars0.githubusercontent.com/u/2810941?v=4","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples","description":".NET code samples used on https://cloud.google.com","fork":false,"url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples","forks_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/forks","keys_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/teams","hooks_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/hooks","issue_events_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/events","assignees_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/tags","blobs_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/languages","stargazers_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/stargazers","contributors_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/contributors","subscribers_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/subscribers","subscription_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/subscription","commits_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/merges","archive_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/downloads","issues_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/labels{/name}","releases_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/releases{/id}","deployments_url":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/deployments","created_at":"2015-10-01T18:29:55Z","updated_at":"2017-07-17T03:35:22Z","pushed_at":"2017-07-21T20:59:20Z","git_url":"git://github.com/GoogleCloudPlatform/dotnet-docs-samples.git","ssh_url":"git@github.com:GoogleCloudPlatform/dotnet-docs-samples.git","clone_url":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git","svn_url":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples","homepage":"https://cloud.google.com/dotnet","size":4641,"stargazers_count":91,"watchers_count":91,"language":"C#","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":245,"mirror_url":null,"open_issues_count":7,"forks":245,"open_issues":7,"watchers":91,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/288"},"html":{"href":"https://github.com/GoogleCloudPlatform/dotnet-docs-samples/pull/288"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/issues/288"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/issues/288/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/288/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/pulls/288/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/dotnet-docs-samples/statuses/018936fc0491b01ccbace6b83c46fd7a94b3ce65"}}}}
{"actor":{"display_login":"jsimonweb"}}