diff --git a/src/main/java/com/fauna/response/ConstraintFailure.java b/src/main/java/com/fauna/response/ConstraintFailure.java
index 253ae492..f01a9481 100644
--- a/src/main/java/com/fauna/response/ConstraintFailure.java
+++ b/src/main/java/com/fauna/response/ConstraintFailure.java
@@ -9,71 +9,45 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
-public class ConstraintFailure {
+public final class ConstraintFailure {
private final String message;
private final String name;
private final PathElement[][] paths;
- public ConstraintFailure(String message, String name,
- PathElement[][] paths) {
+ /**
+ * Initialize a new ConstraintFailure instance. Queries that fail a check
+ * or unique
+ * constraint> return a constraint failure.
+ *
+ * @param message Human-readable description of the constraint failure.
+ * @param name Name of the failed constraint.
+ * @param paths A list of paths where the constraint failure occurred.
+ */
+ public ConstraintFailure(
+ final String message,
+ final String name,
+ final PathElement[][] paths) {
this.message = message;
this.name = name;
this.paths = paths;
}
- public static class PathElement {
- private String sVal = null;
- private Integer iVal = null;
-
- public PathElement(String sVal) {
- this.sVal = sVal;
- }
-
- public PathElement(Integer iVal) {
- this.iVal = iVal;
- }
-
- public boolean isString() {
- return sVal != null;
- }
-
- /**
- * Note that this parse method does not advance the parser.
- *
- * @param parser A JsonParser instance.
- * @return A new PathElement.
- * @throws IOException Can be thrown if e.g. stream ends.
- */
- public static PathElement parse(JsonParser parser) throws IOException {
- if (parser.currentToken().isNumeric()) {
- return new PathElement(parser.getValueAsInt());
- } else {
- return new PathElement(parser.getText());
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof PathElement) {
- PathElement other = (PathElement) o;
- return other.isString() == this.isString() &&
- other.toString().equals(this.toString());
- } else {
- return false;
- }
- }
-
- public String toString() {
- return sVal == null ? String.valueOf(iVal) : sVal;
- }
- }
-
- public static PathElement[] createPath(Object... elements) {
+ /**
+ * Constructs a PathElement[] from the provided objects. Supported types
+ * are String and Integer.
+ *
+ * @param elements The String objects or Integer objects to use.
+ * @return A array of PathElement instances.
+ */
+ public static PathElement[] createPath(final Object... elements) {
List path = new ArrayList<>();
for (Object element : elements) {
if (element instanceof String) {
@@ -88,41 +62,24 @@ public static PathElement[] createPath(Object... elements) {
return path.toArray(new PathElement[0]);
}
-
- public static class Builder {
- private String message = null;
- private String name = null;
- private final List paths = new ArrayList<>();
-
- public Builder message(String message) {
- this.message = message;
- return this;
- }
-
- public Builder name(String name) {
- this.name = name;
- return this;
- }
-
- public Builder path(PathElement[] path) {
- this.paths.add(path);
- return this;
- }
-
- public ConstraintFailure build() {
- PathElement[][] paths =
- this.paths.toArray(new PathElement[this.paths.size()][]);
- return new ConstraintFailure(this.message, this.name,
- this.paths.isEmpty() ? null : paths);
- }
-
- }
-
+ /**
+ * Initializes a new empty Builder.
+ *
+ * @return A new Builder
+ */
public static Builder builder() {
return new Builder();
}
- public static ConstraintFailure parse(JsonParser parser)
+ /**
+ * Builds a ConstraintFailure instance from the provided JsonParser.
+ *
+ * @param parser The JsonParser to consume.
+ * @return A new ConstraintFailure instance.
+ * @throws IOException Thrown if an error is encountered while reading the
+ * parser.
+ */
+ public static ConstraintFailure parse(final JsonParser parser)
throws IOException {
if (parser.currentToken() != JsonToken.START_OBJECT &&
parser.nextToken() != JsonToken.START_OBJECT) {
@@ -152,8 +109,8 @@ public static ConstraintFailure parse(JsonParser parser)
}
} else if (firstPathToken != JsonToken.VALUE_NULL) {
throw new ClientResponseException(
- "Constraint failure path should be array or null, got: " +
- firstPathToken.toString());
+ "Constraint failure path should be array or null, got: "
+ + firstPathToken.toString());
}
paths.forEach(builder::path);
break;
@@ -163,18 +120,38 @@ public static ConstraintFailure parse(JsonParser parser)
}
+ /**
+ * Gets the constraint failure message.
+ *
+ * @return A string representation of the message.
+ */
public String getMessage() {
return this.message;
}
+ /**
+ * Gets the constraint failure name.
+ *
+ * @return A string representation of the name.
+ */
public Optional getName() {
return Optional.ofNullable(this.name);
}
+ /**
+ * Gets an optional path elements related to the constraint failure.
+ *
+ * @return An array of arrays of PathElements.
+ */
public Optional getPaths() {
return Optional.ofNullable(paths);
}
+ /**
+ * Gets a list of string representations of the constraint failure paths.
+ *
+ * @return A list of string representations of constraint failure paths.
+ */
public Optional> getPathStrings() {
if (paths == null) {
return Optional.empty();
@@ -187,7 +164,13 @@ public Optional> getPathStrings() {
}
}
- public boolean pathsAreEqual(ConstraintFailure otherFailure) {
+ /**
+ * Tests path equality with another ConstraintFailure.
+ *
+ * @param otherFailure The other ConstraintFailure.
+ * @return True if the paths are equal.
+ */
+ public boolean pathsAreEqual(final ConstraintFailure otherFailure) {
PathElement[][] thisArray =
this.getPaths().orElse(new PathElement[0][]);
PathElement[][] otherArray =
@@ -195,7 +178,8 @@ public boolean pathsAreEqual(ConstraintFailure otherFailure) {
return Arrays.deepEquals(thisArray, otherArray);
}
- public boolean equals(Object other) {
+ @Override
+ public boolean equals(final Object other) {
if (other instanceof ConstraintFailure) {
ConstraintFailure otherFailure = (ConstraintFailure) other;
return this.getMessage().equals(otherFailure.getMessage())
@@ -206,4 +190,137 @@ public boolean equals(Object other) {
}
}
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ this.name,
+ this.message,
+ Arrays.deepHashCode(this.paths));
+ }
+
+ public static final class PathElement {
+ private String sVal = null;
+ private Integer iVal = null;
+
+ /**
+ * Initializes a PathElement with a string value.
+ *
+ * @param sVal The string value.
+ */
+ public PathElement(final String sVal) {
+ this.sVal = sVal;
+ }
+
+ /**
+ * Initializes a PathElement with an integer value.
+ *
+ * @param iVal The integer value.
+ */
+ public PathElement(final Integer iVal) {
+ this.iVal = iVal;
+ }
+
+ /**
+ * Note that this parse method does not advance the parser.
+ *
+ * @param parser A JsonParser instance.
+ * @return A new PathElement.
+ * @throws IOException Can be thrown if e.g. stream ends.
+ */
+ public static PathElement parse(final JsonParser parser)
+ throws IOException {
+ if (parser.currentToken().isNumeric()) {
+ return new PathElement(parser.getValueAsInt());
+ } else {
+ return new PathElement(parser.getText());
+ }
+ }
+
+ /**
+ * Tests whether the PathElement stores a string or an integer.
+ *
+ * @return If it's a string, true. Otherwise, false.
+ */
+ public boolean isString() {
+ return sVal != null;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (o instanceof PathElement) {
+ PathElement other = (PathElement) o;
+ return other.isString() == this.isString() &&
+ other.toString().equals(this.toString());
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ /**
+ * Converts the PathElement to a string.
+ *
+ * @return A string representation of the PathElement.
+ */
+ public String toString() {
+ return sVal == null ? String.valueOf(iVal) : sVal;
+ }
+ }
+
+ public static class Builder {
+ private final List paths = new ArrayList<>();
+ private String message = null;
+ private String name = null;
+
+ /**
+ * Sets a message on the builder.
+ *
+ * @param message The message to set.
+ * @return this.
+ */
+ public Builder message(final String message) {
+ this.message = message;
+ return this;
+ }
+
+ /**
+ * Sets a name on the builder.
+ *
+ * @param name The name to set.
+ * @return this.
+ */
+ public Builder name(final String name) {
+ this.name = name;
+ return this;
+ }
+
+ /**
+ * Sets a path on the builder.
+ *
+ * @param path The path to set.
+ * @return this.
+ */
+ public Builder path(final PathElement[] path) {
+ this.paths.add(path);
+ return this;
+ }
+
+ /**
+ * Builds a ConstraintFailure instance from the current builder.
+ *
+ * @return A ConstraintFailure instance.
+ */
+ public ConstraintFailure build() {
+ PathElement[][] paths =
+ this.paths.toArray(new PathElement[this.paths.size()][]);
+ return new ConstraintFailure(this.message, this.name,
+ this.paths.isEmpty() ? null : paths);
+ }
+
+ }
+
}
diff --git a/src/main/java/com/fauna/response/ErrorInfo.java b/src/main/java/com/fauna/response/ErrorInfo.java
index fb22ce61..1d288d95 100644
--- a/src/main/java/com/fauna/response/ErrorInfo.java
+++ b/src/main/java/com/fauna/response/ErrorInfo.java
@@ -29,31 +29,142 @@ public class ErrorInfo {
private final ConstraintFailure[] constraintFailures;
private final TreeNode abort;
- public ErrorInfo(String code, String message,
- ConstraintFailure[] constraintFailures, TreeNode abort) {
+ /**
+ * Initializes a new ErrorInfo.
+ *
+ * @param code The Fauna
+ * error code.
+ * @param message A short, human-readable description of the
+ * error.
+ * @param constraintFailures The constraint failures for the error, if any.
+ * Only present if the error code is
+ * `constraint_failure`.
+ * @param abort A user-defined error message passed using an
+ * FQL `abort()` method call. Only present if the error
+ * code is `abort`.
+ */
+ public ErrorInfo(
+ final String code,
+ final String message,
+ final ConstraintFailure[] constraintFailures,
+ final TreeNode abort) {
this.code = code;
this.message = message;
this.constraintFailures = constraintFailures;
this.abort = abort;
}
+ /**
+ * A utility method to instantiate an empty builder.
+ *
+ * @return A new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ private static Builder handleField(final Builder builder,
+ final JsonParser parser)
+ throws IOException {
+ String fieldName = parser.getCurrentName();
+ switch (fieldName) {
+ case ERROR_CODE_FIELD_NAME:
+ return builder.code(parser.nextTextValue());
+ case ERROR_MESSAGE_FIELD_NAME:
+ return builder.message(parser.nextTextValue());
+ case ERROR_ABORT_FIELD_NAME:
+ parser.nextToken();
+ return builder.abort(new ObjectMapper().readTree(parser));
+ case ERROR_CONSTRAINT_FAILURES_FIELD_NAME:
+ List failures = new ArrayList<>();
+ JsonToken token = parser.nextToken();
+ if (token == JsonToken.VALUE_NULL) {
+ return builder;
+ } else if (token == JsonToken.START_ARRAY) {
+ JsonToken nextToken = parser.nextToken();
+ while (nextToken == JsonToken.START_OBJECT) {
+ failures.add(ConstraintFailure.parse(parser));
+ nextToken = parser.nextToken();
+ }
+ return builder.constraintFailures(failures);
+ } else {
+ throw new ClientResponseException(
+ "Unexpected token in constraint failures: "
+ + token);
+ }
+ default:
+ throw new ClientResponseException(
+ "Unexpected token in error info: "
+ + parser.currentToken());
+ }
+ }
+
+ /**
+ * Builds a new ErrorInfo from a JsonParser.
+ *
+ * @param parser The JsonParser to read.
+ * @return A new ErrorInfo instance.
+ * @throws IOException Thrown on errors reading from the parser.
+ */
+ public static ErrorInfo parse(final JsonParser parser) throws IOException {
+ if (parser.nextToken() != JsonToken.START_OBJECT) {
+ throw new ClientResponseException(
+ "Error parsing error info, got token"
+ + parser.currentToken());
+ }
+ Builder builder = ErrorInfo.builder();
+
+ while (parser.nextToken() == JsonToken.FIELD_NAME) {
+ builder = handleField(builder, parser);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Gets the Fauna error code.
+ *
+ * @return A string representing the Fauna error code.
+ */
public String getCode() {
return code;
}
+ /**
+ * Gets the error message.
+ *
+ * @return A string representing the error message.
+ */
public String getMessage() {
return message;
}
+ /**
+ * Gets the constraint failures.
+ *
+ * @return An optional containing the constraint failures.
+ */
public Optional getConstraintFailures() {
return Optional.ofNullable(this.constraintFailures);
}
+ /**
+ * Gets the user-defined abort error message as a JSON node.
+ *
+ * @return An optional TreeNode with the abort data.
+ */
public Optional getAbortJson() {
return Optional.ofNullable(this.abort);
}
- public Optional getAbort(Class abortDataClass) {
+ /**
+ * Parses the abort data into the provided class.
+ *
+ * @param abortDataClass The class to decode into.
+ * @param The type to decode into.
+ * @return An instance of the provided type.
+ */
+ public Optional getAbort(final Class abortDataClass) {
return this.getAbortJson().map(tree -> {
UTF8FaunaParser parser = new UTF8FaunaParser(tree.traverse());
Codec codec = DefaultCodecProvider.SINGLETON.get(abortDataClass);
@@ -62,91 +173,66 @@ public Optional getAbort(Class abortDataClass) {
});
}
-
public static class Builder {
- String code = null;
- String message = null;
- ConstraintFailure[] constraintFailures = null;
- TreeNode abort = null;
-
- public Builder code(String code) {
+ private String code = null;
+ private String message = null;
+ private ConstraintFailure[] constraintFailures = null;
+ private TreeNode abort = null;
+
+ /**
+ * Sets the error code on the builder.
+ *
+ * @param code The error code.
+ * @return this
+ */
+ public Builder code(final String code) {
this.code = code;
return this;
}
- public Builder message(String message) {
+ /**
+ * Sets the message on the builder.
+ *
+ * @param message The message.
+ * @return this
+ */
+ public Builder message(final String message) {
this.message = message;
return this;
}
- public Builder abort(TreeNode abort) {
+ /**
+ * Sets the abort data on the builder.
+ *
+ * @param abort The abort JSON node.
+ * @return this
+ */
+ public Builder abort(final TreeNode abort) {
this.abort = abort;
return this;
}
+ /**
+ * Sets the constraint failures on the builder.
+ *
+ * @param constraintFailures The constraint failures.
+ * @return this
+ */
public Builder constraintFailures(
- List constraintFailures) {
+ final List constraintFailures) {
this.constraintFailures =
constraintFailures.toArray(new ConstraintFailure[0]);
return this;
}
+ /**
+ * Returns a new ErrorInfo instance based on the current builder.
+ *
+ * @return An ErrorInfo instance
+ */
public ErrorInfo build() {
return new ErrorInfo(this.code, this.message,
this.constraintFailures, this.abort);
}
}
-
- public static Builder builder() {
- return new Builder();
- }
-
- private static Builder handleField(Builder builder, JsonParser parser)
- throws IOException {
- String fieldName = parser.getCurrentName();
- switch (fieldName) {
- case ERROR_CODE_FIELD_NAME:
- return builder.code(parser.nextTextValue());
- case ERROR_MESSAGE_FIELD_NAME:
- return builder.message(parser.nextTextValue());
- case ERROR_ABORT_FIELD_NAME:
- parser.nextToken();
- return builder.abort(new ObjectMapper().readTree(parser));
- case ERROR_CONSTRAINT_FAILURES_FIELD_NAME:
- List failures = new ArrayList<>();
- JsonToken token = parser.nextToken();
- if (token == JsonToken.VALUE_NULL) {
- return builder;
- } else if (token == JsonToken.START_ARRAY) {
- JsonToken nextToken = parser.nextToken();
- while (nextToken == JsonToken.START_OBJECT) {
- failures.add(ConstraintFailure.parse(parser));
- nextToken = parser.nextToken();
- }
- return builder.constraintFailures(failures);
- } else {
- throw new ClientResponseException(
- "Unexpected token in constraint failures: " +
- token);
- }
- default:
- throw new ClientResponseException(
- "Unexpected token in error info: " +
- parser.currentToken());
- }
- }
-
- public static ErrorInfo parse(JsonParser parser) throws IOException {
- if (parser.nextToken() != JsonToken.START_OBJECT) {
- throw new ClientResponseException(
- "Error parsing error info, got token" +
- parser.currentToken());
- }
- Builder builder = ErrorInfo.builder();
-
- while (parser.nextToken() == JsonToken.FIELD_NAME) {
- builder = handleField(builder, parser);
- }
- return builder.build();
- }
}
diff --git a/src/main/java/com/fauna/response/MultiByteBufferInputStream.java b/src/main/java/com/fauna/response/MultiByteBufferInputStream.java
index 017cc8e8..4051e063 100644
--- a/src/main/java/com/fauna/response/MultiByteBufferInputStream.java
+++ b/src/main/java/com/fauna/response/MultiByteBufferInputStream.java
@@ -13,21 +13,38 @@
* although markSupported() returns false for this class.
*/
public class MultiByteBufferInputStream extends InputStream {
-
+ private final int ff = 0xFF;
private final List buffers;
private int index = 0;
private ByteBuffer currentBuffer;
- public MultiByteBufferInputStream(List initialBuffers) {
+ /**
+ * Initializes a MultiByteBufferInputStream using the provided byte buffers.
+ *
+ * @param initialBuffers A list of ByteBuffers to use.
+ */
+ public MultiByteBufferInputStream(final List initialBuffers) {
this.buffers = initialBuffers;
this.currentBuffer = buffers.get(index);
}
- public synchronized void add(List additionalBuffers) {
+ /**
+ * Adds additional byte buffers to this instance in a thread-safe manner.
+ *
+ * @param additionalBuffers The additional ByteBuffers.
+ */
+ public synchronized void add(final List additionalBuffers) {
buffers.addAll(additionalBuffers);
}
+ /**
+ * Reads the next byte from the buffer.
+ *
+ * @return The next byte.
+ * @throws IOException Thrown when the byte buffers are exhausted.
+ */
+ @SuppressWarnings("checkstyle:MagicNumber")
@Override
public synchronized int read() throws IOException {
if (currentBuffer.hasRemaining()) {
@@ -41,6 +58,9 @@ public synchronized int read() throws IOException {
}
}
+ /**
+ * Resets the byte buffer.
+ */
@Override
public synchronized void reset() {
for (ByteBuffer buffer : buffers.subList(0, index)) {
diff --git a/src/main/java/com/fauna/response/QueryFailure.java b/src/main/java/com/fauna/response/QueryFailure.java
index 2c2df354..c1c164fa 100644
--- a/src/main/java/com/fauna/response/QueryFailure.java
+++ b/src/main/java/com/fauna/response/QueryFailure.java
@@ -10,7 +10,7 @@ public final class QueryFailure extends QueryResponse {
public QueryFailure(int httpStatus, Builder builder) {
super(builder);
this.statusCode = httpStatus;
- this.errorInfo = builder.error;
+ this.errorInfo = builder.getError();
}
public int getStatusCode() {
diff --git a/src/main/java/com/fauna/response/QueryResponse.java b/src/main/java/com/fauna/response/QueryResponse.java
index e765339b..4b88dac7 100644
--- a/src/main/java/com/fauna/response/QueryResponse.java
+++ b/src/main/java/com/fauna/response/QueryResponse.java
@@ -14,6 +14,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.net.HttpURLConnection;
import java.net.http.HttpResponse;
import java.util.Map;
@@ -37,7 +38,7 @@ public abstract class QueryResponse {
private final QueryStats stats;
@SuppressWarnings("rawtypes")
- QueryResponse(Builder builder) {
+ QueryResponse(final Builder builder) {
this.lastSeenTxn = builder.lastSeenTxn;
this.summary = builder.summary;
this.schemaVersion = builder.schemaVersion;
@@ -45,75 +46,19 @@ public abstract class QueryResponse {
this.queryTags = builder.queryTags;
}
- public static class Builder {
- final Codec codec;
- Long lastSeenTxn;
- String summary;
- Long schemaVersion;
- QueryStats stats;
- QueryTags queryTags;
- String staticType;
- ErrorInfo error;
- T data;
-
- public Builder(Codec codec) {
- this.codec = codec;
- }
-
- public Builder lastSeenTxn(Long lastSeenTxn) {
- this.lastSeenTxn = lastSeenTxn;
- return this;
- }
-
- public Builder schemaVersion(Long schemaVersion) {
- this.schemaVersion = schemaVersion;
- return this;
- }
-
- public Builder data(JsonParser parser) {
- UTF8FaunaParser faunaParser = new UTF8FaunaParser(parser);
- faunaParser.read();
- this.data = this.codec.decode(faunaParser);
- return this;
- }
-
- public Builder queryTags(QueryTags tags) {
- this.queryTags = tags;
- return this;
- }
-
- public Builder error(ErrorInfo info) {
- this.error = info;
- return this;
- }
-
- public Builder staticType(String staticType) {
- this.staticType = staticType;
- return this;
- }
-
- public Builder summary(String summary) {
- this.summary = summary;
- return this;
- }
-
- public Builder stats(QueryStats stats) {
- this.stats = stats;
- return this;
- }
-
- public QuerySuccess buildSuccess() {
- return new QuerySuccess<>(this);
- }
-
- }
-
- public static Builder builder(Codec codec) {
+ /**
+ * A helper method to instantiate a new builder.
+ *
+ * @param codec The codec to use when parsing data.
+ * @param The return type of the data.
+ * @return A new Builder instance.
+ */
+ public static Builder builder(final Codec codec) {
return new Builder<>(codec);
}
- private static Builder handleField(Builder builder,
- JsonParser parser)
+ private static Builder handleField(final Builder builder,
+ final JsonParser parser)
throws IOException {
String fieldName = parser.getCurrentName();
switch (fieldName) {
@@ -139,9 +84,20 @@ private static Builder handleField(Builder builder,
}
}
+ /**
+ * A helper method to adapt an HTTP response into a QuerySuccess or throw
+ * the appropriate FaunaException.
+ *
+ * @param response The HTTP response to adapt.
+ * @param codec The codec to use when reading the HTTP response body.
+ * @param statsCollector The stats collector to accumulate stats against.
+ * @param The response type on success.
+ * @return A QuerySuccess instance.
+ * @throws FaunaException Thrown on non-200 responses.
+ */
public static QuerySuccess parseResponse(
- HttpResponse response, Codec codec,
- StatsCollector statsCollector) throws FaunaException {
+ final HttpResponse response, final Codec codec,
+ final StatsCollector statsCollector) throws FaunaException {
try {
JsonParser parser = JSON_FACTORY.createParser(response.body());
@@ -160,7 +116,7 @@ public static QuerySuccess parseResponse(
}
int httpStatus = response.statusCode();
- if (httpStatus >= 400) {
+ if (httpStatus >= HttpURLConnection.HTTP_BAD_REQUEST) {
QueryFailure failure = new QueryFailure(httpStatus, builder);
ErrorHandler.handleQueryFailure(response.statusCode(), failure);
// Fall back on ProtocolException.
@@ -175,25 +131,197 @@ public static QuerySuccess parseResponse(
}
-
+ /**
+ * Gets the last seen transaction timestamp.
+ *
+ * @return A long representing the last seen transaction timestamp.
+ */
public Long getLastSeenTxn() {
return lastSeenTxn;
}
+ /**
+ * Gets the schema version.
+ *
+ * @return A long representing the schema version.
+ */
public Long getSchemaVersion() {
return schemaVersion;
}
+ /**
+ * Gets the summary associated with the response.
+ *
+ * @return A string representing the summary.
+ */
public String getSummary() {
return summary;
}
+ /**
+ * Gets the query tags associated with the response.
+ *
+ * @return A Map containing the query tags.
+ */
public Map getQueryTags() {
return queryTags;
}
+ /**
+ * Gets the query stats associated with the response.
+ *
+ * @return A QueryStats instance.
+ */
public QueryStats getStats() {
return stats;
}
+
+ public static final class Builder {
+ private final Codec codec;
+ private Long lastSeenTxn;
+ private String summary;
+ private Long schemaVersion;
+ private QueryStats stats;
+ private QueryTags queryTags;
+ private String staticType;
+ private ErrorInfo error;
+ private T data;
+
+ /**
+ * Initializes a QueryResponse.Builder.
+ *
+ * @param codec The codec to use when building data.
+ */
+ public Builder(final Codec codec) {
+ this.codec = codec;
+ }
+
+ /**
+ * Set the last seen transaction timestamp on the builder.
+ *
+ * @param lastSeenTxn The last seen transaction timestamp.
+ * @return This
+ */
+ public Builder lastSeenTxn(final Long lastSeenTxn) {
+ this.lastSeenTxn = lastSeenTxn;
+ return this;
+ }
+
+ /**
+ * Set the schema version on the builder.
+ *
+ * @param schemaVersion The schema version.
+ * @return This
+ */
+ public Builder schemaVersion(final Long schemaVersion) {
+ this.schemaVersion = schemaVersion;
+ return this;
+ }
+
+ /**
+ * Set the data on the builder by consuming the provided JsonParser with
+ * the configured codec.
+ *
+ * @param parser The JsonParser to consume.
+ * @return This
+ */
+ public Builder data(final JsonParser parser) {
+ UTF8FaunaParser faunaParser = new UTF8FaunaParser(parser);
+ faunaParser.read();
+ this.data = this.codec.decode(faunaParser);
+ return this;
+ }
+
+ /**
+ * Set the query tags on the builder.
+ *
+ * @param tags The query tags to set.
+ * @return This
+ */
+ public Builder queryTags(final QueryTags tags) {
+ this.queryTags = tags;
+ return this;
+ }
+
+ /**
+ * Sets the error info on the builder.
+ *
+ * @param info The error info to set.
+ * @return This
+ */
+ public Builder error(final ErrorInfo info) {
+ this.error = info;
+ return this;
+ }
+
+ /**
+ * Sets the static type on the builder.
+ *
+ * @param staticType The static type to set.
+ * @return This
+ */
+ public Builder staticType(final String staticType) {
+ this.staticType = staticType;
+ return this;
+ }
+
+ /**
+ * Sets the summary on the builder.
+ *
+ * @param summary The summary to set.
+ * @return This
+ */
+ public Builder summary(final String summary) {
+ this.summary = summary;
+ return this;
+ }
+
+ /**
+ * Sets the query stats on the builder.
+ *
+ * @param stats The query stats to set.
+ * @return This
+ */
+ public Builder stats(final QueryStats stats) {
+ this.stats = stats;
+ return this;
+ }
+
+ /**
+ * Builds a QuerySuccess.
+ *
+ * @return A QuerySuccess from the current builder.
+ */
+ public QuerySuccess buildSuccess() {
+ return new QuerySuccess<>(this);
+ }
+
+ /**
+ * Gets a string representing the static type.
+ *
+ * @return A string representing the static type.
+ */
+ public String getStaticType() {
+ return staticType;
+ }
+
+ /**
+ * Gets an ErrorInfo instance representing an error on the response.
+ *
+ * @return An ErrorInfo instance.
+ */
+ public ErrorInfo getError() {
+ return error;
+ }
+
+ /**
+ * Gets the parsed data from the response.
+ *
+ * @return The parsed data.
+ */
+ public T getData() {
+ return data;
+ }
+ }
}
diff --git a/src/main/java/com/fauna/response/QueryStats.java b/src/main/java/com/fauna/response/QueryStats.java
index 7f8159ea..67cdcea6 100644
--- a/src/main/java/com/fauna/response/QueryStats.java
+++ b/src/main/java/com/fauna/response/QueryStats.java
@@ -45,7 +45,7 @@ public final class QueryStats {
* requests.
* @param rateLimitsHit Operation types that exceeded
* plan
- * throughput limits.
+ * throughput limits
.
*/
public QueryStats(final int computeOps, final int readOps,
final int writeOps,
@@ -64,6 +64,71 @@ public QueryStats(final int computeOps, final int readOps,
this.rateLimitsHit = rateLimitsHit != null ? rateLimitsHit : List.of();
}
+ static Builder builder() {
+ return new Builder();
+ }
+
+ static Builder parseField(final Builder builder, final JsonParser parser)
+ throws IOException {
+ String fieldName = parser.getValueAsString();
+ switch (fieldName) {
+ case ResponseFields.STATS_COMPUTE_OPS_FIELD_NAME:
+ return builder.computeOps(parser.nextIntValue(0));
+ case ResponseFields.STATS_READ_OPS:
+ return builder.readOps(parser.nextIntValue(0));
+ case ResponseFields.STATS_WRITE_OPS:
+ return builder.writeOps(parser.nextIntValue(0));
+ case ResponseFields.STATS_QUERY_TIME_MS:
+ return builder.queryTimeMs(parser.nextIntValue(0));
+ case ResponseFields.STATS_PROCESSING_TIME_MS:
+ return builder.processingTimeMs(parser.nextIntValue(0));
+ case ResponseFields.STATS_CONTENTION_RETRIES:
+ return builder.contentionRetries(parser.nextIntValue(0));
+ case ResponseFields.STATS_STORAGE_BYTES_READ:
+ return builder.storageBytesRead(parser.nextIntValue(0));
+ case ResponseFields.STATS_STORAGE_BYTES_WRITE:
+ return builder.storageBytesWrite(parser.nextIntValue(0));
+ case ResponseFields.STATS_RATE_LIMITS_HIT:
+ List limits = new ArrayList<>();
+ if (parser.nextToken() == START_ARRAY) {
+ while (parser.nextToken() == VALUE_STRING) {
+ limits.add(parser.getValueAsString());
+ }
+ }
+ return builder.rateLimitsHit(limits);
+ default:
+ throw new ClientResponseException("Unknown field " + fieldName);
+ }
+ }
+
+ /**
+ * Parse QueryStats from a JsonParser.
+ *
+ * @param parser the JsonParser to consume
+ * @return a QueryStats object containing the parsed stats
+ * @throws IOException thrown from the JsonParser
+ */
+ public static QueryStats parseStats(final JsonParser parser)
+ throws IOException {
+ if (parser.nextToken() == START_OBJECT) {
+ Builder builder = builder();
+ while (parser.nextToken() == FIELD_NAME) {
+ builder = parseField(builder, parser);
+ }
+ return builder.build();
+ } else if (parser.nextToken() == VALUE_NULL) {
+ return null;
+ } else {
+ throw new ClientResponseException(
+ "Query stats should be an object or null, not "
+ + parser.getCurrentToken());
+ }
+ }
+
+ private static String statString(final String name, final Object value) {
+ return String.join(": ", name, String.valueOf(value));
+ }
+
/**
* Gets the Transactional Compute Operations (TCOs) recorded.
*
@@ -140,7 +205,7 @@ public int getStorageBytesWrite() {
/**
* Gets a list of operation types that exceeded their plan
- * throughput limits.
+ * throughput limits.
*
* @return A list of operation types that exceeded their throughput limit.
*/
@@ -148,6 +213,23 @@ public List getRateLimitsHit() {
return rateLimitsHit;
}
+ @Override
+ public String toString() {
+ if (this.stringValue == null) {
+ this.stringValue = String.join(", ",
+ statString("compute", computeOps),
+ statString("read", readOps),
+ statString("write", writeOps),
+ statString("queryTime", queryTimeMs),
+ statString("retries", contentionRetries),
+ statString("storageRead", storageBytesRead),
+ statString("storageWrite", storageBytesWrite),
+ statString("limits", rateLimitsHit)
+ );
+ }
+ return this.stringValue;
+ }
+
static class Builder {
private int computeOps;
private int readOps;
@@ -210,86 +292,4 @@ QueryStats build() {
processingTimeMs, rateLimitsHit);
}
}
-
- static Builder builder() {
- return new Builder();
- }
-
- static Builder parseField(final Builder builder, final JsonParser parser)
- throws IOException {
- String fieldName = parser.getValueAsString();
- switch (fieldName) {
- case ResponseFields.STATS_COMPUTE_OPS_FIELD_NAME:
- return builder.computeOps(parser.nextIntValue(0));
- case ResponseFields.STATS_READ_OPS:
- return builder.readOps(parser.nextIntValue(0));
- case ResponseFields.STATS_WRITE_OPS:
- return builder.writeOps(parser.nextIntValue(0));
- case ResponseFields.STATS_QUERY_TIME_MS:
- return builder.queryTimeMs(parser.nextIntValue(0));
- case ResponseFields.STATS_PROCESSING_TIME_MS:
- return builder.processingTimeMs(parser.nextIntValue(0));
- case ResponseFields.STATS_CONTENTION_RETRIES:
- return builder.contentionRetries(parser.nextIntValue(0));
- case ResponseFields.STATS_STORAGE_BYTES_READ:
- return builder.storageBytesRead(parser.nextIntValue(0));
- case ResponseFields.STATS_STORAGE_BYTES_WRITE:
- return builder.storageBytesWrite(parser.nextIntValue(0));
- case ResponseFields.STATS_RATE_LIMITS_HIT:
- List limits = new ArrayList<>();
- if (parser.nextToken() == START_ARRAY) {
- while (parser.nextToken() == VALUE_STRING) {
- limits.add(parser.getValueAsString());
- }
- }
- return builder.rateLimitsHit(limits);
- default:
- throw new ClientResponseException("Unknown field " + fieldName);
- }
- }
-
- /**
- * Parse QueryStats from a JsonParser.
- *
- * @param parser the JsonParser to consume
- * @return a QueryStats object containing the parsed stats
- * @throws IOException thrown from the JsonParser
- */
- public static QueryStats parseStats(final JsonParser parser)
- throws IOException {
- if (parser.nextToken() == START_OBJECT) {
- Builder builder = builder();
- while (parser.nextToken() == FIELD_NAME) {
- builder = parseField(builder, parser);
- }
- return builder.build();
- } else if (parser.nextToken() == VALUE_NULL) {
- return null;
- } else {
- throw new ClientResponseException(
- "Query stats should be an object or null, not "
- + parser.getCurrentToken());
- }
- }
-
- private static String statString(final String name, final Object value) {
- return String.join(": ", name, String.valueOf(value));
- }
-
- @Override
- public String toString() {
- if (this.stringValue == null) {
- this.stringValue = String.join(", ",
- statString("compute", computeOps),
- statString("read", readOps),
- statString("write", writeOps),
- statString("queryTime", queryTimeMs),
- statString("retries", contentionRetries),
- statString("storageRead", storageBytesRead),
- statString("storageWrite", storageBytesWrite),
- statString("limits", rateLimitsHit)
- );
- }
- return this.stringValue;
- }
}
diff --git a/src/main/java/com/fauna/response/QuerySuccess.java b/src/main/java/com/fauna/response/QuerySuccess.java
index 654f9ba2..6f76449a 100644
--- a/src/main/java/com/fauna/response/QuerySuccess.java
+++ b/src/main/java/com/fauna/response/QuerySuccess.java
@@ -7,10 +7,10 @@ public final class QuerySuccess extends QueryResponse {
private final T data;
private final String staticType;
- public QuerySuccess(Builder builder) {
+ public QuerySuccess(final Builder builder) {
super(builder);
- this.data = builder.data;
- this.staticType = builder.staticType;
+ this.data = builder.getData();
+ this.staticType = builder.getStaticType();
}
public T getData() {