Skip to content

Commit adf9fb3

Browse files
authored
Update FieldValue of type Reference (firebase#775)
* update FieldValue of type Reference * address change * fix bad path string literal in test * use ReferenceValue and qualified name
1 parent 4afcfb1 commit adf9fb3

File tree

3 files changed

+104
-5
lines changed

3 files changed

+104
-5
lines changed

Firestore/core/src/firebase/firestore/model/field_value.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ FieldValue& FieldValue::operator=(const FieldValue& value) {
9999
std::swap(blob_value_, tmp);
100100
break;
101101
}
102+
case Type::Reference:
103+
reference_value_ = value.reference_value_;
104+
break;
102105
case Type::GeoPoint:
103106
geo_point_value_ = value.geo_point_value_;
104107
break;
@@ -131,6 +134,11 @@ FieldValue& FieldValue::operator=(FieldValue&& value) {
131134
SwitchTo(Type::Blob);
132135
std::swap(blob_value_, value.blob_value_);
133136
return *this;
137+
case Type::Reference:
138+
SwitchTo(Type::Reference);
139+
std::swap(reference_value_.reference, value.reference_value_.reference);
140+
reference_value_.database_id = value.reference_value_.database_id;
141+
return *this;
134142
case Type::Array:
135143
SwitchTo(Type::Array);
136144
std::swap(array_value_, value.array_value_);
@@ -233,6 +241,26 @@ FieldValue FieldValue::BlobValue(const uint8_t* source, size_t size) {
233241
return result;
234242
}
235243

244+
// Does NOT pass ownership of database_id.
245+
FieldValue FieldValue::ReferenceValue(const DocumentKey& value,
246+
const DatabaseId* database_id) {
247+
FieldValue result;
248+
result.SwitchTo(Type::Reference);
249+
result.reference_value_.reference = value;
250+
result.reference_value_.database_id = database_id;
251+
return result;
252+
}
253+
254+
// Does NOT pass ownership of database_id.
255+
FieldValue FieldValue::ReferenceValue(DocumentKey&& value,
256+
const DatabaseId* database_id) {
257+
FieldValue result;
258+
result.SwitchTo(Type::Reference);
259+
std::swap(result.reference_value_.reference, value);
260+
result.reference_value_.database_id = database_id;
261+
return result;
262+
}
263+
236264
FieldValue FieldValue::GeoPointValue(const GeoPoint& value) {
237265
FieldValue result;
238266
result.SwitchTo(Type::GeoPoint);
@@ -309,6 +337,12 @@ bool operator<(const FieldValue& lhs, const FieldValue& rhs) {
309337
return lhs.string_value_.compare(rhs.string_value_) < 0;
310338
case Type::Blob:
311339
return lhs.blob_value_ < rhs.blob_value_;
340+
case Type::Reference:
341+
return *lhs.reference_value_.database_id <
342+
*rhs.reference_value_.database_id ||
343+
(*lhs.reference_value_.database_id ==
344+
*rhs.reference_value_.database_id &&
345+
lhs.reference_value_.reference < rhs.reference_value_.reference);
312346
case Type::GeoPoint:
313347
return lhs.geo_point_value_ < rhs.geo_point_value_;
314348
case Type::Array:
@@ -343,6 +377,9 @@ void FieldValue::SwitchTo(const Type type) {
343377
case Type::Blob:
344378
blob_value_.~vector();
345379
break;
380+
case Type::Reference:
381+
reference_value_.~ReferenceValue();
382+
break;
346383
case Type::GeoPoint:
347384
geo_point_value_.~GeoPoint();
348385
break;
@@ -370,6 +407,10 @@ void FieldValue::SwitchTo(const Type type) {
370407
// Do not even bother to allocate a new array of size 0.
371408
new (&blob_value_) std::vector<uint8_t>();
372409
break;
410+
case Type::Reference:
411+
// Qualified name to avoid conflict with the member function of same name.
412+
new (&reference_value_) firebase::firestore::model::ReferenceValue();
413+
break;
373414
case Type::GeoPoint:
374415
new (&geo_point_value_) GeoPoint();
375416
break;

Firestore/core/src/firebase/firestore/model/field_value.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include <vector>
2626

2727
#include "Firestore/core/include/firebase/firestore/geo_point.h"
28+
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
29+
#include "Firestore/core/src/firebase/firestore/model/document_key.h"
2830
#include "Firestore/core/src/firebase/firestore/model/timestamp.h"
2931

3032
namespace firebase {
@@ -38,6 +40,12 @@ struct ServerTimestamp {
3840
bool has_previous_value_;
3941
};
4042

43+
struct ReferenceValue {
44+
DocumentKey reference;
45+
// Does not own the DatabaseId instance.
46+
const DatabaseId* database_id;
47+
};
48+
4149
/**
4250
* tagged-union class representing an immutable data value as stored in
4351
* Firestore. FieldValue represents all the different kinds of values
@@ -103,7 +111,10 @@ class FieldValue {
103111
static FieldValue StringValue(const std::string& value);
104112
static FieldValue StringValue(std::string&& value);
105113
static FieldValue BlobValue(const uint8_t* source, size_t size);
106-
// static FieldValue ReferenceValue();
114+
static FieldValue ReferenceValue(const DocumentKey& value,
115+
const DatabaseId* database_id);
116+
static FieldValue ReferenceValue(DocumentKey&& value,
117+
const DatabaseId* database_id);
107118
static FieldValue GeoPointValue(const GeoPoint& value);
108119
static FieldValue ArrayValue(const std::vector<FieldValue>& value);
109120
static FieldValue ArrayValue(std::vector<FieldValue>&& value);
@@ -133,6 +144,8 @@ class FieldValue {
133144
ServerTimestamp server_timestamp_value_;
134145
std::string string_value_;
135146
std::vector<uint8_t> blob_value_;
147+
// Qualified name to avoid conflict with the member function of same name.
148+
firebase::firestore::model::ReferenceValue reference_value_;
136149
GeoPoint geo_point_value_;
137150
std::vector<FieldValue> array_value_;
138151
std::map<const std::string, const FieldValue> object_value_;

Firestore/core/test/firebase/firestore/model/field_value_test.cc

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,20 @@ TEST(FieldValue, BlobType) {
144144
EXPECT_FALSE(a < a);
145145
}
146146

147+
TEST(FieldValue, ReferenceType) {
148+
const DatabaseId id("project", "database");
149+
const FieldValue a =
150+
FieldValue::ReferenceValue(DocumentKey::FromPathString("root/abc"), &id);
151+
DocumentKey key = DocumentKey::FromPathString("root/def");
152+
const FieldValue b = FieldValue::ReferenceValue(key, &id);
153+
const FieldValue c = FieldValue::ReferenceValue(std::move(key), &id);
154+
EXPECT_EQ(Type::Reference, a.type());
155+
EXPECT_EQ(Type::Reference, b.type());
156+
EXPECT_EQ(Type::Reference, c.type());
157+
EXPECT_TRUE(a < b);
158+
EXPECT_FALSE(a < a);
159+
}
160+
147161
TEST(FieldValue, GeoPointType) {
148162
const FieldValue a = FieldValue::GeoPointValue({1, 2});
149163
const FieldValue b = FieldValue::GeoPointValue({3, 4});
@@ -280,6 +294,23 @@ TEST(FieldValue, Copy) {
280294
clone = null_value;
281295
EXPECT_EQ(FieldValue::NullValue(), clone);
282296

297+
const DatabaseId database_id("project", "database");
298+
const FieldValue reference_value = FieldValue::ReferenceValue(
299+
DocumentKey::FromPathString("root/abc"), &database_id);
300+
clone = reference_value;
301+
EXPECT_EQ(FieldValue::ReferenceValue(DocumentKey::FromPathString("root/abc"),
302+
&database_id),
303+
clone);
304+
EXPECT_EQ(FieldValue::ReferenceValue(DocumentKey::FromPathString("root/abc"),
305+
&database_id),
306+
reference_value);
307+
clone = clone;
308+
EXPECT_EQ(FieldValue::ReferenceValue(DocumentKey::FromPathString("root/abc"),
309+
&database_id),
310+
clone);
311+
clone = null_value;
312+
EXPECT_EQ(FieldValue::NullValue(), clone);
313+
283314
const FieldValue geo_point_value = FieldValue::GeoPointValue({1, 2});
284315
clone = geo_point_value;
285316
EXPECT_EQ(FieldValue::GeoPointValue({1, 2}), clone);
@@ -361,7 +392,7 @@ TEST(FieldValue, Move) {
361392
clone = FieldValue::NullValue();
362393
EXPECT_EQ(FieldValue::NullValue(), clone);
363394

364-
const FieldValue timestamp_value = FieldValue::TimestampValue({100, 200});
395+
FieldValue timestamp_value = FieldValue::TimestampValue({100, 200});
365396
clone = std::move(timestamp_value);
366397
EXPECT_EQ(FieldValue::TimestampValue({100, 200}), clone);
367398
clone = FieldValue::NullValue();
@@ -373,13 +404,23 @@ TEST(FieldValue, Move) {
373404
clone = FieldValue::NullValue();
374405
EXPECT_EQ(FieldValue::NullValue(), clone);
375406

376-
const FieldValue blob_value = FieldValue::BlobValue(Bytes("abc"), 4);
407+
FieldValue blob_value = FieldValue::BlobValue(Bytes("abc"), 4);
377408
clone = std::move(blob_value);
378409
EXPECT_EQ(FieldValue::BlobValue(Bytes("abc"), 4), clone);
379410
clone = FieldValue::NullValue();
380411
EXPECT_EQ(FieldValue::NullValue(), clone);
381412

382-
const FieldValue geo_point_value = FieldValue::GeoPointValue({1, 2});
413+
const DatabaseId database_id("project", "database");
414+
FieldValue reference_value = FieldValue::ReferenceValue(
415+
DocumentKey::FromPathString("root/abc"), &database_id);
416+
clone = std::move(reference_value);
417+
EXPECT_EQ(FieldValue::ReferenceValue(DocumentKey::FromPathString("root/abc"),
418+
&database_id),
419+
clone);
420+
clone = null_value;
421+
EXPECT_EQ(FieldValue::NullValue(), clone);
422+
423+
FieldValue geo_point_value = FieldValue::GeoPointValue({1, 2});
383424
clone = std::move(geo_point_value);
384425
EXPECT_EQ(FieldValue::GeoPointValue({1, 2}), clone);
385426
clone = null_value;
@@ -415,6 +456,9 @@ TEST(FieldValue, CompareMixedType) {
415456
const FieldValue timestamp_value = FieldValue::TimestampValue({100, 200});
416457
const FieldValue string_value = FieldValue::StringValue("abc");
417458
const FieldValue blob_value = FieldValue::BlobValue(Bytes("abc"), 4);
459+
const DatabaseId database_id("project", "database");
460+
const FieldValue reference_value = FieldValue::ReferenceValue(
461+
DocumentKey::FromPathString("root/abc"), &database_id);
418462
const FieldValue geo_point_value = FieldValue::GeoPointValue({1, 2});
419463
const FieldValue array_value =
420464
FieldValue::ArrayValue(std::vector<FieldValue>());
@@ -425,7 +469,8 @@ TEST(FieldValue, CompareMixedType) {
425469
EXPECT_TRUE(number_value < timestamp_value);
426470
EXPECT_TRUE(timestamp_value < string_value);
427471
EXPECT_TRUE(string_value < blob_value);
428-
EXPECT_TRUE(blob_value < geo_point_value);
472+
EXPECT_TRUE(blob_value < reference_value);
473+
EXPECT_TRUE(reference_value < geo_point_value);
429474
EXPECT_TRUE(geo_point_value < array_value);
430475
EXPECT_TRUE(array_value < object_value);
431476
}

0 commit comments

Comments
 (0)