Translations/Specs/MessageSharing/Migration

Not logged in - Log In / Register

Revision 23 as of 2009-03-24 08:18:38

Clear message

Message Sharing Migration

Part of the message sharing project.

Assumptions

Migration steps

Migration consists of these phases:

Code changes

To be landed before migration:

Note: When clearing is_current in validate_is_current, converge the TM that's having the flag cleared.

Initial Cleanup

Before migrating, we should probably delete all non-current POTemplates. This saves us from having to worry about them.

Before we can delete a POTemplate, we must delete any rows that refer to it:

  1. Clear TranslationMessage.pofile if the column still exists. We won't be using it anymore.

  2. Delete all TranslationMessages that refer to the template in their potemplate fields.

  3. Find all TranslationTemplateItems that refer to the template, and delete them.

  4. Find any POTMsgSets that the deleted TranslationTemplateItems referred to, and that have no other TranslationTemplateItems referring to them.

  5. Delete any TranslationMessages attached to those POTMsgSets.

  6. Delete those POTMsgSets.

  7. Delete all POFiles that refer to the template. Any references in POFileTranslator should have gone away when we deleted the TranslationMessages.

  8. Delete the POTemplate.

Merge POTMsgSets

At the end of this phase, TranslationMessages will still be mostly diverged, but they'll be sharing POTMsgSets.

This phase requires at least a freeze on imports.

It's best to go through this separately per Ubuntu release, and maybe once for everything else. We must stop imports for whatever product or distroseries we're merging, which we can do individually for each Ubuntu series.

Commit transactions after every equivalence class of POTemplates. Keep track of which ones are done, so we can restart etc.

Pseudocode:

def get_key(potmsgset):
    return (potmsgset.msgid_singular, potmsgset.msgid_plural, potmsgset.context)


def merge_potmsgsets(potemplates):
    # Sort potemplates from "most representative" to "least representative."
    potemplates.sort(cmp=template_precedence)

    representatives = {}
    subordinates = {}

    # Figure out representative potmsgsets and their subordinates.
    for template in potemplates:
        for potmsgset in template.potmsgsets:
            key = get_key(potmsgset)
            if key not in representatives: representatives[key] = potmsgset
            representative = representatives[key]
            if representative in subordinates: 
                subordinates[representative].append(potmsgset)
            else:
                subordinates[representative] = []

    for representative, potmsgsets in subordinates.iteritems():
        for subordinate in potmsgsets:
            merge_translationtemplateitems(subordinate, representative)

            for message in subordinate.translation_messages:
                if message.potemplate is None:
                    # Guard against multiple imported messages.
                    if message.is_imported:
                        imported = representative.getImportedMessage(message.language, message.variant)
                        if imported is not None: message.is_imported = False
                    # Guard against multiple shared current messages.
                    if message.is_current:
                        current = representative.getCurrentMessage(message.language, message.variant, potemplate=None)
                        if current is not None: message.is_current = False
                message.potmsgset = representative
            subordinate.destroy()

Merge TranslationMessages

This phase operates only on TranslationMessage, and can be done at leisure.

Use TranslationMessage.converge() as defined above. Run it on all TranslationMessages in distroseries/productseries that have translation focus, then on all other series.

Database constraints

Once the assumptions are fulfilled:

  • If we still have POFile, drop all constraints involving TranslationMessage.pofile.

After rolling out code changes:

After migration:

Checks

Some things we should check regularly after migration: