Why is sqflite retaining open database reference on hot reload - flutter

I have an app that checks for an sqflite db file in the app storage directory and if it is present, blows away the file and creates a new one and then opens it for the remainder of the app life. What I have noticed is that hot restart fails with sql exceptions because it still sees the database as open somewhere in memory even though all my references are blown away due to the restart. This seems like a bug because I have no way to control the closing of that database unless I try to make sure it is closed if the application is killed. Is this by design? Is there a standard way to approach it?
I noticed this related post

Your assumption and investigation are correct. With bad words, what happens during hot restart is that the dart environment is restarted while the native world is still running and for sqlite that means that open databases remain opened with no easy way to know that from the dart side.
The hot-restart hack in place in sqflite is meant mainly to handle hotrestart even if you are in a sqlite transaction. Without this hack, it should happen what you describe in your scenario. That is said deleteDatabase should be used instead of removing manually the file.
In theory, this should be handled in openDatabase and deleteDatabase.
Can you confirm that you are indeed using deleteDatabase? If yes, in the mean time your workaround is safe and reporting an issue on sqflite for investigation would be great. Thanks!

After further testing it looks like 1 way to handle this is to check for the existence of the file. If the file exists, go ahead and open it using sqflite's openDatabase method. Then immediately close it. Then delete the file using io file delete method. Then you can create a new database file using the openDatabase method. This solution is maybe a little more expensive than I had hoped but it is working.

Related

Is there a way to check how many open watch() connections are there?

I created a web-app that utilizes db.collection.watch() to observe database changes.
However, after a few weeks, the app becomes sluggish and I have to fix it by restarting the backend - which hints at some memory leaks.
My fear is that my db.collection.watch() calls are not being properly closed, so it would be helpfull if I could see how many are actually open at any given time.
Is there a mongo command that can provide this information?

Troubleshooting Azure SQL connection issues

I have an ASP.NET application that is using Entity Framework 6 to access data stored in an Azure SQL database. I've run into a bit of a problem connecting to the database as a whole.
If I spawn a new database instance on Azure, start my app in the debugger and step through it, I'll see that it connects without a problem, can access the seed data and all is well (inserts work without a problem, but this occurs whether I change the data or not).
However, if I restart the debugger and at all points after that attempt to connect to the database when my app restarts, the connection will fail. If I set a breakpoint and look at the Context value in the Locals window, I have the following error as the value for all DbSets:
Function evaluation disabled because a previous function evaluation
timed out. You must continue execution to reenable function
evaluation.
Despite having a try/catch around the logic, no exception will be thrown. If I step into/out of/over this, the application will just run indefinitely and never complete.
If I do a rollback to the $InitialDatabase and then re-apply the automatic migration (via update-database), I still cannot connect to the database, however if I delete the database in Azure, spin up a new one, set up the new connection information in the Web.config file and execute all over again, it'll work like a charm one time. After that, it'll fail to work again, despite no other changes to the application.
What's going on here and why is this behavior occurring? If there's an underlying problem here, how could I tell what it is and how can I resolve it?
Thanks!
After making no headway, I rolled-back to a previous version of my code from when it was working fine about three weeks back. I've updated all the logic to match what was in the latest build, I just haven't updated any of the assemblies yet. It's working perfectly fine and connecting every time now, so apparently this is the fault of one of the as-of-yet unidentified dependencies.
If I ever determine which one, I'll update this answer accordingly.

Iphone SQLite initializing and closing

I'm new to working with iphone and SQLite i have my app working fine with SQLite but i would like to know what you all think is the correct / best way of opening an sqlite connection and closing it..
Would you
Initialise a DB connection on app load and close on app close..
Open and close connections when is needed..
Also is it good practise to constantly update db entries as you go or store all information in an object and write out at the end when needed..
There is not to much information on this via google just some useful small tutorials that cover delete / insert / update but not as a general overview of the best practise in using SQLite with iphone..
Thanks guys
Keep the connection open.
Whenever you execute a SQL query, it has to be compiled into a prepared statement. Once it's compiled, you can use it over and over and it doesn't have to be compiled again.
However, the query is compiled against the database pointer, so if you close your connection, you have to release all of your prepared statements. When you re-open your connection, you then have to re-prepare each statement as you use it again.
Save an object whenever you make a set of changes. If you are changing several things on an object (name, address, etc.) make all the changes first, then save it. Don't wait to commit several unrelated changes all at once, though (i.e. at the termination of the app). Related changes can be delayed until they are all made, before saving them.

Can I read from a SQLite db while writing to it on the iPhone?

Is it possible to read from a SQLite db while it's being written to?
I'm aware that access is blocked for writes when it's being written to, but is that the same for reads?
It's a little convoluted, but check out the File Locking and Concurrency documentation for SQLite. It sounds like if the db is in exclusive locked mode, that is the only time reads are not allowed. Besides unlocked, when the db is not even open.
I'm not 100% sure on it, but that's what I think it means.
After some reading around, and looking through the FMDB code, I discovered that I wasn't using the SQLITE_BUSY and SQLITE_LOCKED return values correctly.
According to the FMDB code, one should loop for a limited number of retries, waiting for a short time bewteen.
So I implemented that in my code, and everything seems to work fine.
Yes, although all the relevent multithreading issues need to be account for. I generally open multiple handles to the same DB file via sqlite3_open_v2().

iPhone Core Data application will terminate save database required?

I have an application that allows you to edit some percentages, however it will only let you commit those changes if the percentages add up to 100. However because the Core Data template includes the save code in the application will terminate. If the user changed something and then exited the application, the item would be of course saved even though it did not add to a 100%.
Therefore I simply decided to comment out the save in the application will terminate. I know the other option would be to use another context for the edit and then merge the changes or setting my context values until the actual save point. However I do not see any harm in commenting out this line, since I save whatever I want in my application when the user clicks the save button, so my question is: is the save on the application will terminate mandatory? what possible consequences could this have?. It is important to note that the application continues to work just fine after commenting this lines (which is what I expected).
Thank you in advance.
-Oscar
You can save whenever you like.
However, you will never know when the app will terminate. Unlike applications on more conventional platforms e.g desktops, the iPhoneOS will terminate your app (from the apps perspective) at random. The only warning you will get will be the applicationWillTerminate message sent to the app delegate. If you don't handle saves there then it is highly likely that at some point, your users will lose data.
I think you should reconsider your design. It sounds like you're putting calculation into the managedobjects that could (1) be handled elsewhere in code or (2) be handled by transient properties. You shouldn't have a condition in which the managedobject can't be saved at the drop of hat. Doing so makes your datamodel utterly dependent on external code for its internal integrity. This causes problem with maintenance, portability and upgrading.
Its not mandatory to save on application will terminate. You can save when ever you feel appropriate for the context of the app.