From 30d7db8662807abc2af7051f0527e1df909a2f1e Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Thu, 14 Mar 2024 21:20:05 +0100 Subject: [PATCH] RDART-910: Add support for RealmObject.objectSchema (#1540) * Add support for RealmObject.objectSchema * Dont use properties * ditto * Remove accidentally committed file * Disable tests that rely on core schema notifications --- CHANGELOG.md | 3 + packages/realm/example/lib/main.realm.dart | 10 +- .../realm_dart/example/bin/myapp.realm.dart | 10 +- .../realm_dart/lib/src/configuration.dart | 28 +- .../realm_dart/lib/src/native/realm_core.dart | 89 +++-- packages/realm_dart/lib/src/realm_class.dart | 90 ++++- packages/realm_dart/lib/src/realm_object.dart | 58 ++- packages/realm_dart/src/realm-core | 2 +- .../realm_dart/test/backlinks_test.realm.dart | 10 +- .../realm_dart/test/dynamic_realm_test.dart | 345 +++++++++++++++++- .../test/dynamic_realm_test.realm.dart | 74 ++++ .../test/geospatial_test.realm.dart | 17 +- .../realm_dart/test/indexed_test.realm.dart | 16 +- packages/realm_dart/test/migration_test.dart | 8 +- .../realm_dart/test/migration_test.realm.dart | 26 +- .../realm_dart/test/realm_map_test.realm.dart | 15 +- .../realm_dart/test/realm_object_test.dart | 2 +- .../test/realm_object_test.realm.dart | 52 ++- .../realm_dart/test/realm_set_test.realm.dart | 10 +- .../test/realm_value_test.realm.dart | 16 +- packages/realm_dart/test/test.realm.dart | 152 ++++++-- .../lib/src/realm_model_info.dart | 5 +- .../test/good_test_data/all_types.expected | 18 +- .../another_mapto.expected_multi | 5 +- .../good_test_data/asymmetric_object.expected | 10 +- .../test/good_test_data/binary_type.expected | 5 +- .../embedded_annotations.expected | 11 +- .../good_test_data/embedded_objects.expected | 15 +- .../good_test_data/indexable_types.expected | 5 +- .../list_initialization.expected | 5 +- .../test/good_test_data/map.expected | 10 +- .../test/good_test_data/mapto.expected | 5 +- .../good_test_data/optional_argument.expected | 5 +- .../test/good_test_data/pinhole.expected | 5 +- .../test/good_test_data/primary_key.expected | 41 ++- .../test/good_test_data/realm_set.expected | 12 +- .../good_test_data/required_argument.expected | 5 +- ...uired_argument_with_default_value.expected | 5 +- .../user_defined_getter.expected | 5 +- 39 files changed, 1012 insertions(+), 193 deletions(-) create mode 100644 packages/realm_dart/test/dynamic_realm_test.realm.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 54b019f19..6d855664f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Realm.shutdown(); } ``` +* Removed `SchemaObject.properties` - instead, `SchemaObject` is now an iterable collection of `Property`. (Issue [#1449](https://github.com/realm/realm-dart/issues/1449)) * `SyncProgress.transferredBytes` and `SyncProgress.transferableBytes` have been consolidated into `SyncProgress.progressEstimate`. The values reported previously were incorrect and did not accurately represent bytes either. The new field better conveys the uncertainty around the progress being reported. With this release, we're reporting accurate estimates for upload progress, but estimating downloads is still unreliable. A future server and SDK release will add better estimations for download progress. (Issue [#1562](https://github.com/realm/realm-dart/issues/1562)) ### Enhancements @@ -104,6 +105,8 @@ ``` * Added `RealmValueType` enum that contains all the possible types that can be wrapped by a `RealmValue`. (PR [#1469](https://github.com/realm/realm-dart/pull/1469)) * Added support for accessing `Set` and `Map` types using the dynamic object API - `obj.dynamic.getSet/getMap`. (PR [#1533](https://github.com/realm/realm-dart/pull/1533)) +* Added `RealmObjectBase.objectSchema` that returns the schema for this object. In most cases, this would be the schema defined in the model, but in case the Realm is opened as dynamic (by providing an empty collection for schemaObjects in the config) or using `FlexibleSyncConfiguration`, it may change as the schema on disk changes. (Issue [#1449](https://github.com/realm/realm-dart/issues/1449)) +* Added `Realm.schemaChanges` that returns a stream of schema changes that can be listened to. Only dynamic and synchronized Realms will emit schema changes. (Issue [#1449](https://github.com/realm/realm-dart/issues/1449)) ### Fixed diff --git a/packages/realm/example/lib/main.realm.dart b/packages/realm/example/lib/main.realm.dart index dfecf73ff..c4891d8de 100644 --- a/packages/realm/example/lib/main.realm.dart +++ b/packages/realm/example/lib/main.realm.dart @@ -88,7 +88,7 @@ class Car extends _Car with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Car._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Car, 'Car', [ + return SchemaObject(ObjectType.realmObject, Car, 'Car', [ SchemaProperty('make', RealmPropertyType.string), SchemaProperty('model', RealmPropertyType.string, optional: true), SchemaProperty('kilometers', RealmPropertyType.int, optional: true), @@ -96,6 +96,9 @@ class Car extends _Car with RealmEntity, RealmObjectBase, RealmObject { optional: true, linkTarget: 'Person'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { @@ -158,9 +161,12 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('name', RealmPropertyType.string), SchemaProperty('age', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/example/bin/myapp.realm.dart b/packages/realm_dart/example/bin/myapp.realm.dart index f6681c65e..273a97422 100644 --- a/packages/realm_dart/example/bin/myapp.realm.dart +++ b/packages/realm_dart/example/bin/myapp.realm.dart @@ -88,7 +88,7 @@ class Car extends _Car with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Car._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Car, 'Car', [ + return SchemaObject(ObjectType.realmObject, Car, 'Car', [ SchemaProperty('make', RealmPropertyType.string), SchemaProperty('model', RealmPropertyType.string, optional: true), SchemaProperty('kilometers', RealmPropertyType.int, optional: true), @@ -96,6 +96,9 @@ class Car extends _Car with RealmEntity, RealmObjectBase, RealmObject { optional: true, linkTarget: 'Person'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { @@ -158,9 +161,12 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('name', RealmPropertyType.string), SchemaProperty('age', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/lib/src/configuration.dart b/packages/realm_dart/lib/src/configuration.dart index 1274c55a7..da92dd551 100644 --- a/packages/realm_dart/lib/src/configuration.dart +++ b/packages/realm_dart/lib/src/configuration.dart @@ -398,13 +398,12 @@ class InMemoryConfiguration extends Configuration { /// A collection of properties describing the underlying schema of a [RealmObjectBase]. /// /// {@category Configuration} -class SchemaObject { +class SchemaObject extends Iterable { + final List _properties; + /// Schema object type. final Type type; - /// Collection of the properties of this schema object. - final List properties; - /// Returns the name of this schema type. final String name; @@ -412,7 +411,18 @@ class SchemaObject { final ObjectType baseType; /// Creates schema instance with object type and collection of object's properties. - const SchemaObject(this.baseType, this.type, this.name, this.properties); + SchemaObject(this.baseType, this.type, this.name, Iterable properties) : _properties = List.from(properties); + + @override + Iterator get iterator => _properties.iterator; + + @override + int get length => _properties.length; + + SchemaProperty operator [](int index) => _properties[index]; + + @override + SchemaProperty elementAt(int index) => _properties.elementAt(index); } /// Describes the complete set of classes which may be stored in a `Realm` @@ -441,6 +451,14 @@ class RealmSchema extends Iterable { /// @nodoc extension SchemaObjectInternal on SchemaObject { bool get isGenericRealmObject => type == RealmObject || type == EmbeddedObject || type == RealmObjectBase; + + void add(SchemaProperty property) => _properties.add(property); +} + +extension RealmSchemaInternal on RealmSchema { + void add(SchemaObject obj) { + _schema.add(obj); + } } /// [ClientResetHandler] is triggered if the device and server cannot agree diff --git a/packages/realm_dart/lib/src/native/realm_core.dart b/packages/realm_dart/lib/src/native/realm_core.dart index 58ff892e7..730e2c6f6 100644 --- a/packages/realm_dart/lib/src/native/realm_core.dart +++ b/packages/realm_dart/lib/src/native/realm_core.dart @@ -161,8 +161,8 @@ class _RealmCore { for (var i = 0; i < classCount; i++) { final schemaObject = schema.elementAt(i); final classInfo = schemaClasses.elementAt(i).ref; - final propertiesCount = schemaObject.properties.length; - final computedCount = schemaObject.properties.where((p) => p.isComputed).length; + final propertiesCount = schemaObject.length; + final computedCount = schemaObject.where((p) => p.isComputed).length; final persistedCount = propertiesCount - computedCount; classInfo.name = schemaObject.name.toCharPtr(arena); @@ -175,7 +175,7 @@ class _RealmCore { final properties = arena(propertiesCount); for (var j = 0; j < propertiesCount; j++) { - final schemaProperty = schemaObject.properties[j]; + final schemaProperty = schemaObject[j]; final propInfo = properties.elementAt(j).ref; propInfo.name = schemaProperty.mapTo.toCharPtr(arena); propInfo.public_name = (schemaProperty.mapTo != schemaProperty.name ? schemaProperty.name : '').toCharPtr(arena); @@ -275,7 +275,7 @@ class _RealmCore { } else if (config is InMemoryConfiguration) { _realmLib.realm_config_set_in_memory(configHandle._pointer, true); } else if (config is FlexibleSyncConfiguration) { - _realmLib.realm_config_set_schema_mode(configHandle._pointer, realm_schema_mode.RLM_SCHEMA_MODE_ADDITIVE_EXPLICIT); + _realmLib.realm_config_set_schema_mode(configHandle._pointer, realm_schema_mode.RLM_SCHEMA_MODE_ADDITIVE_DISCOVERED); final syncConfigPtr = _realmLib.invokeGetPointer(() => _realmLib.realm_flx_sync_config_new(config.user.handle._pointer)); try { _realmLib.realm_sync_config_set_session_stop_policy(syncConfigPtr, config.sessionStopPolicy.index); @@ -321,9 +321,16 @@ class _RealmCore { _realmLib.realm_config_set_schema_mode(configHandle._pointer, realm_schema_mode.RLM_SCHEMA_MODE_ADDITIVE_EXPLICIT); _realmLib.realm_config_set_force_sync_history(configPtr, true); } + if (config.encryptionKey != null) { _realmLib.realm_config_set_encryption_key(configPtr, config.encryptionKey!.toUint8Ptr(arena), encryptionKeySize); } + + // For sync and for dynamic Realms, we need to have a complete view of the schema in Core. + if (config.schemaObjects.isEmpty || config is FlexibleSyncConfiguration) { + _realmLib.realm_config_set_schema_subset_mode(configHandle._pointer, realm_schema_subset_mode.RLM_SCHEMA_SUBSET_MODE_COMPLETE); + } + return configHandle; }); } @@ -948,38 +955,42 @@ class _RealmCore { } final primaryKey = classInfo.ref.primary_key.cast().toRealmDartString(treatEmptyAsNull: true); - return RealmObjectMetadata(schema, classInfo.ref.key, _getPropertyMetadata(realm, classInfo.ref.key, primaryKey)); + return RealmObjectMetadata(schema, classInfo.ref.key, _getPropertiesMetadata(realm, classInfo.ref.key, primaryKey, arena)); }); } - Map _getPropertyMetadata(Realm realm, int classKey, String? primaryKeyName) { + Map getPropertiesMetadata(Realm realm, int classKey, String? primaryKeyName) { return using((Arena arena) { - final propertyCountPtr = arena(); - _realmLib.invokeGetBool( - () => _realmLib.realm_get_property_keys(realm.handle._pointer, classKey, nullptr, 0, propertyCountPtr), "Error getting property count"); - - var propertyCount = propertyCountPtr.value; - final propertiesPtr = arena(propertyCount); - _realmLib.invokeGetBool(() => _realmLib.realm_get_class_properties(realm.handle._pointer, classKey, propertiesPtr, propertyCount, propertyCountPtr), - "Error getting class properties."); - - propertyCount = propertyCountPtr.value; - Map result = {}; - for (var i = 0; i < propertyCount; i++) { - final property = propertiesPtr.elementAt(i); - final propertyName = property.ref.name.cast().toRealmDartString()!; - final objectType = property.ref.link_target.cast().toRealmDartString(treatEmptyAsNull: true); - final linkOriginProperty = property.ref.link_origin_property_name.cast().toRealmDartString(treatEmptyAsNull: true); - final isNullable = property.ref.flags & realm_property_flags.RLM_PROPERTY_NULLABLE != 0; - final isPrimaryKey = propertyName == primaryKeyName; - final propertyMeta = RealmPropertyMetadata(property.ref.key, objectType, linkOriginProperty, RealmPropertyType.values.elementAt(property.ref.type), - isNullable, isPrimaryKey, RealmCollectionType.values.elementAt(property.ref.collection_type)); - result[propertyName] = propertyMeta; - } - return result; + return _getPropertiesMetadata(realm, classKey, primaryKeyName, arena); }); } + Map _getPropertiesMetadata(Realm realm, int classKey, String? primaryKeyName, Arena arena) { + final propertyCountPtr = arena(); + _realmLib.invokeGetBool( + () => _realmLib.realm_get_property_keys(realm.handle._pointer, classKey, nullptr, 0, propertyCountPtr), "Error getting property count"); + + var propertyCount = propertyCountPtr.value; + final propertiesPtr = arena(propertyCount); + _realmLib.invokeGetBool(() => _realmLib.realm_get_class_properties(realm.handle._pointer, classKey, propertiesPtr, propertyCount, propertyCountPtr), + "Error getting class properties."); + + propertyCount = propertyCountPtr.value; + Map result = {}; + for (var i = 0; i < propertyCount; i++) { + final property = propertiesPtr.elementAt(i); + final propertyName = property.ref.name.cast().toRealmDartString()!; + final objectType = property.ref.link_target.cast().toRealmDartString(treatEmptyAsNull: true); + final linkOriginProperty = property.ref.link_origin_property_name.cast().toRealmDartString(treatEmptyAsNull: true); + final isNullable = property.ref.flags & realm_property_flags.RLM_PROPERTY_NULLABLE != 0; + final isPrimaryKey = propertyName == primaryKeyName; + final propertyMeta = RealmPropertyMetadata(property.ref.key, objectType, linkOriginProperty, RealmPropertyType.values.elementAt(property.ref.type), + isNullable, isPrimaryKey, RealmCollectionType.values.elementAt(property.ref.collection_type)); + result[propertyName] = propertyMeta; + } + return result; + } + RealmObjectHandle createRealmObject(Realm realm, int classKey) { final realmPtr = _realmLib.invokeGetPointer(() => _realmLib.realm_object_create(realm.handle._pointer, classKey)); return RealmObjectHandle._(realmPtr, realm.handle); @@ -1757,6 +1768,15 @@ class _RealmCore { controller.onUserChanged(); } + static void schema_change_callback(Pointer userdata, Pointer data) { + final Realm realm = userdata.toObject(); + try { + realm.updateSchema(); + } catch (e) { + Realm.logger.log(RealmLogLevel.error, 'Failed to update Realm schema: $e'); + } + } + RealmNotificationTokenHandle subscribeResultsNotifications(RealmResults results, NotificationsController controller) { final pointer = _realmLib.invokeGetPointer(() => _realmLib.realm_results_add_notification_callback( results.handle._pointer, @@ -1817,6 +1837,13 @@ class _RealmCore { return UserNotificationTokenHandle._(notification_token); } + RealmCallbackTokenHandle subscribeForSchemaNotifications(Realm realm) { + final pointer = _realmLib.invokeGetPointer(() => _realmLib.realm_add_schema_changed_callback(realm.handle._pointer, + Pointer.fromFunction(schema_change_callback), realm.toPersistentHandle(), _realmLib.addresses.realm_dart_delete_persistent_handle)); + + return RealmCallbackTokenHandle._(pointer, realm.handle); + } + bool getObjectChangesIsDeleted(RealmObjectChangesHandle handle) { return _realmLib.realm_object_changes_is_deleted(handle._pointer); } @@ -3256,6 +3283,10 @@ class _RealmQueryHandle extends RootedHandleBase { _RealmQueryHandle._(Pointer pointer, RealmHandle root) : super(root, pointer, 256); } +class RealmCallbackTokenHandle extends RootedHandleBase { + RealmCallbackTokenHandle._(Pointer pointer, RealmHandle root) : super(root, pointer, 32); +} + class RealmNotificationTokenHandle extends RootedHandleBase { RealmNotificationTokenHandle._(Pointer pointer, RealmHandle root) : super(root, pointer, 32); } diff --git a/packages/realm_dart/lib/src/realm_class.dart b/packages/realm_dart/lib/src/realm_class.dart index dee780af9..d63294b60 100644 --- a/packages/realm_dart/lib/src/realm_class.dart +++ b/packages/realm_dart/lib/src/realm_class.dart @@ -109,6 +109,8 @@ class Realm implements Finalizable { late final RealmMetadata _metadata; late final RealmHandle _handle; final bool _isInMigration; + late final RealmCallbackTokenHandle? _schemaCallbackHandle; + final List> _schemaChangeListeners = []; /// An object encompassing this `Realm` instance's dynamic API. late final DynamicRealm dynamic = DynamicRealm._(this); @@ -130,6 +132,18 @@ class Realm implements Finalizable { Realm._(this.config, [RealmHandle? handle, this._isInMigration = false]) : _handle = handle ?? _openRealm(config) { _populateMetadata(); + + // The schema of a Realm file may change due to sync adding new properties/classes. We subscribe for notifications + // in order to update the managed schema instance in case this happens. The same is true for dynamic Realms. For + // local Realms with user-supplied schema, the schema on disk may still change, but Core doesn't report the updated + // schema, so even if we subscribe, we wouldn't be able to see the updates. + if (config is FlexibleSyncConfiguration || config.schemaObjects.isEmpty) { + // TODO: enable once https://github.com/realm/realm-core/issues/7426 is fixed. + // _schemaCallbackHandle = realmCore.subscribeForSchemaNotifications(this); + _schemaCallbackHandle = null; + } else { + _schemaCallbackHandle = null; + } } /// A method for asynchronously opening a [Realm]. @@ -387,6 +401,7 @@ class Realm implements Finalizable { return; } + _schemaCallbackHandle?.release(); realmCore.closeRealm(this); handle.release(); } @@ -596,6 +611,59 @@ class Realm implements Finalizable { Future refreshAsync() async { return realmCore.realmRefreshAsync(this); } + + /// Allows listening for schema changes on this Realm. Only dynamic and synchronized + /// Realms will emit schema change notifications. + /// + /// Returns a [Stream] of [RealmSchemaChanges] that can be listened to. + // TODO: this is private due to https://github.com/realm/realm-core/issues/7426. Once that is fixed, we can expose it. + Stream get _schemaChanges { + late StreamController controller; + controller = StreamController( + onListen: () => _schemaChangeListeners.add(controller), + onPause: () => _schemaChangeListeners.remove(controller), + onResume: () => _schemaChangeListeners.add(controller), + onCancel: () => _schemaChangeListeners.remove(controller), + sync: true); + return controller.stream; + } + + void _updateSchema() { + final newSchema = realmCore.readSchema(this); + for (final listener in _schemaChangeListeners) { + listener.add(RealmSchemaChanges._(schema, newSchema)); + } + + for (final schemaObject in newSchema) { + final existing = schema.firstWhereOrNull((s) => s.name == schemaObject.name); + if (existing == null) { + schema.add(schemaObject); + final meta = realmCore.getObjectMetadata(this, schemaObject); + metadata._add(meta); + } else if (schemaObject.length > existing.length) { + final existingMeta = metadata.getByName(schemaObject.name); + final propertyMeta = realmCore.getPropertiesMetadata(this, existingMeta.classKey, existingMeta.primaryKey); + for (final property in schemaObject) { + final existingProp = existing.firstWhereOrNull((e) => e.mapTo == property.mapTo); + if (existingProp == null) { + existing.add(property); + existingMeta[property.name] = propertyMeta[property.name]!; + } + } + } + } + } +} + +/// Describes the schema changes that occurred on a Realm +class RealmSchemaChanges { + /// The current schema, as returned by [Realm.schema]. + final RealmSchema currentSchema; + + /// The new schema that will be applied to the Realm as soon as the event handler completes. + final RealmSchema newSchema; + + RealmSchemaChanges._(this.currentSchema, this.newSchema); } /// Provides a scope to safely write data to a [Realm]. Can be created using [Realm.beginWrite] or @@ -790,6 +858,10 @@ extension RealmInternal on Realm { static void logMessageForTesting(Level logLevel, String message) { realmCore.logMessageForTesting(logLevel, message); } + + void updateSchema() { + _updateSchema(); + } } /// @nodoc @@ -881,13 +953,19 @@ class RealmMetadata { RealmMetadata._(Iterable objectMetadatas) { for (final metadata in objectMetadatas) { - if (!metadata.schema.isGenericRealmObject) { - _typeMap[metadata.schema.type] = metadata; - } else { - _stringMap[metadata.schema.name] = metadata; - } - _classKeyMap[metadata.classKey] = metadata; + _add(metadata); + } + } + + /// This is used when constructing the metadata, but also when the Realm schema + /// changes. + void _add(RealmObjectMetadata metadata) { + if (!metadata.schema.isGenericRealmObject) { + _typeMap[metadata.schema.type] = metadata; + } else { + _stringMap[metadata.schema.name] = metadata; } + _classKeyMap[metadata.classKey] = metadata; } RealmObjectMetadata getByType(Type type) { diff --git a/packages/realm_dart/lib/src/realm_object.dart b/packages/realm_dart/lib/src/realm_object.dart index 0ee26c800..6b0ed22c0 100644 --- a/packages/realm_dart/lib/src/realm_object.dart +++ b/packages/realm_dart/lib/src/realm_object.dart @@ -12,7 +12,6 @@ import 'list.dart'; import 'native/realm_core.dart'; import 'realm_class.dart'; import 'results.dart'; -import 'set.dart'; import 'map.dart'; typedef DartDynamic = dynamic; @@ -27,18 +26,15 @@ abstract class RealmAccessor { _defaultValues[T] = values; } - static Object? getDefaultValue(Type realmObjectType, String name) { + static (bool valueExists, Object? value) getDefaultValue(Type realmObjectType, String name) { final type = realmObjectType; - if (!_defaultValues.containsKey(type)) { - throw RealmException("Type $type not found."); - } - final values = _defaultValues[type]!; - if (values.containsKey(name)) { - return values[name]; + final values = _defaultValues[type]; + if (values != null && values.containsKey(name)) { + return (true, values[name]); } - return null; + return (false, null); } static Map? getDefaults(Type realmObjectType) { @@ -56,7 +52,12 @@ class RealmValuesAccessor implements RealmAccessor { @override Object? get(RealmObjectBase object, String name) { if (!_values.containsKey(name)) { - return RealmAccessor.getDefaultValue(object.runtimeType, name); + final (valueExists, value) = RealmAccessor.getDefaultValue(object.runtimeType, name); + if (!valueExists) { + throw RealmError("Property '$name' does not exist on object of type '${object.runtimeType}'"); + } + + return value; } return _values[name]; @@ -88,7 +89,7 @@ class RealmValuesAccessor implements RealmAccessor { class RealmObjectMetadata { final int classKey; final SchemaObject schema; - late final String? primaryKey = schema.properties.firstWhereOrNull((element) => element.primaryKey)?.mapTo; + late final String? primaryKey = schema.firstWhereOrNull((element) => element.primaryKey)?.mapTo; final Map _propertyKeys; @@ -99,11 +100,11 @@ class RealmObjectMetadata { RealmPropertyMetadata operator [](String propertyName) { var meta = _propertyKeys[propertyName]; if (meta == null) { - // We couldn't find a proeprty by the name supplied by the user - this may be because the _propertyKeys + // We couldn't find a property by the name supplied by the user - this may be because the _propertyKeys // map is keyed on the property names as they exist in the database while the user supplied the public // name (i.e. the name of the property in the model). Try and look up the property by the public name and // then try to re-fetch the property meta using the database name. - final publicName = schema.properties.firstWhereOrNull((e) => e.name == propertyName)?.mapTo; + final publicName = schema.firstWhereOrNull((e) => e.name == propertyName)?.mapTo; if (publicName != null && publicName != propertyName) { meta = _propertyKeys[publicName]; } @@ -111,9 +112,10 @@ class RealmObjectMetadata { return meta ?? (throw RealmException("Property $propertyName does not exist on class $_realmObjectTypeName")); } - // _propertyKeys[propertyName] ?? - // schema.properties.firstWhereOrNull((p) => p.name == propertyName) ?? - // (throw RealmException("Property $propertyName does not exist on class $_realmObjectTypeName")); + + void operator []=(String propertyName, RealmPropertyMetadata value) { + _propertyKeys[propertyName] = value; + } String? getPropertyName(int propertyKey) { for (final entry in _propertyKeys.entries) { @@ -125,6 +127,7 @@ class RealmObjectMetadata { } } +/// @nodoc class RealmPropertyMetadata { final int key; final RealmCollectionType collectionType; @@ -382,6 +385,16 @@ mixin RealmObjectBase on RealmEntity implements RealmObjectBaseMarker, Finalizab object._accessor.set(object, name, value, update: update); } + /// @nodoc + static SchemaObject? getSchema(RealmObjectBase object) { + final accessor = object.accessor; + if (accessor is RealmCoreAccessor) { + return accessor.metadata.schema; + } + + return null; + } + /// @nodoc static void registerFactory(T Function() factory) { // We register a factory for both the type itself, but also the nullable @@ -557,6 +570,9 @@ mixin RealmObjectBase on RealmEntity implements RealmObjectBaseMarker, Finalizab final handle = realmCore.getBacklinks(this, sourceMeta.classKey, sourceProperty.key); return RealmResultsInternal.create(handle, realm, sourceMeta); } + + /// Returns the schema for this object. + SchemaObject get objectSchema; } /// @nodoc @@ -733,10 +749,16 @@ class RealmObjectNotificationsController extends Noti } /// @nodoc -class _ConcreteRealmObject with RealmEntity, RealmObjectBase, RealmObject {} +class _ConcreteRealmObject with RealmEntity, RealmObjectBase, RealmObject { + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this)!; // _ConcreteRealmObject should only ever be created for managed objects +} /// @nodoc -class _ConcreteEmbeddedObject with RealmEntity, RealmObjectBase, EmbeddedObject {} +class _ConcreteEmbeddedObject with RealmEntity, RealmObjectBase, EmbeddedObject { + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this)!; // _ConcreteEmbeddedObject should only ever be created for managed objects +} // This is necessary whenever we need to pass T? as the type. Type _typeOf() => T; diff --git a/packages/realm_dart/src/realm-core b/packages/realm_dart/src/realm-core index 2bfd5e9ba..677c9c28e 160000 --- a/packages/realm_dart/src/realm-core +++ b/packages/realm_dart/src/realm-core @@ -1 +1 @@ -Subproject commit 2bfd5e9ba74ed2620657bf968d2931f6ceab6785 +Subproject commit 677c9c28e29b3a0899dc46b0054f2354cd47a0d1 diff --git a/packages/realm_dart/test/backlinks_test.realm.dart b/packages/realm_dart/test/backlinks_test.realm.dart index 67866f2a2..d5cec7339 100644 --- a/packages/realm_dart/test/backlinks_test.realm.dart +++ b/packages/realm_dart/test/backlinks_test.realm.dart @@ -108,7 +108,7 @@ class Source extends _Source with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Source._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Source, 'Source', [ + return SchemaObject(ObjectType.realmObject, Source, 'Source', [ SchemaProperty('name', RealmPropertyType.string), SchemaProperty('oneTarget', RealmPropertyType.object, mapTo: 'et mål', optional: true, linkTarget: 'Target'), @@ -120,6 +120,9 @@ class Source extends _Source with RealmEntity, RealmObjectBase, RealmObject { linkTarget: 'Target', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Target extends _Target with RealmEntity, RealmObjectBase, RealmObject { @@ -213,7 +216,7 @@ class Target extends _Target with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Target._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Target, 'Target', [ + return SchemaObject(ObjectType.realmObject, Target, 'Target', [ SchemaProperty('name', RealmPropertyType.string), SchemaProperty('source', RealmPropertyType.object, optional: true, linkTarget: 'Source'), @@ -227,4 +230,7 @@ class Target extends _Target with RealmEntity, RealmObjectBase, RealmObject { linkTarget: 'Source'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/test/dynamic_realm_test.dart b/packages/realm_dart/test/dynamic_realm_test.dart index b9f4fc769..c70b36163 100644 --- a/packages/realm_dart/test/dynamic_realm_test.dart +++ b/packages/realm_dart/test/dynamic_realm_test.dart @@ -3,24 +3,39 @@ // ignore_for_file: avoid_relative_lib_imports +import 'package:collection/collection.dart'; import 'dart:ffi'; import 'dart:typed_data'; - import 'package:test/test.dart' hide test, throws; import 'package:realm_dart/realm.dart'; import 'test.dart'; +part 'dynamic_realm_test.realm.dart'; + +@RealmModel() +@MapTo('Task') +class _Taskv2 { + @PrimaryKey() + @MapTo('_id') + late ObjectId id; + + late String description; +} + void main() { setupTests(); - _assertSchemaExists(Realm realm, SchemaObject expected) { - final foundSchema = realm.schema.singleWhere((e) => e.name == expected.name); - expect(foundSchema.properties.length, expected.properties.length); + void assertSchemaMatches(SchemaObject actual, SchemaObject expected) { + expect(actual.name, expected.name); + expect(actual.baseType, expected.baseType); + expect(actual.length, expected.length); - for (final prop in foundSchema.properties) { - final expectedProp = expected.properties.singleWhere((e) => e.mapTo == prop.name); - expect(prop.collectionType, expectedProp.collectionType); + for (final prop in actual) { + final expectedProp = expected.singleWhereOrNull((e) => e.name == prop.name || e.mapTo == prop.name); + expect(expectedProp, isNotNull, + reason: "Expected to find '${prop.name}' in schema '${actual.name}', but couldn't. Properties in schema: ${expected.map((e) => e.name).join(', ')}"); + expect(prop.collectionType, expectedProp!.collectionType); expect(prop.linkTarget, expectedProp.linkTarget); expect(prop.optional, expectedProp.optional); expect(prop.primaryKey, expectedProp.primaryKey); @@ -28,6 +43,11 @@ void main() { } } + void assertSchemaExists(Realm realm, SchemaObject expected) { + final foundSchema = realm.schema.singleWhere((e) => e.name == expected.name); + assertSchemaMatches(foundSchema, expected); + } + test('schema is read from disk', () { final config = Configuration.local([ Car.schema, @@ -42,23 +62,35 @@ void main() { RecursiveEmbedded3.schema ]); - getRealm(config).close(); + final staticRealm = getRealm(config); + + staticRealm.write(() { + staticRealm.add(ObjectWithEmbedded('abc', recursiveObject: RecursiveEmbedded1('embedded'))); + }); + + staticRealm.close(); final dynamicConfig = Configuration.local([]); final realm = getRealm(dynamicConfig); expect(realm.schema.length, 10); - _assertSchemaExists(realm, Car.schema); - _assertSchemaExists(realm, Dog.schema); - _assertSchemaExists(realm, Person.schema); - _assertSchemaExists(realm, AllTypes.schema); - _assertSchemaExists(realm, LinksClass.schema); - _assertSchemaExists(realm, ObjectWithEmbedded.schema); - _assertSchemaExists(realm, AllTypesEmbedded.schema); - _assertSchemaExists(realm, RecursiveEmbedded1.schema); - _assertSchemaExists(realm, RecursiveEmbedded2.schema); - _assertSchemaExists(realm, RecursiveEmbedded3.schema); + assertSchemaExists(realm, Car.schema); + assertSchemaExists(realm, Dog.schema); + assertSchemaExists(realm, Person.schema); + assertSchemaExists(realm, AllTypes.schema); + assertSchemaExists(realm, LinksClass.schema); + assertSchemaExists(realm, ObjectWithEmbedded.schema); + assertSchemaExists(realm, AllTypesEmbedded.schema); + assertSchemaExists(realm, RecursiveEmbedded1.schema); + assertSchemaExists(realm, RecursiveEmbedded2.schema); + assertSchemaExists(realm, RecursiveEmbedded3.schema); + + final obj = realm.dynamic.all(ObjectWithEmbedded.schema.name).single; + assertSchemaMatches(obj.objectSchema, ObjectWithEmbedded.schema); + + final embedded = obj.dynamic.get('recursiveObject')!; + assertSchemaMatches(embedded.objectSchema, RecursiveEmbedded1.schema); }); test('dynamic is always the same', () { @@ -525,6 +557,23 @@ void main() { expect(() => dynamicRealm.dynamic.find('i-dont-exist', 'i-dont-exist'), throws("Object type i-dont-exist not configured in the current Realm's schema")); }); + + test('all returns objects with schema', () { + final config = Configuration.local([Car.schema]); + final staticRealm = getRealm(config); + staticRealm.write(() { + staticRealm.add(Car('Honda')); + staticRealm.add(Car('Toyota')); + }); + + final realm = _getDynamicRealm(staticRealm); + final allCars = realm.dynamic.all(Car.schema.name); + expect(allCars, hasLength(2)); + + for (final car in allCars) { + assertSchemaMatches(car.objectSchema, Car.schema); + } + }); }); group('RealmObject.dynamic.get when isDynamic=$isDynamic', () { @@ -574,6 +623,7 @@ void main() { expect(obj2.dynamic.get('link'), obj1); expect(obj2.dynamic.get('link')?.dynamic.get('id'), uuid1); + assertSchemaMatches(obj2.dynamic.get('link')!.objectSchema, LinksClass.schema); dynamic dynamicObj1 = obj1; dynamic dynamicObj2 = obj2; @@ -581,6 +631,8 @@ void main() { expect(dynamicObj2.link, obj1); expect(dynamicObj2.link.id, uuid1); + + assertSchemaMatches(dynamicObj2.link.objectSchema, LinksClass.schema); }); test('fails with non-existent property', () { @@ -874,4 +926,261 @@ void main() { expect(dynamicObj2.list, [obj1, obj1]); expect(dynamicObj2.list[0].id, uuid1); }); + + test('Realm.schema is updated with a new class', () { + final v1Config = Configuration.local([ + Car.schema, + ]); + + final v1Realm = getRealm(v1Config); + v1Realm.close(); + + final dynamicRealm = getRealm(Configuration.local([])); + + expect(dynamicRealm.schema, hasLength(1)); + assertSchemaExists(dynamicRealm, Car.schema); + + final v2Config = Configuration.local([Car.schema, Person.schema]); + final v2Realm = getRealm(v2Config); + + v2Realm.write(() { + v2Realm.add(Person('Peter')); + }); + + expect(v2Realm.schema, hasLength(2)); + assertSchemaExists(v2Realm, Car.schema); + assertSchemaExists(v2Realm, Person.schema); + + dynamicRealm.refresh(); + expect(dynamicRealm.schema, hasLength(2)); + assertSchemaExists(dynamicRealm, Car.schema); + assertSchemaExists(dynamicRealm, Person.schema); + + final dynamicPeople = dynamicRealm.dynamic.all(Person.schema.name); + expect(dynamicPeople, hasLength(1)); + expect(dynamicPeople.single.dynamic.get('name'), 'Peter'); + + assertSchemaMatches(dynamicPeople.single.objectSchema, Person.schema); + }, skip: 'Requires https://github.com/realm/realm-core/issues/7426'); + + void updateLocalSchema(String realmPath, List newSchema) { + final config = Configuration.local(newSchema, path: realmPath); + + final realm = getRealm(config); + realm.close(); + } + + void assertSchemaChangeNotification( + RealmSchemaChanges event, List expectedCurrent, List expectedNew, List validationErrors) { + try { + expect(event.currentSchema, hasLength(expectedCurrent.length)); + expect(event.newSchema, hasLength(expectedNew.length)); + expect(event.currentSchema.map((e) => e.name), unorderedMatches(expectedCurrent.map((e) => e.name))); + expect(event.newSchema.map((e) => e.name), unorderedMatches(expectedNew.map((e) => e.name))); + } catch (e) { + validationErrors.add(e); + } + } + + test('Realm.schemaChanges is raised when the schema changes', () async { + final dynamicConfig = Configuration.local([]); + updateLocalSchema(dynamicConfig.path, [Car.schema]); + + final dynamicRealm = getRealm(dynamicConfig); + + final validationErrors = []; + var invocations = 0; + + // final sub = dynamicRealm.schemaChanges.listen((event) { + // invocations++; + // assertSchemaChangeNotification(event, [Car.schema], [Car.schema, Person.schema], validationErrors); + // }); + + // updateLocalSchema(dynamicConfig.path, [Car.schema, Person.schema]); + + // dynamicRealm.refresh(); + // expect(dynamicRealm.schema, hasLength(2)); + // expect(invocations, 1); + // expect(validationErrors, isEmpty); + + // await sub.cancel(); + }, skip: 'Requires https://github.com/realm/realm-core/issues/7426'); + + test('Realm.schemaChanges can be paused and resumed', () async { + final dynamicConfig = Configuration.local([]); + updateLocalSchema(dynamicConfig.path, [Car.schema]); + final dynamicRealm = getRealm(dynamicConfig); + + var invocations = 0; + final validationErrors = []; + // final sub = dynamicRealm.schemaChanges.listen((event) { + // invocations++; + + // if (invocations == 2) { + // assertSchemaChangeNotification(event, [Car.schema, Person.schema, Dog.schema], [Car.schema, Person.schema, Dog.schema, Team.schema], validationErrors); + // } + // }); + + // updateLocalSchema(dynamicConfig.path, [Car.schema, Person.schema]); + // dynamicRealm.refresh(); + + // expect(invocations, 1); + + // sub.pause(); + + // updateLocalSchema(dynamicConfig.path, [Car.schema, Person.schema, Dog.schema]); + + // // We paused the subscription, should not get a notification for this update + // dynamicRealm.refresh(); + // expect(invocations, 1); + + // sub.resume(); + + // updateLocalSchema(dynamicConfig.path, [Car.schema, Person.schema, Dog.schema, Team.schema]); + + // // We resumed the subscription, should get a notification for the latest update only + // dynamicRealm.refresh(); + // expect(invocations, 2); + // expect(validationErrors, isEmpty); + + // await sub.cancel(); + + // updateLocalSchema(dynamicConfig.path, [Car.schema, Person.schema, Dog.schema, Team.schema, RemappedClass.schema]); + + // // We canceled the subscription, should not get a notification + // dynamicRealm.refresh(); + // expect(invocations, 2); + }, skip: 'Requires https://github.com/realm/realm-core/issues/7426'); + + test("Realm.schemaChanges multiple subscribers", () async { + final dynamicConfig = Configuration.local([]); + updateLocalSchema(dynamicConfig.path, [Car.schema]); + + final dynamicRealm = getRealm(dynamicConfig); + + final validationErrors = []; + + var sub1Invocations = 0; + // final sub1 = dynamicRealm.schemaChanges.listen((event) { + // sub1Invocations++; + // assertSchemaChangeNotification(event, [Car.schema], [Car.schema, Person.schema], validationErrors); + // }); + + // var sub2Invocations = 0; + // final sub2 = dynamicRealm.schemaChanges.listen((event) { + // sub2Invocations++; + // }); + + // updateLocalSchema(dynamicConfig.path, [Car.schema, Person.schema]); + // dynamicRealm.refresh(); + + // expect(sub1Invocations, 1); + // expect(sub2Invocations, 1); + + // assertSchemaExists(dynamicRealm, Person.schema); + + // expect(validationErrors, isEmpty); + + // await sub1.cancel(); + // await sub2.cancel(); + }, skip: 'Requires https://github.com/realm/realm-core/issues/7426'); + + Realm openPausedSyncRealm(User user, List schemas) { + // Some tests validate that adding a property in the schema will update the Realm.schema collection + // It goes through sync, because that's the only way to add a property without triggering a migration. + // It is necessary to immediately stop the sync sessions to make sure those changes don't make it to the + // server, otherwise the schema for all tests will be adjusted, which may pollute the test run. + + final config = Configuration.flexibleSync(user, schemas); + + final realm = getRealm(config); + realm.syncSession.pause(); + + realm.subscriptions.update((mutableSubscriptions) { + for (final schema in schemas) { + mutableSubscriptions.add(realm.dynamic.all(schema.name)); + } + }); + + return realm; + } + + baasTest('Realm.schema is updated with a new property', (config) async { + final app = App(config); + final user = await getIntegrationUser(app); + + final v1Realm = openPausedSyncRealm(user, [Task.schema]); + v1Realm.syncSession.pause(); + + final v2Realm = openPausedSyncRealm(user, [Taskv2.schema]); + + final taskId = ObjectId(); + v2Realm.write(() { + v2Realm.add(Taskv2(taskId, 'lorem ipsum')); + }); + + expect(v2Realm.schema, hasLength(1)); + assertSchemaExists(v2Realm, Taskv2.schema); + + v1Realm.refresh(); + expect(v1Realm.schema, hasLength(1)); + assertSchemaExists(v1Realm, Taskv2.schema); + + final tasks = v1Realm.all(); + expect(tasks, hasLength(1)); + expect(tasks.single.id, taskId); + expect(tasks.single.dynamic.get('description'), 'lorem ipsum'); + + assertSchemaMatches(tasks.single.objectSchema, Taskv2.schema); + }, skip: 'Requires https://github.com/realm/realm-core/issues/7426'); + + baasTest('RealmObject.schema is updated with a new property', (config) async { + final app = App(config); + final user = await getIntegrationUser(app); + + final v1Realm = openPausedSyncRealm(user, [Task.schema]); + final task = v1Realm.write(() => v1Realm.add(Task(ObjectId()))); + assertSchemaMatches(task.objectSchema, Task.schema); + + final v2Realm = openPausedSyncRealm(user, [Taskv2.schema]); + + expect(v2Realm.schema, hasLength(1)); + assertSchemaExists(v2Realm, Taskv2.schema); + + v2Realm.write(() { + final v2Task = v2Realm.find(task.id)!; + v2Task.description = 'lorem ipsum'; + }); + + v1Realm.refresh(); + expect(v1Realm.schema, hasLength(1)); + assertSchemaExists(v1Realm, Taskv2.schema); + + assertSchemaMatches(task.objectSchema, Taskv2.schema); + expect(task.dynamic.get('description'), 'lorem ipsum'); + }, skip: 'Requires https://github.com/realm/realm-core/issues/7426'); + + baasTest('UnmanagedObject.schema is updated with a new property', (config) async { + final app = App(config); + final user = await getIntegrationUser(app); + + final v1Realm = openPausedSyncRealm(user, [Task.schema]); + + // Update the schema + openPausedSyncRealm(user, [Taskv2.schema]); + + final task = Task(ObjectId()); + expect(() => task.dynamic.get('description'), + throwsA(isA().having((p0) => p0.message, 'message', "Property 'description' does not exist on object of type 'Task'"))); + assertSchemaMatches(task.objectSchema, Task.schema); + + v1Realm.write(() { + v1Realm.add(task); + }); + + assertSchemaMatches(task.objectSchema, Taskv2.schema); + + // Schema was updated so description shouldn't throw now + expect(task.dynamic.get('description'), ''); + }, skip: 'Requires https://github.com/realm/realm-core/issues/7426'); } diff --git a/packages/realm_dart/test/dynamic_realm_test.realm.dart b/packages/realm_dart/test/dynamic_realm_test.realm.dart new file mode 100644 index 000000000..c65d84fc2 --- /dev/null +++ b/packages/realm_dart/test/dynamic_realm_test.realm.dart @@ -0,0 +1,74 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'dynamic_realm_test.dart'; + +// ************************************************************************** +// RealmObjectGenerator +// ************************************************************************** + +// ignore_for_file: type=lint +class Taskv2 extends _Taskv2 with RealmEntity, RealmObjectBase, RealmObject { + Taskv2( + ObjectId id, + String description, + ) { + RealmObjectBase.set(this, '_id', id); + RealmObjectBase.set(this, 'description', description); + } + + Taskv2._(); + + @override + ObjectId get id => RealmObjectBase.get(this, '_id') as ObjectId; + @override + set id(ObjectId value) => RealmObjectBase.set(this, '_id', value); + + @override + String get description => + RealmObjectBase.get(this, 'description') as String; + @override + set description(String value) => + RealmObjectBase.set(this, 'description', value); + + @override + Stream> get changes => + RealmObjectBase.getChanges(this); + + @override + Taskv2 freeze() => RealmObjectBase.freezeObject(this); + + EJsonValue toEJson() { + return { + '_id': id.toEJson(), + 'description': description.toEJson(), + }; + } + + static EJsonValue _toEJson(Taskv2 value) => value.toEJson(); + static Taskv2 _fromEJson(EJsonValue ejson) { + return switch (ejson) { + { + '_id': EJsonValue id, + 'description': EJsonValue description, + } => + Taskv2( + fromEJson(id), + fromEJson(description), + ), + _ => raiseInvalidEJson(ejson), + }; + } + + static final schema = () { + RealmObjectBase.registerFactory(Taskv2._); + register(_toEJson, _fromEJson); + return SchemaObject(ObjectType.realmObject, Taskv2, 'Task', [ + SchemaProperty('id', RealmPropertyType.objectid, + mapTo: '_id', primaryKey: true), + SchemaProperty('description', RealmPropertyType.string), + ]); + }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; +} diff --git a/packages/realm_dart/test/geospatial_test.realm.dart b/packages/realm_dart/test/geospatial_test.realm.dart index d5427ceb9..7757ff370 100644 --- a/packages/realm_dart/test/geospatial_test.realm.dart +++ b/packages/realm_dart/test/geospatial_test.realm.dart @@ -69,12 +69,15 @@ class Location extends _Location static final schema = () { RealmObjectBase.registerFactory(Location._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.embeddedObject, Location, 'Location', [ + return SchemaObject(ObjectType.embeddedObject, Location, 'Location', [ SchemaProperty('type', RealmPropertyType.string), SchemaProperty('coordinates', RealmPropertyType.double, collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Restaurant extends _Restaurant @@ -133,13 +136,15 @@ class Restaurant extends _Restaurant static final schema = () { RealmObjectBase.registerFactory(Restaurant._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.realmObject, Restaurant, 'Restaurant', [ + return SchemaObject(ObjectType.realmObject, Restaurant, 'Restaurant', [ SchemaProperty('name', RealmPropertyType.string, primaryKey: true), SchemaProperty('location', RealmPropertyType.object, optional: true, linkTarget: 'Location'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class LocationList extends _LocationList @@ -189,10 +194,12 @@ class LocationList extends _LocationList static final schema = () { RealmObjectBase.registerFactory(LocationList._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.realmObject, LocationList, 'LocationList', [ + return SchemaObject(ObjectType.realmObject, LocationList, 'LocationList', [ SchemaProperty('locations', RealmPropertyType.object, linkTarget: 'Location', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/test/indexed_test.realm.dart b/packages/realm_dart/test/indexed_test.realm.dart index 3de4917fd..783221c33 100644 --- a/packages/realm_dart/test/indexed_test.realm.dart +++ b/packages/realm_dart/test/indexed_test.realm.dart @@ -104,8 +104,7 @@ class WithIndexes extends _WithIndexes static final schema = () { RealmObjectBase.registerFactory(WithIndexes._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.realmObject, WithIndexes, 'WithIndexes', [ + return SchemaObject(ObjectType.realmObject, WithIndexes, 'WithIndexes', [ SchemaProperty('anInt', RealmPropertyType.int, indexType: RealmIndexType.regular), SchemaProperty('aBool', RealmPropertyType.bool, @@ -120,6 +119,9 @@ class WithIndexes extends _WithIndexes indexType: RealmIndexType.regular), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NoIndexes extends _NoIndexes @@ -219,7 +221,7 @@ class NoIndexes extends _NoIndexes static final schema = () { RealmObjectBase.registerFactory(NoIndexes._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, NoIndexes, 'NoIndexes', [ + return SchemaObject(ObjectType.realmObject, NoIndexes, 'NoIndexes', [ SchemaProperty('anInt', RealmPropertyType.int), SchemaProperty('aBool', RealmPropertyType.bool), SchemaProperty('string', RealmPropertyType.string), @@ -228,6 +230,9 @@ class NoIndexes extends _NoIndexes SchemaProperty('uuid', RealmPropertyType.uuid), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class ObjectWithFTSIndex extends _ObjectWithFTSIndex @@ -297,7 +302,7 @@ class ObjectWithFTSIndex extends _ObjectWithFTSIndex static final schema = () { RealmObjectBase.registerFactory(ObjectWithFTSIndex._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, ObjectWithFTSIndex, 'ObjectWithFTSIndex', [ SchemaProperty('title', RealmPropertyType.string), SchemaProperty('summary', RealmPropertyType.string, @@ -306,4 +311,7 @@ class ObjectWithFTSIndex extends _ObjectWithFTSIndex optional: true, indexType: RealmIndexType.fullText), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/test/migration_test.dart b/packages/realm_dart/test/migration_test.dart index 8154ccf2e..72179465c 100644 --- a/packages/realm_dart/test/migration_test.dart +++ b/packages/realm_dart/test/migration_test.dart @@ -379,12 +379,12 @@ void main() { v1Realm.close(); final v2Config = Configuration.local([MyObjectWithoutValue.schema], schemaVersion: 2, migrationCallback: (migration, oldSchemaVersion) { - expect(migration.oldRealm.schema.single.properties.length, 2); - expect(migration.newRealm.schema.single.properties.length, 1); + expect(migration.oldRealm.schema.single.length, 2); + expect(migration.newRealm.schema.single.length, 1); }); final v2Realm = getRealm(v2Config); - expect(v2Realm.schema.single.properties.length, 1); + expect(v2Realm.schema.single.length, 1); expect(v2Realm.all().single.name, 'name'); v2Realm.close(); @@ -392,7 +392,7 @@ void main() { final dynamicConfig = Configuration.local([], schemaVersion: 2); final dynamicRealm = getRealm(dynamicConfig); - expect(dynamicRealm.schema.single.properties.length, 1); + expect(dynamicRealm.schema.single.length, 1); expect(dynamicRealm.dynamic.all('MyObject').single.dynamic.get('name'), 'name'); }); diff --git a/packages/realm_dart/test/migration_test.realm.dart b/packages/realm_dart/test/migration_test.realm.dart index 5a073d939..9e087e83e 100644 --- a/packages/realm_dart/test/migration_test.realm.dart +++ b/packages/realm_dart/test/migration_test.realm.dart @@ -51,10 +51,13 @@ class PersonIntName extends _PersonIntName static final schema = () { RealmObjectBase.registerFactory(PersonIntName._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, PersonIntName, 'Person', [ + return SchemaObject(ObjectType.realmObject, PersonIntName, 'Person', [ SchemaProperty('name', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class StudentV1 extends _StudentV1 @@ -112,11 +115,14 @@ class StudentV1 extends _StudentV1 static final schema = () { RealmObjectBase.registerFactory(StudentV1._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, StudentV1, 'Student', [ + return SchemaObject(ObjectType.realmObject, StudentV1, 'Student', [ SchemaProperty('name', RealmPropertyType.string, primaryKey: true), SchemaProperty('yearOfBirth', RealmPropertyType.int, optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class MyObjectWithTypo extends _MyObjectWithTypo @@ -174,12 +180,14 @@ class MyObjectWithTypo extends _MyObjectWithTypo static final schema = () { RealmObjectBase.registerFactory(MyObjectWithTypo._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.realmObject, MyObjectWithTypo, 'MyObject', [ + return SchemaObject(ObjectType.realmObject, MyObjectWithTypo, 'MyObject', [ SchemaProperty('nmae', RealmPropertyType.string), SchemaProperty('vlaue', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class MyObjectWithoutTypo extends _MyObjectWithoutTypo @@ -237,12 +245,15 @@ class MyObjectWithoutTypo extends _MyObjectWithoutTypo static final schema = () { RealmObjectBase.registerFactory(MyObjectWithoutTypo._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, MyObjectWithoutTypo, 'MyObject', [ SchemaProperty('name', RealmPropertyType.string), SchemaProperty('value', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class MyObjectWithoutValue extends _MyObjectWithoutValue @@ -290,9 +301,12 @@ class MyObjectWithoutValue extends _MyObjectWithoutValue static final schema = () { RealmObjectBase.registerFactory(MyObjectWithoutValue._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, MyObjectWithoutValue, 'MyObject', [ SchemaProperty('name', RealmPropertyType.string), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/test/realm_map_test.realm.dart b/packages/realm_dart/test/realm_map_test.realm.dart index 1467abc05..81ed9dc79 100644 --- a/packages/realm_dart/test/realm_map_test.realm.dart +++ b/packages/realm_dart/test/realm_map_test.realm.dart @@ -60,11 +60,14 @@ class Car extends _Car with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Car._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Car, 'Car', [ + return SchemaObject(ObjectType.realmObject, Car, 'Car', [ SchemaProperty('make', RealmPropertyType.string, primaryKey: true), SchemaProperty('color', RealmPropertyType.string, optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class EmbeddedValue extends _EmbeddedValue @@ -111,11 +114,14 @@ class EmbeddedValue extends _EmbeddedValue static final schema = () { RealmObjectBase.registerFactory(EmbeddedValue._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.embeddedObject, EmbeddedValue, 'EmbeddedValue', [ SchemaProperty('intValue', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class TestRealmMaps extends _TestRealmMaps @@ -441,7 +447,7 @@ class TestRealmMaps extends _TestRealmMaps static final schema = () { RealmObjectBase.registerFactory(TestRealmMaps._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, TestRealmMaps, 'TestRealmMaps', [ SchemaProperty('key', RealmPropertyType.int, primaryKey: true), SchemaProperty('boolMap', RealmPropertyType.bool, @@ -492,4 +498,7 @@ class TestRealmMaps extends _TestRealmMaps optional: true, collectionType: RealmCollectionType.map), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/test/realm_object_test.dart b/packages/realm_dart/test/realm_object_test.dart index b0ee63789..be46bbf34 100644 --- a/packages/realm_dart/test/realm_object_test.dart +++ b/packages/realm_dart/test/realm_object_test.dart @@ -286,7 +286,7 @@ void main() { void testPrimaryKey(SchemaObject schema, T Function() createObject, K? key) { test("$T primary key: $key", () { - final pkProp = schema.properties.where((p) => p.primaryKey).single; + final pkProp = schema.where((p) => p.primaryKey).single; final realm = Realm(Configuration.local([schema])); final obj = realm.write(() { return realm.add(createObject()); diff --git a/packages/realm_dart/test/realm_object_test.realm.dart b/packages/realm_dart/test/realm_object_test.realm.dart index 1a5d90c55..a04188cfd 100644 --- a/packages/realm_dart/test/realm_object_test.realm.dart +++ b/packages/realm_dart/test/realm_object_test.realm.dart @@ -52,11 +52,14 @@ class ObjectIdPrimaryKey extends _ObjectIdPrimaryKey static final schema = () { RealmObjectBase.registerFactory(ObjectIdPrimaryKey._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, ObjectIdPrimaryKey, 'ObjectIdPrimaryKey', [ SchemaProperty('id', RealmPropertyType.objectid, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableObjectIdPrimaryKey extends _NullableObjectIdPrimaryKey @@ -105,12 +108,15 @@ class NullableObjectIdPrimaryKey extends _NullableObjectIdPrimaryKey static final schema = () { RealmObjectBase.registerFactory(NullableObjectIdPrimaryKey._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, - NullableObjectIdPrimaryKey, 'NullableObjectIdPrimaryKey', [ + return SchemaObject(ObjectType.realmObject, NullableObjectIdPrimaryKey, + 'NullableObjectIdPrimaryKey', [ SchemaProperty('id', RealmPropertyType.objectid, optional: true, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class IntPrimaryKey extends _IntPrimaryKey @@ -157,11 +163,14 @@ class IntPrimaryKey extends _IntPrimaryKey static final schema = () { RealmObjectBase.registerFactory(IntPrimaryKey._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, IntPrimaryKey, 'IntPrimaryKey', [ SchemaProperty('id', RealmPropertyType.int, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableIntPrimaryKey extends _NullableIntPrimaryKey @@ -209,12 +218,15 @@ class NullableIntPrimaryKey extends _NullableIntPrimaryKey static final schema = () { RealmObjectBase.registerFactory(NullableIntPrimaryKey._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, NullableIntPrimaryKey, + return SchemaObject(ObjectType.realmObject, NullableIntPrimaryKey, 'NullableIntPrimaryKey', [ SchemaProperty('id', RealmPropertyType.int, optional: true, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class StringPrimaryKey extends _StringPrimaryKey @@ -262,11 +274,14 @@ class StringPrimaryKey extends _StringPrimaryKey static final schema = () { RealmObjectBase.registerFactory(StringPrimaryKey._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, StringPrimaryKey, 'StringPrimaryKey', [ SchemaProperty('id', RealmPropertyType.string, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableStringPrimaryKey extends _NullableStringPrimaryKey @@ -314,12 +329,15 @@ class NullableStringPrimaryKey extends _NullableStringPrimaryKey static final schema = () { RealmObjectBase.registerFactory(NullableStringPrimaryKey._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, NullableStringPrimaryKey, + return SchemaObject(ObjectType.realmObject, NullableStringPrimaryKey, 'NullableStringPrimaryKey', [ SchemaProperty('id', RealmPropertyType.string, optional: true, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class UuidPrimaryKey extends _UuidPrimaryKey @@ -366,11 +384,14 @@ class UuidPrimaryKey extends _UuidPrimaryKey static final schema = () { RealmObjectBase.registerFactory(UuidPrimaryKey._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, UuidPrimaryKey, 'UuidPrimaryKey', [ SchemaProperty('id', RealmPropertyType.uuid, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableUuidPrimaryKey extends _NullableUuidPrimaryKey @@ -418,12 +439,15 @@ class NullableUuidPrimaryKey extends _NullableUuidPrimaryKey static final schema = () { RealmObjectBase.registerFactory(NullableUuidPrimaryKey._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, NullableUuidPrimaryKey, + return SchemaObject(ObjectType.realmObject, NullableUuidPrimaryKey, 'NullableUuidPrimaryKey', [ SchemaProperty('id', RealmPropertyType.uuid, optional: true, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class RemappedFromAnotherFile extends _RemappedFromAnotherFile @@ -474,7 +498,7 @@ class RemappedFromAnotherFile extends _RemappedFromAnotherFile static final schema = () { RealmObjectBase.registerFactory(RemappedFromAnotherFile._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, RemappedFromAnotherFile, 'class with spaces', [ SchemaProperty('linkToAnotherClass', RealmPropertyType.object, mapTo: 'property with spaces', @@ -482,6 +506,9 @@ class RemappedFromAnotherFile extends _RemappedFromAnotherFile linkTarget: 'myRemappedClass'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class BoolValue extends _BoolValue @@ -538,9 +565,12 @@ class BoolValue extends _BoolValue static final schema = () { RealmObjectBase.registerFactory(BoolValue._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, BoolValue, 'BoolValue', [ + return SchemaObject(ObjectType.realmObject, BoolValue, 'BoolValue', [ SchemaProperty('key', RealmPropertyType.int, primaryKey: true), SchemaProperty('value', RealmPropertyType.bool), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/test/realm_set_test.realm.dart b/packages/realm_dart/test/realm_set_test.realm.dart index 6f9c2f276..d8c5df19c 100644 --- a/packages/realm_dart/test/realm_set_test.realm.dart +++ b/packages/realm_dart/test/realm_set_test.realm.dart @@ -60,11 +60,14 @@ class Car extends _Car with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Car._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Car, 'Car', [ + return SchemaObject(ObjectType.realmObject, Car, 'Car', [ SchemaProperty('make', RealmPropertyType.string, primaryKey: true), SchemaProperty('color', RealmPropertyType.string, optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class TestRealmSets extends _TestRealmSets @@ -348,7 +351,7 @@ class TestRealmSets extends _TestRealmSets static final schema = () { RealmObjectBase.registerFactory(TestRealmSets._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, TestRealmSets, 'TestRealmSets', [ SchemaProperty('key', RealmPropertyType.int, primaryKey: true), SchemaProperty('boolSet', RealmPropertyType.bool, @@ -389,4 +392,7 @@ class TestRealmSets extends _TestRealmSets optional: true, collectionType: RealmCollectionType.set), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/test/realm_value_test.realm.dart b/packages/realm_dart/test/realm_value_test.realm.dart index 251d68277..f14cdabd4 100644 --- a/packages/realm_dart/test/realm_value_test.realm.dart +++ b/packages/realm_dart/test/realm_value_test.realm.dart @@ -58,10 +58,13 @@ class TuckedIn extends _TuckedIn static final schema = () { RealmObjectBase.registerFactory(TuckedIn._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.embeddedObject, TuckedIn, 'TuckedIn', [ + return SchemaObject(ObjectType.embeddedObject, TuckedIn, 'TuckedIn', [ SchemaProperty('x', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class AnythingGoes extends _AnythingGoes @@ -149,8 +152,7 @@ class AnythingGoes extends _AnythingGoes static final schema = () { RealmObjectBase.registerFactory(AnythingGoes._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.realmObject, AnythingGoes, 'AnythingGoes', [ + return SchemaObject(ObjectType.realmObject, AnythingGoes, 'AnythingGoes', [ SchemaProperty('oneAny', RealmPropertyType.mixed, optional: true, indexType: RealmIndexType.regular), SchemaProperty('manyAny', RealmPropertyType.mixed, @@ -161,6 +163,9 @@ class AnythingGoes extends _AnythingGoes optional: true, collectionType: RealmCollectionType.set), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Stuff extends _Stuff with RealmEntity, RealmObjectBase, RealmObject { @@ -213,8 +218,11 @@ class Stuff extends _Stuff with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Stuff._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Stuff, 'Stuff', [ + return SchemaObject(ObjectType.realmObject, Stuff, 'Stuff', [ SchemaProperty('i', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_dart/test/test.realm.dart b/packages/realm_dart/test/test.realm.dart index 628dd54d6..468443eb0 100644 --- a/packages/realm_dart/test/test.realm.dart +++ b/packages/realm_dart/test/test.realm.dart @@ -50,10 +50,13 @@ class Car extends _Car with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Car._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Car, 'Car', [ + return SchemaObject(ObjectType.realmObject, Car, 'Car', [ SchemaProperty('make', RealmPropertyType.string, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { @@ -99,10 +102,13 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('name', RealmPropertyType.string), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Dog extends _Dog with RealmEntity, RealmObjectBase, RealmObject { @@ -169,13 +175,16 @@ class Dog extends _Dog with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Dog._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Dog, 'Dog', [ + return SchemaObject(ObjectType.realmObject, Dog, 'Dog', [ SchemaProperty('name', RealmPropertyType.string, primaryKey: true), SchemaProperty('age', RealmPropertyType.int, optional: true), SchemaProperty('owner', RealmPropertyType.object, optional: true, linkTarget: 'Person'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Team extends _Team with RealmEntity, RealmObjectBase, RealmObject { @@ -246,7 +255,7 @@ class Team extends _Team with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Team._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Team, 'Team', [ + return SchemaObject(ObjectType.realmObject, Team, 'Team', [ SchemaProperty('name', RealmPropertyType.string), SchemaProperty('players', RealmPropertyType.object, linkTarget: 'Person', collectionType: RealmCollectionType.list), @@ -254,6 +263,9 @@ class Team extends _Team with RealmEntity, RealmObjectBase, RealmObject { collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Student extends _Student with RealmEntity, RealmObjectBase, RealmObject { @@ -331,7 +343,7 @@ class Student extends _Student with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Student._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Student, 'Student', [ + return SchemaObject(ObjectType.realmObject, Student, 'Student', [ SchemaProperty('number', RealmPropertyType.int, primaryKey: true), SchemaProperty('name', RealmPropertyType.string, optional: true), SchemaProperty('yearOfBirth', RealmPropertyType.int, optional: true), @@ -339,6 +351,9 @@ class Student extends _Student with RealmEntity, RealmObjectBase, RealmObject { optional: true, linkTarget: 'School'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class School extends _School with RealmEntity, RealmObjectBase, RealmObject { @@ -432,7 +447,7 @@ class School extends _School with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(School._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, School, 'School', [ + return SchemaObject(ObjectType.realmObject, School, 'School', [ SchemaProperty('name', RealmPropertyType.string, primaryKey: true), SchemaProperty('city', RealmPropertyType.string, optional: true), SchemaProperty('students', RealmPropertyType.object, @@ -443,6 +458,9 @@ class School extends _School with RealmEntity, RealmObjectBase, RealmObject { linkTarget: 'School', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class RemappedClass extends $RemappedClass @@ -505,7 +523,7 @@ class RemappedClass extends $RemappedClass static final schema = () { RealmObjectBase.registerFactory(RemappedClass._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, RemappedClass, 'myRemappedClass', [ SchemaProperty('remappedProperty', RealmPropertyType.string, mapTo: 'primitive_property'), @@ -515,6 +533,9 @@ class RemappedClass extends $RemappedClass collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Task extends _Task with RealmEntity, RealmObjectBase, RealmObject { @@ -560,11 +581,14 @@ class Task extends _Task with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Task._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Task, 'Task', [ + return SchemaObject(ObjectType.realmObject, Task, 'Task', [ SchemaProperty('id', RealmPropertyType.objectid, mapTo: '_id', primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Product extends _Product with RealmEntity, RealmObjectBase, RealmObject { @@ -622,13 +646,16 @@ class Product extends _Product with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Product._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Product, 'Product', [ + return SchemaObject(ObjectType.realmObject, Product, 'Product', [ SchemaProperty('id', RealmPropertyType.objectid, mapTo: '_id', primaryKey: true), SchemaProperty('name', RealmPropertyType.string, mapTo: 'stringQueryField'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Schedule extends _Schedule @@ -687,13 +714,16 @@ class Schedule extends _Schedule static final schema = () { RealmObjectBase.registerFactory(Schedule._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Schedule, 'Schedule', [ + return SchemaObject(ObjectType.realmObject, Schedule, 'Schedule', [ SchemaProperty('id', RealmPropertyType.objectid, mapTo: '_id', primaryKey: true), SchemaProperty('tasks', RealmPropertyType.object, linkTarget: 'Task', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Foo extends _Foo with RealmEntity, RealmObjectBase, RealmObject { @@ -753,12 +783,15 @@ class Foo extends _Foo with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Foo._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Foo, 'Foo', [ + return SchemaObject(ObjectType.realmObject, Foo, 'Foo', [ SchemaProperty('requiredBinaryProp', RealmPropertyType.binary), SchemaProperty('nullableBinaryProp', RealmPropertyType.binary, optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class AllTypes extends _AllTypes @@ -1005,7 +1038,7 @@ class AllTypes extends _AllTypes static final schema = () { RealmObjectBase.registerFactory(AllTypes._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, AllTypes, 'AllTypes', [ + return SchemaObject(ObjectType.realmObject, AllTypes, 'AllTypes', [ SchemaProperty('stringProp', RealmPropertyType.string), SchemaProperty('boolProp', RealmPropertyType.bool), SchemaProperty('dateProp', RealmPropertyType.timestamp), @@ -1034,6 +1067,9 @@ class AllTypes extends _AllTypes optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class LinksClass extends _LinksClass @@ -1131,8 +1167,7 @@ class LinksClass extends _LinksClass static final schema = () { RealmObjectBase.registerFactory(LinksClass._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.realmObject, LinksClass, 'LinksClass', [ + return SchemaObject(ObjectType.realmObject, LinksClass, 'LinksClass', [ SchemaProperty('id', RealmPropertyType.uuid, primaryKey: true), SchemaProperty('link', RealmPropertyType.object, optional: true, linkTarget: 'LinksClass'), @@ -1146,6 +1181,9 @@ class LinksClass extends _LinksClass collectionType: RealmCollectionType.map), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class AllCollections extends _AllCollections @@ -1821,7 +1859,7 @@ class AllCollections extends _AllCollections static final schema = () { RealmObjectBase.registerFactory(AllCollections._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, AllCollections, 'AllCollections', [ SchemaProperty('stringList', RealmPropertyType.string, collectionType: RealmCollectionType.list), @@ -1921,6 +1959,9 @@ class AllCollections extends _AllCollections optional: true, collectionType: RealmCollectionType.map), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableTypes extends _NullableTypes @@ -2068,7 +2109,7 @@ class NullableTypes extends _NullableTypes static final schema = () { RealmObjectBase.registerFactory(NullableTypes._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, NullableTypes, 'NullableTypes', [ SchemaProperty('id', RealmPropertyType.objectid, mapTo: '_id', primaryKey: true), @@ -2085,6 +2126,9 @@ class NullableTypes extends _NullableTypes optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Event extends _Event with RealmEntity, RealmObjectBase, RealmObject { @@ -2178,7 +2222,7 @@ class Event extends _Event with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Event._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Event, 'Event', [ + return SchemaObject(ObjectType.realmObject, Event, 'Event', [ SchemaProperty('id', RealmPropertyType.objectid, mapTo: '_id', primaryKey: true), SchemaProperty('name', RealmPropertyType.string, @@ -2190,6 +2234,9 @@ class Event extends _Event with RealmEntity, RealmObjectBase, RealmObject { SchemaProperty('assignedTo', RealmPropertyType.string, optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Party extends _Party with RealmEntity, RealmObjectBase, RealmObject { @@ -2269,7 +2316,7 @@ class Party extends _Party with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Party._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Party, 'Party', [ + return SchemaObject(ObjectType.realmObject, Party, 'Party', [ SchemaProperty('host', RealmPropertyType.object, optional: true, linkTarget: 'Friend'), SchemaProperty('year', RealmPropertyType.int), @@ -2279,6 +2326,9 @@ class Party extends _Party with RealmEntity, RealmObjectBase, RealmObject { optional: true, linkTarget: 'Party'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Friend extends _Friend with RealmEntity, RealmObjectBase, RealmObject { @@ -2366,7 +2416,7 @@ class Friend extends _Friend with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Friend._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Friend, 'Friend', [ + return SchemaObject(ObjectType.realmObject, Friend, 'Friend', [ SchemaProperty('name', RealmPropertyType.string, primaryKey: true), SchemaProperty('age', RealmPropertyType.int), SchemaProperty('bestFriend', RealmPropertyType.object, @@ -2375,6 +2425,9 @@ class Friend extends _Friend with RealmEntity, RealmObjectBase, RealmObject { linkTarget: 'Friend', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class When extends _When with RealmEntity, RealmObjectBase, RealmObject { @@ -2434,11 +2487,14 @@ class When extends _When with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(When._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, When, 'When', [ + return SchemaObject(ObjectType.realmObject, When, 'When', [ SchemaProperty('dateTimeUtc', RealmPropertyType.timestamp), SchemaProperty('locationName', RealmPropertyType.string), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Player extends _Player with RealmEntity, RealmObjectBase, RealmObject { @@ -2507,7 +2563,7 @@ class Player extends _Player with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Player._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Player, 'Player', [ + return SchemaObject(ObjectType.realmObject, Player, 'Player', [ SchemaProperty('name', RealmPropertyType.string, primaryKey: true), SchemaProperty('game', RealmPropertyType.object, optional: true, linkTarget: 'Game'), @@ -2515,6 +2571,9 @@ class Player extends _Player with RealmEntity, RealmObjectBase, RealmObject { optional: true, collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Game extends _Game with RealmEntity, RealmObjectBase, RealmObject { @@ -2563,11 +2622,14 @@ class Game extends _Game with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Game._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Game, 'Game', [ + return SchemaObject(ObjectType.realmObject, Game, 'Game', [ SchemaProperty('winnerByRound', RealmPropertyType.object, linkTarget: 'Player', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class AllTypesEmbedded extends _AllTypesEmbedded @@ -2892,7 +2954,7 @@ class AllTypesEmbedded extends _AllTypesEmbedded static final schema = () { RealmObjectBase.registerFactory(AllTypesEmbedded._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.embeddedObject, AllTypesEmbedded, 'AllTypesEmbedded', [ SchemaProperty('stringProp', RealmPropertyType.string), SchemaProperty('boolProp', RealmPropertyType.bool), @@ -2935,6 +2997,9 @@ class AllTypesEmbedded extends _AllTypesEmbedded collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class ObjectWithEmbedded extends _ObjectWithEmbedded @@ -3048,7 +3113,7 @@ class ObjectWithEmbedded extends _ObjectWithEmbedded static final schema = () { RealmObjectBase.registerFactory(ObjectWithEmbedded._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, ObjectWithEmbedded, 'ObjectWithEmbedded', [ SchemaProperty('id', RealmPropertyType.string, mapTo: '_id', primaryKey: true), @@ -3065,6 +3130,9 @@ class ObjectWithEmbedded extends _ObjectWithEmbedded collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class RecursiveEmbedded1 extends _RecursiveEmbedded1 @@ -3152,7 +3220,7 @@ class RecursiveEmbedded1 extends _RecursiveEmbedded1 static final schema = () { RealmObjectBase.registerFactory(RecursiveEmbedded1._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.embeddedObject, RecursiveEmbedded1, 'RecursiveEmbedded1', [ SchemaProperty('value', RealmPropertyType.string), SchemaProperty('child', RealmPropertyType.object, @@ -3164,6 +3232,9 @@ class RecursiveEmbedded1 extends _RecursiveEmbedded1 optional: true, linkTarget: 'ObjectWithEmbedded'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class RecursiveEmbedded2 extends _RecursiveEmbedded2 @@ -3251,7 +3322,7 @@ class RecursiveEmbedded2 extends _RecursiveEmbedded2 static final schema = () { RealmObjectBase.registerFactory(RecursiveEmbedded2._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.embeddedObject, RecursiveEmbedded2, 'RecursiveEmbedded2', [ SchemaProperty('value', RealmPropertyType.string), SchemaProperty('child', RealmPropertyType.object, @@ -3263,6 +3334,9 @@ class RecursiveEmbedded2 extends _RecursiveEmbedded2 optional: true, linkTarget: 'ObjectWithEmbedded'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class RecursiveEmbedded3 extends _RecursiveEmbedded3 @@ -3310,11 +3384,14 @@ class RecursiveEmbedded3 extends _RecursiveEmbedded3 static final schema = () { RealmObjectBase.registerFactory(RecursiveEmbedded3._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.embeddedObject, RecursiveEmbedded3, 'RecursiveEmbedded3', [ SchemaProperty('value', RealmPropertyType.string), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class ObjectWithDecimal extends _ObjectWithDecimal @@ -3375,13 +3452,16 @@ class ObjectWithDecimal extends _ObjectWithDecimal static final schema = () { RealmObjectBase.registerFactory(ObjectWithDecimal._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, ObjectWithDecimal, 'ObjectWithDecimal', [ SchemaProperty('decimal', RealmPropertyType.decimal128), SchemaProperty('nullableDecimal', RealmPropertyType.decimal128, optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Asymmetric extends _Asymmetric @@ -3454,8 +3534,7 @@ class Asymmetric extends _Asymmetric static final schema = () { RealmObjectBase.registerFactory(Asymmetric._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.asymmetricObject, Asymmetric, 'Asymmetric', [ + return SchemaObject(ObjectType.asymmetricObject, Asymmetric, 'Asymmetric', [ SchemaProperty('id', RealmPropertyType.objectid, mapTo: '_id', primaryKey: true), SchemaProperty('symmetric', RealmPropertyType.object, @@ -3464,6 +3543,9 @@ class Asymmetric extends _Asymmetric linkTarget: 'Embedded', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Embedded extends _Embedded @@ -3533,13 +3615,16 @@ class Embedded extends _Embedded static final schema = () { RealmObjectBase.registerFactory(Embedded._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.embeddedObject, Embedded, 'Embedded', [ + return SchemaObject(ObjectType.embeddedObject, Embedded, 'Embedded', [ SchemaProperty('value', RealmPropertyType.int), SchemaProperty('any', RealmPropertyType.mixed, optional: true), SchemaProperty('symmetric', RealmPropertyType.object, optional: true, linkTarget: 'Symmetric'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Symmetric extends _Symmetric @@ -3586,9 +3671,12 @@ class Symmetric extends _Symmetric static final schema = () { RealmObjectBase.registerFactory(Symmetric._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Symmetric, 'Symmetric', [ + return SchemaObject(ObjectType.realmObject, Symmetric, 'Symmetric', [ SchemaProperty('id', RealmPropertyType.objectid, mapTo: '_id', primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/lib/src/realm_model_info.dart b/packages/realm_generator/lib/src/realm_model_info.dart index 2c49d9269..69e3b3d29 100644 --- a/packages/realm_generator/lib/src/realm_model_info.dart +++ b/packages/realm_generator/lib/src/realm_model_info.dart @@ -136,7 +136,7 @@ class RealmModelInfo { { yield 'RealmObjectBase.registerFactory($name._);'; yield 'register(_toEJson, _fromEJson);'; - yield "return const SchemaObject(ObjectType.${baseType.name}, $name, '$realmName', ["; + yield "return SchemaObject(ObjectType.${baseType.name}, $name, '$realmName', ["; { yield* fields.map((f) { final namedArgs = { @@ -158,6 +158,9 @@ class RealmModelInfo { yield ']);'; } yield '}();'; + yield ''; + yield '@override'; + yield 'SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema;'; } yield '}'; } diff --git a/packages/realm_generator/test/good_test_data/all_types.expected b/packages/realm_generator/test/good_test_data/all_types.expected index 2007bc68f..b76394f47 100644 --- a/packages/realm_generator/test/good_test_data/all_types.expected +++ b/packages/realm_generator/test/good_test_data/all_types.expected @@ -67,13 +67,15 @@ class Foo extends _Foo with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Foo._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Foo, 'MyFoo', [ - SchemaProperty('x', RealmPropertyType.int, - indexType: RealmIndexType.regular), + return SchemaObject(ObjectType.realmObject, Foo, 'MyFoo', [ + SchemaProperty('x', RealmPropertyType.int, indexType: RealmIndexType.regular), SchemaProperty('bar', RealmPropertyType.object, optional: true, linkTarget: 'Bar'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Bar extends _Bar with RealmEntity, RealmObjectBase, RealmObject { @@ -304,7 +306,7 @@ class Bar extends _Bar with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Bar._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Bar, 'Bar', [ + return SchemaObject(ObjectType.realmObject, Bar, 'Bar', [ SchemaProperty('name', RealmPropertyType.string, primaryKey: true), SchemaProperty('aBool', RealmPropertyType.bool, indexType: RealmIndexType.regular), @@ -338,6 +340,9 @@ class Bar extends _Bar with RealmEntity, RealmObjectBase, RealmObject { linkTarget: 'MyFoo'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class PrimitiveTypes extends _PrimitiveTypes @@ -431,7 +436,7 @@ class PrimitiveTypes extends _PrimitiveTypes static final schema = () { RealmObjectBase.registerFactory(PrimitiveTypes._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, PrimitiveTypes, 'PrimitiveTypes', [ SchemaProperty('stringProp', RealmPropertyType.string), SchemaProperty('boolProp', RealmPropertyType.bool), @@ -440,4 +445,7 @@ class PrimitiveTypes extends _PrimitiveTypes SchemaProperty('objectIdProp', RealmPropertyType.objectid), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/another_mapto.expected_multi b/packages/realm_generator/test/good_test_data/another_mapto.expected_multi index 56a02c4fe..077783060 100644 --- a/packages/realm_generator/test/good_test_data/another_mapto.expected_multi +++ b/packages/realm_generator/test/good_test_data/another_mapto.expected_multi @@ -66,7 +66,7 @@ class MappedToo extends _MappedToo static final schema = () { RealmObjectBase.registerFactory(MappedToo._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, MappedToo, 'this is also mapped', [ SchemaProperty('singleLink', RealmPropertyType.object, optional: true, linkTarget: 'another type'), @@ -74,4 +74,7 @@ class MappedToo extends _MappedToo linkTarget: 'another type', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/asymmetric_object.expected b/packages/realm_generator/test/good_test_data/asymmetric_object.expected index fb44a52f3..fc75ec583 100644 --- a/packages/realm_generator/test/good_test_data/asymmetric_object.expected +++ b/packages/realm_generator/test/good_test_data/asymmetric_object.expected @@ -88,7 +88,7 @@ class Asymmetric extends _Asymmetric static final schema = () { RealmObjectBase.registerFactory(Asymmetric._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, Asymmetric, 'Asymmetric', [ SchemaProperty('id', RealmPropertyType.objectid, mapTo: '_id', primaryKey: true), @@ -100,6 +100,9 @@ class Asymmetric extends _Asymmetric optional: true, linkTarget: 'Embedded'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Embedded extends _Embedded @@ -156,9 +159,12 @@ class Embedded extends _Embedded static final schema = () { RealmObjectBase.registerFactory(Embedded._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.embeddedObject, Embedded, 'Embedded', [ + return SchemaObject(ObjectType.embeddedObject, Embedded, 'Embedded', [ SchemaProperty('name', RealmPropertyType.string), SchemaProperty('age', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/binary_type.expected b/packages/realm_generator/test/good_test_data/binary_type.expected index bec9648ee..f48add498 100644 --- a/packages/realm_generator/test/good_test_data/binary_type.expected +++ b/packages/realm_generator/test/good_test_data/binary_type.expected @@ -64,10 +64,13 @@ class Foo extends _Foo with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Foo._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Foo, 'Foo', [ + return SchemaObject(ObjectType.realmObject, Foo, 'Foo', [ SchemaProperty('requiredBinaryProp', RealmPropertyType.binary), SchemaProperty('nullableBinaryProp', RealmPropertyType.binary, optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/embedded_annotations.expected b/packages/realm_generator/test/good_test_data/embedded_annotations.expected index 4a1efee3f..2d7e133cc 100644 --- a/packages/realm_generator/test/good_test_data/embedded_annotations.expected +++ b/packages/realm_generator/test/good_test_data/embedded_annotations.expected @@ -65,7 +65,7 @@ class Parent extends _Parent with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Parent._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Parent, 'Parent', [ + return SchemaObject(ObjectType.realmObject, Parent, 'Parent', [ SchemaProperty('child', RealmPropertyType.object, mapTo: 'single child', optional: true, linkTarget: 'MySuperChild'), SchemaProperty('children', RealmPropertyType.object, @@ -74,6 +74,9 @@ class Parent extends _Parent with RealmEntity, RealmObjectBase, RealmObject { collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Child1 extends _Child1 with RealmEntity, RealmObjectBase, EmbeddedObject { @@ -143,8 +146,7 @@ class Child1 extends _Child1 with RealmEntity, RealmObjectBase, EmbeddedObject { static final schema = () { RealmObjectBase.registerFactory(Child1._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.embeddedObject, Child1, 'MySuperChild', [ + return SchemaObject(ObjectType.embeddedObject, Child1, 'MySuperChild', [ SchemaProperty('value', RealmPropertyType.string, mapTo: '_value'), SchemaProperty('linkToParent', RealmPropertyType.object, mapTo: '_parent', optional: true, linkTarget: 'Parent'), @@ -152,4 +154,7 @@ class Child1 extends _Child1 with RealmEntity, RealmObjectBase, EmbeddedObject { indexType: RealmIndexType.regular), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/embedded_objects.expected b/packages/realm_generator/test/good_test_data/embedded_objects.expected index a70ce0e1f..48ffc30f1 100644 --- a/packages/realm_generator/test/good_test_data/embedded_objects.expected +++ b/packages/realm_generator/test/good_test_data/embedded_objects.expected @@ -64,13 +64,16 @@ class Parent extends _Parent with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Parent._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Parent, 'Parent', [ + return SchemaObject(ObjectType.realmObject, Parent, 'Parent', [ SchemaProperty('child', RealmPropertyType.object, optional: true, linkTarget: 'Child1'), SchemaProperty('children', RealmPropertyType.object, linkTarget: 'Child1', collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Child1 extends _Child1 with RealmEntity, RealmObjectBase, EmbeddedObject { @@ -152,7 +155,7 @@ class Child1 extends _Child1 with RealmEntity, RealmObjectBase, EmbeddedObject { static final schema = () { RealmObjectBase.registerFactory(Child1._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.embeddedObject, Child1, 'Child1', [ + return SchemaObject(ObjectType.embeddedObject, Child1, 'Child1', [ SchemaProperty('value', RealmPropertyType.string), SchemaProperty('child', RealmPropertyType.object, optional: true, linkTarget: 'Child2'), @@ -162,6 +165,9 @@ class Child1 extends _Child1 with RealmEntity, RealmObjectBase, EmbeddedObject { optional: true, linkTarget: 'Parent'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Child2 extends _Child2 with RealmEntity, RealmObjectBase, EmbeddedObject { @@ -358,7 +364,7 @@ class Child2 extends _Child2 with RealmEntity, RealmObjectBase, EmbeddedObject { static final schema = () { RealmObjectBase.registerFactory(Child2._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.embeddedObject, Child2, 'Child2', [ + return SchemaObject(ObjectType.embeddedObject, Child2, 'Child2', [ SchemaProperty('boolProp', RealmPropertyType.bool), SchemaProperty('intProp', RealmPropertyType.int), SchemaProperty('doubleProp', RealmPropertyType.double), @@ -381,4 +387,7 @@ class Child2 extends _Child2 with RealmEntity, RealmObjectBase, EmbeddedObject { optional: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/indexable_types.expected b/packages/realm_generator/test/good_test_data/indexable_types.expected index 827e459b4..20facb812 100644 --- a/packages/realm_generator/test/good_test_data/indexable_types.expected +++ b/packages/realm_generator/test/good_test_data/indexable_types.expected @@ -225,7 +225,7 @@ class Indexable extends _Indexable static final schema = () { RealmObjectBase.registerFactory(Indexable._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Indexable, 'Indexable', [ + return SchemaObject(ObjectType.realmObject, Indexable, 'Indexable', [ SchemaProperty('aBool', RealmPropertyType.bool, indexType: RealmIndexType.regular), SchemaProperty('aNullableBool', RealmPropertyType.bool, @@ -260,4 +260,7 @@ class Indexable extends _Indexable optional: true, indexType: RealmIndexType.fullText), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/list_initialization.expected b/packages/realm_generator/test/good_test_data/list_initialization.expected index 5430a4e2b..45f49bc96 100644 --- a/packages/realm_generator/test/good_test_data/list_initialization.expected +++ b/packages/realm_generator/test/good_test_data/list_initialization.expected @@ -168,7 +168,7 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('children', RealmPropertyType.object, linkTarget: 'Person', collectionType: RealmCollectionType.list), SchemaProperty('initList', RealmPropertyType.int, @@ -191,4 +191,7 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { collectionType: RealmCollectionType.map), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/map.expected b/packages/realm_generator/test/good_test_data/map.expected index 90fcd3436..7c6f5e6e6 100644 --- a/packages/realm_generator/test/good_test_data/map.expected +++ b/packages/realm_generator/test/good_test_data/map.expected @@ -178,7 +178,7 @@ class LotsOfMaps extends _LotsOfMaps static final schema = () { RealmObjectBase.registerFactory(LotsOfMaps._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, LotsOfMaps, 'LotsOfMaps', [ SchemaProperty('persons', RealmPropertyType.object, optional: true, @@ -206,6 +206,9 @@ class LotsOfMaps extends _LotsOfMaps collectionType: RealmCollectionType.map), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { @@ -251,8 +254,11 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('name', RealmPropertyType.string), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/mapto.expected b/packages/realm_generator/test/good_test_data/mapto.expected index 3007bb42a..eee0a9ff8 100644 --- a/packages/realm_generator/test/good_test_data/mapto.expected +++ b/packages/realm_generator/test/good_test_data/mapto.expected @@ -86,7 +86,7 @@ class Original extends $Original static final schema = () { RealmObjectBase.registerFactory(Original._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, Original, 'another type', [ SchemaProperty('primitiveProperty', RealmPropertyType.int, mapTo: 'remapped primitive'), @@ -98,4 +98,7 @@ class Original extends $Original collectionType: RealmCollectionType.list), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/optional_argument.expected b/packages/realm_generator/test/good_test_data/optional_argument.expected index f496b59f0..0b9dea736 100644 --- a/packages/realm_generator/test/good_test_data/optional_argument.expected +++ b/packages/realm_generator/test/good_test_data/optional_argument.expected @@ -51,9 +51,12 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('spouse', RealmPropertyType.object, optional: true, linkTarget: 'Person'), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/pinhole.expected b/packages/realm_generator/test/good_test_data/pinhole.expected index 83bb19c62..7626ec3c6 100644 --- a/packages/realm_generator/test/good_test_data/pinhole.expected +++ b/packages/realm_generator/test/good_test_data/pinhole.expected @@ -57,8 +57,11 @@ class Foo extends _Foo with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Foo._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Foo, 'Foo', [ + return SchemaObject(ObjectType.realmObject, Foo, 'Foo', [ SchemaProperty('x', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/primary_key.expected b/packages/realm_generator/test/good_test_data/primary_key.expected index 6b29508a5..e7e4d5e58 100644 --- a/packages/realm_generator/test/good_test_data/primary_key.expected +++ b/packages/realm_generator/test/good_test_data/primary_key.expected @@ -50,10 +50,13 @@ class IntPK extends _IntPK with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(IntPK._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, IntPK, 'IntPK', [ + return SchemaObject(ObjectType.realmObject, IntPK, 'IntPK', [ SchemaProperty('id', RealmPropertyType.int, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableIntPK extends _NullableIntPK @@ -100,12 +103,15 @@ class NullableIntPK extends _NullableIntPK static final schema = () { RealmObjectBase.registerFactory(NullableIntPK._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, NullableIntPK, 'NullableIntPK', [ SchemaProperty('id', RealmPropertyType.int, optional: true, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class StringPK extends _StringPK @@ -152,10 +158,13 @@ class StringPK extends _StringPK static final schema = () { RealmObjectBase.registerFactory(StringPK._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, StringPK, 'StringPK', [ + return SchemaObject(ObjectType.realmObject, StringPK, 'StringPK', [ SchemaProperty('id', RealmPropertyType.string, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableStringPK extends _NullableStringPK @@ -203,12 +212,15 @@ class NullableStringPK extends _NullableStringPK static final schema = () { RealmObjectBase.registerFactory(NullableStringPK._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, NullableStringPK, 'NullableStringPK', [ SchemaProperty('id', RealmPropertyType.string, optional: true, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class ObjectIdPK extends _ObjectIdPK @@ -255,11 +267,13 @@ class ObjectIdPK extends _ObjectIdPK static final schema = () { RealmObjectBase.registerFactory(ObjectIdPK._); register(_toEJson, _fromEJson); - return const SchemaObject( - ObjectType.realmObject, ObjectIdPK, 'ObjectIdPK', [ + return SchemaObject(ObjectType.realmObject, ObjectIdPK, 'ObjectIdPK', [ SchemaProperty('id', RealmPropertyType.objectid, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableObjectIdPK extends _NullableObjectIdPK @@ -307,12 +321,15 @@ class NullableObjectIdPK extends _NullableObjectIdPK static final schema = () { RealmObjectBase.registerFactory(NullableObjectIdPK._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, NullableObjectIdPK, 'NullableObjectIdPK', [ SchemaProperty('id', RealmPropertyType.objectid, optional: true, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class UuidPK extends _UuidPK with RealmEntity, RealmObjectBase, RealmObject { @@ -358,10 +375,13 @@ class UuidPK extends _UuidPK with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(UuidPK._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, UuidPK, 'UuidPK', [ + return SchemaObject(ObjectType.realmObject, UuidPK, 'UuidPK', [ SchemaProperty('id', RealmPropertyType.uuid, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class NullableUuidPK extends _NullableUuidPK @@ -408,10 +428,13 @@ class NullableUuidPK extends _NullableUuidPK static final schema = () { RealmObjectBase.registerFactory(NullableUuidPK._); register(_toEJson, _fromEJson); - return const SchemaObject( + return SchemaObject( ObjectType.realmObject, NullableUuidPK, 'NullableUuidPK', [ SchemaProperty('id', RealmPropertyType.uuid, optional: true, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/realm_set.expected b/packages/realm_generator/test/good_test_data/realm_set.expected index 86406c542..42addd289 100644 --- a/packages/realm_generator/test/good_test_data/realm_set.expected +++ b/packages/realm_generator/test/good_test_data/realm_set.expected @@ -50,10 +50,13 @@ class Car extends _Car with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Car._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Car, 'Car', [ + return SchemaObject(ObjectType.realmObject, Car, 'Car', [ SchemaProperty('make', RealmPropertyType.string, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } class RealmSets extends _RealmSets @@ -311,7 +314,7 @@ class RealmSets extends _RealmSets static final schema = () { RealmObjectBase.registerFactory(RealmSets._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, RealmSets, 'RealmSets', [ + return SchemaObject(ObjectType.realmObject, RealmSets, 'RealmSets', [ SchemaProperty('key', RealmPropertyType.int, primaryKey: true), SchemaProperty('boolSet', RealmPropertyType.bool, collectionType: RealmCollectionType.set), @@ -347,4 +350,7 @@ class RealmSets extends _RealmSets linkTarget: 'Car', collectionType: RealmCollectionType.set), ]); }(); -} + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; +} \ No newline at end of file diff --git a/packages/realm_generator/test/good_test_data/required_argument.expected b/packages/realm_generator/test/good_test_data/required_argument.expected index 7849d093e..bcc016240 100644 --- a/packages/realm_generator/test/good_test_data/required_argument.expected +++ b/packages/realm_generator/test/good_test_data/required_argument.expected @@ -50,8 +50,11 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('name', RealmPropertyType.string, primaryKey: true), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/required_argument_with_default_value.expected b/packages/realm_generator/test/good_test_data/required_argument_with_default_value.expected index dde6c5c1c..b7c0fd3cc 100644 --- a/packages/realm_generator/test/good_test_data/required_argument_with_default_value.expected +++ b/packages/realm_generator/test/good_test_data/required_argument_with_default_value.expected @@ -57,8 +57,11 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('age', RealmPropertyType.int), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; } diff --git a/packages/realm_generator/test/good_test_data/user_defined_getter.expected b/packages/realm_generator/test/good_test_data/user_defined_getter.expected index 9aab3d61b..8eb457bd0 100644 --- a/packages/realm_generator/test/good_test_data/user_defined_getter.expected +++ b/packages/realm_generator/test/good_test_data/user_defined_getter.expected @@ -50,8 +50,11 @@ class Person extends _Person with RealmEntity, RealmObjectBase, RealmObject { static final schema = () { RealmObjectBase.registerFactory(Person._); register(_toEJson, _fromEJson); - return const SchemaObject(ObjectType.realmObject, Person, 'Person', [ + return SchemaObject(ObjectType.realmObject, Person, 'Person', [ SchemaProperty('name', RealmPropertyType.string), ]); }(); + + @override + SchemaObject get objectSchema => RealmObjectBase.getSchema(this) ?? schema; }