Restoring default records to a Core Data database - iphone

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.

Related

Restore mongodb data if collection or database was dropped

I need to know - Is it any possibility to restore data in collection or database if it was dropped?
The OS, by default (or in the case of Windows: any case) will not allow you to restore deleted data. You will need a third party program which can read the sectors. It is also good to note that while database drops will delete the files collection drops will not, instead they get nulled.
Dropping a collection should make it near on impossible to retrieve the data since the hard drive sectors that were used have now been overwritten with new data (basically one pass 0).
So the files may be recoverable on a database drop but that is still questionable.

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.

Syncing Core Data Databases in iOS applications

I have a doubt about Core Data migration.
Say I have an application which has some predefined values in a table A. I want to sync it with another database, with a table B in such a way that when new records are added totable B, that record should get added to my table A.
I know using Core Data migration, when I add columns to a table, I will be able to access the values previously stored in the older table before the addition of the column.
I would like to know how my table can be updated with the added records on another table.
Update:
From comment below:
The question I had in mind is this...
I want to release an update for my
app. I'm stuck on how to update the
existing Core Data database which also
stores data entered by the user. All I
need to do is update a couple of
records and preserve current user
data. How do I do this?
Core Data is not SQL. Entities are not tables. Objects are not rows. Columns are not attributes. Core Data is an object graph management system that may or may not persist the object graph and may or may not use SQL far behind the scenes to do so. Trying to think of Core Data in SQL terms will cause you to completely misunderstand Core Data and result in much grief and wasted time.
That way lies madness.
It sounds like you don't actually want to migrate as the term is used in Core Data. Migration in Core Data means moving from an earlier version of a data graph's persistent store to a newer version of the same.
E.g. In the 1.0 version you have an entity Person with the attributes firstNameand lastName. After the app has been release you wish to update to the 2.0 version and add a phoneNumber attribute to the Person entity. You would use migration to update the user's existing object graphs and persistent stores to the new object graph.
If by "table" you actually mean entities, then you can link entities together in a relationship so that they can watch each other. If by "table" you mean a data model or persistent store, then the answer is more complex. It can be done using configurations, fetched attributes, UUIDs etc but you must understand what you really need to do before you jump through all those hoops.

Updates to existing app

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.