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

realm / realm-core / jorgen.edelbo_402

21 Aug 2024 11:10AM UTC coverage: 91.054% (-0.03%) from 91.085%
jorgen.edelbo_402

Pull #7803

Evergreen

jedelbo
Small fix to Table::typed_write

When writing the realm to a new file from a write transaction,
the Table may be COW so that the top ref is changed. So don't
use the ref that is present in the group when the operation starts.
Pull Request #7803: Feature/string compression

103494 of 181580 branches covered (57.0%)

1929 of 1999 new or added lines in 46 files covered. (96.5%)

695 existing lines in 51 files now uncovered.

220142 of 241772 relevant lines covered (91.05%)

7344461.76 hits per line

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

91.1
/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;
15,651,405✔
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 add_index(Path& path, const CollectionParent::Index& ndx) const;
76

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

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

90
    // Check if this object is default constructed
91
    explicit operator bool() const noexcept
92
    {
13,342,428✔
93
        return m_table != nullptr;
13,342,428✔
94
    }
13,342,428✔
95

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

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

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

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

120
    std::optional<StringID> get_string_id(ColKey) const;
121
    std::optional<StringID> get_string_id(StringData col_name) const
NEW
122
    {
×
NEW
123
        return get_string_id(get_column_key(col_name));
×
NEW
124
    }
×
125
    Mixed get_any(ColKey col_key) const;
126
    Mixed get_any(StringData col_name) const
127
    {
9,990✔
128
        return get_any(get_column_key(col_name));
9,990✔
129
    }
9,990✔
130
    Mixed get_primary_key() const;
131

132
    template <typename U>
133
    U get(StringData col_name) const
134
    {
914,386✔
135
        return get<U>(get_column_key(col_name));
914,386✔
136
    }
914,386✔
137
    bool is_unresolved(ColKey col_key) const;
138

139
    size_t get_link_count(ColKey col_key) const;
140
    TableRef get_target_table(ColKey col_key) const;
141

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

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

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

162
    std::string to_string() const;
163

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

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

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

201
    template <typename U>
202
    Obj& set(StringData col_name, U value, bool is_default = false)
203
    {
2,700,225✔
204
        return set(get_column_key(col_name), value, is_default);
2,700,225✔
205
    }
2,700,225✔
206

207
    Obj& set_null(ColKey col_key, bool is_default = false);
208
    Obj& set_null(StringData col_name, bool is_default = false)
209
    {
30✔
210
        return set_null(get_column_key(col_name), is_default);
30✔
211
    }
30✔
212
    Obj& set_json(ColKey col_key, StringData json);
213

214
    Obj& add_int(ColKey col_key, int64_t value);
215
    Obj& add_int(StringData col_name, int64_t value)
216
    {
1,320✔
217
        return add_int(get_column_key(col_name), value);
1,320✔
218
    }
1,320✔
219

220
    template <typename U>
221
    Obj& set_list_values(ColKey col_key, const std::vector<U>& values);
222

223
    template <typename U>
224
    std::vector<U> get_list_values(ColKey col_key) const;
225

226
    template <class Head, class... Tail>
227
    Obj& set_all(Head v, Tail... tail);
228

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

237
    Obj get_linked_object(ColKey link_col_key) const
238
    {
27,474✔
239
        return _get_linked_object(link_col_key, get_any(link_col_key));
27,474✔
240
    }
27,474✔
241
    Obj get_linked_object(StringData link_col_name) const
242
    {
657✔
243
        return get_linked_object(get_column_key(link_col_name));
657✔
244
    }
657✔
245
    Obj get_parent_object() const;
246

247
    template <typename U>
248
    Lst<U> get_list(ColKey col_key) const;
249
    template <typename U>
250
    LstPtr<U> get_list_ptr(ColKey col_key) const;
251
    template <typename U>
252
    std::shared_ptr<Lst<U>> get_list_ptr(const Path& path) const
253
    {
450✔
254
        return std::dynamic_pointer_cast<Lst<U>>(get_collection_ptr(path));
450✔
255
    }
450✔
256

257
    template <typename U>
258
    Lst<U> get_list(StringData col_name) const
