Example #1
0
    public async Task <long> LogCommitStatsAsync(string projectId, string instanceId, string databaseId)
    {
        // Commit statistics are logged at level Info by the default logger.
        // This sample uses a custom logger to access the commit statistics.
        // See https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.Spanner.Data/logging.html
        // for more information on how to use loggers.
        var logger                  = new CommitStatsSampleLogger();
        var options                 = new SessionPoolOptions();
        var poolManager             = SessionPoolManager.Create(options, logger);
        var connectionStringBuilder = new SpannerConnectionStringBuilder
        {
            ConnectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}",
            // Set LogCommitStats to true to enable logging commit statistics for all transactions on the connection.
            // LogCommitStats can also be enabled/disabled for individual Spanner transactions.
            LogCommitStats     = true,
            SessionPoolManager = poolManager,
        };

        using var connection = new SpannerConnection(connectionStringBuilder);
        await connection.OpenAsync();

        using var cmd = connection.CreateDmlCommand("INSERT Singers (SingerId, FirstName, LastName) VALUES (110, 'Virginia', 'Watson')");
        var rowCount = await cmd.ExecuteNonQueryAsync();

        var mutationCount = logger._lastCommitResponse.CommitStats.MutationCount;

        Console.WriteLine($"{rowCount} row(s) inserted...");
        Console.WriteLine($"{mutationCount} mutation(s) in transaction...");

        return(mutationCount);
    }
Example #2
0
        private async Task FillOrderData()
        {
            using (var connection = new SpannerConnection(ConnectionString))
            {
                await connection.OpenAsync();

                for (var i = 0; i < NumPartitionReadRows / 5000; i++)
                {
                    using (var tx = await connection.BeginTransactionAsync())
                        using (var cmd = connection.CreateInsertCommand("Orders", new SpannerParameterCollection
                        {
                            { "OrderID", SpannerDbType.String },
                            { "OrderDate", SpannerDbType.Timestamp },
                            { "Product", SpannerDbType.String }
                        }))
                        {
                            cmd.Transaction = tx;
                            for (var x = 1; x < 5000; x++)
                            {
                                cmd.Parameters["OrderID"].Value   = Guid.NewGuid().ToString();
                                cmd.Parameters["OrderDate"].Value = DateTime.Now.Subtract(TimeSpan.FromDays(x));
                                cmd.Parameters["Product"].Value   = $"Widget#{x}";
                                cmd.ExecuteNonQuery();
                            }
                            await tx.CommitAsync();
                        }
                }
            }
        }
Example #3
0
        async Task RefillMarketingBudgetsAsync(int firstAlbumBudget,
                                               int secondAlbumBudget)
        {
            string connectionString =
                $"Data Source=projects/{_fixture.ProjectId}/instances/{_fixture.InstanceId}"
                + $"/databases/{_fixture.DatabaseId}";

            // Create connection to Cloud Spanner.
            using (var connection =
                       new SpannerConnection(connectionString))
            {
                await connection.OpenAsync();

                var cmd = connection.CreateUpdateCommand("Albums",
                                                         new SpannerParameterCollection
                {
                    { "SingerId", SpannerDbType.Int64 },
                    { "AlbumId", SpannerDbType.Int64 },
                    { "MarketingBudget", SpannerDbType.Int64 },
                });
                for (int i = 1; i <= 2; ++i)
                {
                    cmd.Parameters["SingerId"].Value        = i;
                    cmd.Parameters["AlbumId"].Value         = i;
                    cmd.Parameters["MarketingBudget"].Value = i == 1 ?
                                                              firstAlbumBudget : secondAlbumBudget;
                    await cmd.ExecuteNonQueryAsync();
                }
            }
        }
