Realm C++ SDK Version v2.2.0

realm.hpp

1
2//
3// Copyright 2024 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//
18
19#ifndef CPPREALM_BRIDGE_REALM_HPP
20#define CPPREALM_BRIDGE_REALM_HPP
21
22#include <cpprealm/internal/bridge/utils.hpp>
23
24#include <functional>
25#include <map>
26#include <memory>
27#include <optional>
28#include <string>
29#include <vector>
30
31namespace realm {
32 class Realm;
33 struct RealmConfig;
34 struct SyncConfig;
35 struct scheduler;
36 class SyncUser;
37 namespace app {
38 class User;
39 }
40
41 enum class client_reset_mode: uint8_t {
42 // Fire a client reset error
43 manual,
44 // Discard unsynced local changes, without disrupting accessors or closing the Realm
45 discard_unsynced,
46 // Attempt to recover unsynchronized but committed changes.
47 recover,
48 // Attempt recovery and if that fails, discard local.
49 recover_or_discard,
50 };
51}
52
53namespace realm::internal::bridge {
54 template<typename T> struct client_reset_mode_base;
55 struct group;
56 struct schema;
57 struct object_schema;
58 struct table;
59 struct dictionary;
60 struct thread_safe_reference;
61 struct obj;
62 struct object;
63 struct async_open_task;
64 struct sync_session;
65 struct sync_error;
66
67 struct realm {
68 enum class sync_session_stop_policy: uint8_t {
69 immediately, // Immediately stop the session as soon as all Realms/Sessions go out of scope.
70 live_indefinitely, // Never stop the session.
71 after_changes_uploaded, // Once all Realms/Sessions go out of scope, wait for uploads to complete and stop.
72 };
73
74 struct sync_config {
75
76 struct proxy_config {
77 using port_type = std::uint_fast16_t;
78 std::string address;
79 port_type port;
80 // For basic authorization.
81 std::optional<std::pair<std::string, std::string>> username_password;
82 };
83
85 sync_config() {}
86 sync_config(const std::shared_ptr<SyncUser> &user);
87 sync_config(const std::shared_ptr<SyncConfig> &);//NOLINT(google-explicit-constructor)
88 operator std::shared_ptr<SyncConfig>() const; //NOLINT(google-explicit-constructor)
89 void set_stop_policy(sync_session_stop_policy &&);
90 void set_error_handler(std::function<void(const sync_session &, const sync_error &)> &&fn);
91
92 private:
93 std::shared_ptr<SyncConfig> m_config;
94 };
95
96 struct config {
97 // How to handle update_schema() being called on a file which has
98 // already been initialized with a different schema
99 enum class schema_mode : uint8_t {
100 // If the schema version has increased, automatically apply all
101 // changes, then call the migration function.
102 //
103 // If the schema version has not changed, verify that the only
104 // changes are to add new tables and add or remove indexes, and then
105 // apply them if so. Does not call the migration function.
106 //
107 // This mode does not automatically remove tables which are not
108 // present in the schema that must be manually done in the migration
109 // function, to support sharing a Realm file between processes using
110 // different class subsets.
111 //
112 // This mode allows using schemata with different subsets of tables
113 // on different threads, but the tables which are shared must be
114 // identical.
115 automatic,
116
117 // Open the file in immutable mode. Schema version must match the
118 // version in the file, and all tables present in the file must
119 // exactly match the specified schema, except for indexes. Tables
120 // are allowed to be missing from the file.
121 immutable,
122
123 // Open the Realm in read-only mode, transactions are not allowed to
124 // be performed on the Realm instance. The schema of the existing Realm
125 // file won't be changed through this Realm instance. Extra tables and
126 // extra properties are allowed in the existing Realm schema. The
127 // difference of indexes is allowed as well. Other schema differences
128 // than those will cause an exception. This is different from Immutable
129 // mode, sync Realm can be opened with ReadOnly mode. Changes
130 // can be made to the Realm file through another writable Realm instance.
131 // Thus, notifications are also allowed in this mode.
132 read_only,
133
134 // If the schema version matches and the only schema changes are new
135 // tables and indexes being added or removed, apply the changes to
136 // the existing file.
137 // Otherwise delete the file and recreate it from scratch.
138 // The migration function is not used.
139 //
140 // This mode allows using schemata with different subsets of tables
141 // on different threads, but the tables which are shared must be
142 // identical.
143 soft_reset_file,
144
145 // Delete the file and recreate it from scratch.
146 // The migration function is not used.
147 hard_reset_file,
148
149 // The only changes allowed are to add new tables, add columns to
150 // existing tables, and to add or remove indexes from existing
151 // columns. Extra tables not present in the schema are ignored.
152 // Indexes are only added to or removed from existing columns if the
153 // schema version is greater than the existing one (and unlike other
154 // modes, the schema version is allowed to be less than the existing
155 // one).
156 // The migration function is not used.
157 // This should be used when including discovered user classes.
158 // Previously called Additive.
159 //
160 // This mode allows updating the schema with additive changes even
161 // if the Realm is already open on another thread.
162 additive_discovered,
163
164 // The same additive properties as AdditiveDiscovered, except
165 // in this mode, all classes in the schema have been explicitly
166 // included by the user. This means that stricter schema checks are
167 // run such as throwing an error when an embedded object type which
168 // is not linked from any top level object types is included.
169 additive_explicit,
170
171 // Verify that the schema version has increased, call the migration
172 // function, and then verify that the schema now matches.
173 // The migration function is mandatory for this mode.
174 //
175 // This mode requires that all threads and processes which open a
176 // file use identical schemata.
177 manual
178 };
179 config();
180 config(const config& other);
181 config& operator=(const config& other);
182 config(config&& other);
183 config& operator=(config&& other);
184 ~config();
185 config(const RealmConfig&); //NOLINT(google-explicit-constructor)
186 config(const std::string& path,
187 const std::shared_ptr<struct scheduler>& scheduler);
188 [[nodiscard]] std::string path() const;
189 [[nodiscard]] struct sync_config sync_config() const;
190 [[nodiscard]] std::shared_ptr<struct scheduler> scheduler() const;
191 operator RealmConfig() const; //NOLINT(google-explicit-constructor)
192 void set_path(const std::string&);
193 void set_schema(const std::vector<object_schema>&);
194 void set_schema_mode(schema_mode);
195 void set_scheduler(const std::shared_ptr<struct scheduler>&);
196 void set_sync_config(const std::optional<struct sync_config>&);
197 void set_custom_http_headers(const std::map<std::string, std::string>& headers);
198 void set_proxy_config(const sync_config::proxy_config&);
199 void set_schema_version(uint64_t version);
200 void set_encryption_key(const std::array<char, 64>&);
201 void should_compact_on_launch(std::function<bool(uint64_t total_bytes, uint64_t unused_bytes)>&& fn);
202 std::optional<schema> get_schema();
203
204 template<typename T>
205 void set_client_reset_handler(const client_reset_mode_base<T>& handler) {
206 before_client_reset([fn = std::move(handler.m_before)](realm local_realm) {
207 fn(local_realm.freeze());
208 });
209 after_client_reset([fn = std::move(handler.m_after)](realm local_realm, realm remote_realm) {
210 fn(local_realm.freeze(), remote_realm);
211 });
212 set_client_reset_mode(handler.m_mode);
213 }
214 enum client_reset_mode get_client_reset_mode() const;
215 private:
216 void set_client_reset_mode(enum client_reset_mode mode);
217 void before_client_reset(std::function<void(realm old_realm)> callback);
218 void after_client_reset(std::function<void(realm local_realm, realm remote_realm)> callback);
219 inline RealmConfig* get_config();
220 inline const RealmConfig* get_config() const;
221#ifdef CPPREALM_HAVE_GENERATED_BRIDGE_TYPES
222 storage::Realm_Config m_config[1];
223#else
224 std::shared_ptr<RealmConfig> m_config;
225#endif
226 };
227
228 realm();
229 realm(const config&); //NOLINT(google-explicit-constructor)
230 realm(std::shared_ptr<Realm>); //NOLINT(google-explicit-constructor)
231 realm(thread_safe_reference&& tsr, const std::optional<std::shared_ptr<scheduler>>&); //NOLINT(google-explicit-constructor)
232 operator std::shared_ptr<Realm>() const; //NOLINT(google-explicit-constructor)
233 group read_group();
234 [[nodiscard]] config get_config() const;
235 [[nodiscard]] struct schema schema() const;
236 void begin_transaction() const;
237 void commit_transaction() const;
238 table table_for_object_type(const std::string& object_type);
239 table get_table(const uint32_t &);
240 [[nodiscard]] std::shared_ptr<struct scheduler> scheduler() const;
241 static async_open_task get_synchronized_realm(const config&);
242 bool refresh();
243 bool is_frozen() const;
244 realm freeze(); // throws
245 realm thaw(); // throws
246 void close();
247 bool is_closed();
248 void invalidate();
249 obj import_copy_of(const obj&) const;
250 [[nodiscard]] std::optional<sync_session> get_sync_session() const;
251 private:
252 std::shared_ptr<Realm> m_realm;
253 friend struct group;
254 };
255
256 template<typename T>
258 protected:
259 std::function<void(T local)> m_before;
260 std::function<void(T local, T remote)> m_after;
261 ::realm::client_reset_mode m_mode;
263 };
264
265 template <typename T>
266 T resolve(const realm&, thread_safe_reference&& tsr);
267 template <>
268 dictionary resolve(const realm&, thread_safe_reference&& tsr);
269 template <>
270 object resolve(const realm&, thread_safe_reference&& tsr);
271
272 bool operator ==(const realm&, const realm&);
273 bool operator !=(const realm&, const realm&);
274}
275
276#endif //CPPREALM_BRIDGE_REALM_HPP
Definition: async_open_task.hpp:31
Definition: dictionary.hpp:138
Definition: obj.hpp:244
Definition: obj.hpp:123
Definition: realm.hpp:67
Definition: schema.hpp:32
Definition: sync_error.hpp:40
Definition: sync_session.hpp:33
Definition: table.hpp:40
Definition: thread_safe_reference.hpp:32
Definition: scheduler.hpp:27
Definition: app.hpp:92