Skip to content

Commit

Permalink
Allow opening in-memory synced realms. (#8421)
Browse files Browse the repository at this point in the history
  • Loading branch information
dianaafanador3 authored Jan 23, 2024
1 parent 6a0054a commit 1ef89df
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 12 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ x.y.z Release notes (yyyy-MM-dd)
* The `baseURL` field of `AppConfiguration` can now be updated, rather than the
value being persisted between runs of the application in the metadata
storage. ([Core #7201](https://github.com/realm/realm-core/issues/7201))
* Allow in-memory synced Realms. This will allow setting an in-memory identifier on
a flexible sync realm.

### Fixed
* `@Persisted`'s Encodable implementation did not allow the encoder to
Expand Down Expand Up @@ -9393,7 +9395,7 @@ Prebuilt frameworks are now built with Xcode 7.1.
the properties in a `RLMObject` subclass.
* Fix crash on IN query with several thousand items.
* Fix crash when querying indexed `NSString` properties.
* Fixed an issue which prevented in-memory Realms from being used accross multiple threads.
* Fixed an issue which prevented in-memory Realms from being used across multiple threads.
* Preserve the sort order when querying a sorted `RLMResults`.
* Fixed an issue with migrations where if a Realm file is deleted after a Realm is initialized,
the newly created Realm can be initialized with an incorrect schema version.
Expand Down
46 changes: 46 additions & 0 deletions Realm/ObjectServerTests/AsyncSyncTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,52 @@ class AsyncFlexibleSyncTests: SwiftSyncTestCase {
checkCount(expected: 10, realm, SwiftPerson.self)
}

@MainActor
func testFlexibleSyncInitInMemory() async throws {
try await populateSwiftPerson(5)

let user = try await createUser()
try await Task {
var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
subs.append(QuerySubscription<SwiftPerson> {
$0.age > 0 && $0.firstName == self.name
})
})
config.objectTypes = [SwiftPerson.self]
config.inMemoryIdentifier = "identifier"
let inMemoryRealm = try await Realm(configuration: config, downloadBeforeOpen: .always)
XCTAssertEqual(inMemoryRealm.objects(SwiftPerson.self).count, 5)
try! inMemoryRealm.write {
let person = SwiftPerson(firstName: self.name,
lastName: "lastname_10",
age: 10)
inMemoryRealm.add(person)
}
XCTAssertEqual(inMemoryRealm.objects(SwiftPerson.self).count, 6)
try await inMemoryRealm.syncSession?.wait(for: .upload)
}.value

var config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
subs.append(QuerySubscription<SwiftPerson> {
$0.age > 5 && $0.firstName == self.name
})
})
config.objectTypes = [SwiftPerson.self]
config.inMemoryIdentifier = "identifier"
let inMemoryRealm = try await Realm(configuration: config, downloadBeforeOpen: .always)
XCTAssertEqual(inMemoryRealm.objects(SwiftPerson.self).count, 1)

var config2 = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
subs.append(QuerySubscription<SwiftPerson> {
$0.age > 0 && $0.firstName == self.name
})
})
config2.objectTypes = [SwiftPerson.self]
config2.inMemoryIdentifier = "identifier2"
let inMemoryRealm2 = try await Realm(configuration: config2, downloadBeforeOpen: .always)
XCTAssertEqual(inMemoryRealm2.objects(SwiftPerson.self).count, 6)
}

@MainActor
func testStates() async throws {
let realm = try await openRealm()
Expand Down
4 changes: 2 additions & 2 deletions Realm/RLMRealmConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ typedef void(^RLMFlexibleSyncInitialSubscriptionsBlock)(RLMSyncSubscriptionSet *
@property (nonatomic, copy, nullable) NSURL *fileURL;

/// A string used to identify a particular in-memory Realm. Mutually exclusive with `fileURL`,
/// `seedFilePath`and `syncConfiguration`;
/// setting any one of the three properties will automatically nil out the other two.
/// `seedFilePath`.
/// setting an in-memory identifier will automatically nil out the other two.
@property (nonatomic, copy, nullable) NSString *inMemoryIdentifier;

/// A 64-byte key to use to encrypt the data, or `nil` if encryption is not enabled.
Expand Down
2 changes: 0 additions & 2 deletions Realm/RLMRealmConfiguration.mm
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ - (void)setInMemoryIdentifier:(NSString *)inMemoryIdentifier {
if (inMemoryIdentifier.length == 0) {
@throw RLMException(@"In-memory identifier must not be empty");
}
_config.sync_config = nullptr;
_seedFilePath = nil;

RLMNSStringToStdString(_config.path, [NSTemporaryDirectory() stringByAppendingPathComponent:inMemoryIdentifier]);
Expand Down Expand Up @@ -367,7 +366,6 @@ - (void)setSyncConfiguration:(RLMSyncConfiguration *)syncConfiguration {
}

NSAssert(user.identifier, @"Cannot call this method on a user that doesn't have an identifier.");
_config.in_memory = false;
_config.sync_config = std::make_shared<realm::SyncConfig>(syncConfiguration.rawConfiguration);
_config.path = syncConfiguration.path;

Expand Down
11 changes: 4 additions & 7 deletions RealmSwift/RealmConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ extension Realm {
/**
Creates a `Configuration` which can be used to create new `Realm` instances.
- note: The `fileURL`, `inMemoryIdentifier`, and `syncConfiguration` parameters are mutually exclusive. Only
- note: The `fileURL`, and `inMemoryIdentifier`, parameters are mutually exclusive. Only
set one of them, or none if you wish to use the default file URL.
Synced Realms will set a unique file path unless is an in-memory realm.
- parameter fileURL: The local URL to the Realm file.
- parameter inMemoryIdentifier: A string used to identify a particular in-memory Realm.
Expand Down Expand Up @@ -106,15 +107,13 @@ extension Realm {
// MARK: Configuration Properties

/**
A configuration value used to configure a Realm for synchronization with Atlas App Services. Mutually
exclusive with `inMemoryIdentifier`.
A configuration value used to configure a Realm for synchronization with Atlas App Services.
*/
public var syncConfiguration: SyncConfiguration? {
get {
return _syncConfiguration
}
set {
_inMemoryIdentifier = nil
_syncConfiguration = newValue
}
}
Expand All @@ -128,15 +127,13 @@ extension Realm {
}
}

/// A string used to identify a particular in-memory Realm. Mutually exclusive with `fileURL` and
/// `syncConfiguration`.
/// A string used to identify a particular in-memory Realm. Mutually exclusive with `fileURL`.
public var inMemoryIdentifier: String? {
get {
return _inMemoryIdentifier
}
set {
fileURL = nil
_syncConfiguration = nil
_inMemoryIdentifier = newValue
}
}
Expand Down

0 comments on commit 1ef89df

Please sign in to comment.