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