Skip to content

Commit 281c5d5

Browse files
amabluea-maurice
authored andcommitted
Added VariantGetChild and VariantUpdateChild. These functions more closely
replicate the behavior of Node.GetChild and Node.UpdateChild in the Android implementation to ensure that the behavior is the same as the mobile SDKs. Also went through and updated a large number of places that were using Set/GetInternalVariant or MakeVariantAtPath in a more ad hoc way to simulate the logic in VariantGetChild or VariantUpdateChild. Finally, fixed a number of broken or incorrect tests. PiperOrigin-RevId: 249716604
1 parent 18251b6 commit 281c5d5

24 files changed

+376
-264
lines changed

database/src/desktop/core/child_event_registration.cc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
#include "database/src/desktop/core/child_event_registration.h"
16+
1617
#include "database/src/desktop/data_snapshot_desktop.h"
1718
#include "database/src/desktop/view/event.h"
1819
#include "database/src/desktop/view/event_type.h"
@@ -34,11 +35,17 @@ bool ChildEventRegistration::RespondsTo(EventType event_type) {
3435

3536
Event ChildEventRegistration::GenerateEvent(const Change& change,
3637
const QuerySpec& query_spec) {
37-
return Event(change.event_type, this,
38-
DataSnapshotInternal(database_,
39-
query_spec.path.GetChild(change.child_key),
40-
change.indexed_variant.variant()),
41-
change.prev_name);
38+
// return Event(change.event_type, this,
39+
// DataSnapshotInternal(database_,
40+
// query_spec.path.GetChild(change.child_key),
41+
// change.indexed_variant.variant()),
42+
// change.prev_name);
43+
return Event(
44+
change.event_type, this,
45+
DataSnapshotInternal(database_, change.indexed_variant.variant(),
46+
QuerySpec(query_spec.path.GetChild(change.child_key),
47+
change.indexed_variant.query_params())),
48+
change.prev_name);
4249
}
4350

4451
void ChildEventRegistration::FireEvent(const Event& event) {

database/src/desktop/core/compound_write.cc

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
#include "database/src/desktop/core/compound_write.h"
16+
1617
#include "app/src/assert.h"
1718
#include "database/src/desktop/core/tree.h"
1819
#include "database/src/desktop/util_desktop.h"
@@ -70,19 +71,18 @@ CompoundWrite CompoundWrite::AddWrite(const Path& path,
7071
// TODO(amablue): Consider making FindRootMostPathWithValue also return
7172
// the remainder and not just the root most path.
7273
Optional<Path> relative_path = Path::GetRelative(*root_most_path, path);
73-
const Variant* value = write_tree_.GetValueAt(root_most_path.value());
74+
const Variant* value = write_tree_.GetValueAt(*root_most_path);
7475
std::vector<std::string> directories = relative_path->GetDirectories();
7576
std::string back = directories.empty() ? "" : directories.back();
76-
const Variant* internal_variant =
77-
GetInternalVariant(value, relative_path->GetParent());
78-
if (!relative_path->empty() && back == ".priority" &&
79-
(internal_variant == nullptr || internal_variant->is_null())) {
77+
78+
if (!relative_path->empty() && IsPriorityKey(back) &&
79+
VariantIsEmpty(VariantGetChild(value, relative_path->GetParent()))) {
8080
// Ignore priority updates on empty variants
8181
return *this;
8282
} else {
8383
CompoundWrite result = *this;
8484
Variant updated_variant = *value;
85-
*MakeVariantAtPath(&updated_variant, *relative_path) = *variant;
85+
VariantUpdateChild(&updated_variant, *relative_path, *variant);
8686
result.write_tree_.SetValueAt(*root_most_path, updated_variant);
8787
return result;
8888
}
@@ -144,11 +144,9 @@ const Optional<Variant>& CompoundWrite::GetRootWrite() const {
144144
Optional<Variant> CompoundWrite::GetCompleteVariant(const Path& path) const {
145145
Optional<Path> root_most = write_tree_.FindRootMostPathWithValue(path);
146146
if (root_most.has_value()) {
147-
const Path& root_most_path = root_most.value();
148-
const Variant* root_most_value = write_tree_.GetValueAt(root_most_path);
149-
Optional<Path> remaining_path = Path::GetRelative(root_most_path, path);
150-
return OptionalFromPointer(
151-
GetInternalVariant(root_most_value, *remaining_path));
147+
const Variant* root_most_value = write_tree_.GetValueAt(*root_most);
148+
Optional<Path> remaining_path = Path::GetRelative(*root_most, path);
149+
return Optional<Variant>(VariantGetChild(root_most_value, *remaining_path));
152150
} else {
153151
return Optional<Variant>();
154152
}
@@ -213,14 +211,13 @@ Variant CompoundWrite::ApplySubtreeWrite(const Path& relative_path,
213211
Variant variant) const {
214212
if (write_tree->value().has_value()) {
215213
// Since there a write is always a leaf, we're done here
216-
*MakeVariantAtPath(&variant, relative_path) = write_tree->value().value();
217-
return variant;
214+
VariantUpdateChild(&variant, relative_path, write_tree->value().value());
218215
} else {
219216
Optional<Variant> priority_write;
220217
for (auto& key_tree_pair : write_tree->children()) {
221218
const std::string& child_key = key_tree_pair.first;
222219
const Tree<Variant>& child_tree = key_tree_pair.second;
223-
if (child_key == ".priority") {
220+
if (IsPriorityKey(child_key)) {
224221
// Apply priorities at the end so we don't update priorities for
225222
// either empty variants or forget to apply priorities to empty
226223
// variants that are later filled
@@ -235,13 +232,13 @@ Variant CompoundWrite::ApplySubtreeWrite(const Path& relative_path,
235232
}
236233
// If there was a priority write, we only apply it if the variant is not
237234
// empty.
238-
if (GetInternalVariant(&variant, relative_path) != nullptr &&
235+
if (!VariantIsEmpty(VariantGetChild(&variant, relative_path)) &&
239236
priority_write.has_value()) {
240-
*MakeVariantAtPath(&variant, relative_path.GetChild(".priority")) =
241-
priority_write.value();
237+
VariantUpdateChild(&variant, relative_path.GetChild(kPriorityKey),
238+
priority_write.value());
242239
}
243-
return variant;
244240
}
241+
return variant;
245242
}
246243

247244
} // namespace internal

database/src/desktop/core/indexed_variant.cc

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ const Variant* IndexedVariant::GetOrderByVariant(const Variant& key,
9595
const Variant& value) {
9696
switch (query_params_.order_by) {
9797
case QueryParams::kOrderByPriority: {
98-
return GetVariantPriority(value);
98+
return &GetVariantPriority(value);
9999
}
100100
case QueryParams::kOrderByChild: {
101101
if (value.is_map()) {
@@ -118,16 +118,14 @@ const Variant* IndexedVariant::GetOrderByVariant(const Variant& key,
118118
static bool IsDefinedOn(const Variant& variant, const QueryParams& params) {
119119
switch (params.order_by) {
120120
case QueryParams::kOrderByPriority: {
121-
const Variant* priority = GetVariantPriority(variant);
122-
return priority && !VariantIsEmpty(*priority);
121+
return !VariantIsEmpty(GetVariantPriority(variant));
123122
}
124123
case QueryParams::kOrderByKey: {
125124
return true;
126125
}
127126
case QueryParams::kOrderByChild: {
128-
const Variant* child =
129-
GetInternalVariant(&variant, Path(params.order_by_child));
130-
return child && !VariantIsEmpty(*child);
127+
return !VariantIsEmpty(
128+
VariantGetChild(&variant, Path(params.order_by_child)));
131129
}
132130
case QueryParams::kOrderByValue: {
133131
return true;

database/src/desktop/core/operation.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
// limitations under the License.
1414

1515
#include "database/src/desktop/core/operation.h"
16+
1617
#include <iostream>
18+
1719
#include "app/src/assert.h"
1820
#include "app/src/path.h"
1921
#include "database/src/desktop/util_desktop.h"
@@ -58,11 +60,8 @@ Operation Operation::ListenComplete(const OperationSource& source,
5860
static Optional<Operation> OperationForChildOverwrite(
5961
const Operation& op, const std::string& child_key) {
6062
if (op.path.empty()) {
61-
const Variant* child_snapshot_ptr =
62-
GetInternalVariant(&op.snapshot, child_key);
6363
return Optional<Operation>(Operation::Overwrite(
64-
op.source, Path(),
65-
child_snapshot_ptr ? *child_snapshot_ptr : Variant::Null()));
64+
op.source, Path(), VariantGetChild(&op.snapshot, child_key)));
6665
} else {
6766
std::vector<std::string> directories = op.path.GetDirectories();
6867
Path child_path(std::next(directories.begin()), directories.end());

database/src/desktop/core/repo.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -810,8 +810,8 @@ void Repo::HandleTransactionResponse(const connection::ResponsePtr& ptr) {
810810
TransactionDataPtr& transaction = future_to_complete.transaction;
811811
const Variant& node = future_to_complete.node;
812812

813-
DataSnapshot snapshot(
814-
new DataSnapshotInternal(database_, transaction->path, node));
813+
DataSnapshot snapshot(new DataSnapshotInternal(
814+
database_, node, QuerySpec(transaction->path)));
815815
transaction->ref_future->CompleteWithResult(transaction->future_handle,
816816
kErrorNone, snapshot);
817817
}
@@ -962,8 +962,8 @@ void Repo::RerunTransactionQueue(const std::vector<TransactionDataPtr>& queue,
962962
TransactionDataPtr& transaction = future_to_complete.transaction;
963963
Error& abort_reason = future_to_complete.abort_reason;
964964
Variant& node = future_to_complete.node;
965-
DataSnapshot snapshot(
966-
new DataSnapshotInternal(database_, transaction->path, node));
965+
DataSnapshot snapshot(new DataSnapshotInternal(
966+
database_, node, QuerySpec(transaction->path)));
967967
transaction->ref_future->CompleteWithResult(transaction->future_handle,
968968
abort_reason, snapshot);
969969
}

database/src/desktop/core/server_values.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
// limitations under the License.
1414

1515
#include "database/src/desktop/core/server_values.h"
16+
1617
#include <ctime>
18+
1719
#include "app/src/include/firebase/variant.h"
1820
#include "database/src/desktop/core/compound_write.h"
1921
#include "database/src/desktop/util_desktop.h"
@@ -69,12 +71,11 @@ static void ResolveDeferredValueSnapshotHelper(Variant* data,
6971

7072
Variant ResolveDeferredValueSnapshot(const Variant& data,
7173
const Variant& server_values) {
72-
const Variant* priority = GetVariantPriority(data);
73-
priority = priority ? &ResolveDeferredValue(*priority, server_values)
74-
: &kNullVariant;
74+
Variant priority = GetVariantPriority(data);
75+
priority = ResolveDeferredValue(priority, server_values);
7576
Variant new_data = data;
7677
ResolveDeferredValueSnapshotHelper(&new_data, server_values);
77-
return CombineValueAndPriority(new_data, *priority);
78+
return CombineValueAndPriority(new_data, priority);
7879
}
7980

8081
CompoundWrite ResolveDeferredValueMerge(const CompoundWrite& merge,

database/src/desktop/core/sync_tree.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
// limitations under the License.
1414

1515
#include "database/src/desktop/core/sync_tree.h"
16+
1617
#include <vector>
18+
1719
#include "app/memory/unique_ptr.h"
1820
#include "app/src/assert.h"
1921
#include "app/src/callback.h"
@@ -172,10 +174,10 @@ std::vector<Event> SyncTree::AddEventRegistration(
172174
auto& variant = persistent_server_cache.indexed_variant().variant();
173175
if (variant.is_map()) {
174176
for (auto& key_value_pair : variant.map()) {
175-
Path key(key_value_pair.first.AsString().string_value());
177+
const char* key = key_value_pair.first.AsString().string_value();
178+
const Variant& value = key_value_pair.second;
176179
if (GetInternalVariant(&*server_cache_variant, key) == nullptr) {
177-
SetVariantAtPath(&*server_cache_variant, key,
178-
key_value_pair.second);
180+
VariantUpdateChild(&server_cache_variant.value(), key, value);
179181
}
180182
}
181183
}
@@ -270,7 +272,7 @@ std::vector<Event> SyncTree::ApplyOperationHelper(
270272
Tree<SyncPoint>* child_tree = sync_point_tree->GetChild(child_key);
271273
if (child_tree && child_operation.has_value()) {
272274
const Variant* child_server_cache =
273-
server_cache ? GetInternalVariant(server_cache, child_key) : nullptr;
275+
server_cache ? &VariantGetChild(server_cache, child_key) : nullptr;
274276
WriteTreeRef child_writes_cache = writes_cache->Child(child_key);
275277
events = ApplyOperationHelper(*child_operation, child_tree,
276278
child_server_cache, &child_writes_cache);

database/src/desktop/core/value_event_registration.cc

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
#include "database/src/desktop/core/value_event_registration.h"
16+
1617
#include "database/src/desktop/data_snapshot_desktop.h"
1718
#include "database/src/include/firebase/database/common.h"
1819
#include "firebase/database/data_snapshot.h"
@@ -29,10 +30,15 @@ bool ValueEventRegistration::RespondsTo(EventType event_type) {
2930

3031
Event ValueEventRegistration::GenerateEvent(const Change& change,
3132
const QuerySpec& query_spec) {
32-
return Event(kEventTypeValue, this,
33-
DataSnapshotInternal(database_,
34-
query_spec.path.GetChild(change.child_key),
35-
change.indexed_variant.variant()));
33+
// return Event(kEventTypeValue, this,
34+
// DataSnapshotInternal(database_,
35+
// query_spec.path.GetChild(change.child_key),
36+
// change.indexed_variant.variant()));
37+
return Event(
38+
kEventTypeValue, this,
39+
DataSnapshotInternal(database_, change.indexed_variant.variant(),
40+
QuerySpec(query_spec.path.GetChild(change.child_key),
41+
change.indexed_variant.query_params())));
3642
}
3743

3844
void ValueEventRegistration::FireEvent(const Event& event) {

database/src/desktop/core/write_tree.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
// limitations under the License.
1414

1515
#include "database/src/desktop/core/write_tree.h"
16+
1617
#include <algorithm>
18+
1719
#include "app/src/assert.h"
1820
#include "database/src/desktop/core/compound_write.h"
1921
#include "database/src/desktop/query_params_comparator.h"
@@ -273,8 +275,8 @@ Optional<Variant> WriteTree::CalcEventCacheAfterServerOverwrite(
273275
CompoundWrite child_merge = visible_writes_.ChildCompoundWrite(path);
274276
if (child_merge.IsEmpty()) {
275277
// We're not shadowing at all. Case 1.
276-
return OptionalFromPointer(
277-
GetInternalVariant(existing_server_snap, child_path));
278+
return Optional<Variant>(
279+
VariantGetChild(existing_server_snap, child_path));
278280
} else {
279281
// This could be more efficient if the server_node + updates doesn't
280282
// change the local_snap However this is tricky to find out, since user
@@ -284,8 +286,8 @@ Optional<Variant> WriteTree::CalcEventCacheAfterServerOverwrite(
284286
// therefore not enough to only check if the updates change the
285287
// server_node. Maybe check if the merge tree contains these special
286288
// cases and only do a full overwrite in that case?
287-
return Optional<Variant>(child_merge.Apply(
288-
*GetInternalVariant(existing_server_snap, child_path)));
289+
return Optional<Variant>(
290+
child_merge.Apply(VariantGetChild(existing_server_snap, child_path)));
289291
}
290292
}
291293
}
@@ -301,11 +303,9 @@ Optional<Variant> WriteTree::CalcCompleteChild(
301303
} else {
302304
if (existing_server_snap.IsCompleteForChild(child_key)) {
303305
CompoundWrite child_merge = visible_writes_.ChildCompoundWrite(path);
304-
const Variant* child =
305-
GetInternalVariant(&existing_server_snap.variant(), child_key);
306-
if (child) {
307-
return Optional<Variant>(child_merge.Apply(*child));
308-
}
306+
const Variant& child =
307+
VariantGetChild(&existing_server_snap.variant(), child_key);
308+
return Optional<Variant>(child_merge.Apply(child));
309309
}
310310
return Optional<Variant>();
311311
}
@@ -402,8 +402,8 @@ CompoundWrite WriteTree::LayerTree(const std::vector<UserWriteRecord>& writes,
402402
} else if (write_path.StartsWith(tree_root)) {
403403
compound_write = compound_write.AddWrite(
404404
Path(),
405-
*GetInternalVariant(&write.overwrite,
406-
*Path::GetRelative(write_path, tree_root)));
405+
VariantGetChild(&write.overwrite,
406+
*Path::GetRelative(write_path, tree_root)));
407407
} else {
408408
// There is no overlap between root path and write path, ignore
409409
// write

0 commit comments

Comments
 (0)