added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / exceptions.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_EXCEPTIONS_HPP
20 #define REALM_EXCEPTIONS_HPP
21
22 #include <stdexcept>
23
24 #include <realm/util/features.h>
25
26 namespace realm {
27
28 /// Thrown by various functions to indicate that a specified table does not
29 /// exist.
30 class NoSuchTable : public std::exception {
31 public:
32     const char* what() const noexcept override;
33 };
34
35
36 /// Thrown by various functions to indicate that a specified table name is
37 /// already in use.
38 class TableNameInUse : public std::exception {
39 public:
40     const char* what() const noexcept override;
41 };
42
43
44 // Thrown by functions that require a table to **not** be the target of link
45 // columns, unless those link columns are part of the table itself.
46 class CrossTableLinkTarget : public std::exception {
47 public:
48     const char* what() const noexcept override;
49 };
50
51
52 /// Thrown by various functions to indicate that the dynamic type of a table
53 /// does not match a particular other table type (dynamic or static).
54 class DescriptorMismatch : public std::exception {
55 public:
56     const char* what() const noexcept override;
57 };
58
59
60 /// The FileFormatUpgradeRequired exception can be thrown by the SharedGroup
61 /// constructor when opening a database that uses a deprecated file format
62 /// and/or a deprecated history schema, and the user has indicated he does not
63 /// want automatic upgrades to be performed. This exception indicates that until
64 /// an upgrade of the file format is performed, the database will be unavailable
65 /// for read or write operations.
66 class FileFormatUpgradeRequired : public std::exception {
67 public:
68     const char* what() const noexcept override;
69 };
70
71
72 /// Thrown when a sync agent attempts to join a session in which there is
73 /// already a sync agent. A session may only contain one sync agent at any given
74 /// time.
75 class MultipleSyncAgents : public std::exception {
76 public:
77     const char* what() const noexcept override;
78 };
79
80
81 /// Thrown when memory can no longer be mapped to. When mmap/remap fails.
82 class AddressSpaceExhausted : public std::runtime_error {
83 public:
84     AddressSpaceExhausted(const std::string& msg);
85     /// runtime_error::what() returns the msg provided in the constructor.
86 };
87
88 /// Thrown when creating references that are too large to be contained in our ref_type (size_t)
89 class MaximumFileSizeExceeded : public std::runtime_error {
90 public:
91     MaximumFileSizeExceeded(const std::string& msg);
92     /// runtime_error::what() returns the msg provided in the constructor.
93 };
94
95 /// Thrown when writing fails because the disk is full.
96 class OutOfDiskSpace : public std::runtime_error {
97 public:
98     OutOfDiskSpace(const std::string& msg);
99     /// runtime_error::what() returns the msg provided in the constructor.
100 };
101
102
103 /// The \c LogicError exception class is intended to be thrown only when
104 /// applications (or bindings) violate rules that are stated (or ought to have
105 /// been stated) in the documentation of the public API, and only in cases
106 /// where the violation could have been easily and efficiently predicted by the
107 /// application. In other words, this exception class is for the cases where
108 /// the error is due to incorrect use of the public API.
109 ///
110 /// This class is not supposed to be caught by applications. It is not even
111 /// supposed to be considered part of the public API, and therefore the
112 /// documentation of the public API should **not** mention the \c LogicError
113 /// exception class by name. Note how this contrasts with other exception
114 /// classes, such as \c NoSuchTable, which are part of the public API, and are
115 /// supposed to be mentioned in the documentation by name. The \c LogicError
116 /// exception is part of Realm's private API.
117 ///
118 /// In other words, the \c LogicError class should exclusively be used in
119 /// replacement (or in addition to) asserts (debug or not) in order to
120 /// guarantee program interruption, while still allowing for complete
121 /// test-cases to be written and run.
122 ///
123 /// To this effect, the special `CHECK_LOGIC_ERROR()` macro is provided as a
124 /// test framework plugin to allow unit tests to check that the functions in
125 /// the public API do throw \c LogicError when rules are violated.
126 ///
127 /// The reason behind hiding this class from the public API is to prevent users
128 /// from getting used to the idea that "Undefined Behaviour" equates a specific
129 /// exception being thrown. The whole point of properly documenting "Undefined
130 /// Behaviour" cases is to help the user know what the limits are, without
131 /// constraining the database to handle every and any use-case thrown at it.
132 ///
133 /// FIXME: This exception class should probably be moved to the `_impl`
134 /// namespace, in order to avoid some confusion.
135 class LogicError : public std::exception {
136 public:
137     enum ErrorKind {
138         string_too_big,
139         binary_too_big,
140         table_name_too_long,
141         column_name_too_long,
142         table_index_out_of_range,
143         row_index_out_of_range,
144         column_index_out_of_range,
145         string_position_out_of_range,
146         link_index_out_of_range,
147         bad_version,
148         illegal_type,
149
150         /// Indicates that an argument has a value that is illegal in combination
151         /// with another argument, or with the state of an involved object.
152         illegal_combination,
153
154         /// Indicates a data type mismatch, such as when `Table::find_pkey_int()` is
155         /// called and the type of the primary key is not `type_Int`.
156         type_mismatch,
157
158         /// Indicates that two involved tables are not in the same group.
159         group_mismatch,
160
161         /// Indicates that an involved descriptor is of the wrong kind, i.e., if
162         /// it is a subtable descriptor, and the function requires a root table
163         /// descriptor.
164         wrong_kind_of_descriptor,
165
166         /// Indicates that an involved table is of the wrong kind, i.e., if it
167         /// is a subtable, and the function requires a root table, or if it is a
168         /// free-standing table, and the function requires a group-level table.
169         wrong_kind_of_table,
170
171         /// Indicates that an involved accessor is was detached, i.e., was not
172         /// attached to an underlying object.
173         detached_accessor,
174
175         /// Indicates that a specified row index of a target table (a link) is
176         /// out of range. This is used for disambiguation in cases such as
177         /// Table::set_link() where one specifies both a row index of the origin
178         /// table, and a row index of the target table.
179         target_row_index_out_of_range,
180
181         // Indicates that an involved column lacks a search index.
182         no_search_index,
183
184         /// Indicates that a modification was attempted that would have produced a
185         /// duplicate primary value.
186         unique_constraint_violation,
187
188         /// User attempted to insert null in non-nullable column
189         column_not_nullable,
190
191         /// Group::open() is called on a group accessor that is already in the
192         /// attached state. Or Group::open() or Group::commit() is called on a
193         /// group accessor that is managed by a SharedGroup object.
194         wrong_group_state,
195
196         /// No active transaction on a particular SharedGroup object (e.g.,
197         /// SharedGroup::commit()), or the active transaction on the SharedGroup
198         /// object is of the wrong type (read/write), or an attampt was made to
199         /// initiate a new transaction while one is already in progress on the
200         /// same SharedGroup object.
201         wrong_transact_state,
202
203         /// Attempted use of a continuous transaction through a SharedGroup
204         /// object with no history. See Replication::get_history().
205         no_history,
206
207         /// Durability setting (as passed to the SharedGroup constructor) was
208         /// not consistent across the session.
209         mixed_durability,
210
211         /// History type (as specified by the Replication implementation passed
212         /// to the SharedGroup constructor) was not consistent across the
213         /// session.
214         mixed_history_type,
215
216         /// History schema version (as specified by the Replication
217         /// implementation passed to the SharedGroup constructor) was not
218         /// consistent across the session.
219         mixed_history_schema_version,
220
221         /// Adding rows to a table with no columns is not supported.
222         table_has_no_columns,
223
224         /// Referring to a column that has been deleted.
225         column_does_not_exist,
226
227         /// You can not add index on a subtable of a subtable
228         subtable_of_subtable_index
229     };
230
231     LogicError(ErrorKind message);
232
233     const char* what() const noexcept override;
234     ErrorKind kind() const noexcept;
235
236 private:
237     ErrorKind m_kind;
238 };
239
240
241 // Implementation:
242
243 // LCOV_EXCL_START (Wording of what() strings are not to be tested)
244
245 inline const char* NoSuchTable::what() const noexcept
246 {
247     return "No such table exists";
248 }
249
250 inline const char* TableNameInUse::what() const noexcept
251 {
252     return "The specified table name is already in use";
253 }
254
255 inline const char* CrossTableLinkTarget::what() const noexcept
256 {
257     return "Table is target of cross-table link columns";
258 }
259
260 inline const char* DescriptorMismatch::what() const noexcept
261 {
262     return "Table descriptor mismatch";
263 }
264
265 inline const char* FileFormatUpgradeRequired::what() const noexcept
266 {
267     return "Database upgrade required but prohibited";
268 }
269
270 inline const char* MultipleSyncAgents::what() const noexcept
271 {
272     return "Multiple sync agents attempted to join the same session";
273 }
274
275 // LCOV_EXCL_STOP
276
277 inline AddressSpaceExhausted::AddressSpaceExhausted(const std::string& msg)
278     : std::runtime_error(msg)
279 {
280 }
281
282 inline MaximumFileSizeExceeded::MaximumFileSizeExceeded(const std::string& msg)
283     : std::runtime_error(msg)
284 {
285 }
286
287 inline OutOfDiskSpace::OutOfDiskSpace(const std::string& msg)
288 : std::runtime_error(msg)
289 {
290 }
291
292 inline LogicError::LogicError(LogicError::ErrorKind k)
293     : m_kind(k)
294 {
295 }
296
297 inline LogicError::ErrorKind LogicError::kind() const noexcept
298 {
299     return m_kind;
300 }
301
302
303 } // namespace realm
304
305 #endif // REALM_EXCEPTIONS_HPP