Skip to content

Commit

Permalink
fix file data store clear bug and cleanup logging (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
danReynolds authored Nov 17, 2024
1 parent 3661c16 commit 92f0e9f
Show file tree
Hide file tree
Showing 16 changed files with 64 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 5.1.1

* Fix bug with file data store clear.

## 5.1.0

* Creates generic persistor worker isolate interface.
Expand Down
2 changes: 1 addition & 1 deletion example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ if (flutterVersionName == null) {
android {
namespace "com.example.example"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
ndkVersion = "27.0.12077973"

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand Down
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath 'com.android.tools.build:gradle:8.7.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand Down
3 changes: 3 additions & 0 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
4 changes: 3 additions & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
12 changes: 10 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ final logger = Logger('Playground');
void main() async {
WidgetsFlutterBinding.ensureInitialized();

Loon.configure(persistor: Persistor.current(), enableLogging: true);
Loon.configure(
persistor: Persistor.current(
settings: const PersistorSettings(encrypted: true),
),
enableLogging: true,
);

await logger.measure('Hydrate', () => Loon.hydrate());

logger.log('User count: ${UserModel.store.get().length}');

runApp(const MyApp());
}

Expand Down Expand Up @@ -131,6 +138,7 @@ class _MyHomePageState extends State<MyHomePage> {
builder: (context, usersSnap) {
return Flexible(
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 12),
shrinkWrap: true,
itemCount: usersSnap.length,
itemBuilder: (context, index) {
Expand All @@ -140,7 +148,7 @@ class _MyHomePageState extends State<MyHomePage> {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(user.name),
Flexible(child: Text(user.name)),
TextButton(
onPressed: () {
_showEditDialog(userSnap.doc);
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ packages:
path: ".."
relative: true
source: path
version: "5.0.0"
version: "5.1.0"
matcher:
dependency: transitive
description:
Expand Down
10 changes: 5 additions & 5 deletions lib/persistor/data_store_resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class DataStoreResolverConfig {
final Future<ValueRefStore<String>?> Function() hydrate;
final Future<void> Function(ValueRefStore<String>) persist;
final Future<void> Function() delete;
final Logger logger;

DataStoreResolverConfig({
required this.hydrate,
required this.persist,
required this.delete,
required this.logger,
});
}

Expand All @@ -26,7 +28,7 @@ class DataStoreResolver {

final DataStoreResolverConfig config;

late Logger logger;
late Logger logger = config.logger.child('DataStoreResolver');

DataStoreResolver(this.config) {
// Initialize the root of the resolver with the default file data store key.
Expand Down Expand Up @@ -92,6 +94,7 @@ class DataStoreResolver {

final hydratedStore =
await logger.measure('Hydrate', () => config.hydrate());

if (hydratedStore != null) {
_store = hydratedStore;
}
Expand All @@ -115,10 +118,7 @@ class DataStoreResolver {
}

Future<void> delete() async {
try {
await logger.measure('Delete', () => config.delete());
// ignore: empty_catches
} on PathNotFoundException {}
await logger.measure('Delete', () => config.delete());

_store.clear();
// Re-initialize the root of the store to the default persistor key.
Expand Down
1 change: 1 addition & 0 deletions lib/persistor/file_persistor/file_data_store_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class FileDataStoreConfig extends DataStoreConfig {
class FileDataStoreResolverConfig extends DataStoreResolverConfig {
FileDataStoreResolverConfig({
required File file,
required super.logger,
}) : super(
hydrate: () async {
try {
Expand Down
2 changes: 2 additions & 0 deletions lib/persistor/file_persistor/file_persistor_worker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ class FilePersistorWorker extends PersistorWorker<FilePersistorWorkerConfig> {
),
),
resolverConfig: FileDataStoreResolverConfig(
logger: logger,
file: File("${config.directory.path}/${DataStoreResolver.name}.json"),
),
clearAll: () async {
try {
await config.directory.delete(recursive: true);
await config.directory.create();
} on PathNotFoundException {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class IndexedDBDataStoreResolverConfig extends DataStoreResolverConfig {

IndexedDBDataStoreResolverConfig({
required IndexedDBTransactionCallback runTransaction,
required super.logger,
}) : super(
hydrate: () async {
final result =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class IndexedDBPersistor extends Persistor {
),
),
resolverConfig: IndexedDBDataStoreResolverConfig(
logger: logger,
runTransaction: runTransaction,
),
clearAll: () => runTransaction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class SqliteDataStoreResolverConfig extends DataStoreResolverConfig {

SqliteDataStoreResolverConfig({
required Database db,
required super.logger,
}) : super(
hydrate: () async {
final rows = await db.query(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class SqlitePersistorWorker
logger: logger,
),
),
resolverConfig: SqliteDataStoreResolverConfig(db: db),
resolverConfig: SqliteDataStoreResolverConfig(db: db, logger: logger),
clearAll: () => db.delete(SqlitePersistor.tableName),
getAll: () async {
final records = await db.query(
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: loon
description: Loon is a reactive collection data store for Dart & Flutter.
version: 5.1.0
version: 5.1.1
homepage: https://github.com/danReynolds/loon

environment:
Expand Down
44 changes: 28 additions & 16 deletions test/core/persistor/persistor_test_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ void persistorTestRunner<T extends Persistor>({
);

test(
'Deletes empty files',
'Deletes empty data stores',
() async {
final userCollection = Loon.collection(
'users',
Expand All @@ -282,7 +282,7 @@ void persistorTestRunner<T extends Persistor>({

expect(await exists('__store__'), true);

// If all documents of a file are deleted, the file itself should be deleted.
// If all documents in a data store are deleted, the store itself should be deleted.
userCollection.doc('1').delete();
userCollection.doc('2').delete();

Expand Down Expand Up @@ -2385,7 +2385,7 @@ void persistorTestRunner<T extends Persistor>({
);

group('hydrate', () {
test('Hydrates all data from persistence files by default', () async {
test('Hydrates all data from persisted stores by default', () async {
final userCollection = Loon.collection(
'users',
fromJson: TestUserModel.fromJson,
Expand Down Expand Up @@ -2917,8 +2917,8 @@ void persistorTestRunner<T extends Persistor>({
},
);

// In this scenario, multiple collections share a file data store and therefore
// the file should not be deleted since it still has documents from another collection.
// In this scenario, multiple collections share a data store and therefore
// the store should not be deleted since it still has documents from another collection.
test(
'Retains data stores that still contain other collections',
() async {
Expand Down Expand Up @@ -2986,7 +2986,7 @@ void persistorTestRunner<T extends Persistor>({
'clearAll',
() {
test(
"Deletes all file data stores",
"Deletes all data stores",
() async {
final userCollection = Loon.collection(
'users',
Expand All @@ -2997,8 +2997,13 @@ void persistorTestRunner<T extends Persistor>({
),
);

userCollection.doc('1').create(TestUserModel('User 1'));
userCollection.doc('2').create(TestUserModel('User 2'));
final userDoc = userCollection.doc('1');
final userDoc2 = userCollection.doc('2');
final user = TestUserModel('User 1');
final user2 = TestUserModel('User 2');

userDoc.create(user);
userDoc2.create(user2);

await completer.onSync;

Expand All @@ -3009,6 +3014,13 @@ void persistorTestRunner<T extends Persistor>({

expect(await exists('users'), false);
expect(await exists('__resolver__'), false);

userDoc.create(user);
userDoc2.create(user2);

await completer.onSync;

expect(await exists('users'), true);
},
);
},
Expand Down Expand Up @@ -3082,7 +3094,7 @@ void persistorTestRunner<T extends Persistor>({

group('hydrate', () {
test(
'Merges data from plaintext and encrypted persistence files into collections',
'Merges data from plaintext and encrypted persistence stores into collections',
() async {
final userCollection = Loon.collection<TestUserModel>(
'users',
Expand Down Expand Up @@ -3146,12 +3158,12 @@ void persistorTestRunner<T extends Persistor>({
},
);

// This scenario takes a bit of a description. In the situation where a file for a collection is unencrypted,
// but encryption settings now specify that the collection should be encrypted, then the unencrypted file should
// This scenario takes a bit of a description. In the situation where a data store for a collection is unencrypted,
// but encryption settings now specify that the collection should be encrypted, then the unencrypted store should
// be hydrated into memory, but any subsequent persistence calls for that collection should move the updated data
// from the unencrypted data store to the encrypted data store. Once all the data has been moved, the unencrypted
// file should be deleted.
test('Encrypts collections hydrated from unencrypted files', () async {
// store should be deleted.
test('Encrypts collections hydrated from unencrypted stores', () async {
configure(settings: const PersistorSettings());

final usersCollection = Loon.collection(
Expand Down Expand Up @@ -3203,7 +3215,7 @@ void persistorTestRunner<T extends Persistor>({

await completer.onSync;

// The new user should have been written to the encrypted store file, since the persistor was configured with encryption
// The new user should have been written to the encrypted data store, since the persistor was configured with encryption
// enabled globally.
expect(
await get('__store__', encrypted: true),
Expand Down Expand Up @@ -3238,7 +3250,7 @@ void persistorTestRunner<T extends Persistor>({

await completer.onSync;

// The documents should now have been updated to exist in the encrypted store file.
// The documents should now have been updated to exist in the encrypted store.
expect(
await get('__store__', encrypted: true),
{
Expand All @@ -3254,7 +3266,7 @@ void persistorTestRunner<T extends Persistor>({
},
);

// The now empty plaintext root file should have been deleted.
// The now empty plaintext root data store should have been deleted.
expect(await exists('__store__'), false);
});
});
Expand Down

0 comments on commit 92f0e9f

Please sign in to comment.