added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / schema.hpp
1 ////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright 2015 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_SCHEMA_HPP
20 #define REALM_SCHEMA_HPP
21
22 #include <string>
23 #include <vector>
24
25 #include <realm/util/features.h>
26
27 namespace realm {
28 class ObjectSchema;
29 class SchemaChange;
30 class StringData;
31 struct Property;
32
33 class Schema : private std::vector<ObjectSchema> {
34 private:
35     using base = std::vector<ObjectSchema>;
36 public:
37     Schema();
38     ~Schema();
39     // Create a schema from a vector of ObjectSchema
40     Schema(base types);
41     Schema(std::initializer_list<ObjectSchema> types);
42
43     Schema(Schema const&);
44     Schema(Schema &&);
45     Schema& operator=(Schema const&);
46     Schema& operator=(Schema&&);
47
48     // find an ObjectSchema by name
49     iterator find(StringData name);
50     const_iterator find(StringData name) const;
51
52     // find an ObjectSchema with the same name as the passed in one
53     iterator find(ObjectSchema const& object) noexcept;
54     const_iterator find(ObjectSchema const& object) const noexcept;
55
56     // Verify that this schema is internally consistent (i.e. all properties are
57     // valid, links link to types that actually exist, etc.)
58     void validate() const;
59
60     // Get the changes which must be applied to this schema to produce the passed-in schema
61     std::vector<SchemaChange> compare(Schema const&) const;
62
63     void copy_table_columns_from(Schema const&);
64
65     friend bool operator==(Schema const&, Schema const&);
66     friend bool operator!=(Schema const& a, Schema const& b) { return !(a == b); }
67
68     using base::iterator;
69     using base::const_iterator;
70     using base::begin;
71     using base::end;
72     using base::empty;
73     using base::size;
74
75 private:
76     template<typename T, typename U, typename Func>
77     static void zip_matching(T&& a, U&& b, Func&& func);
78 };
79
80 namespace schema_change {
81 struct AddTable {
82     const ObjectSchema* object;
83 };
84
85 struct AddInitialProperties {
86     const ObjectSchema* object;
87 };
88
89 struct AddProperty {
90     const ObjectSchema* object;
91     const Property* property;
92 };
93
94 struct RemoveProperty {
95     const ObjectSchema* object;
96     const Property* property;
97 };
98
99 struct ChangePropertyType {
100     const ObjectSchema* object;
101     const Property* old_property;
102     const Property* new_property;
103 };
104
105 struct MakePropertyNullable {
106     const ObjectSchema* object;
107     const Property* property;
108 };
109
110 struct MakePropertyRequired {
111     const ObjectSchema* object;
112     const Property* property;
113 };
114
115 struct AddIndex {
116     const ObjectSchema* object;
117     const Property* property;
118 };
119
120 struct RemoveIndex {
121     const ObjectSchema* object;
122     const Property* property;
123 };
124
125 struct ChangePrimaryKey {
126     const ObjectSchema* object;
127     const Property* property;
128 };
129 }
130
131 #define REALM_FOR_EACH_SCHEMA_CHANGE_TYPE(macro) \
132     macro(AddTable) \
133     macro(AddInitialProperties) \
134     macro(AddProperty) \
135     macro(RemoveProperty) \
136     macro(ChangePropertyType) \
137     macro(MakePropertyNullable) \
138     macro(MakePropertyRequired) \
139     macro(AddIndex) \
140     macro(RemoveIndex) \
141     macro(ChangePrimaryKey) \
142
143 class SchemaChange {
144 public:
145 #define REALM_SCHEMA_CHANGE_CONSTRUCTOR(name) \
146     SchemaChange(schema_change::name value) : m_kind(Kind::name) { name = value; }
147         REALM_FOR_EACH_SCHEMA_CHANGE_TYPE(REALM_SCHEMA_CHANGE_CONSTRUCTOR)
148 #undef REALM_SCHEMA_CHANGE_CONSTRUCTOR
149
150     template<typename Visitor>
151     auto visit(Visitor&& visitor) const {
152         switch (m_kind) {
153 #define REALM_SWITCH_CASE(name) case Kind::name: return visitor(name);
154         REALM_FOR_EACH_SCHEMA_CHANGE_TYPE(REALM_SWITCH_CASE)
155 #undef REALM_SWITCH_CASE
156         }
157         REALM_COMPILER_HINT_UNREACHABLE();
158     }
159
160     friend bool operator==(SchemaChange const& lft, SchemaChange const& rgt);
161 private:
162     enum class Kind {
163 #define REALM_SCHEMA_CHANGE_TYPE(name) name,
164         REALM_FOR_EACH_SCHEMA_CHANGE_TYPE(REALM_SCHEMA_CHANGE_TYPE)
165 #undef REALM_SCHEMA_CHANGE_TYPE
166
167     } m_kind;
168     union {
169 #define REALM_DEFINE_FIELD(name) schema_change::name name;
170         REALM_FOR_EACH_SCHEMA_CHANGE_TYPE(REALM_DEFINE_FIELD)
171 #undef REALM_DEFINE_FIELD
172     };
173 };
174
175 #undef REALM_FOR_EACH_SCHEMA_CHANGE_TYPE
176 }
177
178 #endif /* defined(REALM_SCHEMA_HPP) */