259
    {
392✔
260
        return get_list<U>(get_column_key(col_name));
392✔
261
    }
392✔
262

263
    LnkLst get_linklist(ColKey col_key) const;
264
    LnkLstPtr get_linklist_ptr(ColKey col_key) const;
265
    LnkLst get_linklist(StringData col_name) const;
266

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

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

289
    LnkSet get_linkset(ColKey col_key) const;
290
    LnkSet get_linkset(StringData col_name) const;
291
    LnkSetPtr get_linkset_ptr(ColKey col_key) const;
292
    SetBasePtr get_setbase_ptr(ColKey col_key) const;
293
    Dictionary get_dictionary(ColKey col_key) const;
294
    Dictionary get_dictionary(StringData col_name) const;
295

296
    Obj& set_collection(ColKey col_key, CollectionType type);
297
    DictionaryPtr get_dictionary_ptr(ColKey col_key) const;
298
    DictionaryPtr get_dictionary_ptr(const Path& path) const;
299

300
    CollectionBasePtr get_collection_ptr(ColKey col_key) const;
301
    CollectionBasePtr get_collection_ptr(StringData col_name) const;
302
    CollectionPtr get_collection_ptr(const Path& path) const;
303
    CollectionPtr get_collection_by_stable_path(const StablePath& path) const;
304
    LinkCollectionPtr get_linkcollection_ptr(ColKey col_key) const;
305

306
    void assign_pk_and_backlinks(Obj& other);
307

308
    class Internal {
309
        friend class _impl::DeepChangeChecker;
310

311
        static ref_type get_ref(const Obj& obj, ColKey col_key);
312
    };
313

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

331
    mutable TableRef m_table;
332
    ObjKey m_key;
333
    mutable MemRef m_mem;
334
    mutable size_t m_row_ndx = -1;
335
    mutable uint64_t m_storage_version = -1;
336
    mutable uint32_t m_version_counter = 0;
337
    mutable bool m_valid = false;
338

339
    Allocator& _get_alloc() const noexcept;
340

341

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

348
    template <class T>
349
    bool do_is_null(ColKey::Idx col_ndx) const;
350

351
    const ClusterTree* get_tree_top() const;
352
    ColKey get_column_key(StringData col_name) const;
353
    ColKey get_primary_key_column() const;
354
    TableKey get_table_key() const;
355
    TableRef get_target_table(ObjLink link) const;
356
    const Spec& get_spec() const;
357

358
    template <typename U>
359
    U _get(ColKey::Idx col_ndx) const;
360

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

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

381
    // Dictionary support
382
    size_t get_row_ndx() const
383
    {
×
384
        return m_row_ndx;
×
385
    }
×
386

387
    Obj _get_linked_object(ColKey link_col_key, Mixed link) const;
388
    Obj _get_linked_object(StringData link_col_name, Mixed link) const
389
    {
228✔
390
        return _get_linked_object(get_column_key(link_col_name), link);
228✔
391
    }
228✔
392

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

403
    void fix_linking_object_during_schema_migration(Obj linking_obj, Obj obj, ColKey opposite_col_key) const;
404

405
    bool compare_values(Mixed, Mixed, ColKey, Obj, StringData) const;
406
    bool compare_list_in_mixed(Lst<Mixed>&, Lst<Mixed>&, ColKey, Obj, StringData) const;
407
    bool compare_dict_in_mixed(Dictionary&, Dictionary&, ColKey, Obj, StringData) const;
408

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

