can liquibase be used to work with two different schema versions of the db at the same time? - ios

I'm trying to overcome the following issue...
I have a MariaDB database that is used for an IOS application.
I'm about to release a new version to the apple store that uses a different version of the schema of the database. means all achievement related tables are modified.
can liquibase be used to configure the changes and allow selected users to connect and work with the schema as if the old schema version is configured, and to actually make the actual changes to the new schema?
before I release the application I need to provide apple with a test version so they will confirm it. so I want users that are connected from apple to see the new achievements features and to work with the new schema while regular users to still be able to user to previous version of the application and to work with the old schema that behind the scenes will actually update the database according to the new schema.
I hope I explained myself properly.
can Liquibase do that ? or it's just like a git for db changes ?
thank you! :)

Related

CoreData: How do you migrate an unversioned store?

So I'm working on a project which has been published to users. Before I put my hand on this project, this project has an 1.0 and an 2.0 version, v2.0 modified the data model of core data, but the one who did this didn't add a new version to data model.
So when user upgrade from v1.0 to v2.0, it will crash.
My problem is now I'm deploying v3.0, how do I modify my xcdatamodel so that user with v1.0 and v2.0 can both upgrade to v3.0 without problem?
Get the V1 model and add a new version to it that is identical to v2 and then add another V3 model to that so that you end up with a model that has all three versions. That way you should be able to use lightweight migration from either of the previous versions, assuming that your model changes will in fact support lightweight migration. If not then do a manual migration as suggested by #Mundi. You can recover the V1 model from the V1 app bundle if you no longer have the source code but you do need a copy of the V1 app bundle to do so. You might have to google for how to do this or let me know and I will hunt around as I will have it documented somewhere... Hope this helps.
The only feasible solution that comes to mind seems to be to include two data models in the bundle. (Essentially, the versioning system does something similar.)
Read the data with the first model, then "manually" copy it to the data store of the second model (modifying it as necessary). From then on, only use the second model (which should be versioned for future changes).
I would block the UI and put up a message like "migrating your data" to make sure no user interaction interferes with this process.

Generate Data of Previous Version of xcdatamodel for Core Data Migration Testing

In our existing app, we have many different version of xcdatamodel:
+ TheApp.xcdatamodel
TheApp.1.0.xcdatamodel
TheApp.1.1.xcdatamodel
TheApp.2.0.xcdatamodel
...
We know that the traditional way of doing database migration testing is what have been proposed in this question: How to Test Core Data Migration With an App Already in the App Store? In short, it works like the following:
install a old version of the app;
create some data in the old version of the app;
install the new version on top it;
see if everything is migrated properly.
We have been using this migration testing method for all our previous version of the app. Our QAs will perform the above steps and then judge by themselves that whether migration is successful or not.
However, in the most recent upgrade, we have changed a lot in our data model. It doesn't sound like such a good idea to ask the QAs to remember what have been created in the old version of the app and know what have been missing or not during migration. Therefore, we would like to see whether it is possible to write unit testing for the database migration by the developers ourself.
So one of the first step is to generate test data. Notice that we can see all the previous version of the xcdatamodel from within our Xcode project, it seems that it is possible. In a nutshell, the question:
Is it possible to generate test data of previous version of xcdatamodel programmatically from within our current version of the app?
Please let me know what you think. Suggestions are also acceptable.
This is how we do it: we need to first get an URL to any model you would like to work with, and then create a managedObjectModel from it.
let oldModelUrl = NSBundle.mainBundle().URLForResource("CoreDataExample.momd/CoreDataExample",
withExtension: "mom")!
let oldManagedObjectModel = NSManagedObjectModel.init(contentsOfURL: oldModelUrl)
Referece: https://medium.com/#yzhong.cs/1d9f941b3168.

iOS Core data migration to another machine

I received the source for an application from a guy to make a few changes in the app. The data model version was, say, App3. I had to add about 3-4 more data model versions in the process. So the active model version when I sent him was App7
I built the project (it was running properly on my mac)
I sent him the zip and when he ran, he got the error "Can't find model for source store"
I had him create the latest data model again, based on the data model App3 and make it the same as App7 and set it as the current version.
He still has the error and I can't figure out why? Are the intermediate data model version causing issues? Is it required to delete the sqlite file in the application support->iphone simulator folder? I am all over the place with this. Please help!
You need to have both model files and have some sort of versioning in place. The new model that you made will no longer work with his data file unless you specify to Core Data that you want it to update the data.
Versioning isn't that easy, but if your changes are small enough, you might be able to get away with automatic versioning. Read the guide and see:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/Introduction.html
In my understanding, it will. But really that is not the thing to do if ultimately the versioning is going to happen on existing live apps too.
For the light-weight migration to work, you need to send him all the intermediate versions of the model as well since the migration takes place stage by stage through all versions.
And you have to make sure that you have made no modification (even accidentally) to the base version App3.

