Skip to content

Commit f331295

Browse files
authored
operator== and operator!= for DocumentSnapshot. (#602)
* operator== and operator!= for DocumentSnapshot. * Address feedback. * Fix license. * Address comments. * Add missing header. * Better code structure (fix build for Android). * Address comments.
1 parent 4725fa6 commit f331295

17 files changed

+129
-22
lines changed

firestore/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ set(android_SRCS
143143
src/jni/class.h
144144
src/jni/collection.cc
145145
src/jni/collection.h
146+
src/jni/compare.h
146147
src/jni/declaration.h
147148
src/jni/double.cc
148149
src/jni/double.h

firestore/integration_test_internal/src/document_snapshot_test.cc

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <utility>
1818

1919
#include "firebase/firestore.h"
20+
#include "firestore_integration_test.h"
21+
2022
#if defined(__ANDROID__)
2123
#include "firestore/src/android/document_snapshot_android.h"
2224
#include "firestore/src/common/wrapper_assertions.h"
@@ -28,9 +30,9 @@
2830
namespace firebase {
2931
namespace firestore {
3032

31-
#if defined(__ANDROID__)
33+
using DocumentSnapshotTest = FirestoreIntegrationTest;
3234

33-
using DocumentSnapshotTest = testing::Test;
35+
#if defined(__ANDROID__)
3436

3537
TEST_F(DocumentSnapshotTest, Construction) {
3638
testutil::AssertWrapperConstructionContract<DocumentSnapshot,
@@ -44,5 +46,27 @@ TEST_F(DocumentSnapshotTest, Assignment) {
4446

4547
#endif
4648

49+
TEST_F(DocumentSnapshotTest, Equality) {
50+
DocumentReference doc1 = Collection("col1").Document();
51+
DocumentReference doc2 = Collection("col1").Document();
52+
DocumentSnapshot doc1_snap1 = ReadDocument(doc1);
53+
DocumentSnapshot doc1_snap2 = ReadDocument(doc1);
54+
DocumentSnapshot doc2_snap1 = ReadDocument(doc2);
55+
DocumentSnapshot snap3 = DocumentSnapshot();
56+
DocumentSnapshot snap4 = DocumentSnapshot();
57+
58+
EXPECT_TRUE(doc1_snap1 == doc1_snap1);
59+
EXPECT_TRUE(doc1_snap1 == doc1_snap2);
60+
EXPECT_TRUE(doc1_snap1 != doc2_snap1);
61+
EXPECT_TRUE(doc1_snap1 != snap3);
62+
EXPECT_TRUE(snap3 == snap4);
63+
64+
EXPECT_FALSE(doc1_snap1 != doc1_snap1);
65+
EXPECT_FALSE(doc1_snap1 != doc1_snap2);
66+
EXPECT_FALSE(doc1_snap1 == doc2_snap1);
67+
EXPECT_FALSE(doc1_snap1 == snap3);
68+
EXPECT_FALSE(snap3 != snap4);
69+
}
70+
4771
} // namespace firestore
4872
} // namespace firebase

firestore/src/android/document_snapshot_android.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "firestore/src/android/server_timestamp_behavior_android.h"
2525
#include "firestore/src/android/snapshot_metadata_android.h"
2626
#include "firestore/src/include/firebase/firestore.h"
27+
#include "firestore/src/jni/compare.h"
2728
#include "firestore/src/jni/env.h"
2829
#include "firestore/src/jni/loader.h"
2930

@@ -128,5 +129,10 @@ FieldValue DocumentSnapshotInternal::Get(const FieldPath& field,
128129
return FieldValueInternal::Create(env, field_value);
129130
}
130131

132+
bool operator==(const DocumentSnapshotInternal& lhs,
133+
const DocumentSnapshotInternal& rhs) {
134+
return jni::EqualityCompareJni(lhs, rhs);
135+
}
136+
131137
} // namespace firestore
132138
} // namespace firebase

firestore/src/android/document_snapshot_android.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ class DocumentSnapshotInternal : public Wrapper {
6464
mutable std::string cached_id_;
6565
};
6666

67+
bool operator==(const DocumentSnapshotInternal& lhs,
68+
const DocumentSnapshotInternal& rhs);
69+
70+
inline bool operator!=(const DocumentSnapshotInternal& lhs,
71+
const DocumentSnapshotInternal& rhs) {
72+
return !(lhs == rhs);
73+
}
74+
6775
} // namespace firestore
6876
} // namespace firebase
6977
#endif // FIREBASE_FIRESTORE_SRC_ANDROID_DOCUMENT_SNAPSHOT_ANDROID_H_

firestore/src/android/field_value_android.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "firestore/src/jni/array_list.h"
2626
#include "firestore/src/jni/boolean.h"
2727
#include "firestore/src/jni/class.h"
28+
#include "firestore/src/jni/compare.h"
2829
#include "firestore/src/jni/double.h"
2930
#include "firestore/src/jni/env.h"
3031
#include "firestore/src/jni/hash_map.h"
@@ -384,8 +385,7 @@ FieldValue FieldValueInternal::DoubleIncrement(double by_value) {
384385
}
385386