Example #4
0
        public async Task InsertDataAsync()
        {
            await _fixture.EnsureTestDatabaseAsync().ConfigureAwait(false);

            // Sample: InsertDataAsync
            using (var connection = new SpannerConnection(
                       $"Data Source=projects/{_projectId}/instances/{_instanceName}/databases/{_databaseName}"))
            {
                await connection.OpenAsync();

                var cmd = connection.CreateInsertCommand(
                    "TestTable", new SpannerParameterCollection
                {
                    { "Key", SpannerDbType.String },
                    { "StringValue", SpannerDbType.String },
                    { "Int64Value", SpannerDbType.Int64 }
                });

                // This executes 5 distinct transactions with one row written per transaction.
                for (var i = 0; i < 5; i++)
                {
                    cmd.Parameters["Key"].Value         = Guid.NewGuid().ToString("N");
                    cmd.Parameters["StringValue"].Value = $"StringValue{i}";
                    cmd.Parameters["Int64Value"].Value  = i;
                    int rowsAffected = await cmd.ExecuteNonQueryAsync();

                    Console.WriteLine($"{rowsAffected} rows written...");
                }
            }
            // End sample
        }
    private async Task InsertStructDataAsync()
    {
        List <Singer> singers = new List <Singer>
        {
            new Singer {
                SingerId = 6, FirstName = "Elena", LastName = "Campbell"
            },
            new Singer {
                SingerId = 7, FirstName = "Gabriel", LastName = "Wright"
            },
            new Singer {
                SingerId = 8, FirstName = "Benjamin", LastName = "Martinez"
            },
            new Singer {
                SingerId = 9, FirstName = "Hannah", LastName = "Harris"
            }
        };

        using var connection = new SpannerConnection(ConnectionString);
        await connection.OpenAsync();

        var rows = await Task.WhenAll(singers.Select(singer =>
        {
            var cmd = connection.CreateInsertCommand("Singers",
                                                     new SpannerParameterCollection
            {
                { "SingerId", SpannerDbType.Int64, singer.SingerId },
                { "FirstName", SpannerDbType.String, singer.FirstName },
                { "LastName", SpannerDbType.String, singer.LastName }
            });

            return(cmd.ExecuteNonQueryAsync());
        }));
    }
        private async Task <SpannerConnection> CreateAndOpen()
        {
            var connection = new SpannerConnection(_testFixture.ConnectionString);
            await connection.OpenAsync();

            return(connection);
        }
Example #7
0
    public async Task <List <Album> > ReadStaleDataAsync(string projectId, string instanceId, string databaseId)
    {
        string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";

        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        var staleness = TimestampBound.OfExactStaleness(TimeSpan.FromSeconds(15));

        using var transaction = await connection.BeginReadOnlyTransactionAsync(staleness);

        using var cmd   = connection.CreateSelectCommand("SELECT SingerId, AlbumId, MarketingBudget FROM Albums");
        cmd.Transaction = transaction;

        var albums = new List <Album>();

        using var reader = await cmd.ExecuteReaderAsync();

        while (await reader.ReadAsync())
        {
            albums.Add(new Album
            {
                SingerId        = reader.GetFieldValue <int>("SingerId"),
                AlbumId         = reader.GetFieldValue <int>("AlbumId"),
                MarketingBudget = reader.IsDBNull(reader.GetOrdinal("MarketingBudget")) ? 0 : reader.GetFieldValue <long>("MarketingBudget")
            });
        }
        return(albums);
    }
    public async Task UpdateDataWithNumericAsync(string projectId, string instanceId, string databaseId)
    {
        string       connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";
        List <Venue> venues           = new List <Venue>
        {
            new Venue {
                VenueId = 4, Revenue = SpannerNumeric.Parse("35000")
            },
            new Venue {
                VenueId = 19, Revenue = SpannerNumeric.Parse("104500")
            },
            new Venue {
                VenueId = 42, Revenue = SpannerNumeric.Parse("99999999999999999999999999999.99")
            },
        };

        // Create connection to Cloud Spanner.
        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        await Task.WhenAll(venues.Select(venue =>
        {
            // Update rows in the Venues table.
            using var cmd = connection.CreateUpdateCommand("Venues", new SpannerParameterCollection
            {
                { "VenueId", SpannerDbType.Int64, venue.VenueId },
                { "Revenue", SpannerDbType.Numeric, venue.Revenue }
            });
            return(cmd.ExecuteNonQueryAsync());
        }));

        Console.WriteLine("Data updated.");
    }