EF Migrations - how to manage during dev and deployment?

We're considering using EF 4.3.1 code-based migrations, but aren't clear about how to integrate Migrations with our present dev/deployment methodology...
The app in-question is a desktop WPF app, with each desktop having its own SQL Server instance (each with 4 separate databases). It is deployed into a "field" environment with zero local IT support. Any database migration must be done using SQL scripts executed by the installer (probably InstallShield). There will not be anyone available who can run a command at a PMC prompt to upgrade the db when it is deployed/upgraded at a field location. Thus the ultimate "output" from EF Migrations must be a set of SQL scripts, which the installer will selectively apply.
Also, we have multiple developers making concurrent database changes.. there is NO DBA. Each developer simply checks-in their code (model) changes to TFS, and the next time they do get-latest, the changes to the model automatically cause a new database to be created on their dev system. So how can we now have each developer perform their own local migrations (rather than deleting/recreating their local databases), and then manage/consolidate/combine those migrations? And what about collisions?
During dev and unit-testing, each developer may delete their (entire) local database multiple times during a single checkout/checkin iteration. This works great with Code First, since the database gets automatically rebuilt when the app is restarted. But this means that the _MigrationHistory table in the database also gets deleted. How do we handle this? Don't we need the migration history of each dev system? If not, then where/how do we detect the aggregate changes which need to be applied to the delivered system?
I can see the value of using Migrations to deal with the mechanics of migrating a database, but what's not clear is how to take advantage of it without introducing a centralized database "change-control" bottleneck into the dev cycle, and thus losing one of the key benefits of Code First.
Any insight/advice would be greatly appreciated!
DadCat
I know this is an old question but I thought I'd post some of my experiences with EF Migrations (v6.1).
Each dev will be fine. Migrations are put into classes with a timestamp in the name, so no collisions will happen. The DB on the dev's machine will be updated after doing a get latest and running the app (or the update-database command).
Deleting the local db and recreating is fine. Just make sure the dev runs update-database before adding additional migrations or things will get out of sync. I'm a bit confused as to why they'd need to delete the local DB, but that's out of scope. You may find that your process needs to change to accommodate EF Migrations.
I can't help you with the installer question, as a similar question brought me here. The update-database command does have a -script option that will generate the proper change script, but I'm unclear how to automate that on a build server.

Updating new version to app store with different sqlite db structure

I have uploaded an app on app store (version 1.0). My app is using a sqlite database for storing some data. Now, I have made some changes in the database (I have added 2 or 3 new columns in one of the tables in my db). I want to update the previous version of my app with the new version 1.1 (which is having different db structure). Now, when the users which are already using the version 1.0 upgrade the app to version 1.1, the db is already present in app sandbox and hence, the app is pointing to version 1.1, but my db is still the old one. I want to have the new db with the old data, if any. Please help me out. Thanks.
sqlite supports something called as user_version property, you can execute PRAGMA user_version to query for current schema version of your app db. This query can happen write at the beginning when your app starts.
to update this user_version execute following update query PRAGMA user_version = version_num;
Whenever you create sqlite db, it is best practice to put this property user_version, so that when you are upgrading in future you can query current value. Check what it's needs to be and execute remaining alter or create tables to upgrade your schema version.
For example:
In first release I create table1 with col1, col2
I execute sql to create table1 and once it is successfully done, i execute pragma user_version = 1. so this will indicate my current schema version is 1
In future release i add new col3, i need to change my schema version to 2
I first query user_version, check it's value and if it is 1, then you need to run alter script to add new column and set user version to 2.
In your case, since you haven't set the user_version before, it would be difficult to differentiate new install vs an upgrade scenario. So for now may be you assume if db is present it is upgrade scenario and execute alter scripts and if not present assume it is a new
install scenario and run create scripts. But see if you can use above pragma to solve your problem in future atleast.
You could check on launch if it's the old db, and if so have a routine to create a new db with the new structure (with a temporary name), copy all the data from the old to the new, close the old db & delete it, close the new db, rename it, then finally open it again for your updated app to use. Easy, fast, & you don't need an in-depth knowledge of SQLite to do it.

Resources