Skip to content

Commit 41d8506

Browse files
committed
Implement concat
1 parent 78e7ae0 commit 41d8506

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

packages/firestore/src/api_pipelines.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export {
162162
stringReverse,
163163
length as len,
164164
abs,
165+
concat,
165166
Expression,
166167
AliasedExpression,
167168
Field,
@@ -174,7 +175,7 @@ export {
174175
export type {
175176
ExpressionType,
176177
AggregateWithAlias,
177-
Selectable,
178+
Selectable
178179
} from './lite-api/expressions';
179180

180181
export { _internalPipelineToExecutePipelineRequestProto } from './remote/internal_serializer';

packages/firestore/src/lite-api/expressions.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,27 @@ export abstract class Expression implements ProtoValueSerializable, UserData {
10461046
);
10471047
}
10481048

1049+
/**
1050+
* Creates an expression that concatenates expression results together.
1051+
*
1052+
* ```typescript
1053+
* // Combine the 'firstName', ' ', and 'lastName' fields into a single value.
1054+
* field("firstName").concat(constant(" "), field("lastName"));
1055+
* ```
1056+
*
1057+
* @param second The additional expression or literal to concatenate.
1058+
* @param others Optional additional expressions or literals to concatenate.
1059+
* @return A new `Expr` representing the concatenated value.
1060+
*/
1061+
concat(
1062+
second: Expression | unknown,
1063+
...others: Array<Expression | unknown>
1064+
): FunctionExpression {
1065+
const elements = [second, ...others];
1066+
const exprs = elements.map(valueToDefaultExpr);
1067+
return new FunctionExpression('concat', [this, ...exprs], 'concat');
1068+
}
1069+
10491070
/**
10501071
* Creates an expression that reverses this string expression.
10511072
*
@@ -7142,6 +7163,56 @@ export function stringReverse(expr: Expression | string): FunctionExpression {
71427163
return fieldOrExpression(expr).stringReverse();
71437164
}
71447165

7166+
/**
7167+
* Creates an expression that concatenates strings, arrays, or blobs. Types cannot be mixed.
7168+
*
7169+
* ```typescript
7170+
* // Concatenate the 'firstName' and 'lastName' fields with a space in between.
7171+
* concat(field("firstName"), " ", field("lastName"))
7172+
* ```
7173+
*
7174+
* @param first The first expressions to concatenate.
7175+
* @param second The second literal or expression to concatenate.
7176+
* @param others Additional literals or expressions to concatenate.
7177+
* @return A new `Expression` representing the concatenation.
7178+
*/
7179+
export function concat(
7180+
first: Expression,
7181+
second: Expression | unknown,
7182+
...others: Array<Expression | unknown>
7183+
): FunctionExpression;
7184+
7185+
/**
7186+
* Creates an expression that concatenates strings, arrays, or blobs. Types cannot be mixed.
7187+
*
7188+
* ```typescript
7189+
* // Concatenate a field with a literal string.
7190+
* concat(field("firstName"), "Doe")
7191+
* ```
7192+
*
7193+
* @param fieldName The name of a field to concatenate.
7194+
* @param second The second literal or expression to concatenate.
7195+
* @param others Additional literal or expressions to concatenate.
7196+
* @return A new `Expression` representing the concatenation.
7197+
*/
7198+
export function concat(
7199+
fieldName: string,
7200+
second: Expression | unknown,
7201+
...others: Array<Expression | unknown>
7202+
): FunctionExpression;
7203+
7204+
export function concat(
7205+
fieldNameOrExpression: string | Expression,
7206+
second: Expression | unknown,
7207+
...others: Array<Expression | unknown>
7208+
): FunctionExpression {
7209+
return new FunctionExpression('concat', [
7210+
fieldOrExpression(fieldNameOrExpression),
7211+
valueToDefaultExpr(second),
7212+
...others.map(valueToDefaultExpr)
7213+
]);
7214+
}
7215+
71457216
/**
71467217
* Creates an expression that computes the absolute value of a numeric value.
71477218
*

packages/firestore/test/integration/api/pipeline.test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ import {
138138
sqrt,
139139
stringReverse,
140140
len as length,
141-
abs
141+
abs,
142+
concat
142143
} from '../util/pipeline_export';
143144

144145
use(chaiAsPromised);
@@ -988,6 +989,26 @@ apiDescribe.only('Pipelines', persistence => {
988989
});
989990
});
990991

992+
describe('concat stage', () => {
993+
it('can concat fields', async () => {
994+
const snapshot = await execute(
995+
firestore
996+
.pipeline()
997+
.collection(randomCol.path)
998+
.addFields(
999+
concat('author', ' ', field('title')).as('display'),
1000+
field('author').concat(': ', field('title')).as('display2')
1001+
)
1002+
.where(equal('author', 'Douglas Adams'))
1003+
.select('display', 'display2')
1004+
);
1005+
expectResults(snapshot, {
1006+
display: "Douglas Adams The Hitchhiker's Guide to the Galaxy",
1007+
display2: "Douglas Adams: The Hitchhiker's Guide to the Galaxy"
1008+
});
1009+
});
1010+
});
1011+
9911012
describe('distinct stage', () => {
9921013
it('returns distinct values as expected', async () => {
9931014
const snapshot = await execute(

0 commit comments

Comments
 (0)