386387
bool operator==(const FieldValueInternal& lhs, const FieldValueInternal& rhs) {
387-
Env env = FieldValueInternal::GetEnv();
388-
return Object::Equals(env, lhs.object_, rhs.object_);
388+
return jni::EqualityCompareJni(lhs, rhs);
389389
}
390390

391391
template <typename T>

firestore/src/android/query_android.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "firestore/src/include/firebase/firestore.h"
3333
#include "firestore/src/jni/array.h"
3434
#include "firestore/src/jni/array_list.h"
35+
#include "firestore/src/jni/compare.h"
3536
#include "firestore/src/jni/env.h"
3637
#include "firestore/src/jni/loader.h"
3738
#include "firestore/src/jni/task.h"
@@ -346,8 +347,7 @@ Local<Array<Object>> QueryInternal::ConvertFieldValues(
346347
}
347348

348349
bool operator==(const QueryInternal& lhs, const QueryInternal& rhs) {
349-
Env env = FirestoreInternal::GetEnv();
350-
return Object::Equals(env, lhs.ToJava(), rhs.ToJava());
350+
return jni::EqualityCompareJni(lhs, rhs);
351351
}
352352

353353
} // namespace firestore

firestore/src/android/query_snapshot_android.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "firestore/src/android/query_android.h"
2424
#include "firestore/src/android/snapshot_metadata_android.h"
2525
#include "firestore/src/android/util_android.h"
26+
#include "firestore/src/jni/compare.h"
2627
#include "firestore/src/jni/env.h"
2728
#include "firestore/src/jni/list.h"
2829
#include "firestore/src/jni/loader.h"
@@ -88,8 +89,7 @@ std::size_t QuerySnapshotInternal::size() const {
8889

8990
bool operator==(const QuerySnapshotInternal& lhs,
9091
const QuerySnapshotInternal& rhs) {
91-
Env env = FirestoreInternal::GetEnv();
92-
return Object::Equals(env, lhs.ToJava(), rhs.ToJava());
92+
return jni::EqualityCompareJni(lhs, rhs);
9393
}
9494

9595
} // namespace firestore

firestore/src/common/document_snapshot.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,9 @@ std::ostream& operator<<(std::ostream& out, const DocumentSnapshot& document) {
155155
return out << document.ToString();
156156
}
157157

158+
bool operator==(const DocumentSnapshot& lhs, const DocumentSnapshot& rhs) {
159+
return EqualityCompare(lhs.internal_, rhs.internal_);
160+
}
161+
158162
} // namespace firestore
159163
} // namespace firebase

firestore/src/common/field_value.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "firebase/firestore/timestamp.h"
2626
#include "firestore/src/common/hard_assert_common.h"
2727
#include "firestore/src/common/to_string.h"
28+
#include "firestore/src/common/util.h"
2829
#include "firestore/src/include/firebase/firestore/document_reference.h"
2930
#if defined(__ANDROID__)
3031
#include "firestore/src/android/field_value_android.h"
@@ -341,9 +342,7 @@ std::string FieldValue::ToString() const {
341342
}
342343

343344
bool operator==(const FieldValue& lhs, const FieldValue& rhs) {
344-
return lhs.internal_ == rhs.internal_ ||
345-
(lhs.internal_ != nullptr && rhs.internal_ != nullptr &&
346-
*lhs.internal_ == *rhs.internal_);
345+
return EqualityCompare(lhs.internal_, rhs.internal_);
347346
}
348347

349348
std::ostream& operator<<(std::ostream& out, const FieldValue& value) {

firestore/src/common/query.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "firestore/src/common/event_listener.h"
2323
#include "firestore/src/common/futures.h"
2424
#include "firestore/src/common/hard_assert_common.h"
25+
#include "firestore/src/common/util.h"
2526
#include "firestore/src/include/firebase/firestore/document_snapshot.h"
2627
#include "firestore/src/include/firebase/firestore/field_path.h"
2728
#include "firestore/src/include/firebase/firestore/field_value.h"
@@ -302,11 +303,7 @@ ListenerRegistration Query::AddSnapshotListener(
302303
}
303304

304305
bool operator==(const Query& lhs, const Query& rhs) {
305-
if (!lhs.internal_ || !rhs.internal_) {
306-
return lhs.internal_ == rhs.internal_;
307-
}
308-
309-
return lhs.internal_ == rhs.internal_ || *lhs.internal_ == *rhs.internal_;
306+
return EqualityCompare(lhs.internal_, rhs.internal_);
310307
}
311308

312309
} // namespace firestore

