added iOS source code
[wl-app.git] / iOS / Pods / Realm / Realm / RLMClassInfo.mm
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 #import "RLMClassInfo.hpp"
20
21 #import "RLMRealm_Private.hpp"
22 #import "RLMObjectSchema_Private.h"
23 #import "RLMSchema.h"
24 #import "RLMProperty_Private.h"
25 #import "RLMQueryUtil.hpp"
26 #import "RLMUtil.hpp"
27
28 #import "object_schema.hpp"
29 #import "object_store.hpp"
30 #import "schema.hpp"
31 #import "shared_realm.hpp"
32
33 #import <realm/table.hpp>
34
35 using namespace realm;
36
37 RLMClassInfo::RLMClassInfo(RLMRealm *realm, RLMObjectSchema *rlmObjectSchema,
38                              const realm::ObjectSchema *objectSchema)
39 : realm(realm), rlmObjectSchema(rlmObjectSchema), objectSchema(objectSchema) { }
40
41 realm::Table *RLMClassInfo::table() const {
42     if (!m_table) {
43         m_table = ObjectStore::table_for_object_type(realm.group, objectSchema->name).get();
44     }
45     return m_table;
46 }
47
48 RLMProperty *RLMClassInfo::propertyForTableColumn(NSUInteger col) const noexcept {
49     auto const& props = objectSchema->persisted_properties;
50     for (size_t i = 0; i < props.size(); ++i) {
51         if (props[i].table_column == col) {
52             return rlmObjectSchema.properties[i];
53         }
54     }
55     return nil;
56 }
57
58 RLMProperty *RLMClassInfo::propertyForPrimaryKey() const noexcept {
59     return rlmObjectSchema.primaryKeyProperty;
60 }
61
62 NSUInteger RLMClassInfo::tableColumn(NSString *propertyName) const {
63     return tableColumn(RLMValidatedProperty(rlmObjectSchema, propertyName));
64 }
65
66 NSUInteger RLMClassInfo::tableColumn(RLMProperty *property) const {
67     return objectSchema->persisted_properties[property.index].table_column;
68 }
69
70 RLMClassInfo &RLMClassInfo::linkTargetType(size_t propertyIndex) {
71     if (propertyIndex < m_linkTargets.size() && m_linkTargets[propertyIndex]) {
72         return *m_linkTargets[propertyIndex];
73     }
74     if (m_linkTargets.size() <= propertyIndex) {
75         m_linkTargets.resize(propertyIndex + 1);
76     }
77     m_linkTargets[propertyIndex] = &realm->_info[rlmObjectSchema.properties[propertyIndex].objectClassName];
78     return *m_linkTargets[propertyIndex];
79 }
80
81 RLMClassInfo &RLMClassInfo::linkTargetType(realm::Property const& property) {
82     REALM_ASSERT(property.type == PropertyType::Object);
83     return linkTargetType(&property - &objectSchema->persisted_properties[0]);
84 }
85
86 RLMSchemaInfo::impl::iterator RLMSchemaInfo::begin() noexcept { return m_objects.begin(); }
87 RLMSchemaInfo::impl::iterator RLMSchemaInfo::end() noexcept { return m_objects.end(); }
88 RLMSchemaInfo::impl::const_iterator RLMSchemaInfo::begin() const noexcept { return m_objects.begin(); }
89 RLMSchemaInfo::impl::const_iterator RLMSchemaInfo::end() const noexcept { return m_objects.end(); }
90
91 RLMClassInfo& RLMSchemaInfo::operator[](NSString *name) {
92     auto it = m_objects.find(name);
93     if (it == m_objects.end()) {
94         @throw RLMException(@"Object type '%@' is not managed by the Realm. "
95                             @"If using a custom `objectClasses` / `objectTypes` array in your configuration, "
96                             @"add `%@` to the list of `objectClasses` / `objectTypes`.",
97                             name, name);
98     }
99     return *&it->second;
100 }
101
102 RLMSchemaInfo::RLMSchemaInfo(RLMRealm *realm) {
103     RLMSchema *rlmSchema = realm.schema;
104     realm::Schema const& schema = realm->_realm->schema();
105     REALM_ASSERT(rlmSchema.objectSchema.count == schema.size());
106
107     m_objects.reserve(schema.size());
108     for (RLMObjectSchema *rlmObjectSchema in rlmSchema.objectSchema) {
109         m_objects.emplace(std::piecewise_construct,
110                           std::forward_as_tuple(rlmObjectSchema.className),
111                           std::forward_as_tuple(realm, rlmObjectSchema,
112                                                 &*schema.find(rlmObjectSchema.objectName.UTF8String)));
113     }
114 }
115
116 RLMSchemaInfo RLMSchemaInfo::clone(realm::Schema const& source_schema,
117                                    __unsafe_unretained RLMRealm *const target_realm) {
118     RLMSchemaInfo info;
119     info.m_objects.reserve(m_objects.size());
120
121     auto& schema = target_realm->_realm->schema();
122     for (auto& pair : m_objects) {
123         size_t idx = pair.second.objectSchema - &*source_schema.begin();
124         info.m_objects.emplace(std::piecewise_construct,
125                                std::forward_as_tuple(pair.first),
126                                std::forward_as_tuple(target_realm, pair.second.rlmObjectSchema,
127                                                      &*schema.begin() + idx));
128     }
129     return info;
130 }