I'm seeing a lot of answers that explain to perform the following check in onUpgrade
in openDatabase
:
if (oldVersion < newVersion) {
await db.execute('CREATE TABLE CUSTOMER....');
}
This will work when performing your first database upgrade (ie version 1 to 2), but will fail when executing your second (say 2 to 3) since the table 'CUSTOMER' will already have been created. So you need logic to only call upgrades one time. In addition, you may be on version 10 of your database and the user is on version 5, so you need to handle only upgrades of 6,7,8,9 and 10. Below is the the logic I built to handle these scenarios:
static Future<Database?> getDatabase() async {
if (_dbInstance == null) {
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, _databaseName);
_dbInstance = await openDatabase(path, version: _databaseVersion,
onUpgrade: (Database db, int oldVersion, int newVersion) async {
//
//Iterate from the current version to the latest version and execute SQL statements
for (int version = oldVersion; version < newVersion; version++) {
await _performDBUpgrade(db, version + 1);
}
},
onCreate: (Database db, int newVersion) async {
//
//Start from version 1 to current version and create DB
for (int version = 0; version < newVersion; version++) {
await _performDBUpgrade(db, version + 1);
}
});
}
return _dbInstance;
}
//Call to upgrade the database. [upgradeToVersion] is the version of SQL statements that should be
//executed. A version of 1 is the initial creation of the database. Anything higher would
//be an upgrade of the database. This function should be called once for every version upgrade.
//For example, if current version is 1 and user is now performing an update and new version is
//5, then this function should be called 4 times (from `onUpgrade`), where [upgradeToVersion] would be passed a 2, 3, 4 and 5.
static Future<void> _performDBUpgrade(Database db, int upgradeToVersion) async {
switch (upgradeToVersion) {
//Upgrade to V1 (initial creation)
case 1:
await _dbUpdatesVersion_1(db);
break;
//Upgrades for V2
case 2:
//await _dbUpdatesVersion_2(db);
break;
}
}
///Database updates for Version 1 (initial creation)
static Future<void> _dbUpdatesVersion_1(Database db) async {
await db.execute('CREATE TABLE Customer...)');
}