Example #9
0
        public static async Task InsertPlayersAsync(string projectId,
                                                    string instanceId, string databaseId)
        {
            string connectionString =
                $"Data Source=projects/{projectId}/instances/{instanceId}"
                + $"/databases/{databaseId}";
            Int64 numberOfPlayers = 0;

            using (var connection = new SpannerConnection(connectionString))
            {
                await connection.OpenAsync();

                using (var tx = await connection.BeginTransactionAsync())
                {
                    // Execute a SQL statement to get current number of records
                    // in the Players table.
                    var cmd = connection.CreateSelectCommand(
                        @"SELECT Count(PlayerId) as PlayerCount FROM Players");
                    cmd.Transaction = tx;
                    using (var reader = await cmd.ExecuteReaderAsync())
                    {
                        while (await reader.ReadAsync())
                        {
                            long parsedValue;
                            if (reader["PlayerCount"] != DBNull.Value)
                            {
                                bool result = Int64.TryParse(
                                    reader.GetFieldValue <string>("PlayerCount"),
                                    out parsedValue);
                                if (result)
                                {
                                    numberOfPlayers = parsedValue;
                                }
                            }
                        }
                    }
                    // Insert 100 player records into the Players table.
                    using (cmd = connection.CreateInsertCommand(
                               "Players", new SpannerParameterCollection
                    {
                        { "PlayerId", SpannerDbType.String },
                        { "PlayerName", SpannerDbType.String }
                    }))
                    {
                        cmd.Transaction = tx;
                        for (var x = 1; x <= 100; x++)
                        {
                            numberOfPlayers++;
                            cmd.Parameters["PlayerId"].Value =
                                Math.Abs(Guid.NewGuid().GetHashCode());
                            cmd.Parameters["PlayerName"].Value =
                                $"Player {numberOfPlayers}";
                            cmd.ExecuteNonQuery();
                        }
                    }
                    await tx.CommitAsync();
                }
            }
            Console.WriteLine("Done inserting player records...");
        }
        private static async Task <T> ExecuteCommandAsync <T>(
            SpannerConnection connection, Func <DbCommand, Task <T> > executeAsync, string sql, bool useTransaction,
            IReadOnlyList <object> parameters)
        {
            if (connection.State != ConnectionState.Closed)
            {
                connection.Close();
            }
            await connection.OpenAsync().ConfigureAwait(false);

            try
            {
                using (var transaction = useTransaction ? connection.BeginTransaction() : null)
                {
                    T result;
                    using (var command = CreateCommand(connection, sql, parameters))
                    {
                        result = await executeAsync(command).ConfigureAwait(false);
                    }
                    transaction?.Commit();

                    return(result);
                }
            }
            finally
            {
                if (connection.State == ConnectionState.Closed &&
                    connection.State != ConnectionState.Closed)
                {
                    connection.Close();
                }
            }
        }
Example #11
0
        private async Task FillSampleData(string testTable)
        {
            using (var connection = new SpannerConnection(ConnectionString))
            {
                await connection.OpenAsync();

                using (var tx = await connection.BeginTransactionAsync())
                {
                    var cmd = connection.CreateInsertCommand(
                        testTable,
                        new SpannerParameterCollection
                    {
                        { "Key", SpannerDbType.String },
                        { "StringValue", SpannerDbType.String }
                    });
                    cmd.Transaction = tx;

                    for (var i = 0; i < TestTableRowCount - 1; ++i)
                    {
                        cmd.Parameters["Key"].Value         = "k" + i;
                        cmd.Parameters["StringValue"].Value = "v" + i;
                        await cmd.ExecuteNonQueryAsync();
                    }

                    // And one extra row, with a null value.
                    cmd.Parameters["Key"].Value         = "kNull";
                    cmd.Parameters["StringValue"].Value = DBNull.Value;
                    await cmd.ExecuteNonQueryAsync();

                    await tx.CommitAsync();
                }
            }
        }
    public async Task <int> InsertStructSampleDataAsync(string projectId, string instanceId, string databaseId)
    {
        string        connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";
        List <Singer> singers          = new List <Singer> {
            new Singer {
                SingerId = 6, FirstName = "Elena", LastName = "Campbell"
            },
            new Singer {
                SingerId = 7, FirstName = "Gabriel", LastName = "Wright"
            },
            new Singer {
                SingerId = 8, FirstName = "Benjamin", LastName = "Martinez"
            },
            new Singer {
                SingerId = 9, FirstName = "Hannah", LastName = "Harris"
            }
        };

        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        var rows = await Task.WhenAll(singers.Select(singer =>
        {
            var cmd = connection.CreateInsertCommand("Singers",
                                                     new SpannerParameterCollection {
                { "SingerId", SpannerDbType.Int64, singer.SingerId },
                { "FirstName", SpannerDbType.String, singer.FirstName },
                { "LastName", SpannerDbType.String, singer.LastName }
            });
            return(cmd.ExecuteNonQueryAsync());
        }));

        return(rows.Sum());
    }
