added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / sync / impl / sync_metadata.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_OS_SYNC_METADATA_HPP
20 #define REALM_OS_SYNC_METADATA_HPP
21
22 #include <string>
23
24 #include <realm/row.hpp>
25 #include <realm/table.hpp>
26 #include <realm/util/optional.hpp>
27
28 #include "results.hpp"
29 #include "shared_realm.hpp"
30
31 namespace realm {
32 template<typename T> class BasicRowExpr;
33 using RowExpr = BasicRowExpr<Table>;
34 class SyncMetadataManager;
35
36 // A facade for a metadata Realm object representing a sync user.
37 class SyncUserMetadata {
38 public:
39     struct Schema {
40         // The ROS identity of the user. This, plus the auth server URL, uniquely identifies a user.
41         size_t idx_identity;
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;
52     };
53
54     // Cannot be set after creation.
55     std::string identity() const;
56
57     // Cannot be set after creation.
58     std::string local_uuid() const;
59
60     util::Optional<std::string> user_token() const;
61     void set_user_token(util::Optional<std::string>);
62
63     // Cannot be set after creation.
64     std::string auth_server_url() const;
65
66     bool is_admin() const;
67     void set_is_admin(bool);
68
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();
72
73     void remove();
74
75     bool is_valid() const
76     {
77         return !m_invalid;
78     }
79
80     // INTERNAL USE ONLY
81     SyncUserMetadata(Schema schema, SharedRealm realm, RowExpr row);
82 private:
83     bool m_invalid = false;
84     SharedRealm m_realm;
85     Schema m_schema;
86     Row m_row;
87 };
88
89 // A facade for a metadata Realm object representing a pending action to be carried out upon a specific file(s).
90 class SyncFileActionMetadata {
91 public:
92     struct Schema {
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.
96         size_t idx_new_name;
97         // An enum describing the action to take.
98         size_t idx_action;
99         // The full remote URL of the Realm on the ROS.
100         size_t idx_url;
101         // The local UUID of the user to whom the file action applies (despite the internal column name).
102         size_t idx_user_identity;
103     };
104
105     enum class Action {
106         // The Realm files at the given directory will be deleted.
107         DeleteRealm,
108         // The Realm file will be copied to a 'recovery' directory, and the original Realm files will be deleted.
109         BackUpThenDeleteRealm
110     };
111
112     // The absolute path to the Realm file in question.
113     std::string original_name() const;
114
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;
120
121     // Get the local UUID of the user associated with this file action metadata.
122     std::string user_local_uuid() const;
123
124     Action action() const;
125     std::string url() const;
126     void remove();
127
128     // INTERNAL USE ONLY
129     SyncFileActionMetadata(Schema schema, SharedRealm realm, RowExpr row);
130 private:
131     SharedRealm m_realm;
132     Schema m_schema;
133     Row m_row;
134 };
135
136 class SyncClientMetadata {
137 public:
138     struct Schema {
139         // A UUID that identifies this client.
140         size_t idx_uuid;
141     };
142 };
143
144 template<class T>
145 class SyncMetadataResults {
146 public:
147     size_t size() const
148     {
149         return m_results.size();
150     }
151
152     T get(size_t idx) const
153     {
154         RowExpr row = m_results.get(idx);
155         return T(m_schema, m_realm, row);
156     }
157
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))
162     { }
163 private:
164     typename T::Schema m_schema;
165     SharedRealm m_realm;
166     // FIXME: remove 'mutable' once `realm::Results` is properly annotated for const
167     mutable Results m_results;
168 };
169 using SyncUserMetadataResults = SyncMetadataResults<SyncUserMetadata>;
170 using SyncFileActionMetadataResults = SyncMetadataResults<SyncFileActionMetadata>;
171
172 // A facade for the application's metadata Realm.
173 class SyncMetadataManager {
174 friend class SyncUserMetadata;
175 friend class SyncFileActionMetadata;
176 public:
177     // Return a Results object containing all users not marked for removal.
178     SyncUserMetadataResults all_unmarked_users() const;
179
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;
184
185     // Return a Results object containing all pending actions.
186     SyncFileActionMetadataResults all_pending_actions() const;
187
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;
191
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;
196
197     // Retrieve file action metadata.
198     util::Optional<SyncFileActionMetadata> get_file_action_metadata(const std::string& path) const;
199
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;
206
207     // Get the unique identifier of this client, generating one if it does not already exist.
208     std::string client_uuid() const;
209
210     /// Construct the metadata manager.
211     ///
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,
216                         bool should_encrypt,
217                         util::Optional<std::vector<char>> encryption_key=none);
218
219 private:
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;
225 };
226
227 }
228
229 #endif // REALM_OS_SYNC_METADATA_HPP