[odb-users] Custom migration functions fails when migrating multiple versions

stef dalbosco stef.dalbosco at hotmail.com
Wed Apr 27 06:23:28 EDT 2022


Hi,

I have a db object that has a member that I want to fill in at run time. So I registered a migration function that fills in that member when migrating to that version.
In this migration function, I loaded in the object because the default value is depended on the other members. This worked as expected until a new version was added that added a new member.
If I now migrate both versions at the same time, my custom migration function crashes when I query. I think this is because it calls code that is already for the newest version but the schema is still in between.

Is there a way to fix this?
I could register my migration function with the latest version so during migration it will be called last. But I'm not confident this is a permanently solution.
See example below for  clearer description.


I have a object Person with a name and a guid that is depended on the name:
#pragma db object
struct Person //created in version 1
{
    #pragma db id auto
    unsigned id_;

    std::string name_;
    #pragma db default("")
   std::string guid_;  //added in version 2
    std::string email_;  //added in version 3
}

After generating I get two schema migration functions which both will add a column:
static const schema_catalog_migrate_entry
  migrate_schema_entry_2_ (id_sqlite, "lib", 2ULL, &migrate_schema_2);

static const schema_catalog_migrate_entry
  migrate_schema_entry_3_ (id_sqlite, "lib", 3ULL, &migrate_schema_3);

And this is my custom migration:
static void migrate_GUIDS(odb::database& db)
{
    auto persons = db.query<lib::Person>();
    for (auto it = persons.begin(); it != persons.end(); ++it)
    {
        auto pPerson = it.load();

        if (!pPerson->guid().value.isEmpty())
            continue;

        pComposition->set_guid(/*generate guid depended on name*/);
        db.update(pComposition);
    }
}
odb::schema_catalog::data_migration_function(db, 2ULL, &migrate_GUIDS, "lib");

For this example, if I migrate a db that is on version 1 to version 3, the migration will call the functions in this order

  1.  migrate_schema_2 that adds the guid column
  2.  migrate_GUIDS that fills in the guid
  3.  migrate_schema_3 that adds the email column
But migrate_GUIDS will crash on the line db.query<lib::Person>() because the query statement is from the form:
SELECT "person"."id", "person"."name", "person"."guid", "person"."email" FROM "person"
At that time person.email is not added yet.


Thanks in advance for your help,
Stef



More information about the odb-users mailing list