public void TimeSpan_Valid(long ticks) { var timeSpan = new TimeSpan(ticks); TimestampBound.OfExactStaleness(timeSpan); TimestampBound.OfMaxStaleness(timeSpan); }
public async Task ExactReadMultiUseWithReturnReadTimestamp() { using (var connection = _fixture.GetConnection()) { await connection.OpenAsync(); var targetReadTimestamp = _fixture.TimestampBeforeEntries; var bound = TimestampBound.OfReadTimestamp(targetReadTimestamp).WithReturnReadTimestamp(true); using (var tx = await connection.BeginReadOnlyTransactionAsync(bound)) { Assert.Equal(TransactionMode.ReadOnly, tx.Mode); Assert.Equal(targetReadTimestamp, tx.TimestampBound.Timestamp); Assert.True(tx.TimestampBound.ReturnReadTimestamp); var cmd = CreateSelectAllCommandForKey(connection); cmd.Transaction = tx; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.Equal(wkt::Timestamp.FromDateTime(targetReadTimestamp), reader.GetReadTimestamp()); Assert.False( await reader.ReadAsync(), "no data should be here from yesterday!"); } } } }
public async Task ReadStaleExact() { await WriteSampleRowsAsync(); using (var connection = await _testFixture.GetTestDatabaseConnectionAsync()) { await connection.OpenAsync(); using (var tx = await connection.BeginReadOnlyTransactionAsync( TimestampBound.OfExactStaleness(TimeSpan.FromSeconds(50)))) { Assert.Equal(TransactionMode.ReadOnly, tx.Mode); Assert.Equal(TimeSpan.FromSeconds(50), tx.TimestampBound.Staleness); var cmd = connection.CreateSelectCommand( "SELECT * FROM TX WHERE K=@k", new SpannerParameterCollection { { "k", _key, SpannerDbType.String } }); cmd.Transaction = tx; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.False(await reader.ReadAsync(), "We should have read no rows at this time!"); } } } }
public void Equality() { DateTime timestamp1 = new DateTime(2000, 6, 1, 23, 1, 5, DateTimeKind.Utc); TimeSpan staleness1 = TimeSpan.FromSeconds(10); DateTime timestamp2 = new DateTime(2005, 1, 1, 1, 1, 1, DateTimeKind.Utc); TimeSpan staleness2 = TimeSpan.FromSeconds(30); var strong = TimestampBound.Strong; var minRead = TimestampBound.OfMinReadTimestamp(timestamp1); var read = TimestampBound.OfReadTimestamp(timestamp1); var exactStaleness = TimestampBound.OfExactStaleness(staleness1); var maxStaleness = TimestampBound.OfMaxStaleness(staleness1); EqualityTester.AssertEqual(strong, new[] { strong }, new[] { minRead, read, exactStaleness, maxStaleness }); EqualityTester.AssertEqual(minRead, new[] { TimestampBound.OfMinReadTimestamp(timestamp1) }, new[] { strong, read, exactStaleness, maxStaleness, TimestampBound.OfMinReadTimestamp(timestamp2) }); EqualityTester.AssertEqual(read, new[] { TimestampBound.OfReadTimestamp(timestamp1) }, new[] { strong, minRead, exactStaleness, maxStaleness, TimestampBound.OfReadTimestamp(timestamp2) }); EqualityTester.AssertEqual(exactStaleness, new[] { TimestampBound.OfExactStaleness(staleness1) }, new[] { strong, minRead, read, maxStaleness, TimestampBound.OfExactStaleness(staleness2) }); EqualityTester.AssertEqual(maxStaleness, new[] { TimestampBound.OfMaxStaleness(staleness1) }, new[] { strong, minRead, read, exactStaleness, TimestampBound.OfMaxStaleness(staleness2) }); }
public void Timestamp_UtcIsValid() { var timestamp = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc); TimestampBound.OfMinReadTimestamp(timestamp); TimestampBound.OfReadTimestamp(timestamp); }
public void TimeSpan_NegativeIsInvalid() { var timeSpan = new TimeSpan(-1); Assert.Throws <ArgumentOutOfRangeException>(() => TimestampBound.OfExactStaleness(timeSpan)); Assert.Throws <ArgumentOutOfRangeException>(() => TimestampBound.OfMaxStaleness(timeSpan)); }
public async Task ReadStaleMax() { await WriteSampleRowsAsync(); await Task.Delay(6); using (var connection = await _testFixture.GetTestDatabaseConnectionAsync()) { await connection.OpenAsync(); await Assert.ThrowsAsync <ArgumentException>( async() => { await connection.BeginReadOnlyTransactionAsync( TimestampBound.OfMaxStaleness(TimeSpan.FromSeconds(50))); }).ConfigureAwait(false); var cmd = connection.CreateSelectCommand( "SELECT * FROM TX WHERE K=@k", new SpannerParameterCollection { { "k", SpannerDbType.String, _key } }); using (var reader = await cmd.ExecuteReaderAsync( TimestampBound.OfMaxStaleness(TimeSpan.FromMilliseconds(5)))) { if (await reader.ReadAsync()) { Assert.Equal(_history[2].Value, reader.GetFieldValue <string>(reader.GetOrdinal("StringValue"))); } } } }
public void Timestamp_NonUtcIsInvalid(DateTimeKind kind) { var timestamp = new DateTime(2000, 1, 1, 0, 0, 0, kind); Assert.Throws <ArgumentException>(() => TimestampBound.OfMinReadTimestamp(timestamp)); Assert.Throws <ArgumentException>(() => TimestampBound.OfReadTimestamp(timestamp)); }
public async Task ReadMin() { using (var connection = _fixture.GetConnection()) { await connection.OpenAsync(); await Assert.ThrowsAsync <ArgumentException>( async() => { await connection.BeginReadOnlyTransactionAsync( TimestampBound.OfMinReadTimestamp(_newestEntry.Timestamp)); }).ConfigureAwait(false); var cmd = CreateSelectAllCommandForKey(connection); using (var reader = await cmd.ExecuteReaderAsync( TimestampBound.OfMinReadTimestamp(_newestEntry.Timestamp))) { if (await reader.ReadAsync()) { Assert.Equal(_newestEntry.Value, reader.GetFieldValue <string>(reader.GetOrdinal("StringValue"))); } } } }
public async Task ReadExact() { using (var connection = _fixture.GetConnection()) { await connection.OpenAsync(); var targetReadTimestamp = _fixture.TimestampBeforeEntries; using (var tx = await connection.BeginReadOnlyTransactionAsync( TimestampBound.OfReadTimestamp(targetReadTimestamp))) { Assert.Equal(TransactionMode.ReadOnly, tx.Mode); Assert.Equal(targetReadTimestamp, tx.TimestampBound.Timestamp); var cmd = CreateSelectAllCommandForKey(connection); cmd.Transaction = tx; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.False( await reader.ReadAsync(), "no data should be here from yesterday!"); } } } }
public async Task ReadExact() { await WriteSampleRowsAsync(); using (var connection = await _testFixture.GetTestDatabaseConnectionAsync()) { await connection.OpenAsync(); var targetReadTimestamp = _history[0].Timestamp.AddMinutes(-1); using (var tx = await connection.BeginReadOnlyTransactionAsync( TimestampBound.OfReadTimestamp(targetReadTimestamp))) { Assert.Equal(TransactionMode.ReadOnly, tx.Mode); Assert.Equal(targetReadTimestamp, tx.TimestampBound.Timestamp); var cmd = connection.CreateSelectCommand( "SELECT * FROM TX WHERE K=@k", new SpannerParameterCollection { { "k", _key, SpannerDbType.String } }); cmd.Transaction = tx; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.False( await reader.ReadAsync(), "no data should be here from yesterday!"); } } } }
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); }
private static void AssertProtoConversion(ReadOnly expectedReadOnly, TimestampBound bound) { var expected = new TransactionOptions { ReadOnly = expectedReadOnly }; Assert.Equal(expected, bound.ToTransactionOptions()); }
public void ToTransactionOptions_OfExactStaleness() { var bound = TimestampBound.OfExactStaleness(TimeSpan.FromSeconds(5)); AssertProtoConversion(new ReadOnly { ExactStaleness = new Duration { Seconds = 5 } }, bound); }
public void ToTransactionOptions_WithReturnReadTimestamp() { var bound = TimestampBound.OfReadTimestamp(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc)).WithReturnReadTimestamp(true); AssertProtoConversion(new ReadOnly { ReadTimestamp = new Timestamp { Seconds = 10 }, ReturnReadTimestamp = true }, bound); }
public void ToTransactionOptions_OfExactTimestamp() { var bound = TimestampBound.OfReadTimestamp(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc)); AssertProtoConversion(new ReadOnly { ReadTimestamp = new Timestamp { Seconds = 10 } }, bound); }
public async Task ReadStaleExactSingle() { using (var connection = _fixture.GetConnection()) { await connection.OpenAsync(); var cmd = CreateSelectAllCommandForKey(connection); var bound = TimestampBound.OfExactStaleness(_fixture.Staleness); using (var reader = await cmd.ExecuteReaderAsync(bound)) { Assert.False(await reader.ReadAsync(), "We should have read no rows at this time!"); } } }
public async Task ReadExactSingle() { using (var connection = _fixture.GetConnection()) { await connection.OpenAsync(); var cmd = CreateSelectAllCommandForKey(connection); using (var reader = await cmd.ExecuteReaderAsync(TimestampBound.OfReadTimestamp(_oldestEntry.Timestamp))) { if (await reader.ReadAsync()) { Assert.Equal(_oldestEntry.Value, reader.GetFieldValue <string>(reader.GetOrdinal("StringValue"))); } } } }
public async Task ExactReadSinglueUseWithReturnReadTimestamp() { using (var connection = _fixture.GetConnection()) { await connection.OpenAsync(); var cmd = CreateSelectAllCommandForKey(connection); var bound = TimestampBound.OfReadTimestamp(_oldestEntry.Timestamp).WithReturnReadTimestamp(true); using (var reader = (SpannerDataReader)(await cmd.ExecuteReaderAsync(bound))) { Assert.Equal(wkt::Timestamp.FromDateTime(_oldestEntry.Timestamp), reader.GetReadTimestamp()); if (await reader.ReadAsync()) { Assert.Equal(_oldestEntry.Value, reader.GetFieldValue <string>(reader.GetOrdinal("StringValue"))); } } } }
public async Task ReadStaleMax() { using (var connection = _fixture.GetConnection()) { await connection.OpenAsync(); // Can't use MaxStaleness to create a transaction var staleBound = TimestampBound.OfMaxStaleness(_fixture.Staleness); await Assert.ThrowsAsync <ArgumentException>(() => connection.BeginReadOnlyTransactionAsync(staleBound)); var cmd = CreateSelectAllCommandForKey(connection); var recentBound = TimestampBound.OfMaxStaleness(TimeSpan.FromMilliseconds(5)); using (var reader = await cmd.ExecuteReaderAsync(recentBound)) { if (await reader.ReadAsync()) { Assert.Equal(_newestEntry.Value, reader.GetFieldValue <string>(reader.GetOrdinal("StringValue"))); } } } }
public async Task ReadStaleExact() { using (var connection = _fixture.GetConnection()) { await connection.OpenAsync(); var bound = TimestampBound.OfExactStaleness(_fixture.Staleness); using (var tx = await connection.BeginReadOnlyTransactionAsync(bound)) { Assert.Equal(TransactionMode.ReadOnly, tx.Mode); Assert.Equal(_fixture.Staleness, tx.TimestampBound.Staleness); var cmd = CreateSelectAllCommandForKey(connection); cmd.Transaction = tx; using (var reader = await cmd.ExecuteReaderAsync()) { Assert.False(await reader.ReadAsync(), "We should have read no rows at this time!"); } } } }
public async Task ReadMin() { ArgumentException caughtException = null; await WriteSampleRowsAsync(); using (var connection = await _testFixture.GetTestDatabaseConnectionAsync()) { await connection.OpenAsync(); try { await connection.BeginReadOnlyTransactionAsync( TimestampBound.OfMinReadTimestamp(_history[2].Timestamp)); } catch (ArgumentException ex) { caughtException = ex; } var cmd = connection.CreateSelectCommand( "SELECT * FROM TX WHERE K=@k", new SpannerParameterCollection { { "k", _key, SpannerDbType.String } }); using (var reader = await cmd.ExecuteReaderAsync( TimestampBound.OfMinReadTimestamp(_history[2].Timestamp))) { if (await reader.ReadAsync()) { Assert.Equal(_history[2].Value, reader.GetFieldValue <string>(reader.GetOrdinal("StringValue"))); } } } Assert.NotNull(caughtException); }
public async Task ReadExactSingle() { await WriteSampleRowsAsync(); await Task.Delay(6); using (var connection = await _testFixture.GetTestDatabaseConnectionAsync()) { await connection.OpenAsync(); var cmd = connection.CreateSelectCommand( "SELECT * FROM TX WHERE K=@k", new SpannerParameterCollection { { "k", _key, SpannerDbType.String } }); using (var reader = await cmd.ExecuteReaderAsync(TimestampBound.OfReadTimestamp(_history[0].Timestamp))) { if (await reader.ReadAsync()) { Assert.Equal(_history[0].Value, reader.GetFieldValue <string>(reader.GetOrdinal("StringValue"))); } } } }
/// <summary> /// Begins a read-only transaction for a Cloud Spanner database using the specified <see cref="TimestampBound"/> /// </summary> /// <param name="databaseFacade">The Cloud Spanner database to begin the transaction on</param> /// <param name="timestampBound">The timestamp to use for the read-only transaction</param> /// <returns>A read-only transaction using the specified <see cref="TimestampBound"/></returns> /// <exception cref="InvalidOperationException">If the database is not a Cloud Spanner database.</exception> public static IDbContextTransaction BeginReadOnlyTransaction([NotNull] this DatabaseFacade databaseFacade, [NotNull] TimestampBound timestampBound) => BeginReadOnlyTransactionAsync(databaseFacade, timestampBound).ResultWithUnwrappedExceptions();
/// <summary> /// Begins a read-only transaction for a Cloud Spanner database using the specified <see cref="TimestampBound"/> /// </summary> /// <param name="databaseFacade">The Cloud Spanner database to begin the transaction on</param> /// <param name="timestampBound">The timestamp to use for the read-only transaction</param> /// <param name="cancellationToken">A <see cref="CancellationToken" /> cancellation token to monitor for the asynchronous operation.</param> /// <returns>A read-only transaction using the specified <see cref="TimestampBound"/></returns> /// <exception cref="InvalidOperationException">If the database is not a Cloud Spanner database.</exception> public static Task <IDbContextTransaction> BeginReadOnlyTransactionAsync([NotNull] this DatabaseFacade databaseFacade, [NotNull] TimestampBound timestampBound, CancellationToken cancellationToken = default) { var transactionManager = databaseFacade.GetService <IDbContextTransactionManager>(); if (transactionManager is SpannerRelationalConnection spannerRelationalConnection) { return(spannerRelationalConnection.BeginReadOnlyTransactionAsync(timestampBound, cancellationToken)); } throw new InvalidOperationException("Read-only transactions can only be started for Spanner databases"); }
/// <summary> /// Begins a read-only transaction with the specified <see cref="TimestampBound"/> on this connection. /// </summary> /// <param name="timestampBound">The read timestamp to use for the transaction</param> /// <param name="cancellationToken">A <see cref="CancellationToken" /> cancellation token to monitor for the asynchronous operation.</param> /// <returns>A read-only transaction that uses the specified <see cref="TimestampBound"/></returns> public async Task <IDbContextTransaction> BeginReadOnlyTransactionAsync(TimestampBound timestampBound, CancellationToken cancellationToken = default) => await UseTransactionAsync(await Connection.BeginReadOnlyTransactionAsync(timestampBound, cancellationToken));
/// <summary> /// Begins a read-only transaction with the specified <see cref="TimestampBound"/> on this connection. /// </summary> /// <param name="timestampBound">The read timestamp to use for the transaction</param> /// <returns>A read-only transaction that uses the specified <see cref="TimestampBound"/></returns> public IDbContextTransaction BeginReadOnlyTransaction(TimestampBound timestampBound) => UseTransaction(Connection.BeginReadOnlyTransaction(timestampBound));
public void Base64RoundTrip(TimestampBound bound) { Assert.Equal(bound, TimestampBound.FromBase64String(bound.ToBase64String())); }