Skip to content

Commit c89f1d5

Browse files
committed
DEVEXP-460 resultRows now honors point-in-time query timestamp
1 parent 2fb75e9 commit c89f1d5

File tree

3 files changed

+89
-8
lines changed

3 files changed

+89
-8
lines changed

marklogic-client-api/src/main/java/com/marklogic/client/impl/RowManagerImpl.java

+12-7
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ public void execute(Plan plan, Transaction transaction) {
226226

227227
@Override
228228
public <T extends StructureReadHandle> RowSet<T> resultRows(Plan plan, T rowHandle) {
229-
return resultRows(plan, rowHandle, (Transaction) null);
229+
return resultRows(plan, rowHandle, null);
230230
}
231231

232232
@Override
@@ -236,13 +236,18 @@ public <T extends StructureReadHandle> RowSet<T> resultRows(Plan plan, T rowHand
236236
String rowFormat = getRowFormat(rowHandle);
237237

238238
PlanBuilderBaseImpl.RequestPlan requestPlan = checkPlan(plan);
239-
RequestParameters params = newRowsParamsBuilder(requestPlan)
240-
.withRowFormat(rowFormat)
241-
.withNodeColumns("inline")
242-
.withColumnTypes(datatypeStyle)
243-
.withOutput(rowStructureStyle)
244-
.getRequestParameters();
245239

240+
RowsParamsBuilder rowsParamsBuilder = newRowsParamsBuilder(requestPlan)
241+
.withRowFormat(rowFormat)
242+
.withNodeColumns("inline")
243+
.withColumnTypes(datatypeStyle)
244+
.withOutput(rowStructureStyle);
245+
246+
if (rowHandle instanceof BaseHandle) {
247+
rowsParamsBuilder.withTimestamp(((BaseHandle)rowHandle).getPointInTimeQueryTimestamp());
248+
}
249+
250+
RequestParameters params = rowsParamsBuilder.getRequestParameters();
246251
RESTServiceResultIterator iter = submitPlan(requestPlan, params, transaction);
247252
RowSetHandle<T> rowset = new RowSetHandle<>(rowFormat, datatypeStyle, rowStructureStyle, iter, rowHandle);
248253
rowset.init();

marklogic-client-api/src/main/java/com/marklogic/client/impl/RowsParamsBuilder.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,14 @@ public RowsParamsBuilder withTraceLabel(String label) {
9191
return this;
9292
}
9393

94+
public RowsParamsBuilder withTimestamp(long serverTimestamp) {
95+
if (serverTimestamp > 0) {
96+
params.add("timestamp", serverTimestamp + "");
97+
}
98+
return this;
99+
}
100+
94101
public RequestParameters getRequestParameters() {
95102
return this.params;
96103
}
97-
}
104+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.marklogic.client.test.rows;
2+
3+
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.marklogic.client.io.JacksonHandle;
5+
import com.marklogic.client.io.StringHandle;
6+
import com.marklogic.client.row.RawQueryDSLPlan;
7+
import com.marklogic.client.test.Common;
8+
import org.junit.jupiter.api.AfterEach;
9+
import org.junit.jupiter.api.Test;
10+
11+
import java.util.Iterator;
12+
13+
import static org.junit.jupiter.api.Assertions.assertEquals;
14+
import static org.junit.jupiter.api.Assertions.assertTrue;
15+
16+
public class ResultRowsWithTimestampTest extends AbstractOpticUpdateTest {
17+
18+
private final static String NEW_MUSICIAN_URI = "/test/newMusician.json";
19+
20+
private final static String NEW_MUSICIAN_JSON = "{\n" +
21+
" \"musician\": {\n" +
22+
" \"lastName\": \"Smith\",\n" +
23+
" \"firstName\": \"Jane\",\n" +
24+
" \"dob\": \"1901-08-04\"\n" +
25+
" }\n" +
26+
"}";
27+
28+
@AfterEach
29+
void deleteNewMusician() {
30+
Common.client.newJSONDocumentManager().delete(NEW_MUSICIAN_URI);
31+
}
32+
33+
@Test
34+
void testResultRowsWithPointInTimeQueryTimestamp() {
35+
final RawQueryDSLPlan plan = rowManager.newRawQueryDSLPlan(new StringHandle("op.fromView('opticUnitTest', 'musician')"));
36+
37+
JacksonHandle result = new JacksonHandle();
38+
JsonNode doc = rowManager.resultDoc(plan, result).get();
39+
assertEquals(4, doc.get("rows").size(), "Expecting the 4 musicians loaded by test-app to exist");
40+
41+
final long serverTimestamp = result.getServerTimestamp();
42+
assertTrue(serverTimestamp > 0, "Unexpected timestamp: " + serverTimestamp);
43+
44+
// Insert a new musician, which will bump up the server timestamp
45+
Common.client.newJSONDocumentManager().write(NEW_MUSICIAN_URI, newDefaultMetadata(), new StringHandle(NEW_MUSICIAN_JSON));
46+
47+
doc = rowManager.resultDoc(plan, new JacksonHandle()).get();
48+
assertEquals(5, doc.get("rows").size(), "Should now get 5 musician rows due to the 5th row being added by " +
49+
"inserting the new musician doc");
50+
51+
// Now verify a point-in-time query works
52+
result = new JacksonHandle();
53+
result.setPointInTimeQueryTimestamp(serverTimestamp);
54+
doc = rowManager.resultDoc(plan, result).get();
55+
assertEquals(4, doc.get("rows").size(), "Only 4 rows should be returned since the query should have been " +
56+
"run at a server timestamp prior to the newMusician doc being inserted.");
57+
58+
// And verify point-in-time works when using resultRows too
59+
result = new JacksonHandle();
60+
result.setPointInTimeQueryTimestamp(serverTimestamp);
61+
Iterator<JacksonHandle> rows = rowManager.resultRows(plan, result).iterator();
62+
int count = 0;
63+
while (rows.hasNext()) {
64+
rows.next();
65+
count++;
66+
}
67+
assertEquals(4, count, "resultRows should honor the point-in-time timestamp, just like resultDoc does");
68+
}
69+
}

0 commit comments

Comments
 (0)