418
class ObjCollectionParent final : public Obj, public CollectionParent {
419
public:
420
    ObjCollectionParent() = default;
3,328,884✔
421
    ObjCollectionParent(const Obj& obj) noexcept
422
        : Obj(obj)
63,867✔
423
    {
127,746✔
424
    }
127,746✔
425
    ObjCollectionParent& operator=(const Obj& obj) noexcept
426
    {
3,328,482✔
427
        static_cast<Obj&>(*this) = obj;
3,328,482✔
428
        return *this;
3,328,482✔
429
    }
3,328,482✔
430

431
private:
432
    FullPath get_path() const override
433
    {
111,090✔
434
        return Obj::get_path();
111,090✔
435
    }
111,090✔
436
    Path get_short_path() const override
437
    {
402,315✔
438
        return Obj::get_short_path();
402,315✔
439
    }
402,315✔
440
    ColKey get_col_key() const noexcept override
441
    {
×
442
        return Obj::get_col_key();
×
443
    }
×
444
    StablePath get_stable_path() const override
445
    {
2,013,681✔
446
        return Obj::get_stable_path();
2,013,681✔
447
    }
2,013,681✔
448
    void add_index(Path& path, const Index& ndx) const override
449
    {
513,405✔
450
        Obj::add_index(path, ndx);
513,405✔
451
    }
513,405✔
452
    size_t find_index(const Index&) const override
453
    {
×
454
        return realm::npos;
×
455
    }
×
456
    TableRef get_table() const noexcept override
457
    {
16,648,407✔
458
        return Obj::get_table();
16,648,407✔
459
    }
16,648,407✔
460
    UpdateStatus update_if_needed() const override
461
    {
49,461,849✔
462
        return Obj::update_if_needed();
49,461,849✔
463
    }
49,461,849✔
464
    const Obj& get_object() const noexcept override
465
    {
6,930,960✔
466
        return *this;
6,930,960✔
467
    }
6,930,960✔
468
    uint32_t parent_version() const noexcept override
469
    {
48,195,780✔
470
        return m_version_counter;
48,195,780✔
471
    }
48,195,780✔
472
    ref_type get_collection_ref(Index index, CollectionType type) const override
473
    {
4,367,265✔
474
        return Obj::get_collection_ref(index, type);
4,367,265✔
475
    }
4,367,265✔
476
    bool check_collection_ref(Index index, CollectionType type) const noexcept override
477
    {
1,165,254✔
478
        return Obj::check_collection_ref(index, type);
1,165,254✔
479
    }
1,165,254✔
480
    void set_collection_ref(Index index, ref_type ref, CollectionType type) override
481
    {
736,419✔
482
        Obj::set_collection_ref(index, ref, type);
736,419✔
483
    }
736,419✔
484
    void update_content_version() const noexcept override
485
    {
9,086,109✔
486
        // not applicable to Obj
487
    }
9,086,109✔
488
};
489

490
std::ostream& operator<<(std::ostream&, const Obj& obj);
491

492
template <>
493
int64_t Obj::get(ColKey) const;
494
template <>
495
bool Obj::get(ColKey) const;
496

497
template <>
498
int64_t Obj::_get(ColKey::Idx col_ndx) const;
499
template <>
500
StringData Obj::_get(ColKey::Idx col_ndx) const;
501
template <>
502
BinaryData Obj::_get(ColKey::Idx col_ndx) const;
503
template <>
504
ObjKey Obj::_get(ColKey::Idx col_ndx) const;
505

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

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

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

518
template <>
519
Obj& Obj::set(ColKey, ObjLink value, bool is_default);
520

521

522
template <>
523
inline Obj& Obj::set(ColKey col_key, int value, bool is_default)
524
{
16,460,391✔
525
    return set(col_key, int_fast64_t(value), is_default);
16,460,391✔
526
}
16,460,391✔
527

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

538
template <>
539
inline Obj& Obj::set(ColKey col_key, const char* str, bool is_default)
540
{
178,851✔
541
    return set(col_key, StringData(str), is_default);
178,851✔
542
}
178,851✔
543

544
template <>
545
inline Obj& Obj::set(ColKey col_key, char* str, bool is_default)
546
{
107✔
547
    return set(col_key, StringData(str), is_default);
107✔
548
}
107✔
549

550
template <>
551
inline Obj& Obj::set(ColKey col_key, std::string str, bool is_default)
552
{
892,068✔
553
    return set(col_key, StringData(str), is_default);
892,068✔
554
}
892,068✔
555

556
template <>
557
inline Obj& Obj::set(ColKey col_key, std::string_view str, bool is_default)
558
{
202✔
559
    return set(col_key, StringData(str), is_default);
202✔
560
}
202✔
561

