Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,46 @@ public static BooleanExpression or(BooleanExpression condition, BooleanExpressio
return new BooleanFunctionExpression("or", builder.build());
}

/**
* Creates an expression that performs a logical 'NOR' operation.
*
* @param condition The first {@link BooleanExpression}.
* @param conditions Additional {@link BooleanExpression}s.
* @return A new {@link BooleanExpression} representing the logical 'NOR' operation.
*/
@BetaApi
public static BooleanExpression nor(
BooleanExpression condition, BooleanExpression... conditions) {
ImmutableList.Builder<Expression> builder = ImmutableList.builder();
builder.add(condition);
builder.add(conditions);
System.out.println("nor: " + builder.build());
return new BooleanFunctionExpression("nor", builder.build());
}

/**
* Creates an expression that evaluates to the result corresponding to the first true condition.
*
* <p>This function behaves like a `switch` statement. It accepts an alternating sequence of
* conditions and their corresponding results. If an odd number of arguments is provided, the
* final argument serves as a default fallback result. If no default is provided and no condition
* evaluates to true, it throws an error.
*
* @param condition The first {@link BooleanExpression}.
* @param result The result if the first condition is true.
* @param others Additional conditions and results, and optionally a default value.
* @return A new {@link Expression} representing the switchOn operation.
*/
@BetaApi
public static Expression switchOn(
BooleanExpression condition, Expression result, Object... others) {
ImmutableList.Builder<Expression> builder = ImmutableList.builder();
builder.add(condition);
builder.add(result);
builder.addAll(toArrayOfExprOrConstant(others));
return new FunctionExpression("switch_on", builder.build());
}

/**
* Creates an expression that performs a logical 'XOR' operation.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import static com.google.cloud.firestore.pipeline.expressions.Expression.logicalMinimum;
import static com.google.cloud.firestore.pipeline.expressions.Expression.mapMerge;
import static com.google.cloud.firestore.pipeline.expressions.Expression.mapRemove;
import static com.google.cloud.firestore.pipeline.expressions.Expression.nor;
import static com.google.cloud.firestore.pipeline.expressions.Expression.notEqual;
import static com.google.cloud.firestore.pipeline.expressions.Expression.nullValue;
import static com.google.cloud.firestore.pipeline.expressions.Expression.or;
Expand All @@ -79,6 +80,7 @@
import static com.google.cloud.firestore.pipeline.expressions.Expression.stringConcat;
import static com.google.cloud.firestore.pipeline.expressions.Expression.substring;
import static com.google.cloud.firestore.pipeline.expressions.Expression.subtract;
import static com.google.cloud.firestore.pipeline.expressions.Expression.switchOn;
import static com.google.cloud.firestore.pipeline.expressions.Expression.timestampAdd;
import static com.google.cloud.firestore.pipeline.expressions.Expression.timestampToUnixMicros;
import static com.google.cloud.firestore.pipeline.expressions.Expression.timestampToUnixMillis;
Expand Down Expand Up @@ -845,6 +847,78 @@ public void whereByOrCondition() throws Exception {
map("title", "1984")));
}

@Test
public void whereByNorCondition() throws Exception {
List<PipelineResult> results =
firestore
.pipeline()
.createFrom(collection)
.where(
nor(
equal("genre", "Romance"),
equal("genre", "Dystopian"),
equal("genre", "Fantasy"),
greaterThan("published", 1949)))
.select("title")
.execute()
.get()
.getResults();

assertThat(data(results))
.containsExactlyElementsIn(
Lists.newArrayList(
map("title", "Crime and Punishment"),
map("title", "The Great Gatsby"),
map("title", "Timestamp Book")));
}

@Test
public void selectWithSwitchOn() throws Exception {
List<PipelineResult> results =
firestore
.pipeline()
.createFrom(collection)
.limit(1)
.replaceWith(Expression.map(map("value", 2)))
.select(
switchOn(equal(field("value"), 2), constant("two"), constant("NA")).as("result1"),
switchOn(equal(field("value"), 3), constant("three"), constant("NA")).as("result2"),
switchOn(
equal(field("value"), 1),
constant("one"),
equal(field("value"), 2),
constant("two"),
equal(field("value"), 3),
constant("three"),
constant("default"))
.as("result3"))
.execute()
.get()
.getResults();
assertThat(data(results))
.isEqualTo(Lists.newArrayList(map("result1", "two", "result2", "NA", "result3", "two")));

// throws if no match and no default
ExecutionException exception =
assertThrows(
ExecutionException.class,
() ->
firestore
.pipeline()
.createFrom(collection)
.limit(1)
.replaceWith(Expression.map(map("value", 5)))
.select(
switchOn(
equal(field("value"), 1), constant("one"),
equal(field("value"), 2), constant("two"))
.as("result"))
.execute()
.get()
.getResults());
assertThat(exception).hasMessageThat().contains("all switch cases evaluate to false");
}

@Test
public void testPipelineWithOffsetAndLimit() throws Exception {
List<PipelineResult> results =
Expand Down
Loading