Example #13
0
        public async Task DistributedReadAsync()
        {
            int numRows;

            using (var connection = await _testFixture.GetTestDatabaseConnectionAsync())
                using (var cmd = connection.CreateSelectCommand("SELECT COUNT(*) FROM Orders"))
                {
                    numRows = await cmd.ExecuteScalarAsync <int>();
                }

            using (var connection = new SpannerConnection(_testFixture.ConnectionString))
            {
                await connection.OpenAsync();

                using (var transaction = await connection.BeginReadOnlyTransactionAsync())
                    using (var cmd = connection.CreateSelectCommand("SELECT * FROM Orders"))
                    {
                        transaction.DisposeBehavior = DisposeBehavior.CloseResources;
                        cmd.Transaction             = transaction;
                        var partitions = await cmd.GetReaderPartitionsAsync(1000);

                        var transactionId = transaction.TransactionId;

                        //we simulate a serialization/deserialization step in the call to the subtask.
                        await Task.WhenAll(partitions.Select(
                                               x => DistributedReadWorkerAsync(CommandPartition.FromBase64String(x.ToBase64String()),
                                                                               TransactionId.FromBase64String(transactionId.ToBase64String()))))
                        .ConfigureAwait(false);
                    }

                Assert.Equal(numRows, _rowsRead);
            }
        }
Example #14
0
    public async Task <int> WriteWithTransactionUsingDmlCoreAsync(string projectId, string instanceId, string databaseId)
    {
        // This sample transfers 200,000 from the MarketingBudget
        // field of the second Album to the first Album. Make sure to run
        // the AddColumnAsyncSample and WriteDataToNewColumnAsyncSample first,
        // in that order.
        string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";

        decimal transferAmount = 200000;
        decimal secondBudget   = 0;

        // Create connection to Cloud Spanner.
        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        // Create a readwrite transaction that we'll assign
        // to each SpannerCommand.
        using var transaction = await connection.BeginTransactionAsync();

        // Create statement to select the second album's data.
        var cmdLookup = connection.CreateSelectCommand("SELECT * FROM Albums WHERE SingerId = 2 AND AlbumId = 2");

        cmdLookup.Transaction = transaction;
        // Execute the select query.
        using var reader1 = await cmdLookup.ExecuteReaderAsync();

        while (await reader1.ReadAsync())
        {
            // Read the second album's budget.
            secondBudget = reader1.GetFieldValue <decimal>("MarketingBudget");
            // Confirm second Album's budget is sufficient and
            // if not raise an exception. Raising an exception
            // will automatically roll back the transaction.
            if (secondBudget < transferAmount)
            {
                throw new Exception($"The second album's budget {secondBudget} is less than the amount to transfer.");
            }
        }

        // Update second album to remove the transfer amount.
        secondBudget -= transferAmount;
        SpannerCommand cmd = connection.CreateDmlCommand("UPDATE Albums SET MarketingBudget = @MarketingBudget  WHERE SingerId = 2 and AlbumId = 2");

        cmd.Parameters.Add("MarketingBudget", SpannerDbType.Int64, secondBudget);
        cmd.Transaction = transaction;
        var rowCount = await cmd.ExecuteNonQueryAsync();

        // Update first album to add the transfer amount.
        cmd = connection.CreateDmlCommand("UPDATE Albums SET MarketingBudget = MarketingBudget + @MarketingBudgetIncrement WHERE SingerId = 1 and AlbumId = 1");
        cmd.Parameters.Add("MarketingBudgetIncrement", SpannerDbType.Int64, transferAmount);
        cmd.Transaction = transaction;
        rowCount       += await cmd.ExecuteNonQueryAsync();

        await transaction.CommitAsync();

        Console.WriteLine("Transaction complete.");
        return(rowCount);
    }
        public async Task <CurrencyRate> GetRate(string from, string to)
        {
            await using var connection = new SpannerConnection(connectionString);
            await connection.OpenAsync();

            var result = await GetRatesImpl(connection, from, to);

            return(result.FirstOrDefault());
        }
        public async Task <CurrencyRate[]> GetRates(string from)
        {
            await using var connection = new SpannerConnection(connectionString);
            await connection.OpenAsync();

            var result = await GetRatesImpl(connection, from);

            return(result.ToArray());
        }
        private static async Task Can_use_an_existing_closed_connection_test(bool openConnection)
        {
            var serviceProvider = new ServiceCollection()
                                  .AddEntityFrameworkSpanner()
                                  .BuildServiceProvider();

            using (var store = SpannerTestStore.GetNorthwindStore())
            {
                var openCount    = 0;
                var closeCount   = 0;
                var disposeCount = 0;

                using (var connection = new SpannerConnection(store.ConnectionString))
                {
                    if (openConnection)
                    {
                        await connection.OpenAsync();
                    }

                    connection.StateChange += (_, a) =>
                    {
                        if (a.CurrentState == ConnectionState.Open)
                        {
                            openCount++;
                        }
                        else if (a.CurrentState == ConnectionState.Closed)
                        {
                            closeCount++;
                        }
                    };
                    connection.Disposed += (_, __) => disposeCount++;

                    using (var context = new NorthwindContext(serviceProvider, connection))
                    {
                        Assert.Equal(91, await context.Customers.CountAsync());
                    }

                    if (openConnection)
                    {
                        Assert.Equal(ConnectionState.Open, connection.State);
                        Assert.Equal(0, openCount);
                        Assert.Equal(0, closeCount);
                    }
                    else
                    {
                        Assert.Equal(ConnectionState.Closed, connection.State);
                        Assert.Equal(1, openCount);
                        Assert.Equal(1, closeCount);
                    }

                    Assert.Equal(0, disposeCount);
                }
            }
        }
    public async Task <int> DeleteUsingDmlCoreAsync(string projectId, string instanceId, string databaseId)
    {
        string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";

        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        using var cmd = connection.CreateDmlCommand("DELETE FROM Singers WHERE FirstName = 'Alice'");
        int rowCount = await cmd.ExecuteNonQueryAsync();

        Console.WriteLine($"{rowCount} row(s) deleted...");
        return(rowCount);
    }
