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

Add support for embedded objects #2017

Merged
merged 14 commits into from
Sep 17, 2020
Merged

Add support for embedded objects #2017

merged 14 commits into from
Sep 17, 2020

Conversation

nirinchev
Copy link
Member

@nirinchev nirinchev commented Sep 8, 2020

Description

Adds support for embedded objects. Embedded objects are objects which are owned by a single parent object, and are deleted when that parent object is deleted or their parent no longer references them. Embedded objects are declared by subclassing EmbeddedObject instead of RealmObject. Reassigning an embedded object is not allowed and neither is linking to it from multiple parents. Querying for embedded objects directly is also disallowed as they should be viewed as complex structures belonging to their parents as opposed to standalone objects. A trivial example is:

public class Address : EmbeddedObject
{
    public string Street { get; set; }

    public string City { get; set; }
}

public class Person : RealmObject
{
    public string Name { get; set; }

    // Address is an embedded object - you reference it as usual
    public Address Address { get; set; }
}

public class Company : RealmObject
{
    public string PhoneNumber { get; set; }

    // Embedded objects can be contained in lists too
    public IList<Address> OfficeAddresses { get; }
}

Added new dynamic methods for instantiating embedded objects:

  • Realm.DynamicApi.CreateEmbeddedObjectForProperty should be used to create an embedded object and assign it to a parent's property. For example:

    // static API
    var person = new Person();
    person.Address = new Address
    {
        City = "New York"
    };
    
    // dynamic API
    var dynamicPerson = realm.DynamicApi.CreateObject("Person");
    var address = realm.DynamicApi.CreateEmbeddedObjectForProperty(dynamicPerson, "Address")
    address.City = "New York";
  • Realm.DynamicApi.AddEmbeddedObjectToList should be used to create an embedded object and add it to a parent's list property.

  • Realm.DynamicApi.InsertEmbeddedObjectInList should be used to create an embedded object and insert it in a parent's list property at a specified index.

  • Realm.DynamicApi.SetEmbeddedObjectInList should be used to create an embedded object and set it at an index in a parent's list property.

    // static API
    var company = new Company();
    company.OfficeAddresses.Add(new Address
    {
        City = "New York"
    });
    
    company.OfficeAddresses.Insert(0, new Address
    {
        City = "Palo Alto"
    });
    
    company.OfficeAddresses[1] = new Address
    {
        City = "New Jersey"
    };
    
    // dynamic API
    var dynamicCompany = realm.DynamicApi.CreateObject("Company");
    var officeToAdd = realm.DynamicApi.AddEmbeddedObjectToList(dynamicCompany.OfficeAddresses)  ;
    officeToAdd.City = "New York";
    
    var officeToInsert = realm.DynamicApi.InsertEmbeddedObjectInList(dynamicCompany.  OfficeAddresses, 0);
    officeToInsert.City = "Palo Alto";
    
    var officeToSet = realm.DynamicApi.SetEmbeddedObjectInList(dynamicCompany.  OfficeAddresses, 1);
    officeToSet.City = "New Jersey";

Fixes #1937

Breaking changes

This moves all the string-based/dynamic API from Realm to Realm.DynamicAPI. This is necessary because of the increased number of dynamic API which would unnecessarily pollute the interface for strongly typed access which is the primary use case.

