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

realm / realm-core / 2300

08 May 2024 08:02AM UTC coverage: 90.775% (+0.02%) from 90.754%
2300

push

Evergreen

web-flow
RCORE-2108: Clear backlinks when object containing nested collections is deleted (#7680)

102002 of 180582 branches covered (56.49%)

64 of 82 new or added lines in 6 files covered. (78.05%)

39 existing lines in 14 files now uncovered.

213205 of 234873 relevant lines covered (90.77%)

5873707.76 hits per line

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

93.08
/src/realm/collection_parent.cpp
1
/*************************************************************************
2
 *
3
 * Copyright 2023 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/collection_parent.hpp>
20
#include "realm/list.hpp"
21
#include "realm/set.hpp"
22
#include "realm/dictionary.hpp"
23
#include "realm/util/overload.hpp"
24

25
#include <random>
26
#include <mutex>
27

28
namespace realm {
29

30
std::ostream& operator<<(std::ostream& ostr, const PathElement& elem)
31
{
49,689✔
32
    if (elem.is_ndx()) {
49,689✔
33
        size_t ndx = elem.get_ndx();
11,058✔
34
        if (ndx == 0) {
11,058✔
35
            ostr << "FIRST";
4,032✔
36
        }
4,032✔
37
        else if (ndx == size_t(-1)) {
7,026✔
38
            ostr << "LAST";
330✔
39
        }
330✔
40
        else {
6,696✔
41
            ostr << elem.get_ndx();
6,696✔
42
        }
6,696✔
43
    }
11,058✔
44
    else if (elem.is_col_key()) {
38,631✔
45
        ostr << elem.get_col_key();
×
46
    }
×
47
    else if (elem.is_key()) {
38,631✔
48
        ostr << "'" << elem.get_key() << "'";
38,487✔
49
    }
38,487✔
50
    else if (elem.is_all()) {
144✔
51
        ostr << '*';
144✔
52
    }
144✔
53

54
    return ostr;
49,689✔
55
}
49,689✔
56

57
std::ostream& operator<<(std::ostream& ostr, const Path& path)
58
{
21,747✔
59
    for (auto& elem : path) {
48,633✔
60
        ostr << '[' << elem << ']';
48,633✔
61
    }
48,633✔
62
    return ostr;
21,747✔
63
}
21,747✔
64

65
bool StablePath::is_prefix_of(const StablePath& other) const noexcept
66
{
10,686✔
67
    if (size() > other.size())
10,686✔
68
        return false;
234✔
69
    return std::equal(begin(), end(), other.begin());
10,452✔
70
}
10,686✔
71

72
/***************************** CollectionParent ******************************/
73

74
CollectionParent::~CollectionParent() {}
2,711,682✔
75

76
void CollectionParent::check_level() const
77
{
4,428✔
78
    if (size_t(m_level) + 1 > s_max_level) {
4,428✔
79
        throw LogicError(ErrorCodes::LimitExceeded, "Max nesting level reached");
6✔
80
    }
6✔
81
}
4,428✔
82

83
template <typename Base, template <typename> typename Collection, typename LinkCol>
84
std::unique_ptr<Base> create_collection(ColKey col_key, uint8_t level)
85
{
439,677✔
86
    bool nullable = col_key.get_attrs().test(col_attr_Nullable);
439,677✔
87
    switch (col_key.get_type()) {
439,677✔
88
        case col_type_Int:
27,078✔
89
            if (nullable)
27,078✔
90
                return std::make_unique<Collection<util::Optional<Int>>>(col_key);
5,622✔
91
            return std::make_unique<Collection<Int>>(col_key);
21,456✔
92
        case col_type_Bool:
9,264✔
93
            if (nullable)
9,264✔
94
                return std::make_unique<Collection<util::Optional<Bool>>>(col_key);
4,812✔
95
            return std::make_unique<Collection<Bool>>(col_key);
4,452✔
96
        case col_type_Float:
10,056✔
97
            if (nullable)
10,056✔
98
                return std::make_unique<Collection<util::Optional<Float>>>(col_key);
5,226✔
99
            return std::make_unique<Collection<Float>>(col_key);
4,830✔
100
        case col_type_Double:
10,314✔
101
            if (nullable)
10,314✔
102
                return std::make_unique<Collection<util::Optional<Double>>>(col_key);
5,226✔
103
            return std::make_unique<Collection<Double>>(col_key);
5,088✔
104
        case col_type_String:
245,211✔
105
            return std::make_unique<Collection<String>>(col_key);
245,211✔
106
        case col_type_Binary:
9,882✔
107
            return std::make_unique<Collection<Binary>>(col_key);
9,882✔
108
        case col_type_Timestamp:
9,978✔
109
            return std::make_unique<Collection<Timestamp>>(col_key);
9,978✔
110
        case col_type_Decimal:
9,564✔
111
            return std::make_unique<Collection<Decimal128>>(col_key);
9,564✔
112
        case col_type_ObjectId:
18,414✔
113
            if (nullable)
18,414✔
114
                return std::make_unique<Collection<util::Optional<ObjectId>>>(col_key);
13,944✔
115
            return std::make_unique<Collection<ObjectId>>(col_key);
4,470✔
116
        case col_type_UUID:
9,306✔
117
            if (nullable)
9,306✔
118
                return std::make_unique<Collection<util::Optional<UUID>>>(col_key);
4,848✔
119
            return std::make_unique<Collection<UUID>>(col_key);
4,458✔
120
        case col_type_TypedLink:
✔
121
            return std::make_unique<Collection<ObjLink>>(col_key);
×
122
        case col_type_Mixed:
15,714✔
123
            return std::make_unique<Collection<Mixed>>(col_key, level + 1);
15,714✔
124
        case col_type_Link:
64,896✔
125
            return std::make_unique<LinkCol>(col_key);
64,896✔
126
        default:
✔
127
            REALM_TERMINATE("Unsupported column type.");
128
    }
439,677✔
129
}
439,677✔
130

131
LstBasePtr CollectionParent::get_listbase_ptr(ColKey col_key, uint8_t level)
132
{
321,858✔
133
    REALM_ASSERT(col_key.get_attrs().test(col_attr_List) || col_key.get_type() == col_type_Mixed);
321,858✔
134
    return create_collection<LstBase, Lst, LnkLst>(col_key, level);
321,858✔
135
}
321,858✔
136

137
SetBasePtr CollectionParent::get_setbase_ptr(ColKey col_key, uint8_t level)
138
{
117,819✔
139
    REALM_ASSERT(col_key.get_attrs().test(col_attr_Set));
117,819✔
140
    return create_collection<SetBase, Set, LnkSet>(col_key, level);
117,819✔
141
}
117,819✔
142

143
CollectionBasePtr CollectionParent::get_collection_ptr(ColKey col_key, uint8_t level)
144
{
127,461✔
145
    if (col_key.is_list()) {
127,461✔
146
        return get_listbase_ptr(col_key, level);
23,451✔
147
    }
23,451✔
148
    else if (col_key.is_set()) {
104,010✔
149
        return get_setbase_ptr(col_key, level);
74,271✔
150
    }
74,271✔
151
    else if (col_key.is_dictionary()) {
29,739✔
152
        return std::make_unique<Dictionary>(col_key, level + 1);
29,739✔
153
    }
29,739✔
154
    return {};
×
155
}
127,461✔
156

157
int64_t CollectionParent::generate_key(size_t sz)
158
{
6,984✔
159
    static std::mt19937 gen32;
6,984✔
160
    static std::mutex mutex;
6,984✔
161

162
    int64_t key;
6,984✔
163
    const std::lock_guard<std::mutex> lock(mutex);
6,984✔
164
    do {
6,984✔
165
        if (sz < 0x10) {
6,984✔
166
            key = int8_t(gen32());
4,158✔
167
        }
4,158✔
168
        else if (sz < 0x1000) {
2,826✔
169
            key = int16_t(gen32());
2,826✔
170
        }
2,826✔
UNCOV
171
        else {
×
UNCOV
172
            key = int32_t(gen32());
×
UNCOV
173
        }
×
174
    } while (key == 0);
6,984✔
175

176
    return key;
6,984✔
177
}
6,984✔
178

179
void CollectionParent::set_key(BPlusTreeMixed& tree, size_t index)
180
{
4,158✔
181
    int64_t key = generate_key(tree.size());
4,158✔
182
    while (tree.find_key(key) != realm::not_found) {
4,164✔
183
        key++;
6✔
184
    }
6✔
185
    tree.set_key(index, key);
4,158✔
186
}
4,158✔
187

188
} // namespace realm
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

© 2026 Coveralls, Inc