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
11 changes: 9 additions & 2 deletions Firestore/Source/API/FIRPipelineBridge+Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <memory>

#include "Firestore/core/src/api/expressions.h"
#include "Firestore/core/src/api/firestore.h"
#include "Firestore/core/src/api/pipeline.h"
#include "Firestore/core/src/api/stages.h"

Expand All @@ -30,13 +31,13 @@ NS_ASSUME_NONNULL_BEGIN

@interface FIRExprBridge (Internal)

- (std::shared_ptr<api::Expr>)cpp_expr;
- (std::shared_ptr<api::Expr>)cppExprWithReader:(FSTUserDataReader *)reader;

@end

@interface FIRStageBridge (Internal)

- (std::shared_ptr<api::Stage>)cpp_stage;
- (std::shared_ptr<api::Stage>)cppStageWithReader:(FSTUserDataReader *)reader;

@end

Expand All @@ -46,4 +47,10 @@ NS_ASSUME_NONNULL_BEGIN

@end

@interface __FIRPipelineResultBridge (Internal)

- (id)initWithCppResult:(api::PipelineResult)result db:(std::shared_ptr<api::Firestore>)db;

@end

NS_ASSUME_NONNULL_END
154 changes: 127 additions & 27 deletions Firestore/Source/API/FIRPipelineBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@

#include <memory>

#import "Firestore/Source/API/FIRDocumentReference+Internal.h"
#import "Firestore/Source/API/FIRFirestore+Internal.h"
#import "Firestore/Source/API/FIRPipelineBridge+Internal.h"
#import "Firestore/Source/API/FSTUserDataReader.h"
#import "Firestore/Source/API/FSTUserDataWriter.h"

#include "Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h"

#include "Firestore/core/src/api/document_reference.h"
#include "Firestore/core/src/api/expressions.h"
#include "Firestore/core/src/api/pipeline.h"
#include "Firestore/core/src/api/pipeline_result.h"
Expand All @@ -32,12 +38,14 @@

using firebase::firestore::api::CollectionSource;
using firebase::firestore::api::Constant;
using firebase::firestore::api::DocumentReference;
using firebase::firestore::api::Expr;
using firebase::firestore::api::Field;
using firebase::firestore::api::FunctionExpr;
using firebase::firestore::api::Pipeline;
using firebase::firestore::api::Where;
using firebase::firestore::util::MakeCallback;
using firebase::firestore::util::MakeNSString;
using firebase::firestore::util::MakeString;

NS_ASSUME_NONNULL_BEGIN
Expand All @@ -57,47 +65,60 @@ - (id)init:(NSString *)name {
return self;
}

