Last updated:
0 purchases
nosql persistence
Using NoSQL databases with migrations
Using NoSQL databases is now easier. We want to simplify a lot of work with NoSQL databases in Flutter using migrations between versions. All the logic for working with data will remain in the class, and you will have to use the prepared methods!
Features #
💻 Good work with models fromJson & toJson.
💐 Migrations between versions.
🌱 Hidden logic inside the class, the connection is SOLID.
🏁 Speed of work and data loading from Hive and Flutter Secure Storage.
Motivation #
Using NoSQL databases is difficult when you need to update data between versions. In our package, we have tried to simplify working with them so that it is easier for you to work. Now migrations can be done like this:
@override
Future<void> migrate(int oldVersion, int currentVersion) async {
if (oldVersion < currentVersion) {
await put(key: "key", value: "value");
}
return super.migrate(oldVersion, currentVersion);
}
copied to clipboard
Getting Started #
Add nosql_persistence to dependencies
Initialize according to the instructions Hive and Flutter Secure Storage.
Create your final class and inherit it from SecureDataSource (if it is protected data) and StorageDataSource (if there are a lot of them and you need fast work).
You will get something like this
final class ExampleDataSource extends SecureDataSource {
ExampleDataSource(super.secureStorage)
: super(
databaseName: 'example',
databaseVersion: 1,
);
}
copied to clipboard
Describe the methods you need
Future<String?> getLastEmail() async => get('last_email');
Future<void> putLastEmail(String value) async =>
put(key: 'last_email', value: value);
copied to clipboard
Describe the methods with the models that you need
Future<People?> getCurrentPeople() async => getJsonTyped(
'current',
People.fromJson
);
Future<void> putCurrentPeople(People value) async => putJsonTyped(
'current',
value.toJson(),
);
copied to clipboard
Use migrations between versions (the current version of the database is specified in the super constructor)
@override
Future<void> migrate(int oldVersion, int currentVersion) async {
if (oldVersion < 2) {
await delete('current');
}
return super.migrate(oldVersion, currentVersion);
}
copied to clipboard
Initialize the class and be sure to call initAsync before using it!
Future<void> test() async {
final dataSource = ExampleDataSource(secureStorage);
await dataSource.initAsync();
print(await dataSource.getCurrentPeople());
}
copied to clipboard
Here's what we'll get:
final class ExampleDataSource extends SecureDataSource {
ExampleDataSource(super.secureStorage)
: super(
databaseName: 'example',
databaseVersion: 1,
);
@override
Future<void> migrate(int oldVersion, int currentVersion) async {
if (oldVersion < 2) {
await delete('current');
}
return super.migrate(oldVersion, currentVersion);
}
Future<String?> getLastEmail() async => read('last_email');
Future<void> putLastEmail(String value) async =>
write(key: 'last_email', value: value);
Future<People?> getCurrentPeople() async =>
getJsonTyped('current', People.fromJson);
Future<void> putCurrentPeople(People value) async => putJsonTyped(
'current',
value.toJson(),
);
}
copied to clipboard
Very simple and clean! 🌱
Opportunities #
The implementation of features in datasources occurs with the help of mixins. Here are their descriptions and methods so that you can use them more easily:
PersistenseJsonResolver
Allows you to conveniently store and work with objects through serialization.
final taskModel = await getJsonTyped<TaskModel>("your key", TaskModel.fromJson);
await putJsonTyped("your key", taskModel.toJson());
copied to clipboard
PersistenceMigrationsResolver
Allows you to work with migrations between versions.
ExampleDataSource(super.secureStorage)
: super(
databaseName: 'example',
databaseVersion: 1,
);
@override
Future<void> migrate(int oldVersion, int currentVersion) async {
if (oldVersion < 2) {
await delete('current');
}
return super.migrate(oldVersion, currentVersion);
}
copied to clipboard
PersistenceExpiredSystemResolver
Allows you to save a value with the condition that when it is received after such a period, the value will be marked as obsolete and deleted from the database. Convenient for temporary caching.
@override
Duration? get databaseExpiredDuration => const Duration(seconds: 5);
Future<int> getCounter() async =>
int.parse((await getExpired(_counterKey)) ?? '0');
Future<void> saveCounter(int value) => putExpired(
key: _counterKey,
value: value.toString(),
);
copied to clipboard
Contributing #
Contributions are welcomed!
Here is a curated list of how you can help:
Report bugs and scenarios that are difficult to implement
Report parts of the documentation that are unclear
Fix typos/grammar mistakes
Update the documentation / add examples
Implement new features by making a pull-request
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.