Closed Prn-Ice closed 2 years ago
In my honest opinion it’s probably more performant and memory efficient to use just one store However it all depends on your app constraints as it could make sense to separate. I wouldn’t do it though without a strong reason. This is valid mostly for persistent backends something like memory is very light
For example I have one app where I use a vault just to store assets ( images / binaries etc ) and a custom database for the metadata.
It all depends on your scenario but I don’t see any technical constraints to do not do it
If I did use one store wouldn't i loose the automatic deserialization?
Ha I see it’s different types ? Meaning you need different fromEncodable functions per store ?
If thats the case yes you will need different stores. I have to say that this is a limitation of the library itself as in theory I should be able to allow the configuration of multiple fromEncodable functions per store name ( partitions ). I will consider the implications of doing that, seems a nice feature to add.
Answering directly with the current implementation, you need multiple stores if you are storing different object types. Bear in mind that even on a scenario where I hypothetically support multiple fromEncodable functions per store partition you would always loose the generic option as you will not be able to specify a type (as you can have multiple underneath ) when creating a vault/cache or a store
I see, so should I keep the issue open till then?
Yes let met look at this as it seems fairly easy to do. However something tells me that at some point in time I had already looked at this but for some reason I didn't implemented it.
Let me look at it on this weekend to see if there's any blocker for this work
Hi from what I was able to investigate this is possible to do. I will add this feature at vault / cache creation. I still need a couple of days to do this due to the number places that I have to change
That's awesome news, I'll be ready to test anytime.
Hi, development is completed. This will unfortunately bring a small breaking change but honestly it was a miss and having this makes the library much better. Find a complete example bellow and notice that the fromEncodable
function is configured per partition and not per store as previously
```dart
import 'dart:io';
import 'package:stash/stash_api.dart';
import 'package:stash_file/stash_file.dart';
class Task {
final int id;
final String title;
final bool completed;
Task({required this.id, required this.title, this.completed = false});
/// Creates a [Task] from json map
factory Task.fromJson(Map<String, dynamic> json) => Task(
id: json['id'] as int,
title: json['title'] as String,
completed: json['completed'] as bool);
/// Creates a json map from a [Task]
Map<String, dynamic> toJson() =>
<String, dynamic>{'id': id, 'title': title, 'completed': completed};
@override
String toString() {
return 'Task $id, "$title" is ${completed ? "completed" : "not completed"}';
}
}
class Contact {
final int id;
final String name;
Contact({required this.id, required this.name});
/// Creates a [Contact] from json map
factory Contact.fromJson(Map<String, dynamic> json) =>
Contact(id: json['id'] as int, name: json['name'] as String);
/// Creates a json map from a [Contact]
Map<String, dynamic> toJson() => <String, dynamic>{'id': id, 'name': name};
@override
String toString() {
return 'Contact $id, "$name"';
}
}
void main() async {
// Temporary directory
final path = Directory.systemTemp.path;
// Creates a store
final store = await newFileLocalVaultStore(path: path);
// Creates a vault that stores Tasks from the previously created store
final taskVault = await store.vault<Task>(
name: 'taskVault',
fromEncodable: (json) => Task.fromJson(json),
eventListenerMode: EventListenerMode.synchronous)
..on<VaultEntryCreatedEvent<Task>>().listen(
(event) => print('Key "${event.entry.key}" added to the task vault'));
// Creates a vault that stores Contacts from the previously created store
final contactVault = await store.vault<Contact>(
name: 'contactVault',
fromEncodable: (json) => Contact.fromJson(json),
eventListenerMode: EventListenerMode.synchronous)
..on<VaultEntryCreatedEvent<Contact>>().listen((event) =>
print('Key "${event.entry.key}" added to the contact vault'));
// Adds a task with key 'task1' to the vault
await taskVault.put('task1',
Task(id: 1, title: 'Run task vault store example', completed: true));
// Adds a contact with key 'contact1' to the vault
await contactVault.put(
'contact1', Contact(id: 1, name: 'Run contact vault store example'));
// Retrieves the value from the task vault
print(await taskVault.get('task1'));
// Retrieves the value from the contact vault
print(await contactVault.get('contact1'));
}
I will release it today.
Note: I didn't had time to develop automatic unit tests for this feature as the existing ones are per type and this needs to test multi-types. I will add it later
Thanks, currently on holiday, will test tomorrow
Seems to work just fine, want me to leave the issue open until you find time to add those tests?
Thanks you can close it. I will try to add it in a future release
This is a question
Currently I have an app with multiple repositories
HiveLocalDataSource
base class that was implemented by all local data sourcesFor example my new local data source for my account_repository will look like this.
Is it safe to do this in all my repositories or is it more efficient to have one store shared through the entire app?