Skip to content

Commit

Permalink
Merge pull request realm#5385 from realm/kk/migration
Browse files Browse the repository at this point in the history
Fixed an issue that crash when enumerating after clearing data during migration.
  • Loading branch information
kishikawakatsumi committed Oct 13, 2017
2 parents 1f42c2a + 6f89f75 commit ccd1f35
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ x.x.x Release notes (yyyy-MM-dd)
level.
* Fix a race condition that could lead to a crash accessing to the freed configuration object
if a default configuration was set from a different thread.
* Fixed an issue that crash when enumerating after clearing data during migration.

3.0.0-rc.1 Release notes (2017-10-03)
=============================================================
Expand Down
31 changes: 24 additions & 7 deletions Realm/RLMMigration.mm
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ - (void)beginWriteTransaction {
@implementation RLMMigration {
realm::Schema *_schema;
NSMutableDictionary *deletedObjectIndices;
NSMutableSet *deletedClasses;
}

- (instancetype)initWithRealm:(RLMRealm *)realm oldRealm:(RLMRealm *)oldRealm schema:(realm::Schema &)schema {
Expand All @@ -67,6 +68,7 @@ - (instancetype)initWithRealm:(RLMRealm *)realm oldRealm:(RLMRealm *)oldRealm sc
_schema = &schema;
object_setClass(_oldRealm, RLMMigrationRealm.class);
deletedObjectIndices = [NSMutableDictionary dictionary];
deletedClasses = [NSMutableSet set];
}
return self;
}
Expand All @@ -80,6 +82,10 @@ - (RLMSchema *)newSchema {
}

- (void)enumerateObjects:(NSString *)className block:(RLMObjectMigrationBlock)block {
if ([deletedClasses containsObject:className]) {
return;
}

// get all objects
RLMResults *objects = [_realm.schema schemaForClassName:className] ? [_realm allObjects:className] : nil;
RLMResults *oldObjects = [_oldRealm.schema schemaForClassName:className] ? [_oldRealm allObjects:className] : nil;
Expand Down Expand Up @@ -128,7 +134,9 @@ - (void)execute:(RLMMigrationBlock)block {
}

block(self, _oldRealm->_realm->schema_version());

[self deleteObjectsMarkedForDeletion];
[self deleteDataMarkedForDeletion];

_oldRealm = nil;
_realm = nil;
Expand Down Expand Up @@ -167,16 +175,25 @@ - (BOOL)deleteDataForClassName:(NSString *)name {
return false;
}

if ([_realm.schema schemaForClassName:name]) {
table->clear();
}
else {
realm::ObjectStore::delete_data_for_object(_realm.group, name.UTF8String);
}

[deletedClasses addObject:name];
return true;
}

- (void)deleteDataMarkedForDeletion {
for (NSString *className in deletedClasses) {
TableRef table = ObjectStore::table_for_object_type(_realm.group, className.UTF8String);
if (!table) {
continue;
}
if ([_realm.schema schemaForClassName:className]) {
table->clear();
}
else {
realm::ObjectStore::delete_data_for_object(_realm.group, className.UTF8String);
}
}
}

- (void)renamePropertyForClass:(NSString *)className oldName:(NSString *)oldName newName:(NSString *)newName {
const char *objectType = className.UTF8String;
realm::ObjectStore::rename_property(_realm.group, *_schema, objectType, oldName.UTF8String, newName.UTF8String);
Expand Down
28 changes: 28 additions & 0 deletions RealmSwift/Tests/MigrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,34 @@ class MigrationTests: TestCase {
}
}

func testEnumerateObjectsAfterDeleteData() {
autoreleasepool {
// add object
try! Realm().write {
try! Realm().create(SwiftStringObject.self, value: ["1"])
try! Realm().create(SwiftStringObject.self, value: ["2"])
try! Realm().create(SwiftStringObject.self, value: ["3"])
}
}

migrateAndTestDefaultRealm(1) { migration, _ in
var count = 0
migration.enumerateObjects(ofType: "SwiftStringObject") { _, _ in
count += 1
}
XCTAssertEqual(count, 3)

migration.deleteData(forType: "SwiftStringObject")
migration.create("SwiftStringObject", value: ["A"])

count = 0
migration.enumerateObjects(ofType: "SwiftStringObject") { _, _ in
count += 1
}
XCTAssertEqual(count, 0)
}
}

func testCreate() {
autoreleasepool {
_ = try! Realm()
Expand Down

0 comments on commit ccd1f35

Please sign in to comment.