Skip to content

Commit 2e981af

Browse files
committed
removing modular pipeline creation and removing fluent pipline execution. This was a decision from API review
1 parent 4526ad1 commit 2e981af

File tree

7 files changed

+1054
-1093
lines changed

7 files changed

+1054
-1093
lines changed

packages/firestore/src/api/pipeline.ts

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,12 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { firestoreClientExecutePipeline } from '../core/firestore_client';
1918
import { Pipeline as LitePipeline } from '../lite-api/pipeline';
20-
import { PipelineResult } from '../lite-api/pipeline-result';
21-
import { DocumentReference } from '../lite-api/reference';
2219
import { Stage } from '../lite-api/stage';
2320
import { UserDataReader } from '../lite-api/user_data_reader';
2421
import { AbstractUserDataWriter } from '../lite-api/user_data_writer';
25-
import { cast } from '../util/input_validation';
2622

27-
import { ensureFirestoreConfigured, Firestore } from './database';
23+
import { Firestore } from './database';
2824

2925
export class Pipeline extends LitePipeline {
3026
/**
@@ -45,61 +41,4 @@ export class Pipeline extends LitePipeline {
4541
): Pipeline {
4642
return new Pipeline(db, userDataReader, userDataWriter, stages);
4743
}
48-
49-
/**
50-
* Executes this pipeline and returns a Promise to represent the asynchronous operation.
51-
*
52-
* <p>The returned Promise can be used to track the progress of the pipeline execution
53-
* and retrieve the results (or handle any errors) asynchronously.
54-
*
55-
* <p>The pipeline results are returned as a list of {@link PipelineResult} objects. Each {@link
56-
* PipelineResult} typically represents a single key/value map that has passed through all the
57-
* stages of the pipeline, however this might differ depending on the stages involved in the
58-
* pipeline. For example:
59-
*
60-
* <ul>
61-
* <li>If there are no stages or only transformation stages, each {@link PipelineResult}
62-
* represents a single document.</li>
63-
* <li>If there is an aggregation, only a single {@link PipelineResult} is returned,
64-
* representing the aggregated results over the entire dataset .</li>
65-
* <li>If there is an aggregation stage with grouping, each {@link PipelineResult} represents a
66-
* distinct group and its associated aggregated values.</li>
67-
* </ul>
68-
*
69-
* <p>Example:
70-
*
71-
* ```typescript
72-
* const futureResults = await firestore.pipeline().collection("books")
73-
* .where(gt(Field.of("rating"), 4.5))
74-
* .select("title", "author", "rating")
75-
* .execute();
76-
* ```
77-
*
78-
* @return A Promise representing the asynchronous pipeline execution.
79-
*/
80-
execute(): Promise<PipelineResult[]> {
81-
const firestore = cast(this._db, Firestore);
82-
const client = ensureFirestoreConfigured(firestore);
83-
return firestoreClientExecutePipeline(client, this).then(result => {
84-
const docs = result
85-
// Currently ignore any response from ExecutePipeline that does
86-
// not contain any document data in the `fields` property.
87-
.filter(element => !!element.fields)
88-
.map(
89-
element =>
90-
new PipelineResult(
91-
this._userDataWriter,
92-
element.key?.path
93-
? new DocumentReference(firestore, null, element.key)
94-
: undefined,
95-
element.fields,
96-
element.executionTime?.toTimestamp(),
97-
element.createTime?.toTimestamp(),
98-
element.updateTime?.toTimestamp()
99-
)
100-
);
101-
102-
return docs;
103-
});
104-
}
10544
}

packages/firestore/src/api/pipeline_impl.ts

Lines changed: 67 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
import { Pipeline } from '../api/pipeline';
19+
import { firestoreClientExecutePipeline } from '../core/firestore_client';
1920
import { toPipeline } from '../core/pipeline-util';
2021
import { Pipeline as LitePipeline } from '../lite-api/pipeline';
2122
import { PipelineResult } from '../lite-api/pipeline-result';
@@ -24,8 +25,8 @@ import { Stage } from '../lite-api/stage';
2425
import { newUserDataReader } from '../lite-api/user_data_reader';
2526
import { cast } from '../util/input_validation';
2627

27-
import { Firestore } from './database';
28-
import { Query } from './reference';
28+
import { ensureFirestoreConfigured, Firestore } from './database';
29+
import { DocumentReference, Query } from './reference';
2930
import { ExpUserDataWriter } from './user_data_writer';
3031

