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_OS_SYNC_METADATA_HPP
20 #define REALM_OS_SYNC_METADATA_HPP
24 #include <realm/row.hpp>
25 #include <realm/table.hpp>
26 #include <realm/util/optional.hpp>
28 #include "results.hpp"
29 #include "shared_realm.hpp"
32 template<typename T> class BasicRowExpr;
33 using RowExpr = BasicRowExpr<Table>;
34 class SyncMetadataManager;
36 // A facade for a metadata Realm object representing a sync user.
37 class SyncUserMetadata {
40 // The ROS identity of the user. This, plus the auth server URL, uniquely identifies a user.
42 // A locally issued UUID for the user. This is used to generate the on-disk user directory.
43 size_t idx_local_uuid;
44 // Whether or not this user has been marked for removal.
45 size_t idx_marked_for_removal;
46 // The cached refresh token for this user.
47 size_t idx_user_token;
48 // The URL of the authentication server this user resides upon.
49 size_t idx_auth_server_url;
50 // Whether or not the auth server reported that this user is marked as an administrator.
51 size_t idx_user_is_admin;
54 // Cannot be set after creation.
55 std::string identity() const;
57 // Cannot be set after creation.
58 std::string local_uuid() const;
60 util::Optional<std::string> user_token() const;
61 void set_user_token(util::Optional<std::string>);
63 // Cannot be set after creation.
64 std::string auth_server_url() const;
66 bool is_admin() const;
67 void set_is_admin(bool);
69 // Mark the user as "ready for removal". Since Realm files cannot be safely deleted after being opened, the actual
70 // deletion of a user must be deferred until the next time the host application is launched.
71 void mark_for_removal();
81 SyncUserMetadata(Schema schema, SharedRealm realm, RowExpr row);
83 bool m_invalid = false;
89 // A facade for a metadata Realm object representing a pending action to be carried out upon a specific file(s).
90 class SyncFileActionMetadata {
93 // The original path on disk of the file (generally, the main file for an on-disk Realm).
94 size_t idx_original_name;
95 // A new path on disk for a file to be written to. Context-dependent.
97 // An enum describing the action to take.
99 // The full remote URL of the Realm on the ROS.
101 // The local UUID of the user to whom the file action applies (despite the internal column name).
102 size_t idx_user_identity;
106 // The Realm files at the given directory will be deleted.
108 // The Realm file will be copied to a 'recovery' directory, and the original Realm files will be deleted.
109 BackUpThenDeleteRealm
112 // The absolute path to the Realm file in question.
113 std::string original_name() const;
115 // The meaning of this parameter depends on the `Action` specified.
116 // For `BackUpThenDeleteRealm`, it is the absolute path where the backup copy
117 // of the Realm file found at `original_name()` will be placed.
118 // For all other `Action`s, it is ignored.
119 util::Optional<std::string> new_name() const;
121 // Get the local UUID of the user associated with this file action metadata.
122 std::string user_local_uuid() const;
124 Action action() const;
125 std::string url() const;
129 SyncFileActionMetadata(Schema schema, SharedRealm realm, RowExpr row);
136 class SyncClientMetadata {
139 // A UUID that identifies this client.
145 class SyncMetadataResults {
149 return m_results.size();
152 T get(size_t idx) const
154 RowExpr row = m_results.get(idx);
155 return T(m_schema, m_realm, row);
158 SyncMetadataResults(Results results, SharedRealm realm, typename T::Schema schema)
159 : m_schema(std::move(schema))
160 , m_realm(std::move(realm))
161 , m_results(std::move(results))
164 typename T::Schema m_schema;
166 // FIXME: remove 'mutable' once `realm::Results` is properly annotated for const
167 mutable Results m_results;
169 using SyncUserMetadataResults = SyncMetadataResults<SyncUserMetadata>;
170 using SyncFileActionMetadataResults = SyncMetadataResults<SyncFileActionMetadata>;
172 // A facade for the application's metadata Realm.
173 class SyncMetadataManager {
174 friend class SyncUserMetadata;
175 friend class SyncFileActionMetadata;
177 // Return a Results object containing all users not marked for removal.
178 SyncUserMetadataResults all_unmarked_users() const;
180 // Return a Results object containing all users marked for removal. It is the binding's responsibility to call
181 // `remove()` on each user to actually remove it from the database. (This is so that already-open Realm files can be
182 // safely cleaned up the next time the host is launched.)
183 SyncUserMetadataResults all_users_marked_for_removal() const;
185 // Return a Results object containing all pending actions.
186 SyncFileActionMetadataResults all_pending_actions() const;
188 // Delete an existing metadata action given the original name of the Realm it involves.
189 // Returns true iff there was an existing metadata action and it was deleted.
190 bool delete_metadata_action(const std::string&) const;
192 // Retrieve or create user metadata.
193 // Note: if `make_is_absent` is true and the user has been marked for deletion, it will be unmarked.
194 util::Optional<SyncUserMetadata> get_or_make_user_metadata(const std::string& identity, const std::string& url,
195 bool make_if_absent=true) const;
197 // Retrieve file action metadata.
198 util::Optional<SyncFileActionMetadata> get_file_action_metadata(const std::string& path) const;
200 // Create file action metadata.
201 SyncFileActionMetadata make_file_action_metadata(const std::string& original_name,
202 const std::string& url,
203 const std::string& local_uuid,
204 SyncFileActionMetadata::Action action,
205 util::Optional<std::string> new_name=none) const;
207 // Get the unique identifier of this client, generating one if it does not already exist.
208 std::string client_uuid() const;
210 /// Construct the metadata manager.
212 /// If the platform supports it, setting `should_encrypt` to `true` and not specifying an encryption key will make
213 /// the object store handle generating and persisting an encryption key for the metadata database. Otherwise, an
214 /// exception will be thrown.
215 SyncMetadataManager(std::string path,
217 util::Optional<std::vector<char>> encryption_key=none);
220 SyncUserMetadataResults get_users(bool marked) const;
221 Realm::Config m_metadata_config;
222 SyncUserMetadata::Schema m_user_schema;
223 SyncFileActionMetadata::Schema m_file_action_schema;
224 SyncClientMetadata::Schema m_client_schema;
229 #endif // REALM_OS_SYNC_METADATA_HPP