Example #19
0
    public async Task <int> UpdateUsingDmlWithTimestampCoreAsync(string projectId, string instanceId, string databaseId)
    {
        string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";

        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        using var cmd = connection.CreateDmlCommand("UPDATE Albums SET LastUpdateTime = PENDING_COMMIT_TIMESTAMP() WHERE SingerId = 1");
        int rowCount = await cmd.ExecuteNonQueryAsync();

        Console.WriteLine($"{rowCount} row(s) updated...");
        return(rowCount);
    }
    public async Task <long> DeleteUsingPartitionedDmlCoreAsync(string projectId, string instanceId, string databaseId)
    {
        string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";

        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        using var cmd = connection.CreateDmlCommand("DELETE FROM Singers WHERE SingerId > 10");
        long rowCount = await cmd.ExecutePartitionedUpdateAsync();

        Console.WriteLine($"{rowCount} row(s) deleted...");
        return(rowCount);
    }
Example #21
0
    public async Task <int> UpdateUsingDmlCoreAsync(string projectId, string instanceId, string databaseId)
    {
        string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";

        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        using var cmd = connection.CreateDmlCommand("UPDATE Albums SET MarketingBudget = MarketingBudget * 2 WHERE SingerId = 1 and AlbumId = 1");
        int rowCount = await cmd.ExecuteNonQueryAsync();

        Console.WriteLine($"{rowCount} row(s) updated...");
        return(rowCount);
    }
    public async Task <int> InsertUsingDmlCoreAsync(string projectId, string instanceId, string databaseId)
    {
        string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";

        using var connection = new SpannerConnection(connectionString);
        await connection.OpenAsync();

        using var cmd = connection.CreateDmlCommand("INSERT Singers (SingerId, FirstName, LastName) VALUES (10, 'Virginia', 'Watson')");
        int rowCount = await cmd.ExecuteNonQueryAsync();

        Console.WriteLine($"{rowCount} row(s) inserted...");
        return(rowCount);
    }