562
template <>
563
inline Obj& Obj::set(ColKey col_key, realm::null, bool is_default)
564
{
50✔
565
    return set_null(col_key, is_default);
50✔
566
}
50✔
567

568
template <>
569
inline Obj& Obj::set(ColKey col_key, util::Optional<bool> value, bool is_default)
570
{
20,728✔
571
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
20,728✔
572
}
20,728✔
573

574
template <>
575
inline Obj& Obj::set(ColKey col_key, util::Optional<int64_t> value, bool is_default)
576
{
35,841✔
577
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
35,841✔
578
}
35,841✔
579

580
template <>
581
inline Obj& Obj::set(ColKey col_key, util::Optional<float> value, bool is_default)
582
{
20,880✔
583
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
20,880✔
584
}
20,880✔
585

586
template <>
587
inline Obj& Obj::set(ColKey col_key, util::Optional<double> value, bool is_default)
588
{
20,880✔
589
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
20,880✔
590
}
20,880✔
591

592
template <>
593
inline Obj& Obj::set(ColKey col_key, util::Optional<ObjectId> value, bool is_default)
594
{
20,736✔
595
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
20,736✔
596
}
20,736✔
597

598
template <>
599
inline Obj& Obj::set(ColKey col_key, util::Optional<UUID> value, bool is_default)
600
{
8,456✔
601
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
8,456✔
602
}
8,456✔
603

604
template <typename U>
605
Obj& Obj::set_list_values(ColKey col_key, const std::vector<U>& values)
606
{
11,292✔
607
    size_t sz = values.size();
11,292✔
608
    auto list = get_list<U>(col_key);
11,292✔
609
    size_t list_sz = list.size();
11,292✔
610
    if (sz < list_sz) {
11,292✔
611
        list.resize(sz);
752✔
612
        list_sz = sz;
752✔
613
    }
752✔
614
    size_t i = 0;
11,292✔
615
    while (i < list_sz) {
14,484✔
616
        list.set(i, values[i]);
3,192✔
617
        i++;
3,192✔
618
    }
3,192✔
619
    while (i < sz) {
33,744✔
620
        list.add(values[i]);
22,452✔
621
        i++;
22,452✔
622
    }
22,452✔
623

624
    return *this;
11,292✔
625
}
11,292✔
626

627
template <typename U>
628
std::vector<U> Obj::get_list_values(ColKey col_key) const
629
{
7,670✔
630
    std::vector<U> values;
7,670✔
631
    auto list = get_list<U>(col_key);
7,670✔
632
    for (auto v : list)
7,670✔
633
        values.push_back(v);
10,964✔
634

635
    return values;
7,670✔
636
}
7,670✔
637

638
template <class Val>
639
inline Obj& Obj::_set_all(size_t col_ndx, Val v)
640
{
4,623,975✔
641
    return set(spec_ndx2colkey(col_ndx), v);
4,623,975✔
642
}
4,623,975✔
643

644
template <class Head, class... Tail>
645
inline Obj& Obj::_set_all(size_t col_ndx, Head v, Tail... tail)
646
{
1,527,352✔
647
    set(spec_ndx2colkey(col_ndx), v);
1,527,352✔
648
    return _set_all(col_ndx + 1, tail...);
1,527,352✔
649
}
1,527,352✔
650

651
template <class Head, class... Tail>
652
inline Obj& Obj::set_all(Head v, Tail... tail)
653
{
3,686,205✔
654
    size_t start_index = 0;
3,686,205✔
655

656
    // Avoid trying to set the PK column.
657
    if (get_primary_key_column()) {
3,686,205✔
658
        REALM_ASSERT(colkey2spec_ndx(get_primary_key_column()) == 0);
1,011!
659
        start_index = 1;
1,011✔
660
    }
1,011✔
661

662
    return _set_all(start_index, v, tail...);
3,686,205✔
663
}
3,686,205✔
664

665
inline int_fast64_t Obj::bump_content_version()
666
{
×
667
    Allocator& alloc = get_alloc();
×
668
    return alloc.bump_content_version();
×
669
}
×
670

671
} // namespace realm
672

673
#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