• 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

88.72
/src/realm/obj.hpp
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
#ifndef REALM_OBJ_HPP
20
#define REALM_OBJ_HPP
21

22
#include <realm/node.hpp>
23
#include <realm/collection_parent.hpp>
24
#include <realm/mixed.hpp>
25
#include "realm/column_type_traits.hpp"
26

27
#include <map>
28

29
#define REALM_CLUSTER_IF
30

31
namespace realm {
32

33
class ClusterTree;
34
class TableView;
35
class CascadeState;
36
class ObjList;
37
struct GlobalKey;
38

39
template <class>
40
class Lst;
41
template <class>
42
class Set;
43
template <class T>
44
using LstPtr = std::unique_ptr<Lst<T>>;
45
template <class T>
46
using SetPtr = std::unique_ptr<Set<T>>;
47

48
using LinkCollectionPtr = std::unique_ptr<ObjList>;
49

50
class LnkLst;
51
using LnkLstPtr = std::unique_ptr<LnkLst>;
52
class LnkSet;
53
using LnkSetPtr = std::unique_ptr<LnkSet>;
54

55
namespace _impl {
56
class DeepChangeChecker;
57
}
58

59
// 'Object' would have been a better name, but it clashes with a class in ObjectStore
60
class Obj {
61
public:
62
    constexpr Obj() = default;
14,511,645✔
63
    Obj(TableRef table, MemRef mem, ObjKey key, size_t row_ndx);
64

65
    // CollectionParent implementation
66
    UpdateStatus update_if_needed() const;
67
    // Get the path in a minimal format without including object accessors.
68
    // If you need to obtain additional information for each object in the path,
69
    // you should use get_fat_path() or traverse_path() instead (see below).
70
    FullPath get_path() const;
71
    std::string get_id() const;
72
    Path get_short_path() const noexcept;
73
    ColKey get_col_key() const noexcept;
74
    StablePath get_stable_path() const noexcept;
75
    void translate_path(const StablePath&, Path&) const;
76
    void add_index(Path& path, const CollectionParent::Index& ndx) const;
77

78
    TableRef get_table() const noexcept
79
    {
74,312,748✔
80
        return m_table.cast_away_const();
74,312,748✔
81
    }
74,312,748✔
82
    ref_type get_collection_ref(CollectionParent::Index, CollectionType) const;
83
    bool check_collection_ref(CollectionParent::Index, CollectionType) const noexcept;
84
    void set_collection_ref(CollectionParent::Index, ref_type, CollectionType);
85
    StableIndex build_index(ColKey) const;
86
    bool check_index(StableIndex) const;
87

88
    // Operator overloads
89
    bool operator==(const Obj& other) const;
90

91
    // Check if this object is default constructed
92
    explicit operator bool() const noexcept
93
    {
11,936,703✔
94
        return m_table != nullptr;
11,936,703✔
95
    }
11,936,703✔
96

97
    // Simple getters
98
    Allocator& get_alloc() const;
99
    Replication* get_replication() const;
100
    ObjKey get_key() const noexcept
101
    {
39,011,691✔
102
        return m_key;
39,011,691✔
103
    }
39,011,691✔
104
    GlobalKey get_object_id() const;
105
    ObjLink get_link() const;
106

107
    /// Check if the object is still alive
108
    bool is_valid() const noexcept;
109

110
    /// Delete object from table. Object is invalid afterwards.
111
    void remove();
112
    /// Invalidate
113
    ///  - this turns the object into a tombstone if links to the object exist.
114
    ///  - deletes the object is no links to the object exist.
115
    ///  - To be used by the Sync client.
116
    void invalidate();
117

118
    template <typename U>
119
    U get(ColKey col_key) const;
120

121
    Mixed get_any(ColKey col_key) const;
122
    Mixed get_any(StringData col_name) const
123
    {
12,966✔
124
        return get_any(get_column_key(col_name));
12,966✔
125
    }
12,966✔
126
    Mixed get_primary_key() const;
127

128
    template <typename U>
129
    U get(StringData col_name) const
130
    {
928,669✔
131
        return get<U>(get_column_key(col_name));
928,669✔
132
    }
928,669✔
133
    bool is_unresolved(ColKey col_key) const;
134

135
    size_t get_link_count(ColKey col_key) const;
136
    TableRef get_target_table(ColKey col_key) const;
137

138
    bool is_null(ColKey col_key) const;
139
    bool is_null(StringData col_name) const
140
    {
4,884✔
141
        return is_null(get_column_key(col_name));
4,884✔
142
    }
4,884✔
143
    bool has_backlinks(bool only_strong_links) const;
144
    size_t get_backlink_count() const;
145
    size_t get_backlink_count(const Table& origin, ColKey origin_col_key) const;
146
    ObjKey get_backlink(const Table& origin, ColKey origin_col_key, size_t backlink_ndx) const;
147
    TableView get_backlink_view(TableRef src_table, ColKey src_col_key) const;
148
    void verify_backlink(const Table& origin, ColKey origin_col_key, ObjKey origin_key) const;
149

150
    // To be used by the query system when a single object should
151
    // be tested. Will allow a function to be called in the context
152
    // of the owning cluster.
153
    template <class T>
154
    bool evaluate(T func) const;
155

156
    void to_json(std::ostream& out, JSONOutputMode output_mode = output_mode_json) const;
157

158
    std::string to_string() const;
159

160
    // Get the fat path to this object expressed as a vector of fat path elements.
161
    // each Fat path elements include a Obj allowing for low cost access to the
162
    // objects data.
163
    // For a top-level object, the returned vector will be empty.
164
    // For an embedded object, the vector has the top object as first element,
165
    // and the embedded object itself is not included in the path.
166
    struct FatPathElement;
167
    using FatPath = std::vector<FatPathElement>;
168
    FatPath get_fat_path() const;
169

170
    // For an embedded object, traverse the path leading to this object.
171
    // The PathSizer is called first to set the size of the path
172
    // Then there is one call for each object on that path, starting with the top level object
173
    // The embedded object itself is not considered part of the path.
174
    // Note: You should never provide the path_index for calls to traverse_path.
175
    using Visitor = util::FunctionRef<void(const Obj&, ColKey, Mixed)>;
176
    using PathSizer = util::FunctionRef<void(size_t)>;
177
    void traverse_path(Visitor v, PathSizer ps, size_t path_index = 0) const;
178

179
    template <typename U>
180
    Obj& set(ColKey col_key, U value, bool is_default = false);
181
    // Create a new object and link it. If an embedded object
182
    // is already set, it will be removed. If a non-embedded
183
    // object is already set, we throw LogicError (to prevent
184
    // dangling objects, since they do not delete automatically
185
    // if they are not embedded...)
186
    Obj create_and_set_linked_object(ColKey col_key, bool is_default = false);
187
    // Clear all fields of a linked object returning it to its
188
    // default state. If the object does not exist, create a
189
    // new object and link it. (To Be Implemented)
190
    Obj clear_linked_object(ColKey col_key);
191
    Obj& set_any(ColKey col_key, Mixed value, bool is_default = false);
192
    Obj& set_any(StringData col_name, Mixed value, bool is_default = false)
193
    {
2✔
194
        return set_any(get_column_key(col_name), value, is_default);
2✔
195
    }
2✔
196

197
    template <typename U>
198
    Obj& set(StringData col_name, U value, bool is_default = false)
199
    {
2,702,769✔
200
        return set(get_column_key(col_name), value, is_default);
2,702,769✔
201
    }
2,702,769✔
202

203
    Obj& set_null(ColKey col_key, bool is_default = false);
204
    Obj& set_null(StringData col_name, bool is_default = false)
205
    {
30✔
206
        return set_null(get_column_key(col_name), is_default);
30✔
207
    }
30✔
208
    Obj& set_json(ColKey col_key, StringData json);
209

210
    Obj& add_int(ColKey col_key, int64_t value);
211
    Obj& add_int(StringData col_name, int64_t value)
212
    {
1,316✔
213
        return add_int(get_column_key(col_name), value);
1,316✔
214
    }
1,316✔
215

216
    template <typename U>
217
    Obj& set_list_values(ColKey col_key, const std::vector<U>& values);
218

219
    template <typename U>
220
    std::vector<U> get_list_values(ColKey col_key) const;
221

222
    template <class Head, class... Tail>
223
    Obj& set_all(Head v, Tail... tail);
224

225
    // The main algorithm for handling schema migrations if we try to convert
226
    // from TopLevel* to Embedded, in this case all the orphan objects are deleted
227
    // and all the objects with multiple backlinks are cloned in order to avoid to
228
    // get schema violations during the migration.
229
    // By default this alogirithm is disabled. RealmConfig contains a boolean flag
230
    // to enable it.
231
    void handle_multiple_backlinks_during_schema_migration();
232

233
    Obj get_linked_object(ColKey link_col_key) const
234
    {
26,286✔
235
        return _get_linked_object(link_col_key, get_any(link_col_key));
26,286✔
236
    }
26,286✔
237
    Obj get_linked_object(StringData link_col_name) const
238
    {
657✔
239
        return get_linked_object(get_column_key(link_col_name));
657✔
240
    }
657✔
241
    Obj get_parent_object() const;
242

243
    template <typename U>
244
    Lst<U> get_list(ColKey col_key) const;
245
    template <typename U>
246
    LstPtr<U> get_list_ptr(ColKey col_key) const;
247
    template <typename U>
248
    std::shared_ptr<Lst<U>> get_list_ptr(const Path& path) const
249
    {
246✔
250
        return std::dynamic_pointer_cast<Lst<U>>(get_collection_ptr(path));
246✔
251
    }
246✔
252

253
    template <typename U>
254
    Lst<U> get_list(StringData col_name) const
255
    {
350✔
256
        return get_list<U>(get_column_key(col_name));
350✔
257
    }
350✔
258

259
    LnkLst get_linklist(ColKey col_key) const;
260
    LnkLstPtr get_linklist_ptr(ColKey col_key) const;
261
    LnkLst get_linklist(StringData col_name) const;
262

263
    /// Get a type-erased list instance for the given list column.
264
    ///
265
    /// Note: For lists of links, this always returns a `LnkLst`, rather than a
266
    /// `Lst<ObjKey>`. Use `get_list_ptr<ObjKey>(col_key)` to get a list of
267
    /// links with uncondensed indices.
268
    LstBasePtr get_listbase_ptr(ColKey col_key) const;
269

270
    template <typename U>
271
    Set<U> get_set(StringData col_name) const
272
    {
4,978✔
273
        return get_set<U>(get_column_key(col_name));
4,978✔
274
    }
4,978✔
275
    template <typename U>
276
    Set<U> get_set(ColKey col_key) const;
277
    template <typename U>
278
    SetPtr<U> get_set_ptr(ColKey col_key) const;
279
    template <typename U>
280
    std::shared_ptr<Set<U>> get_set_ptr(const Path& path) const
281
    {
282
        return std::dynamic_pointer_cast<Set<U>>(get_collection_ptr(path));
283
    }
284

285
    LnkSet get_linkset(ColKey col_key) const;
286
    LnkSet get_linkset(StringData col_name) const;
287
    LnkSetPtr get_linkset_ptr(ColKey col_key) const;
288
    SetBasePtr get_setbase_ptr(ColKey col_key) const;
289
    Dictionary get_dictionary(ColKey col_key) const;
290
    Dictionary get_dictionary(StringData col_name) const;
291

292
    Obj& set_collection(ColKey col_key, CollectionType type);
293
    DictionaryPtr get_dictionary_ptr(ColKey col_key) const;
294
    DictionaryPtr get_dictionary_ptr(const Path& path) const;
295

296
    CollectionBasePtr get_collection_ptr(ColKey col_key) const;
297
    CollectionBasePtr get_collection_ptr(StringData col_name) const;
298
    CollectionPtr get_collection_ptr(const Path& path) const;
299
    CollectionPtr get_collection_by_stable_path(const StablePath& path) const;
300
    LinkCollectionPtr get_linkcollection_ptr(ColKey col_key) const;
301

302
    void assign_pk_and_backlinks(Obj& other);
303

304
    class Internal {
305
        friend class _impl::DeepChangeChecker;
306

307
        static ref_type get_ref(const Obj& obj, ColKey col_key);
308
    };
309

310
private:
311
    friend class ArrayBacklink;
312
    friend class CascadeState;
313
    friend class Cluster;
314
    friend class CollectionParent;
315
    friend class ColumnListBase;
316
    friend class LinkCount;
317
    friend class LinkMap;
318
    friend class Lst<ObjKey>;
319
    friend class ObjCollectionParent;
320
    friend class Table;
321
    friend class TableView;
322
    template <class>
323
    friend class CollectionBaseImpl;
324
    template <class>
325
    friend class Set;
326

327
    mutable TableRef m_table;
328
    ObjKey m_key;
329
    mutable MemRef m_mem;
330
    mutable size_t m_row_ndx = -1;
331
    mutable uint64_t m_storage_version = -1;
332
    mutable uint32_t m_version_counter = 0;
333
    mutable bool m_valid = false;
334

335
    Allocator& _get_alloc() const noexcept;
336

337

338
    /// Update the accessor. Returns true when the accessor was updated to
339
    /// reflect new changes to the underlying state.
340
    bool update() const;
341
    bool _update_if_needed() const; // no check, use only when already checked
342
    void checked_update_if_needed() const;
343

344
    template <class T>
345
    bool do_is_null(ColKey::Idx col_ndx) const;
346

347
    const ClusterTree* get_tree_top() const;
348
    ColKey get_column_key(StringData col_name) const;
349
    ColKey get_primary_key_column() const;
350
    TableKey get_table_key() const;
351
    TableRef get_target_table(ObjLink link) const;
352
    const Spec& get_spec() const;
353

354
    template <typename U>
355
    U _get(ColKey::Idx col_ndx) const;
356

357
    ObjKey get_backlink(ColKey backlink_col, size_t backlink_ndx) const;
358
    // Return all backlinks from a specific backlink column
359
    std::vector<ObjKey> get_all_backlinks(ColKey backlink_col) const;
360
    // Return number of backlinks from a specific backlink column
361
    size_t get_backlink_cnt(ColKey backlink_col) const;
362
    ObjKey get_unfiltered_link(ColKey col_key) const;
363
    Mixed get_unfiltered_mixed(ColKey::Idx col_ndx) const;
364

365
    template <class Val>
366
    Obj& _set_all(size_t col_ndx, Val v);
367
    template <class Head, class... Tail>
368
    Obj& _set_all(size_t col_ndx, Head v, Tail... tail);
369
    ColKey spec_ndx2colkey(size_t col_ndx);
370
    size_t colkey2spec_ndx(ColKey);
371
    bool ensure_writeable();
372
    void sync(Node& arr);
373
    int_fast64_t bump_content_version();
374
    void bump_both_versions();
375
    template <class T>
376
    void do_set_null(ColKey col_key);
377

378
    // Dictionary support
379
    size_t get_row_ndx() const
UNCOV
380
    {
×
UNCOV
381
        return m_row_ndx;
×
UNCOV
382
    }
×
383

384
    Obj _get_linked_object(ColKey link_col_key, Mixed link) const;
385
    Obj _get_linked_object(StringData link_col_name, Mixed link) const
386
    {
228✔
387
        return _get_linked_object(get_column_key(link_col_name), link);
228✔
388
    }
228✔
389

390
    void set_int(ColKey::Idx col_ndx, int64_t value);
391
    void set_ref(ColKey::Idx col_ndx, ref_type value, CollectionType type);
392
    void add_backlink(ColKey backlink_col, ObjKey origin_key);
393
    bool remove_one_backlink(ColKey backlink_col, ObjKey origin_key);
394
    void nullify_link(ColKey origin_col, ObjLink target_key) &&;
395
    template <class T>
396
    inline void set_spec(T&, ColKey);
397
    template <class ValueType>
398
    inline void nullify_single_link(ColKey col, ValueType target);
399

400
    void fix_linking_object_during_schema_migration(Obj linking_obj, Obj obj, ColKey opposite_col_key) const;
401

402
    bool compare_values(Mixed, Mixed, ColKey, Obj, StringData) const;
403
    bool compare_list_in_mixed(Lst<Mixed>&, Lst<Mixed>&, ColKey, Obj, StringData) const;
404
    bool compare_dict_in_mixed(Dictionary&, Dictionary&, ColKey, Obj, StringData) const;
405

406
    // Used when inserting a new link. You will not remove existing links in this process
407
    void set_backlink(ColKey col_key, ObjLink new_link) const;
408
    // Used when replacing a link, return true if CascadeState contains objects to remove
409
    bool replace_backlink(ColKey col_key, ObjLink old_link, ObjLink new_link, CascadeState& state) const;
410
    // Used when removing a backlink, return true if CascadeState contains objects to remove
411
    bool remove_backlink(ColKey col_key, ObjLink old_link, CascadeState& state) const;
412
};
413
static_assert(std::is_trivially_destructible_v<Obj>);
414

415
class ObjCollectionParent final : public Obj, public CollectionParent {
416
public:
417
    ObjCollectionParent() = default;
2,402,619✔
418
    ObjCollectionParent(const Obj& obj) noexcept
419
        : Obj(obj)
420
    {
30,213✔
421
    }
30,213✔
422
    ObjCollectionParent& operator=(const Obj& obj) noexcept
423
    {
2,401,896✔
424
        static_cast<Obj&>(*this) = obj;
2,401,896✔
425
        return *this;
2,401,896✔
426
    }
2,401,896✔
427

428
private:
429
    FullPath get_path() const override
430
    {
103,716✔
431
        return Obj::get_path();
103,716✔
432
    }
103,716✔
433
    Path get_short_path() const override
434
    {
367,020✔
435
        return Obj::get_short_path();
367,020✔
436
    }
367,020✔
437
    ColKey get_col_key() const noexcept override
UNCOV
438
    {
×
UNCOV
439
        return Obj::get_col_key();
×
UNCOV
440
    }
×
441
    StablePath get_stable_path() const override
442
    {
1,913,691✔
443
        return Obj::get_stable_path();
1,913,691✔
444
    }
1,913,691✔
445
    void translate_path(const StablePath& stable_path, Path& path) const override
NEW
446
    {
×
NEW
447
        Obj::translate_path(stable_path, path);
×
NEW
448
    }
×
449
    void add_index(Path& path, const Index& ndx) const override
450
    {
470,736✔
451
        Obj::add_index(path, ndx);
470,736✔
452
    }
470,736✔
453
    size_t find_index(const Index&) const override
UNCOV
454
    {
×
UNCOV
455
        return realm::npos;
×
UNCOV
456
    }
×
457
    TableRef get_table() const noexcept override
458
    {
15,847,407✔
459
        return Obj::get_table();
15,847,407✔
460
    }
15,847,407✔
461
    UpdateStatus update_if_needed() const override
462
    {
44,388,228✔
463
        return Obj::update_if_needed();
44,388,228✔
464
    }
44,388,228✔
465
    const Obj& get_object() const noexcept override
466
    {
6,541,872✔
467
        return *this;
6,541,872✔
468
    }
6,541,872✔
469
    uint32_t parent_version() const noexcept override
470
    {
43,452,078✔
471
        return m_version_counter;
43,452,078✔
472
    }
43,452,078✔
473
    ref_type get_collection_ref(Index index, CollectionType type) const override
474
    {
3,249,456✔
475
        return Obj::get_collection_ref(index, type);
3,249,456✔
476
    }
3,249,456✔
477
    bool check_collection_ref(Index index, CollectionType type) const noexcept override
478
    {
852,963✔
479
        return Obj::check_collection_ref(index, type);
852,963✔
480
    }
852,963✔
481
    void set_collection_ref(Index index, ref_type ref, CollectionType type) override
482
    {
511,683✔
483
        Obj::set_collection_ref(index, ref, type);
511,683✔
484
    }
511,683✔
485
};
486

487
std::ostream& operator<<(std::ostream&, const Obj& obj);
488

489
template <>
490
int64_t Obj::get(ColKey) const;
491
template <>
492
bool Obj::get(ColKey) const;
493

494
template <>
495
int64_t Obj::_get(ColKey::Idx col_ndx) const;
496
template <>
497
StringData Obj::_get(ColKey::Idx col_ndx) const;
498
template <>
499
BinaryData Obj::_get(ColKey::Idx col_ndx) const;
500
template <>
501
ObjKey Obj::_get(ColKey::Idx col_ndx) const;
502

503
struct Obj::FatPathElement {
504
    Obj obj;        // Object which embeds...
505
    ColKey col_key; // Column holding link or link list which embeds...
506
    Mixed index;    // index into link list or dictionary (or null)
507
};
508

509
template <>
510
Obj& Obj::set(ColKey, int64_t value, bool is_default);
511

512
template <>
513
Obj& Obj::set(ColKey, ObjKey value, bool is_default);
514

515
template <>
516
Obj& Obj::set(ColKey, ObjLink value, bool is_default);
517

518

519
template <>
520
inline Obj& Obj::set(ColKey col_key, int value, bool is_default)
521
{
15,390,843✔
522
    return set(col_key, int_fast64_t(value), is_default);
15,390,843✔
523
}
15,390,843✔
524

525
template <>
526
inline Obj& Obj::set(ColKey col_key, uint_fast64_t value, bool is_default)
527
{
1,638✔
528
    int_fast64_t value_2 = 0;
1,638✔
529
    if (REALM_UNLIKELY(util::int_cast_with_overflow_detect(value, value_2))) {
1,638✔
530
        REALM_TERMINATE("Unsigned integer too big.");
UNCOV
531
    }
×
532
    return set(col_key, value_2, is_default);
1,638✔
533
}
1,638✔
534

535
template <>
536
inline Obj& Obj::set(ColKey col_key, const char* str, bool is_default)
537
{
1,380,957✔
538
    return set(col_key, StringData(str), is_default);
1,380,957✔
539
}
1,380,957✔
540

541
template <>
542
inline Obj& Obj::set(ColKey col_key, char* str, bool is_default)
543
{
88✔
544
    return set(col_key, StringData(str), is_default);
88✔
545
}
88✔
546

547
template <>
548
inline Obj& Obj::set(ColKey col_key, std::string str, bool is_default)
549
{
347,613✔
550
    return set(col_key, StringData(str), is_default);
347,613✔
551
}
347,613✔
552

553
template <>
554
inline Obj& Obj::set(ColKey col_key, realm::null, bool is_default)
555
{
52✔
556
    return set_null(col_key, is_default);
52✔
557
}
52✔
558

559
template <>
560
inline Obj& Obj::set(ColKey col_key, util::Optional<bool> value, bool is_default)
561
{
20,728✔
562
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
19,618✔
563
}
20,728✔
564

565
template <>
566
inline Obj& Obj::set(ColKey col_key, util::Optional<int64_t> value, bool is_default)
567
{
33,984✔
568
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
32,352✔
569
}
33,984✔
570

571
template <>
572
inline Obj& Obj::set(ColKey col_key, util::Optional<float> value, bool is_default)
573
{
20,880✔
574
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
19,762✔
575
}
20,880✔
576

577
template <>
578
inline Obj& Obj::set(ColKey col_key, util::Optional<double> value, bool is_default)
579
{
20,880✔
580
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
19,756✔
581
}
20,880✔
582

583
template <>
584
inline Obj& Obj::set(ColKey col_key, util::Optional<ObjectId> value, bool is_default)
585
{
20,736✔
586
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
19,698✔
587
}
20,736✔
588

589
template <>
590
inline Obj& Obj::set(ColKey col_key, util::Optional<UUID> value, bool is_default)
591
{
8,456✔
592
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
6,424✔
593
}
8,456✔
594

595
template <typename U>
596
Obj& Obj::set_list_values(ColKey col_key, const std::vector<U>& values)
597
{
11,292✔
598
    size_t sz = values.size();
11,292✔
599
    auto list = get_list<U>(col_key);
11,292✔
600
    size_t list_sz = list.size();
11,292✔
601
    if (sz < list_sz) {
11,292✔
602
        list.resize(sz);
752✔
603
        list_sz = sz;
752✔
604
    }
752✔
605
    size_t i = 0;
11,292✔
606
    while (i < list_sz) {
14,484✔
607
        list.set(i, values[i]);
3,192✔
608
        i++;
3,192✔
609
    }
3,192✔
610
    while (i < sz) {
33,744✔
611
        list.add(values[i]);
22,452✔
612
        i++;
22,452✔
613
    }
22,452✔
614

5,646✔
615
    return *this;
11,292✔
616
}
11,292✔
617

618
template <typename U>
619
std::vector<U> Obj::get_list_values(ColKey col_key) const
620
{
7,670✔
621
    std::vector<U> values;
7,670✔
622
    auto list = get_list<U>(col_key);
7,670✔
623
    for (auto v : list)
7,670✔
624
        values.push_back(v);
10,964✔
625

3,835✔
626
    return values;
7,670✔
627
}
7,670✔
628

629
template <class Val>
630
inline Obj& Obj::_set_all(size_t col_ndx, Val v)
631
{
4,424,975✔
632
    return set(spec_ndx2colkey(col_ndx), v);
4,424,975✔
633
}
4,424,975✔
634

635
template <class Head, class... Tail>
636
inline Obj& Obj::_set_all(size_t col_ndx, Head v, Tail... tail)
637
{
1,528,500✔
638
    set(spec_ndx2colkey(col_ndx), v);
1,528,500✔
639
    return _set_all(col_ndx + 1, tail...);
1,528,500✔
640
}
1,528,500✔
641

642
template <class Head, class... Tail>
643
inline Obj& Obj::set_all(Head v, Tail... tail)
644
{
3,286,586✔
645
    size_t start_index = 0;
3,286,586✔
646

1,644,660✔
647
    // Avoid trying to set the PK column.
1,644,660✔
648
    if (get_primary_key_column()) {
3,286,586✔
649
        REALM_ASSERT(colkey2spec_ndx(get_primary_key_column()) == 0);
1,011!
650
        start_index = 1;
1,011✔
651
    }
1,011✔
652

1,644,660✔
653
    return _set_all(start_index, v, tail...);
3,286,586✔
654
}
3,286,586✔
655

656
inline int_fast64_t Obj::bump_content_version()
UNCOV
657
{
×
UNCOV
658
    Allocator& alloc = get_alloc();
×
UNCOV
659
    return alloc.bump_content_version();
×
UNCOV
660
}
×
661

662
inline void Obj::bump_both_versions()
UNCOV
663
{
×
UNCOV
664
    Allocator& alloc = get_alloc();
×
UNCOV
665
    alloc.bump_content_version();
×
UNCOV
666
    alloc.bump_storage_version();
×
UNCOV
667
}
×
668

669
} // namespace realm
670

671
#endif // REALM_OBJ_HPP
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