Example #23
0
        private static async Task BatchInsertPlayersAsync(string projectId,
                                                          string instanceId, string databaseId)
        {
            string connectionString =
                $"Data Source=projects/{projectId}/instances/{instanceId}"
                + $"/databases/{databaseId}";

            long playerStartingPlanetDollars = 1000000;

            // Batch insert 249,900 player records into the Players table.
            using (var connection = new SpannerConnection(connectionString))
            {
                await connection.OpenAsync();

                for (int i = 0; i < 100; i++)
                {
                    // For details on transaction isolation, see the "Isolation" section in:
                    // https://cloud.google.com/spanner/docs/transactions#read-write_transactions
                    using (var tx = await connection.BeginTransactionAsync())
                        using (var cmd = connection.CreateInsertCommand("Players", new SpannerParameterCollection
                        {
                            { "PlayerId", SpannerDbType.String },
                            { "PlayerName", SpannerDbType.String },
                            { "PlanetDollars", SpannerDbType.Int64 }
                        }))
                        {
                            cmd.Transaction = tx;
                            for (var x = 1; x < 2500; x++)
                            {
                                string nameSuffix = Guid.NewGuid().ToString().Substring(0, 8);
                                cmd.Parameters["PlayerId"].Value      = Guid.NewGuid().ToString("N");
                                cmd.Parameters["PlayerName"].Value    = $"Player-{nameSuffix}";
                                cmd.Parameters["PlanetDollars"].Value = playerStartingPlanetDollars;
                                try
                                {
                                    cmd.ExecuteNonQuery();
                                }
                                catch (SpannerException ex) {
                                    Console.WriteLine($"Spanner Exception: {ex.Message}");
                                    // Decrement x and retry
                                    x--;
                                    continue;
                                }
                            }
                            await tx.CommitAsync();
                        }
                }
            }
            Console.WriteLine("Done inserting sample records...");
        }
