1 /*************************************************************************
3 * Copyright 2016 Realm Inc.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 **************************************************************************/
19 #ifndef REALM_COLUMN_LINKBASE_HPP
20 #define REALM_COLUMN_LINKBASE_HPP
22 #include <realm/table.hpp>
29 // Abstract base class for columns containing links
30 class LinkColumnBase : public IntegerColumn {
32 // Create unattached root array aaccessor.
33 LinkColumnBase(Allocator& alloc, ref_type ref, Table* table, size_t column_ndx);
34 ~LinkColumnBase() noexcept override;
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;
40 bool supports_search_index() const noexcept final
44 StringIndex* create_search_index() override;
46 bool get_weak_links() const noexcept;
47 void set_weak_links(bool) noexcept;
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;
54 void swap_rows(size_t, size_t) override = 0;
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;
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;
70 void verify(const Table&, size_t) const override;
71 using IntegerColumn::verify;
74 // A pointer to the table that this column is part of.
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)
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);
90 inline LinkColumnBase::LinkColumnBase(Allocator& alloc, ref_type ref, Table* table, size_t column_ndx)
91 : IntegerColumn(alloc, ref, column_ndx) // Throws
96 inline LinkColumnBase::~LinkColumnBase() noexcept
100 inline StringIndex* LinkColumnBase::create_search_index()
105 inline bool LinkColumnBase::get_weak_links() const noexcept
110 inline void LinkColumnBase::set_weak_links(bool value) noexcept
112 m_weak_links = value;
115 inline Table& LinkColumnBase::get_target_table() const noexcept
117 return *m_target_table;
120 inline void LinkColumnBase::set_target_table(Table& table) noexcept
122 REALM_ASSERT(!m_target_table);
123 m_target_table = table.get_table_ref();
126 inline BacklinkColumn& LinkColumnBase::get_backlink_column() const noexcept
128 return *m_backlink_column;
131 inline void LinkColumnBase::set_backlink_column(BacklinkColumn& column) noexcept
133 m_backlink_column = &column;
136 inline void LinkColumnBase::adj_acc_insert_rows(size_t row_ndx, size_t num_rows) noexcept
138 IntegerColumn::adj_acc_insert_rows(row_ndx, num_rows);
140 typedef _impl::TableFriend tf;
141 tf::mark(*m_target_table);
144 inline void LinkColumnBase::adj_acc_erase_row(size_t row_ndx) noexcept
146 IntegerColumn::adj_acc_erase_row(row_ndx);
148 typedef _impl::TableFriend tf;
149 tf::mark(*m_target_table);
152 inline void LinkColumnBase::adj_acc_move_over(size_t from_row_ndx, size_t to_row_ndx) noexcept
154 IntegerColumn::adj_acc_move_over(from_row_ndx, to_row_ndx);
156 typedef _impl::TableFriend tf;
157 tf::mark(*m_target_table);
160 inline void LinkColumnBase::adj_acc_swap_rows(size_t row_ndx_1, size_t row_ndx_2) noexcept
162 IntegerColumn::adj_acc_swap_rows(row_ndx_1, row_ndx_2);
164 typedef _impl::TableFriend tf;
165 tf::mark(*m_target_table);
168 inline void LinkColumnBase::adj_acc_move_row(size_t from_ndx, size_t to_ndx) noexcept
170 IntegerColumn::adj_acc_move_row(from_ndx, to_ndx);
172 using tf = _impl::TableFriend;
173 tf::mark(*m_target_table);
176 inline void LinkColumnBase::adj_acc_clear_root_table() noexcept
178 IntegerColumn::adj_acc_clear_root_table();
180 typedef _impl::TableFriend tf;
181 tf::mark(*m_target_table);
184 inline void LinkColumnBase::mark(int type) noexcept
186 if (type & mark_LinkTargets) {
187 typedef _impl::TableFriend tf;
188 tf::mark(*m_target_table);
192 inline void LinkColumnBase::bump_link_origin_table_version() noexcept
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);
206 #endif // REALM_COLUMN_LINKBASE_HPP