Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More checkstyle fixes #173

Merged
merged 5 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
<!-- See https://checkstyle.org/checks/sizes/index.html -->
<module name="FileLength"/>
<module name="LineLength">
<property name="max" value="120"/>
<property name="fileExtensions" value="java"/>
</module>

Expand Down Expand Up @@ -161,7 +162,6 @@
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<module name="MagicNumber"/>
<module name="MissingSwitchDefault"/>
<module name="MultipleVariableDeclarations"/>
Expand Down
29 changes: 27 additions & 2 deletions src/main/java/com/fauna/query/AfterToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,43 @@

import java.util.Optional;

/**
* Represents an `after` token used for <a
* href="https://docs.fauna.com/fauna/current/learn/query/pagination/">Set
* pagination</a>.
*/
public class AfterToken {

private final String token;

public AfterToken(String token) {
/**
* Constructs an {@code AfterToken} with the specified token.
*
* @param token the token to be stored in this {@code AfterToken} instance.
*/
public AfterToken(final String token) {
this.token = token;
}

/**
* Returns the token stored in this {@code AfterToken} instance.
*
* @return the token as a {@code String}.
*/
public String getToken() {
return token;
}

public static Optional<AfterToken> fromString(String token) {
/**
* Creates an {@code AfterToken} instance from the specified token string.
* If the provided token is {@code null}, an empty {@code Optional} is
* returned.
*
* @param token the token string to convert into an {@code AfterToken}.
* @return an {@code Optional} containing an {@code AfterToken} if the
* token is non-null, or an empty {@code Optional} if it is null.
*/
public static Optional<AfterToken> fromString(final String token) {
return Optional.ofNullable(
token != null ? new AfterToken(token) : null);
}
Expand Down
136 changes: 120 additions & 16 deletions src/main/java/com/fauna/query/QueryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,66 +5,145 @@

import static com.fauna.constants.Defaults.DEFAULT_TIMEOUT;

/**
* Encapsulates options for configuring Fauna queries, such as timeout,
* linearized reads, typechecking, query tags, and trace parent for
* distributed tracing.
*/
public class QueryOptions {
private final Boolean linearized;
private final Boolean typeCheck;
private final Duration timeout;
private final QueryTags queryTags;
private final String traceParent;

public static QueryOptions DEFAULT = QueryOptions.builder().build();

public QueryOptions(Builder builder) {
/**
* Creates an instance of QueryOptions using the specified builder.
*
* @param builder the builder with values for query options.
*/
public QueryOptions(final Builder builder) {
this.linearized = builder.linearized;
this.typeCheck = builder.typeCheck;
this.timeout = builder.timeout;
this.queryTags = builder.queryTags;
this.traceParent = builder.traceParent;
}

/**
* Default QueryOptions instance with default configurations.
*
* @return a new QueryOptions instance with defaults.
*/
public static QueryOptions getDefault() {
return QueryOptions.builder().build();
}

/**
* Returns an Optional indicating if linearized reads are enabled.
*
* @return an Optional containing the linearized setting, or empty if not
* specified.
*/
public Optional<Boolean> getLinearized() {
return Optional.ofNullable(this.linearized);
}

/**
* Returns an Optional indicating if type checking is enabled.
*
* @return an Optional containing the typeCheck setting, or empty if not
* specified.
*/
public Optional<Boolean> getTypeCheck() {
return Optional.ofNullable(this.typeCheck);
}

/**
* Returns an Optional of the query timeout duration in milliseconds.
*
* @return an Optional containing the query timeout duration in milliseconds, or
* empty if not specified.
*/
public Optional<Long> getTimeoutMillis() {
return Optional.ofNullable(this.timeout).map(Duration::toMillis);
}

/**
* Returns an Optional of the query tags.
*
* @return an Optional containing the QueryTags, or empty if not specified.
*/
public Optional<QueryTags> getQueryTags() {
return Optional.ofNullable(this.queryTags);
}

/**
* Returns an Optional of the trace parent for distributed tracing.
*
* @return an Optional containing the traceParent, or empty if not
* specified.
*/
public Optional<String> getTraceParent() {
return Optional.ofNullable(this.traceParent);
}

/**
* Builder class for constructing instances of QueryOptions.
*/
public static class Builder {
public Boolean linearized = null;
public Boolean typeCheck = null;
public Duration timeout = DEFAULT_TIMEOUT;
public QueryTags queryTags = null;
public String traceParent = null;

public Builder linearized(boolean linearized) {
private Boolean linearized = null;
private Boolean typeCheck = null;
private Duration timeout = DEFAULT_TIMEOUT;
private QueryTags queryTags = null;
private String traceParent = null;

/**
* If true, read-only transactions that don't read indexes are <a
* href="https://docs.fauna.com/fauna/current/learn/transactions/">strictly
* serialized</a>.
*
* @param linearized true to enable linearized reads, false otherwise.
* @return this Builder instance for chaining.
*/
public Builder linearized(final boolean linearized) {
this.linearized = linearized;
return this;
}

public Builder typeCheck(boolean typeCheck) {
/**
* If true, <a href="/fauna/current/learn/query/static-typing/">typechecking</a>
* is enabled for queries. You can only enable typechecking for databases that
* have typechecking enabled.
*
* @param typeCheck true to enable type checking, false otherwise.
* @return this Builder instance for chaining.
*/
public Builder typeCheck(final boolean typeCheck) {
this.typeCheck = typeCheck;
return this;
}

public Builder timeout(Duration timeout) {
/**
* Sets the timeout duration for the query.
*
* @param timeout the timeout Duration for the query.
* @return this Builder instance for chaining.
*/
public Builder timeout(final Duration timeout) {
this.timeout = timeout;
return this;
}

public Builder queryTags(QueryTags queryTags) {
/**
* Sets <a href="https://docs.fauna.com/fauna/current/manage/query-logs/#tags">query tags</a> used to
* instrument the query. You typically use query tags to monitor and debug query requests in
* <a href="https://docs.fauna.com/fauna/current/manage/query-logs/">Fauna Logs</a>.
*
* @param queryTags the QueryTags to associate with the query.
* @return this Builder instance for chaining.
*/
public Builder queryTags(final QueryTags queryTags) {
if (this.queryTags != null) {
this.queryTags.putAll(queryTags);
} else {
Expand All @@ -73,27 +152,52 @@ public Builder queryTags(QueryTags queryTags) {
return this;
}

public Builder queryTag(String key, String value) {
/**
* Adds a single query tag to the existing tags.
*
* @param key the key of the query tag.
* @param value the value of the query tag.
* @return this Builder instance for chaining.
*/
public Builder queryTag(final String key, final String value) {
if (this.queryTags == null) {
this.queryTags = new QueryTags();
}
this.queryTags.put(key, value);
return this;
}

public Builder traceParent(String traceParent) {
/**
* Traceparent identifier used for distributed tracing. Passed by the drive in the `traceparent` header of <a
* href="https://docs.fauna.com/fauna/current/reference/http/reference/core-api/#operation/query">Query
* HTTP endpoint</a> requests. If you don’t include a traceparent identifier or use an invalid identifier,
* Fauna generates a valid identifier.
*
* @param traceParent the trace parent ID.
* @return this Builder instance for chaining.
*/
public Builder traceParent(final String traceParent) {
this.traceParent = traceParent;
return this;
}

/**
* Builds and returns a new instance of QueryOptions.
*
* @return a new QueryOptions instance with the configured settings.
*/
public QueryOptions build() {
return new QueryOptions(this);
}

}

/**
* Creates and returns a new Builder instance for constructing QueryOptions.
*
* @return a new Builder instance.
*/
public static Builder builder() {
return new Builder();
}

}
38 changes: 31 additions & 7 deletions src/main/java/com/fauna/query/QueryTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,25 @@
import java.util.Map;
import java.util.stream.Collectors;

/**
* A utility class representing a collection of <a
* href="https://docs.fauna.com/fauna/current/manage/query-logs/#tags">query tags</a> as a map of key-value pairs.
* This class extends {@link HashMap} and provides methods to build, encode, and parse query tags.
*/
public class QueryTags extends HashMap<String, String> {
private static final String EQUALS = "=";
private static final String COMMA = ",";

/**
* Build a set of query tags from a collection of strings.
* Creates a new {@code QueryTags} instance from an array of tag strings.
* Each tag string must be in the form "key=value".
*
* @param tags 1 or more strings of the form "k=v" where k is the tag key, and v is the tag value.
* @return A new QueryTags instance.
* @param tags an array of strings representing tags in the format "k=v",
* where {@code k} is the tag key and {@code v} is the tag value.
* @return a new {@code QueryTags} instance containing the parsed tags.
* @throws ClientResponseException if a tag string is not in the expected "k=v" format.
*/
public static QueryTags of(String... tags) {
public static QueryTags of(final String... tags) {
QueryTags queryTags = new QueryTags();
for (String tagString : tags) {
String[] tag = tagString.split(EQUALS);
Expand All @@ -33,14 +41,30 @@ public static QueryTags of(String... tags) {
return queryTags;
}

/**
* Encodes the {@code QueryTags} instance as a single string.
* The tags are sorted by their keys and concatenated in the format "key=value,key=value,...".
*
* @return a {@code String} representing the encoded query tags.
*/
public String encode() {
return this.entrySet().stream().sorted(Map.Entry.comparingByKey())
.map(entry -> String.join(EQUALS, entry.getKey(),
entry.getValue()))
.collect(Collectors.joining(COMMA));
}

public static QueryTags parse(JsonParser parser) throws IOException {
/**
* Parses a JSON parser to construct a {@code QueryTags} instance.
* This method expects the JSON to contain either a null value or a string representation of tags in
* "key=value,key=value,..." format.
*
* @param parser a {@code JsonParser} positioned at the JSON data to parse.
* @return a {@code QueryTags} instance representing the parsed tags, or {@code null} if the JSON value is null.
* @throws IOException if an error occurs during parsing.
* @throws ClientResponseException if the JSON token is not a string or null.
*/
public static QueryTags parse(final JsonParser parser) throws IOException {
if (parser.nextToken() == JsonToken.VALUE_NULL) {
return null;
} else if (parser.getCurrentToken() == JsonToken.VALUE_STRING) {
Expand All @@ -52,8 +76,8 @@ public static QueryTags parse(JsonParser parser) throws IOException {
}
} else {
throw new ClientResponseException(
"Unexpected token for QueryTags: " +
parser.getCurrentToken());
"Unexpected token for QueryTags: "
+ parser.getCurrentToken());
}
}
}
Loading
Loading