added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / sync / instruction_replication.hpp
1 /*************************************************************************
2  *
3  * Copyright 2017 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_SYNC_IMPL_INSTRUCTION_REPLICATION_HPP
20 #define REALM_SYNC_IMPL_INSTRUCTION_REPLICATION_HPP
21
22 #include <realm/replication.hpp>
23 #include <realm/sync/instructions.hpp>
24 #include <realm/sync/object.hpp>
25 #include <realm/sync/changeset_encoder.hpp>
26
27 namespace realm {
28 namespace sync {
29
30
31 class InstructionReplication: public TrivialReplication, public ObjectIDProvider {
32 public:
33     explicit InstructionReplication(const std::string& realm_path);
34     void set_short_circuit(bool) noexcept;
35     bool is_short_circuited() const noexcept;
36
37     // reset() resets the encoder, the selected tables and the cache. It is
38     // called by do_initiate_transact(), but can be called at the other times
39     // as well.
40     virtual void reset();
41
42     ChangesetEncoder& get_instruction_encoder() noexcept;
43
44     //@{
45     /// Generate instructions for Object Store tables. These must be called
46     /// prior to calling the equivalent functions in Core's API. When creating a
47     /// class-like table, `add_class()` must be called prior to
48     /// `Group::insert_group_level_table()`. Similarly, `create_object()` or
49     /// `create_object_with_primary_key()` must be called prior to
50     /// `Table::insert_empty_row()` and/or `Table::set_int_unique()` or
51     /// `Table::set_string_unique()` or `Table::set_null_unique()`.
52     ///
53     /// If a class-like table is added, or an object-like row is inserted,
54     /// without calling these methods first, an exception will be thrown.
55     ///
56     /// A "class-like table" is defined as a table whose name begins with
57     /// "class_" (this is the convention used by Object Store). Non-class-like
58     /// tables can be created and modified using Core's API without calling
59     /// these functions, because they do not result in instructions being
60     /// emitted.
61     void add_class(StringData table_name);
62     void add_class_with_primary_key(StringData table_name, DataType pk_type, StringData pk_field, bool nullable);
63     void create_object(const Table*, ObjectID);
64     void create_object_with_primary_key(const Table*, ObjectID, StringData);
65     void create_object_with_primary_key(const Table*, ObjectID, int_fast64_t);
66     void create_object_with_primary_key(const Table*, ObjectID, realm::util::None);
67     //@}
68
69     // TrivialReplication interface:
70     void initialize(SharedGroup&) override;
71
72     // TransactLogConvenientEncoder interface:
73     void insert_group_level_table(size_t table_ndx, size_t num_tables, StringData name) override;
74     void erase_group_level_table(size_t table_ndx, size_t num_tables) override;
75     void rename_group_level_table(size_t table_ndx, StringData new_name) override;
76     void insert_column(const Descriptor&, size_t col_ndx, DataType type, StringData name, LinkTargetInfo& link,
77                                bool nullable = false) override;
78     void erase_column(const Descriptor&, size_t col_ndx) override;
79     void rename_column(const Descriptor&, size_t col_ndx, StringData name) override;
80
81     void set_int(const Table*, size_t col_ndx, size_t ndx, int_fast64_t value, _impl::Instruction variant) override;
82     void add_int(const Table*, size_t col_ndx, size_t ndx, int_fast64_t value) override;
83     void set_bool(const Table*, size_t col_ndx, size_t ndx, bool value, _impl::Instruction variant) override;
84     void set_float(const Table*, size_t col_ndx, size_t ndx, float value, _impl::Instruction variant) override;
85     void set_double(const Table*, size_t col_ndx, size_t ndx, double value, _impl::Instruction variant) override;
86     void set_string(const Table*, size_t col_ndx, size_t ndx, StringData value, _impl::Instruction variant) override;
87     void set_binary(const Table*, size_t col_ndx, size_t ndx, BinaryData value, _impl::Instruction variant) override;
88     void set_olddatetime(const Table*, size_t col_ndx, size_t ndx, OldDateTime value,
89                                  _impl::Instruction variant) override;
90     void set_timestamp(const Table*, size_t col_ndx, size_t ndx, Timestamp value, _impl::Instruction variant) override;
91     void set_table(const Table*, size_t col_ndx, size_t ndx, _impl::Instruction variant) override;
92     void set_mixed(const Table*, size_t col_ndx, size_t ndx, const Mixed& value, _impl::Instruction variant) override;
93     void set_link(const Table*, size_t col_ndx, size_t ndx, size_t value, _impl::Instruction variant) override;
94     void set_null(const Table*, size_t col_ndx, size_t ndx, _impl::Instruction variant) override;
95     void set_link_list(const LinkView&, const IntegerColumn& values) override;
96     void insert_substring(const Table*, size_t col_ndx, size_t row_ndx, size_t pos, StringData) override;
97     void erase_substring(const Table*, size_t col_ndx, size_t row_ndx, size_t pos, size_t size) override;
98     void insert_empty_rows(const Table*, size_t row_ndx, size_t num_rows_to_insert, size_t prior_num_rows) override;
99     void add_row_with_key(const Table*, size_t row_ndx, size_t prior_num_rows, size_t key_col_ndx, int64_t key) override;
100     void erase_rows(const Table*, size_t row_ndx, size_t num_rows_to_erase, size_t prior_num_rowsp,
101                             bool is_move_last_over) override;
102     void swap_rows(const Table*, size_t row_ndx_1, size_t row_ndx_2) override;
103     void move_row(const Table*, size_t row_ndx_1, size_t row_ndx_2) override;
104     void merge_rows(const Table*, size_t row_ndx, size_t new_row_ndx) override;
105     void add_search_index(const Descriptor&, size_t col_ndx) override;
106     void remove_search_index(const Descriptor&, size_t col_ndx) override;
107     void set_link_type(const Table*, size_t col_ndx, LinkType) override;
108     void clear_table(const Table*, size_t prior_num_rows) override;
109     void optimize_table(const Table*) override;
110     void link_list_set(const LinkView&, size_t ndx, size_t value) override;
111     void link_list_insert(const LinkView&, size_t ndx, size_t value) override;
112     void link_list_move(const LinkView&, size_t from_ndx, size_t to_ndx) override;
113     void link_list_swap(const LinkView&, size_t ndx_1, size_t ndx_2) override;
114     void link_list_erase(const LinkView&, size_t ndx) override;
115     void link_list_clear(const LinkView&) override;
116     void nullify_link(const Table*, size_t col_ndx, size_t ndx) override;
117     void link_list_nullify(const LinkView&, size_t ndx) override;
118
119 protected:
120     // Replication interface:
121     void do_initiate_transact(version_type current_version, bool history_updated) override;
122 private:
123     bool m_short_circuit = false;
124
125     ChangesetEncoder m_encoder;
126     SharedGroup* m_sg = nullptr;
127     std::unique_ptr<TableInfoCache> m_cache;
128
129     enum class TableBehavior {
130         Class,
131         Array,
132         Ignore
133     };
134
135     // FIXME: The base class already caches this.
136     const Table* m_selected_table = nullptr;
137     TableBehavior m_selected_table_behavior; // cache
138     const LinkView* m_selected_link_list = nullptr;
139
140     // Consistency checks:
141     std::string m_table_being_created;
142     std::string m_table_being_created_primary_key;
143     util::Optional<ObjectID> m_object_being_created;
144
145     void unsupported_instruction(); // Throws TransformError
146     TableBehavior select_table(const Table*);
147     TableBehavior select_table(const Descriptor&);
148     bool select_link_list(const LinkView&); // returns true if table behavior != ignored
149
150     TableBehavior get_table_behavior(const Table*) const;
151
152     template <class T>
153     void set(const Table*, size_t row_ndx, size_t col_ndx, T payload,
154              _impl::Instruction variant);
155     template <class T>
156     void set_pk(const Table*, size_t row_ndx, size_t col_ndx, T payload,
157                 _impl::Instruction variant);
158     template <class T>
159     auto as_payload(T value);
160     template <class T>
161     void emit(T instruction);
162 };
163
164 inline void InstructionReplication::set_short_circuit(bool b) noexcept
165 {
166     m_short_circuit = b;
167 }
168
169 inline bool InstructionReplication::is_short_circuited() const noexcept
170 {
171     return m_short_circuit;
172 }
173
174 inline ChangesetEncoder& InstructionReplication::get_instruction_encoder() noexcept
175 {
176     return m_encoder;
177 }
178
179 // Temporarily short-circuit replication
180 class TempShortCircuitReplication {
181 public:
182     TempShortCircuitReplication(InstructionReplication& bridge): m_bridge(bridge)
183     {
184         m_was_short_circuited = bridge.is_short_circuited();
185         bridge.set_short_circuit(true);
186     }
187
188     ~TempShortCircuitReplication() {
189         m_bridge.set_short_circuit(m_was_short_circuited);
190     }
191 private:
192     InstructionReplication& m_bridge;
193     bool m_was_short_circuited;
194 };
195
196 } // namespace sync
197 } // namespace realm
198
199 #endif // REALM_SYNC_IMPL_INSTRUCTION_REPLICATION_HPP