Skip to content

Commit 3151067

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

File tree

3 files changed

+82
-8
lines changed

3 files changed

+82
-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,62 @@
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.Test;
9+
10+
import java.util.Iterator;
11+
12+
import static org.junit.jupiter.api.Assertions.assertEquals;
13+
import static org.junit.jupiter.api.Assertions.assertTrue;
14+
15+
public class ResultRowsWithTimestampTest extends AbstractOpticUpdateTest {
16+
17+
private final static String NEW_MUSICIAN_JSON = "{\n" +
18+
" \"musician\": {\n" +
19+
" \"lastName\": \"Smith\",\n" +
20+
" \"firstName\": \"Jane\",\n" +
21+
" \"dob\": \"1901-08-04\"\n" +
22+
" }\n" +
23+
"}";
24+
25+
@Test
26+
void testResultRowsWithPointInTimeQueryTimestamp() {
27+
final RawQueryDSLPlan plan = rowManager.newRawQueryDSLPlan(new StringHandle("op.fromView('opticUnitTest', 'musician')"));
28+
29+
JacksonHandle result = new JacksonHandle();
30+
JsonNode doc = rowManager.resultDoc(plan, result).get();
31+
assertEquals(4, doc.get("rows").size(), "Expecting the 4 musicians loaded by test-app to exist");
32+
33+
final long serverTimestamp = result.getServerTimestamp();
34+
assertTrue(serverTimestamp > 0, "Unexpected timestamp: " + serverTimestamp);
35+
36+
// Insert a new musician, which will bump up the server timestamp
37+
String uri = "/acme/newMusician.json";
38+
Common.client.newJSONDocumentManager().write(uri, newDefaultMetadata(), new StringHandle(NEW_MUSICIAN_JSON));
39+
40+
doc = rowManager.resultDoc(plan, new JacksonHandle()).get();
41+
assertEquals(5, doc.get("rows").size(), "Should now get 5 musician rows due to the 5th row being added by " +
42+
"inserting the new musician doc");
43+
44+
// Now verify a point-in-time query works
45+
result = new JacksonHandle();
46+
result.setPointInTimeQueryTimestamp(serverTimestamp);
47+
doc = rowManager.resultDoc(plan, result).get();
48+
assertEquals(4, doc.get("rows").size(), "Only 4 rows should be returned since the query should have been " +
49+
"run at a server timestamp prior to the newMusician doc being inserted.");
50+
51+
// And verify point-in-time works when using resultRows too
52+
result = new JacksonHandle();
53+
result.setPointInTimeQueryTimestamp(serverTimestamp);
54+
Iterator<JacksonHandle> rows = rowManager.resultRows(plan, result).iterator();
55+
int count = 0;
56+
while (rows.hasNext()) {
57+
rows.next();
58+
count++;
59+
}
60+
assertEquals(4, count, "resultRows should honor the point-in-time timestamp, just like resultDoc does");
61+
}
62+
}

0 commit comments

Comments
 (0)