Skip to content

Commit 3c86df9

Browse files
committed
Firestore pipeline prototype
1 parent 8b099b2 commit 3c86df9

35 files changed

+1283
-4
lines changed

Firestore/Example/Firestore.xcodeproj/project.pbxproj

+17-4
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@
127127
11F8EE69182C9699E90A9E3D /* database_info_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB38D92E20235D22000A432D /* database_info_test.cc */; };
128128
12158DFCEE09D24B7988A340 /* maybe_document.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE7E20B89AAC00B5BCE7 /* maybe_document.pb.cc */; };
129129
121F0FB9DCCBFB7573C7AF48 /* bundle_serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C2A94EE24E60543F62CC35 /* bundle_serializer_test.cc */; };
130+
12260A2A2D56A3CE001766EB /* PipelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12260A292D56A3CE001766EB /* PipelineTests.swift */; };
131+
12260A2B2D56A3CE001766EB /* PipelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12260A292D56A3CE001766EB /* PipelineTests.swift */; };
132+
12260A2C2D56A3CE001766EB /* PipelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12260A292D56A3CE001766EB /* PipelineTests.swift */; };
130133
124AAEE987451820F24EEA8E /* user_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CCC9BD953F121B9E29F9AA42 /* user_test.cc */; };
131134
125B1048ECB755C2106802EB /* executor_std_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4687208F9B9100554BA2 /* executor_std_test.cc */; };
132135
1290FA77A922B76503AE407C /* lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 277EAACC4DD7C21332E8496A /* lru_garbage_collector_test.cc */; };
@@ -1735,6 +1738,7 @@
17351738
0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json; sourceTree = "<group>"; };
17361739
0EE5300F8233D14025EF0456 /* string_apple_test.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = string_apple_test.mm; sourceTree = "<group>"; };
17371740
11984BA0A99D7A7ABA5B0D90 /* Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS/Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.release.xcconfig"; sourceTree = "<group>"; };
1741+
12260A292D56A3CE001766EB /* PipelineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PipelineTests.swift; sourceTree = "<group>"; };
17381742
1235769122B7E915007DDFA9 /* EncodableFieldValueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncodableFieldValueTests.swift; sourceTree = "<group>"; };
17391743
1235769422B86E65007DDFA9 /* FirestoreEncoderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FirestoreEncoderTests.swift; sourceTree = "<group>"; };
17401744
124C932B22C1642C00CA8C2D /* CodableIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableIntegrationTests.swift; sourceTree = "<group>"; };
@@ -1797,7 +1801,7 @@
17971801
4334F87873015E3763954578 /* status_testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = status_testing.h; sourceTree = "<group>"; };
17981802
4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json; sourceTree = "<group>"; };
17991803
444B7AB3F5A2929070CB1363 /* hard_assert_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = hard_assert_test.cc; sourceTree = "<group>"; };
1800-
4564AD9C55EC39C080EB9476 /* globals_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; path = globals_cache_test.cc; sourceTree = "<group>"; };
1804+
4564AD9C55EC39C080EB9476 /* globals_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = globals_cache_test.cc; sourceTree = "<group>"; };
18011805
478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json; sourceTree = "<group>"; };
18021806
48D0915834C3D234E5A875A9 /* grpc_stream_tester.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = grpc_stream_tester.h; sourceTree = "<group>"; };
18031807
4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json; sourceTree = "<group>"; };
@@ -1915,7 +1919,7 @@
19151919
5B5414D28802BC76FDADABD6 /* stream_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = stream_test.cc; sourceTree = "<group>"; };
19161920
5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json; sourceTree = "<group>"; };
19171921
5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_1_01_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_membership_test_result.json; sourceTree = "<group>"; };
1918-
5C6DEA63FBDE19D841291723 /* memory_globals_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; path = memory_globals_cache_test.cc; sourceTree = "<group>"; };
1922+
5C6DEA63FBDE19D841291723 /* memory_globals_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = memory_globals_cache_test.cc; sourceTree = "<group>"; };
19191923
5C7942B6244F4C416B11B86C /* leveldb_mutation_queue_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_mutation_queue_test.cc; sourceTree = "<group>"; };
19201924
5CAE131920FFFED600BE9A4A /* Firestore_Benchmarks_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Firestore_Benchmarks_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
19211925
5CAE131D20FFFED600BE9A4A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -2296,6 +2300,7 @@
22962300
124C932B22C1642C00CA8C2D /* CodableIntegrationTests.swift */,
22972301
3355BE9391CC4857AF0BDAE3 /* DatabaseTests.swift */,
22982302
62E54B832A9E910A003347C8 /* IndexingTests.swift */,
2303+
12260A292D56A3CE001766EB /* PipelineTests.swift */,
22992304
621D620928F9CE7400D2FA26 /* QueryIntegrationTests.swift */,
23002305
4D65F6E69993611D47DC8E7C /* SnapshotListenerSourceTests.swift */,
23012306
EFF22EA92C5060A4009A369B /* VectorIntegrationTests.swift */,
@@ -3381,6 +3386,9 @@
33813386
ProvisioningStyle = Automatic;
33823387
TestTargetID = 6003F589195388D20070C39A;
33833388
};
3389+
6003F589195388D20070C39A = {
3390+
DevelopmentTeam = PP3FQRCL4W;
3391+
};
33843392
6003F5AD195388D20070C39A = {
33853393
CreatedOnToolsVersion = 9.0;
33863394
DevelopmentTeam = EQHXZ8M8AV;
@@ -3401,7 +3409,7 @@
34013409
};
34023410
DE03B2941F2149D600A30B9C = {
34033411
CreatedOnToolsVersion = 9.0;
3404-
DevelopmentTeam = EQHXZ8M8AV;
3412+
DevelopmentTeam = PP3FQRCL4W;
34053413
};
34063414
};
34073415
};
@@ -4685,6 +4693,7 @@
46854693
432056C4D1259F76C80FC2A8 /* FSTUserDataReaderTests.mm in Sources */,
46864694
3B1E27D951407FD237E64D07 /* FirestoreEncoderTests.swift in Sources */,
46874695
62E54B862A9E910B003347C8 /* IndexingTests.swift in Sources */,
4696+
12260A2C2D56A3CE001766EB /* PipelineTests.swift in Sources */,
46884697
621D620C28F9CE7400D2FA26 /* QueryIntegrationTests.swift in Sources */,
46894698
1CFBD4563960D8A20C4679A3 /* SnapshotListenerSourceTests.swift in Sources */,
46904699
EFF22EAC2C5060A4009A369B /* VectorIntegrationTests.swift in Sources */,
@@ -4935,6 +4944,7 @@
49354944
75A176239B37354588769206 /* FSTUserDataReaderTests.mm in Sources */,
49364945
5E89B1A5A5430713C79C4854 /* FirestoreEncoderTests.swift in Sources */,
49374946
62E54B852A9E910B003347C8 /* IndexingTests.swift in Sources */,
4947+
12260A2B2D56A3CE001766EB /* PipelineTests.swift in Sources */,
49384948
621D620B28F9CE7400D2FA26 /* QueryIntegrationTests.swift in Sources */,
49394949
A0BC30D482B0ABD1A3A24CDC /* SnapshotListenerSourceTests.swift in Sources */,
49404950
EFF22EAB2C5060A4009A369B /* VectorIntegrationTests.swift in Sources */,
@@ -5440,6 +5450,7 @@
54405450
F5BDECEB3B43BD1591EEADBD /* FSTUserDataReaderTests.mm in Sources */,
54415451
6F45846C159D3C063DBD3CBE /* FirestoreEncoderTests.swift in Sources */,
54425452
62E54B842A9E910B003347C8 /* IndexingTests.swift in Sources */,
5453+
12260A2A2D56A3CE001766EB /* PipelineTests.swift in Sources */,
54435454
621D620A28F9CE7400D2FA26 /* QueryIntegrationTests.swift in Sources */,
54445455
B00F8D1819EE20C45B660940 /* SnapshotListenerSourceTests.swift in Sources */,
54455456
EFF22EAA2C5060A4009A369B /* VectorIntegrationTests.swift in Sources */,
@@ -6097,6 +6108,7 @@
60976108
buildSettings = {
60986109
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
60996110
CLANG_ENABLE_MODULES = YES;
6111+
DEVELOPMENT_TEAM = PP3FQRCL4W;
61006112
GCC_PRECOMPILE_PREFIX_HEADER = YES;
61016113
GCC_PREFIX_HEADER = "";
61026114
HEADER_SEARCH_PATHS = (
@@ -6119,6 +6131,7 @@
61196131
buildSettings = {
61206132
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
61216133
CLANG_ENABLE_MODULES = YES;
6134+
DEVELOPMENT_TEAM = PP3FQRCL4W;
61226135
GCC_PRECOMPILE_PREFIX_HEADER = YES;
61236136
GCC_PREFIX_HEADER = "";
61246137
HEADER_SEARCH_PATHS = (
@@ -6367,7 +6380,7 @@
63676380
baseConfigurationReference = 1277F98C20D2DF0867496976 /* Pods-Firestore_IntegrationTests_iOS.debug.xcconfig */;
63686381
buildSettings = {
63696382
BUNDLE_LOADER = "$(TEST_HOST)";
6370-
DEVELOPMENT_TEAM = EQHXZ8M8AV;
6383+
DEVELOPMENT_TEAM = PP3FQRCL4W;
63716384
GCC_PRECOMPILE_PREFIX_HEADER = YES;
63726385
GCC_PREFIX_HEADER = "";
63736386
GCC_PREPROCESSOR_DEFINITIONS = (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2025 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "FIRPipelineBridge.h"
18+
19+
#include <memory>
20+
21+
#include "Firestore/core/src/api/expressions.h"
22+
#include "Firestore/core/src/api/pipeline.h"
23+
#include "Firestore/core/src/api/stages.h"
24+
25+
@class FIRFilter;
26+
27+
namespace api = firebase::firestore::api;
28+
29+
NS_ASSUME_NONNULL_BEGIN
30+
31+
@interface FIRExprBridge (Internal)
32+
33+
- (std::shared_ptr<api::Expr>)cpp_expr;
34+
35+
@end
36+
37+
@interface FIRStageBridge (Internal)
38+
39+
- (std::shared_ptr<api::Stage>)cpp_stage;
40+
41+
@end
42+
43+
@interface __FIRPipelineSnapshotBridge (Internal)
44+
45+
- (id)initWithCppSnapshot:(api::PipelineSnapshot)snapshot;
46+
47+
@end
48+
49+
NS_ASSUME_NONNULL_END
+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
//
2+
// FIRExprBridge.m
3+
// FirebaseFirestoreInternal
4+
//
5+
// Created by Hui Wu on 2/25/25.
6+
//
7+
8+
#import "FIRPipelineBridge.h"
9+
10+
#include <memory>
11+
12+
#import "Firestore/Source/API/FIRFirestore+Internal.h"
13+
#import "Firestore/Source/API/FIRPipelineBridge+Internal.h"
14+
15+
#include "Firestore/core/src/api/expressions.h"
16+
#include "Firestore/core/src/api/pipeline.h"
17+
#include "Firestore/core/src/api/pipeline_result.h"
18+
#include "Firestore/core/src/api/pipeline_snapshot.h"
19+
#include "Firestore/core/src/api/stages.h"
20+
#include "Firestore/core/src/util/error_apple.h"
21+
#include "Firestore/core/src/util/status.h"
22+
#include "Firestore/core/src/util/string_apple.h"
23+
24+
using firebase::firestore::api::CollectionSource;
25+
using firebase::firestore::api::Constant;
26+
using firebase::firestore::api::Eq;
27+
using firebase::firestore::api::Expr;
28+
using firebase::firestore::api::Field;
29+
using firebase::firestore::api::Pipeline;
30+
using firebase::firestore::api::Where;
31+
using firebase::firestore::util::MakeCallback;
32+
using firebase::firestore::util::MakeString;
33+
34+
NS_ASSUME_NONNULL_BEGIN
35+
36+
@implementation FIRExprBridge
37+
@end
38+
39+
@implementation FIRFieldBridge {
40+
std::shared_ptr<Field> field;
41+
}
42+
43+
- (id)init:(NSString *)name {
44+
self = [super init];
45+
if (self) {
46+
field = std::make_shared<Field>(MakeString(name));
47+
}
48+
return self;
49+
}
50+
51+
- (std::shared_ptr<api::Expr>)cpp_expr {
52+
return field;
53+
}
54+
55+
@end
56+
57+
@implementation FIRConstantBridge {
58+
std::shared_ptr<Constant> constant;
59+
}
60+
- (id)init:(NSNumber *)value {
61+
self = [super init];
62+
if (self) {
63+
constant = std::make_shared<Constant>(value.doubleValue);
64+
}
65+
return self;
66+
}
67+
68+
- (std::shared_ptr<api::Expr>)cpp_expr {
69+
return constant;
70+
}
71+
72+
@end
73+
74+
@implementation FIREqFunctionBridge {
75+
std::shared_ptr<Eq> eq;
76+
}
77+
- (id)initWithLeft:(FIRExprBridge *)left right:(FIRExprBridge *)right {
78+
self = [super init];
79+
if (self) {
80+
eq = std::make_shared<Eq>(left.cpp_expr, right.cpp_expr);
81+
}
82+
return self;
83+
}
84+
85+
- (std::shared_ptr<api::Expr>)cpp_expr {
86+
return eq;
87+
}
88+
89+
@end
90+
91+
@implementation FIRStageBridge
92+
@end
93+
94+
@implementation FIRCollectionSourceStageBridge {
95+
std::shared_ptr<CollectionSource> collection_source;
96+
}
97+
98+
- (id)initWithPath:(NSString *)path {
99+
self = [super init];
100+
if (self) {
101+
collection_source = std::make_shared<CollectionSource>(MakeString(path));
102+
}
103+
return self;
104+
}
105+
106+
- (std::shared_ptr<api::Stage>)cpp_stage {
107+
return collection_source;
108+
}
109+
110+
@end
111+
112+
@implementation FIRWhereStageBridge {
113+
std::shared_ptr<Where> where;
114+
}
115+
116+
- (id)initWithExpr:(FIRExprBridge *)expr {
117+
self = [super init];
118+
if (self) {
119+
where = std::make_shared<Where>(expr.cpp_expr);
120+
}
121+
return self;
122+
}
123+
124+
- (std::shared_ptr<api::Stage>)cpp_stage {
125+
return where;
126+
}
127+
128+
@end
129+
130+
@implementation __FIRPipelineSnapshotBridge {
131+
absl::optional<api::PipelineSnapshot> pipeline;
132+
}
133+
134+
- (id)initWithCppSnapshot:(api::PipelineSnapshot)snapshot {
135+
self = [super init];
136+
if (self) {
137+
pipeline = std::move(snapshot);
138+
}
139+
140+
return self;
141+
}
142+
143+
@end
144+
145+
@implementation FIRPipelineBridge {
146+
std::shared_ptr<Pipeline> pipeline;
147+
}
148+
149+
- (id)initWithStages:(NSArray<FIRStageBridge *> *)stages db:(FIRFirestore *)db {
150+
self = [super init];
151+
if (self) {
152+
std::vector<std::shared_ptr<firebase::firestore::api::Stage>> cpp_stages;
153+
for (FIRStageBridge *stage in stages) {
154+
cpp_stages.push_back(stage.cpp_stage);
155+
}
156+
pipeline = std::make_shared<Pipeline>(cpp_stages, db.wrapped);
157+
}
158+
return self;
159+
}
160+
161+
- (void)executeWithCompletion:(void (^)(__FIRPipelineSnapshotBridge *_Nullable result,
162+
NSError *_Nullable error))completion {
163+
pipeline->execute([completion](StatusOr<api::PipelineSnapshot> maybe_value) {
164+
if (maybe_value.ok()) {
165+
__FIRPipelineSnapshotBridge *bridge = [[__FIRPipelineSnapshotBridge alloc]
166+
initWithCppSnapshot:std::move(maybe_value).ValueOrDie()];
167+
completion(bridge, nil);
168+
} else {
169+
completion(nil, MakeNSError(std::move(maybe_value).status()));
170+
}
171+
});
172+
}
173+
174+
@end
175+
176+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)