Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assigning a mixed property with a collection should replace instead of merge #7809

Closed
sync-by-unito bot opened this issue Jun 13, 2024 · 4 comments · Fixed by #7810 or #7821
Closed

Assigning a mixed property with a collection should replace instead of merge #7809

sync-by-unito bot opened this issue Jun 13, 2024 · 4 comments · Fixed by #7810 or #7821
Assignees

Comments

@sync-by-unito
Copy link

sync-by-unito bot commented Jun 13, 2024

The current API for setting a mixed field in all SDKs should behave as a replace, even if the server is capable of merging lists. This is because SDKs only expose assignment operations - i.e. after:

foo.mixed = [1, 2, "abc"]

users would expect var bar = foo.mixed matches what they assigned to it, not something merged. We haven't designed an API that would allow merging, but if we did, it would look differently and be more explicit about the expected outcome - like:

var list = foo.mixed.getOrCreateList(); list.add([1, 2, "abc"]);

At the moment this test is failing

@MainActor func testAssignMixedListWithSamePrimaryKey() async throws {
        let realm1 = try await openRealm()
        let results1try await realm1.objects(SwiftTypesSyncObject.self).where { $0.stringCol == name }.subscribe()
 
        let realm2 = try await openRealm()
        let results2try await realm2.objects(SwiftTypesSyncObject.self).where { $0.stringCol == name }.subscribe()
 
        let primaryKey = ObjectId.generate()
 
        let object = SwiftTypesSyncObject(id: primaryKey)
        object.stringCol = name
        object.anyCol = AnyRealmValue.fromArray([.string("John")])
        try realm1.write {
            realm1.add(object)
        }
 
        let object2 = SwiftTypesSyncObject(id: primaryKey)
        object2.stringCol = name
        object2.anyCol = AnyRealmValue.fromArray([.string("Marie")])
        try realm2.write {
            realm2.add(object2)
        }
 
        try await realm1.syncSession?.wait(for: .upload)
        try await realm2.syncSession?.wait(for: .upload)
        try await realm1.syncSession?.wait(for: .download)
        try await realm2.syncSession?.wait(for: .download)
 
        XCTAssertEqual(results1.first?.anyCol.listValue?.count, 1)
        XCTAssertEqual(results2.first?.anyCol.listValue?.count, 1)
        XCTAssertEqual(results1.first?.anyCol.listValue?[0], results2.first?.anyCol.listValue?[0])
    }

Even though we clear the collection before assigning to it, this is because the clear instruction is not been sent to the server.

Copy link
Author

sync-by-unito bot commented Jun 13, 2024

➤ PM Bot commented:

Jira ticket: RCORE-2168

Copy link
Author

sync-by-unito bot commented Jun 13, 2024

➤ dianaafanador3 commented:

This branch https://github.com/realm/realm-core/tree/dp/clear-before-assign-collections-in-mixed fixes the issue but I don't know the implications of sending a clear instructions even if the collection is empty in other uses cases

Copy link
Author

sync-by-unito bot commented Jun 13, 2024

➤ danieltabacaru commented:

I find the title a bit misleading. What I think we want to do is the SDKs to clear the list before inserting the elements and core to replicate the clear instruction.

@nirinchev
Copy link
Member

Yeah, to clarify, the request here is that Core unconditionally replicates the clear instruction, even if the collection is empty. Then SDKs can implement the replace semantics for collections in mixed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants