Rickard Öberg wrote:
Hey,

Yes, versioning again. I have thought some more about versioning and am coming back to that while the previous scheme was way too complicated, and that it's an implementation detail, Qi4j could still help somewhat to make it easier.

To do data migration in key-value stores it would be useful if each stored entity had a version number of the entire application, rather than the version of the entity-type that we played with in the SPI some time ago. This way it becomes easier to specify migration rules and ensure that data is in a consistent format. Importing old backups would also be possible, as it could be upgraded on the fly.

Here's what I suggest: in Application we add a method version(), with a corresponding method in ApplicationAssembly to set it. What to set it to is up to the user. It could be on the "1.2.3" format, or it could be revision nr (e.g. "345"). Just something that makes sense for the application. Then, the default EntityStore implementations would store this version in the data. When state is read the stored version can be compared with the current version. If they are the same, all is ok. If they are not the same, then a Migrator service should be invoked.

The Migrator service, and how to configure it, is not defined. Well, the Migrator interface would be defined in the SPI, but there could be many implementations, with different strategies. One would be to declare rules using some Fluent API, like so:
migrator.
onVersion("1.2.1").
  forEntities("SomeEntity").
    renameProperty("oldName","newName").
    addProperty("name","someDefaultValue").
    removeAssociation("someName").
    migrate(new CustomEntityMigrator());
and so on. This should allow pretty powerful possibilities for doing both standard and custom migrations. The migration could either be done lazily on read, or eagerly on startup. This could be specified as well in such a fluent API:
migrator.onVersion("1.3.0").eagerMigrate();

All of this would be done in the assembly phase, btw.

Another implementation could take a JSON-export of the database and serialize it to XML and use XSLT for the rules. And yet another one could post it to some REST-resource that performs the transformation. And so on.

But the point is that if we just add the version property in the Application API, and a Migrator service that EntityStores can call, then I think that would be enough.

I have quite urgent need for it, so unless this is an obviously bad idea I would like to go ahead and add it.

What do you think?

/Rickard

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev
Hi Rickard,

as I understand your sample for the migrator API,
the onVersion(String) method takes the version of the entities,
which are to be migrated to the version defined by
ApplicationAssembly.version().

So if we have a bunch of old version lying around, we (may) have
migration rules for all this old versions to the actual
application version,e.g.

migrator.
onVersion("1.2.1").
...

migrator.
onVersion("1.3.0").
...

if we e.g. assume that the current version history is

1.2.1 -> 1.3.0 -> 1.4.0

where 1.4.0 is the current application version and '->' means 'has successor'.
The problem with the API I see is, that the migration rules always
describe the *full* migration from each of the predecessors of
the current application version to it (or did I get something wrong?). I.e. if we later have
a 1.5.0 as sucessor of 1.4.0, and the 'diff' between 1.4.0 and 1.5.0 is
something like addProperty("name","someDefaultValue"), we must not only
introduce a

migrator.
onVersion("1.4.0").
...
addProperty("name","someDefaultValue")

rule, but we also must touch the older rules and add the same statement.

Would'nt it be better to specify the migration rules as diffs (or better patches) from one version to its direct successor, plus the version history, and let the migrator service determine which patches to apply in the correct order?

Cheers,
Georg

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to