Example #24
0
        public static async Task InsertScoresAsync(
            string projectId, string instanceId, string databaseId)
        {
            string connectionString =
                $"Data Source=projects/{projectId}/instances/{instanceId}"
                + $"/databases/{databaseId}";

            // Insert 4 score records into the Scores table for each player in the Players table.
            using (var connection = new SpannerConnection(connectionString))
            {
                await connection.OpenAsync();

                Random r         = new Random();
                var    cmdLookup = connection.CreateSelectCommand("SELECT * FROM Players");
                using (var reader = await cmdLookup.ExecuteReaderAsync())
                {
                    while (await reader.ReadAsync())
                    {
                        using (var tx = await connection.BeginTransactionAsync())
                            using (var cmd = connection.CreateInsertCommand("Scores", new SpannerParameterCollection
                            {
                                { "PlayerId", SpannerDbType.String },
                                { "Score", SpannerDbType.Int64 },
                                { "Timestamp", SpannerDbType.Timestamp }
                            }))
                            {
                                cmd.Transaction = tx;
                                for (var x = 1; x <= 4; x++)
                                {
                                    DateTime randomTimestamp = DateTime.Now
                                                               .AddYears(r.Next(-1, 1))
                                                               .AddMonths(r.Next(-12, 1))
                                                               .AddDays(r.Next(-10, 1))
                                                               .AddSeconds(r.Next(-60, 0))
                                                               .AddMilliseconds(r.Next(-100000, 0));
                                    cmd.Parameters["PlayerId"].Value = reader.GetFieldValue <int>("PlayerId");
                                    // Insert random value for score between 10000 and 1000000.
                                    cmd.Parameters["Score"].Value = r.Next(1000, 1000001);
                                    // Insert random past timestamp value into Timestamp column.
                                    cmd.Parameters["Timestamp"].Value = randomTimestamp.ToString("o");
                                    cmd.ExecuteNonQuery();
                                }
                                await tx.CommitAsync();
                            }
                    }
                }
            }
            Console.WriteLine("Done inserting score records...");
        }
    public async Task <int> DeleteDataAsync(string projectId, string instanceId, string databaseId)
    {
        string connectionString = $"Data Source=projects/{projectId}/instances/{instanceId}/databases/{databaseId}";

        var albums = new List <Album>
        {
            new Album {
                SingerId = 2, AlbumId = 1, AlbumTitle = "Green"
            },
            new Album {
                SingerId = 2, AlbumId = 3, AlbumTitle = "Terrified"
            },
        };

        int rowCount = 0;

        using (var connection = new SpannerConnection(connectionString))
        {
            await connection.OpenAsync();

            // Delete individual rows from the Albums table.
            await Task.WhenAll(albums.Select(async album =>
            {
                var cmd = connection.CreateDeleteCommand("Albums", new SpannerParameterCollection
                {
                    { "SingerId", SpannerDbType.Int64, album.SingerId },
                    { "AlbumId", SpannerDbType.Int64, album.AlbumId }
                });
                rowCount += await cmd.ExecuteNonQueryAsync();
            }));

            Console.WriteLine("Deleted individual rows in Albums.");

            // Delete a range of rows from the Singers table where the column key is >=3 and <5.
            var cmd = connection.CreateDmlCommand("DELETE FROM Singers WHERE SingerId >= 3 AND SingerId < 5");
            rowCount += await cmd.ExecuteNonQueryAsync();

            Console.WriteLine($"{rowCount} row(s) deleted from Singers.");

            // Delete remaining Singers rows, which will also delete the remaining
            // Albums rows since it was defined with ON DELETE CASCADE.
            cmd       = connection.CreateDmlCommand("DELETE FROM Singers WHERE true");
            rowCount += await cmd.ExecuteNonQueryAsync();

            Console.WriteLine($"{rowCount} row(s) deleted from Singers.");
        }
        return(rowCount);
    }
    public async Task RefillMarketingBudgetsAsync(int firstAlbumBudget, int secondAlbumBudget)
    {
        using var connection = new SpannerConnection(ConnectionString);
        await connection.OpenAsync();

        for (int i = 1; i <= 2; ++i)
        {
            var cmd = connection.CreateUpdateCommand("Albums", new SpannerParameterCollection
            {
                { "SingerId", SpannerDbType.Int64, i },
                { "AlbumId", SpannerDbType.Int64, i },
                { "MarketingBudget", SpannerDbType.Int64, i == 1 ? firstAlbumBudget : secondAlbumBudget },
            });
            await cmd.ExecuteNonQueryAsync();
        }
    }
        public async Task SetActualRates(ICollection <CurrencyRate> rates)
        {
            await using var connection = new SpannerConnection(connectionString);
            await connection.OpenAsync();

            var actualRates = await GetRatesImpl(connection);

            var tasks = new List <Task>();

            foreach (var newRate in rates)
            {
                var actualRate = actualRates.FirstOrDefault(r => r.Key == newRate.Key);
                if (actualRate == null)
                {
                    var insertActualRate = connection.CreateInsertCommand("actual_rates");
                    insertActualRate.Parameters.Add("currency_from", SpannerDbType.String, newRate.CurrencyFrom);
                    insertActualRate.Parameters.Add("currency_to", SpannerDbType.String, newRate.CurrencyTo);
                    insertActualRate.Parameters.Add("provider_name", SpannerDbType.String, newRate.ProviderName);
                    insertActualRate.Parameters.Add("expiration_time", SpannerDbType.Timestamp, newRate.ExpirationTime);
                    insertActualRate.Parameters.Add("original_published_time", SpannerDbType.Timestamp, newRate.OriginalPublishedTime);
                    insertActualRate.Parameters.Add("time_of_receipt", SpannerDbType.Timestamp, newRate.TimeOfReceipt);
                    insertActualRate.Parameters.Add("value", SpannerDbType.Int64, newRate.Value);
                    tasks.Add(insertActualRate.ExecuteNonQueryAsync());
                }
                else
                {
                    actualRate.Update(newRate, mapper);

                    var cmd = connection.CreateDmlCommand(
                        "UPDATE actual_rates " +
                        "SET expiration_time = @expiration_time, " +
                        "original_published_time = @original_published_time, " +
                        "provider_name = @provider_name, " +
                        "time_of_receipt = @time_of_receipt, " +
                        "value = @value " +
                        "WHERE currency_from = @currency_from and currency_to = @currency_to");
                    cmd.Parameters.Add("provider_name", SpannerDbType.String, newRate.ProviderName);
                    cmd.Parameters.Add("expiration_time", SpannerDbType.Timestamp, newRate.ExpirationTime);
                    cmd.Parameters.Add("original_published_time", SpannerDbType.Timestamp, newRate.OriginalPublishedTime);
                    cmd.Parameters.Add("time_of_receipt", SpannerDbType.Timestamp, newRate.TimeOfReceipt);
                    cmd.Parameters.Add("value", SpannerDbType.Int64, newRate.Value);
                    tasks.Add(cmd.ExecuteNonQueryAsync());
                }
            }

            await Task.WhenAll(tasks);
        }
