Skip to content

Commit 3eda847

Browse files
committed
feat: Add LastStatement DML option
1 parent 6cbaf7e commit 3eda847

File tree

5 files changed

+74
-12
lines changed

5 files changed

+74
-12
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractReadContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,9 @@ ExecuteSqlRequest.Builder getExecuteSqlRequestBuilder(
696696
if (!isReadOnly()) {
697697
builder.setSeqno(getSeqNo());
698698
}
699+
if (options.hasLastStatementSet()) {
700+
builder.setLastStatement(options.lastStatementSet());
701+
}
699702
builder.setQueryOptions(buildQueryOptions(statement.getQueryOptions()));
700703
builder.setRequestOptions(buildRequestOptions(options));
701704
return builder;
@@ -741,6 +744,9 @@ ExecuteBatchDmlRequest.Builder getExecuteBatchDmlRequestBuilder(
741744
if (selector != null) {
742745
builder.setTransaction(selector);
743746
}
747+
if (options.hasLastStatementSet()) {
748+
builder.setLastStatements(options.lastStatementSet());
749+
}
744750
builder.setSeqno(getSeqNo());
745751
builder.setRequestOptions(buildRequestOptions(options));
746752
return builder;

google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,20 @@ public static DataBoostQueryOption dataBoostEnabled(Boolean dataBoostEnabled) {
212212
return new DataBoostQueryOption(dataBoostEnabled);
213213
}
214214

215+
/**
216+
* If set to true, this option marks the end of the transaction. The transaction should be
217+
* committed or aborted after this statement executes, and attempts to execute any other requests
218+
* against this transaction (including reads and queries) will be rejected. Mixing mutations with
219+
* statements that are marked as the last statement is not allowed.
220+
*
221+
* <p>For DML statements, setting this option may cause some error reporting to be deferred until
222+
* commit time (e.g. validation of unique constraints). Given this, successful execution of a DML
223+
* statement should not be assumed until the transaction commits.
224+
*/
225+
public static LastStatementUpdateOption lastStatementSet(Boolean lastStatementSet) {
226+
return new LastStatementUpdateOption(lastStatementSet);
227+
}
228+
215229
/**
216230
* Specifying this will cause the list operation to start fetching the record from this onwards.
217231
*/
@@ -470,6 +484,8 @@ void appendToOptions(Options options) {
470484
private DecodeMode decodeMode;
471485
private RpcOrderBy orderBy;
472486

487+
private Boolean lastStatementSet;
488+
473489
// Construction is via factory methods below.
474490
private Options() {}
475491

@@ -605,6 +621,14 @@ OrderBy orderBy() {
605621
return orderBy == null ? null : orderBy.proto;
606622
}
607623

624+
boolean hasLastStatementSet() {
625+
return lastStatementSet != null;
626+
}
627+
628+
Boolean lastStatementSet() {
629+
return lastStatementSet;
630+
}
631+
608632
@Override
609633
public String toString() {
610634
StringBuilder b = new StringBuilder();
@@ -661,6 +685,9 @@ public String toString() {
661685
if (orderBy != null) {
662686
b.append("orderBy: ").append(orderBy).append(' ');
663687
}
688+
if (lastStatementSet != null) {
689+
b.append("lastStatementSet: ").append(lastStatementSet).append(' ');
690+
}
664691
return b.toString();
665692
}
666693

@@ -700,7 +727,8 @@ public boolean equals(Object o) {
700727
&& Objects.equals(withExcludeTxnFromChangeStreams(), that.withExcludeTxnFromChangeStreams())
701728
&& Objects.equals(dataBoostEnabled(), that.dataBoostEnabled())
702729
&& Objects.equals(directedReadOptions(), that.directedReadOptions())
703-
&& Objects.equals(orderBy(), that.orderBy());
730+
&& Objects.equals(orderBy(), that.orderBy())
731+
&& Objects.equals(lastStatementSet(), that.lastStatementSet());
704732
}
705733

706734
@Override
@@ -760,6 +788,9 @@ public int hashCode() {
760788
if (orderBy != null) {
761789
result = 31 * result + orderBy.hashCode();
762790
}
791+
if (lastStatementSet != null) {
792+
result = 31 * result + lastStatementSet.hashCode();
793+
}
763794
return result;
764795
}
765796

@@ -912,4 +943,18 @@ public boolean equals(Object o) {
912943
return Objects.equals(filter, ((FilterOption) o).filter);
913944
}
914945
}
946+
947+
static final class LastStatementUpdateOption extends InternalOption implements UpdateOption {
948+
949+
private final Boolean lastStatementSet;
950+
951+
LastStatementUpdateOption(Boolean lastStatementSet) {
952+
this.lastStatementSet = lastStatementSet;
953+
}
954+
955+
@Override
956+
void appendToOptions(Options options) {
957+
options.lastStatementSet = lastStatementSet;
958+
}
959+
}
915960
}

samples/install-without-bom/pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@
3333
<dependency>
3434
<groupId>com.google.cloud</groupId>
3535
<artifactId>google-cloud-spanner</artifactId>
36-
<version>6.81.1</version>
36+
<version>6.83.1-SNAPSHOT</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>com.google.api.grpc</groupId>
40+
<artifactId>proto-google-cloud-spanner-v1</artifactId>
41+
<version>6.83.1-SNAPSHOT</version>
3742
</dependency>
3843
<!-- [END spanner_install_without_bom] -->
3944

samples/snippets/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@
4545
<dependency>
4646
<groupId>com.google.cloud</groupId>
4747
<artifactId>google-cloud-spanner</artifactId>
48+
<version>6.83.1-SNAPSHOT</version>
49+
</dependency>
50+
<dependency>
51+
<groupId>com.google.api.grpc</groupId>
52+
<artifactId>proto-google-cloud-spanner-v1</artifactId>
53+
<version>6.83.1-SNAPSHOT</version>
4854
</dependency>
4955
<!-- [END spanner_install_with_bom] -->
5056

samples/snippets/src/main/java/com/example/spanner/SpannerSample.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.cloud.spanner.KeyRange;
3333
import com.google.cloud.spanner.KeySet;
3434
import com.google.cloud.spanner.Mutation;
35+
import com.google.cloud.spanner.Options;
3536
import com.google.cloud.spanner.ReadOnlyTransaction;
3637
import com.google.cloud.spanner.ResultSet;
3738
import com.google.cloud.spanner.Spanner;
@@ -996,15 +997,15 @@ static void queryNestedStructField(DatabaseClient dbClient) {
996997
// [START spanner_dml_standard_insert]
997998
static void insertUsingDml(DatabaseClient dbClient) {
998999
dbClient
999-
.readWriteTransaction()
1000-
.run(transaction -> {
1001-
String sql =
1002-
"INSERT INTO Singers (SingerId, FirstName, LastName) "
1003-
+ " VALUES (10, 'Virginia', 'Watson')";
1004-
long rowCount = transaction.executeUpdate(Statement.of(sql));
1005-
System.out.printf("%d record inserted.\n", rowCount);
1006-
return null;
1007-
});
1000+
.readWriteTransaction()
1001+
.run(transaction -> {
1002+
String sql =
1003+
"INSERT INTO Singers (SingerId, FirstName, LastName) "
1004+
+ " VALUES (10, 'Virginia', 'Watson')";
1005+
long rowCount = transaction.executeUpdate(Statement.of(sql));
1006+
System.out.printf("%d record inserted.\n", rowCount);
1007+
return null;
1008+
});
10081009
}
10091010
// [END spanner_dml_standard_insert]
10101011

@@ -2230,7 +2231,6 @@ public static void main(String[] args) {
22302231
printUsageAndExit();
22312232
}
22322233
// [START init_client]
2233-
SpannerOptions options = SpannerOptions.newBuilder().build();
22342234
Spanner spanner = options.getService();
22352235
DatabaseAdminClient dbAdminClient = null;
22362236
try {

0 commit comments

Comments
 (0)