Skip to content

Commit de5bc65

Browse files
tom-andersenchkuang-gAlmostMattDellaBittasunmou99
authored
Firestore COUNT API (#1174)
* Firestore COUNT API * Exempt from go/allstar check (#1173) * Token-changed listeners for iOS AppCheck (#1172) * [macOS sandbox mode] Application group name mangling for semaphores (#1167) When macOS Sandbox mode is enabled, macOS requires that semaphores have a name that is prefixed by the App's Group Name. If the semaphore's name doesn't match this convention then its creation fails. Unfortunately there's no official way for the SDK to query the app's group name at runtime, so we can't automatically mangle the semaphore names. Instead I've updated the SDK to use an Info.plist property named FBAppGroupEntitlementName on macOS. If that property is present then the SDK will use it's value to prefix the semaphore names. As an additional issue, the SDK attempted to detect semaphore creation errors by comparing the semaphore handle to nil. But in the case of macOS, a semaphore creation error returns SEM_FAILED which is 0xFFFFFFFFFFFFFFFF, not nil. And on Linux, sem_init returns -1. I've updated the corresponding platform implementations to detect the correct values for these errors. * Setup Desktop test workflow that detects C++ SDK breakage caused by iOS SDK changes (#1162) * [Bugfx] Fix Nightly Test Report template (#1181) * Reduce number of RewardedAd loads on iOS in CI (#1180) The GMA backend doesn't whitelist iOS devices running in CI which means number of ads that can be served to iOS in CI is restricted. This is true even when using the prescribed Demo Ad Unit Id. This PR reduces the number of ads we load on iOS in an attempt to minimize the chance of encountering NoFillErrors and push our CI to green. * Firestore COUNT implementation (WIP) * Firestore COUNT implementation (WIP) * Fix linting * Fix linting * Fix linking * Cleanup * Fix release notes * Format * Fixes from review * Formatting * Responding to PR comments. * Add Hash * Add Hash * Fix copyright year * Rename * Format * Rename * Fixup constructor/assignment parameter naming. * Format --------- Co-authored-by: chkuang-g <[email protected]> Co-authored-by: Matthew Hyndman <[email protected]> Co-authored-by: DellaBitta <[email protected]> Co-authored-by: Mou Sun <[email protected]>
1 parent 0d93bad commit de5bc65

20 files changed

+926
-1
lines changed

app/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,9 @@ if (IOS)
522522
${FIREBASE_SOURCE_DIR}/dynamic_links/src/include/firebase/dynamic_links/components.h)
523523
set(firestore_HDRS
524524
${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore.h
525+
${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_query.h
526+
${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_query_snapshot.h
527+
${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/aggregate_source.h
525528
${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/collection_reference.h
526529
${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/document_change.h
527530
${FIREBASE_SOURCE_DIR}/firestore/src/include/firebase/firestore/document_reference.h

firestore/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ else()
2020
endif()
2121

2222
set(common_SRCS
23+
src/common/aggregate_query.cc
24+
src/common/aggregate_query_snapshot.cc
2325
src/common/cleanup.h
2426
src/common/collection_reference.cc
2527
src/common/compiler_info.cc
@@ -185,6 +187,10 @@ set(android_SRCS
185187

186188
# Sources that apply to all non-Android platforms.
187189
set(main_SRCS
190+
src/main/aggregate_query_main.cc
191+
src/main/aggregate_query_main.h
192+
src/main/aggregate_query_snapshot_main.cc
193+
src/main/aggregate_query_snapshot_main.h
188194
src/main/collection_reference_main.cc
189195
src/main/collection_reference_main.h
190196
src/main/converter_main.h

firestore/CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ a Python3 installation.
1919

2020
# Architecture
2121

22-
It is easier to work this Firestore CPP SDK by keeping a high level archetecture in mind:
22+
It is easier to work this Firestore CPP SDK by keeping a high level architecture in mind:
2323

2424
![architecture.png](architecture.png)
2525

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright 2023 Google LLC
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+
#include "firestore/src/include/firebase/firestore/aggregate_query.h"
18+
#include "firestore/src/common/cleanup.h"
19+
#include "firestore/src/common/futures.h"
20+
#include "firestore/src/common/util.h"
21+
#include "firestore/src/include/firebase/firestore/aggregate_query_snapshot.h"
22+
23+
#if defined(__ANDROID__)
24+
// TODO(tomandersen) #include "firestore/src/android/aggregate_query_android.h"
25+
#else
26+
#include "firestore/src/main/aggregate_query_main.h"
27+
#endif // defined(__ANDROID__)
28+
29+
namespace firebase {
30+
namespace firestore {
31+
32+
using CleanupFnAggregateQuery = CleanupFn<AggregateQuery>;
33+
34+
AggregateQuery::AggregateQuery() {}
35+
36+
AggregateQuery::AggregateQuery(const AggregateQuery& other) {
37+
if (other.internal_) {
38+
internal_ = new AggregateQueryInternal(*other.internal_);
39+
}
40+
CleanupFnAggregateQuery::Register(this, internal_);
41+
}
42+
43+
AggregateQuery::AggregateQuery(AggregateQuery&& other) {
44+
CleanupFnAggregateQuery::Unregister(&other, other.internal_);
45+
std::swap(internal_, other.internal_);
46+
CleanupFnAggregateQuery::Register(this, internal_);
47+
}
48+
49+
AggregateQuery::AggregateQuery(AggregateQueryInternal* internal)
50+
: internal_(internal) {
51+
SIMPLE_HARD_ASSERT(internal != nullptr);
52+
CleanupFnAggregateQuery::Register(this, internal_);
53+
}
54+
55+
AggregateQuery::~AggregateQuery() {
56+
CleanupFnAggregateQuery::Unregister(this, internal_);
57+
delete internal_;
58+
internal_ = nullptr;
59+
}
60+
61+
AggregateQuery& AggregateQuery::operator=(const AggregateQuery& other) {
62+
if (this == &other) {
63+
return *this;
64+
}
65+
66+
CleanupFnAggregateQuery::Unregister(this, internal_);
67+
delete internal_;
68+
if (other.internal_) {
69+
internal_ = new AggregateQueryInternal(*other.internal_);
70+
} else {
71+
internal_ = nullptr;
72+
}
73+
CleanupFnAggregateQuery::Register(this, internal_);
74+
return *this;
75+
}
76+
77+
AggregateQuery& AggregateQuery::operator=(AggregateQuery&& other) {
78+
if (this == &other) {
79+
return *this;
80+
}
81+
82+
CleanupFnAggregateQuery::Unregister(&other, other.internal_);
83+
CleanupFnAggregateQuery::Unregister(this, internal_);
84+
delete internal_;
85+
internal_ = other.internal_;
86+
other.internal_ = nullptr;
87+
CleanupFnAggregateQuery::Register(this, internal_);
88+
return *this;
89+
}
90+
91+
Query AggregateQuery::query() const {
92+
if (!internal_) return {};
93+
return internal_->query();
94+
}
95+
96+
Future<AggregateQuerySnapshot> AggregateQuery::Get(
97+
AggregateSource aggregate_source) const {
98+
if (!internal_) return FailedFuture<AggregateQuerySnapshot>();
99+
return internal_->Get(aggregate_source);
100+
}
101+
102+
size_t AggregateQuery::Hash() const {
103+
if (!internal_) return {};
104+
return internal_->Hash();
105+
}
106+
107+
bool operator==(const AggregateQuery& lhs, const AggregateQuery& rhs) {
108+
return EqualityCompare(lhs.internal_, rhs.internal_);
109+
}
110+
111+
} // namespace firestore
112+
} // namespace firebase
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright 2023 Google LLC
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+
#include "firestore/src/include/firebase/firestore/aggregate_query_snapshot.h"
18+
19+
#include "firestore/src/common/cleanup.h"
20+
#include "firestore/src/common/util.h"
21+
#include "firestore/src/include/firebase/firestore/aggregate_query.h"
22+
23+
#if defined(__ANDROID__)
24+
// TODO(tomandersen) #include
25+
// "firestore/src/android/aggregate_query_snapshot_android.h"
26+
#else
27+
#include "firestore/src/main/aggregate_query_snapshot_main.h"
28+
#endif // defined(__ANDROID__)
29+
30+
namespace firebase {
31+
namespace firestore {
32+
33+
using CleanupFnAggregateQuerySnapshot = CleanupFn<AggregateQuerySnapshot>;
34+
35+
AggregateQuerySnapshot::AggregateQuerySnapshot() {}
36+
37+
AggregateQuerySnapshot::AggregateQuerySnapshot(
38+
const AggregateQuerySnapshot& other) {
39+
if (other.internal_) {
40+
internal_ = new AggregateQuerySnapshotInternal(*other.internal_);
41+
}
42+
CleanupFnAggregateQuerySnapshot::Register(this, internal_);
43+
}
44+
45+
AggregateQuerySnapshot::AggregateQuerySnapshot(AggregateQuerySnapshot&& other) {
46+
CleanupFnAggregateQuerySnapshot::Unregister(&other, other.internal_);
47+
std::swap(internal_, other.internal_);
48+
CleanupFnAggregateQuerySnapshot::Register(this, internal_);
49+
}
50+
51+
AggregateQuerySnapshot::AggregateQuerySnapshot(
52+
AggregateQuerySnapshotInternal* internal)
53+
: internal_(internal) {
54+
SIMPLE_HARD_ASSERT(internal != nullptr);
55+
CleanupFnAggregateQuerySnapshot::Register(this, internal_);
56+
}
57+
58+
AggregateQuerySnapshot::~AggregateQuerySnapshot() {
59+
CleanupFnAggregateQuerySnapshot::Unregister(this, internal_);
60+
delete internal_;
61+
internal_ = nullptr;
62+
}
63+
64+
AggregateQuerySnapshot& AggregateQuerySnapshot::operator=(
65+
const AggregateQuerySnapshot& other) {
66+
if (this == &other) {
67+
return *this;
68+
}
69+
70+
CleanupFnAggregateQuerySnapshot::Unregister(this, internal_);
71+
delete internal_;
72+
if (other.internal_) {
73+
internal_ = new AggregateQuerySnapshotInternal(*other.internal_);
74+
} else {
75+
internal_ = nullptr;
76+
}
77+
CleanupFnAggregateQuerySnapshot::Register(this, internal_);
78+
return *this;
79+
}
80+
81+
AggregateQuerySnapshot& AggregateQuerySnapshot::operator=(
82+
AggregateQuerySnapshot&& other) {
83+
if (this == &other) {
84+
return *this;
85+
}
86+
87+
CleanupFnAggregateQuerySnapshot::Unregister(&other, other.internal_);
88+
CleanupFnAggregateQuerySnapshot::Unregister(this, internal_);
89+
delete internal_;
90+
internal_ = other.internal_;
91+
other.internal_ = nullptr;
92+
CleanupFnAggregateQuerySnapshot::Register(this, internal_);
93+
return *this;
94+
}
95+
96+
AggregateQuery AggregateQuerySnapshot::query() const {
97+
if (!internal_) return {};
98+
return internal_->query();
99+
}
100+
101+
int64_t AggregateQuerySnapshot::count() const {
102+
if (!internal_) return 0;
103+
return internal_->count();
104+
}
105+
106+
bool operator==(const AggregateQuerySnapshot& lhs,
107+
const AggregateQuerySnapshot& rhs) {
108+
return EqualityCompare(lhs.internal_, rhs.internal_);
109+
}
110+
111+
size_t AggregateQuerySnapshot::Hash() const {
112+
if (!internal_) return {};
113+
return internal_->Hash();
114+
}
115+
116+
} // namespace firestore
117+
} // namespace firebase

firestore/src/common/query.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "firestore/src/common/futures.h"
2424
#include "firestore/src/common/hard_assert_common.h"
2525
#include "firestore/src/common/util.h"
26+
#include "firestore/src/include/firebase/firestore/aggregate_query.h"
2627
#include "firestore/src/include/firebase/firestore/document_snapshot.h"
2728
#include "firestore/src/include/firebase/firestore/field_path.h"
2829
#include "firestore/src/include/firebase/firestore/field_value.h"
@@ -106,6 +107,11 @@ Firestore* Query::firestore() {
106107
return internal_->firestore();
107108
}
108109

110+
AggregateQuery Query::Count() const {
111+
if (!internal_) return {};
112+
return internal_->Count();
113+
}
114+
109115
Query Query::WhereEqualTo(const std::string& field,
110116
const FieldValue& value) const {
111117
return WhereEqualTo(FieldPath::FromDotSeparatedString(field), value);

firestore/src/common/type_mapping.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
namespace firebase {
2323
namespace firestore {
2424

25+
class AggregateQuery;
26+
class AggregateQueryInternal;
27+
class AggregateQuerySnapshot;
28+
class AggregateQuerySnapshotInternal;
2529
class CollectionReference;
2630
class CollectionReferenceInternal;
2731
class DocumentChange;
@@ -54,6 +58,14 @@ class WriteBatchInternal;
5458
template <typename T>
5559
struct InternalTypeMap {};
5660

61+
template <>
62+
struct InternalTypeMap<AggregateQuery> {
63+
using type = AggregateQueryInternal;
64+
};
65+
template <>
66+
struct InternalTypeMap<AggregateQuerySnapshot> {
67+
using type = AggregateQuerySnapshotInternal;
68+
};
5769
template <>
5870
struct InternalTypeMap<CollectionReference> {
5971
using type = CollectionReferenceInternal;

firestore/src/include/firebase/firestore.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include "firebase/log.h"
2828
// Include *all* the public headers to make sure including just "firestore.h" is
2929
// sufficient for users.
30+
#include "firebase/firestore/aggregate_query.h"
31+
#include "firebase/firestore/aggregate_query_snapshot.h"
32+
#include "firebase/firestore/aggregate_source.h"
3033
#include "firebase/firestore/collection_reference.h"
3134
#include "firebase/firestore/document_change.h"
3235
#include "firebase/firestore/document_reference.h"

0 commit comments

Comments
 (0)