The MIGRATION_XXX constants do not allow for a migration process that has stages that write to the old and the new schema, but only reads from one of the schemas. For the MCR migration, it's more useful to first have a stage when both schemas are written but the old schema is still read, and then switching to a stage where both schemas are still written, but only the new schema is read: this allows us to exerciser the new code fore reading, while still avoiding extra fallback code (which is especially complex and error prone when we have to do it in a single SQL query), and still allowing us to easily back out of the migration and go back to using the old schema.
To achieve this, the migration stage should be defined as a bit field, with individual bits that control reading and writing of the old and the new schema:
define( 'SCHEMA_COMPAT_WRITE_OLD', 0x01 ); define( 'SCHEMA_COMPAT_READ_OLD', 0x02 ); define( 'SCHEMA_COMPAT_WRITE_NEW', 0x10 ); define( 'SCHEMA_COMPAT_READ_NEW', 0x20 ); define( 'SCHEMA_COMPAT_WRITE_BOTH', SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_WRITE_NEW ); define( 'SCHEMA_COMPAT_READ_BOTH', SCHEMA_COMPAT_READ_OLD | SCHEMA_COMPAT_READ_NEW ); define( 'SCHEMA_COMPAT_OLD', SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_OLD ); define( 'SCHEMA_COMPAT_NEW', SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_NEW );
To keep the MIGRATION_XXX constants compatible with the new bit field logic, their numeric value is changed to contain the bit field in the lower bits, and use higher bits to preserve their original ordering, like so:
define( 'MIGRATION_OLD', 0x00000000 | SCHEMA_COMPAT_OLD ); define( 'MIGRATION_WRITE_BOTH', 0x10000000 | SCHEMA_COMPAT_READ_BOTH | SCHEMA_COMPAT_WRITE_BOTH ); define( 'MIGRATION_WRITE_NEW', 0x20000000 | SCHEMA_COMPAT_READ_BOTH | SCHEMA_COMPAT_WRITE_NEW ); define( 'MIGRATION_NEW', 0x30000000 | SCHEMA_COMPAT_NEW );