RLMAccessor.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2017 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. #import "RLMAccessor.h"
  19. #import "RLMDecimal128_Private.hpp"
  20. #import "RLMObjectId_Private.hpp"
  21. #import "RLMUtil.hpp"
  22. #import <realm/object-store/object_accessor.hpp>
  23. @class RLMRealm;
  24. class RLMClassInfo;
  25. class RLMObservationTracker;
  26. typedef NS_ENUM(NSUInteger, RLMUpdatePolicy);
  27. // realm::util::Optional<id> doesn't work because Objective-C types can't
  28. // be members of unions with ARC, so this covers the subset of Optional that we
  29. // actually need.
  30. struct RLMOptionalId {
  31. id value;
  32. RLMOptionalId(id value) : value(value) { }
  33. explicit operator bool() const noexcept { return value; }
  34. id operator*() const noexcept { return value; }
  35. };
  36. class RLMAccessorContext {
  37. public:
  38. ~RLMAccessorContext();
  39. // Accessor context interface
  40. RLMAccessorContext(RLMAccessorContext& parent, realm::Obj const& parent_obj, realm::Property const& property);
  41. id box(realm::List&&);
  42. id box(realm::Results&&);
  43. id box(realm::Object&&);
  44. id box(realm::Obj&&);
  45. id box(realm::object_store::Dictionary&&) { REALM_COMPILER_HINT_UNREACHABLE(); }
  46. id box(realm::object_store::Set&&) { REALM_COMPILER_HINT_UNREACHABLE(); }
  47. id box(bool v) { return @(v); }
  48. id box(double v) { return @(v); }
  49. id box(float v) { return @(v); }
  50. id box(long long v) { return @(v); }
  51. id box(realm::StringData v) { return RLMStringDataToNSString(v) ?: NSNull.null; }
  52. id box(realm::BinaryData v) { return RLMBinaryDataToNSData(v) ?: NSNull.null; }
  53. id box(realm::Timestamp v) { return RLMTimestampToNSDate(v) ?: NSNull.null; }
  54. id box(realm::Decimal128 v) { return v.is_null() ? NSNull.null : [[RLMDecimal128 alloc] initWithDecimal128:v]; }
  55. id box(realm::ObjectId v) { return [[RLMObjectId alloc] initWithValue:v]; }
  56. id box(realm::Mixed v) { return RLMMixedToObjc(v); }
  57. id box(realm::util::Optional<bool> v) { return v ? @(*v) : NSNull.null; }
  58. id box(realm::util::Optional<double> v) { return v ? @(*v) : NSNull.null; }
  59. id box(realm::util::Optional<float> v) { return v ? @(*v) : NSNull.null; }
  60. id box(realm::util::Optional<int64_t> v) { return v ? @(*v) : NSNull.null; }
  61. id box(realm::util::Optional<realm::ObjectId> v) { return v ? box(*v) : NSNull.null; }
  62. void will_change(realm::Obj const&, realm::Property const&);
  63. void will_change(realm::Object& obj, realm::Property const& prop) { will_change(obj.obj(), prop); }
  64. void did_change();
  65. RLMOptionalId value_for_property(id dict, realm::Property const&, size_t prop_index);
  66. RLMOptionalId default_value_for_property(realm::ObjectSchema const&,
  67. realm::Property const& prop);
  68. bool is_same_list(realm::List const& list, id v) const noexcept;
  69. bool is_same_dictionary(realm::object_store::Dictionary const&, id) const noexcept { REALM_COMPILER_HINT_UNREACHABLE(); }
  70. bool is_same_set(realm::object_store::Set const&, id) const noexcept { REALM_COMPILER_HINT_UNREACHABLE(); }
  71. template<typename Func>
  72. void enumerate_collection(__unsafe_unretained const id v, Func&& func) {
  73. id enumerable = RLMAsFastEnumeration(v) ?: v;
  74. for (id value in enumerable) {
  75. func(value);
  76. }
  77. }
  78. template<typename Func>
  79. void enumerate_dictionary(__unsafe_unretained const id, Func&&) {
  80. REALM_COMPILER_HINT_UNREACHABLE();
  81. }
  82. template<typename T>
  83. T unbox(id v, realm::CreatePolicy = realm::CreatePolicy::Skip, realm::ObjKey = {});
  84. realm::Obj create_embedded_object();
  85. bool is_null(id v) { return v == NSNull.null; }
  86. id null_value() { return NSNull.null; }
  87. id no_value() { return nil; }
  88. bool allow_missing(id v) { return [v isKindOfClass:[NSArray class]]; }
  89. std::string print(id obj) { return [obj description].UTF8String; }
  90. // Internal API
  91. RLMAccessorContext(RLMObjectBase *parentObject, const realm::Property *property = nullptr);
  92. RLMAccessorContext(RLMObjectBase *parentObject, realm::ColKey);
  93. RLMAccessorContext(RLMClassInfo& info);
  94. // The property currently being accessed; needed for KVO things for boxing
  95. // List and Results
  96. RLMProperty *currentProperty;
  97. std::pair<realm::Obj, bool>
  98. createObject(id value, realm::CreatePolicy policy, bool forceCreate=false, realm::ObjKey existingKey={});
  99. private:
  100. __unsafe_unretained RLMRealm *const _realm;
  101. RLMClassInfo& _info;
  102. realm::Obj _parentObject;
  103. RLMClassInfo* _parentObjectInfo = nullptr;
  104. realm::ColKey _colKey;
  105. // Cached default values dictionary to avoid having to call the class method
  106. // for every property
  107. NSDictionary *_defaultValues;
  108. std::unique_ptr<RLMObservationTracker> _observationHelper;
  109. id defaultValue(NSString *key);
  110. id propertyValue(id obj, size_t propIndex, __unsafe_unretained RLMProperty *const prop);
  111. };