• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / jorgen.edelbo_138

13 Mar 2024 08:41AM UTC coverage: 91.77% (-0.3%) from 92.078%
jorgen.edelbo_138

Pull #7356

Evergreen

jedelbo
Add ability to get path to modified collections in object notifications
Pull Request #7356: Add ability to get path to modified collections in object notifications

94532 of 174642 branches covered (54.13%)

118 of 163 new or added lines in 16 files covered. (72.39%)

765 existing lines in 41 files now uncovered.

242808 of 264584 relevant lines covered (91.77%)

5878961.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.0
/src/realm/object-store/impl/list_notifier.cpp
1
////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright 2016 Realm Inc.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
//
17
////////////////////////////////////////////////////////////////////////////
18

19
#include <realm/object-store/impl/list_notifier.hpp>
20

21
#include <realm/list.hpp>
22
#include <realm/dictionary.hpp>
23

24
#include <realm/transaction.hpp>
25
#include <realm/util/scope_exit.hpp>
26

27
using namespace realm;
28
using namespace realm::_impl;
29

30
ListNotifier::ListNotifier(std::shared_ptr<Realm> realm, CollectionBase const& list, PropertyType type)
31
    : CollectionNotifier(std::move(realm))
32
    , m_type(type)
33
    , m_prev_size(list.size())
34
{
1,200✔
35
    attach(list);
1,200✔
36
    if (m_logger && m_logger->would_log(util::Logger::Level::debug)) {
1,200✔
37
        auto path = m_list->get_short_path();
74✔
38
        auto prop_name = m_list->get_table()->get_column_name(path[0].get_col_key());
74✔
39
        path[0] = PathElement(prop_name);
74✔
40

37✔
41
        m_description = util::format("%1 %2%3", list.get_collection_type(), m_list->get_obj().get_id(), path);
74✔
42
        m_logger->log(util::LogCategory::notification, util::Logger::Level::debug,
74✔
43
                      "Creating CollectionNotifier for %1", m_description);
74✔
44
    }
74✔
45
}
1,200✔
46

47
void ListNotifier::release_data() noexcept
48
{
1,200✔
49
    m_list = {};
1,200✔
50
    CollectionNotifier::release_data();
1,200✔
51
}
1,200✔
52

53
void ListNotifier::reattach()
54
{
2,396✔
55
    REALM_ASSERT(m_list);
2,396✔
56
    attach(*m_list);
2,396✔
57
}
2,396✔
58

59
void ListNotifier::attach(CollectionBase const& src)
60
{
3,596✔
61
    auto& tr = transaction();
3,596✔
62
    if (auto obj = tr.get_table(src.get_table()->get_key())->try_get_object(src.get_owner_key())) {
3,596✔
63
        auto path = src.get_stable_path();
3,512✔
64
        m_list = std::static_pointer_cast<CollectionBase>(obj.get_collection_by_stable_path(path));
3,512✔
65
        m_collection_parent = dynamic_cast<CollectionParent*>(m_list.get());
3,512✔
66
    }
3,512✔
67
    else {
84✔
68
        m_list = nullptr;
84✔
69
        m_collection_parent = nullptr;
84✔
70
    }
84✔
71
}
3,596✔
72

73
bool ListNotifier::do_add_required_change_info(TransactionChangeInfo& info)
74
{
1,816✔
75
    if (!m_list || !m_list->is_attached())
1,816✔
76
        return false; // origin row was deleted after the notification was added
96✔
77

860✔
78
    StablePath this_path = m_list->get_stable_path();
1,720✔
79
    info.collections.push_back(
1,720✔
80
        {m_list->get_table()->get_key(), m_list->get_owner_key(), std::move(this_path), &m_change});
1,720✔
81

860✔
82
    m_info = &info;
1,720✔
83

860✔
84
    // When adding or removing a callback, the related tables can change due to the way we calculate related tables
860✔
85
    // when key path filters are set, hence we need to recalculate every time the callbacks are changed.
860✔
86
    // We only need to do this for lists that link to other lists. Lists of primitives cannot have related tables.
860✔
87
    util::CheckedLockGuard lock(m_callback_mutex);
1,720✔
88
    if (m_did_modify_callbacks && m_type == PropertyType::Object) {
1,720✔
89
        update_related_tables(*m_list->get_table());
238✔
90
    }
238✔
91

860✔
92
    return true;
1,720✔
93
}
1,720✔
94

95
void ListNotifier::run()
96
{
2,846✔
97
    NotifierRunLogger log(m_logger.get(), "ListNotifier", m_description);
2,846✔
98

1,423✔
99
    if (!m_list || !m_list->is_attached()) {
2,846✔
100
        // List was deleted, so report all of the rows being removed if this is
193✔
101
        // the first run after that
193✔
102
        if (m_prev_size) {
386✔
103
            m_change.deletions.set(m_prev_size);
242✔
104
            m_prev_size = 0;
242✔
105
        }
242✔
106
        else {
144✔
107
            m_change = {};
144✔
108
        }
144✔
109
        report_collection_root_is_deleted();
386✔
110
        return;
386✔
111
    }
386✔
112

1,230✔
113
    m_prev_size = m_list->size();
2,460✔
114

1,230✔
115
    if (m_info && m_type == PropertyType::Object) {
2,460✔
116
        auto object_did_change = get_modification_checker(*m_info, m_list->get_target_table());
326✔
117
        for (size_t i = 0; i < m_prev_size; ++i) {
1,650✔
118
            if (m_change.modifications.contains(i))
1,324✔
119
                continue;
52✔
120
            auto m = m_list->get_any(i);
1,272✔
121
            if (!m.is_null() && object_did_change(m.get<ObjKey>()))
1,272✔
122
                m_change.modifications.add(i);
68✔
123
        }
1,272✔
124

163✔
125
        for (auto const& move : m_change.moves) {
169✔
126
            if (m_change.modifications.contains(move.to))
12✔
127
                continue;
8✔
128
            if (object_did_change(m_list->get_any(move.to).get<ObjKey>()))
4✔
UNCOV
129
                m_change.modifications.add(move.to);
×
130
        }
4✔
131
    }
326✔
132

1,230✔
133
    // Modifications to nested values in Mixed are recorded in replication as
1,230✔
134
    // StableIndex and we have to look up the actual index afterwards
1,230✔
135
    if (m_change.stable_indexes.size()) {
2,460✔
136
        REALM_ASSERT(m_collection_parent);
36✔
137
        REALM_ASSERT(m_type == PropertyType::Mixed);
36✔
138
        for (auto& p : m_change.stable_indexes) {
40✔
139
            if (auto ndx = m_collection_parent->find_index(p); ndx != realm::not_found)
40✔
140
                m_change.modifications.add(ndx);
40✔
141
        }
40✔
142
    }
36✔
143
}
2,460✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc