private TimestampBound getRandomBound() { Date date = new Date(); switch (RANDOM.nextInt(3)) { case 0: return TimestampBound.strong(); case 1: return TimestampBound.ofExactStaleness(STALENESS_MILLISEC, TimeUnit.MILLISECONDS); default: return TimestampBound.ofReadTimestamp( Timestamp.of(new Date(date.getTime() - STALENESS_MILLISEC))); } }
@Test public void readTimestamp() { Timestamp ts = Timestamp.ofTimeSecondsAndNanos(TEST_TIME_SECONDS, 0); TimestampBound bound = TimestampBound.ofReadTimestamp(ts); assertThat(bound.getMode()).isEqualTo(Mode.READ_TIMESTAMP); assertThat(bound.getReadTimestamp()).isEqualTo(ts); assertThat(bound.toString()).isEqualTo("exact_timestamp: " + TEST_TIME_ISO); assertProto(bound, "read_timestamp { seconds: " + TEST_TIME_SECONDS + " }"); }
@Test public void singleReadTimestamp() { History expected = history.get(2); TimestampBound bound = TimestampBound.ofReadTimestamp(expected.timestamp); ReadOnlyTransaction readContext = client.singleUseReadOnlyTransaction(bound); Struct row = readRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isEqualTo(expected.timestamp); row = readRow(client.singleUse(bound)); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); }
@Test public void multiReadTimestamp() { setUpPrivateDatabase(); History expected = history.get(2); try (ReadOnlyTransaction readContext = client.readOnlyTransaction(TimestampBound.ofReadTimestamp(expected.timestamp))) { Struct row = readRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isEqualTo(expected.timestamp); insertAndReadAgain(readContext, readContext.getReadTimestamp(), expected.value); } }
@Test public void query() { // We don't exhaustively test query with all modes - the read tests give us enough confidence // that transaction options are generated appropriately. Just do one test for each type of // context to ensure that transaction options are set at all. History expected = history.get(2); TimestampBound bound = TimestampBound.ofReadTimestamp(expected.timestamp); ReadOnlyTransaction readContext = client.singleUseReadOnlyTransaction(bound); Struct row = queryRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isEqualTo(expected.timestamp); readContext = client.readOnlyTransaction(bound); row = queryRow(readContext); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); assertThat(readContext.getReadTimestamp()).isEqualTo(expected.timestamp); readContext.close(); row = queryRow(client.singleUse(bound)); assertThat(row).isNotNull(); assertThat(row.getString(0)).isEqualTo(expected.value); }
@Test public void equalsAndHashCode() { Timestamp ts = Timestamp.ofTimeSecondsAndNanos(1444662894L, 0); Timestamp ts2 = Timestamp.ofTimeSecondsAndNanos(1444662895L, 0); int staleness = 5; EqualsTester tester = new EqualsTester(); tester.addEqualityGroup(TimestampBound.strong(), TimestampBound.strong()); tester.addEqualityGroup(TimestampBound.ofReadTimestamp(ts), TimestampBound.ofReadTimestamp(ts)); tester.addEqualityGroup(TimestampBound.ofReadTimestamp(ts2)); tester.addEqualityGroup( TimestampBound.ofMinReadTimestamp(ts), TimestampBound.ofMinReadTimestamp(ts)); tester.addEqualityGroup(TimestampBound.ofMinReadTimestamp(ts2)); tester.addEqualityGroup( TimestampBound.ofExactStaleness(staleness, TimeUnit.SECONDS), TimestampBound.ofExactStaleness(staleness, TimeUnit.SECONDS)); tester.addEqualityGroup(TimestampBound.ofExactStaleness(staleness, TimeUnit.MILLISECONDS)); tester.addEqualityGroup( TimestampBound.ofMaxStaleness(staleness, TimeUnit.SECONDS), TimestampBound.ofMaxStaleness(staleness, TimeUnit.SECONDS)); tester.addEqualityGroup(TimestampBound.ofMaxStaleness(staleness, TimeUnit.MILLISECONDS)); tester.testEquals(); }
@Test public void serialization() throws Exception { reserializeAndAssert(TimestampBound.strong()); reserializeAndAssert(TimestampBound.ofExactStaleness(10, TimeUnit.NANOSECONDS)); reserializeAndAssert(TimestampBound.ofMaxStaleness(100, TimeUnit.DAYS)); reserializeAndAssert(TimestampBound.ofMinReadTimestamp(Timestamp.now())); reserializeAndAssert(TimestampBound.ofReadTimestamp(Timestamp.now())); }
public Read withTimestamp(Timestamp timestamp) { return withTimestampBound(TimestampBound.ofReadTimestamp(timestamp)); }
public ReadAll withTimestamp(Timestamp timestamp) { return withTimestampBound(TimestampBound.ofReadTimestamp(timestamp)); }
protected ReadContext getReadContext(Timestamp timestamp) { return doWithOrWithoutTransactionContext((x) -> x, () -> this.databaseClient.singleUse(TimestampBound.ofReadTimestamp(timestamp))); }
protected ReadContext getReadContext(Timestamp timestamp) { return doWithOrWithoutTransactionContext((x) -> x, () -> this.databaseClient.singleUse(TimestampBound.ofReadTimestamp(timestamp))); }
@Override public <T> T performReadOnlyTransaction(Function<SpannerTemplate, T> operations, SpannerReadOptions readOptions) { return doWithOrWithoutTransactionContext((x) -> { throw new IllegalStateException("There is already declarative transaction open. " + "Spanner does not support nested transactions"); }, () -> { SpannerReadOptions options = (readOptions != null) ? readOptions : new SpannerReadOptions(); try (ReadOnlyTransaction readOnlyTransaction = (options.getTimestamp() != null) ? this.databaseClient.readOnlyTransaction( TimestampBound.ofReadTimestamp(options.getTimestamp())) : this.databaseClient.readOnlyTransaction()) { return operations.apply(new ReadOnlyTransactionSpannerTemplate( SpannerTemplate.this.databaseClient, SpannerTemplate.this.mappingContext, SpannerTemplate.this.spannerEntityProcessor, SpannerTemplate.this.mutationFactory, SpannerTemplate.this.spannerSchemaUtils, readOnlyTransaction)); } }); }
@Override public <T> T performReadOnlyTransaction(Function<SpannerTemplate, T> operations, SpannerReadOptions readOptions) { return doWithOrWithoutTransactionContext((x) -> { throw new IllegalStateException("There is already declarative transaction open. " + "Spanner does not support nested transactions"); }, () -> { SpannerReadOptions options = (readOptions != null) ? readOptions : new SpannerReadOptions(); try (ReadOnlyTransaction readOnlyTransaction = (options.getTimestamp() != null) ? this.databaseClient.readOnlyTransaction( TimestampBound.ofReadTimestamp(options.getTimestamp())) : this.databaseClient.readOnlyTransaction()) { return operations.apply(new ReadOnlyTransactionSpannerTemplate( SpannerTemplate.this.databaseClient, SpannerTemplate.this.mappingContext, SpannerTemplate.this.spannerEntityProcessor, SpannerTemplate.this.mutationFactory, SpannerTemplate.this.spannerSchemaUtils, readOnlyTransaction)); } }); }
@Test public void readPipeline() throws Exception { Timestamp timestamp = Timestamp.ofTimeMicroseconds(12345); TimestampBound timestampBound = TimestampBound.ofReadTimestamp(timestamp);
@Test public void readAllPipeline() throws Exception { Timestamp timestamp = Timestamp.ofTimeMicroseconds(12345); TimestampBound timestampBound = TimestampBound.ofReadTimestamp(timestamp);