18
18
19
19
#include < memory>
20
20
21
+ #import " Firestore/Source/API/FIRDocumentReference+Internal.h"
21
22
#import " Firestore/Source/API/FIRFirestore+Internal.h"
22
23
#import " Firestore/Source/API/FIRPipelineBridge+Internal.h"
24
+ #import " Firestore/Source/API/FSTUserDataReader.h"
25
+ #import " Firestore/Source/API/FSTUserDataWriter.h"
23
26
27
+ #include " Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h"
28
+
29
+ #include " Firestore/core/src/api/document_reference.h"
24
30
#include " Firestore/core/src/api/expressions.h"
25
31
#include " Firestore/core/src/api/pipeline.h"
26
32
#include " Firestore/core/src/api/pipeline_result.h"
32
38
33
39
using firebase::firestore::api::CollectionSource;
34
40
using firebase::firestore::api::Constant;
41
+ using firebase::firestore::api::DocumentReference;
35
42
using firebase::firestore::api::Expr;
36
43
using firebase::firestore::api::Field;
37
44
using firebase::firestore::api::FunctionExpr;
38
45
using firebase::firestore::api::Pipeline;
39
46
using firebase::firestore::api::Where;
40
47
using firebase::firestore::util::MakeCallback;
48
+ using firebase::firestore::util::MakeNSString;
41
49
using firebase::firestore::util::MakeString;
42
50
43
51
NS_ASSUME_NONNULL_BEGIN
@@ -57,47 +65,60 @@ - (id)init:(NSString *)name {
57
65
return self;
58
66
}
59
67
60
- - (std::shared_ptr<api::Expr>)cpp_expr {
68
+ - (std::shared_ptr<api::Expr>)cppExprWithReader : (FSTUserDataReader *) reader {
61
69
return field;
62
70
}
63
71
64
72
@end
65
73
66
74
@implementation FIRConstantBridge {
67
75
std::shared_ptr<Constant> constant;
76
+ id _input;
77
+ Boolean isUserDataRead;
68
78
}
69
- - (id )init : (NSNumber *) value {
79
+ - (id )init : (id ) input {
70
80
self = [super init ];
71
- if (self) {
72
- constant = std::make_shared<Constant>(value.doubleValue );
73
- }
81
+ _input = input;
82
+ isUserDataRead = NO ;
74
83
return self;
75
84
}
76
85
77
- - (std::shared_ptr<api::Expr>)cpp_expr {
86
+ - (std::shared_ptr<api::Expr>)cppExprWithReader : (FSTUserDataReader *)reader {
87
+ if (!isUserDataRead) {
88
+ constant = std::make_shared<Constant>([reader parsedQueryValue: _input]);
89
+ }
90
+
91
+ isUserDataRead = YES ;
78
92
return constant;
79
93
}
80
94
81
95
@end
82
96
83
97
@implementation FIRFunctionExprBridge {
84
98
std::shared_ptr<FunctionExpr> eq;
99
+ NSString *_name;
100
+ NSArray <FIRExprBridge *> *_args;
101
+ Boolean isUserDataRead;
85
102
}
86
103
87
104
- (nonnull id )initWithName : (NSString *)name Args : (nonnull NSArray <FIRExprBridge *> *)args {
88
105
self = [super init ];
89
- if (self) {
106
+ _name = name;
107
+ _args = args;
108
+ isUserDataRead = NO ;
109
+ return self;
110
+ }
111
+
112
+ - (std::shared_ptr<api::Expr>)cppExprWithReader : (FSTUserDataReader *)reader {
113
+ if (!isUserDataRead) {
90
114
std::vector<std::shared_ptr<Expr>> cpp_args;
91
- for (FIRExprBridge *arg in args ) {
92
- cpp_args.push_back (arg. cpp_expr );
115
+ for (FIRExprBridge *arg in _args ) {
116
+ cpp_args.push_back ([ arg cppExprWithReader: reader] );
93
117
}
94
-
95
- eq = std::make_shared<FunctionExpr>(MakeString (name), std::move (cpp_args));
118
+ eq = std::make_shared<FunctionExpr>(MakeString (_name), std::move (cpp_args));
96
119
}
97
- return self;
98
- }
99
120
100
- - (std::shared_ptr<api::Expr>) cpp_expr {
121
+ isUserDataRead = YES ;
101
122
return eq;
102
123
}
103
124
@@ -118,63 +139,142 @@ - (id)initWithPath:(NSString *)path {
118
139
return self;
119
140
}
120
141
121
- - (std::shared_ptr<api::Stage>)cpp_stage {
142
+ - (std::shared_ptr<api::Stage>)cppStageWithReader : (FSTUserDataReader *) reader {
122
143
return collection_source;
123
144
}
124
145
125
146
@end
126
147
127
148
@implementation FIRWhereStageBridge {
149
+ FIRExprBridge *_exprBridge;
150
+ Boolean isUserDataRead;
128
151
std::shared_ptr<Where> where;
129
152
}
130
153
131
154
- (id )initWithExpr : (FIRExprBridge *)expr {
132
155
self = [super init ];
133
156
if (self) {
134
- where = std::make_shared<Where>(expr.cpp_expr );
157
+ _exprBridge = expr;
158
+ isUserDataRead = NO ;
135
159
}
136
160
return self;
137
161
}
138
162
139
- - (std::shared_ptr<api::Stage>)cpp_stage {
163
+ - (std::shared_ptr<api::Stage>)cppStageWithReader : (FSTUserDataReader *)reader {
164
+ if (!isUserDataRead) {
165
+ where = std::make_shared<Where>([_exprBridge cppExprWithReader: reader]);
166
+ }
167
+
168
+ isUserDataRead = YES ;
140
169
return where;
141
170
}
142
171
143
172
@end
144
173
174
+ @interface __FIRPipelineSnapshotBridge ()
175
+
176
+ @property (nonatomic , strong , readwrite ) NSArray <__FIRPipelineSnapshotBridge *> *results;
177
+
178
+ @end
179
+
145
180
@implementation __FIRPipelineSnapshotBridge {
146
- absl::optional<api::PipelineSnapshot> pipeline;
181
+ absl::optional<api::PipelineSnapshot> snapshot_;
182
+ NSMutableArray <__FIRPipelineResultBridge *> *results_;
147
183
}
148
184
149
185
- (id )initWithCppSnapshot : (api::PipelineSnapshot)snapshot {
150
186
self = [super init ];
151
187
if (self) {
152
- pipeline = std::move (snapshot);
188
+ snapshot_ = std::move (snapshot);
189
+ if (!snapshot_.has_value ()) {
190
+ results_ = nil ;
191
+ } else {
192
+ NSMutableArray <__FIRPipelineResultBridge *> *results = [NSMutableArray array ];
193
+ for (auto &result : snapshot_.value ().results ()) {
194
+ [results addObject: [[__FIRPipelineResultBridge alloc ]
195
+ initWithCppResult: result
196
+ db: snapshot_.value ().firestore ()]];
197
+ }
198
+ results_ = results;
199
+ }
153
200
}
154
201
155
202
return self;
156
203
}
157
204
205
+ - (NSArray <__FIRPipelineResultBridge *> *)results {
206
+ return results_;
207
+ }
208
+
158
209
@end
159
210
160
- @implementation FIRPipelineBridge {
161
- std::shared_ptr<Pipeline> pipeline;
211
+ @implementation __FIRPipelineResultBridge {
212
+ api::PipelineResult _result;
213
+ std::shared_ptr<api::Firestore> _db;
162
214
}
163
215
164
- - (id )initWithStages : (NSArray <FIRStageBridge *> *)stages db : (FIRFirestore *)db {
216
+ - (FIRDocumentReference *)reference {
217
+ if (!_result.internal_key ().has_value ()) return nil ;
218
+
219
+ return [[FIRDocumentReference alloc ] initWithKey: _result.internal_key ().value () firestore: _db];
220
+ }
221
+
222
+ - (NSString *)documentID {
223
+ if (!_result.document_id ().has_value ()) {
224
+ return nil ;
225
+ }
226
+
227
+ return MakeNSString (_result.document_id ().value ());
228
+ }
229
+
230
+ - (id )initWithCppResult : (api::PipelineResult)result db : (std::shared_ptr<api::Firestore>)db {
165
231
self = [super init ];
166
232
if (self) {
167
- std::vector<std::shared_ptr<firebase::firestore::api::Stage>> cpp_stages;
168
- for (FIRStageBridge *stage in stages) {
169
- cpp_stages.push_back (stage.cpp_stage );
170
- }
171
- pipeline = std::make_shared<Pipeline>(cpp_stages, db.wrapped );
233
+ _result = std::move (result);
234
+ _db = std::move (db);
172
235
}
236
+
173
237
return self;
174
238
}
175
239
240
+ - (nullable NSDictionary <NSString *, id> *)data {
241
+ return [self dataWithServerTimestampBehavior: FIRServerTimestampBehaviorNone];
242
+ }
243
+
244
+ - (nullable NSDictionary <NSString *, id> *)dataWithServerTimestampBehavior :
245
+ (FIRServerTimestampBehavior)serverTimestampBehavior {
246
+ absl::optional<firebase::firestore::google_firestore_v1_Value> data =
247
+ _result.internal_value ()->Get ();
248
+ if (!data) return nil ;
249
+
250
+ FSTUserDataWriter *dataWriter =
251
+ [[FSTUserDataWriter alloc ] initWithFirestore: _db
252
+ serverTimestampBehavior: serverTimestampBehavior];
253
+ return [dataWriter convertedValue: *data];
254
+ }
255
+
256
+ @end
257
+
258
+ @implementation FIRPipelineBridge {
259
+ NSArray <FIRStageBridge *> *_stages;
260
+ FIRFirestore *firestore;
261
+ std::shared_ptr<Pipeline> pipeline;
262
+ }
263
+
264
+ - (id )initWithStages : (NSArray <FIRStageBridge *> *)stages db : (FIRFirestore *)db {
265
+ _stages = stages;
266
+ firestore = db;
267
+ return [super init ];
268
+ }
269
+
176
270
- (void )executeWithCompletion : (void (^)(__FIRPipelineSnapshotBridge *_Nullable result,
177
271
NSError *_Nullable error))completion {
272
+ std::vector<std::shared_ptr<firebase::firestore::api::Stage>> cpp_stages;
273
+ for (FIRStageBridge *stage in _stages) {
274
+ cpp_stages.push_back ([stage cppStageWithReader: firestore.dataReader]);
275
+ }
276
+ pipeline = std::make_shared<Pipeline>(cpp_stages, firestore.wrapped );
277
+
178
278
pipeline->execute ([completion](StatusOr<api::PipelineSnapshot> maybe_value) {
179
279
if (maybe_value.ok ()) {
180
280
__FIRPipelineSnapshotBridge *bridge = [[__FIRPipelineSnapshotBridge alloc ]
0 commit comments