diff --git a/packages/realm_dart/lib/src/handles/app_handle.dart b/packages/realm_dart/lib/src/handles/app_handle.dart index 47b326f03..e2a57a8e4 100644 --- a/packages/realm_dart/lib/src/handles/app_handle.dart +++ b/packages/realm_dart/lib/src/handles/app_handle.dart @@ -1,5 +1,38 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/app_handle.dart' - if (dart.library.js_interop) 'web/app_handle.dart'; +import '../../realm.dart'; + +import 'credentials_handle.dart'; +import 'native/app_handle.dart' if (dart.library.js_interop) 'web/app_handle.dart' as impl; +import 'user_handle.dart'; + +abstract interface class AppHandle { + factory AppHandle.from(AppConfiguration configuration) = impl.AppHandle.from; + static AppHandle? get(String id, String? baseUrl) => impl.AppHandle.get(id, baseUrl); + + String get id; + + UserHandle? get currentUser; + List get users; + Future logIn(CredentialsHandle credentials); + Future removeUser(UserHandle user); + void switchUser(UserHandle user); + Future refreshCustomData(UserHandle user); + + void reconnect(); + String get baseUrl; + Future updateBaseUrl(Uri? baseUrl); + + Future registerUser(String email, String password); + Future confirmUser(String token, String tokenId); + Future resendConfirmation(String email); + + Future completeResetPassword(String password, String token, String tokenId); + Future requestResetPassword(String email); + Future callResetPasswordFunction(String email, String password, String? argsAsJSON); + Future retryCustomConfirmationFunction(String email); + Future deleteUser(UserHandle user); + bool resetRealm(String realmPath); + Future callAppFunction(UserHandle user, String functionName, String? argsAsJSON); +} diff --git a/packages/realm_dart/lib/src/handles/async_open_task_handle.dart b/packages/realm_dart/lib/src/handles/async_open_task_handle.dart index 43c4aeae2..47d988585 100644 --- a/packages/realm_dart/lib/src/handles/async_open_task_handle.dart +++ b/packages/realm_dart/lib/src/handles/async_open_task_handle.dart @@ -1,5 +1,20 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/async_open_task_handle.dart' - if (dart.library.js_interop) 'web/async_open_task_handle.dart'; +import '../realm_class.dart'; +import 'handle_base.dart'; +import 'native/async_open_task_handle.dart' if (dart.library.js_interop) 'web/async_open_task_handle.dart' as impl; +import 'realm_handle.dart'; + +abstract interface class AsyncOpenTaskHandle extends HandleBase { + factory AsyncOpenTaskHandle.from(FlexibleSyncConfiguration config) = impl.AsyncOpenTaskHandle.from; + + Future openAsync(CancellationToken? cancellationToken); + void cancel(); + + AsyncOpenTaskProgressNotificationTokenHandle registerProgressNotifier( + RealmAsyncOpenProgressNotificationsController controller, + ); +} + +abstract class AsyncOpenTaskProgressNotificationTokenHandle extends HandleBase {} \ No newline at end of file diff --git a/packages/realm_dart/lib/src/handles/collection_changes_handle.dart b/packages/realm_dart/lib/src/handles/collection_changes_handle.dart index 8988dae68..e8295ba1d 100644 --- a/packages/realm_dart/lib/src/handles/collection_changes_handle.dart +++ b/packages/realm_dart/lib/src/handles/collection_changes_handle.dart @@ -1,5 +1,9 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/collection_changes_handle.dart' - if (dart.library.js_interop) 'web/collection_changes_handle.dart'; +import '../collections.dart'; +import 'handle_base.dart'; + +abstract interface class CollectionChangesHandle extends HandleBase { + CollectionChanges get changes; +} diff --git a/packages/realm_dart/lib/src/handles/handle_base.dart b/packages/realm_dart/lib/src/handles/handle_base.dart index 3cc73da68..bf255de0e 100644 --- a/packages/realm_dart/lib/src/handles/handle_base.dart +++ b/packages/realm_dart/lib/src/handles/handle_base.dart @@ -1,5 +1,9 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/handle_base.dart' - if (dart.library.js_interop) 'web/handle_base.dart'; +abstract class HandleBase { + bool get released; + bool get isUnowned; + void releaseCore(); + void release(); +} diff --git a/packages/realm_dart/lib/src/handles/list_handle.dart b/packages/realm_dart/lib/src/handles/list_handle.dart index f6ebbab17..4606fe831 100644 --- a/packages/realm_dart/lib/src/handles/list_handle.dart +++ b/packages/realm_dart/lib/src/handles/list_handle.dart @@ -1,5 +1,32 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/list_handle.dart' - if (dart.library.js_interop) 'web/list_handle.dart'; +import '../realm_dart.dart'; +import 'handle_base.dart'; +import 'notification_token_handle.dart'; +import 'object_handle.dart'; +import 'realm_handle.dart'; +import 'results_handle.dart'; + +abstract interface class ListHandle extends HandleBase { + bool get isValid; + int get size; + + // TODO: Consider splitting into two methods + void addOrUpdateAt(int index, Object? value, bool insert); + // TODO: avoid taking the [realm] parameter + void addOrUpdateCollectionAt(Realm realm, int index, RealmValue value, bool insert); + ResultsHandle asResults(); + void clear(); + void deleteAll(); + // TODO: avoid taking the [realm] parameter + Object? elementAt(Realm realm, int index); + int indexOf(Object? value); + ObjectHandle insertEmbeddedAt(int index); + void move(int from, int to); + ResultsHandle query(String query, List args); + void removeAt(int index); + ListHandle? resolveIn(RealmHandle frozenRealm); + ObjectHandle setEmbeddedAt(int index); + NotificationTokenHandle subscribeForNotifications(NotificationsController controller); +} diff --git a/packages/realm_dart/lib/src/handles/map_changes_handle.dart b/packages/realm_dart/lib/src/handles/map_changes_handle.dart index 83cc550db..a90197e6b 100644 --- a/packages/realm_dart/lib/src/handles/map_changes_handle.dart +++ b/packages/realm_dart/lib/src/handles/map_changes_handle.dart @@ -1,5 +1,9 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/map_changes_handle.dart' - if (dart.library.js_interop) 'web/map_changes_handle.dart'; +import '../collections.dart'; +import 'handle_base.dart'; + +abstract interface class MapChangesHandle extends HandleBase { + MapChanges get changes; +} \ No newline at end of file diff --git a/packages/realm_dart/lib/src/handles/map_handle.dart b/packages/realm_dart/lib/src/handles/map_handle.dart index afc43b6be..2ffa43557 100644 --- a/packages/realm_dart/lib/src/handles/map_handle.dart +++ b/packages/realm_dart/lib/src/handles/map_handle.dart @@ -1,5 +1,31 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/map_handle.dart' - if (dart.library.js_interop) 'web/map_handle.dart'; +import '../realm_class.dart'; +import 'handle_base.dart'; +import 'notification_token_handle.dart'; +import 'object_handle.dart'; +import 'realm_handle.dart'; +import 'results_handle.dart'; + +abstract interface class MapHandle extends HandleBase { + bool get isValid; + ResultsHandle get keys; + int get size; + ResultsHandle get values; + + void clear(); + bool containsKey(String key); + bool containsValue(Object? value); + // TODO: avoid taking a [Realm] as parameter (wrong layer) + Object? find(Realm realm, String key); + int indexOf(Object? value); + void insert(String key, Object? value); + // TODO: avoid taking a [Realm] as parameter (wrong layer) + void insertCollection(Realm realm, String key, RealmValue value); + ObjectHandle insertEmbedded(String key); + ResultsHandle query(String query, List args); + bool remove(String key); + MapHandle? resolveIn(RealmHandle frozenRealm); + NotificationTokenHandle subscribeForNotifications(NotificationsController controller); +} diff --git a/packages/realm_dart/lib/src/handles/mutable_subscription_set_handle.dart b/packages/realm_dart/lib/src/handles/mutable_subscription_set_handle.dart index 557f97f1d..06cb2a811 100644 --- a/packages/realm_dart/lib/src/handles/mutable_subscription_set_handle.dart +++ b/packages/realm_dart/lib/src/handles/mutable_subscription_set_handle.dart @@ -1,5 +1,18 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/mutable_subscription_set_handle.dart' - if (dart.library.js_interop) 'web/mutable_subscription_set_handle.dart'; +import 'results_handle.dart'; +import 'subscription_handle.dart'; +import 'subscription_set_handle.dart'; + +abstract interface class MutableSubscriptionSetHandle extends SubscriptionSetHandle { + SubscriptionSetHandle commit(); + + SubscriptionHandle insertOrAssignSubscription(ResultsHandle results, String? name, bool update); + + bool erase(SubscriptionHandle subscription); + bool eraseByName(String name); + bool eraseByResults(ResultsHandle results); + + void clear(); +} diff --git a/packages/realm_dart/lib/src/handles/native/app_handle.dart b/packages/realm_dart/lib/src/handles/native/app_handle.dart index 38b1900b2..63f09d030 100644 --- a/packages/realm_dart/lib/src/handles/native/app_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/app_handle.dart @@ -8,7 +8,6 @@ import 'dart:isolate'; import '../../init.dart'; import '../../realm_class.dart'; -import '../../scheduler.dart'; import 'convert.dart'; import 'convert_native.dart'; import 'credentials_handle.dart'; @@ -19,9 +18,12 @@ import 'http_transport_handle.dart'; import 'realm_bindings.dart'; import 'realm_core.dart'; import 'realm_library.dart'; +import 'scheduler_handle.dart'; import 'user_handle.dart'; -class AppHandle extends HandleBase { +import '../app_handle.dart' as intf; + +class AppHandle extends HandleBase implements intf.AppHandle { AppHandle(Pointer pointer) : super(pointer, 16); static bool _firstTime = true; @@ -51,10 +53,12 @@ class AppHandle extends HandleBase { }); } + @override UserHandle? get currentUser { return realmLib.realm_app_get_current_user(pointer).convert(UserHandle.new); } + @override List get users => using((arena) => _getUsers(arena)); List _getUsers(Arena arena, {int expectedSize = 2}) { @@ -76,7 +80,8 @@ class AppHandle extends HandleBase { return result; } - Future removeUser(UserHandle user) { + @override + Future removeUser(covariant UserHandle user) { final completer = Completer(); realmLib .realm_app_remove_user( @@ -90,7 +95,8 @@ class AppHandle extends HandleBase { return completer.future; } - void switchUser(UserHandle user) { + @override + void switchUser(covariant UserHandle user) { using((arena) { realmLib .realm_app_switch_user( @@ -101,13 +107,16 @@ class AppHandle extends HandleBase { }); } + @override void reconnect() => realmLib.realm_app_sync_client_reconnect(pointer); + @override String get baseUrl { final customDataPtr = realmLib.realm_app_get_base_url(pointer); return customDataPtr.cast().toRealmDartString(freeRealmMemory: true)!; } + @override Future updateBaseUrl(Uri? baseUrl) { final completer = Completer(); using((arena) { @@ -124,7 +133,8 @@ class AppHandle extends HandleBase { return completer.future; } - Future refreshCustomData(UserHandle user) { + @override + Future refreshCustomData(covariant UserHandle user) { final completer = Completer(); realmLib .realm_app_refresh_custom_data( @@ -138,10 +148,12 @@ class AppHandle extends HandleBase { return completer.future; } + @override String get id { return realmLib.realm_app_get_app_id(pointer).cast().toRealmDartString()!; } + @override Future logIn(CredentialsHandle credentials) { final completer = Completer(); realmLib @@ -156,6 +168,7 @@ class AppHandle extends HandleBase { return completer.future; } + @override Future registerUser(String email, String password) { final completer = Completer(); using((arena) { @@ -173,6 +186,7 @@ class AppHandle extends HandleBase { return completer.future; } + @override Future confirmUser(String token, String tokenId) { final completer = Completer(); using((arena) { @@ -190,6 +204,7 @@ class AppHandle extends HandleBase { return completer.future; } + @override Future resendConfirmation(String email) { final completer = Completer(); using((arena) { @@ -206,6 +221,7 @@ class AppHandle extends HandleBase { return completer.future; } + @override Future completeResetPassword(String password, String token, String tokenId) { final completer = Completer(); using((arena) { @@ -224,6 +240,7 @@ class AppHandle extends HandleBase { return completer.future; } + @override Future requestResetPassword(String email) { final completer = Completer(); using((arena) { @@ -240,6 +257,7 @@ class AppHandle extends HandleBase { return completer.future; } + @override Future callResetPasswordFunction(String email, String password, String? argsAsJSON) { final completer = Completer(); using((arena) { @@ -258,6 +276,7 @@ class AppHandle extends HandleBase { return completer.future; } + @override Future retryCustomConfirmationFunction(String email) { final completer = Completer(); using((arena) { @@ -274,7 +293,8 @@ class AppHandle extends HandleBase { return completer.future; } - Future deleteUser(UserHandle user) { + @override + Future deleteUser(covariant UserHandle user) { final completer = Completer(); realmLib .realm_app_delete_user( @@ -288,6 +308,7 @@ class AppHandle extends HandleBase { return completer.future; } + @override bool resetRealm(String realmPath) { return using((arena) { final didRun = arena(); @@ -302,7 +323,8 @@ class AppHandle extends HandleBase { }); } - Future callAppFunction(UserHandle user, String functionName, String? argsAsJSON) { + @override + Future callAppFunction(covariant UserHandle user, String functionName, String? argsAsJSON) { return using((arena) { final completer = Completer(); realmLib @@ -333,7 +355,7 @@ Pointer createAsyncFunctionCallbackUserdata(Completer completer) { final userdata = realmLib.realm_dart_userdata_async_new( completer, callback.cast(), - scheduler.handle.pointer, + schedulerHandle.pointer, ); return userdata.cast(); @@ -361,7 +383,7 @@ Pointer createAsyncCallbackUserdata(Completer completer) { final userdata = realmLib.realm_dart_userdata_async_new( completer, callback.cast(), - scheduler.handle.pointer, + schedulerHandle.pointer, ); return userdata.cast(); diff --git a/packages/realm_dart/lib/src/handles/native/async_open_task_handle.dart b/packages/realm_dart/lib/src/handles/native/async_open_task_handle.dart index ee938a75c..7a6d202e4 100644 --- a/packages/realm_dart/lib/src/handles/native/async_open_task_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/async_open_task_handle.dart @@ -6,14 +6,16 @@ import 'error_handling.dart'; import 'realm_bindings.dart'; import '../../realm_dart.dart'; -import '../../scheduler.dart'; import 'config_handle.dart'; import 'handle_base.dart'; import 'realm_handle.dart'; import 'realm_library.dart'; +import 'scheduler_handle.dart'; import 'session_handle.dart'; -class AsyncOpenTaskHandle extends HandleBase { +import '../async_open_task_handle.dart' as intf; + +class AsyncOpenTaskHandle extends HandleBase implements intf.AsyncOpenTaskHandle { AsyncOpenTaskHandle(Pointer pointer) : super(pointer, 32); factory AsyncOpenTaskHandle.from(FlexibleSyncConfiguration config) { @@ -27,7 +29,7 @@ class AsyncOpenTaskHandle extends HandleBase { if (!completer.isCancelled) { final callback = Pointer.fromFunction realm, Pointer error)>(_openRealmAsyncCallback); - final userData = realmLib.realm_dart_userdata_async_new(completer, callback.cast(), scheduler.handle.pointer); + final userData = realmLib.realm_dart_userdata_async_new(completer, callback.cast(), schedulerHandle.pointer); realmLib.realm_async_open_task_start( pointer, realmLib.addresses.realm_dart_async_open_task_callback, @@ -46,7 +48,7 @@ class AsyncOpenTaskHandle extends HandleBase { RealmAsyncOpenProgressNotificationsController controller, ) { final callback = Pointer.fromFunction(syncProgressCallback); - final userdata = realmLib.realm_dart_userdata_async_new(controller, callback.cast(), scheduler.handle.pointer); + final userdata = realmLib.realm_dart_userdata_async_new(controller, callback.cast(), schedulerHandle.pointer); return AsyncOpenTaskProgressNotificationTokenHandle( realmLib.realm_async_open_task_register_download_progress_notifier( pointer, @@ -58,7 +60,8 @@ class AsyncOpenTaskHandle extends HandleBase { } } -class AsyncOpenTaskProgressNotificationTokenHandle extends HandleBase { +class AsyncOpenTaskProgressNotificationTokenHandle extends HandleBase + implements intf.AsyncOpenTaskProgressNotificationTokenHandle { AsyncOpenTaskProgressNotificationTokenHandle(Pointer pointer) : super(pointer, 40); } @@ -75,6 +78,6 @@ void _openRealmAsyncCallback(Object userData, Pointer { +import '../collection_changes_handle.dart' as intf; + +class CollectionChangesHandle extends HandleBase implements intf.CollectionChangesHandle { CollectionChangesHandle(Pointer pointer) : super(pointer, 256); + @override CollectionChanges get changes { return using((arena) { final outNumDeletions = arena(); diff --git a/packages/realm_dart/lib/src/handles/native/collection_handle_base.dart b/packages/realm_dart/lib/src/handles/native/collection_handle_base.dart index 4fbd3e235..7342ced4f 100644 --- a/packages/realm_dart/lib/src/handles/native/collection_handle_base.dart +++ b/packages/realm_dart/lib/src/handles/native/collection_handle_base.dart @@ -7,18 +7,18 @@ import '../../realm_class.dart'; import 'list_handle.dart'; import 'map_handle.dart'; import 'realm_bindings.dart'; +import 'realm_handle.dart'; import 'rooted_handle.dart'; abstract class CollectionHandleBase extends RootedHandleBase { CollectionHandleBase(super.root, super.pointer, super.size); } - void createCollection(Realm realm, RealmValue value, Pointer Function() createList, Pointer Function() createMap) { CollectionHandleBase? collectionHandle; try { switch (value.collectionType) { case RealmCollectionType.list: - final listHandle = ListHandle(createList(), realm.handle); + final listHandle = ListHandle(createList(), realm.handle as RealmHandle); collectionHandle = listHandle; final list = realm.createList(listHandle, null); @@ -30,7 +30,7 @@ void createCollection(Realm realm, RealmValue value, Pointer Functio list.add(item); } case RealmCollectionType.map: - final mapHandle = MapHandle(createMap(), realm.handle); + final mapHandle = MapHandle(createMap(), realm.handle as RealmHandle); collectionHandle = mapHandle; final map = realm.createMap(mapHandle, null); diff --git a/packages/realm_dart/lib/src/handles/native/config_handle.dart b/packages/realm_dart/lib/src/handles/native/config_handle.dart index 1c0365357..6c1134264 100644 --- a/packages/realm_dart/lib/src/handles/native/config_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/config_handle.dart @@ -4,20 +4,20 @@ import 'dart:async'; import 'dart:ffi'; -import 'ffi.dart'; -import 'error_handling.dart'; - import '../../configuration.dart'; import '../../migration.dart'; import '../../realm_class.dart'; -import '../../scheduler.dart'; import '../../user.dart'; import 'convert_native.dart'; +import 'error_handling.dart'; +import 'ffi.dart'; import 'handle_base.dart'; import 'realm_bindings.dart'; import 'realm_handle.dart'; import 'realm_library.dart'; +import 'scheduler_handle.dart'; import 'schema_handle.dart'; +import 'user_handle.dart'; class ConfigHandle extends HandleBase { ConfigHandle(Pointer pointer) : super(pointer, 512); @@ -32,7 +32,7 @@ class ConfigHandle extends HandleBase { } realmLib.realm_config_set_path(configHandle.pointer, config.path.toCharPtr(arena)); - realmLib.realm_config_set_scheduler(configHandle.pointer, scheduler.handle.pointer); + realmLib.realm_config_set_scheduler(configHandle.pointer, schedulerHandle.pointer); if (config.fifoFilesFallbackPath != null) { realmLib.realm_config_set_fifo_path(configHandle.pointer, config.fifoFilesFallbackPath!.toCharPtr(arena)); @@ -87,19 +87,19 @@ class ConfigHandle extends HandleBase { 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_DISCOVERED); - final syncConfigPtr = realmLib.realm_flx_sync_config_new(config.user.handle.pointer).raiseLastErrorIfNull(); + final syncConfigPtr = realmLib.realm_flx_sync_config_new((config.user.handle as UserHandle).pointer).raiseLastErrorIfNull(); try { realmLib.realm_sync_config_set_session_stop_policy(syncConfigPtr, config.sessionStopPolicy.index); realmLib.realm_sync_config_set_resync_mode(syncConfigPtr, config.clientResetHandler.clientResyncMode.index); final errorHandlerCallback = Pointer.fromFunction, realm_sync_error_t)>(_syncErrorHandlerCallback); - final errorHandlerUserdata = realmLib.realm_dart_userdata_async_new(config, errorHandlerCallback.cast(), scheduler.handle.pointer); + final errorHandlerUserdata = realmLib.realm_dart_userdata_async_new(config, errorHandlerCallback.cast(), schedulerHandle.pointer); realmLib.realm_sync_config_set_error_handler(syncConfigPtr, realmLib.addresses.realm_dart_sync_error_handler_callback, errorHandlerUserdata.cast(), realmLib.addresses.realm_dart_userdata_async_free); if (config.clientResetHandler.onBeforeReset != null) { final syncBeforeResetCallback = Pointer.fromFunction, Pointer)>(_syncBeforeResetCallback); - final beforeResetUserdata = realmLib.realm_dart_userdata_async_new(config, syncBeforeResetCallback.cast(), scheduler.handle.pointer); + final beforeResetUserdata = realmLib.realm_dart_userdata_async_new(config, syncBeforeResetCallback.cast(), schedulerHandle.pointer); realmLib.realm_sync_config_set_before_client_reset_handler(syncConfigPtr, realmLib.addresses.realm_dart_sync_before_reset_handler_callback, beforeResetUserdata.cast(), realmLib.addresses.realm_dart_userdata_async_free); @@ -109,7 +109,7 @@ class ConfigHandle extends HandleBase { final syncAfterResetCallback = Pointer.fromFunction, Pointer, Bool, Pointer)>( _syncAfterResetCallback); - final afterResetUserdata = realmLib.realm_dart_userdata_async_new(config, syncAfterResetCallback.cast(), scheduler.handle.pointer); + final afterResetUserdata = realmLib.realm_dart_userdata_async_new(config, syncAfterResetCallback.cast(), schedulerHandle.pointer); realmLib.realm_sync_config_set_after_client_reset_handler(syncConfigPtr, realmLib.addresses.realm_dart_sync_after_reset_handler_callback, afterResetUserdata.cast(), realmLib.addresses.realm_dart_userdata_async_free); @@ -163,7 +163,7 @@ void _syncAfterResetCallback(Object userdata, Pointer beforeHandle syncConfig, RealmHandle.unowned(realmLib.realm_from_thread_safe_reference( afterReference, - scheduler.handle.pointer, + schedulerHandle.pointer, ))); try { diff --git a/packages/realm_dart/lib/src/handles/native/from_native.dart b/packages/realm_dart/lib/src/handles/native/from_native.dart index d6ab87d4b..7f2c34c7a 100644 --- a/packages/realm_dart/lib/src/handles/native/from_native.dart +++ b/packages/realm_dart/lib/src/handles/native/from_native.dart @@ -13,6 +13,7 @@ import 'decimal128.dart'; import 'list_handle.dart'; import 'map_handle.dart'; import 'realm_bindings.dart'; +import 'realm_handle.dart'; import 'realm_library.dart'; // TODO: Duplicated in to_native.dart @@ -64,14 +65,14 @@ extension RealmValueEx on realm_value_t { throw RealmException('toDartValue called with a list argument but without a list getter'); } - final listHandle = ListHandle(getList(), realm.handle); + final listHandle = ListHandle(getList(), realm.handle as RealmHandle); return realm.createList(listHandle, null); case realm_value_type.RLM_TYPE_DICTIONARY: if (getMap == null || realm == null) { throw RealmException('toDartValue called with a list argument but without a list getter'); } - final mapHandle = MapHandle(getMap(), realm.handle); + final mapHandle = MapHandle(getMap(), realm.handle as RealmHandle); return realm.createMap(mapHandle, null); default: throw RealmException("realm_value_type $type not supported"); diff --git a/packages/realm_dart/lib/src/handles/native/handle_base.dart b/packages/realm_dart/lib/src/handles/native/handle_base.dart index 93bdadf95..0835503e8 100644 --- a/packages/realm_dart/lib/src/handles/native/handle_base.dart +++ b/packages/realm_dart/lib/src/handles/native/handle_base.dart @@ -3,9 +3,13 @@ import 'dart:ffi'; +import 'package:realm_dart/realm.dart'; + import 'error_handling.dart'; import 'realm_library.dart'; +import '../handle_base.dart' as intf; + // Flag to enable trace on finalization. // // Be aware that the trace is likely late, and it might in rare case be missing, @@ -32,33 +36,42 @@ void _tearDownFinalizationTrace(Object value, Object finalizationToken) { _traceFinalization(finalizationToken); } -abstract class HandleBase implements Finalizable { +abstract class HandleBase implements Finalizable, intf.HandleBase { late Pointer _finalizableHandle; - Pointer pointer; - bool get released => pointer == nullptr; + Pointer _pointer; + Pointer get pointer { + if (released) throw RealmError('Trying to access a released handle'); + return _pointer; + } + + @override + bool get released => _pointer == nullptr; + @override final bool isUnowned; - HandleBase(this.pointer, int size) : isUnowned = false { - pointer.raiseLastErrorIfNull(); + HandleBase(this._pointer, int size) : isUnowned = false { + _pointer.raiseLastErrorIfNull(); _finalizableHandle = realmLib.realm_attach_finalizer(this, pointer.cast(), size); if (_enableFinalizerTrace) { - _setupFinalizationTrace(this, pointer); + _setupFinalizationTrace(this, _pointer); } } - HandleBase.unowned(this.pointer) : isUnowned = true { - pointer.raiseLastErrorIfNull(); + HandleBase.unowned(this._pointer) : isUnowned = true { + _pointer.raiseLastErrorIfNull(); } @override - String toString() => "${pointer.toString()} value=${pointer.cast().value}${isUnowned ? ' (unowned)' : ''}"; + String toString() => "${_pointer.toString()} value=${_pointer.cast().value}${isUnowned ? ' (unowned)' : ''}"; /// @nodoc /// A method that will be invoked just before the handle is released. Allows to cleanup /// any custom data that inheritors are storing. + @override void releaseCore() {} + @override void release() { if (released) { return; @@ -69,21 +82,21 @@ abstract class HandleBase implements Finalizable { if (!isUnowned) { realmLib.realm_detach_finalizer(_finalizableHandle, this); - realmLib.realm_release(pointer.cast()); + realmLib.realm_release(_pointer.cast()); } - pointer = nullptr; + _pointer = nullptr; if (_enableFinalizerTrace) { - _tearDownFinalizationTrace(this, pointer); + _tearDownFinalizationTrace(this, _pointer); } } @override // ignore: hash_and_equals bool operator ==(Object other) => other is HandleBase - ? pointer == other.pointer + ? _pointer == other._pointer ? true - : realmLib.realm_equals(pointer.cast(), other.pointer.cast()) + : realmLib.realm_equals(_pointer.cast(), other._pointer.cast()) : false; } diff --git a/packages/realm_dart/lib/src/handles/native/http_transport_handle.dart b/packages/realm_dart/lib/src/handles/native/http_transport_handle.dart index c7988f4d2..bf4f4fec5 100644 --- a/packages/realm_dart/lib/src/handles/native/http_transport_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/http_transport_handle.dart @@ -7,19 +7,19 @@ import 'dart:io'; import '../../logging.dart'; import '../../realm_dart.dart'; -import '../../scheduler.dart'; import 'convert_native.dart'; import 'ffi.dart'; import 'handle_base.dart'; import 'realm_bindings.dart'; import 'realm_library.dart'; +import 'scheduler_handle.dart'; class HttpTransportHandle extends HandleBase { HttpTransportHandle(Pointer pointer) : super(pointer, 24); factory HttpTransportHandle.from(HttpClient httpClient) { final requestCallback = Pointer.fromFunction)>(_requestCallback); - final requestCallbackUserdata = realmLib.realm_dart_userdata_async_new(httpClient, requestCallback.cast(), scheduler.handle.pointer); + final requestCallbackUserdata = realmLib.realm_dart_userdata_async_new(httpClient, requestCallback.cast(), schedulerHandle.pointer); return HttpTransportHandle(realmLib.realm_http_transport_new( realmLib.addresses.realm_dart_http_request_callback, requestCallbackUserdata.cast(), diff --git a/packages/realm_dart/lib/src/handles/native/list_handle.dart b/packages/realm_dart/lib/src/handles/native/list_handle.dart index 4c1d330ca..222710e17 100644 --- a/packages/realm_dart/lib/src/handles/native/list_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/list_handle.dart @@ -16,15 +16,20 @@ import 'realm_handle.dart'; import 'realm_library.dart'; import 'results_handle.dart'; -class ListHandle extends CollectionHandleBase { +import '../list_handle.dart' as intf; + +class ListHandle extends CollectionHandleBase implements intf.ListHandle { ListHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 88); + @override bool get isValid => realmLib.realm_list_is_valid(pointer); + @override ResultsHandle asResults() { return ResultsHandle(realmLib.realm_list_to_results(pointer), root); } + @override int get size { return using((arena) { final size = arena(); @@ -33,18 +38,22 @@ class ListHandle extends CollectionHandleBase { }); } + @override void removeAt(int index) { realmLib.realm_list_erase(pointer, index).raiseLastErrorIfFalse(); } + @override void move(int from, int to) { realmLib.realm_list_move(pointer, from, to).raiseLastErrorIfFalse(); } + @override void deleteAll() { realmLib.realm_list_remove_all(pointer).raiseLastErrorIfFalse(); } + @override int indexOf(Object? value) { return using((arena) { final outIndex = arena(); @@ -64,11 +73,12 @@ class ListHandle extends CollectionHandleBase { }); } + @override void clear() { realmLib.realm_list_clear(pointer).raiseLastErrorIfFalse(); } - // TODO: avoid taking the [realm] parameter + @override Object? elementAt(Realm realm, int index) { return using((arena) { final realmValue = arena(); @@ -81,7 +91,8 @@ class ListHandle extends CollectionHandleBase { }); } - ListHandle? resolveIn(RealmHandle frozenRealm) { + @override + ListHandle? resolveIn(covariant RealmHandle frozenRealm) { return using((arena) { final resultPtr = arena>(); realmLib.realm_list_resolve_in(pointer, frozenRealm.pointer, resultPtr).raiseLastErrorIfFalse(); @@ -90,6 +101,7 @@ class ListHandle extends CollectionHandleBase { } // TODO: Consider splitting into two methods + @override void addOrUpdateAt(int index, Object? value, bool insert) { using((arena) { final realmValue = value.toNative(arena); @@ -97,20 +109,23 @@ class ListHandle extends CollectionHandleBase { }); } - // TODO: avoid taking the [realm] parameter + @override void addOrUpdateCollectionAt(Realm realm, int index, RealmValue value, bool insert) { createCollection(realm, value, () => (insert ? realmLib.realm_list_insert_list : realmLib.realm_list_set_list)(pointer, index), () => (insert ? realmLib.realm_list_insert_dictionary : realmLib.realm_list_set_dictionary)(pointer, index)); } + @override ObjectHandle setEmbeddedAt(int index) { return ObjectHandle(realmLib.realm_list_set_embedded(pointer, index), root); } + @override ObjectHandle insertEmbeddedAt(int index) { return ObjectHandle(realmLib.realm_list_insert_embedded(pointer, index), root); } + @override ResultsHandle query(String query, List args) { return using((arena) { final length = args.length; @@ -131,6 +146,7 @@ class ListHandle extends CollectionHandleBase { }); } + @override NotificationTokenHandle subscribeForNotifications(NotificationsController controller) { return NotificationTokenHandle( realmLib.realm_list_add_notification_callback( diff --git a/packages/realm_dart/lib/src/handles/native/map_changes_handle.dart b/packages/realm_dart/lib/src/handles/native/map_changes_handle.dart index 4ba4b1f81..98d695f5a 100644 --- a/packages/realm_dart/lib/src/handles/native/map_changes_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/map_changes_handle.dart @@ -10,9 +10,12 @@ import 'handle_base.dart'; import 'realm_bindings.dart'; import 'realm_library.dart'; -class MapChangesHandle extends HandleBase { +import '../map_changes_handle.dart' as intf; + +class MapChangesHandle extends HandleBase implements intf.MapChangesHandle { MapChangesHandle(Pointer pointer) : super(pointer, 256); + @override MapChanges get changes { return using((arena) { final outNumDeletions = arena(); diff --git a/packages/realm_dart/lib/src/handles/native/map_handle.dart b/packages/realm_dart/lib/src/handles/native/map_handle.dart index 5453de7bb..0a3877dd2 100644 --- a/packages/realm_dart/lib/src/handles/native/map_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/map_handle.dart @@ -17,9 +17,12 @@ import 'realm_handle.dart'; import 'realm_library.dart'; import 'results_handle.dart'; -class MapHandle extends CollectionHandleBase { +import '../map_handle.dart' as intf; + +class MapHandle extends CollectionHandleBase implements intf.MapHandle { MapHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 96); // TODO: check size + @override int get size { return using((arena) { final outSize = arena(); @@ -28,6 +31,7 @@ class MapHandle extends CollectionHandleBase { }); } + @override bool remove(String key) { return using((arena) { final keyNative = key.toNative(arena); @@ -37,7 +41,7 @@ class MapHandle extends CollectionHandleBase { }); } - // TODO: avoid taking the [realm] parameter + @override Object? find(Realm realm, String key) { return using((arena) { final keyNative = key.toNative(arena); @@ -55,14 +59,17 @@ class MapHandle extends CollectionHandleBase { }); } + @override bool get isValid { return realmLib.realm_dictionary_is_valid(pointer); } + @override void clear() { realmLib.realm_dictionary_clear(pointer).raiseLastErrorIfFalse(); } + @override ResultsHandle get keys { return using((arena) { final outSize = arena(); @@ -72,10 +79,12 @@ class MapHandle extends CollectionHandleBase { }); } + @override ResultsHandle get values { return ResultsHandle(realmLib.realm_dictionary_to_results(pointer), root); } + @override bool containsKey(String key) { return using((arena) { final keyNative = key.toNative(arena); @@ -85,6 +94,7 @@ class MapHandle extends CollectionHandleBase { }); } + @override int indexOf(Object? value) { return using((arena) { // TODO: how should this behave for collections @@ -95,8 +105,10 @@ class MapHandle extends CollectionHandleBase { }); } + @override bool containsValue(Object? value) => indexOf(value) > -1; + @override ObjectHandle insertEmbedded(String key) { return using((arena) { final keyNative = key.toNative(arena); @@ -104,6 +116,7 @@ class MapHandle extends CollectionHandleBase { }); } + @override void insert(String key, Object? value) { using((arena) { final keyNative = key.toNative(arena); @@ -120,6 +133,7 @@ class MapHandle extends CollectionHandleBase { }); } + @override void insertCollection(Realm realm, String key, RealmValue value) { using((arena) { final keyNative = key.toNative(arena); @@ -132,6 +146,7 @@ class MapHandle extends CollectionHandleBase { }); } + @override ResultsHandle query(String query, List args) { return using((arena) { final length = args.length; @@ -153,7 +168,8 @@ class MapHandle extends CollectionHandleBase { }); } - MapHandle? resolveIn(RealmHandle frozenRealm) { + @override + MapHandle? resolveIn(covariant RealmHandle frozenRealm) { return using((arena) { final resultPtr = arena>(); realmLib.realm_dictionary_resolve_in(pointer, frozenRealm.pointer, resultPtr).raiseLastErrorIfFalse(); @@ -161,6 +177,7 @@ class MapHandle extends CollectionHandleBase { }); } + @override NotificationTokenHandle subscribeForNotifications(NotificationsController controller) { return NotificationTokenHandle( realmLib.realm_dictionary_add_notification_callback( diff --git a/packages/realm_dart/lib/src/handles/native/mutable_subscription_set_handle.dart b/packages/realm_dart/lib/src/handles/native/mutable_subscription_set_handle.dart index 16f5fd9ff..f78264362 100644 --- a/packages/realm_dart/lib/src/handles/native/mutable_subscription_set_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/mutable_subscription_set_handle.dart @@ -15,14 +15,18 @@ import 'results_handle.dart'; import 'subscription_handle.dart'; import 'subscription_set_handle.dart'; -class MutableSubscriptionSetHandle extends SubscriptionSetHandle { +import '../mutable_subscription_set_handle.dart' as intf; + +class MutableSubscriptionSetHandle extends SubscriptionSetHandle implements intf.MutableSubscriptionSetHandle { MutableSubscriptionSetHandle(Pointer pointer, RealmHandle root) : super(pointer.cast(), root); Pointer get _mutablePointer => super.pointer.cast(); + @override SubscriptionSetHandle commit() => SubscriptionSetHandle(realmLib.realm_sync_subscription_set_commit(_mutablePointer), root); - SubscriptionHandle insertOrAssignSubscription(ResultsHandle results, String? name, bool update) { + @override + SubscriptionHandle insertOrAssignSubscription(covariant ResultsHandle results, String? name, bool update) { if (!update) { if (name != null && findByName(name) != null) { throw RealmException('Duplicate subscription with name: $name'); @@ -44,7 +48,8 @@ class MutableSubscriptionSetHandle extends SubscriptionSetHandle { }); } - bool erase(SubscriptionHandle subscription) { + @override + bool erase(covariant SubscriptionHandle subscription) { return using((arena) { final outErased = arena(); realmLib @@ -58,6 +63,7 @@ class MutableSubscriptionSetHandle extends SubscriptionSetHandle { }); } + @override bool eraseByName(String name) { return using((arena) { final outErased = arena(); @@ -72,7 +78,8 @@ class MutableSubscriptionSetHandle extends SubscriptionSetHandle { }); } - bool eraseByResults(ResultsHandle results) { + @override + bool eraseByResults(covariant ResultsHandle results) { return using((arena) { final outErased = arena(); realmLib @@ -86,5 +93,11 @@ class MutableSubscriptionSetHandle extends SubscriptionSetHandle { }); } + @override void clear() => realmLib.realm_sync_subscription_set_clear(_mutablePointer).raiseLastErrorIfFalse(); + + @override + // Workaround for weird compiler bug + // ignore: unnecessary_overrides + SubscriptionHandle? findByResults(covariant ResultsHandle results) => super.findByResults(results); } diff --git a/packages/realm_dart/lib/src/handles/native/notification_token_handle.dart b/packages/realm_dart/lib/src/handles/native/notification_token_handle.dart index d72f36676..55a7e7cc4 100644 --- a/packages/realm_dart/lib/src/handles/native/notification_token_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/notification_token_handle.dart @@ -8,7 +8,9 @@ import 'realm_handle.dart'; import 'realm_library.dart'; import 'rooted_handle.dart'; -class NotificationTokenHandle extends RootedHandleBase { +import '../notification_token_handle.dart' as intf; + +class NotificationTokenHandle extends RootedHandleBase implements intf.NotificationTokenHandle { NotificationTokenHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 32); } diff --git a/packages/realm_dart/lib/src/handles/native/object_changes_handle.dart b/packages/realm_dart/lib/src/handles/native/object_changes_handle.dart new file mode 100644 index 000000000..54e183a4c --- /dev/null +++ b/packages/realm_dart/lib/src/handles/native/object_changes_handle.dart @@ -0,0 +1,32 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:ffi'; + +import 'ffi.dart'; +import 'handle_base.dart'; +import 'realm_bindings.dart'; +import 'realm_library.dart'; + +import '../object_changes_handle.dart' as intf; + +class ObjectChangesHandle extends HandleBase implements intf.ObjectChangesHandle { + ObjectChangesHandle(Pointer pointer) : super(pointer, 256); + + @override + bool get isDeleted { + return realmLib.realm_object_changes_is_deleted(pointer); + } + + @override + List get properties { + return using((arena) { + final count = realmLib.realm_object_changes_get_num_modified_properties(pointer); + + final outModified = arena(count); + realmLib.realm_object_changes_get_modified_properties(pointer, outModified, count); + + return outModified.asTypedList(count).toList(); + }); + } +} diff --git a/packages/realm_dart/lib/src/handles/native/object_handle.dart b/packages/realm_dart/lib/src/handles/native/object_handle.dart index 019e85c9e..ecc6e0eed 100644 --- a/packages/realm_dart/lib/src/handles/native/object_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/object_handle.dart @@ -1,6 +1,8 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 +// ignore_for_file: annotate_overrides + import 'dart:ffi'; import '../../realm_dart.dart'; @@ -8,10 +10,10 @@ import 'collection_handle_base.dart'; import 'convert_native.dart'; import 'error_handling.dart'; import 'ffi.dart'; -import 'handle_base.dart'; import 'list_handle.dart'; import 'map_handle.dart'; import 'notification_token_handle.dart'; +import 'object_changes_handle.dart'; import 'realm_bindings.dart'; import 'realm_handle.dart'; import 'realm_library.dart'; @@ -19,13 +21,17 @@ import 'results_handle.dart'; import 'rooted_handle.dart'; import 'set_handle.dart'; -class ObjectHandle extends RootedHandleBase { +import '../object_handle.dart' as intf; + +class ObjectHandle extends RootedHandleBase implements intf.ObjectHandle { ObjectHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 112); + @override ObjectHandle createEmbedded(int propertyKey) { return ObjectHandle(realmLib.realm_set_embedded(pointer, propertyKey), root); } + @override (ObjectHandle, int) get parent { return using((arena) { final parentPtr = arena>(); @@ -38,16 +44,20 @@ class ObjectHandle extends RootedHandleBase { }); } + @override int get classKey => realmLib.realm_object_get_table(pointer); + @override bool get isValid => realmLib.realm_object_is_valid(pointer); + @override Link get asLink { final realmLink = realmLib.realm_object_as_link(pointer); return Link(realmLink); } // TODO: avoid taking the [realm] parameter + @override Object? getValue(Realm realm, int propertyKey) { return using((arena) { final realmValue = arena(); @@ -62,6 +72,7 @@ class ObjectHandle extends RootedHandleBase { // TODO: value should be RealmValue, and perhaps this method should be combined // with setCollection? + @override void setValue(int propertyKey, Object? value, bool isDefault) { using((arena) { final realmValue = value.toNative(arena); @@ -76,22 +87,27 @@ class ObjectHandle extends RootedHandleBase { }); } + @override ListHandle getList(int propertyKey) { return ListHandle(realmLib.realm_get_list(pointer, propertyKey), root); } + @override SetHandle getSet(int propertyKey) { return SetHandle(realmLib.realm_get_set(pointer, propertyKey), root); } + @override MapHandle getMap(int propertyKey) { return MapHandle(realmLib.realm_get_dictionary(pointer, propertyKey), root); } + @override ResultsHandle getBacklinks(int sourceTableKey, int propertyKey) { return ResultsHandle(realmLib.realm_get_backlinks(pointer, sourceTableKey, propertyKey), root); } + @override void setCollection(Realm realm, int propertyKey, RealmValue value) { createCollection( realm, @@ -101,15 +117,17 @@ class ObjectHandle extends RootedHandleBase { ); } + @override String objectToString() { return realmLib.realm_object_to_string(pointer).cast().toRealmDartString(freeRealmMemory: true)!; } + @override void delete() { realmLib.realm_object_delete(pointer).raiseLastErrorIfFalse(); } - ObjectHandle? resolveIn(RealmHandle frozenRealm) { + ObjectHandle? resolveIn(covariant RealmHandle frozenRealm) { return using((arena) { final resultPtr = arena>(); realmLib.realm_object_resolve_in(pointer, frozenRealm.pointer, resultPtr).raiseLastErrorIfFalse(); @@ -117,6 +135,7 @@ class ObjectHandle extends RootedHandleBase { }); } + @override NotificationTokenHandle subscribeForNotifications(NotificationsController controller, [List? keyPaths]) { return using((arena) { final kpNative = buildAndVerifyKeyPath(keyPaths); @@ -151,16 +170,26 @@ class ObjectHandle extends RootedHandleBase { }); } + void verifyKeyPath(List? keyPaths) => buildAndVerifyKeyPath(keyPaths); + @override // equals handled by HandleBase // ignore: hash_and_equals int get hashCode => asLink.hash; } -extension type Link(realm_link_t link) { +class Link implements intf.Link { + final realm_link link; + + Link(this.link); + + @override int get targetKey => link.target; + + @override int get classKey => link.target_table; + @override int get hash => Object.hash(targetKey, classKey); } @@ -185,22 +214,3 @@ void _objectChangeCallback(Pointer userdata, Pointer controller.onError(RealmError("Error handling change notifications. Error: $e")); } } - -class ObjectChangesHandle extends HandleBase { - ObjectChangesHandle(Pointer pointer) : super(pointer, 256); - - bool get isDeleted { - return realmLib.realm_object_changes_is_deleted(pointer); - } - - List get properties { - return using((arena) { - final count = realmLib.realm_object_changes_get_num_modified_properties(pointer); - - final outModified = arena(count); - realmLib.realm_object_changes_get_modified_properties(pointer, outModified, count); - - return outModified.asTypedList(count).toList(); - }); - } -} diff --git a/packages/realm_dart/lib/src/handles/native/realm_handle.dart b/packages/realm_dart/lib/src/handles/native/realm_handle.dart index 8f63fd6b1..7bfb1b2c0 100644 --- a/packages/realm_dart/lib/src/handles/native/realm_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/realm_handle.dart @@ -25,7 +25,9 @@ import 'schema_handle.dart'; import 'session_handle.dart'; import 'subscription_set_handle.dart'; -class RealmHandle extends HandleBase { +import '../realm_handle.dart' as intf; + +class RealmHandle extends HandleBase implements intf.RealmHandle { int _counter = 0; final Map> _children = {}; @@ -41,13 +43,15 @@ class RealmHandle extends HandleBase { .raiseLastErrorIfNull()); } - int addChild(RootedHandleBase child) { + @override + int addChild(covariant RootedHandleBase child) { final id = _counter++; _children[id] = WeakReference(child); rootedHandleFinalizer.attach(this, FinalizationToken(this, id), detach: this); return id; } + @override void removeChild(int id) { final child = _children.remove(id); if (child != null) { @@ -65,6 +69,7 @@ class RealmHandle extends HandleBase { } } + @override ObjectHandle createWithPrimaryKey(int classKey, Object? primaryKey) { return using((arena) { final realmValue = primaryKey.toNative(arena); @@ -72,10 +77,12 @@ class RealmHandle extends HandleBase { }); } + @override ObjectHandle create(int classKey) { return ObjectHandle(realmLib.realm_object_create(pointer, classKey), this); } + @override ObjectHandle getOrCreateWithPrimaryKey(int classKey, Object? primaryKey) { return using((arena) { final realmValue = primaryKey.toNative(arena); @@ -92,6 +99,7 @@ class RealmHandle extends HandleBase { }); } + @override bool compact() { return using((arena) { final outDidCompact = arena(); @@ -100,11 +108,13 @@ class RealmHandle extends HandleBase { }); } + @override void writeCopy(Configuration config) { final configHandle = ConfigHandle.from(config); realmLib.realm_convert_with_config(pointer, configHandle.pointer, false).raiseLastErrorIfFalse(); } + @override ResultsHandle queryClass(int classKey, String query, List args) { return using((arena) { final length = args.length; @@ -126,40 +136,50 @@ class RealmHandle extends HandleBase { }); } + @override RealmHandle freeze() => RealmHandle(realmLib.realm_freeze(pointer)); + @override SessionHandle getSession() { return SessionHandle(realmLib.realm_sync_session_get(pointer), this); } + @override bool get isFrozen { return realmLib.realm_is_frozen(pointer.cast()); } + @override SubscriptionSetHandle get subscriptions { return SubscriptionSetHandle(realmLib.realm_sync_get_active_subscription_set(pointer), this); } + @override void disableAutoRefreshForTesting() { realmLib.realm_set_auto_refresh(pointer, false); } + @override void close() { realmLib.realm_close(pointer).raiseLastErrorIfFalse(); } + @override bool get isClosed { return realmLib.realm_is_closed(pointer); } + @override void beginWrite() { realmLib.realm_begin_write(pointer).raiseLastErrorIfFalse(); } + @override void commitWrite() { realmLib.realm_commit(pointer).raiseLastErrorIfFalse(); } + @override Future beginWriteAsync(CancellationToken? ct) { int? id; final completer = CancellableCompleter(ct, onCancel: () { @@ -186,6 +206,7 @@ class RealmHandle extends HandleBase { return completer.future; } + @override Future commitWriteAsync(CancellationToken? ct) { int? id; final completer = CancellableCompleter(ct, onCancel: () { @@ -250,6 +271,7 @@ class RealmHandle extends HandleBase { }); } + @override Future refreshAsync() async { final completer = Completer(); final callback = Pointer.fromFunction)>(_realmRefreshAsyncCallback); @@ -271,10 +293,12 @@ class RealmHandle extends HandleBase { completer.complete(true); } + @override ResultsHandle findAll(int classKey) { return ResultsHandle(realmLib.realm_object_find_all(pointer, classKey), this); } + @override ObjectHandle? find(int classKey, Object? primaryKey) { return using((arena) { final realmValue = primaryKey.toNative(arena); @@ -288,12 +312,14 @@ class RealmHandle extends HandleBase { }); } - ObjectHandle? findExisting(int classKey, ObjectHandle other) { + @override + ObjectHandle? findExisting(int classKey, covariant ObjectHandle other) { final key = realmLib.realm_object_get_key(other.pointer); return ObjectHandle(realmLib.realm_get_object(pointer, classKey, key), this); } - void renameProperty(String objectType, String oldName, String newName, SchemaHandle schema) { + @override + void renameProperty(String objectType, String oldName, String newName, covariant SchemaHandle schema) { using((arena) { realmLib .realm_schema_rename_property( @@ -307,6 +333,7 @@ class RealmHandle extends HandleBase { }); } + @override bool deleteType(String objectType) { return using((arena) { final tableDeleted = arena(); @@ -315,10 +342,12 @@ class RealmHandle extends HandleBase { }); } + @override ObjectHandle getObject(int classKey, int objectKey) { return ObjectHandle(realmLib.realm_get_object(pointer, classKey, objectKey), this); } + @override CallbackTokenHandle subscribeForSchemaNotifications(Realm realm) { return CallbackTokenHandle( realmLib.realm_add_schema_changed_callback( @@ -331,6 +360,7 @@ class RealmHandle extends HandleBase { ); } + @override RealmSchema readSchema() { return using((arena) { return _readSchema(arena); @@ -397,12 +427,14 @@ class RealmHandle extends HandleBase { return SchemaObject(baseType, type, name, result); } + @override Map getPropertiesMetadata(int classKey, String? primaryKeyName) { return using((arena) { return _getPropertiesMetadata(classKey, primaryKeyName, arena); }); } + @override RealmObjectMetadata getObjectMetadata(SchemaObject schema) { return using((arena) { final found = arena(); @@ -438,7 +470,7 @@ class RealmHandle extends HandleBase { } } -class CallbackTokenHandle extends RootedHandleBase { +class CallbackTokenHandle extends RootedHandleBase implements intf.CallbackTokenHandle { CallbackTokenHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 32); } diff --git a/packages/realm_dart/lib/src/handles/native/results_handle.dart b/packages/realm_dart/lib/src/handles/native/results_handle.dart index 9fa5c1ab6..43c32a06f 100644 --- a/packages/realm_dart/lib/src/handles/native/results_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/results_handle.dart @@ -16,9 +16,12 @@ import 'realm_handle.dart'; import 'realm_library.dart'; import 'rooted_handle.dart'; -class ResultsHandle extends RootedHandleBase { +import '../results_handle.dart' as intf; + +class ResultsHandle extends RootedHandleBase implements intf.ResultsHandle { ResultsHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 872); + @override ResultsHandle queryResults(String query, List args) { return using((arena) { final length = args.length; @@ -39,6 +42,7 @@ class ResultsHandle extends RootedHandleBase { }); } + @override int find(Object? value) { return using((arena) { final outIndex = arena(); @@ -58,10 +62,12 @@ class ResultsHandle extends RootedHandleBase { }); } + @override ObjectHandle getObjectAt(int index) { return ObjectHandle(realmLib.realm_results_get_object(pointer, index), root); } + @override int get count { return using((arena) { final countPtr = arena(); @@ -70,6 +76,7 @@ class ResultsHandle extends RootedHandleBase { }); } + @override bool isValid() { return using((arena) { final isValid = arena(); @@ -78,18 +85,22 @@ class ResultsHandle extends RootedHandleBase { }); } + @override void deleteAll() { realmLib.realm_results_delete_all(pointer).raiseLastErrorIfFalse(); } + @override ResultsHandle snapshot() { return ResultsHandle(realmLib.realm_results_snapshot(pointer), root); } - ResultsHandle resolveIn(RealmHandle realmHandle) { + @override + ResultsHandle resolveIn(covariant RealmHandle realmHandle) { return ResultsHandle(realmLib.realm_results_resolve_in(pointer, realmHandle.pointer), realmHandle); } + @override Object? elementAt(Realm realm, int index) { return using((arena) { final realmValue = arena(); @@ -102,6 +113,7 @@ class ResultsHandle extends RootedHandleBase { }); } + @override NotificationTokenHandle subscribeForNotifications(NotificationsController controller) { return NotificationTokenHandle( realmLib.realm_results_add_notification_callback( diff --git a/packages/realm_dart/lib/src/handles/native/scheduler_handle.dart b/packages/realm_dart/lib/src/handles/native/scheduler_handle.dart index 4ad210542..c408943bc 100644 --- a/packages/realm_dart/lib/src/handles/native/scheduler_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/scheduler_handle.dart @@ -3,11 +3,14 @@ import 'dart:ffi'; +import '../../scheduler.dart'; import 'handle_base.dart'; import 'realm_bindings.dart'; import 'realm_library.dart'; -class SchedulerHandle extends HandleBase { +import '../scheduler_handle.dart' as intf; + +class SchedulerHandle extends HandleBase implements intf.SchedulerHandle { SchedulerHandle._(Pointer pointer) : super(pointer, 24); factory SchedulerHandle(int isolateId, int sendPort) { @@ -15,8 +18,13 @@ class SchedulerHandle extends HandleBase { return SchedulerHandle._(schedulerPtr); } + @override void invoke(int workQueue) { final queuePointer = Pointer.fromAddress(workQueue); realmLib.realm_scheduler_perform_work(queuePointer); } } + +final schedulerHandle = scheduler.handle as SchedulerHandle; + + diff --git a/packages/realm_dart/lib/src/handles/native/schema_handle.dart b/packages/realm_dart/lib/src/handles/native/schema_handle.dart index 7143cb1b8..00a4896b4 100644 --- a/packages/realm_dart/lib/src/handles/native/schema_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/schema_handle.dart @@ -3,6 +3,8 @@ import 'dart:ffi'; +import 'package:realm_dart/src/handles/scheduler_handle.dart'; + import 'ffi.dart'; import 'package:realm_common/realm_common.dart'; @@ -12,7 +14,9 @@ import 'realm_bindings.dart'; import 'realm_library.dart'; import 'to_native.dart'; -class SchemaHandle extends HandleBase { +import '../schema_handle.dart' as intf; + +class SchemaHandle extends HandleBase implements intf.SchemaHandle { SchemaHandle(Pointer pointer) : super(pointer, 24); SchemaHandle.unowned(super.pointer) : super.unowned(); diff --git a/packages/realm_dart/lib/src/handles/native/session_handle.dart b/packages/realm_dart/lib/src/handles/native/session_handle.dart index e8f20ad23..dcc3415ca 100644 --- a/packages/realm_dart/lib/src/handles/native/session_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/session_handle.dart @@ -4,38 +4,43 @@ import 'dart:ffi'; import 'package:cancellation_token/cancellation_token.dart'; -import 'ffi.dart'; import '../../realm_dart.dart'; -import '../../scheduler.dart'; import '../../session.dart'; +import '../session_handle.dart' as intf; import 'convert_native.dart'; +import 'ffi.dart'; import 'handle_base.dart'; import 'realm_bindings.dart'; import 'realm_handle.dart'; import 'realm_library.dart'; import 'rooted_handle.dart'; +import 'scheduler_handle.dart'; import 'user_handle.dart'; -class SessionHandle extends RootedHandleBase { +class SessionHandle extends RootedHandleBase implements intf.SessionHandle { @override bool get shouldRoot => true; SessionHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 24); + @override String get path { return realmLib.realm_sync_session_get_file_path(pointer).cast().toRealmDartString()!; } + @override ConnectionState get connectionState { final value = realmLib.realm_sync_session_get_connection_state(pointer); return ConnectionState.values[value]; } + @override UserHandle get user { return UserHandle(realmLib.realm_sync_session_get_user(pointer)); } + @override SessionState get state { final value = realmLib.realm_sync_session_get_state(pointer); return _convertCoreSessionState(value); @@ -55,14 +60,17 @@ class SessionHandle extends RootedHandleBase { } } + @override void pause() { realmLib.realm_sync_session_pause(pointer); } + @override void resume() { realmLib.realm_sync_session_resume(pointer); } + @override void raiseError(int errorCode, bool isFatal) { using((arena) { final message = "Simulated session error".toCharPtr(arena); @@ -70,11 +78,12 @@ class SessionHandle extends RootedHandleBase { }); } + @override Future waitForUpload([CancellationToken? cancellationToken]) { final completer = CancellableCompleter(cancellationToken); if (!completer.isCancelled) { final callback = Pointer.fromFunction)>(_waitCompletionCallback); - final userdata = realmLib.realm_dart_userdata_async_new(completer, callback.cast(), scheduler.handle.pointer); + final userdata = realmLib.realm_dart_userdata_async_new(completer, callback.cast(), schedulerHandle.pointer); realmLib.realm_sync_session_wait_for_upload_completion( pointer, realmLib.addresses.realm_dart_sync_wait_for_completion_callback, @@ -85,11 +94,12 @@ class SessionHandle extends RootedHandleBase { return completer.future; } + @override Future waitForDownload([CancellationToken? cancellationToken]) { final completer = CancellableCompleter(cancellationToken); if (!completer.isCancelled) { final callback = Pointer.fromFunction)>(_waitCompletionCallback); - final userdata = realmLib.realm_dart_userdata_async_new(completer, callback.cast(), scheduler.handle.pointer); + final userdata = realmLib.realm_dart_userdata_async_new(completer, callback.cast(), schedulerHandle.pointer); realmLib.realm_sync_session_wait_for_download_completion( pointer, realmLib.addresses.realm_dart_sync_wait_for_completion_callback, @@ -113,9 +123,10 @@ class SessionHandle extends RootedHandleBase { } } + @override SyncSessionNotificationTokenHandle subscribeForConnectionStateNotifications(SessionConnectionStateController controller) { final callback = Pointer.fromFunction(_onConnectionStateChange); - final userdata = realmLib.realm_dart_userdata_async_new(controller, callback.cast(), scheduler.handle.pointer); + final userdata = realmLib.realm_dart_userdata_async_new(controller, callback.cast(), schedulerHandle.pointer); return SyncSessionNotificationTokenHandle( realmLib.realm_sync_session_register_connection_state_change_callback( pointer, @@ -126,6 +137,7 @@ class SessionHandle extends RootedHandleBase { ); } + @override SyncSessionNotificationTokenHandle subscribeForProgressNotifications( ProgressDirection direction, ProgressMode mode, @@ -133,7 +145,7 @@ class SessionHandle extends RootedHandleBase { ) { final isStreaming = mode == ProgressMode.reportIndefinitely; final callback = Pointer.fromFunction(syncProgressCallback); - final userdata = realmLib.realm_dart_userdata_async_new(controller, callback.cast(), scheduler.handle.pointer); + final userdata = realmLib.realm_dart_userdata_async_new(controller, callback.cast(), schedulerHandle.pointer); return SyncSessionNotificationTokenHandle( realmLib.realm_sync_session_register_progress_notifier( pointer, @@ -147,7 +159,8 @@ class SessionHandle extends RootedHandleBase { } } -class SyncSessionNotificationTokenHandle extends HandleBase { +class SyncSessionNotificationTokenHandle extends HandleBase + implements intf.SyncSessionNotificationTokenHandle { SyncSessionNotificationTokenHandle(Pointer pointer) : super(pointer, 32); } diff --git a/packages/realm_dart/lib/src/handles/native/set_handle.dart b/packages/realm_dart/lib/src/handles/native/set_handle.dart index f0a458d87..0a2de4a01 100644 --- a/packages/realm_dart/lib/src/handles/native/set_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/set_handle.dart @@ -16,13 +16,17 @@ import 'realm_library.dart'; import 'results_handle.dart'; import 'rooted_handle.dart'; -class SetHandle extends RootedHandleBase { +import '../set_handle.dart' as intf; + +class SetHandle extends RootedHandleBase implements intf.SetHandle { SetHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 96); + @override ResultsHandle get asResults { return ResultsHandle(realmLib.realm_set_to_results(pointer), root); } + @override ResultsHandle query(String query, List args) { return using((arena) { final length = args.length; @@ -43,6 +47,7 @@ class SetHandle extends RootedHandleBase { }); } + @override bool insert(Object? value) { return using((arena) { final realmValue = value.toNative(arena); @@ -54,6 +59,7 @@ class SetHandle extends RootedHandleBase { } // TODO: avoid taking the [realm] parameter + @override Object? elementAt(Realm realm, int index) { return using((arena) { final realmValue = arena(); @@ -67,6 +73,7 @@ class SetHandle extends RootedHandleBase { }); } + @override bool find(Object? value) { return using((arena) { // TODO: how should this behave for collections @@ -78,6 +85,7 @@ class SetHandle extends RootedHandleBase { }); } + @override bool remove(Object? value) { return using((arena) { // TODO: do we support sets containing mixed collections @@ -88,10 +96,12 @@ class SetHandle extends RootedHandleBase { }); } + @override void clear() { realmLib.realm_set_clear(pointer).raiseLastErrorIfFalse(); } + @override int get size { return using((arena) { final outSize = arena(); @@ -100,15 +110,18 @@ class SetHandle extends RootedHandleBase { }); } + @override bool get isValid { return realmLib.realm_set_is_valid(pointer); } + @override void deleteAll() { realmLib.realm_set_remove_all(pointer).raiseLastErrorIfFalse(); } - SetHandle? resolveIn(RealmHandle frozenRealm) { + @override + SetHandle? resolveIn(covariant RealmHandle frozenRealm) { return using((arena) { final resultPtr = arena>(); realmLib.realm_set_resolve_in(pointer, frozenRealm.pointer, resultPtr).raiseLastErrorIfFalse(); @@ -116,6 +129,7 @@ class SetHandle extends RootedHandleBase { }); } + @override NotificationTokenHandle subscribeForNotifications(NotificationsController controller) { return NotificationTokenHandle( realmLib.realm_set_add_notification_callback( diff --git a/packages/realm_dart/lib/src/handles/native/subscription_handle.dart b/packages/realm_dart/lib/src/handles/native/subscription_handle.dart index e3ffc9d74..b2b6b4fed 100644 --- a/packages/realm_dart/lib/src/handles/native/subscription_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/subscription_handle.dart @@ -9,20 +9,28 @@ import 'handle_base.dart'; import 'realm_bindings.dart'; import 'realm_library.dart'; -class SubscriptionHandle extends HandleBase { +import '../subscription_handle.dart' as intf; +class SubscriptionHandle extends HandleBase implements intf.SubscriptionHandle{ SubscriptionHandle(Pointer pointer) : super(pointer, 184); + @override ObjectId get id => realmLib.realm_sync_subscription_id(pointer).toDart(); + @override String? get name => realmLib.realm_sync_subscription_name(pointer).toDart(); + @override String get objectClassName => realmLib.realm_sync_subscription_object_class_name(pointer).toDart()!; + @override String get queryString => realmLib.realm_sync_subscription_query_string(pointer).toDart()!; + @override DateTime get createdAt => realmLib.realm_sync_subscription_created_at(pointer).toDart(); + @override DateTime get updatedAt => realmLib.realm_sync_subscription_updated_at(pointer).toDart(); - bool equalTo(SubscriptionHandle other) => realmLib.realm_equals(pointer.cast(), other.pointer.cast()); + @override + bool equalTo(covariant SubscriptionHandle other) => realmLib.realm_equals(pointer.cast(), other.pointer.cast()); } diff --git a/packages/realm_dart/lib/src/handles/native/subscription_set_handle.dart b/packages/realm_dart/lib/src/handles/native/subscription_set_handle.dart index fa1b7883f..271291913 100644 --- a/packages/realm_dart/lib/src/handles/native/subscription_set_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/subscription_set_handle.dart @@ -4,39 +4,44 @@ import 'dart:ffi'; import 'package:cancellation_token/cancellation_token.dart'; -import 'ffi.dart'; import '../../realm_dart.dart'; -import '../../scheduler.dart'; +import '../subscription_set_handle.dart' as intf; import 'convert.dart'; import 'convert_native.dart'; import 'error_handling.dart'; +import 'ffi.dart'; import 'mutable_subscription_set_handle.dart'; import 'realm_bindings.dart'; import 'realm_handle.dart'; import 'realm_library.dart'; import 'results_handle.dart'; import 'rooted_handle.dart'; +import 'scheduler_handle.dart'; import 'subscription_handle.dart'; - -class SubscriptionSetHandle extends RootedHandleBase { +class SubscriptionSetHandle extends RootedHandleBase implements intf.SubscriptionSetHandle { @override bool get shouldRoot => true; SubscriptionSetHandle(Pointer pointer, RealmHandle root) : super(root, pointer, 128); + @override void refresh() => realmLib.realm_sync_subscription_set_refresh(pointer).raiseLastErrorIfFalse(); + @override int get size => realmLib.realm_sync_subscription_set_size(pointer); + @override Exception? get error { final error = realmLib.realm_sync_subscription_set_error_str(pointer); final message = error.cast().toRealmDartString(treatEmptyAsNull: true); return message.convert(RealmException.new); } + @override SubscriptionHandle operator [](int index) => SubscriptionHandle(realmLib.realm_sync_subscription_at(pointer, index)); + @override SubscriptionHandle? findByName(String name) { return using((arena) { final result = realmLib.realm_sync_find_subscription_by_name( @@ -47,7 +52,8 @@ class SubscriptionSetHandle extends RootedHandleBase realmLib.realm_sync_subscription_set_version(pointer); + @override SubscriptionSetState get state => SubscriptionSetState.values[realmLib.realm_sync_subscription_set_state(pointer)]; + @override MutableSubscriptionSetHandle toMutable() => MutableSubscriptionSetHandle(realmLib.realm_sync_make_subscription_set_mutable(pointer), root); static void _stateChangeCallback(Object userdata, int state) { @@ -68,11 +77,12 @@ class SubscriptionSetHandle extends RootedHandleBase waitForStateChange(SubscriptionSetState notifyWhen, [CancellationToken? cancellationToken]) { final completer = CancellableCompleter(cancellationToken); if (!completer.isCancelled) { final callback = Pointer.fromFunction(_stateChangeCallback); - final userdata = realmLib.realm_dart_userdata_async_new(completer, callback.cast(), scheduler.handle.pointer); + final userdata = realmLib.realm_dart_userdata_async_new(completer, callback.cast(), schedulerHandle.pointer); realmLib.realm_sync_on_subscription_set_state_change_async(pointer, notifyWhen.index, realmLib.addresses.realm_dart_sync_on_subscription_state_changed_callback, userdata.cast(), realmLib.addresses.realm_dart_userdata_async_free); } diff --git a/packages/realm_dart/lib/src/handles/native/user_handle.dart b/packages/realm_dart/lib/src/handles/native/user_handle.dart index abacd3c87..ff8e2d0c2 100644 --- a/packages/realm_dart/lib/src/handles/native/user_handle.dart +++ b/packages/realm_dart/lib/src/handles/native/user_handle.dart @@ -5,40 +5,44 @@ import 'dart:async'; import 'dart:convert'; import 'dart:ffi'; -import 'ffi.dart'; - import '../../credentials.dart'; import '../../realm_dart.dart'; -import '../../scheduler.dart'; import '../../user.dart'; +import '../user_handle.dart' as intf; import 'app_handle.dart'; import 'convert.dart'; import 'convert_native.dart'; import 'credentials_handle.dart'; import 'error_handling.dart'; +import 'ffi.dart'; import 'handle_base.dart'; import 'realm_bindings.dart'; import 'realm_library.dart'; +import 'scheduler_handle.dart'; -class UserHandle extends HandleBase { +class UserHandle extends HandleBase implements intf.UserHandle { UserHandle(Pointer pointer) : super(pointer, 24); + @override AppHandle get app { return realmLib.realm_user_get_app(pointer).convert(AppHandle.new) ?? (throw RealmException('User does not have an associated app. This is likely due to the user being logged out.')); } + @override UserState get state { final nativeUserState = realmLib.realm_user_get_state(pointer); return UserState.values.fromIndex(nativeUserState); } + @override String get id { final idPtr = realmLib.realm_user_get_identity(pointer).raiseLastErrorIfNull(); final userId = idPtr.cast().toDartString(); return userId; } + @override List get identities { return using((arena) { return _userGetIdentities(arena); @@ -67,31 +71,37 @@ class UserHandle extends HandleBase { return result; } + @override Future logOut() async { realmLib.realm_user_log_out(pointer).raiseLastErrorIfFalse(); } + @override String? get deviceId { final deviceId = realmLib.realm_user_get_device_id(pointer).raiseLastErrorIfNull(); return deviceId.cast().toRealmDartString(treatEmptyAsNull: true, freeRealmMemory: true); } + @override UserProfile get profileData { final data = realmLib.realm_user_get_profile_data(pointer).raiseLastErrorIfNull(); final dynamic profileData = jsonDecode(data.cast().toRealmDartString(freeRealmMemory: true)!); return UserProfile(profileData as Map); } + @override String get refreshToken { final token = realmLib.realm_user_get_refresh_token(pointer).raiseLastErrorIfNull(); return token.cast().toRealmDartString(freeRealmMemory: true)!; } + @override String get accessToken { final token = realmLib.realm_user_get_access_token(pointer).raiseLastErrorIfNull(); return token.cast().toRealmDartString(freeRealmMemory: true)!; } + @override String get path { final syncConfigPtr = realmLib.realm_flx_sync_config_new(pointer).raiseLastErrorIfNull(); try { @@ -102,12 +112,14 @@ class UserHandle extends HandleBase { } } + @override String? get customData { final customDataPtr = realmLib.realm_user_get_custom_data(pointer); return customDataPtr.cast().toRealmDartString(freeRealmMemory: true, treatEmptyAsNull: true); } - Future linkCredentials(AppHandle app, CredentialsHandle credentials) { + @override + Future linkCredentials(covariant AppHandle app, CredentialsHandle credentials) { final completer = Completer(); realmLib .realm_app_link_user( @@ -122,7 +134,8 @@ class UserHandle extends HandleBase { return completer.future; } - Future createApiKey(AppHandle app, String name) { + @override + Future createApiKey(covariant AppHandle app, String name) { return using((arena) { final namePtr = name.toCharPtr(arena); final completer = Completer(); @@ -141,7 +154,8 @@ class UserHandle extends HandleBase { }); } - Future fetchApiKey(AppHandle app, ObjectId id) { + @override + Future fetchApiKey(covariant AppHandle app, ObjectId id) { return using((arena) { final completer = Completer(); final nativeId = id.toNative(arena); @@ -160,7 +174,8 @@ class UserHandle extends HandleBase { }); } - Future> fetchAllApiKeys(AppHandle app) { + @override + Future> fetchAllApiKeys(covariant AppHandle app) { return using((arena) { final completer = Completer>(); realmLib @@ -177,7 +192,8 @@ class UserHandle extends HandleBase { }); } - Future deleteApiKey(AppHandle app, ObjectId id) { + @override + Future deleteApiKey(covariant AppHandle app, ObjectId id) { return using((arena) { final completer = Completer(); final nativeId = id.toNative(arena); @@ -196,7 +212,8 @@ class UserHandle extends HandleBase { }); } - Future disableApiKey(AppHandle app, ObjectId objectId) { + @override + Future disableApiKey(covariant AppHandle app, ObjectId objectId) { return using((arena) { final completer = Completer(); final nativeId = objectId.toNative(arena); @@ -216,7 +233,8 @@ class UserHandle extends HandleBase { }); } - Future enableApiKey(AppHandle app, ObjectId objectId) { + @override + Future enableApiKey(covariant AppHandle app, ObjectId objectId) { return using((arena) { final completer = Completer(); final nativeId = objectId.toNative(arena); @@ -236,9 +254,10 @@ class UserHandle extends HandleBase { }); } + @override UserNotificationTokenHandle subscribeForNotifications(UserNotificationsController controller) { final callback = Pointer.fromFunction(_userChangeCallback); - final userdata = realmLib.realm_dart_userdata_async_new(controller, callback.cast(), scheduler.handle.pointer); + final userdata = realmLib.realm_dart_userdata_async_new(controller, callback.cast(), schedulerHandle.pointer); final notificationToken = realmLib.realm_sync_user_on_state_change_register_callback( pointer, realmLib.addresses.realm_dart_user_change_callback, @@ -249,7 +268,7 @@ class UserHandle extends HandleBase { } } -class UserNotificationTokenHandle extends HandleBase { +class UserNotificationTokenHandle extends HandleBase implements intf.UserNotificationTokenHandle { UserNotificationTokenHandle(Pointer pointer) : super(pointer, 32); } @@ -270,7 +289,7 @@ Pointer createAsyncUserCallbackUserdata(Completer completer) { final userdata = realmLib.realm_dart_userdata_async_new( completer, callback.cast(), - scheduler.handle.pointer, + schedulerHandle.pointer, ); return userdata.cast(); @@ -304,7 +323,7 @@ Pointer _createAsyncApikeyCallbackUserdata(Completer _createAsyncApikeyListCallbackUserdata(Complet final userdata = realmLib.realm_dart_userdata_async_new( completer, callback.cast(), - scheduler.handle.pointer, + schedulerHandle.pointer, ); return userdata.cast(); diff --git a/packages/realm_dart/lib/src/handles/notification_token_handle.dart b/packages/realm_dart/lib/src/handles/notification_token_handle.dart index ddca8f3cc..a1698ea02 100644 --- a/packages/realm_dart/lib/src/handles/notification_token_handle.dart +++ b/packages/realm_dart/lib/src/handles/notification_token_handle.dart @@ -1,5 +1,6 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/notification_token_handle.dart' - if (dart.library.js_interop) 'web/notification_token_handle.dart'; +import 'handle_base.dart'; + +abstract interface class NotificationTokenHandle extends HandleBase {} diff --git a/packages/realm_dart/lib/src/handles/object_changes_handle.dart b/packages/realm_dart/lib/src/handles/object_changes_handle.dart new file mode 100644 index 000000000..6a42fa2d7 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/object_changes_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import 'handle_base.dart'; + +abstract interface class ObjectChangesHandle extends HandleBase { + bool get isDeleted; + List get properties; +} diff --git a/packages/realm_dart/lib/src/handles/object_handle.dart b/packages/realm_dart/lib/src/handles/object_handle.dart index 2fc8c6dd7..a3ceaa60a 100644 --- a/packages/realm_dart/lib/src/handles/object_handle.dart +++ b/packages/realm_dart/lib/src/handles/object_handle.dart @@ -1,5 +1,55 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/object_handle.dart' - if (dart.library.js_interop) 'web/object_handle.dart'; +import '../realm_class.dart'; +import 'handle_base.dart'; +import 'list_handle.dart'; +import 'map_handle.dart'; +import 'notification_token_handle.dart'; +import 'realm_handle.dart'; +import 'results_handle.dart'; +import 'set_handle.dart'; + +abstract interface class ObjectHandle extends HandleBase { + ObjectHandle createEmbedded(int propertyKey); + (ObjectHandle, int) get parent; + + int get classKey; + + bool get isValid; + + Link get asLink; + + // TODO: avoid taking the [realm] parameter + Object? getValue(Realm realm, int propertyKey); + + // TODO: value should be RealmValue, and perhaps this method should be combined + // with setCollection? + void setValue(int propertyKey, Object? value, bool isDefault); + ListHandle getList(int propertyKey); + SetHandle getSet(int propertyKey); + MapHandle getMap(int propertyKey); + ResultsHandle getBacklinks(int sourceTableKey, int propertyKey); + + void setCollection(Realm realm, int propertyKey, RealmValue value); + + String objectToString(); + void delete(); + + ObjectHandle? resolveIn(RealmHandle frozenRealm); + + NotificationTokenHandle subscribeForNotifications(NotificationsController controller, [List? keyPaths]); + + void verifyKeyPath(List? keyPaths); + + @override + // equals handled by HandleBase + // ignore: hash_and_equals + int get hashCode => asLink.hash; +} + +abstract class Link { + int get targetKey; + int get classKey; + int get hash; +} diff --git a/packages/realm_dart/lib/src/handles/realm_handle.dart b/packages/realm_dart/lib/src/handles/realm_handle.dart index 9a2522cc0..a70d0817f 100644 --- a/packages/realm_dart/lib/src/handles/realm_handle.dart +++ b/packages/realm_dart/lib/src/handles/realm_handle.dart @@ -1,5 +1,69 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/realm_handle.dart' - if (dart.library.js_interop) 'web/realm_handle.dart'; +import '../realm_class.dart'; +import '../realm_object.dart'; +import 'handle_base.dart'; +import 'object_handle.dart'; +import 'results_handle.dart'; +import 'schema_handle.dart'; +import 'session_handle.dart'; +import 'subscription_set_handle.dart'; + +import 'native/realm_handle.dart' if (dart.library.js_interop) 'web/realm_handle.dart' as impl; + +abstract interface class RealmHandle extends HandleBase { + factory RealmHandle.open(Configuration config) = impl.RealmHandle.open; + + int addChild(HandleBase child); + void removeChild(int id); + + @override + void releaseCore(); + + ObjectHandle createWithPrimaryKey(int classKey, Object? primaryKey); + + ObjectHandle create(int classKey); + ObjectHandle getOrCreateWithPrimaryKey(int classKey, Object? primaryKey); + + bool compact(); + + void writeCopy(Configuration config); + ResultsHandle queryClass(int classKey, String query, List args); + RealmHandle freeze(); + SessionHandle getSession(); + bool get isFrozen; + + SubscriptionSetHandle get subscriptions; + + void disableAutoRefreshForTesting(); + void close(); + + bool get isClosed; + + void beginWrite(); + + void commitWrite(); + + Future beginWriteAsync(CancellationToken? ct); + Future commitWriteAsync(CancellationToken? ct); + bool get isWritable; + void rollbackWrite(); + bool refresh(); + Future refreshAsync(); + ResultsHandle findAll(int classKey); + ObjectHandle? find(int classKey, Object? primaryKey); + ObjectHandle? findExisting(int classKey, ObjectHandle other); + void renameProperty(String objectType, String oldName, String newName, SchemaHandle schema); + bool deleteType(String objectType); + ObjectHandle getObject(int classKey, int objectKey); + + CallbackTokenHandle subscribeForSchemaNotifications(Realm realm); + + RealmSchema readSchema(); + Map getPropertiesMetadata(int classKey, String? primaryKeyName); + + RealmObjectMetadata getObjectMetadata(SchemaObject schema); +} + +abstract class CallbackTokenHandle extends HandleBase {} diff --git a/packages/realm_dart/lib/src/handles/results_handle.dart b/packages/realm_dart/lib/src/handles/results_handle.dart index d4e4d4c67..69e05cc42 100644 --- a/packages/realm_dart/lib/src/handles/results_handle.dart +++ b/packages/realm_dart/lib/src/handles/results_handle.dart @@ -1,5 +1,28 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/results_handle.dart' - if (dart.library.js_interop) 'web/results_handle.dart'; +import 'package:realm_dart/src/handles/handle_base.dart'; +import 'package:realm_dart/src/handles/notification_token_handle.dart'; + +import '../realm_class.dart'; +import 'object_handle.dart'; +import 'realm_handle.dart'; + +abstract interface class ResultsHandle extends HandleBase { + ResultsHandle queryResults(String query, List args); + + int find(Object? value); + + ObjectHandle getObjectAt(int index); + + int get count; + + bool isValid(); + + void deleteAll(); + ResultsHandle snapshot(); + ResultsHandle resolveIn(RealmHandle realmHandle); + + Object? elementAt(Realm realm, int index); + NotificationTokenHandle subscribeForNotifications(NotificationsController controller); +} diff --git a/packages/realm_dart/lib/src/handles/scheduler_handle.dart b/packages/realm_dart/lib/src/handles/scheduler_handle.dart index b0b88e593..3a3682a7c 100644 --- a/packages/realm_dart/lib/src/handles/scheduler_handle.dart +++ b/packages/realm_dart/lib/src/handles/scheduler_handle.dart @@ -1,5 +1,12 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/scheduler_handle.dart' - if (dart.library.js_interop) 'web/scheduler_handle.dart'; +import 'handle_base.dart'; + +import 'native/scheduler_handle.dart' if (dart.library.js_interop) 'web/scheduler_handle.dart' as impl; + +abstract interface class SchedulerHandle extends HandleBase { + factory SchedulerHandle(int isolateId, int sendPort) = impl.SchedulerHandle; + + void invoke(int workQueue); +} diff --git a/packages/realm_dart/lib/src/handles/schema_handle.dart b/packages/realm_dart/lib/src/handles/schema_handle.dart index 73445a6e2..39d153028 100644 --- a/packages/realm_dart/lib/src/handles/schema_handle.dart +++ b/packages/realm_dart/lib/src/handles/schema_handle.dart @@ -1,5 +1,11 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/schema_handle.dart' - if (dart.library.js_interop) 'web/schema_handle.dart'; +import '../configuration.dart'; +import 'handle_base.dart'; + +import 'native/schema_handle.dart' if (dart.library.js_interop) 'web/schema_handle.dart' as impl; + +abstract interface class SchemaHandle extends HandleBase { + factory SchemaHandle.from(Iterable schema) = impl.SchemaHandle.from; +} diff --git a/packages/realm_dart/lib/src/handles/session_handle.dart b/packages/realm_dart/lib/src/handles/session_handle.dart index ff4b82552..f5c3aeb15 100644 --- a/packages/realm_dart/lib/src/handles/session_handle.dart +++ b/packages/realm_dart/lib/src/handles/session_handle.dart @@ -1,5 +1,35 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/session_handle.dart' - if (dart.library.js_interop) 'web/session_handle.dart'; +import 'package:cancellation_token/cancellation_token.dart'; + +import '../session.dart'; +import 'handle_base.dart'; +import 'user_handle.dart'; + +abstract interface class SessionHandle extends HandleBase { + String get path; + ConnectionState get connectionState; + + UserHandle get user; + + SessionState get state; + + void pause(); + + void resume(); + + void raiseError(int errorCode, bool isFatal); + + Future waitForUpload([CancellationToken? cancellationToken]); + Future waitForDownload([CancellationToken? cancellationToken]); + SyncSessionNotificationTokenHandle subscribeForConnectionStateNotifications(SessionConnectionStateController controller); + + SyncSessionNotificationTokenHandle subscribeForProgressNotifications( + ProgressDirection direction, + ProgressMode mode, + SessionProgressNotificationsController controller, + ); +} + +abstract interface class SyncSessionNotificationTokenHandle extends HandleBase {} \ No newline at end of file diff --git a/packages/realm_dart/lib/src/handles/set_handle.dart b/packages/realm_dart/lib/src/handles/set_handle.dart index 1e1eb1073..bbad63523 100644 --- a/packages/realm_dart/lib/src/handles/set_handle.dart +++ b/packages/realm_dart/lib/src/handles/set_handle.dart @@ -1,5 +1,34 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/set_handle.dart' - if (dart.library.js_interop) 'web/set_handle.dart'; +import 'package:realm_dart/src/handles/handle_base.dart'; + +import '../realm_class.dart'; +import 'notification_token_handle.dart'; +import 'realm_handle.dart'; +import 'results_handle.dart'; + +abstract interface class SetHandle extends HandleBase { + ResultsHandle get asResults; + + ResultsHandle query(String query, List args); + + bool insert(Object? value); + + // TODO: avoid taking the [realm] parameter + Object? elementAt(Realm realm, int index); + bool find(Object? value); + + bool remove(Object? value); + + void clear(); + int get size; + + bool get isValid; + + void deleteAll(); + + SetHandle? resolveIn(RealmHandle frozenRealm); + + NotificationTokenHandle subscribeForNotifications(NotificationsController controller); +} diff --git a/packages/realm_dart/lib/src/handles/subscription_handle.dart b/packages/realm_dart/lib/src/handles/subscription_handle.dart index 10f79f5d7..7f3cc40e9 100644 --- a/packages/realm_dart/lib/src/handles/subscription_handle.dart +++ b/packages/realm_dart/lib/src/handles/subscription_handle.dart @@ -1,5 +1,16 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/subscription_handle.dart' - if (dart.library.js_interop) 'web/subscription_handle.dart'; +import 'package:realm_common/realm_common.dart'; + +import 'handle_base.dart'; + +abstract interface class SubscriptionHandle extends HandleBase { + ObjectId get id; + String? get name; + String get objectClassName; + String get queryString; + DateTime get createdAt; + DateTime get updatedAt; + bool equalTo(SubscriptionHandle other); +} diff --git a/packages/realm_dart/lib/src/handles/subscription_set_handle.dart b/packages/realm_dart/lib/src/handles/subscription_set_handle.dart index 452510a76..82a2e1abe 100644 --- a/packages/realm_dart/lib/src/handles/subscription_set_handle.dart +++ b/packages/realm_dart/lib/src/handles/subscription_set_handle.dart @@ -1,5 +1,31 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/subscription_set_handle.dart' - if (dart.library.js_interop) 'web/subscription_set_handle.dart'; +import 'package:cancellation_token/cancellation_token.dart'; + +import '../subscription.dart'; +import 'handle_base.dart'; +import 'mutable_subscription_set_handle.dart'; +import 'results_handle.dart'; +import 'subscription_handle.dart'; + +abstract class SubscriptionSetHandle extends HandleBase { + void refresh(); + + int get size; + + Exception? get error; + + SubscriptionHandle operator [](int index); + + SubscriptionHandle? findByName(String name); + + SubscriptionHandle? findByResults(ResultsHandle results); + + int get version; + SubscriptionSetState get state; + + MutableSubscriptionSetHandle toMutable(); + + Future waitForStateChange(SubscriptionSetState notifyWhen, [CancellationToken? cancellationToken]); +} diff --git a/packages/realm_dart/lib/src/handles/user_handle.dart b/packages/realm_dart/lib/src/handles/user_handle.dart index 1060b55ea..cf498b10f 100644 --- a/packages/realm_dart/lib/src/handles/user_handle.dart +++ b/packages/realm_dart/lib/src/handles/user_handle.dart @@ -1,5 +1,33 @@ // Copyright 2024 MongoDB, Inc. // SPDX-License-Identifier: Apache-2.0 -export 'native/user_handle.dart' - if (dart.library.js_interop) 'web/user_handle.dart'; +import 'package:realm_common/realm_common.dart'; + +import '../user.dart'; +import 'app_handle.dart'; +import 'credentials_handle.dart'; +import 'handle_base.dart'; + +abstract interface class UserHandle extends HandleBase { + AppHandle get app; + UserState get state; + String get id; + List get identities; + Future logOut(); + String? get deviceId; + UserProfile get profileData; + String get refreshToken; + String get accessToken; + String get path; + String? get customData; + Future linkCredentials(AppHandle app, CredentialsHandle credentials); + Future createApiKey(AppHandle app, String name); + Future fetchApiKey(AppHandle app, ObjectId id); + Future> fetchAllApiKeys(AppHandle app); + Future deleteApiKey(AppHandle app, ObjectId id); + Future disableApiKey(AppHandle app, ObjectId objectId); + Future enableApiKey(AppHandle app, ObjectId objectId); + UserNotificationTokenHandle subscribeForNotifications(UserNotificationsController controller); +} + +abstract interface class UserNotificationTokenHandle extends HandleBase {} diff --git a/packages/realm_dart/lib/src/handles/web/app_handle.dart b/packages/realm_dart/lib/src/handles/web/app_handle.dart new file mode 100644 index 000000000..45556bdeb --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/app_handle.dart @@ -0,0 +1,13 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../../../realm.dart'; +import '../app_handle.dart' as intf; + +class AppHandle implements intf.AppHandle { + factory AppHandle.from(AppConfiguration configuration) => throw UnsupportedError('web not supported'); + static AppHandle? get(String id, String? baseUrl) => throw UnsupportedError('web not supported'); + + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/async_open_task_handle.dart b/packages/realm_dart/lib/src/handles/web/async_open_task_handle.dart new file mode 100644 index 000000000..12225d979 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/async_open_task_handle.dart @@ -0,0 +1,14 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../async_open_task_handle.dart' as intf; + +class AsyncOpenTaskHandle implements intf.AsyncOpenTaskHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} + +abstract class AsyncOpenTaskProgressNotificationTokenHandle implements intf.AsyncOpenTaskProgressNotificationTokenHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/collection_changes_handle.dart b/packages/realm_dart/lib/src/handles/web/collection_changes_handle.dart new file mode 100644 index 000000000..7bc265a76 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/collection_changes_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../collection_changes_handle.dart' as intf; + +class CollectionChangesHandle implements intf.CollectionChangesHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/handle_base.dart b/packages/realm_dart/lib/src/handles/web/handle_base.dart new file mode 100644 index 000000000..9d2c26ff0 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/handle_base.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../handle_base.dart' as intf; + +class HandleBase implements intf.HandleBase { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/list_handle.dart b/packages/realm_dart/lib/src/handles/web/list_handle.dart new file mode 100644 index 000000000..9f8180a35 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/list_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../list_handle.dart' as intf; + +class ListHandle implements intf.ListHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/map_changes_handle.dart b/packages/realm_dart/lib/src/handles/web/map_changes_handle.dart new file mode 100644 index 000000000..9e7d0f6ed --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/map_changes_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../map_changes_handle.dart' as intf; + +abstract class MapChangesHandle implements intf.MapChangesHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} \ No newline at end of file diff --git a/packages/realm_dart/lib/src/handles/web/map_handle.dart b/packages/realm_dart/lib/src/handles/web/map_handle.dart new file mode 100644 index 000000000..28970217a --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/map_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../map_handle.dart' as intf; + +class MapHandle implements intf.MapHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/object_changes_handle.dart b/packages/realm_dart/lib/src/handles/web/object_changes_handle.dart new file mode 100644 index 000000000..300cb34a4 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/object_changes_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../object_changes_handle.dart' as intf; + +class ObjectChangesHandle implements intf.ObjectChangesHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/object_handle.dart b/packages/realm_dart/lib/src/handles/web/object_handle.dart new file mode 100644 index 000000000..ba1be46fd --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/object_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../object_handle.dart' as intf; + +class ObjectHandle implements intf.ObjectHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/realm_handle.dart b/packages/realm_dart/lib/src/handles/web/realm_handle.dart new file mode 100644 index 000000000..9521293dd --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/realm_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../realm_handle.dart' as intf; + +class RealmHandle implements intf.RealmHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/results_handle.dart b/packages/realm_dart/lib/src/handles/web/results_handle.dart new file mode 100644 index 000000000..142779085 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/results_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../results_handle.dart' as intf; + +class ResultsHandle implements intf.ResultsHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/set_handle.dart b/packages/realm_dart/lib/src/handles/web/set_handle.dart new file mode 100644 index 000000000..7eb07ad3f --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/set_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../set_handle.dart' as intf; + +class SetHandle implements intf.SetHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/subscription_handle.dart b/packages/realm_dart/lib/src/handles/web/subscription_handle.dart new file mode 100644 index 000000000..dab3f79c5 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/subscription_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../subscription_handle.dart' as intf; + +class SubscriptionHandle implements intf.SubscriptionHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/subscription_set_handle.dart b/packages/realm_dart/lib/src/handles/web/subscription_set_handle.dart new file mode 100644 index 000000000..69d710bd4 --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/subscription_set_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../subscription_set_handle.dart' as intf; + +class SubscriptionSetHandle implements intf.SubscriptionSetHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/handles/web/user_handle.dart b/packages/realm_dart/lib/src/handles/web/user_handle.dart new file mode 100644 index 000000000..baeef586a --- /dev/null +++ b/packages/realm_dart/lib/src/handles/web/user_handle.dart @@ -0,0 +1,9 @@ +// Copyright 2024 MongoDB, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import '../user_handle.dart' as intf; + +class UserHandle implements intf.UserHandle { + @override + noSuchMethod(Invocation invocation) => throw UnsupportedError('web not supported'); +} diff --git a/packages/realm_dart/lib/src/realm_class.dart b/packages/realm_dart/lib/src/realm_class.dart index d4c435113..ce4bcfebc 100644 --- a/packages/realm_dart/lib/src/realm_class.dart +++ b/packages/realm_dart/lib/src/realm_class.dart @@ -365,7 +365,6 @@ class Realm { T write(T Function() writeCallback) { assert(!_isFuture(), 'writeCallback must be synchronous'); final transaction = beginWrite(); - try { T result = writeCallback(); transaction.commit(); diff --git a/packages/realm_dart/lib/src/realm_object.dart b/packages/realm_dart/lib/src/realm_object.dart index 4f2165602..f9c77720b 100644 --- a/packages/realm_dart/lib/src/realm_object.dart +++ b/packages/realm_dart/lib/src/realm_object.dart @@ -9,6 +9,7 @@ import 'package:realm_common/realm_common.dart'; import 'configuration.dart'; import 'handles/handle_base.dart'; import 'handles/notification_token_handle.dart'; +import 'handles/object_changes_handle.dart'; import 'handles/object_handle.dart'; import 'handles/realm_library.dart'; import 'list.dart'; @@ -175,6 +176,7 @@ class RealmCoreAccessor implements RealmAccessor { if (listMetadata != null && _isTypeGenericObject()) { switch (listMetadata.schema.baseType) { case ObjectType.realmObject: + //ManagedRealmList._(handle, object.realm, listMetadata); return object.realm.createList(handle, listMetadata); case ObjectType.embeddedObject: return object.realm.createList(handle, listMetadata); @@ -758,7 +760,7 @@ class RealmObjectNotificationsController extends Noti throw RealmException("It is not allowed to have empty key paths."); } // throw early if the key paths are invalid - realmObject.handle.buildAndVerifyKeyPath(keyPaths); + realmObject.handle.verifyKeyPath(keyPaths); } } diff --git a/packages/realm_dart/lib/src/subscription.dart b/packages/realm_dart/lib/src/subscription.dart index 12bf8c6c1..2fc945854 100644 --- a/packages/realm_dart/lib/src/subscription.dart +++ b/packages/realm_dart/lib/src/subscription.dart @@ -111,11 +111,9 @@ enum SubscriptionSetState { /// {@category Sync} sealed class SubscriptionSet with Iterable { final Realm _realm; - SubscriptionSetHandle __handle; - SubscriptionSetHandle get _handle => __handle.nullPtrAsNull ?? (throw RealmClosedError('Cannot access a SubscriptionSet that belongs to a closed Realm')); - set _handle(SubscriptionSetHandle value) => __handle = value; + SubscriptionSetHandle _handle; - SubscriptionSet._(this._realm, this.__handle); + SubscriptionSet._(this._realm, this._handle); /// Finds an existing [Subscription] in this set by its query /// diff --git a/packages/realm_dart/test/subscription_test.dart b/packages/realm_dart/test/subscription_test.dart index ab9fa7f2e..819fbee6d 100644 --- a/packages/realm_dart/test/subscription_test.dart +++ b/packages/realm_dart/test/subscription_test.dart @@ -6,11 +6,10 @@ import 'dart:io'; import 'dart:math'; import 'dart:typed_data'; -import 'package:test/expect.dart' hide throws; - import 'package:realm_dart/realm.dart'; import 'package:realm_dart/src/handles/realm_core.dart'; import 'package:realm_dart/src/subscription.dart'; + import 'test.dart'; void main() { @@ -549,7 +548,7 @@ void main() { expect(() => subscriptions.state, returnsNormally); realm.close(); - expect(() => subscriptions.state, throws()); + expect(() => subscriptions.state, throws()); }); baasTest('SyncSessionErrorCode.compensatingWrite', (configuration) async {