drift
that resides in a user defined directory. So, I will only get access to that directory using Android's storage access framework. Because of that I don't get a regular file system path, but only a document URI, that I can use with the ContentResolver
API. So it is possible to get a Java File
from it, a file descriptor and an input stream. Is there a way to somehow plumb that into drift
?
file_picker
plugin from my current self-backed solution. A quick glance at the source code seems to reveal that it also uses the storage access framework on newer Android versions which is a requirement in my case. But it will also do some magic to reveal the real file paths. I'll try it out!
ContentResolver.openFileDescriptor
for the document's URI, then use ParcelFileDesciptor.detachFd()
to get the native FD and finally open /dev/fd/$fdFromParcel
as a sqlite3 database. I guess it would break since sqlite3 stores a journal or WAL next to the input path and I don't know if that can be overridden. Might be easier to let a plugin manage the path handling for you :D
forEach(() async {})
, the result of what happens in forEach
is not awaited. Instead, I would probably use a regular for loop (like for (final categoryModelMap in List.from(...)) {}
). Alternatively, you can use Future.forEach(yourList, () async { /*action*/ })
.
I've got a watch that I've defined in a provider for flutter, the provider only exists for the scope of a page. I get the data and then process through it in the provider with a .forEach
on the stream and then notify the listeners. I've noticed that if while on the page if I insert data it seems from that point going forward that the more and more watches trigger.
So, for example, if I go into the page, I'll see the .forEach
is processed once. Then if I insert 3 records and come out and back into the page I'll see the .forEach
get processed several times which means the more I go in and out the page the more notificationListners
/setStates
will be getting called. Is this what you'd expect to happen?
@andrewpmoore The problem is that forEach
does something for each element in a stream. Query watches from drift are (most likely) infinite streams though, so the forEach
never completes and you get a new listener whenever the page is opened. You can use a different stream API to dispose the listener after the provider is destroyed. If your model is a ChangeNotifier
, you could do something like this:
class MyModel extends ChangeNotifier {
StreamSubscription? _subscription;
MyModel(AppDatabase db) {
_subscription = db.someStreamQuery().listen((data) {
// do something, then notifyListeners()
});
}
@override
void dispose() {
_subscription?.cancel();
super.dispose();
}
}
If you previously called .forEach
in the create
method of the provider, you'll also need to change that to .listen
and make sure that you .cancel()
the stream subscription once the provider is disposed. Or just use a StreamProvider
I guess.
Hello sir, I have a class where multiple methods are there where I have used transaction (for eg. CRUD methods with multiple insertion and updates) but after calling them one after another, it's displaying an error after the first one i.e. Bad state: This database or transaction runner has already been closed and may not be used
What are the ways to fix it? Or how to close the first transaction so that the next won't display error messages?
Can you help me out with any possible ways to solve this, sir?
transaction()
is defined