Chris Tutty wrote:
> Does anyone out there have a good example of multi-version
> preference handling that includes upgrading prior preference
> versions?  

I can tell you how I do it.  I just have a struct, and when I need
to add fields, I add them to the end.  I have revision numbers for
the struct, and an integer storing the revision number is part of
the (earliest version of) the struct.

Then I have a list of all revision numbers that ever occurred, and
a big function that sets default values for all the fields added
in a revision.

So, kinda like this:

        typedef struct
        {
            Int32 revision;

            // 20050101 fields
            Int32 oldfield1;
            Int32 oldfield2;

            // 20050203 fields
            Int32 newfield1;
            Int32 newfield2;
        } PrefsData;

        static const Int32 gAllRevisions[] = { 20050101, 20050203, 0 };
        static const Int32 gCurrentRevision = 20050203;

        void FillInMissingDefaults (PrefsData *prefsdata)
        {
            Int32 *revisionptr;

            for (revisionptr = gAllRevisions; *revisionptr != 0; revisionptr++)
            {
                if (prefsdata->revision < *revisionptr)
                {
                     SetDefaultsForRevision (prefsdata, *revisionptr);
                }
            }

            prefsdata->revision = gCurrentRevision;
        }

        void SetDefaultsForRevision (PrefsData *prefsdata, Int32 revision)
        {
            switch (revision)
            {
            case 20050101:
                prefsdata->oldfield1 = 42;
                prefsdata->oldfield2 = 99;
                break;

            case 20050203:
                prefsdata->newfield1 = 86;
                prefsdata->newfield2 = 77;
                break;
            }
        }

If the preferences data doesn't exist (first program invocation,
or missing preferences), you can just set prefsdata->revision to 0
and then call FillInMissingDefaults().

This system works OK, but every time I update it I worry that
I'll make a careless error (like not adding a revision to
gAllRevisions[]) and then I'm gonna have users out in the
field with uninitialized fields in their preferences.

I think if I were starting from scratch, I would write preferences
out as a symbol table.  Then at app start time, I'd read that
symbol table in to some data structure (probably hash based on
symbol table string value, or just linked list with linear search
if I only expect to have like 10 preferences values).  Then check
for the existence of certain symbols, and if they don't exist,
set them to defaults.  That wouldn't give me as much control as
the method I'm using now, but it also would free me from having
to be super careful when changing anything about preferences.
Right now I have to remember lots of rules (never remove a field
from the struct, never change the order, always add new fields
to the end of the struct, always add new revision numbers to the
list of revision numbers, always update the current revision number),
so that's a pain.

Oh yeah, a totally different approach:  just save each new
piece of the preferences data in a separate preferences
record.  First piece is record 0, second piece is record 1,
etc.  Down side to this is that you'll end up with lots of
records with just one field in them.

  - Logan



-- 
For information on using the Palm Developer Forums, or to unsubscribe, please 
see http://www.palmos.com/dev/support/forums/

Reply via email to