From 8aa08d77ee001f7937e2989ff570725280b6ce81 Mon Sep 17 00:00:00 2001 From: blagoev Date: Thu, 3 Nov 2022 18:19:42 +0200 Subject: [PATCH 01/21] support realm compact --- CHANGELOG.md | 1 + lib/src/native/realm_core.dart | 8 ++++++++ lib/src/realm_class.dart | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e3890d1c..814e95ab2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Support results of primitives, ie. `RealmResult`. (Issue [#162](https://github.com/realm/realm-dart/issues/162)) * Support notifications on all managed realm lists, including list of primitives, ie. `RealmList.changes` is supported. ([#893](https://github.com/realm/realm-dart/pull/893)) * Support named backlinks on realm models. You can now add and annotate a realm object iterator field with `@Backlink(#fieldName)`. ([#996](https://github.com/realm/realm-dart/pull/996)) +* Added Realm file compaction support. ([#](https://github.com/realm/realm-dart/pull/)) ### Fixed * Fixed a wrong mapping for `AuthProviderType` returned by `User.provider` for google, facebook and apple credentials. diff --git a/lib/src/native/realm_core.dart b/lib/src/native/realm_core.dart index 40eebca36..0e6604235 100644 --- a/lib/src/native/realm_core.dart +++ b/lib/src/native/realm_core.dart @@ -2164,6 +2164,14 @@ class _RealmCore { return completer.future; }); } + + bool compact(Realm realm) { + return using((arena) { + final out_did_compact = arena(); + _realmLib.invokeGetBool(() => _realmLib.realm_compact(realm.handle._pointer, out_did_compact)); + return out_did_compact.value; + }); + } } class LastError { diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index 3854b1cc2..3c9075679 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -483,6 +483,16 @@ class Realm implements Finalizable { throw RealmError('Starting a write transaction on a frozen Realm is not allowed.'); } } + + /// Compacts a Realm file. A Realm file usually contains free/unused space. + /// + /// This method removes this free space and the file size is thereby reduced. + /// Objects within the Realm file are untouched. + /// Note: The file system should have free space for at least a copy of the Realm file. This method must not be called inside a transaction. + /// The Realm file is left untouched if any file operation fails. + bool compact() { + return realmCore.compact(this); + } } /// Provides a scope to safely write data to a [Realm]. Can be created using [Realm.beginWrite] or From f9e22795d20b446f48def5295554c6a005ba106c Mon Sep 17 00:00:00 2001 From: blagoev Date: Thu, 3 Nov 2022 18:34:24 +0200 Subject: [PATCH 02/21] add compact tests --- test/realm_test.dart | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/realm_test.dart b/test/realm_test.dart index 0eada13b6..a8b013303 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1394,6 +1394,44 @@ Future main([List? args]) async { expect(await realmIsCancelled, isTrue); expect(progressReturned, isFalse); }); + + test('Realm - local realm can be compacted', () { + var config = Configuration.local([Car.schema]); + var realm = getRealm(config); + final compacted = realm.compact(); + expect(compacted, true); + }); + + test('Realm - local encrypted realm can be compacted', () { + final config = Configuration.local([Friend.schema], + encryptionKey: generateEncryptionKey(), path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final realm = getRealm(config); + final compacted = realm.compact(); + expect(compacted, true); + }); + + baasTest('Realm - synced realm can be compacted', (appConfiguration) async { + final app = App(appConfiguration); + final credentials = Credentials.anonymous(); + final user = await app.logIn(credentials); + final configuration = Configuration.flexibleSync(user, [Task.schema]); + + final realm = getRealm(configuration); + final compacted = realm.compact(); + expect(compacted, true); + }); + + baasTest('Realm - synced encrypted realm can be compacted', (appConfiguration) async { + final app = App(appConfiguration); + final credentials = Credentials.anonymous(); + final user = await app.logIn(credentials); + List key = List.generate(encryptionKeySize, (i) => random.nextInt(256)); + final configuration = Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + + final realm = getRealm(configuration); + final compacted = realm.compact(); + expect(compacted, true); + }); } List generateEncryptionKey() { From 176fbb2e6efdf25fb85e3bef00e8ed66cc647261 Mon Sep 17 00:00:00 2001 From: blagoev Date: Thu, 3 Nov 2022 18:55:32 +0200 Subject: [PATCH 03/21] add compact in worker isolate test --- test/realm_test.dart | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/test/realm_test.dart b/test/realm_test.dart index a8b013303..a5e923e6b 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -20,6 +20,7 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:isolate'; import 'package:test/test.dart' hide test, throws; import 'package:timezone/timezone.dart' as tz; import 'package:timezone/data/latest.dart' as tz; @@ -1402,6 +1403,19 @@ Future main([List? args]) async { expect(compacted, true); }); + test('Realm - local realm can be compacted in worker isolate', () async { + final receivePort = ReceivePort(); + await Isolate.spawn((SendPort sendPort) { + var config = Configuration.local([Car.schema]); + var realm = getRealm(config); + final compacted = realm.compact(); + Isolate.exit(sendPort, compacted); + }, receivePort.sendPort); + + final compacted = await receivePort.first as bool; + expect(compacted, true); + }); + test('Realm - local encrypted realm can be compacted', () { final config = Configuration.local([Friend.schema], encryptionKey: generateEncryptionKey(), path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); @@ -1426,7 +1440,8 @@ Future main([List? args]) async { final credentials = Credentials.anonymous(); final user = await app.logIn(credentials); List key = List.generate(encryptionKeySize, (i) => random.nextInt(256)); - final configuration = Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final configuration = + Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final realm = getRealm(configuration); final compacted = realm.compact(); From f3398b3c082ba48092d979c60df3b993d3fd4773 Mon Sep 17 00:00:00 2001 From: blagoev Date: Thu, 3 Nov 2022 18:57:17 +0200 Subject: [PATCH 04/21] update pr in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9c5f1270..61a941f41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ * Support results of primitives, ie. `RealmResult`. (Issue [#162](https://github.com/realm/realm-dart/issues/162)) * Support notifications on all managed realm lists, including list of primitives, ie. `RealmList.changes` is supported. ([#893](https://github.com/realm/realm-dart/pull/893)) * Support named backlinks on realm models. You can now add and annotate a realm object iterator field with `@Backlink(#fieldName)`. ([#996](https://github.com/realm/realm-dart/pull/996)) -* Added Realm file compaction support. ([#](https://github.com/realm/realm-dart/pull/)) +* Added Realm file compaction support. ([#1005](https://github.com/realm/realm-dart/pull/1005)) * Allow `@Indexed` attribute on all indexable type, and ensure appropriate indexes are created in the realm. ([#797](https://github.com/realm/realm-dart/issues/797)) ### Fixed From a0b2bfa121f03d1b3cd88212614e5d6c779ac821 Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 09:15:56 +0200 Subject: [PATCH 05/21] refactor compact support --- lib/src/realm_class.dart | 36 ++++++++++++++++++++---- test/realm_test.dart | 61 +++++++++++++++++++++++++++++----------- 2 files changed, 75 insertions(+), 22 deletions(-) diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index 3c9075679..b2d39765e 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -484,14 +484,38 @@ class Realm implements Finalizable { } } - /// Compacts a Realm file. A Realm file usually contains free/unused space. - /// - /// This method removes this free space and the file size is thereby reduced. + /// Compacts a Realm file. A Realm file usually contains free/unused space. + /// + /// This method removes this free space and the file size is thereby reduced. /// Objects within the Realm file are untouched. - /// Note: The file system should have free space for at least a copy of the Realm file. This method must not be called inside a transaction. + /// Note: The file system should have free space for at least a copy of the Realm file. This method must not be called inside a transaction. /// The Realm file is left untouched if any file operation fails. - bool compact() { - return realmCore.compact(this); + static Future compact(Configuration config) { + late Configuration compactConfig; + if (config is LocalConfiguration) { + compactConfig = Configuration.local(config.schemaObjects.toList(), + schemaVersion: config.schemaVersion, + fifoFilesFallbackPath: config.fifoFilesFallbackPath, + path: config.path, + encryptionKey: config.encryptionKey, + disableFormatUpgrade: true, + isReadOnly: false); + } else if (config is FlexibleSyncConfiguration || config is DisconnectedSyncConfiguration) { + compactConfig = Configuration.disconnectedSync(config.schemaObjects.toList(), + fifoFilesFallbackPath: config.fifoFilesFallbackPath, path: config.path, encryptionKey: config.encryptionKey); + } else if (config is InMemoryConfiguration) { + compactConfig = config; + } + else { + throw RealmError("Unsupported realm configuration type ${config.runtimeType}"); + } + + final realm = Realm(compactConfig); + try { + return Future.value(realmCore.compact(realm)); + } finally { + realm.close(); + } } } diff --git a/test/realm_test.dart b/test/realm_test.dart index a5e923e6b..3fa8515b1 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1396,43 +1396,73 @@ Future main([List? args]) async { expect(progressReturned, isFalse); }); - test('Realm - local realm can be compacted', () { - var config = Configuration.local([Car.schema]); - var realm = getRealm(config); - final compacted = realm.compact(); + test('Realm - local realm can be compacted', () async { + var config = Configuration.local([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final compacted = await Realm.compact(config); expect(compacted, true); + + //test the realm can be opened. This also allows the compacted realm to be deleted after the test + final realm = getRealm(config); }); test('Realm - local realm can be compacted in worker isolate', () async { + var config = Configuration.local([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final receivePort = ReceivePort(); - await Isolate.spawn((SendPort sendPort) { - var config = Configuration.local([Car.schema]); - var realm = getRealm(config); - final compacted = realm.compact(); + await Isolate.spawn((List args) async { + SendPort sendPort = args[0] as SendPort; + final path = args[1] as String; + var config = Configuration.local([Car.schema], path: path); + final compacted = await Realm.compact(config); Isolate.exit(sendPort, compacted); - }, receivePort.sendPort); + }, [receivePort.sendPort, config.path]); final compacted = await receivePort.first as bool; expect(compacted, true); + + //test the realm can be opened. This also allows the compacted realm to be deleted after the test + final realm = getRealm(config); }); - test('Realm - local encrypted realm can be compacted', () { + test('Realm - local encrypted realm can be compacted', () async { final config = Configuration.local([Friend.schema], encryptionKey: generateEncryptionKey(), path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final compacted = await Realm.compact(config); + expect(compacted, true); + + //test the realm can be opened. This also allows the compacted realm to be deleted after the test + final realm = getRealm(config); + }); + + test('Realm - in-memory realm can be compacted', () async { + var config = Configuration.inMemory([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final compacted = await Realm.compact(config); + expect(compacted, true); + + //test the realm can be opened. This also allows the compacted realm to be deleted after the test final realm = getRealm(config); - final compacted = realm.compact(); + }); + + test('Realm - disconnected sync realm can be compacted', () async { + var config = Configuration.disconnectedSync([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final compacted = await Realm.compact(config); expect(compacted, true); + + //test the realm can be opened. This also allows the compacted realm to be deleted after the test + final realm = getRealm(config); }); baasTest('Realm - synced realm can be compacted', (appConfiguration) async { final app = App(appConfiguration); final credentials = Credentials.anonymous(); final user = await app.logIn(credentials); - final configuration = Configuration.flexibleSync(user, [Task.schema]); + final config = Configuration.flexibleSync(user, [Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final realm = getRealm(configuration); - final compacted = realm.compact(); + final compacted = await Realm.compact(config); expect(compacted, true); + + //test the realm can be opened. This also allows the compacted realm to be deleted after the test + final realm = getRealm(config); }); baasTest('Realm - synced encrypted realm can be compacted', (appConfiguration) async { @@ -1443,8 +1473,7 @@ Future main([List? args]) async { final configuration = Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final realm = getRealm(configuration); - final compacted = realm.compact(); + final compacted = await Realm.compact(configuration); expect(compacted, true); }); } From 57c14329f42003cf7c8bc0858fa96427eea0d8bb Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 10:03:53 +0200 Subject: [PATCH 06/21] clear realm compaction space files after tests --- test/realm_test.dart | 7 +++++-- test/test.dart | 11 +++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/test/realm_test.dart b/test/realm_test.dart index 3fa8515b1..0e9653476 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1470,11 +1470,14 @@ Future main([List? args]) async { final credentials = Credentials.anonymous(); final user = await app.logIn(credentials); List key = List.generate(encryptionKeySize, (i) => random.nextInt(256)); - final configuration = + final config = Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final compacted = await Realm.compact(configuration); + final compacted = await Realm.compact(config); expect(compacted, true); + + //test the realm can be opened. This also allows the compacted realm to be deleted after the test + final realm = getRealm(config); }); } diff --git a/test/test.dart b/test/test.dart index 70f0ef3ae..66736aeaa 100644 --- a/test/test.dart +++ b/test/test.dart @@ -465,13 +465,20 @@ Future tryDeleteRealm(String path) async { return; } + final dummy = File(""); + const duration = Duration(milliseconds: 100); for (var i = 0; i < 5; i++) { try { Realm.deleteRealm(path); - await File('$path.lock').delete(); + + //delete lock file + await File('$path.lock').delete().onError((error, stackTrace) => dummy); + + //delete compaction space file + await File('$path.tmp_compaction_space').delete().onError((error, stackTrace) => dummy); + return; } catch (e) { - const duration = Duration(milliseconds: 100); print('Failed to delete realm at path $path. Trying again in ${duration.inMilliseconds}ms'); await Future.delayed(duration); } From 224b2eaf6e1640d94e16ea4a3db0e56d1357b732 Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 11:55:08 +0200 Subject: [PATCH 07/21] sych api --- lib/src/realm_class.dart | 4 ++-- test/realm_test.dart | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index b2d39765e..2f323016c 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -490,7 +490,7 @@ class Realm implements Finalizable { /// Objects within the Realm file are untouched. /// Note: The file system should have free space for at least a copy of the Realm file. This method must not be called inside a transaction. /// The Realm file is left untouched if any file operation fails. - static Future compact(Configuration config) { + static bool compact(Configuration config) { late Configuration compactConfig; if (config is LocalConfiguration) { compactConfig = Configuration.local(config.schemaObjects.toList(), @@ -512,7 +512,7 @@ class Realm implements Finalizable { final realm = Realm(compactConfig); try { - return Future.value(realmCore.compact(realm)); + return realmCore.compact(realm); } finally { realm.close(); } diff --git a/test/realm_test.dart b/test/realm_test.dart index 0e9653476..b001e3531 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1398,7 +1398,7 @@ Future main([List? args]) async { test('Realm - local realm can be compacted', () async { var config = Configuration.local([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final compacted = await Realm.compact(config); + final compacted = Realm.compact(config); expect(compacted, true); //test the realm can be opened. This also allows the compacted realm to be deleted after the test @@ -1413,7 +1413,7 @@ Future main([List? args]) async { SendPort sendPort = args[0] as SendPort; final path = args[1] as String; var config = Configuration.local([Car.schema], path: path); - final compacted = await Realm.compact(config); + final compacted = Realm.compact(config); Isolate.exit(sendPort, compacted); }, [receivePort.sendPort, config.path]); @@ -1427,7 +1427,7 @@ Future main([List? args]) async { test('Realm - local encrypted realm can be compacted', () async { final config = Configuration.local([Friend.schema], encryptionKey: generateEncryptionKey(), path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final compacted = await Realm.compact(config); + final compacted = Realm.compact(config); expect(compacted, true); //test the realm can be opened. This also allows the compacted realm to be deleted after the test @@ -1436,7 +1436,7 @@ Future main([List? args]) async { test('Realm - in-memory realm can be compacted', () async { var config = Configuration.inMemory([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final compacted = await Realm.compact(config); + final compacted = Realm.compact(config); expect(compacted, true); //test the realm can be opened. This also allows the compacted realm to be deleted after the test @@ -1445,7 +1445,7 @@ Future main([List? args]) async { test('Realm - disconnected sync realm can be compacted', () async { var config = Configuration.disconnectedSync([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final compacted = await Realm.compact(config); + final compacted = Realm.compact(config); expect(compacted, true); //test the realm can be opened. This also allows the compacted realm to be deleted after the test @@ -1458,7 +1458,7 @@ Future main([List? args]) async { final user = await app.logIn(credentials); final config = Configuration.flexibleSync(user, [Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final compacted = await Realm.compact(config); + final compacted = Realm.compact(config); expect(compacted, true); //test the realm can be opened. This also allows the compacted realm to be deleted after the test @@ -1473,7 +1473,7 @@ Future main([List? args]) async { final config = Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final compacted = await Realm.compact(config); + final compacted = Realm.compact(config); expect(compacted, true); //test the realm can be opened. This also allows the compacted realm to be deleted after the test From f644769aae34b2cd10f8eaf01babedcacff1f06e Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 11:56:54 +0200 Subject: [PATCH 08/21] don't override isreadonly --- lib/src/realm_class.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index 2f323016c..68e83b6e3 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -499,7 +499,7 @@ class Realm implements Finalizable { path: config.path, encryptionKey: config.encryptionKey, disableFormatUpgrade: true, - isReadOnly: false); + isReadOnly: config.isReadOnly); } else if (config is FlexibleSyncConfiguration || config is DisconnectedSyncConfiguration) { compactConfig = Configuration.disconnectedSync(config.schemaObjects.toList(), fifoFilesFallbackPath: config.fifoFilesFallbackPath, path: config.path, encryptionKey: config.encryptionKey); From 87d2116c20768bc4fcaea9993983706aea9af5dc Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 12:02:50 +0200 Subject: [PATCH 09/21] add a test for readonly realm --- test/realm_test.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/realm_test.dart b/test/realm_test.dart index b001e3531..bdb3c6b66 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1443,6 +1443,19 @@ Future main([List? args]) async { final realm = getRealm(config); }); + test('Realm - readonly realm can not be compacted', () async { + var path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); + var config = Configuration.local([Car.schema], path: path); + var realm = getRealm(config); + realm.close(); + + config = Configuration.local([Car.schema], isReadOnly: true, path: path); + expect(() => Realm.compact(config), throws("Can't compact a read-only Realm")); + + //test the realm can be opened. This also allows the compacted realm to be deleted after the test + realm = getRealm(config); + }); + test('Realm - disconnected sync realm can be compacted', () async { var config = Configuration.disconnectedSync([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final compacted = Realm.compact(config); From 20eb5a163c80b4f1579d5296762fc08fa62acf12 Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 12:23:58 +0200 Subject: [PATCH 10/21] format realm_test --- test/realm_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/realm_test.dart b/test/realm_test.dart index bdb3c6b66..b60a40df0 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1400,7 +1400,7 @@ Future main([List? args]) async { var config = Configuration.local([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final compacted = Realm.compact(config); expect(compacted, true); - + //test the realm can be opened. This also allows the compacted realm to be deleted after the test final realm = getRealm(config); }); @@ -1443,7 +1443,7 @@ Future main([List? args]) async { final realm = getRealm(config); }); - test('Realm - readonly realm can not be compacted', () async { + test('Realm - readonly realm can not be compacted', () async { var path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); var config = Configuration.local([Car.schema], path: path); var realm = getRealm(config); @@ -1456,7 +1456,7 @@ Future main([List? args]) async { realm = getRealm(config); }); - test('Realm - disconnected sync realm can be compacted', () async { + test('Realm - disconnected sync realm can be compacted', () async { var config = Configuration.disconnectedSync([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final compacted = Realm.compact(config); expect(compacted, true); From 059efbe91d1ae7d816efc8d54fce96b1bbe33bb1 Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 13:36:04 +0200 Subject: [PATCH 11/21] fix tests --- test/realm_test.dart | 131 +++++++++++++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 30 deletions(-) diff --git a/test/realm_test.dart b/test/realm_test.dart index b60a40df0..8b460610f 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -21,6 +21,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:isolate'; +import 'dart:math'; import 'package:test/test.dart' hide test, throws; import 'package:timezone/timezone.dart' as tz; import 'package:timezone/data/latest.dart' as tz; @@ -1396,72 +1397,132 @@ Future main([List? args]) async { expect(progressReturned, isFalse); }); + void addDataForCompact(Realm realm) { + realm.write(() { + for (var i = 0; i < 2500; i++) { + realm.add(Task(ObjectId())); + } + }); + + realm.write(() => realm.deleteAll()); + + realm.write(() { + for (var i = 10; i < 20; i++) { + realm.add(Task(ObjectId())); + } + }); + } + + Future createRealmForCompact(Configuration config) async { + var realm = getRealm(config); + + if (config is FlexibleSyncConfiguration) { + realm.subscriptions.update((mutableSubscriptions) { + mutableSubscriptions.add(realm.all()); + }); + await realm.subscriptions.waitForSynchronization(); + } + + addDataForCompact(realm); + + final beforeSize = await File(config.path).stat().then((value) => value.size); + + if (config is FlexibleSyncConfiguration) { + await realm.syncSession.waitForDownload(); + await realm.syncSession.waitForUpload(); + } + + realm.close(); + return beforeSize; + } + + void validateCompact(bool compacted, String realmPath, int before) async { + expect(compacted, true); + final afterSize = await File(realmPath).stat().then((value) => value.size); + expect(before, greaterThan(afterSize)); + } + test('Realm - local realm can be compacted', () async { - var config = Configuration.local([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + var config = Configuration.local([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final beforeCompact = await createRealmForCompact(config); + final compacted = Realm.compact(config); - expect(compacted, true); - //test the realm can be opened. This also allows the compacted realm to be deleted after the test + validateCompact(compacted, config.path, beforeCompact); + + //test the realm can be opened. final realm = getRealm(config); }); test('Realm - local realm can be compacted in worker isolate', () async { - var config = Configuration.local([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + var config = Configuration.local([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final beforeCompact = await createRealmForCompact(config); final receivePort = ReceivePort(); await Isolate.spawn((List args) async { SendPort sendPort = args[0] as SendPort; final path = args[1] as String; - var config = Configuration.local([Car.schema], path: path); + var config = Configuration.local([Task.schema], path: path); final compacted = Realm.compact(config); Isolate.exit(sendPort, compacted); }, [receivePort.sendPort, config.path]); final compacted = await receivePort.first as bool; - expect(compacted, true); - //test the realm can be opened. This also allows the compacted realm to be deleted after the test + validateCompact(compacted, config.path, beforeCompact); + + //test the realm can be opened. final realm = getRealm(config); }); test('Realm - local encrypted realm can be compacted', () async { - final config = Configuration.local([Friend.schema], + final config = Configuration.local([Task.schema], encryptionKey: generateEncryptionKey(), path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + + final beforeCompact = await createRealmForCompact(config); + final compacted = Realm.compact(config); - expect(compacted, true); - //test the realm can be opened. This also allows the compacted realm to be deleted after the test + validateCompact(compacted, config.path, beforeCompact); + + //test the realm can be opened. final realm = getRealm(config); }); test('Realm - in-memory realm can be compacted', () async { - var config = Configuration.inMemory([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + var config = Configuration.inMemory([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final beforeCompact = await createRealmForCompact(config); + final compacted = Realm.compact(config); - expect(compacted, true); - //test the realm can be opened. This also allows the compacted realm to be deleted after the test + validateCompact(compacted, config.path, beforeCompact); + + //test the realm can be opened. final realm = getRealm(config); }); test('Realm - readonly realm can not be compacted', () async { var path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); - var config = Configuration.local([Car.schema], path: path); - var realm = getRealm(config); - realm.close(); + var config = Configuration.local([Task.schema], path: path); + final beforeCompact = await createRealmForCompact(config); - config = Configuration.local([Car.schema], isReadOnly: true, path: path); + config = Configuration.local([Task.schema], isReadOnly: true, path: path); expect(() => Realm.compact(config), throws("Can't compact a read-only Realm")); - //test the realm can be opened. This also allows the compacted realm to be deleted after the test - realm = getRealm(config); + //test the realm can be opened. + final realm = getRealm(config); }); test('Realm - disconnected sync realm can be compacted', () async { - var config = Configuration.disconnectedSync([Car.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + var config = Configuration.disconnectedSync([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + + final beforeCompact = await createRealmForCompact(config); + final compacted = Realm.compact(config); - expect(compacted, true); - //test the realm can be opened. This also allows the compacted realm to be deleted after the test + validateCompact(compacted, config.path, beforeCompact); + + //test the realm can be opened. final realm = getRealm(config); }); @@ -1469,28 +1530,38 @@ Future main([List? args]) async { final app = App(appConfiguration); final credentials = Credentials.anonymous(); final user = await app.logIn(credentials); - final config = Configuration.flexibleSync(user, [Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); + final config = Configuration.flexibleSync(user, [Task.schema], path: path); + final beforeCompact = await createRealmForCompact(config); + user.logOut(); + Future.delayed(Duration(seconds: 5)); final compacted = Realm.compact(config); - expect(compacted, true); - //test the realm can be opened. This also allows the compacted realm to be deleted after the test - final realm = getRealm(config); + validateCompact(compacted, config.path, beforeCompact); + + //test the realm can be opened. + final realm = getRealm(Configuration.disconnectedSync([Task.schema], path: path)); }); baasTest('Realm - synced encrypted realm can be compacted', (appConfiguration) async { final app = App(appConfiguration); final credentials = Credentials.anonymous(); + final path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); final user = await app.logIn(credentials); List key = List.generate(encryptionKeySize, (i) => random.nextInt(256)); final config = - Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: path); + final beforeCompact = await createRealmForCompact(config); + user.logOut(); + Future.delayed(Duration(seconds: 5)); final compacted = Realm.compact(config); - expect(compacted, true); - //test the realm can be opened. This also allows the compacted realm to be deleted after the test - final realm = getRealm(config); + validateCompact(compacted, config.path, beforeCompact); + + //test the realm can be opened. + final realm = getRealm(Configuration.disconnectedSync([Task.schema], path: path, encryptionKey: key)); }); } From cfeb8cfb2afe669e4f2aaf8f0827ec823bd6f99b Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 13:52:35 +0200 Subject: [PATCH 12/21] don't allow in-memory realm compact. Makes no sense. --- lib/src/realm_class.dart | 2 +- test/realm_test.dart | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index 68e83b6e3..f70cb4266 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -504,7 +504,7 @@ class Realm implements Finalizable { compactConfig = Configuration.disconnectedSync(config.schemaObjects.toList(), fifoFilesFallbackPath: config.fifoFilesFallbackPath, path: config.path, encryptionKey: config.encryptionKey); } else if (config is InMemoryConfiguration) { - compactConfig = config; + throw RealmException("Can't compact an in-memory Realm"); } else { throw RealmError("Unsupported realm configuration type ${config.runtimeType}"); diff --git a/test/realm_test.dart b/test/realm_test.dart index 8b460610f..a8bba3fdb 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1489,16 +1489,9 @@ Future main([List? args]) async { final realm = getRealm(config); }); - test('Realm - in-memory realm can be compacted', () async { + test('Realm - in-memory realm can not be compacted', () async { var config = Configuration.inMemory([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final beforeCompact = await createRealmForCompact(config); - - final compacted = Realm.compact(config); - - validateCompact(compacted, config.path, beforeCompact); - - //test the realm can be opened. - final realm = getRealm(config); + expect(() => Realm.compact(config), throws("Can't compact an in-memory Realm")); }); test('Realm - readonly realm can not be compacted', () async { From 9cff27d66bfdc09ebe6cb124fa452c5c9e90c40b Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 15:59:50 +0200 Subject: [PATCH 13/21] use custom objects for compact tests --- test/realm_test.dart | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/test/realm_test.dart b/test/realm_test.dart index a8bba3fdb..2086da333 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1397,18 +1397,19 @@ Future main([List? args]) async { expect(progressReturned, isFalse); }); + const compactTest = "compact_test"; void addDataForCompact(Realm realm) { realm.write(() { for (var i = 0; i < 2500; i++) { - realm.add(Task(ObjectId())); + realm.add(Product(ObjectId(), compactTest)); } }); - realm.write(() => realm.deleteAll()); + realm.write(() => realm.deleteMany(realm.query("stringQueryField CONTAINS '$compactTest'"))); realm.write(() { - for (var i = 10; i < 20; i++) { - realm.add(Task(ObjectId())); + for (var i = 0; i < 10; i++) { + realm.add(Product(ObjectId(), compactTest)); } }); } @@ -1418,20 +1419,20 @@ Future main([List? args]) async { if (config is FlexibleSyncConfiguration) { realm.subscriptions.update((mutableSubscriptions) { - mutableSubscriptions.add(realm.all()); + mutableSubscriptions.add(realm.query("stringQueryField CONTAINS '$compactTest'")); }); await realm.subscriptions.waitForSynchronization(); } addDataForCompact(realm); - - final beforeSize = await File(config.path).stat().then((value) => value.size); if (config is FlexibleSyncConfiguration) { await realm.syncSession.waitForDownload(); await realm.syncSession.waitForUpload(); } + final beforeSize = await File(config.path).stat().then((value) => value.size); + realm.close(); return beforeSize; } @@ -1443,7 +1444,7 @@ Future main([List? args]) async { } test('Realm - local realm can be compacted', () async { - var config = Configuration.local([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + var config = Configuration.local([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final beforeCompact = await createRealmForCompact(config); final compacted = Realm.compact(config); @@ -1455,14 +1456,14 @@ Future main([List? args]) async { }); test('Realm - local realm can be compacted in worker isolate', () async { - var config = Configuration.local([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + var config = Configuration.local([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final beforeCompact = await createRealmForCompact(config); final receivePort = ReceivePort(); await Isolate.spawn((List args) async { SendPort sendPort = args[0] as SendPort; final path = args[1] as String; - var config = Configuration.local([Task.schema], path: path); + var config = Configuration.local([Product.schema], path: path); final compacted = Realm.compact(config); Isolate.exit(sendPort, compacted); }, [receivePort.sendPort, config.path]); @@ -1476,7 +1477,7 @@ Future main([List? args]) async { }); test('Realm - local encrypted realm can be compacted', () async { - final config = Configuration.local([Task.schema], + final config = Configuration.local([Product.schema], encryptionKey: generateEncryptionKey(), path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final beforeCompact = await createRealmForCompact(config); @@ -1490,16 +1491,16 @@ Future main([List? args]) async { }); test('Realm - in-memory realm can not be compacted', () async { - var config = Configuration.inMemory([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + var config = Configuration.inMemory([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); expect(() => Realm.compact(config), throws("Can't compact an in-memory Realm")); }); test('Realm - readonly realm can not be compacted', () async { var path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); - var config = Configuration.local([Task.schema], path: path); + var config = Configuration.local([Product.schema], path: path); final beforeCompact = await createRealmForCompact(config); - config = Configuration.local([Task.schema], isReadOnly: true, path: path); + config = Configuration.local([Product.schema], isReadOnly: true, path: path); expect(() => Realm.compact(config), throws("Can't compact a read-only Realm")); //test the realm can be opened. @@ -1507,7 +1508,7 @@ Future main([List? args]) async { }); test('Realm - disconnected sync realm can be compacted', () async { - var config = Configuration.disconnectedSync([Task.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + var config = Configuration.disconnectedSync([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final beforeCompact = await createRealmForCompact(config); @@ -1524,7 +1525,7 @@ Future main([List? args]) async { final credentials = Credentials.anonymous(); final user = await app.logIn(credentials); final path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); - final config = Configuration.flexibleSync(user, [Task.schema], path: path); + final config = Configuration.flexibleSync(user, [Product.schema], path: path); final beforeCompact = await createRealmForCompact(config); user.logOut(); Future.delayed(Duration(seconds: 5)); @@ -1534,7 +1535,7 @@ Future main([List? args]) async { validateCompact(compacted, config.path, beforeCompact); //test the realm can be opened. - final realm = getRealm(Configuration.disconnectedSync([Task.schema], path: path)); + final realm = getRealm(Configuration.disconnectedSync([Product.schema], path: path)); }); baasTest('Realm - synced encrypted realm can be compacted', (appConfiguration) async { @@ -1544,7 +1545,7 @@ Future main([List? args]) async { final user = await app.logIn(credentials); List key = List.generate(encryptionKeySize, (i) => random.nextInt(256)); final config = - Configuration.flexibleSync(user, [Task.schema], encryptionKey: key, path: path); + Configuration.flexibleSync(user, [Product.schema], encryptionKey: key, path: path); final beforeCompact = await createRealmForCompact(config); user.logOut(); Future.delayed(Duration(seconds: 5)); @@ -1554,7 +1555,7 @@ Future main([List? args]) async { validateCompact(compacted, config.path, beforeCompact); //test the realm can be opened. - final realm = getRealm(Configuration.disconnectedSync([Task.schema], path: path, encryptionKey: key)); + final realm = getRealm(Configuration.disconnectedSync([Product.schema], path: path, encryptionKey: key)); }); } From 86401196c89ba827a382196f8dfa370875354fcd Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 16:44:56 +0200 Subject: [PATCH 14/21] skip non existing realm compaction add a test --- lib/src/realm_class.dart | 14 +++++++------- test/realm_test.dart | 6 ++++++ test/test.dart | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index f70cb4266..5e0ee1d85 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -492,14 +492,14 @@ class Realm implements Finalizable { /// The Realm file is left untouched if any file operation fails. static bool compact(Configuration config) { late Configuration compactConfig; + if (!File(config.path).existsSync()) { + return false; + } + if (config is LocalConfiguration) { - compactConfig = Configuration.local(config.schemaObjects.toList(), - schemaVersion: config.schemaVersion, - fifoFilesFallbackPath: config.fifoFilesFallbackPath, - path: config.path, - encryptionKey: config.encryptionKey, - disableFormatUpgrade: true, - isReadOnly: config.isReadOnly); + //compact opens the realm file so it can triger schema version upgrade, file format upgrade, migration and initial data callbacks etc. + //We must to allow that to happen so use the local config as is. + compactConfig = config; } else if (config is FlexibleSyncConfiguration || config is DisconnectedSyncConfiguration) { compactConfig = Configuration.disconnectedSync(config.schemaObjects.toList(), fifoFilesFallbackPath: config.fifoFilesFallbackPath, path: config.path, encryptionKey: config.encryptionKey); diff --git a/test/realm_test.dart b/test/realm_test.dart index 2086da333..9a746ebb7 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1455,6 +1455,12 @@ Future main([List? args]) async { final realm = getRealm(config); }); + test('Realm - non existing realm can not be compacted', () async { + var config = Configuration.local([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); + final compacted = Realm.compact(config); + expect(compacted, false); + }); + test('Realm - local realm can be compacted in worker isolate', () async { var config = Configuration.local([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); final beforeCompact = await createRealmForCompact(config); diff --git a/test/test.dart b/test/test.dart index 66736aeaa..168c7db51 100644 --- a/test/test.dart +++ b/test/test.dart @@ -396,8 +396,8 @@ String generateRandomRealmPath() { final random = Random(); String generateRandomString(int len) { - const _chars = 'abcdefghjklmnopqrstuvwxuz'; - return List.generate(len, (index) => _chars[random.nextInt(_chars.length)]).join(); + const chars = 'abcdefghjklmnopqrstuvwxuz'; + return List.generate(len, (index) => chars[random.nextInt(chars.length)]).join(); } Realm getRealm(Configuration config) { From 39dd99f88937a69b3b8910b2426958b5be7a59e7 Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 16:46:36 +0200 Subject: [PATCH 15/21] add bug comment --- test/test.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test.dart b/test/test.dart index 168c7db51..46f254077 100644 --- a/test/test.dart +++ b/test/test.dart @@ -474,6 +474,7 @@ Future tryDeleteRealm(String path) async { //delete lock file await File('$path.lock').delete().onError((error, stackTrace) => dummy); + //Bug in Core https://github.com/realm/realm-core/issues/5997. Remove when fixed //delete compaction space file await File('$path.tmp_compaction_space').delete().onError((error, stackTrace) => dummy); From e8063aae73af6431a0a562d836718f44494b814d Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 16:52:15 +0200 Subject: [PATCH 16/21] throw early on in-memory realms pass disconnectedsync config as is --- lib/src/realm_class.dart | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index 5e0ee1d85..e2fbadb51 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -491,22 +491,26 @@ class Realm implements Finalizable { /// Note: The file system should have free space for at least a copy of the Realm file. This method must not be called inside a transaction. /// The Realm file is left untouched if any file operation fails. static bool compact(Configuration config) { + if (config is InMemoryConfiguration) { + throw RealmException("Can't compact an in-memory Realm"); + } + late Configuration compactConfig; + if (!File(config.path).existsSync()) { return false; } if (config is LocalConfiguration) { - //compact opens the realm file so it can triger schema version upgrade, file format upgrade, migration and initial data callbacks etc. + //compact opens the realm file so it can triger schema version upgrade, file format upgrade, migration and initial data callbacks etc. //We must to allow that to happen so use the local config as is. compactConfig = config; - } else if (config is FlexibleSyncConfiguration || config is DisconnectedSyncConfiguration) { + } else if (config is DisconnectedSyncConfiguration) { + compactConfig = config; + } else if (config is FlexibleSyncConfiguration) { compactConfig = Configuration.disconnectedSync(config.schemaObjects.toList(), fifoFilesFallbackPath: config.fifoFilesFallbackPath, path: config.path, encryptionKey: config.encryptionKey); - } else if (config is InMemoryConfiguration) { - throw RealmException("Can't compact an in-memory Realm"); - } - else { + } else { throw RealmError("Unsupported realm configuration type ${config.runtimeType}"); } From 66e3b9c42cca6a24a86f889db4841125e6af441a Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 16:58:12 +0200 Subject: [PATCH 17/21] fix bad merge --- lib/src/native/realm_core.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/native/realm_core.dart b/lib/src/native/realm_core.dart index 8d16f3a8b..aabb9208e 100644 --- a/lib/src/native/realm_core.dart +++ b/lib/src/native/realm_core.dart @@ -2254,6 +2254,8 @@ class _RealmCore { final out_did_compact = arena(); _realmLib.invokeGetBool(() => _realmLib.realm_compact(realm.handle._pointer, out_did_compact)); return out_did_compact.value; + }); + } void immediatelyRunFileActions(App app, String realmPath) { using((arena) { From a32c68854a6ba1073abfa72389fda493794166d6 Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 17:03:22 +0200 Subject: [PATCH 18/21] Update lib/src/realm_class.dart Co-authored-by: Desislava Stefanova <95419820+desistefanova@users.noreply.github.com> --- lib/src/realm_class.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index 7397d20a7..3b2aa565e 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -516,8 +516,8 @@ class Realm implements Finalizable { } if (config is LocalConfiguration) { - //compact opens the realm file so it can triger schema version upgrade, file format upgrade, migration and initial data callbacks etc. - //We must to allow that to happen so use the local config as is. + // `compact` opens the realm file so it can triger schema version upgrade, file format upgrade, migration and initial data callbacks etc. + // We must allow that to happen so use the local config as it is. compactConfig = config; } else if (config is DisconnectedSyncConfiguration) { compactConfig = config; From cc38e3987ccc8c51725bb2220e47736222932483 Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 17:04:50 +0200 Subject: [PATCH 19/21] fix --- lib/src/realm_class.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/realm_class.dart b/lib/src/realm_class.dart index 3b2aa565e..5d7a529d3 100644 --- a/lib/src/realm_class.dart +++ b/lib/src/realm_class.dart @@ -517,7 +517,7 @@ class Realm implements Finalizable { if (config is LocalConfiguration) { // `compact` opens the realm file so it can triger schema version upgrade, file format upgrade, migration and initial data callbacks etc. - // We must allow that to happen so use the local config as it is. + // We must allow that to happen so use the local config as is. compactConfig = config; } else if (config is DisconnectedSyncConfiguration) { compactConfig = config; From 6ed1ba53f569226ca099404e9890a1e628cdcddf Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 17:09:51 +0200 Subject: [PATCH 20/21] rename local variables --- test/realm_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/realm_test.dart b/test/realm_test.dart index 9a746ebb7..d52d52a6d 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1437,10 +1437,10 @@ Future main([List? args]) async { return beforeSize; } - void validateCompact(bool compacted, String realmPath, int before) async { + void validateCompact(bool compacted, String realmPath, int beforeCompactSize) async { expect(compacted, true); - final afterSize = await File(realmPath).stat().then((value) => value.size); - expect(before, greaterThan(afterSize)); + final afterCompactSize = await File(realmPath).stat().then((value) => value.size); + expect(beforeCompactSize, greaterThan(afterCompactSize)); } test('Realm - local realm can be compacted', () async { From dbfcb03f1f3c442ac688efe9993e9544b3694d05 Mon Sep 17 00:00:00 2001 From: blagoev Date: Fri, 4 Nov 2022 17:12:24 +0200 Subject: [PATCH 21/21] rename local variable --- test/realm_test.dart | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/realm_test.dart b/test/realm_test.dart index d52d52a6d..cfa240733 100644 --- a/test/realm_test.dart +++ b/test/realm_test.dart @@ -1437,19 +1437,19 @@ Future main([List? args]) async { return beforeSize; } - void validateCompact(bool compacted, String realmPath, int beforeCompactSize) async { + void validateCompact(bool compacted, String realmPath, int beforeCompactSizeSize) async { expect(compacted, true); final afterCompactSize = await File(realmPath).stat().then((value) => value.size); - expect(beforeCompactSize, greaterThan(afterCompactSize)); + expect(beforeCompactSizeSize, greaterThan(afterCompactSize)); } test('Realm - local realm can be compacted', () async { var config = Configuration.local([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final beforeCompact = await createRealmForCompact(config); + final beforeCompactSizeSize = await createRealmForCompact(config); final compacted = Realm.compact(config); - validateCompact(compacted, config.path, beforeCompact); + validateCompact(compacted, config.path, beforeCompactSizeSize); //test the realm can be opened. final realm = getRealm(config); @@ -1463,7 +1463,7 @@ Future main([List? args]) async { test('Realm - local realm can be compacted in worker isolate', () async { var config = Configuration.local([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final beforeCompact = await createRealmForCompact(config); + final beforeCompactSizeSize = await createRealmForCompact(config); final receivePort = ReceivePort(); await Isolate.spawn((List args) async { @@ -1476,7 +1476,7 @@ Future main([List? args]) async { final compacted = await receivePort.first as bool; - validateCompact(compacted, config.path, beforeCompact); + validateCompact(compacted, config.path, beforeCompactSizeSize); //test the realm can be opened. final realm = getRealm(config); @@ -1486,11 +1486,11 @@ Future main([List? args]) async { final config = Configuration.local([Product.schema], encryptionKey: generateEncryptionKey(), path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final beforeCompact = await createRealmForCompact(config); + final beforeCompactSizeSize = await createRealmForCompact(config); final compacted = Realm.compact(config); - validateCompact(compacted, config.path, beforeCompact); + validateCompact(compacted, config.path, beforeCompactSizeSize); //test the realm can be opened. final realm = getRealm(config); @@ -1504,7 +1504,7 @@ Future main([List? args]) async { test('Realm - readonly realm can not be compacted', () async { var path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); var config = Configuration.local([Product.schema], path: path); - final beforeCompact = await createRealmForCompact(config); + final beforeCompactSize = await createRealmForCompact(config); config = Configuration.local([Product.schema], isReadOnly: true, path: path); expect(() => Realm.compact(config), throws("Can't compact a read-only Realm")); @@ -1516,11 +1516,11 @@ Future main([List? args]) async { test('Realm - disconnected sync realm can be compacted', () async { var config = Configuration.disconnectedSync([Product.schema], path: p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm")); - final beforeCompact = await createRealmForCompact(config); + final beforeCompactSize = await createRealmForCompact(config); final compacted = Realm.compact(config); - validateCompact(compacted, config.path, beforeCompact); + validateCompact(compacted, config.path, beforeCompactSize); //test the realm can be opened. final realm = getRealm(config); @@ -1532,13 +1532,13 @@ Future main([List? args]) async { final user = await app.logIn(credentials); final path = p.join(Configuration.defaultStoragePath, "${generateRandomString(8)}.realm"); final config = Configuration.flexibleSync(user, [Product.schema], path: path); - final beforeCompact = await createRealmForCompact(config); + final beforeCompactSize = await createRealmForCompact(config); user.logOut(); Future.delayed(Duration(seconds: 5)); final compacted = Realm.compact(config); - validateCompact(compacted, config.path, beforeCompact); + validateCompact(compacted, config.path, beforeCompactSize); //test the realm can be opened. final realm = getRealm(Configuration.disconnectedSync([Product.schema], path: path)); @@ -1552,13 +1552,13 @@ Future main([List? args]) async { List key = List.generate(encryptionKeySize, (i) => random.nextInt(256)); final config = Configuration.flexibleSync(user, [Product.schema], encryptionKey: key, path: path); - final beforeCompact = await createRealmForCompact(config); + final beforeCompactSize = await createRealmForCompact(config); user.logOut(); Future.delayed(Duration(seconds: 5)); final compacted = Realm.compact(config); - validateCompact(compacted, config.path, beforeCompact); + validateCompact(compacted, config.path, beforeCompactSize); //test the realm can be opened. final realm = getRealm(Configuration.disconnectedSync([Product.schema], path: path, encryptionKey: key));