Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

RDART-930: Refactor handles #1550

Merged
merged 68 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
891f72d
Refactor handles subscription.dart
nielsenko Mar 11, 2024
877b99e
Refactor: use import over part for handle_base.dart
nielsenko Mar 12, 2024
1db5918
Fix regression: Check if close on handle deref
nielsenko Mar 12, 2024
8eeb897
TMP: Skip some tests (something broke with RootedHandle)
nielsenko Mar 12, 2024
8d8b6e5
Ups!
nielsenko Mar 12, 2024
47f98af
Wip
nielsenko Mar 12, 2024
4f0e48c
After rebase
nielsenko Mar 20, 2024
b626fab
wip
nielsenko Mar 27, 2024
4d7d979
Fix after rebase
nielsenko Apr 12, 2024
1664e9a
Revert "TMP: Skip some tests (something broke with RootedHandle)"
nielsenko Apr 12, 2024
26db1ad
Use dart_test.yaml to configure tags. Make baas a tag instead of a pr…
nielsenko Apr 12, 2024
f16caef
Fix nullPtr related bug
nielsenko Apr 12, 2024
a33bd25
Doh! I'll go die in shame!!
nielsenko Apr 12, 2024
fe80da4
Refactor RealmHandle
nielsenko Apr 12, 2024
0b6d1b6
Refactor ConfigHandle
nielsenko Apr 13, 2024
9cb1337
Refactor _RealmQueryHandler (now QueryHandle)
nielsenko Apr 13, 2024
df00b0e
Refactor RealmObjectHandle (now ObjectHandle)
nielsenko Apr 13, 2024
03b864f
Refactor RealmResultHandle (now ResultsHandle)
nielsenko Apr 13, 2024
789eb61
More RealmHandle stuff
nielsenko Apr 13, 2024
79ecfc5
Don't need Tuple
nielsenko Apr 13, 2024
3a967da
Expose disableAutoRefreshForTesting
nielsenko Apr 13, 2024
89550b4
Refactor UserHandle
nielsenko Apr 13, 2024
e867005
RealmHandle.findAll
nielsenko Apr 13, 2024
77338d0
Realm.find/.findExiting/.renameProperty
nielsenko Apr 13, 2024
91c5229
Drop superfluous this.
nielsenko Apr 13, 2024
3265692
Refactor AppHandle
nielsenko Apr 13, 2024
516f65c
Refactor SchedulerHandle
nielsenko Apr 13, 2024
ac78305
Move config handles
nielsenko Apr 13, 2024
eb60375
Refactor SessionHandle
nielsenko Apr 13, 2024
ff70878
UserHandle.linkCredentials/.createApiKey/.fetchApiKey/.fetchAllApiKey…
nielsenko Apr 14, 2024
72c42f2
Refactor RealmListHandle (now ListHandle)
nielsenko Apr 15, 2024
1b0b535
Refactor RealmSetHandle (now SetHandle)
nielsenko Apr 15, 2024
769671d
Refactor RealmAppCredentialsHandle (now CredentialsHandle)
nielsenko Apr 15, 2024
e5addc3
WIP
nielsenko Apr 16, 2024
f0f1e03
WIP2
nielsenko Apr 18, 2024
7725757
Organize imports
nielsenko Apr 23, 2024
b7197a2
ResultsHandle stuff
nielsenko Apr 23, 2024
b914d0e
More UserHandle stuff
nielsenko Apr 23, 2024
59fbdef
subscribeForSchemaNotification (something rubs me the wrong way about…
nielsenko Apr 23, 2024
72322d9
Move MapHandle.query
nielsenko Apr 23, 2024
f0e3ee3
More ObjectHandle stuff
nielsenko Apr 23, 2024
4e7c73c
Move callback functions into handle files
nielsenko Apr 23, 2024
312f90f
Move resolveX to XHandle.resolveIn
nielsenko Apr 23, 2024
b1ebcc5
Make a bunch of function public in prep for getting rid of parts
nielsenko Apr 24, 2024
95ff222
Refactor XChangesHandle
nielsenko Apr 24, 2024
e3e6788
Use CredentialsHandle not Credentils
nielsenko Apr 24, 2024
62ed52a
Traffic in ResultsHandle not RealmResult + dart fix stuff
nielsenko Apr 24, 2024
cd11777
Split part files
nielsenko Apr 25, 2024
5c62750
Move XTokenHandles
nielsenko Apr 25, 2024
0e3acef
toNative extension method replaces toRealmValue function
nielsenko Apr 25, 2024
082686f
Replace last use of deprecated Pointer.elementAt(i)
nielsenko Apr 25, 2024
bfefe18
More RealmHandle stuff
nielsenko Apr 26, 2024
ef67743
Replace invokeGetBool and invokeGetPointer
nielsenko Apr 26, 2024
e262b1d
Run melos custom_format
nielsenko Apr 26, 2024
f311129
Move callAppFunction stuff
nielsenko May 3, 2024
5c8be2e
Refactor equals
nielsenko May 3, 2024
6af1dd9
Move raiseIfNull to HandleBase ctor. Rename to be explicit about call…
nielsenko May 3, 2024
82a0330
Completely unrelated spelling corrections in CHANGELOG
nielsenko May 6, 2024
defc5ae
Seperate AsyncOpenTaskHandle and NotificationHandle from realm_core.dart
nielsenko May 6, 2024
4e359f3
moving guardSynchronousCallback and getApp out of realm_core.dart
nielsenko May 6, 2024
199663e
Split native convertion functions into separate files
nielsenko May 6, 2024
90f2e92
Last leg.. for now
nielsenko May 7, 2024
1922252
PR feedback
nielsenko May 8, 2024
fe9227b
Fix rebase
nielsenko May 13, 2024
8ee2b31
Tweat memEquals perf test
nielsenko May 23, 2024
fe7d582
fixup! Last leg.. for now
nielsenko May 23, 2024
4e75f51
Fix after rebase
nielsenko May 23, 2024
47fefcc
more PR feedback
nielsenko May 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"geospatial",
"HRESULT",
"keepalive",
"keypaths",
"loggable",
"maccatalyst",
"mugaritz",
Expand Down
14 changes: 7 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
* Fixed a `DecryptionFailed` exception thrown when opening a small (<4k of data) Realm generated on a device with a page size of 4k if it was bundled and opened on a device with a larger page size.
* Fixed an issue during a subsequent open of an encrypted Realm for some rare allocation patterns when the top ref was within ~50 bytes of the end of a page. This could manifest as a DecryptionFailed exception or as an assertion: `encrypted_file_mapping.hpp:183: Assertion failed: local_ndx < m_page_state.size()`.
* Schema initialization could hit an assertion failure if the sync client applied a downloaded changeset while the Realm file was in the process of being opened. (Core 14.6.0)
* Improve perfomance of "chained OR equality" queries for UUID/ObjectId types and RQL parsed "IN" queries on string/int/uuid/objectid types. (Core 14.6.0)
* Improve performance of "chained OR equality" queries for UUID/ObjectId types and RQL parsed "IN" queries on string/int/uuid/objectid types. (Core 14.6.0)
* Fixed a bug when running a IN query (or a query of the pattern `x == 1 OR x == 2 OR x == 3`) when evaluating on a string property with an empty string in the search condition. Matches with an empty string would have been evaluated as if searching for a null string instead. (Core 14.6.2)

### Compatibility
Expand Down Expand Up @@ -184,9 +184,9 @@
```
* Removed `SchemaObject.properties` - instead, `SchemaObject` is now an iterable collection of `Property`. (Issue [#1449](https://github.com/realm/realm-dart/issues/1449))
* `SyncProgress.transferredBytes` and `SyncProgress.transferableBytes` have been consolidated into `SyncProgress.progressEstimate`. The values reported previously were incorrect and did not accurately represent bytes either. The new field better conveys the uncertainty around the progress being reported. With this release, we're reporting accurate estimates for upload progress, but estimating downloads is still unreliable. A future server and SDK release will add better estimations for download progress. (Issue [#1562](https://github.com/realm/realm-dart/issues/1562))
* `Realm.logger` is no longer settable, and no longer implements `Logger` from package `logging`. In particular you can no longer call `Realm.logger.level =`. Instead you should call `Realm.logger.setLogLevel(RealmLogLevel level, {RealmLogCategory? category})` that takes an optional category. If no category is exlicitly given, then `RealmLogCategory.realm` is assumed.
* `Realm.logger` is no longer settable, and no longer implements `Logger` from package `logging`. In particular you can no longer call `Realm.logger.level =`. Instead you should call `Realm.logger.setLogLevel(RealmLogLevel level, {RealmLogCategory? category})` that takes an optional category. If no category is explicitly given, then `RealmLogCategory.realm` is assumed.

Also, note that setting a level is no longer local to the current isolate, but shared accross all isolates. At the core level there is just one process wide logger.
Also, note that setting a level is no longer local to the current isolate, but shared across all isolates. At the core level there is just one process wide logger.

Categories form a hierarchy and setting the log level of a parent category will override the level of its children. The hierarchy is exposed in a type safe manner with:
```dart
Expand Down Expand Up @@ -928,7 +928,7 @@ class _Address {
* Queries on results didn't filter the existing results. ([#908](https://github.com/realm/realm-dart/issues/908)).
Example
```dart
expect(realm.query<Person>('FALSEPREDICATE').query('TRUEPREDICATE'), isEmpty); //<-- Fails if a Persion object exists
expect(realm.query<Person>('FALSEPREDICATE').query('TRUEPREDICATE'), isEmpty); //<-- Fails if a Person object exists
```
* Fixed copying of native structs for session errors and http requests. ([#924](https://github.com/realm/realm-dart/pull/924))
* Fixed a crash when closing the SyncSession on App instance teardown. ([#5752](https://github.com/realm/realm-core/issues/5752))
Expand Down Expand Up @@ -1091,7 +1091,7 @@ class _Address {

```dart
final subscription = realm.all<Dog>().changes.listen((changes) {
changes.inserted // indexes of inserted ojbects
changes.inserted // indexes of inserted objects
changes.modified // indexes of modified objects
changes.deleted // indexes of deleted objects
changes.newModified // indexes of modified objects after deletions and insertions are accounted for.
Expand Down Expand Up @@ -1231,7 +1231,7 @@ Notes: This release is a prerelease version. All API's might change without warn
Notes: This release is a prerelease version. All API's might change without warning and no guarantees are given about stability.

### Enhancements
* Completеly rewritten from the ground up with sound null safety and using Dart FFI
* Completely rewritten from the ground up with sound null safety and using Dart FFI

### Fixed
* Realm close stops internal scheduler.
Expand All @@ -1247,7 +1247,7 @@ Notes: This release is a prerelease version. All API's might change without warn
Notes: This release is a prerelease version. All API's might change without warning and no guarantees are given about stability.

### Enhancements
* Completеly rewritten from the ground up with sound null safety and using Dart FFI
* Completely rewritten from the ground up with sound null safety and using Dart FFI

### Compatibility
* Dart ^2.15 on Windows, MacOS and Linux
Expand Down
1 change: 0 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ linter:
rules:
avoid_relative_lib_imports: false
package_api_docs: true
dangling_library_doc_comments: false

# For more information about the core and recommended set of lints, see
# https://dart.dev/go/core-lints
Expand Down
2 changes: 1 addition & 1 deletion packages/realm/bin/realm.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2021 MongoDB, Inc.
// SPDX-License-Identifier: Apache-2.0


import 'package:realm_dart/src/cli/main.dart' as x;

void main(List<String> arguments) => x.main(arguments);
8 changes: 0 additions & 8 deletions packages/realm_common/lib/src/realm_common_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,3 @@ class Backlink {
final Symbol fieldName;
const Backlink(this.fieldName);
}

/// @nodoc
class Tuple<T1, T2> {
T1 item1;
T2 item2;

Tuple(this.item1, this.item2);
}
10 changes: 5 additions & 5 deletions packages/realm_common/lib/src/realm_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ enum RealmCollectionType {
map;

String get plural => switch (this) {
RealmCollectionType.list => 'lists',
RealmCollectionType.set => 'sets',
RealmCollectionType.map => 'maps',
_ => 'none'
};
RealmCollectionType.list => 'lists',
RealmCollectionType.set => 'sets',
RealmCollectionType.map => 'maps',
_ => 'none',
};
}

/// A base class of all Realm errors.
Expand Down
2 changes: 1 addition & 1 deletion packages/realm_dart/bin/realm_dart.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2021 MongoDB, Inc.
// SPDX-License-Identifier: Apache-2.0


import 'package:realm_dart/src/cli/main.dart' as x;

void main(List<String> arguments) => x.main(arguments);
2 changes: 2 additions & 0 deletions packages/realm_dart/dart_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tags:
baas: { timeout: 2x }
29 changes: 15 additions & 14 deletions packages/realm_dart/lib/src/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import 'dart:io';
import 'dart:isolate';

import 'package:meta/meta.dart';
import 'package:path/path.dart' as _path;
import 'package:path/path.dart' as path;

import '../realm.dart';
import 'credentials.dart';
import 'logging.dart';
import 'native/app_handle.dart';
import 'native/realm_core.dart';
import 'user.dart';

Expand Down Expand Up @@ -125,7 +126,7 @@ class AppConfiguration {
this.maxConnectionTimeout = const Duration(minutes: 2),
HttpClient? httpClient,
}) : baseUrl = baseUrl ?? Uri.parse(realmCore.getDefaultBaseUrl()),
baseFilePath = baseFilePath ?? Directory(_path.dirname(Configuration.defaultRealmPath)),
baseFilePath = baseFilePath ?? Directory(path.dirname(Configuration.defaultRealmPath)),
httpClient = httpClient ?? _defaultClient {
if (appId == '') {
throw RealmException('Supplied appId must be a non-empty value');
Expand All @@ -144,7 +145,7 @@ class App implements Finalizable {

/// The id of this application. This is the same as the appId in the [AppConfiguration] used to
/// create this [App].
String get id => realmCore.appGetId(this);
String get id => handle.id;

/// Create an app with a particular [AppConfiguration]. This constructor should only be used on the main isolate and,
/// ideally, only once as soon as the app starts.
Expand All @@ -163,26 +164,26 @@ class App implements Finalizable {
/// on the main isolate. If an App hasn't been already constructed with the same id, will return null. This method is safe to call
/// on a background isolate.
static App? getById(String id, {Uri? baseUrl}) {
final handle = realmCore.getApp(id, baseUrl?.toString());
final handle = AppHandle.get(id, baseUrl?.toString());
return handle == null ? null : App._(handle);
}

App._(this._handle);

static AppHandle _createApp(AppConfiguration configuration) {
configuration.baseFilePath.createSync(recursive: true);
return realmCore.createApp(configuration);
return AppHandle.from(configuration);
}

/// Logs in a user with the given credentials.
Future<User> logIn(Credentials credentials) async {
var userHandle = await realmCore.logIn(this, credentials);
var userHandle = await handle.logIn(credentials.handle);
return UserInternal.create(userHandle, this);
}

/// Gets the currently logged in [User]. If none exists, `null` is returned.
User? get currentUser {
final userHandle = realmCore.getCurrentUser(_handle);
final userHandle = _handle.currentUser;
if (userHandle == null) {
return null;
}
Expand All @@ -191,30 +192,30 @@ class App implements Finalizable {

/// Gets all currently logged in users.
Iterable<User> get users {
return realmCore.getUsers(this).map((handle) => UserInternal.create(handle, this));
return handle.users.map((handle) => UserInternal.create(handle, this));
}

/// Removes a [user] and their local data from the device. If the user is logged in, they will be logged out in the process.
Future<void> removeUser(User user) async {
return await realmCore.removeUser(this, user);
return await handle.removeUser(user.handle);
}

/// Deletes a user and all its data from the device as well as the server.
Future<void> deleteUser(User user) async {
return await realmCore.deleteUser(this, user);
return await handle.deleteUser(user.handle);
}

/// Switches the [currentUser] to the one specified in [user].
void switchUser(User user) {
realmCore.switchUser(this, user);
handle.switchUser(user.handle);
}

/// Provide a hint to this app's sync client to reconnect.
/// Useful when the device has been offline and then receives a network reachability update.
///
/// The sync client will always attempt to reconnect eventually, this is just a hint.
void reconnect() {
realmCore.reconnect(this);
handle.reconnect();
}

/// Returns the current value of the base URL used to communicate with the server.
Expand All @@ -223,7 +224,7 @@ class App implements Finalizable {
/// be updated with the new value until that operation has completed.
@experimental
Uri get baseUrl {
return Uri.parse(realmCore.getBaseUrl(this));
return Uri.parse(handle.baseUrl);
}

/// Temporarily overrides the [baseUrl] value from [AppConfiguration] with a new [baseUrl] value
Expand All @@ -237,7 +238,7 @@ class App implements Finalizable {
/// The App will revert to using the value in [AppConfiguration] when it is restarted.
@experimental
Future<void> updateBaseUrl(Uri? baseUrl) async {
return await realmCore.updateBaseUrl(this, baseUrl);
return await handle.updateBaseUrl(baseUrl);
}

/// Returns an instance of [EmailPasswordAuthProvider]
Expand Down
1 change: 0 additions & 1 deletion packages/realm_dart/lib/src/cli/common/archive.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2021 MongoDB, Inc.
// SPDX-License-Identifier: Apache-2.0

///
import 'dart:io';
import 'package:tar/tar.dart';
import 'package:path/path.dart' as path;
Expand Down
2 changes: 1 addition & 1 deletion packages/realm_dart/lib/src/cli/common/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension StringEx on String {

bool isRealmCI = Platform.environment['REALM_CI'] != null;

FutureOr<T?> safe<T>(FutureOr<T> Function() f, {String message = 'Ignoring error', Function(Object e, StackTrace s)? onError}) async {
FutureOr<T?> safe<T>(FutureOr<T> Function() f, {String message = 'Ignoring error', void Function(Object e, StackTrace s)? onError}) async {
try {
return await f();
} catch (e, s) {
Expand Down
8 changes: 3 additions & 5 deletions packages/realm_dart/lib/src/collections.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import 'dart:ffi';
import 'native/realm_core.dart';
import 'native/collection_changes_handle.dart';

/// Contains index information about objects that moved within the same collection.
class Move {
Expand Down Expand Up @@ -47,13 +47,11 @@ class MapChanges {

/// Describes the changes in a Realm collection since the last time the notification callback was invoked.
class RealmCollectionChanges implements Finalizable {
final RealmCollectionChangesHandle _handle;
CollectionChanges? _values;
final CollectionChangesHandle _handle;
late final CollectionChanges _changes = _handle.changes;

RealmCollectionChanges(this._handle);

CollectionChanges get _changes => _values ??= realmCore.getCollectionChanges(_handle);

/// The indexes in the previous version of the collection which have been removed from this one.
List<int> get deleted => _changes.deletions;

Expand Down
15 changes: 10 additions & 5 deletions packages/realm_dart/lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ import 'dart:io';

// ignore: no_leading_underscores_for_library_prefixes
import 'package:path/path.dart' as _path;

import 'app.dart';
import 'init.dart';
import 'logging.dart';
import 'native/from_native.dart';
import 'native/realm_core.dart';
import 'realm_class.dart';
import 'init.dart';
import 'user.dart';

const encryptionKeySize = 64;

/// The signature of a callback used to determine if compaction
/// should be attempted.
///
Expand Down Expand Up @@ -225,8 +230,8 @@ abstract class Configuration implements Finalizable {
return;
}

if (key.length != realmCore.encryptionKeySize) {
throw RealmException("Wrong encryption key size (must be ${realmCore.encryptionKeySize}, but was ${key.length})");
if (key.length != encryptionKeySize) {
throw RealmException("Wrong encryption key size (must be $encryptionKeySize, but was ${key.length})");
}

int notAByteElement = key.firstWhere((e) => e > 255, orElse: () => -1);
Expand Down Expand Up @@ -368,7 +373,7 @@ class FlexibleSyncConfiguration extends Configuration {
}) : super._();

@override
String get _defaultPath => realmCore.getPathForUser(user);
String get _defaultPath => user.handle.path;
}

extension FlexibleSyncConfigurationInternal on FlexibleSyncConfiguration {
Expand Down Expand Up @@ -653,7 +658,7 @@ class ClientResetError extends SyncError {
throw RealmException("Missing `originalFilePath`");
}

return realmCore.immediatelyRunFileActions(_app!, originalFilePath!);
return _app.handle.resetRealm(originalFilePath!);
}
}

Expand Down
Loading
Loading