cherylEnkidu 1 rok temu
rodzic
commit
113da450e7

+ 1 - 0
.gitignore

@@ -155,6 +155,7 @@ FirebaseAppCheck/Apps/AppCheckCustomProvideApp/AppCheckCustomProvideApp/GoogleSe
 /Example/FirestoreSample/ui-debug.log
 /Example/FirestoreSample/firestore-debug.log
 /Example/FirestoreSample/firebase-debug.log
+Firestore/Example/GoogleService-Info.plist
 
 # generated Terraform docs
 .terraform/*

+ 1 - 1
Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm

@@ -85,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN
 static const double kPrimingTimeout = 45.0;
 
 static NSString *defaultProjectId;
-static NSString *defaultDatabaseId = @"(default)";
+static NSString *defaultDatabaseId = @"enterprise";
 static FIRFirestoreSettings *defaultSettings;
 
 static bool runningAgainstEmulator = false;

+ 115 - 0
Firestore/Source/API/FIRPipelineBridge.mm

@@ -39,13 +39,18 @@
 #include "Firestore/core/src/util/status.h"
 #include "Firestore/core/src/util/string_apple.h"
 
+using firebase::firestore::api::CollectionGroupSource;
 using firebase::firestore::api::CollectionSource;
 using firebase::firestore::api::Constant;
+using firebase::firestore::api::DatabaseSource;
 using firebase::firestore::api::DocumentReference;
+using firebase::firestore::api::DocumentsSource;
 using firebase::firestore::api::Expr;
 using firebase::firestore::api::Field;
 using firebase::firestore::api::FunctionExpr;
+using firebase::firestore::api::LimitStage;
 using firebase::firestore::api::MakeFIRTimestamp;
+using firebase::firestore::api::OffsetStage;
 using firebase::firestore::api::Pipeline;
 using firebase::firestore::api::Where;
 using firebase::firestore::util::MakeCallback;
@@ -149,6 +154,64 @@ NS_ASSUME_NONNULL_BEGIN
 
 @end
 
+@implementation FIRDatabaseSourceStageBridge {
+  std::shared_ptr<DatabaseSource> database_source;
+}
+
+- (id)init {
+  self = [super init];
+  if (self) {
+    database_source = std::make_shared<DatabaseSource>();
+  }
+  return self;
+}
+
+- (std::shared_ptr<api::Stage>)cppStageWithReader:(FSTUserDataReader *)reader {
+  return database_source;
+}
+
+@end
+
+@implementation FIRCollectionGroupSourceStageBridge {
+  std::shared_ptr<CollectionGroupSource> collection_group_source;
+}
+
+- (id)initWithCollectionId:(NSString *)id {
+  self = [super init];
+  if (self) {
+    collection_group_source = std::make_shared<CollectionGroupSource>(MakeString(id));
+  }
+  return self;
+}
+
+- (std::shared_ptr<api::Stage>)cppStageWithReader:(FSTUserDataReader *)reader {
+  return collection_group_source;
+}
+
+@end
+
+@implementation FIRDocumentsSourceStageBridge {
+  std::shared_ptr<DocumentsSource> document_source;
+}
+
+- (id)initWithDocuments:(NSArray<NSString *> *)documents {
+  self = [super init];
+  if (self) {
+    std::vector<std::string> cpp_documents;
+    for (NSString *doc in documents) {
+      cpp_documents.push_back(MakeString(doc));
+    }
+    document_source = std::make_shared<DocumentsSource>(std::move(cpp_documents));
+  }
+  return self;
+}
+
+- (std::shared_ptr<api::Stage>)cppStageWithReader:(FSTUserDataReader *)reader {
+  return document_source;
+}
+
+@end
+
 @implementation FIRWhereStageBridge {
   FIRExprBridge *_exprBridge;
   Boolean isUserDataRead;
@@ -175,6 +238,58 @@ NS_ASSUME_NONNULL_BEGIN
 
 @end
 
+@implementation FIRLimitStageBridge {
+  Boolean isUserDataRead;
+  std::shared_ptr<LimitStage> limit_stage;
+  int32_t limit;
+}
+
+- (id)initWithLimit:(NSInteger)value {
+  self = [super init];
+  if (self) {
+    isUserDataRead = NO;
+    limit = static_cast<int32_t>(value);
+  }
+  return self;
+}
+
+- (std::shared_ptr<api::Stage>)cppStageWithReader:(FSTUserDataReader *)reader {
+  if (!isUserDataRead) {
+    limit_stage = std::make_shared<LimitStage>(limit);
+  }
+
+  isUserDataRead = YES;
+  return limit_stage;
+}
+
+@end
+
+@implementation FIROffsetStageBridge {
+  Boolean isUserDataRead;
+  std::shared_ptr<OffsetStage> offset_stage;
+  int32_t offset;
+}
+
+- (id)initWithOffset:(NSInteger)value {
+  self = [super init];
+  if (self) {
+    isUserDataRead = NO;
+    offset = static_cast<int32_t>(value);
+  }
+  return self;
+}
+
+- (std::shared_ptr<api::Stage>)cppStageWithReader:(FSTUserDataReader *)reader {
+  if (!isUserDataRead) {
+    offset_stage = std::make_shared<OffsetStage>(offset);
+  }
+
+  isUserDataRead = YES;
+  return offset_stage;
+}
+
+@end
+
 @interface __FIRPipelineSnapshotBridge ()
 
 @property(nonatomic, strong, readwrite) NSArray<__FIRPipelineResultBridge *> *results;

+ 40 - 0
Firestore/Source/Public/FirebaseFirestore/FIRPipelineBridge.h

@@ -60,6 +60,30 @@ NS_SWIFT_NAME(CollectionSourceStageBridge)
 
 @end
 
+NS_SWIFT_SENDABLE
+NS_SWIFT_NAME(DatabaseSourceStageBridge)
+@interface FIRDatabaseSourceStageBridge : FIRStageBridge
+
+- (id)init;
+
+@end
+
+NS_SWIFT_SENDABLE
+NS_SWIFT_NAME(CollectionGroupSourceStageBridge)
+@interface FIRCollectionGroupSourceStageBridge : FIRStageBridge
+
+- (id)initWithCollectionId:(NSString *)id;
+
+@end
+
+NS_SWIFT_SENDABLE
+NS_SWIFT_NAME(DocumentsSourceStageBridge)
+@interface FIRDocumentsSourceStageBridge : FIRStageBridge
+
+- (id)initWithDocuments:(NSArray<NSString *> *)documents;
+
+@end
+
 NS_SWIFT_SENDABLE
 NS_SWIFT_NAME(WhereStageBridge)
 @interface FIRWhereStageBridge : FIRStageBridge
@@ -68,6 +92,22 @@ NS_SWIFT_NAME(WhereStageBridge)
 
 @end
 
+NS_SWIFT_SENDABLE
+NS_SWIFT_NAME(LimitStageBridge)
+@interface FIRLimitStageBridge : FIRStageBridge
+
+- (id)initWithLimit:(NSInteger)value;
+
+@end
+
+NS_SWIFT_SENDABLE
+NS_SWIFT_NAME(OffsetStageBridge)
+@interface FIROffsetStageBridge : FIRStageBridge
+
+- (id)initWithOffset:(NSInteger)value;
+
+@end
+
 NS_SWIFT_SENDABLE
 NS_SWIFT_NAME(__PipelineResultBridge)
 @interface __FIRPipelineResultBridge : NSObject

+ 2 - 2
Firestore/Swift/Source/SwiftAPI/Pipeline/Pipeline.swift

@@ -141,7 +141,7 @@ public struct Pipeline: @unchecked Sendable {
   /// - Parameter offset: The number of documents to skip.
   /// - Returns: A new `Pipeline` object with this stage appended to the stage list.
   public func offset(_ offset: Int32) -> Pipeline {
-    return self
+    return Pipeline(stages: stages + [Offset(offset)], db: db)
   }
 
   /// Limits the maximum number of documents returned by previous stages to `limit`.
@@ -157,7 +157,7 @@ public struct Pipeline: @unchecked Sendable {
   /// - Parameter limit: The maximum number of documents to return.
   /// - Returns: A new `Pipeline` object with this stage appended to the stage list.
   public func limit(_ limit: Int32) -> Pipeline {
-    return self
+    return Pipeline(stages: stages + [Limit(limit)], db: db)
   }
 
   /// Returns a set of distinct `Expr` values from the inputs to this stage.

+ 4 - 1
Firestore/Swift/Source/SwiftAPI/Pipeline/PipelineSource.swift

@@ -25,7 +25,10 @@ public struct PipelineSource: @unchecked Sendable {
   }
 
   public func collectionGroup(_ collectionId: String) -> Pipeline {
-    return Pipeline(stages: [CollectionSource(collection: "placeholder")], db: db)
+    return Pipeline(
+      stages: [CollectionGroupSource(collectionId: collectionId)],
+      db: db
+    )
   }
 
   public func database() -> Pipeline {

+ 39 - 3
Firestore/Swift/Source/SwiftAPI/Stages.swift

@@ -34,14 +34,50 @@ class CollectionSource: Stage {
   }
 }
 
+class CollectionGroupSource: Stage {
+  var name: String = "collectionId"
+
+  var bridge: StageBridge
+  private var collectionId: String
+
+  init(collectionId: String) {
+    self.collectionId = collectionId
+    bridge = CollectionGroupSourceStageBridge(collectionId: collectionId)
+  }
+}
+
 class Where: Stage {
   var name: String = "where"
 
   var bridge: StageBridge
-  private var condition: Expr // TODO: should be FilterCondition
+  private var condition: BooleanExpr
 
-  init(condition: Expr) {
+  init(condition: BooleanExpr) {
     self.condition = condition
-    bridge = WhereStageBridge(expr: (condition as! (Expr & BridgeWrapper)).bridge)
+    bridge = WhereStageBridge(expr: condition.bridge)
+  }
+}
+
+class Limit: Stage {
+  var name: String = "limit"
+
+  var bridge: StageBridge
+  private var limit: Int32
+
+  init(_ limit: Int32) {
+    self.limit = limit
+    bridge = LimitStageBridge(limit: NSInteger(limit))
+  }
+}
+
+class Offset: Stage {
+  var name: String = "offset"
+
+  var bridge: StageBridge
+  private var offset: Int32
+
+  init(_ offset: Int32) {
+    self.offset = offset
+    bridge = OffsetStageBridge(offset: NSInteger(offset))
   }
 }

+ 1 - 1
Firestore/Swift/Tests/Integration/PipelineTests.swift

@@ -132,7 +132,7 @@ class PipelineIntegrationTests: FSTIntegrationTestCase {
 
     let snapshot = try await db
       .pipeline()
-      .collection(collRef.collectionID)
+      .collection("/" + collRef.path)
       .limit(0)
       .execute()
 

+ 2 - 2
Firestore/core/src/api/stages.h

@@ -169,14 +169,14 @@ class FindNearestStage : public Stage {
 
 class LimitStage : public Stage {
  public:
-  explicit LimitStage(int64_t limit) : limit_(limit) {
+  explicit LimitStage(int32_t limit) : limit_(limit) {
   }
   ~LimitStage() override = default;
 
   google_firestore_v1_Pipeline_Stage to_proto() const override;
 
  private:
-  int64_t limit_;
+  int32_t limit_;
 };
 
 class OffsetStage : public Stage {