TODO

  • Changelog entry
  • Test recursive objects
  • Implement lists of embedded objects
  • Test lists
  • Test dynamic API
  • Wire up EmbeddedObject.Parent (blocked on Expose a Obj::get_parent API realm-core#3898)
  • Test backlinks
  • Read embeddedness from object store schema

@@ -25,7 +25,7 @@ namespace Realms
/// </summary>
/// <example>
/// <code>
/// class Dog : RealmObject
/// class Dog : RealmObjectB
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??

REALM_EXPORT Object* list_add_embedded(List& list, NativeException::Marshallable& ex)
{
return handle_errors(ex, [&]() {
return new Object(list.get_realm(), list.add_embedded());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return new Object(list.get_realm(), list.add_embedded());
return new Object(list.get_realm(), list.get_object_schema(), list.add_embedded());

throw IndexOutOfRangeException("Insert into RealmList", list_ndx, count);
}

return new Object(list.get_realm(), list.insert_embedded(list_ndx));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

Base automatically changed from ni/decimal to v10 September 17, 2020 20:29
@nirinchev nirinchev marked this pull request as ready for review September 17, 2020 22:54
@nirinchev nirinchev merged commit 295ed0a into v10 Sep 17, 2020
@nirinchev nirinchev deleted the ni/embedded-objects branch September 17, 2020 22:55
nirinchev added a commit that referenced this pull request Oct 2, 2020
* Remove ISchemaSource

* Split the RealmObject hierarchy

* Pass embedded to native, start work on the weaver for embedded objects

* Wire more things

* Add list methods + recursive tests

* More tests

* Get more dynamic APIs working

* After rebase fixes

* Backlinks + more dynamic API

* oops

* Read embeddedness from disk

* add some preservation logic for xamarin.ios

* Fix dynamic methods for statically typed platforms

* Try to fix ios tests
nirinchev added a commit that referenced this pull request Oct 14, 2020
* Some preliminary cleanup

* Remove some stuff from cmakelists

* Get things building

* wip - migrate to column keys from property indices

* Fix remaining tests

* fix rebase issues

* Get all column keys in a single call

* Remove dependencies

* Reduce the number of objecthandle methods a little

* Use PrimitiveValue for some object methods

* Remove the manual tests

* build on vs 2019 nodes

* Add concrete methods for constructing a primitive value

* Refactor RealmObject to reduce the number of methods (#2013)

* Refactor RealmObject to reduce the number of methods

* more fixes

* some comments

* Use PrimitiveValue for queries too

* some after-rebase fixes

* Update to latest core and sync (#2031)

* Disable sync tests

* Use the CPH macs for building v10 (#2034)

* Use the CPH macs for building v10

* revert some restrictions

* Add decimal support (#2014)

* Add decimal support

* Add querying support for decimal

* Add changelog entry

* After rebase fixes

* Preserve the decimal128->decimal conversion operator

* try removing the objectid remainder

* Some *s and &s

* More &s

* Less &s

* CR comments

* Use the Bid128 directly in the union

* Explicitly define low and high

* return the array

* Add support for embedded objects (#2017)

* Remove ISchemaSource

* Split the RealmObject hierarchy

* Pass embedded to native, start work on the weaver for embedded objects

* Wire more things

* Add list methods + recursive tests

* More tests

* Get more dynamic APIs working

* After rebase fixes

* Backlinks + more dynamic API

* oops

* Read embeddedness from disk

* add some preservation logic for xamarin.ios

* Fix dynamic methods for statically typed platforms

* Try to fix ios tests

* Only allow x86 and x64 targets for simulator builds (#2037)

* Only allow x86 and x64 targets for simulator builds

* try with a different OS version

* Try #3

* RNET-176: Add support for ObjectId (#2035)

* Initial objectid support

* Tests + support for ObjectId PKs

* Fix some tests

* Try to preserve the find method

* Changelog

* add support for lists of decimals/objectids (#2038)

* V10 assorted improvements (#2039)

* Replace I1 with U1 for bools

* Revert to using property indices

(cherry picked from commit f00e79a7ebed995bfeb7b64914a593d34eb7ef91)

* Use latest OS

* Update Core/Sync and revert to an older OS

* checkout correct OS commit

* Add MDB Realm support (#2041)

* replace sync manager with app

* Start working on MDB Realm
- Expose App
- Expose AppConfiguration
- Move stuff from User to App
- Expose the new credentials
- Move Realm_OpenWithSync to SharedRealm
- Replace Uri with partition in SyncConfig

* wire up the network transport (without error handling)

* Add AppException class
Add App.EmailPasswordAuth
Add User.Profile

* Correct content encoding for the message body

* Try to get ci running

* Fix a compilation error

* Fix compile #2

* Add docs for Credentials

* Try using sh instead of readfile

* another try

* Try with a custom app

* ..

* .

* Test fixes

* Reenable session tests

* Reenable more tests

* Reenable more tests

* Try to get some sleep

* inline the sleep

* Try to cat the app_id instead of executing it 🤦‍♂️

* 🤞

* Add port to baas url

* Preserve some serializers

* Add user.customdata

* Fix tests

* Add User.Provider

* Use unencrypted metadata realm for tests

* Lock the stringbuilder

* More attempts to compact the Realm

* some docs + warning fixes

* Add more docs

* Fix some warnings

* Rework errors + add api key creation

* Add api key tests

* fix displayed sdk and platform versions

* Add function support

* Make the error code internal

* more function tests

* Add docs for functions

* More tests

* wip

* Add docs for remote  mongo client

* Add logs link to app exceptions

* Add v10 as package publishing branch

* Build the package as 10.0.0

* Clean up some things

* Clean up some json serialization code

* Some cleanup

* preserve object serializer

* Try to fix iOS tests

* Mount /tmp on docker builds for caching purposes

* Use dots for alpha builds

* Add linkCredentials (#2056)

* Clean up tests and ensure we delete everything we create (#2058)

* clean up tests and ensure we delete everything we create

* Try to fix linux tests

* Increase the dummy data size in release

* Download realm binaries to a random path (#2061)

* Add user identities (#2059)

* Add push client API + rename some things (#2063)

* Remove Realm Object Server references

* Fix up the changelog

* Implement MongoCollection APIs (#2068)

* Implement MongoCollection APIs

* Some test fixes

* More tests

* Final methods

* Update OS

* Fix tests with recursive embedded objects

* don't link MongoDB.Bson

* Update some error codes (#2070)

* add jwt and user profile tests (#2071)

* Add facebook test

* Reorder the arguments in UpdateOne and UpdateMany

* Add tests for user.customdata

* Update to latest Core/Sync (#2073)

* Update to latest Core/Sync

* Clean up changelog + update OS

* Make GetCustomData a method with generic arg

* Expose the http status code of AppException

* Fix compilation warnings

* Fix ConfirmUser calling the incorrect method
@dev-thinks
Copy link

@nirinchev The description over here is clearly explaining the usage of IList. I think this need to be transferred to the documentation as well. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants