0
1

How smart and good are the DO upgrade functions?

In my desktop application I am using SQL CE as a backend. I basically have 1 entity called Program which contains several other entities, but all are linked to a single Program.

Let's say that, over the course of a year, I release 5 versions of my desktop application, each containing a small modification to the data model. If a user updates from version 1 - 2 - 3 - 4 - 5 the upgrade functions do their job and everything seems to work nicely. But I also want my users to be able to update from version 1 - 5 directly, 2 - 4, 3 - 5 and so forth. Are the upgrade functions of DO smart enough to detect this, or will I have to foresee upgrade functions from each possible start version to each possible end version myself? What would be best practice?

Secondly, users can export and import data. Since the data is identical to a single Program entity my quickest and easiest solution was to create a new database file, which contains the exact same layout as my main application database file, it will just contain a single instance of a Program and all it's required data. So far, no problem. But user A can export a Program from version 1, and user B should be able to import it into his version 5. So the same upgrade steps should be performed on the exported database file before the data is added to the main application database file. Again, is DO smart enough to detect from which version to start, and in which version to end?

asked Jan 12 '11 at 08:29

jensen's gravatar image

jensen
399913

edited Jan 14 '11 at 15:36

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

It seems I didn't fully understood the question. Do you mean:

  • You have a custom DB import / export routines
  • They dump (or import) the DB to custom format
  • This format varies from version to version (I assume it is similar to DB schema)
  • You must be able to import the data from any version of this format.

Is this a correct description?

(Jan 12 '11 at 13:13) Alex Yakunin Alex%20Yakunin's gravatar image

I updated the initial question since I ran out of characters in this comment box.

So the question becomes, how smart and good are the DO upgrade functions, how much manual work will I need to do and how complicated will it get?

(Jan 13 '11 at 02:40) jensen jensen's gravatar image

One Answer:

But I also want my users to be able to update from version 1 - 5 directly, 2 - 4, 3 - 5 and so forth.

Schema upgrade in DO is generally designed to upgrade the data from precisely known version to the current one. So in some cases it will be possible to upgrade to v3 from both v2 and v1, but in general case - no.

In general case you need incremental upgrade routine to handle this. Imagine user upgrades your application from v1 to v4:

  • When your application starts, DO discovers it can't build a Domain (upgrade handler of v4 detects there is v1 instead of v3, so it can't upgrade the data), and you get a specific exception.
  • You launch a special upgrade routine, that sequentially launches Domain.Build() for v3 (fails), v2 (succeeds with upgrade), and v3 again (succeeds with upgrade). All these Domains are build in dedicated AppDomains, since you must load different versions of model assemblies for this.
  • When this process completes, you can rebuild the domain.

To implement this, you should:

  • Maintain a directory (e.g. "Migrations") with all the previous model versions of your applicaiton (i.e. with "v1", "v2", ... subdirs).
  • Use some convention allowing your upgrade tool to build a Domain based on assemblies in each of these folders. E.g. it can simply look for some specific type and method there (DomainBuilder).
  • And finally, write the upgrade routine implementing this logic (i.e. iterating over directories and launching the code based on convention in dedicated AppDomain). Likely, we'll implement such a tool in future.

So the same upgrade steps should be performed on the exported database file before the data is added to the main application database file. Again, is DO smart enough to detect from which version to start, and in which version to end?

No, DO can't do that, and moreover, there is principally impossible. DO uses a specific set of rules on upgrade and doesn't have any history of changes of your model, so it can't do this. I.e. if you rename A to B in v1 -> v2 with data loss, and rename B to A back in v3 (again, with data loss), upgrade from v1 to v3 directly will lead to different result then incremental upgrade. So I'd advice you to use incremental upgrade.

Btw, default upgrade handler (see UpgradeHandler class) reports it can upgrade the data from empty DB, or from the same version:

public virtual bool CanUpgradeFrom(string oldVersion)
{
  return oldVersion==null || oldVersion==AssemblyVersion;
}

But since normally you don't explicitly specify the schema version (i.e. use default "1.0.0.0"), no error occurs even if you change your persistent types.

answered Jan 14 '11 at 15:36

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

OK, than I'll guess my only option is to keep the older data model versions and perform incremental upgrades. It's a bit more work (or let's say I don't like keeping legacy data models around) but I can live with that.

Working with the errors of the domain build functionality seems an acceptable solution to upgrade both the application database as the exported data files. If I understand correctly that also means I do not need to keep track of those version numbers.

So I think this solves my issues.

(Jan 15 '11 at 10:48) jensen jensen's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA