123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- ////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2014 Realm Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- ////////////////////////////////////////////////////////////////////////////
- #import "RLMMigration_Private.h"
- #import "RLMAccessor.h"
- #import "RLMObject_Private.h"
- #import "RLMObject_Private.hpp"
- #import "RLMObjectSchema_Private.hpp"
- #import "RLMObjectStore.h"
- #import "RLMProperty_Private.h"
- #import "RLMRealm_Dynamic.h"
- #import "RLMRealm_Private.hpp"
- #import "RLMResults_Private.hpp"
- #import "RLMSchema_Private.hpp"
- #import "RLMUtil.hpp"
- #import <realm/object-store/object_store.hpp>
- #import <realm/object-store/shared_realm.hpp>
- #import <realm/object-store/schema.hpp>
- #import <realm/table.hpp>
- using namespace realm;
- @implementation RLMMigration {
- realm::Schema *_schema;
- }
- - (instancetype)initWithRealm:(RLMRealm *)realm oldRealm:(RLMRealm *)oldRealm schema:(realm::Schema &)schema {
- self = [super init];
- if (self) {
- _realm = realm;
- _oldRealm = oldRealm;
- _schema = &schema;
- }
- return self;
- }
- - (RLMSchema *)oldSchema {
- return self.oldRealm.schema;
- }
- - (RLMSchema *)newSchema {
- return self.realm.schema;
- }
- - (void)enumerateObjects:(NSString *)className block:(__attribute__((noescape)) RLMObjectMigrationBlock)block {
- RLMResults *objects = [_realm.schema schemaForClassName:className] ? [_realm allObjects:className] : nil;
- RLMResults *oldObjects = [_oldRealm.schema schemaForClassName:className] ? [_oldRealm allObjects:className] : nil;
- // For whatever reason if this is a newly added table we enumerate the
- // objects in it, while in all other cases we enumerate only the existing
- // objects. It's unclear how this could be useful, but changing it would
- // also be a pointless breaking change and it's unlikely to be hurting anyone.
- if (objects && !oldObjects) {
- for (RLMObject *object in objects) {
- @autoreleasepool {
- block(nil, object);
- }
- }
- return;
- }
-
- // If a table will be deleted it can still be enumerated during the migration
- // so that data can be saved or transfered to other tables if necessary.
- if (!objects && oldObjects) {
- for (RLMObject *oldObject in oldObjects) {
- @autoreleasepool {
- block(oldObject, nil);
- }
- }
- return;
- }
-
- if (oldObjects.count == 0 || objects.count == 0) {
- return;
- }
- auto& info = _realm->_info[className];
- for (RLMObject *oldObject in oldObjects) {
- @autoreleasepool {
- Obj newObj;
- try {
- newObj = info.table()->get_object(oldObject->_row.get_key());
- }
- catch (KeyNotFound const&) {
- continue;
- }
- block(oldObject, (id)RLMCreateObjectAccessor(info, std::move(newObj)));
- }
- }
- }
- - (void)execute:(RLMMigrationBlock)block objectClass:(Class)dynamicObjectClass {
- if (!dynamicObjectClass) {
- dynamicObjectClass = RLMDynamicObject.class;
- }
- @autoreleasepool {
- // disable all primary keys for migration and use DynamicObject for all types
- for (RLMObjectSchema *objectSchema in _realm.schema.objectSchema) {
- objectSchema.accessorClass = dynamicObjectClass;
- objectSchema.primaryKeyProperty.isPrimary = NO;
- }
- for (RLMObjectSchema *objectSchema in _oldRealm.schema.objectSchema) {
- objectSchema.accessorClass = dynamicObjectClass;
- }
- block(self, _oldRealm->_realm->schema_version());
- _oldRealm = nil;
- _realm = nil;
- }
- }
- - (RLMObject *)createObject:(NSString *)className withValue:(id)value {
- return [_realm createObject:className withValue:value];
- }
- - (RLMObject *)createObject:(NSString *)className withObject:(id)object {
- return [self createObject:className withValue:object];
- }
- - (void)deleteObject:(RLMObject *)object {
- [_realm deleteObject:object];
- }
- - (BOOL)deleteDataForClassName:(NSString *)name {
- if (!name) {
- return false;
- }
- TableRef table = ObjectStore::table_for_object_type(_realm.group, name.UTF8String);
- if (!table) {
- return false;
- }
- if ([_realm.schema schemaForClassName:name]) {
- table->clear();
- }
- else {
- _realm.group.remove_table(table->get_key());
- }
- return true;
- }
- - (void)renamePropertyForClass:(NSString *)className oldName:(NSString *)oldName newName:(NSString *)newName {
- realm::ObjectStore::rename_property(_realm.group, *_schema, className.UTF8String,
- oldName.UTF8String, newName.UTF8String);
- }
- @end
|