160
160
import com .google .spanner .v1 .CommitResponse ;
161
161
import com .google .spanner .v1 .CreateSessionRequest ;
162
162
import com .google .spanner .v1 .DeleteSessionRequest ;
163
+ import com .google .spanner .v1 .DirectedReadOptions ;
163
164
import com .google .spanner .v1 .ExecuteBatchDmlRequest ;
164
165
import com .google .spanner .v1 .ExecuteBatchDmlResponse ;
165
166
import com .google .spanner .v1 .ExecuteSqlRequest ;
@@ -304,6 +305,7 @@ private void awaitTermination() throws InterruptedException {
304
305
private static final double ADMINISTRATIVE_REQUESTS_RATE_LIMIT = 1.0D ;
305
306
private static final ConcurrentMap <String , RateLimiter > ADMINISTRATIVE_REQUESTS_RATE_LIMITERS =
306
307
new ConcurrentHashMap <>();
308
+ private final DirectedReadOptions directedReadOptions ;
307
309
308
310
public static GapicSpannerRpc create (SpannerOptions options ) {
309
311
return new GapicSpannerRpc (options );
@@ -354,6 +356,7 @@ public GapicSpannerRpc(final SpannerOptions options) {
354
356
internalHeaderProviderBuilder .getResourceHeaderKey ());
355
357
this .callCredentialsProvider = options .getCallCredentialsProvider ();
356
358
this .compressorName = options .getCompressorName ();
359
+ this .directedReadOptions = options .getDirectedReadOptions ();
357
360
358
361
if (initializeStubs ) {
359
362
// Create a managed executor provider.
@@ -1636,7 +1639,11 @@ public ApiFuture<Empty> asyncDeleteSession(String sessionName, @Nullable Map<Opt
1636
1639
1637
1640
@ Override
1638
1641
public StreamingCall read (
1639
- ReadRequest request , ResultStreamConsumer consumer , @ Nullable Map <Option , ?> options ) {
1642
+ ReadRequest request ,
1643
+ ResultStreamConsumer consumer ,
1644
+ @ Nullable Map <Option , ?> options ,
1645
+ boolean readOnly ) {
1646
+ request = validateReadRequest (request , readOnly );
1640
1647
GrpcCallContext context =
1641
1648
newCallContext (options , request .getSession (), request , SpannerGrpc .getReadMethod ());
1642
1649
SpannerResponseObserver responseObserver = new SpannerResponseObserver (consumer );
@@ -1658,13 +1665,15 @@ public void cancel(String message) {
1658
1665
}
1659
1666
1660
1667
@ Override
1661
- public ResultSet executeQuery (ExecuteSqlRequest request , @ Nullable Map <Option , ?> options ) {
1662
- return get (executeQueryAsync (request , options ));
1668
+ public ResultSet executeQuery (
1669
+ ExecuteSqlRequest request , @ Nullable Map <Option , ?> options , boolean readOnly ) {
1670
+ return get (executeQueryAsync (request , options , readOnly ));
1663
1671
}
1664
1672
1665
1673
@ Override
1666
1674
public ApiFuture <ResultSet > executeQueryAsync (
1667
- ExecuteSqlRequest request , @ Nullable Map <Option , ?> options ) {
1675
+ ExecuteSqlRequest request , @ Nullable Map <Option , ?> options , boolean readOnly ) {
1676
+ request = validateExecuteSqlRequest (request , readOnly );
1668
1677
GrpcCallContext context =
1669
1678
newCallContext (options , request .getSession (), request , SpannerGrpc .getExecuteSqlMethod ());
1670
1679
return spannerStub .executeSqlCallable ().futureCall (request , context );
@@ -1673,6 +1682,7 @@ public ApiFuture<ResultSet> executeQueryAsync(
1673
1682
@ Override
1674
1683
public ResultSet executePartitionedDml (
1675
1684
ExecuteSqlRequest request , @ Nullable Map <Option , ?> options ) {
1685
+ request = validateExecuteSqlRequest (request , false );
1676
1686
GrpcCallContext context =
1677
1687
newCallContext (options , request .getSession (), request , SpannerGrpc .getExecuteSqlMethod ());
1678
1688
return get (partitionedDmlStub .executeSqlCallable ().futureCall (request , context ));
@@ -1686,6 +1696,7 @@ public RetrySettings getPartitionedDmlRetrySettings() {
1686
1696
@ Override
1687
1697
public ServerStream <PartialResultSet > executeStreamingPartitionedDml (
1688
1698
ExecuteSqlRequest request , Map <Option , ?> options , Duration timeout ) {
1699
+ request = validateExecuteSqlRequest (request , false );
1689
1700
GrpcCallContext context =
1690
1701
newCallContext (
1691
1702
options , request .getSession (), request , SpannerGrpc .getExecuteStreamingSqlMethod ());
@@ -1696,7 +1707,11 @@ public ServerStream<PartialResultSet> executeStreamingPartitionedDml(
1696
1707
1697
1708
@ Override
1698
1709
public StreamingCall executeQuery (
1699
- ExecuteSqlRequest request , ResultStreamConsumer consumer , @ Nullable Map <Option , ?> options ) {
1710
+ ExecuteSqlRequest request ,
1711
+ ResultStreamConsumer consumer ,
1712
+ @ Nullable Map <Option , ?> options ,
1713
+ boolean readOnly ) {
1714
+ request = validateExecuteSqlRequest (request , readOnly );
1700
1715
GrpcCallContext context =
1701
1716
newCallContext (
1702
1717
options , request .getSession (), request , SpannerGrpc .getExecuteStreamingSqlMethod ());
@@ -2014,4 +2029,32 @@ private static Duration systemProperty(String name, int defaultValue) {
2014
2029
String stringValue = System .getProperty (name , "" );
2015
2030
return Duration .ofSeconds (stringValue .isEmpty () ? defaultValue : Integer .parseInt (stringValue ));
2016
2031
}
2032
+
2033
+ private ExecuteSqlRequest validateExecuteSqlRequest (ExecuteSqlRequest request , boolean readOnly ) {
2034
+ if (!readOnly ) {
2035
+ if (request .hasDirectedReadOptions () || (directedReadOptions != null )) {
2036
+ throw SpannerExceptionFactory .newSpannerException (
2037
+ ErrorCode .FAILED_PRECONDITION ,
2038
+ "DirectedReadOptions can't be set for Read-Write or Partitioned DML transactions" );
2039
+ }
2040
+ }
2041
+ if (directedReadOptions != null ) {
2042
+ request = request .toBuilder ().setDirectedReadOptions (directedReadOptions ).build ();
2043
+ }
2044
+ return request ;
2045
+ }
2046
+
2047
+ private ReadRequest validateReadRequest (ReadRequest request , boolean readOnly ) {
2048
+ if (!readOnly ) {
2049
+ if (request .hasDirectedReadOptions () || (directedReadOptions != null )) {
2050
+ throw SpannerExceptionFactory .newSpannerException (
2051
+ ErrorCode .FAILED_PRECONDITION ,
2052
+ "DirectedReadOptions can't be set for Read-Write or Partitioned DML transactions" );
2053
+ }
2054
+ }
2055
+ if (directedReadOptions != null ) {
2056
+ request = request .toBuilder ().setDirectedReadOptions (directedReadOptions ).build ();
2057
+ }
2058
+ return request ;
2059
+ }
2017
2060
}
0 commit comments