Versioning

Mar 21, 2011 at 7:27 PM

 

I've been using Sterling for about a week now and have been very happy with it. However to go from "Proof of Concept" to "Real product" I need to be able to version my database. My server (via RIA / WCF) will give me a database version #, at which point I can either use the one on disk (if they match) or delete the DB and create a new one.

I'm having two distinct problems:

Problem 1: Versioning Failures:

1 - Assume my V1 database has two tables ("Test.A", "Test.B").

2 - In my codebase, I delete "Test.B" class and remove it from the project.

3 - When I startup sterling, the DB will give an NRE because the type "Test.A", which it finds in the database, cannot be resolved via GetType.

How can I work past this? It seems like a showstopper to any versioning. All I need is to know the DB is out of date.

Problem 2: Deleting the database

From code, how can I completly wipe the database? Short of deleting all the files from Isolated Storage (which is very heavy handed) there has to be a way to do this. Purge() doesn't do it, as it seems to retain the schema.

Any thoughts that anyone has are appriciated!

--
Chris Mullins

 

 

Coordinator
Mar 21, 2011 at 7:45 PM

Hi, Chris! I responded to your contact form but I'm repeating the reply here for the benefit of others running into a similar issue:

I know the versioning story is a pain point and working with some ways to handle that. I can easily add a version to the database, that's a non issue and will go into the next release.

I'm working around the guidance for versioning. Right now, the best way is to have a V1 and V2 database. I've posted a user who provided some guidance there but it basically involved using namespaces for the new versions and then detecting if the old database existed - if so, the entities are read, transferred, and updated to the new.

One thing I'm exploring is saving a table definition with the properties in a version. Right now I iterate from the type definition itself, which obviously can collide with the serialized. With a type definition, I can look for a mismatch, then drive from the old properties on load and the new on save and make it more automatic - something I'm looking into but has been behind the drivers I've recently implemented as a priority. I believe the drivers may provide you with some more flexibility, not sure if you've seen the latest change set but basically the storage is completely separated from the serialization, so you can have an in-memory driver, a iso driver, an elevated trust, and I have a project I'm working on where they are looking at an Azure object storage driver which is why I made the change in the first place.

To solve the version issue, you can have a database that uses the driver. When version two comes out, you replace the driver with a conversion driver and have a new driver for the new database. The conversion driver checks for the existence, then works with the new driver to load (old driver) then save (new driver) and migrate the database.

To blow the database away, there is an IsolatedStorageHelper static method now for purging that you pass the root to and it recursively deletes the items on disk. You can see that in the unit tests.

Let me summarize what I think I can do to help you out, and you let me know and correct my list as needed:

1. Provide a database version - is this for your database, or for the Sterling database? The intent for user databases was to allow the version to be embedded in the database name, i.e. "Database V1" "Database V2." This discussion shows you one way a user dealt with the versioning, but I also believe the new driver architecture will give you even more flexibility: http://sterling.codeplex.com/discussions/239428
2. Give you access to register the table. I have to work with this because I use ordinals to store the tables internally, which is why order does matter .. I may just switch to use the full name for the table type and then there won't be a collision, but giving you the ability to late-bind a table definition.

Will those 2 get you closer to what you need?

Mar 21, 2011 at 8:39 PM

It turns out that IsoStorageHelper is an Internal class, not callable from standard user code.

Any other suggestions for blowing away a database?

--
Chris

Coordinator
Mar 21, 2011 at 9:00 PM

You might see an email reply come across too - basically the answer is that IsolatedStorageHelper will be public. It has to switch so other people can use it in their custom drivers, just haven't made those changes yet. I'll work on a build to check in later this week that addresses the late-binding tables as well as the public modifier on the isolated storage.

Coordinator
Mar 27, 2011 at 7:30 PM

Just a quick FYI - the iso storage helper is public now, and I also addressed the issue of registering tables. You can now do that any time so it should be MEF-friendly for you.