Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,42 @@ Expression parseExpression(@NonNull Map<String, Object> expressionMap) {
Map<String, Object> delimiterMap = (Map<String, Object>) args.get("delimiter");
return Expression.join(parseExpression(arrayMap), parseExpression(delimiterMap));
}
case "string_index_of":
return parseChild(args, "expression").stringIndexOf(parseChild(args, "search"));
case "string_repeat":
return parseChild(args, "expression").stringRepeat(parseChild(args, "repetitions"));
case "string_replace_one":
{
Expression expression = parseChild(args, "expression");
Expression find = parseChild(args, "find");
Expression replacement = parseChild(args, "replacement");
return expression.stringReplaceOne(find, replacement);
}
case "string_replace_all":
{
Expression expression = parseChild(args, "expression");
Expression find = parseChild(args, "find");
Expression replacement = parseChild(args, "replacement");
return expression.stringReplaceAll(find, replacement);
}
Comment on lines +258 to +264

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we add e2e tests for this too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I've added it

case "ltrim":
{
Expression expression = parseChild(args, "expression");
Map<String, Object> valueMap = (Map<String, Object>) args.get("value");
if (valueMap == null) {
return expression.ltrim();
}
return expression.ltrimValue(parseExpression(valueMap));
}
case "rtrim":
{
Expression expression = parseChild(args, "expression");
Map<String, Object> valueMap = (Map<String, Object>) args.get("value");
if (valueMap == null) {
return expression.rtrim();
}
return expression.rtrimValue(parseExpression(valueMap));
}
case "abs":
return Expression.abs(parseChild(args, "expression"));
case "negate":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,70 @@ - (FIRExprBridge *)parseExpression:(NSDictionary<NSString *, id> *)map error:(NS
return FLTNewFunctionExprBridge(@"string_replace", @[ expr, find, replacement ]);
}

// -------------------------------------------------------------------------
// expression + find + replacement: string_replace_one / string_replace_all
// -------------------------------------------------------------------------
if ([name isEqualToString:@"string_replace_one"] ||
[name isEqualToString:@"string_replace_all"]) {
id exprMap = args[@"expression"];
id findMap = args[@"find"];
id replacementMap = args[@"replacement"];
if (![exprMap isKindOfClass:[NSDictionary class]] ||
![findMap isKindOfClass:[NSDictionary class]] ||
![replacementMap isKindOfClass:[NSDictionary class]]) {
if (error)
*error = parseError(
[NSString stringWithFormat:@"%@ requires expression, find, and replacement", name]);
return nil;
}
FIRExprBridge *expr = [self parseExpression:exprMap error:error];
FIRExprBridge *find = [self parseExpression:findMap error:error];
FIRExprBridge *replacement = [self parseExpression:replacementMap error:error];
if (!expr || !find || !replacement) return nil;
return FLTNewFunctionExprBridge(name, @[ expr, find, replacement ]);
}

// -------------------------------------------------------------------------
// expression + search/repetitions: string_index_of / string_repeat
// -------------------------------------------------------------------------
if ([name isEqualToString:@"string_index_of"] || [name isEqualToString:@"string_repeat"]) {
id exprMap = args[@"expression"];
NSString *argumentName = [name isEqualToString:@"string_index_of"] ? @"search" : @"repetitions";
id argumentMap = args[argumentName];
if (![exprMap isKindOfClass:[NSDictionary class]] ||
![argumentMap isKindOfClass:[NSDictionary class]]) {
if (error)
*error = parseError(
[NSString stringWithFormat:@"%@ requires expression and %@", name, argumentName]);
return nil;
}
FIRExprBridge *expr = [self parseExpression:exprMap error:error];
FIRExprBridge *argument = [self parseExpression:argumentMap error:error];
if (!expr || !argument) return nil;
return FLTNewFunctionExprBridge(name, @[ expr, argument ]);
}

// -------------------------------------------------------------------------
// expression + optional value: ltrim / rtrim
// -------------------------------------------------------------------------
if ([name isEqualToString:@"ltrim"] || [name isEqualToString:@"rtrim"]) {
id exprMap = args[@"expression"];
if (![exprMap isKindOfClass:[NSDictionary class]]) {
if (error) *error = parseError([NSString stringWithFormat:@"%@ requires expression", name]);
return nil;
}
FIRExprBridge *expr = [self parseExpression:exprMap error:error];
if (!expr) return nil;

id valueMap = args[@"value"];
if (![valueMap isKindOfClass:[NSDictionary class]]) {
return FLTNewFunctionExprBridge(name, @[ expr ]);
}
FIRExprBridge *value = [self parseExpression:valueMap error:error];
if (!value) return nil;
return FLTNewFunctionExprBridge(name, @[ expr, value ]);
}

// -------------------------------------------------------------------------
// expression + delimiter: split, join (SDK: split, join)
// -------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -930,9 +930,25 @@ void runPipelineExpressionsTests() {
{'s1': 'Zy', 'iy': 1, 's2': 'xyxy'},
]);
},
skip: !kIsWeb,
);

test('addFields stringReplaceAll replaces every match on s', () async {
final snapshot = await firestore
.pipeline()
.collection('pipeline-e2e')
.where(Expression.field('test').equalValue('expressions'))
.where(Expression.field('score').equalValue(50))
.addFields(
Expression.field('s').stringReplaceAllLiteral('-', '_').as('s_all'),
)
.limit(1)
.execute();
expectResultCount(snapshot, 1);
expectResultsData(snapshot, [
{'s_all': 'a_b_c'},
]);
});

test('addFields ltrim rtrim on padded s', () async {
final snapshot = await firestore
.pipeline()
Expand All @@ -949,7 +965,7 @@ void runPipelineExpressionsTests() {
expectResultsData(snapshot, [
{'lt': 'AbC ', 'rt': ' AbC'},
]);
}, skip: !kIsWeb);
});

test('addFields mapSet and mapEntries on m', () async {
final snapshot = await firestore
Expand Down
Loading