Example #28
0
        public async Task ReadUpdateDeleteAsync()
        {
            await _fixture.EnsureTestDatabaseAsync().ConfigureAwait(false);

            // Sample: ReadUpdateDeleteAsync
            using (var connection = new SpannerConnection(
                       $"Data Source=projects/{_projectId}/instances/{_instanceName}/databases/{_databaseName}"))
            {
                await connection.OpenAsync();

                // Read the first two keys in the database.
                var keys      = new List <string>();
                var selectCmd = connection.CreateSelectCommand("SELECT * FROM TestTable");
                using (var reader = await selectCmd.ExecuteReaderAsync())
                {
                    while (await reader.ReadAsync())
                    {
                        if (keys.Count < 3)
                        {
                            keys.Add(reader.GetFieldValue <string>("Key"));
                            continue;
                        }
                        break;
                    }
                }

                // Update the Int64Value of keys[0]
                // Include the primary key and update columns.
                var updateCmd = connection.CreateUpdateCommand(
                    "TestTable", new SpannerParameterCollection
                {
                    { "Key", SpannerDbType.String, keys[0] },
                    { "Int64Value", SpannerDbType.Int64, 0L }
                });
                await updateCmd.ExecuteNonQueryAsync();

                // Delete row for keys[1]
                var deleteCmd = connection.CreateDeleteCommand(
                    "TestTable", new SpannerParameterCollection
                {
                    { "Key", SpannerDbType.String, keys[1] }
                });
                await deleteCmd.ExecuteNonQueryAsync();
            }
            // End sample
        }
Example #29
0
        public async Task TransactionAsync()
        {
            await _fixture.EnsureTestDatabaseAsync().ConfigureAwait(false);

            // Sample: TransactionAsync
            // Additional: BeginTransactionAsync
            var retryPolicy = new RetryPolicy <SpannerFaultDetectionStrategy>(RetryStrategy.DefaultExponential);

            await retryPolicy.ExecuteAsync(
                async() =>
            {
                using (var connection =
                           new SpannerConnection(
                               $"Data Source=projects/{_projectId}/instances/{_instanceName}/databases/{_databaseName}"))
                {
                    await connection.OpenAsync();

                    using (var transaction = await connection.BeginTransactionAsync())
                    {
                        var cmd = connection.CreateInsertCommand(
                            "TestTable", new SpannerParameterCollection
                        {
                            { "Key", SpannerDbType.String },
                            { "StringValue", SpannerDbType.String },
                            { "Int64Value", SpannerDbType.Int64 }
                        });
                        cmd.Transaction = transaction;

                        // This executes a single transactions with alls row written at once during CommitAsync().
                        // If a transient fault occurs, this entire method is re-run.
                        for (var i = 0; i < 5; i++)
                        {
                            cmd.Parameters["Key"].Value         = Guid.NewGuid().ToString("N");
                            cmd.Parameters["StringValue"].Value = $"StringValue{i}";
                            cmd.Parameters["Int64Value"].Value  = i;
                            await cmd.ExecuteNonQueryAsync();
                        }

                        await transaction.CommitAsync();
                    }
                }
            });

            // End sample
        }
Example #30
0
        public static async Task InsertPlayersAsync(string projectId,
                                                    string instanceId, string databaseId)
        {
            string connectionString =
                $"Data Source=projects/{projectId}/instances/{instanceId}"
                + $"/databases/{databaseId}";

            long numberOfPlayers = 0;

            using (var connection = new SpannerConnection(connectionString))
            {
                await connection.OpenAsync();

                await connection.RunWithRetriableTransactionAsync(async (transaction) =>
                {
                    // Execute a SQL statement to get current number of records
                    // in the Players table to use as an incrementing value
                    // for each PlayerName to be inserted.
                    var cmd = connection.CreateSelectCommand(
                        @"SELECT Count(PlayerId) as PlayerCount FROM Players");
                    numberOfPlayers = await cmd.ExecuteScalarAsync <long>();
                    // Insert 100 player records into the Players table.
                    SpannerBatchCommand cmdBatch = connection.CreateBatchDmlCommand();
                    for (int i = 0; i < 100; i++)
                    {
                        numberOfPlayers++;
                        SpannerCommand cmdInsert = connection.CreateDmlCommand(
                            "INSERT INTO Players "
                            + "(PlayerId, PlayerName) "
                            + "VALUES (@PlayerId, @PlayerName)",
                            new SpannerParameterCollection {
                            { "PlayerId", SpannerDbType.Int64 },
                            { "PlayerName", SpannerDbType.String }
                        });
                        cmdInsert.Parameters["PlayerId"].Value =
                            Math.Abs(Guid.NewGuid().GetHashCode());
                        cmdInsert.Parameters["PlayerName"].Value =
                            $"Player {numberOfPlayers}";
                        cmdBatch.Add(cmdInsert);
                    }
                    await cmdBatch.ExecuteNonQueryAsync();
                });
            }
            Console.WriteLine("Done inserting player records...");
        }