Dynamic creation of tables in sqlite locks the database? - iphone

I am using sqlite database for my application. When i create tables in it dynamically the app works fine for the first time but when I re start the app i can only read the earlier values that i inserted but no new values get inserted.
there is nothing wrong with the code all finalize and all related statements are in place.
Any suggestion why it is happening, the sqlite is giving the error that the database is locked.

As many time mentioned:
"Open the database once at the start of your app, then close it in applicationWillTerminate of the AppDelegate. After every exec you will want to do a reset to clear the connection state."
so did you close your database at app quit?
try sqlite3_reset(stmt) befor finalize

Related

Huge CoreData migration in swift

I have a CoreData sqlite files *.sqlite *.sqlite-shm *.sqlite-wal in a zip format from my previous application version. The file is almost few hundred MBs.
In recent version, I have done some changes in the database schema i-e adding few new fields etc.
In Importing, I am simply replacing the current database by old database and making the user to restart application, which is crude. It does work however it causes 2 issues
1- It takes a lot of time on splash screen hanging the application.
2- If the database is big enough, the hanging time passes the Timeout
of Application and closes the application automatically.
What is the better way of importing database into core data saved in Documents as zip file.
First detect whether you are doing a migration. If you are, then display a ViewController with a spinner that explains what you are you doing ("please wait while we optimize the app"). When the database migration is done, the load your regular viewController.
This exact issue is discussed in this lecture: Core Data Potpourri (Paul Goracke, February 13, 2014) around 58:00. While the lecture is a bit dated (it was made before NSPersistentContainer) it is still one of the best I have ever seen and it is worthwhile to watch the entire video.

How to perform SQL Roll back from transaction logs

I have transaction log file that goes back 6 months. I need to roll back everything that happened after 5/20/2013 from a database. Can anyone please enlighten me on how to do this?
First of all, copy the database MDF and LDF files. Better safe than sorry
The database can be restored to a point in time in SQL Server 2008R2, also. There's no need to create a transaction log backup first, it'll be done automatically by SQL Server. You can find more about the log-tail backup here: Tail-Log Backups
Select to restore the database in the database context menu
Leave Database as Source. Click Timeline
Select Specific date and time. If you drag the time pointer, you'll able to see how long back your transaction log goes. Note that bright green shows that the transactions have never been backed up
After all is done, schedule transaction log backups. There's no point to have a database in Full recovery model and never backup the online transaction log

sqlite3 database is getting locked

I am creating an application with sqlite. I am performing all kind of task on the database Insert, Update, Delete, Select.
For that I open the database every time, Then execute my query using sqlite3_step() and after the result I use sqlite3_finalize() and sqlite3_close() methods. It is working well in most cases. I am not getting when its happening but some times my database gets locked with the same process I follow and some time it works.
I need to unlock database so even in any case my database get locked then I can unlock it or Plz guide me if I can check by code that my database is locked so I can replace my database with the resource database.
I am using webservice too so I don't have issue about data loss.
Is it make sense if I replace my database if it get locked or if there is any way to unlock the database.
Open database once in the beginning. And close it in the end in AppWillterminate function. You are only consuming time by opening and closing it in every database function.
As far as database lock is concerned, it gets locked when some application is still using it and other application is trying to get its access.
This could be your app, or possibly the sqlite manager add-on of your firefox.
I faced same problem once and what i did was
Disabled the option in sqlite add-on where it remembers the previously opened database.
Restart xcode, simulator.
Make a copy of the sqlite file (desktop), delete it from the project and then add in project again from desktop.
The last solution sounds weird, but i was mad that time.
I hope this could help you.

which xcode application for pre filling a database

I am still learning xcode and objective-c. I use to build app for iphone environment only.
However I am in need of realizing an application with an existing prefilled sql database.
For prefilling the database I wouldn't like to use code in the ditributed app, but I would rather prefer to have a separate app for doing that.
The reason is that, the app could only download the updated database, rather than a whole code update .
So, questions are:
is this a possible scenario
if yes, what kind of application
should I build in xcode for
prefilling database ?
thanks
There's no reason that you can't have one app that both uses the database and downloads updates. Keeping the database updated without downloading the whole thing is pretty simple.
If you record the creation and modification timestamps of rows in the database on the server and keep track of those same modification timestamps on the device, updating the database works like this:
The device determines latest modification timestamp it has for a given table. We'll call it latestTimestamp. It sends the latestTimestamp to the server.
The server compares the latestTimestamp to the creation and modification timestamps in the database. The server sends back data based on the comparison result:
If the modification timestamp is earlier than latestTimestamp it doesn't need to send the record, the device already has it;
If the modification timestamp is later than latestTimestamp and the creation timestamp is earlier than latestTimestamp, it sends the record back noting that it is to be updated in the device database;
If the modification timestamp is later than latestTimestamp and the creation timestamp is later than latestTimestamp, it sends the record back noting that it is to be added in the device database.
Lastly, the server database needs to keep track of deleted records and a deletion timestamp for every record recorded. If latestTimestamp is later than the deletion timestamp, it sends back that the record needs to be deleted.
Obviously it gets a bit more complicated when you have a variety of connected tables, but as long as things are sent back in the correct order, it works great.
Use asynchronous data requests (the ASIHTTPRequest library makes it a breeze) and update the data in the background while the user uses the app. If it's essential that the data be updated prior to any interaction with it you can display an activity indicator and have the user wait.
No need at all for a separate app.
I would discourage you from doing that. No matter it is a pre-filled-database-purpose app, or a normal-purpose app, Apple Review Team would treat them with the same procedure, leaving the developer waiting for weeks before that app is finally available on App Store.
Besides, as far as I know, communication between apps is still strictly limited. If the data you would like to transfer between your main app and your db app is larger than a few lines of, let's say, NSString, it might be technically un-plausible.

Should I put my faith in SQLite transactions to avoid file corruption?

Short version
If my process is terminated in the middle of a transaction, or while SQLite is committing a transaction, what are the chances that the database file will be corrupted?
Long version
My application uses an SQLite database for storage (directly, not via Core Data). I'm working on a new version of the application which will require an update to the database schema. On launch, the app will check the database and, if it needs updating, execute a series of SQL statements to do so.
Depending on the amount of data in the database, the update may be long running (on the order of seconds), so I need to consider the possibility that the process may be terminated before the update is completed. (For context, this on an iPhone, where the processor is slow and the app may be terminated by an incoming phone call.) I will, of course, wrap the upgrade SQL statements in a transaction. Will that be enough to guarantee that the database will not be corrupted?
I'm assuming that transactions work as advertised, and that if the process is terminated in the middle of the transaction, the file will be OK. But I'm also assuming there is a window of time during the COMMIT where something can go wrong.
To play it safe, I could create a backup copy of the database file before starting the update, but if the transactions are safe then that would be overkill. It would also make the update process take longer, which increases the chance it would be interrupted, and then I'd have to consider that the file copy operation might be interrupted... I'd like to keep the code as simple as possible (but no simpler).
In the course of researching this question I've started reading "Atomic Commit In SQLite", which is more detail than I probably need to know, but is giving me faith that I don't need to second-guess SQLite's ability to protect the database file. But I'd still like to hear from Stack Overflow: is a transaction good enough, or should I be more cautious?
I have read the Atomic Commit in SQLite document. It may not be overkill if you really want to understand what's going on, but in a nutshell, a transaction goes like this:
Lock the database file
Create the rollback journal
Determine what portions of the database file are going to be changing
Write copies of those pages to the journal file
Write the journal file header
Write your intended changes to the database file
Delete the rollback journal (THIS IS THE COMMIT)
When the user is done talking to mom and re-starts your app, when it tries to open the database file, if there is a rollback journal present, it will write the original data back to the datafile using a similarly safe process. Even if you lose your transaction, and lose a rollback, it will eventually be taken care of once mom's nervous breakdown is properly thwarted and he can run the app for more than a couple seconds at a time.
If it were me, I would trust the transactions. With so many users of SQLite, even in embedded apps, I think transaction commit failures would be a very hot topic all over the net if they weren't working properly.
Are you using CoreData with a SQLite backend? If so, I actually find that the best way to handle this problem is to create two separate NSManagedObjectContexts (a read-only and an editing). When the process completes, just save the "editing" context and then the two contexts will be in sync. If something happens during your operation, the editing context won't get saved, so you'll be fine.