- (std::shared_ptr<api::Expr>)cpp_expr {
- (std::shared_ptr<api::Expr>)cppExprWithReader:(FSTUserDataReader *)reader {
return field;
}

@end

@implementation FIRConstantBridge {
std::shared_ptr<Constant> constant;
id _input;
Boolean isUserDataRead;
}
- (id)init:(NSNumber *)value {
- (id)init:(id)input {
self = [super init];
if (self) {
constant = std::make_shared<Constant>(value.doubleValue);
}
_input = input;
isUserDataRead = NO;
return self;
}

- (std::shared_ptr<api::Expr>)cpp_expr {
- (std::shared_ptr<api::Expr>)cppExprWithReader:(FSTUserDataReader *)reader {
if (!isUserDataRead) {
constant = std::make_shared<Constant>([reader parsedQueryValue:_input]);
}

isUserDataRead = YES;
return constant;
}

@end

@implementation FIRFunctionExprBridge {
std::shared_ptr<FunctionExpr> eq;
NSString *_name;
NSArray<FIRExprBridge *> *_args;
Boolean isUserDataRead;
}

- (nonnull id)initWithName:(NSString *)name Args:(nonnull NSArray<FIRExprBridge *> *)args {
self = [super init];
if (self) {
_name = name;
_args = args;
isUserDataRead = NO;
return self;
}

- (std::shared_ptr<api::Expr>)cppExprWithReader:(FSTUserDataReader *)reader {
if (!isUserDataRead) {
std::vector<std::shared_ptr<Expr>> cpp_args;
for (FIRExprBridge *arg in args) {
cpp_args.push_back(arg.cpp_expr);
for (FIRExprBridge *arg in _args) {
cpp_args.push_back([arg cppExprWithReader:reader]);
}

eq = std::make_shared<FunctionExpr>(MakeString(name), std::move(cpp_args));
eq = std::make_shared<FunctionExpr>(MakeString(_name), std::move(cpp_args));
}
return self;
}

- (std::shared_ptr<api::Expr>)cpp_expr {
isUserDataRead = YES;
return eq;
}

Expand All @@ -118,63 +139,142 @@ - (id)initWithPath:(NSString *)path {
return self;
}

- (std::shared_ptr<api::Stage>)cpp_stage {
- (std::shared_ptr<api::Stage>)cppStageWithReader:(FSTUserDataReader *)reader {
return collection_source;
}

@end

@implementation FIRWhereStageBridge {
FIRExprBridge *_exprBridge;
Boolean isUserDataRead;
std::shared_ptr<Where> where;
}

- (id)initWithExpr:(FIRExprBridge *)expr {
self = [super init];
if (self) {
where = std::make_shared<Where>(expr.cpp_expr);
_exprBridge = expr;
isUserDataRead = NO;
}
return self;
}

- (std::shared_ptr<api::Stage>)cpp_stage {
- (std::shared_ptr<api::Stage>)cppStageWithReader:(FSTUserDataReader *)reader {
if (!isUserDataRead) {
where = std::make_shared<Where>([_exprBridge cppExprWithReader:reader]);
}

isUserDataRead = YES;
return where;
}

@end

@interface __FIRPipelineSnapshotBridge ()

@property(nonatomic, strong, readwrite) NSArray<__FIRPipelineSnapshotBridge *> *results;

@end

@implementation __FIRPipelineSnapshotBridge {
absl::optional<api::PipelineSnapshot> pipeline;
absl::optional<api::PipelineSnapshot> snapshot_;
NSMutableArray<__FIRPipelineResultBridge *> *results_;
}

- (id)initWithCppSnapshot:(api::PipelineSnapshot)snapshot {
self = [super init];
if (self) {
pipeline = std::move(snapshot);
snapshot_ = std::move(snapshot);
if (!snapshot_.has_value()) {
results_ = nil;
} else {
NSMutableArray<__FIRPipelineResultBridge *> *results = [NSMutableArray array];
for (auto &result : snapshot_.value().results()) {
[results addObject:[[__FIRPipelineResultBridge alloc]
initWithCppResult:result
db:snapshot_.value().firestore()]];
}
results_ = results;
}
}

return self;
}

- (NSArray<__FIRPipelineResultBridge *> *)results {
return results_;
}

@end

@implementation FIRPipelineBridge {
std::shared_ptr<Pipeline> pipeline;
@implementation __FIRPipelineResultBridge {
api::PipelineResult _result;
std::shared_ptr<api::Firestore> _db;
}

- (id)initWithStages:(NSArray<FIRStageBridge *> *)stages db:(FIRFirestore *)db {
- (FIRDocumentReference *)reference {
if (!_result.internal_key().has_value()) return nil;

return [[FIRDocumentReference alloc] initWithKey:_result.internal_key().value() firestore:_db];
}

- (NSString *)documentID {
if (!_result.document_id().has_value()) {
return nil;
}

return MakeNSString(_result.document_id().value());
}

- (id)initWithCppResult:(api::PipelineResult)result db:(std::shared_ptr<api::Firestore>)db {
self = [super init];
if (self) {
std::vector<std::shared_ptr<firebase::firestore::api::Stage>> cpp_stages;
for (FIRStageBridge *stage in stages) {
cpp_stages.push_back(stage.cpp_stage);
}
pipeline = std::make_shared<Pipeline>(cpp_stages, db.wrapped);
_result = std::move(result);
_db = std::move(db);
}

return self;
}

- (nullable NSDictionary<NSString *, id> *)data {
return [self dataWithServerTimestampBehavior:FIRServerTimestampBehaviorNone];
}

- (nullable NSDictionary<NSString *, id> *)dataWithServerTimestampBehavior:
(FIRServerTimestampBehavior)serverTimestampBehavior {
absl::optional<firebase::firestore::google_firestore_v1_Value> data =
_result.internal_value()->Get();
if (!data) return nil;

FSTUserDataWriter *dataWriter =
[[FSTUserDataWriter alloc] initWithFirestore:_db
serverTimestampBehavior:serverTimestampBehavior];
return [dataWriter convertedValue:*data];
}

@end

@implementation FIRPipelineBridge {
NSArray<FIRStageBridge *> *_stages;
FIRFirestore *firestore;
std::shared_ptr<Pipeline> pipeline;
}

- (id)initWithStages:(NSArray<FIRStageBridge *> *)stages db:(FIRFirestore *)db {
_stages = stages;
firestore = db;
return [super init];
}

- (void)executeWithCompletion:(void (^)(__FIRPipelineSnapshotBridge *_Nullable result,
NSError *_Nullable error))completion {
std::vector<std::shared_ptr<firebase::firestore::api::Stage>> cpp_stages;
for (FIRStageBridge *stage in _stages) {
cpp_stages.push_back([stage cppStageWithReader:firestore.dataReader]);
}
pipeline = std::make_shared<Pipeline>(cpp_stages, firestore.wrapped);

pipeline->execute([completion](StatusOr<api::PipelineSnapshot> maybe_value) {
if (maybe_value.ok()) {
__FIRPipelineSnapshotBridge *bridge = [[__FIRPipelineSnapshotBridge alloc]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#import <Foundation/Foundation.h>

#import "FIRDocumentSnapshot.h"

NS_ASSUME_NONNULL_BEGIN

NS_SWIFT_NAME(ExprBridge)
Expand All @@ -31,7 +33,7 @@ NS_SWIFT_NAME(FieldBridge)

NS_SWIFT_NAME(ConstantBridge)
@interface FIRConstantBridge : FIRExprBridge
- (id)init:(NSNumber *)value;
- (id)init:(id)input;
@end

NS_SWIFT_NAME(FunctionExprBridge)
Expand Down Expand Up @@ -72,6 +74,8 @@ NS_SWIFT_NAME(__PipelineResultBridge)
@property(nonatomic, copy, readonly) NSString *documentID;

- (nullable NSDictionary<NSString *, id> *)data;
- (nullable NSDictionary<NSString *, id> *)dataWithServerTimestampBehavior:
(FIRServerTimestampBehavior)serverTimestampBehavior;

@end

Expand Down
30 changes: 18 additions & 12 deletions Firestore/Swift/Source/SwiftAPI/Expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,28 @@

import Foundation

public protocol Expr {
public protocol Expr {}

protocol BridgeWrapper {
var bridge: ExprBridge { get }
}

public struct Constant: Expr {
public var bridge: ExprBridge
public struct Constant: Expr, BridgeWrapper {
var bridge: ExprBridge

var value: any Numeric
init(value: any Numeric) {
var value: Any
init(value: Any) {
self.value = value
bridge = ConstantBridge(value as! NSNumber)
bridge = ConstantBridge(value)
}
}

public func constant(_ number: any Numeric) -> Constant {
public func constant(_ number: Any) -> Constant {
return Constant(value: number)
}

public struct Field: Expr {
public var bridge: ExprBridge
public struct Field: Expr, BridgeWrapper {
var bridge: ExprBridge

var name: String
init(name: String) {
Expand All @@ -52,16 +54,20 @@ protocol Function: Expr {
var name: String { get }
}

public struct FunctionExpr: Function {
public var bridge: ExprBridge
public struct FunctionExpr: Function, BridgeWrapper {
var bridge: ExprBridge

var name: String
private var args: [Expr]

init(name: String, args: [Expr]) {
self.name = name
self.args = args
bridge = FunctionExprBridge(name: name, args: args.map { $0.bridge })
bridge = FunctionExprBridge(
name: name,
args: args.map { ($0 as! (Expr & BridgeWrapper)).bridge
}
)
}
}

Expand Down
2 changes: 1 addition & 1 deletion Firestore/Swift/Source/SwiftAPI/Stages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import FirebaseFirestoreInternal

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, visionOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, visionOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, iOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, macOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'

Check failure on line 17 in Firestore/Swift/Source/SwiftAPI/Stages.swift

View workflow job for this annotation

GitHub Actions / spm-source (macos-15, Xcode_16.2, tvOS)

no such module 'FirebaseFirestoreInternal'
import Foundation

protocol Stage {
Expand Down Expand Up @@ -42,6 +42,6 @@

init(condition: Expr) {
self.condition = condition
bridge = WhereStageBridge(expr: condition.bridge)
bridge = WhereStageBridge(expr: (condition as! (Expr & BridgeWrapper)).bridge)
}
}
Loading
Loading