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

Port embedded object support to master #975

Merged
merged 14 commits into from
Oct 21, 2022
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,29 @@
* Added `realm.beginWriteAsync` which returns a `Future<Transaction>` that resolves when the write lock has been obtained.
* Added `realm.writeAsync` which opens an asynchronous transaction, invokes the provided callback, then commits the transaction asynchronously.
* Support `Realm.open` API to asynchronously open a local or synced Realm. When opening a synchronized Realm it will download all the content available at the time the operation began and then return a usable Realm. ([#731](https://github.com/realm/realm-dart/pull/731))
* Add 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 passing `ObjectType.embedded` to the `@RealmModel` annotation. 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. (Issue [#662](https://github.com/realm/realm-dart/issues/662))

```dart
@RealmModel()
class _Person {
late String name;

_Address? address;
}

// The generated `Address` class will be an embedded object.
@RealmModel(ObjectType.embedded)
class _Address {
late String street;
late String city;
}
```

### Fixed
* Added more validations when using `User.apiKeys` to return more meaningful errors when the user cannot perform API key actions - e.g. when the user has been logged in with API key credentials or when the user has been logged out. (Issue [#950](https://github.com/realm/realm-dart/issues/950))
* Fixed `dart run realm_dart generate` and `flutter pub run realm generate` commands to exit with the correct error code on failure.
* Added more descriptive error messages when passing objects managed by another Realm as arguments to `Realm.add/delete/deleteMany`. (PR [#942](https://github.com/realm/realm-dart/pull/942))
* Fixed a bug where `list.remove` would not correctly remove the value if the value is the first element in the list. (PR [#975](https://github.com/realm/realm-dart/pull/975))
nirinchev marked this conversation as resolved.
Show resolved Hide resolved

### Compatibility
* Realm Studio: 12.0.0 or later.
Expand Down
43 changes: 38 additions & 5 deletions common/lib/src/realm_common_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,45 @@
//
// //////////////////////////////////////////////////////////////////////////////

/// An enum controlling the base type for a [RealmModel].
///
/// {@category Annotations}
enum ObjectType {
/// A standalone top-level object that can be persisted in Realm. It can link
/// to other objects or collections of other objects.
realmObject('RealmObject', 0),

/// An object that can be embedded in other objects. It is considered owned
/// by its parent and will be deleted if its parent is deleted.
embeddedObject('EmbeddedObject', 1),

/// A special type of object used to facilitate unidirectional synchronization
/// with Atlas App Services. It is used to push data to Realm without the ability
/// to query or modify it.
_asymmetricObject('AsymmetricObject', 2);

const ObjectType([this._className = 'Unknown', this._flags = -1]);

final String _className;

final int _flags;
}

extension ObjectTypeInternal on ObjectType {
int get flags => _flags;

String get className => _className;
}

/// Annotation class used to define `Realm` data model classes and their properties
///
/// {@category Annotations}
class RealmModel {
const RealmModel();
/// The base type of the object
final ObjectType type;

/// Creates a new instance of [RealmModel] specifying the desired base type.
const RealmModel([this.type = ObjectType.realmObject]);
}

/// MapTo annotation for class member level.
Expand All @@ -36,7 +69,7 @@ class MapTo {
}

/// Indicates a primary key property.
///
///
/// It enables quick lookup of objects and enforces uniqueness of the values stored.
/// It may only be applied to a single property in a [RealmModel] class.
/// Only [String] and [int] can be used as primary keys.
Expand All @@ -47,8 +80,8 @@ class PrimaryKey {
const PrimaryKey();
}

/// Indicates an indexed property.
///
/// Indicates an indexed property.
///
/// Indexed properties slightly slow down insertions but can greatly speed up queries.
///
/// {@category Annotations}
Expand All @@ -57,7 +90,7 @@ class Indexed {
}

/// Indicates an ignored property.
///
///
/// Ignored properties will not be persisted in the `Realm`.
///
/// {@category Annotations}
Expand Down
10 changes: 8 additions & 2 deletions common/lib/src/realm_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,13 @@ class RealmStateError extends StateError implements RealmError {
class Decimal128 {} // TODO Support decimal128 datatype https://github.com/realm/realm-dart/issues/725

/// @nodoc
class RealmObjectMarker {}
class RealmObjectBaseMarker {}

/// @nodoc
class RealmObjectMarker extends RealmObjectBaseMarker {}

/// @nodoc
class EmbeddedObjectMarker extends RealmObjectBaseMarker {}

// Union type
/// @nodoc
Expand All @@ -107,7 +113,7 @@ class RealmAny {
const RealmAny.double(double d) : this._(d);
const RealmAny.uint8List(Uint8List data) : this._(data);
// TODO: RealmObjectMarker introduced to avoid dependency inversion. It would be better if we could use RealmObject directly. https://github.com/realm/realm-dart/issues/701
const RealmAny.realmObject(RealmObjectMarker o) : this._(o);
const RealmAny.realmObject(RealmObjectBaseMarker o) : this._(o);
const RealmAny.dateTime(DateTime timestamp) : this._(timestamp);
const RealmAny.objectId(ObjectId id) : this._(id);
const RealmAny.decimal128(Decimal128 decimal) : this._(decimal);
Expand Down
61 changes: 31 additions & 30 deletions example/bin/myapp.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading