Updates to existing app - iphone

I have an App using sqlite. On first start, I copy the .db file into NSDocumentDirectory (so that I can make updates to it). In later versions, I plan to add new data to this database. How can I make sure, that with every application update (but not with every app start) the newest copy of this DB will be copied to NSDocumentDirectory?
Thanks
-Konstantin

I have a constant that I increment with new builds, say kDatabaseVersion.
At startup, I check for the following:
Does the DB exist in the Documents directory? If not, copy it. This probably means a first launch has occurred.
If the DB does exist, check the version from the constant against a NSUserDefaults entry with the same key. If the constant is greater, copy the database over. If not, do not. Update NSUserDefaults accordingly.
Of course, if the database contains data from your users also, you have to work out how to migrate that to a new data store. If you are using Core Data, you might even consider multiple persistent stores to separate user and default data.

Keep a database version number in your App.
When the app starts, check if the database exists in document directory. If not, copy it to the doc. directory.
If the database already exists, compare the database version number from your app with the number stored in a database table. if the numbers are equal everything is fine, otherwise you have to "upgrade" the existing database (modify database schema or whatever). So you can upgrade the database with every version of your app. Code a simple function "CheckForDatabaseUpdate" that contains all the neccessary logic. And make a "UpgradeToDatabaseVersion" function with a version number as parameter. This function will handle the upgrade of the database schema from one version to another.

Related

Insert MongoDB document with an objectId that existed in the past

I've a bunch of collections (12) and I need to rename many fields of them. I can't do it live in the database, all I can do is download and reupload a dump of it.
So I've downloaded the collection with mongodump manipulated the data and I'm planning to use mongorestore to push it back on the database.
I'm wondering what will happen then with ObjectIds.. I know that an objectId is unique throughout the database so I'm thinking about deleting all the old data right before using mongorestore, is it ok or will I still have problems with the ids?
You can specify any value for MongoID whatever you want. You even can use string instead of MongoID.
If you have production app you need to perform upgrade and migrate data by application itself step by step.
If you have one proccess singlethreaded application or if you can run your app in that way - it is most simple case. Else you need synchronization service.
Be carefull with async/await and promises and so on asyncronous processes. They receive and have in memory one the data in one time and continue process with that data in another time, and it need to have in mind that.
You need to do:
modify service to be ready to both data format
create modification code which will go through all the data and migrate it
modify service to be ready only to new data format once all the data migrate done

How can I update only a few tables using a pre-populated Core Data database via an App Store Update

We have an app in the app store right now that uses a pre-populated Core Data database. We want to update all the tables in the database, except for 1 table which is the Favorites table where users store their Favourite bus routes or stops. Currently, we are accomplishing this update having the app delegate use the SQLite C API, and NSFileManager to do the following:
Create a temporary Favorites database
Copy the favourites from the database on the disk to the temporary database
Delete the database on disk ([fileManager removeItemAtPath:storePath error:NULL] )
Copy the new database from the app bundle to disk ([fileManager copyItemAtPath:databaseBundlePath toPath:storePath error:&copyError])
Copy Favourites from the Temp database into the new database.
Delete the temporary Favorites database.
I was wondering if there was another way to do this because there have been a lot of complaints with our app crashing during the splash screen which is the time where the database copying happens.
I heard of Core Data Migration, but my understanding of Core Data Migration is that you can migrate data only when a the model changes, but in our case the model hasn't changed.
Why don't you leave the database as it is and just insert/remove the data into it as needed instead of copying a prefilled database?
Alternatively you can also take the opposite approach: leave the original database, copy the prefilled one with a new name, insert the favorites from the original database into the new one, remove the original one, and now only use the new one. Like this, you are always sure nothing happens to your user's favorites.
Or you could write the favorites first into a text file, and then do the same thing you describe. If anything happens (like a crash), you always still have the favorites in the saved text file.
It also may work with core data migration, but up to now I avoided that ... any structural database change is something I would rather avoid, I think ...

how can I selectively update some SQLite table to preserve user data for an iphone app update?

can you selectively update certain sqllite tables when updating an iphone app, in order to preserve user stored data? how? appreciate the help!
At the simplest level, you'll need to:
Store some version number information in the SQL database in the app's document directory.
When your app launches, you can compare this version data to the copy in your bundle.
If the version is different, you'll then need to activate a "updater" class, the responsibility of which is to:
3.1. Check for the existence of each table.
3.2. If it exists, load any existing data into a suitable data structure (an NSDictionary most likely), cull the table and create it in the "current" format, providing sensible defaults where no data exists.
As you can imagine, in the above scenario the updater class effectively needs to know how to create each table in turn, which isn't ideal - an alternative approach being to store a list of ALTER TABLE statements for each version and then apply them in turn until the database structure is up to date.

Restoring default records to a Core Data database

I have an iPhone app that has a sqlLite Core Data model that is pre-loaded with default data. I want to enable the user to restore this default data if they have modified or deleted records from the model, while retaining any new records added to the model by the user.
The sqlLite database is copied to the users documents directory on first run, so the untouched original database is available in the app package. What is the easiest way to copy records between the two databases? I assume that it involves setting up an additional persistentStoreCoordinator, or adding the original dB to the coordinator as an additional persistentStore, but the docs are skimpy on how to do this.
Thanks,
Jk
If you do not want to delete the destination store and just overwrite it then the workflow is:
Stand up a second Core Data stack with the source persistent store.
Fetch each entity from the source.
Look for the object in the destination.
If it exists, update it.
If it doesn't, create it.
Save the destination store.
Depending on how much data you have, this can be a very expensive operation.

SQlite synchronization scheme

I know it is xmas eve, so it is a perfect time to find hardcore programers online :).
I have a sqlite db fiel that contains over 10 K record, I generate the db from a mysql database, I have built the sqlite db within my iphone application the usual way.
The records contains information about products and their prices, shops and the like, this info of course is not static, I use an automatic scheme to populate and keep updating my mysql db.
Now, how can I update the iphoen app sqlite database with the new information available in the mysql db, the db structure is still the same, but the records contains new information.
Thanks.
Ahed
info:
libsqlite3.0,
iphone OS 3.1,
mysql 2005,
Mac OS X 10.6.2
There is a question you need to answer first; How do you determine the set of changed records in your MySQL database?
Or, more specifically, given that the MySQL database is in state A, some transactions occur and now it is in state B, how do you know what changed between A and B?
Bottom line; you need a schema in MySQL that enables this. Once you have answered that question, then you can answer the "how do I sync problem?".
I have a similar application.
I am using Push Notification to let my users know there is new or updated data available.
Each time a record on the server is updated, I store a sequential record-number alongside the record.
Each UDID that's registered has a "last updated" number associated with it that contains the highest record-number it has ever downloaded.
When any given device comes to get it's updates, all database records greater than the UDID's last updated record-number as stored on the server are sent to the device. If everything goes OK, the last updated record-number for the UDID is set to the last record number sent.
The user has the option to fetch all records and refresh his database if he feels any need to sync his device to the entire database.
Seems to be working well.
-t
You can find many other similar questions by searching for "iphone synchronization":
https://stackoverflow.com/search?q=iphone+synchronization
I'm going to assume that the data is going only from mysql to sqlite, and not the reverse direction.
Three are a few ways that I could imagine doing this. The first is to just redownload
the entire database during every update. Another way, which I'm describing below, would be to create a "log" table to record the modifications to your master table, and then download just the new logs when doing the update.
I would creat a new "log" table in your SQL database to log changes to the table needing synchronization. The log could contain a "revision" column to track in what order changes were made, a "type" column to specify if it was a insert, update, or or delete, a the row-id if your affected row, and finally have the entire set of columns from your master table.
You could automate the creation of log entries by using stored procedures as wrappers to modify your master table.
With only 10k records, I wouldn't expect this log table to grow to be that huge.
You would then in sqlite keep track of the latest revision downloaded from mysql. To update the table, you would download all log entries after the latest update, and then apply them to your sqlite table.