added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / column_linkbase.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_COLUMN_LINKBASE_HPP
20 #define REALM_COLUMN_LINKBASE_HPP
21
22 #include <realm/table.hpp>
23
24 namespace realm {
25
26 class BacklinkColumn;
27 class Table;
28
29 // Abstract base class for columns containing links
30 class LinkColumnBase : public IntegerColumn {
31 public:
32     // Create unattached root array aaccessor.
33     LinkColumnBase(Allocator& alloc, ref_type ref, Table* table, size_t column_ndx);
34     ~LinkColumnBase() noexcept override;
35
36     bool is_nullable() const noexcept override = 0;
37     void set_null(size_t) override = 0;
38     bool is_null(size_t) const noexcept override = 0;
39
40     bool supports_search_index() const noexcept final
41     {
42         return false;
43     }
44     StringIndex* create_search_index() override;
45
46     bool get_weak_links() const noexcept;
47     void set_weak_links(bool) noexcept;
48
49     Table& get_target_table() const noexcept;
50     void set_target_table(Table&) noexcept;
51     BacklinkColumn& get_backlink_column() const noexcept;
52     void set_backlink_column(BacklinkColumn&) noexcept;
53
54     void swap_rows(size_t, size_t) override = 0;
55
56     virtual void do_nullify_link(size_t row_ndx, size_t old_target_row_ndx) = 0;
57     virtual void do_update_link(size_t row_ndx, size_t old_target_row_ndx, size_t new_target_row_ndx) = 0;
58     virtual void do_swap_link(size_t row_ndx, size_t target_row_ndx_1, size_t target_row_ndx_2) = 0;
59
60     void adj_acc_insert_rows(size_t, size_t) noexcept override;
61     void adj_acc_erase_row(size_t) noexcept override;
62     void adj_acc_move_over(size_t, size_t) noexcept override;
63     void adj_acc_swap_rows(size_t, size_t) noexcept override;
64     void adj_acc_move_row(size_t, size_t) noexcept override;
65     void adj_acc_clear_root_table() noexcept override;
66     void mark(int) noexcept override;
67     void refresh_accessor_tree(size_t, const Spec&) override;
68     void bump_link_origin_table_version() noexcept override;
69
70     void verify(const Table&, size_t) const override;
71     using IntegerColumn::verify;
72
73 protected:
74     // A pointer to the table that this column is part of.
75     Table* const m_table;
76
77     TableRef m_target_table;
78     BacklinkColumn* m_backlink_column = nullptr;
79     bool m_weak_links = false; // True if these links are weak (not strong)
80
81     /// Call Table::cascade_break_backlinks_to() for the specified target row if
82     /// it is not already in \a state.rows, and the number of strong links to it
83     /// has dropped to zero.
84     void check_cascade_break_backlinks_to(size_t target_table_ndx, size_t target_row_ndx, CascadeState& state);
85 };
86
87
88 // Implementation
89
90 inline LinkColumnBase::LinkColumnBase(Allocator& alloc, ref_type ref, Table* table, size_t column_ndx)
91     : IntegerColumn(alloc, ref, column_ndx) // Throws
92     , m_table(table)
93 {
94 }
95
96 inline LinkColumnBase::~LinkColumnBase() noexcept
97 {
98 }
99
100 inline StringIndex* LinkColumnBase::create_search_index()
101 {
102     return nullptr;
103 }
104
105 inline bool LinkColumnBase::get_weak_links() const noexcept
106 {
107     return m_weak_links;
108 }
109
110 inline void LinkColumnBase::set_weak_links(bool value) noexcept
111 {
112     m_weak_links = value;
113 }
114
115 inline Table& LinkColumnBase::get_target_table() const noexcept
116 {
117     return *m_target_table;
118 }
119
120 inline void LinkColumnBase::set_target_table(Table& table) noexcept
121 {
122     REALM_ASSERT(!m_target_table);
123     m_target_table = table.get_table_ref();
124 }
125
126 inline BacklinkColumn& LinkColumnBase::get_backlink_column() const noexcept
127 {
128     return *m_backlink_column;
129 }
130
131 inline void LinkColumnBase::set_backlink_column(BacklinkColumn& column) noexcept
132 {
133     m_backlink_column = &column;
134 }
135
136 inline void LinkColumnBase::adj_acc_insert_rows(size_t row_ndx, size_t num_rows) noexcept
137 {
138     IntegerColumn::adj_acc_insert_rows(row_ndx, num_rows);
139
140     typedef _impl::TableFriend tf;
141     tf::mark(*m_target_table);
142 }
143
144 inline void LinkColumnBase::adj_acc_erase_row(size_t row_ndx) noexcept
145 {
146     IntegerColumn::adj_acc_erase_row(row_ndx);
147
148     typedef _impl::TableFriend tf;
149     tf::mark(*m_target_table);
150 }
151
152 inline void LinkColumnBase::adj_acc_move_over(size_t from_row_ndx, size_t to_row_ndx) noexcept
153 {
154     IntegerColumn::adj_acc_move_over(from_row_ndx, to_row_ndx);
155
156     typedef _impl::TableFriend tf;
157     tf::mark(*m_target_table);
158 }
159
160 inline void LinkColumnBase::adj_acc_swap_rows(size_t row_ndx_1, size_t row_ndx_2) noexcept
161 {
162     IntegerColumn::adj_acc_swap_rows(row_ndx_1, row_ndx_2);
163
164     typedef _impl::TableFriend tf;
165     tf::mark(*m_target_table);
166 }
167
168 inline void LinkColumnBase::adj_acc_move_row(size_t from_ndx, size_t to_ndx) noexcept
169 {
170     IntegerColumn::adj_acc_move_row(from_ndx, to_ndx);
171
172     using tf = _impl::TableFriend;
173     tf::mark(*m_target_table);
174 }
175
176 inline void LinkColumnBase::adj_acc_clear_root_table() noexcept
177 {
178     IntegerColumn::adj_acc_clear_root_table();
179
180     typedef _impl::TableFriend tf;
181     tf::mark(*m_target_table);
182 }
183
184 inline void LinkColumnBase::mark(int type) noexcept
185 {
186     if (type & mark_LinkTargets) {
187         typedef _impl::TableFriend tf;
188         tf::mark(*m_target_table);
189     }
190 }
191
192 inline void LinkColumnBase::bump_link_origin_table_version() noexcept
193 {
194     // It is important to mark connected tables as modified.
195     // Also see BacklinkColumn::bump_link_origin_table_version().
196     typedef _impl::TableFriend tf;
197     if (m_target_table) {
198         bool bump_global = false;
199         tf::bump_version(*m_target_table, bump_global);
200     }
201 }
202
203
204 } // namespace realm
205
206 #endif // REALM_COLUMN_LINKBASE_HPP