firestore/src/common/query_snapshot.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "firestore/src/common/cleanup.h"
2222
#include "firestore/src/common/hard_assert_common.h"
23+
#include "firestore/src/common/util.h"
2324
#include "firestore/src/include/firebase/firestore/document_change.h"
2425
#include "firestore/src/include/firebase/firestore/document_snapshot.h"
2526
#include "firestore/src/include/firebase/firestore/query.h"
@@ -118,11 +119,7 @@ std::size_t QuerySnapshot::size() const {
118119
}
119120

120121
bool operator==(const QuerySnapshot& lhs, const QuerySnapshot& rhs) {
121-
if (!lhs.internal_ || !rhs.internal_) {
122-
return lhs.internal_ == rhs.internal_;
123-
}
124-
125-
return lhs.internal_ == rhs.internal_ || *lhs.internal_ == *rhs.internal_;
122+
return EqualityCompare(lhs.internal_, rhs.internal_);
126123
}
127124

128125
} // namespace firestore

firestore/src/common/util.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ namespace firestore {
2727
// a string to refer to.
2828
const std::string& EmptyString();
2929

30+
// Returns true if the two given pointers are equal or the underlying objects
31+
// that they point to are equal. Returns false otherwise.
32+
template <typename T>
33+
bool EqualityCompare(T* lhs, T* rhs) {
34+
return lhs == rhs || (lhs != nullptr && rhs != nullptr && *lhs == *rhs);
35+
}
36+
3037
} // namespace firestore
3138
} // namespace firebase
3239

firestore/src/include/firebase/firestore/document_snapshot.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ class DocumentSnapshot {
261261
const DocumentSnapshot& document);
262262

263263
private:
264+
friend bool operator==(const DocumentSnapshot& lhs,
265+
const DocumentSnapshot& rhs);
266+
264267
friend class DocumentChangeInternal;
265268
friend class EventListenerInternal;
266269
friend class FirestoreInternal;
@@ -276,6 +279,15 @@ class DocumentSnapshot {
276279
mutable DocumentSnapshotInternal* internal_ = nullptr;
277280
};
278281

282+
/** Checks `lhs` and `rhs` for equality. */
283+
bool operator==(const DocumentSnapshot& lhs, const DocumentSnapshot& rhs);
284+
285+
/** Checks `lhs` and `rhs` for inequality. */
286+
inline bool operator!=(const DocumentSnapshot& lhs,
287+
const DocumentSnapshot& rhs) {
288+
return !(lhs == rhs);
289+
}
290+
279291
} // namespace firestore
280292
} // namespace firebase
281293

firestore/src/jni/compare.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2021 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/android/exception_android.h"
18+
#include "firestore/src/android/wrapper.h"
19+
#include "firestore/src/jni/env.h"
20+
#include "firestore/src/jni/object.h"
21+
22+
namespace firebase {
23+
namespace firestore {
24+
namespace jni {
25+
26+
/**
27+
* Returns the result of `Object::Equals` for the given `lhs` and `rhs` in the
28+
* current Firestore `jni::Env`.
29+
*/
30+
template <typename T>
31+
bool EqualityCompareJni(const T& lhs, const T& rhs) {
32+
Env env;
33+
env.SetUnhandledExceptionHandler(GlobalUnhandledExceptionHandler, nullptr);
34+
return Object::Equals(env, lhs.ToJava(), rhs.ToJava());
35+
}
36+
37+
} // namespace jni
38+
} // namespace firestore
39+
} // namespace firebase

firestore/src/main/document_snapshot_main.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,10 @@ FieldValue DocumentSnapshotInternal::ConvertServerTimestamp(
215215
FIRESTORE_UNREACHABLE();
216216
}
217217

218+
bool operator==(const DocumentSnapshotInternal& lhs,
219+
const DocumentSnapshotInternal& rhs) {
220+
return lhs.snapshot_ == rhs.snapshot_;
221+
}
222+
218223
} // namespace firestore
219224
} // namespace firebase

firestore/src/main/document_snapshot_main.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class DocumentSnapshotInternal {
6363

6464
DocumentReference reference() const;
6565

66+
friend bool operator==(const DocumentSnapshotInternal& lhs,
67+
const DocumentSnapshotInternal& rhs);
68+
6669
private:
6770
using ServerTimestampBehavior = DocumentSnapshot::ServerTimestampBehavior;
6871

@@ -87,6 +90,11 @@ class DocumentSnapshotInternal {
8790
api::DocumentSnapshot snapshot_;
8891
};
8992

93+
inline bool operator!=(const DocumentSnapshotInternal& lhs,
94+
const DocumentSnapshotInternal& rhs) {
95+
return !(lhs == rhs);
96+
}
97+
9098
} // namespace firestore
9199
} // namespace firebase
92100

release_build_files/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ code.
571571
- Changes
572572
- General: Updating Android and iOS dependencies to the latest.
573573
- Firestore: Added `operator==` and `operator!=` for `SnapshotMetadata`,
574-
`Settings`, and `QuerySnapshot`.
574+
`Settings`, `QuerySnapshot`, and `DocumentSnapshot`.
575575

576576
### 8.3.0
577577
- Changes

0 commit comments

Comments
 (0)