Skip to content

Commit a864272

Browse files
authored
Merge pull request #1657 from marklogic/feature/13687-backup
MLE-13687 Able to use onError in plan builder
2 parents dda3edd + 7b3e825 commit a864272

File tree

4 files changed

+89
-72
lines changed

4 files changed

+89
-72
lines changed

marklogic-client-api/src/main/java/com/marklogic/client/expression/PlanBuilder.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -227,32 +227,6 @@ protected PlanBuilder(
227227
*/
228228
public abstract ServerExpression subtract(ServerExpression left, ServerExpression right);
229229
/**
230-
* Add an error-handler to the Optic Pipeline to catch Optic Update runtime errors. The runtime errors are added in the errors column. If no error occurred the value of the error column is null. When added, the error-handler should be the last operator before op:result.
231-
* @param action The Optic Plan. You can either use the XQuery => chaining operator or specify the variable that captures the return value from the previous operation.
232-
* @return a ModifyPlan object
233-
*/
234-
public abstract ModifyPlan onError(String action);
235-
/**
236-
* Add an error-handler to the Optic Pipeline to catch Optic Update runtime errors. The runtime errors are added in the errors column. If no error occurred the value of the error column is null. When added, the error-handler should be the last operator before op:result.
237-
* @param action The Optic Plan. You can either use the XQuery => chaining operator or specify the variable that captures the return value from the previous operation.
238-
* @return a ModifyPlan object
239-
*/
240-
public abstract ModifyPlan onError(XsStringVal action);
241-
/**
242-
* Add an error-handler to the Optic Pipeline to catch Optic Update runtime errors. The runtime errors are added in the errors column. If no error occurred the value of the error column is null. When added, the error-handler should be the last operator before op:result.
243-
* @param action The Optic Plan. You can either use the XQuery => chaining operator or specify the variable that captures the return value from the previous operation.
244-
* @param errorColumn Valid options are: "fail" - stop procesisng and "continue" - add an error to the error column and continue processing. See {@link PlanBuilder#col(XsStringVal)}
245-
* @return a ModifyPlan object
246-
*/
247-
public abstract ModifyPlan onError(String action, String errorColumn);
248-
/**
249-
* Add an error-handler to the Optic Pipeline to catch Optic Update runtime errors. The runtime errors are added in the errors column. If no error occurred the value of the error column is null. When added, the error-handler should be the last operator before op:result.
250-
* @param action The Optic Plan. You can either use the XQuery => chaining operator or specify the variable that captures the return value from the previous operation.
251-
* @param errorColumn Valid options are: "fail" - stop procesisng and "continue" - add an error to the error column and continue processing. See {@link PlanBuilder#col(XsStringVal)}
252-
* @return a ModifyPlan object
253-
*/
254-
public abstract ModifyPlan onError(XsStringVal action, PlanExprCol errorColumn);
255-
/**
256230
* Create a patch builder which can be used to chain patch operations.
257231
* @param contextPath The context path to patch.
258232
* @return a PatchBuilder object
@@ -1805,6 +1779,32 @@ public interface ModifyPlan extends PreparePlan, PlanBuilderBase.ModifyPlanBase
18051779
* @return a ModifyPlan object
18061780
*/
18071781
public abstract ModifyPlan orderBy(PlanSortKeySeq keys);
1782+
/**
1783+
* Add an error-handler to the Optic Pipeline to catch Optic Update runtime errors. The runtime errors are added in the errors column. If no error occurred the value of the error column is null. When added, the error-handler should be the last operator before op:result.
1784+
* @param action Valid options are: "fail" - stop procesisng and "continue" - add an error to the error column and continue processing.
1785+
* @return a ModifyPlan object
1786+
*/
1787+
public abstract ModifyPlan onError(String action);
1788+
/**
1789+
* Add an error-handler to the Optic Pipeline to catch Optic Update runtime errors. The runtime errors are added in the errors column. If no error occurred the value of the error column is null. When added, the error-handler should be the last operator before op:result.
1790+
* @param action Valid options are: "fail" - stop procesisng and "continue" - add an error to the error column and continue processing.
1791+
* @return a ModifyPlan object
1792+
*/
1793+
public abstract ModifyPlan onError(XsStringVal action);
1794+
/**
1795+
* Add an error-handler to the Optic Pipeline to catch Optic Update runtime errors. The runtime errors are added in the errors column. If no error occurred the value of the error column is null. When added, the error-handler should be the last operator before op:result.
1796+
* @param action Valid options are: "fail" - stop procesisng and "continue" - add an error to the error column and continue processing.
1797+
* @param errorColumn An optional error column which is not used in the plan. If this parameter is not passed in 'sys.errors' is used. See {@link PlanBuilder#col(XsStringVal)}
1798+
* @return a ModifyPlan object
1799+
*/
1800+
public abstract ModifyPlan onError(String action, String errorColumn);
1801+
/**
1802+
* Add an error-handler to the Optic Pipeline to catch Optic Update runtime errors. The runtime errors are added in the errors column. If no error occurred the value of the error column is null. When added, the error-handler should be the last operator before op:result.
1803+
* @param action Valid options are: "fail" - stop procesisng and "continue" - add an error to the error column and continue processing.
1804+
* @param errorColumn An optional error column which is not used in the plan. If this parameter is not passed in 'sys.errors' is used. See {@link PlanBuilder#col(XsStringVal)}
1805+
* @return a ModifyPlan object
1806+
*/
1807+
public abstract ModifyPlan onError(XsStringVal action, PlanExprCol errorColumn);
18081808
/**
18091809
* Builds a patch operation including a sequence of inserts, replaces, replace-inserts and deletes.
18101810
* @param docColumn The document column which need to be patched. See {@link PlanBuilder#col(XsStringVal)}

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

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -856,36 +856,6 @@ public PlanJoinKey on(PlanExprCol left, PlanExprCol right) {
856856
}
857857

858858

859-
@Override
860-
public ModifyPlan onError(String action) {
861-
return onError((action == null) ? (XsStringVal) null : xs.string(action));
862-
}
863-
864-
865-
@Override
866-
public ModifyPlan onError(XsStringVal action) {
867-
if (action == null) {
868-
throw new IllegalArgumentException("action parameter for onError() cannot be null");
869-
}
870-
return new PlanBuilderSubImpl.ModifyPlanSubImpl("op", "on-error", new Object[]{ action });
871-
}
872-
873-
874-
@Override
875-
public ModifyPlan onError(String action, String errorColumn) {
876-
return onError((action == null) ? (XsStringVal) null : xs.string(action), (errorColumn == null) ? (PlanExprCol) null : exprCol(errorColumn));
877-
}
878-
879-
880-
@Override
881-
public ModifyPlan onError(XsStringVal action, PlanExprCol errorColumn) {
882-
if (action == null) {
883-
throw new IllegalArgumentException("action parameter for onError() cannot be null");
884-
}
885-
return new PlanBuilderSubImpl.ModifyPlanSubImpl("op", "on-error", new Object[]{ action, errorColumn });
886-
}
887-
888-
889859
@Override
890860
public ServerExpression or(ServerExpression... left) {
891861
if (left == null) {
@@ -2170,6 +2140,36 @@ public ModifyPlan notExistsJoin(ModifyPlan right, PlanJoinKeySeq keys, ServerExp
21702140
}
21712141

21722142

2143+
@Override
2144+
public ModifyPlan onError(String action) {
2145+
return onError((action == null) ? (XsStringVal) null : xs.string(action));
2146+
}
2147+
2148+
2149+
@Override
2150+
public ModifyPlan onError(XsStringVal action) {
2151+
if (action == null) {
2152+
throw new IllegalArgumentException("action parameter for onError() cannot be null");
2153+
}
2154+
return new PlanBuilderSubImpl.ModifyPlanSubImpl(this, "op", "on-error", new Object[]{ action });
2155+
}
2156+
2157+
2158+
@Override
2159+
public ModifyPlan onError(String action, String errorColumn) {
2160+
return onError((action == null) ? (XsStringVal) null : xs.string(action), (errorColumn == null) ? (PlanExprCol) null : exprCol(errorColumn));
2161+
}
2162+
2163+
2164+
@Override
2165+
public ModifyPlan onError(XsStringVal action, PlanExprCol errorColumn) {
2166+
if (action == null) {
2167+
throw new IllegalArgumentException("action parameter for onError() cannot be null");
2168+
}
2169+
return new PlanBuilderSubImpl.ModifyPlanSubImpl(this, "op", "on-error", new Object[]{ action, errorColumn });
2170+
}
2171+
2172+
21732173
@Override
21742174
public ModifyPlan orderBy(PlanSortKeySeq keys) {
21752175
if (keys == null) {

marklogic-client-api/src/test/java/com/marklogic/client/test/rows/OpticPatchTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import com.marklogic.client.io.JacksonHandle;
99
import com.marklogic.client.io.StringHandle;
1010
import com.marklogic.client.test.Common;
11+
import com.marklogic.client.test.junit5.RequiresML11;
1112
import org.junit.jupiter.api.BeforeEach;
1213
import org.junit.jupiter.api.Test;
14+
import org.junit.jupiter.api.extension.ExtendWith;
1315

1416
import java.util.HashMap;
1517
import java.util.Map;
@@ -21,6 +23,7 @@
2123
* These tests are not intended to be great examples of how to use patch operations, but
2224
* rather to provide some test coverage.
2325
*/
26+
@ExtendWith(RequiresML11.class)
2427
public class OpticPatchTest extends AbstractOpticUpdateTest {
2528

2629
private static final String JSON_URI = "/a.json";
@@ -129,7 +132,7 @@ void replaceInsertChild() {
129132
)).get(0).getContent("doc", new StringHandle()).get();
130133

131134
System.out.println(content);
132-
assertTrue(content.contains("<parent xmlns=\"org:example\"><child>1</child>new text</parent>"),
135+
assertTrue(content.contains("<parent xmlns=\"org:example\">new text</parent>"),
133136
"Unexpected content: " + content);
134137
}
135138

marklogic-client-api/src/test/java/com/marklogic/client/test/rows/ValidateDocTest.java

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.marklogic.client.test.rows;
1717

18+
import com.fasterxml.jackson.databind.JsonNode;
1819
import com.fasterxml.jackson.databind.node.ObjectNode;
1920
import com.marklogic.client.FailedRequestException;
2021
import com.marklogic.client.datamovement.DataMovementManager;
@@ -25,6 +26,7 @@
2526
import com.marklogic.client.expression.PlanBuilder;
2627
import com.marklogic.client.io.DocumentMetadataHandle;
2728
import com.marklogic.client.io.Format;
29+
import com.marklogic.client.io.JacksonHandle;
2830
import com.marklogic.client.io.StringHandle;
2931
import com.marklogic.client.row.RowRecord;
3032
import com.marklogic.client.test.Common;
@@ -83,6 +85,9 @@ public void testXmlSchemaWithLaxMode() {
8385
expectedUris.forEach(uri -> assertTrue(persistedUris.contains(uri), "persistedUris does not contain " + uri));
8486
}
8587

88+
/**
89+
* Shoehorning some test coverage of onError for the 11.2 server release into this test.
90+
*/
8691
@Test
8792
public void testXmlSchemaWithStrictMode() {
8893
String[][] triples = new String[][]{
@@ -94,11 +99,11 @@ public void testXmlSchemaWithStrictMode() {
9499

95100
String triplesXML =
96101
"<sem:triples xmlns:sem=\"http://marklogic.com/semantics\">\n" +
97-
String.join("\n", (String[]) Arrays
102+
String.join("\n", Arrays
98103
.stream(triples)
99104
.map(triple ->
100105
"<sem:triple>" +
101-
"<sem:subject>" + triple[0] + "</sem:subject>" +
106+
"<sem:subjectt>" + triple[0] + "</sem:subjectt>" +
102107
"<sem:predicate>" + triple[1] + "</sem:predicate>" +
103108
"<sem:object>" + triple[2] + "</sem:object>" +
104109
"</sem:triple>"
@@ -112,21 +117,30 @@ public void testXmlSchemaWithStrictMode() {
112117
}
113118
docMgr.write(writeSet);
114119

115-
PlanBuilder.Plan plan = op
120+
PlanBuilder.ModifyPlan plan = op
116121
.fromDocUris(op.cts.directoryQuery("/acme/"))
117122
.joinDoc(op.col("doc"), op.col("uri"))
118-
.validateDoc(op.col("doc"),
119-
op.schemaDefinition("xmlSchema").withMode("strict")
120-
);
121-
Iterator<RowRecord> rows = rowManager.resultRows(plan).iterator();
122-
Set<String> uris = new HashSet<>();
123-
while (rows.hasNext()) {
124-
uris.add(rows.next().getString("uri"));
125-
}
126-
assertTrue(uris.size() == 4);
127-
for (int i = 0; i < 4; i++) {
128-
assertTrue(uris.contains("/acme/" + i + ".xml"), "uris does not contain /acme/" + i + ".xml");
129-
}
123+
.validateDoc(op.col("doc"), op.schemaDefinition("xmlSchema").withMode("strict"));
124+
125+
// Verify that "continue" results in errors being returned.
126+
final String defaultErrorsColumn = "sys.errors";
127+
resultRows(plan.onError("continue")).forEach(row -> {
128+
JsonNode errors = row.getContent(defaultErrorsColumn, new JacksonHandle()).get();
129+
assertEquals("Validation error", errors.get("message").asText());
130+
assertTrue(errors.has("data"));
131+
String errorMessage = errors.get("data").get(0).asText();
132+
assertTrue(errorMessage.contains("Found sem:subjectt but expected"), "Unexpected error: " + errorMessage);
133+
});
134+
135+
// And verify a custom error column works.
136+
resultRows(plan.onError("continue", "myErrors")).forEach(row -> {
137+
JsonNode errors = row.getContent("myErrors", new JacksonHandle()).get();
138+
assertEquals("Validation error", errors.get("message").asText());
139+
});
140+
141+
// "fail" should throw an error.
142+
FailedRequestException ex = assertThrows(FailedRequestException.class, () -> resultRows(plan.onError("fail")));
143+
assertTrue(ex.getMessage().contains("Found sem:subjectt but expected"), "Unexpected error: " + ex.getMessage());
130144
}
131145

132146
@Test

0 commit comments

Comments
 (0)