3132
declare module './database' {
@@ -35,52 +36,78 @@ declare module './database' {
3536
}
3637

3738
/**
38-
* Experimental Modular API for console testing.
39-
* @param firestore
40-
*/
41-
export function pipeline(firestore: Firestore): PipelineSource<Pipeline>;
42-
43-
/**
44-
* Experimental Modular API for console testing.
45-
* @param query
39+
* Executes this pipeline and returns a Promise to represent the asynchronous operation.
40+
*
41+
* <p>The returned Promise can be used to track the progress of the pipeline execution
42+
* and retrieve the results (or handle any errors) asynchronously.
43+
*
44+
* <p>The pipeline results are returned as a list of {@link PipelineResult} objects. Each {@link
45+
* PipelineResult} typically represents a single key/value map that has passed through all the
46+
* stages of the pipeline, however this might differ depending on the stages involved in the
47+
* pipeline. For example:
48+
*
49+
* <ul>
50+
* <li>If there are no stages or only transformation stages, each {@link PipelineResult}
51+
* represents a single document.</li>
52+
* <li>If there is an aggregation, only a single {@link PipelineResult} is returned,
53+
* representing the aggregated results over the entire dataset .</li>
54+
* <li>If there is an aggregation stage with grouping, each {@link PipelineResult} represents a
55+
* distinct group and its associated aggregated values.</li>
56+
* </ul>
57+
*
58+
* <p>Example:
59+
*
60+
* ```typescript
61+
* const futureResults = await execute(firestore.pipeline().collection("books")
62+
* .where(gt(Field.of("rating"), 4.5))
63+
* .select("title", "author", "rating"));
64+
* ```
65+
*
66+
* @param pipeline The pipeline to execute.
67+
* @return A Promise representing the asynchronous pipeline execution.
4668
*/
47-
export function pipeline(query: Query): Pipeline;
48-
49-
export function pipeline(
50-
firestoreOrQuery: Firestore | Query
51-
): PipelineSource<Pipeline> | Pipeline {
52-
if (firestoreOrQuery instanceof Firestore) {
53-
const firestore = firestoreOrQuery;
54-
return new PipelineSource<Pipeline>(
55-
firestore._databaseId,
56-
(stages: Stage[]) => {
57-
return new Pipeline(
58-
firestore,
59-
newUserDataReader(firestore),
60-
new ExpUserDataWriter(firestore),
61-
stages
62-
);
63-
}
64-
);
65-
} else {
66-
const query = firestoreOrQuery;
67-
const db = cast<Firestore>(query.firestore, Firestore);
68-
69-
const litePipeline: LitePipeline = toPipeline(query._query, db);
70-
return cast<Pipeline>(litePipeline, Pipeline);
71-
}
72-
}
73-
7469
export function execute(pipeline: LitePipeline): Promise<PipelineResult[]> {
75-
return pipeline.execute();
70+
const firestore = cast(pipeline._db, Firestore);
71+
const client = ensureFirestoreConfigured(firestore);
72+
return firestoreClientExecutePipeline(client, pipeline).then(result => {
73+
const docs = result
74+
// Currently ignore any response from ExecutePipeline that does
75+
// not contain any document data in the `fields` property.
76+
.filter(element => !!element.fields)
77+
.map(
78+
element =>
79+
new PipelineResult(
80+
pipeline._userDataWriter,
81+
element.key?.path
82+
? new DocumentReference(firestore, null, element.key)
83+
: undefined,
84+
element.fields,
85+
element.executionTime?.toTimestamp(),
86+
element.createTime?.toTimestamp(),
87+
element.updateTime?.toTimestamp()
88+
)
89+
);
90+
91+
return docs;
92+
});
7693
}
7794

7895
// Augment the Firestore class with the pipeline() factory method
7996
Firestore.prototype.pipeline = function (): PipelineSource<Pipeline> {
80-
return pipeline(this);
97+
return new PipelineSource<Pipeline>(this._databaseId, (stages: Stage[]) => {
98+
return new Pipeline(
99+
this,
100+
newUserDataReader(this),
101+
new ExpUserDataWriter(this),
102+
stages
103+
);
104+
});
81105
};
82106

83107
// Augment the Query class with the pipeline() factory method
84108
Query.prototype.pipeline = function (): Pipeline {
85-
return pipeline(this);
109+
const db = cast<Firestore>(this.firestore, Firestore);
110+
111+
const litePipeline: LitePipeline = toPipeline(this._query, db);
112+
return cast<Pipeline>(litePipeline, Pipeline);
86113
};

packages/firestore/src/api_pipelines.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export { PipelineResult } from './lite-api/pipeline-result';
2121

2222
export { Pipeline } from './api/pipeline';
2323

24-
export { pipeline, execute } from './api/pipeline_impl';
24+
export { execute } from './api/pipeline_impl';
2525

2626
export {
2727
Stage,

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

Lines changed: 6 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@ import {
2222
Pipeline as ProtoPipeline,
2323
Stage as ProtoStage
2424
} from '../protos/firestore_proto_api';
25-
import { invokeExecutePipeline } from '../remote/datastore';
2625
import { JsonProtoSerializer, ProtoSerializable } from '../remote/serializer';
2726
import { isPlainObject } from '../util/input_validation';
2827

29-
import { getDatastore } from './components';
3028
import { Firestore } from './database';
3129
import {
3230
_mapValue,
@@ -40,8 +38,6 @@ import {
4038
Ordering,
4139
Selectable
4240
} from './expressions';
43-
import { PipelineResult } from './pipeline-result';
44-
import { DocumentReference } from './reference';
4541
import {
4642
AddFields,
4743
Aggregate,
@@ -99,23 +95,20 @@ function isReadableUserData(value: any): value is ReadableUserData {
9995
* const db: Firestore; // Assumes a valid firestore instance.
10096
*
10197
* // Example 1: Select specific fields and rename 'rating' to 'bookRating'
102-
* const results1 = await db.pipeline()
98+
* const results1 = await execute(db.pipeline()
10399
* .collection("books")
104-
* .select("title", "author", Field.of("rating").as("bookRating"))
105-
* .execute();
100+
* .select("title", "author", Field.of("rating").as("bookRating")));
106101
*
107102
* // Example 2: Filter documents where 'genre' is "Science Fiction" and 'published' is after 1950
108-
* const results2 = await db.pipeline()
103+
* const results2 = await execute(db.pipeline()
109104
* .collection("books")
110-
* .where(and(Field.of("genre").eq("Science Fiction"), Field.of("published").gt(1950)))
111-
* .execute();
105+
* .where(and(Field.of("genre").eq("Science Fiction"), Field.of("published").gt(1950))));
112106
*
113107
* // Example 3: Calculate the average rating of books published after 1980
114-
* const results3 = await db.pipeline()
108+
* const results3 = await execute(db.pipeline()
115109
* .collection("books")
116110
* .where(Field.of("published").gt(1980))
117-
* .aggregate(avg(Field.of("rating")).as("averageRating"))
118-
* .execute();
111+
* .aggregate(avg(Field.of("rating")).as("averageRating")));
119112
* ```
120113
*/
121114

@@ -760,62 +753,6 @@ export class Pipeline implements ProtoSerializable<ProtoPipeline> {
760753
return this._addStage(new GenericStage(name, expressionParams));
761754
}
762755

763-
/**
764-
* Executes this pipeline and returns a Promise to represent the asynchronous operation.
765-
*
766-
* <p>The returned Promise can be used to track the progress of the pipeline execution
767-
* and retrieve the results (or handle any errors) asynchronously.
768-
*
769-
* <p>The pipeline results are returned as a list of {@link PipelineResult} objects. Each {@link
770-
* PipelineResult} typically represents a single key/value map that has passed through all the
771-
* stages of the pipeline, however this might differ depending on the stages involved in the
772-
* pipeline. For example:
773-
*
774-
* <ul>
775-
* <li>If there are no stages or only transformation stages, each {@link PipelineResult}
776-
* represents a single document.</li>
777-
* <li>If there is an aggregation, only a single {@link PipelineResult} is returned,
778-
* representing the aggregated results over the entire dataset .</li>
779-
* <li>If there is an aggregation stage with grouping, each {@link PipelineResult} represents a
780-
* distinct group and its associated aggregated values.</li>
781-
* </ul>
782-
*
783-
* <p>Example:
784-
*
785-
* ```typescript
786-
* const futureResults = await firestore.pipeline().collection("books")
787-
* .where(gt(Field.of("rating"), 4.5))
788-
* .select("title", "author", "rating")
789-
* .execute();
790-
* ```
791-
*
792-
* @return A Promise representing the asynchronous pipeline execution.
793-
*/
794-
execute(): Promise<PipelineResult[]> {
795-
const datastore = getDatastore(this._db);
796-
return invokeExecutePipeline(datastore, this).then(result => {
797-
return (
798-
result
799-
// Currently ignore any response from ExecutePipeline that does
800-
// not contain any document data in the `fields` property.
801-
.filter(element => !!element.fields)
802-
.map(
803-
element =>
804-
new PipelineResult(
805-
this._userDataWriter,
806-
element.key?.path
807-
? new DocumentReference(this._db, null, element.key)
808-
: undefined,
809-
element.fields,
810-
element.executionTime?.toTimestamp(),
811-
element.createTime?.toTimestamp(),
812-
element.updateTime?.toTimestamp()
813-
)
814-
)
815-
);
816-
});
817-
}
818-
819756
/**
820757
* @internal
821758
* @private

0 commit comments

Comments
 (0)