public bool MigrateDatabaseData() { ISQLDatabase database = ServiceRegistration.Get <ISQLDatabase>(false); int curVersionMajor; int curVersionMinor; int totalMigrationSteps = 1; try { if (GetDatabaseVersion(out curVersionMajor, out curVersionMinor, true)) { if (curVersionMajor != DATABASE_VERSION_MAJOR || curVersionMinor != DATABASE_VERSION_MINOR) { ServiceRegistration.Get <ILogger>().Info("DatabaseManager: Initiating data migration to database version {0}.{1}", DATABASE_VERSION_MAJOR, DATABASE_VERSION_MINOR); //Database was not migratable before version 2.1 if (curVersionMajor == 2 && curVersionMinor == 0) { curVersionMinor = GuessMiniorVersion(true); } var miaTypes = GetMiaTypes().OrderBy(m => m.Date); var oldMiaTypes = GetMiaTypes(true); //Add subschemas List <DatabaseMigrationManager> schemaManagers = new List <DatabaseMigrationManager>(); foreach (string subSchema in GetDatabaseSubSchemas()) { DatabaseMigrationManager schemaManager = new DatabaseMigrationManager(subSchema); schemaManager.AddDirectory(MediaPortal_Basis_Schema.DatabaseUpgradeScriptDirectory); schemaManagers.Add(schemaManager); } //Add aspects List <DatabaseMigrationManager> aspectManagers = new List <DatabaseMigrationManager>(); foreach (var mia in miaTypes) { DatabaseMigrationManager aspectManager = GetMiaMigrationManager(mia.Id, mia.Name); if (aspectManager != null) { aspectManagers.Add(aspectManager); } else { ServiceRegistration.Get <ILogger>().Warn("DatabaseManager: Migration of aspect '{0}' skipped because no migration manager was available", mia.Name); } } foreach (var mia in oldMiaTypes.Where(o => !miaTypes.Any(m => m.Id == o.Id))) { ServiceRegistration.Get <ILogger>().Warn("DatabaseManager: Migration of aspect '{0}' skipped because it no longer exists", mia.Name); } //Add cleanup script List <DatabaseMigrationManager> scriptManagers = new List <DatabaseMigrationManager>(); DatabaseMigrationManager cleanupManager = new DatabaseMigrationManager("Cleanup"); cleanupManager.AddDirectory(MediaPortal_Basis_Schema.DatabaseUpgradeScriptDirectory); scriptManagers.Add(cleanupManager); totalMigrationSteps = schemaManagers.Count + aspectManagers.Count + scriptManagers.Count; //All migrations totalMigrationSteps += 2; //Add backup steps that has already been completed totalMigrationSteps += 2; //Add commit and drop steps that will be done after migration is complete int currentMigrationStep = 2; //Backup is already complete using (ITransaction transaction = database.BeginTransaction(IsolationLevel.Serializable)) { //Migrate sub schema data. Note that not all sub schemas need to be migrated foreach (var manager in schemaManagers) { if (manager.MigrateData(transaction, curVersionMajor, curVersionMinor, DATABASE_VERSION_MAJOR, DATABASE_VERSION_MINOR)) { ServiceRegistration.Get <ILogger>().Info("DatabaseManager: Migrated subschema '{0}'", manager.MigrationOwnerName); } SendUpgradeProgress(++currentMigrationStep, totalMigrationSteps); } //Migrate aspect data foreach (var manager in aspectManagers) { if (manager.MigrateData(transaction, curVersionMajor, curVersionMinor, DATABASE_VERSION_MAJOR, DATABASE_VERSION_MINOR)) { ServiceRegistration.Get <ILogger>().Info("DatabaseManager: Migrated aspect '{0}'", manager.MigrationOwnerName); } else { ServiceRegistration.Get <ILogger>().Warn("DatabaseManager: Migration of aspect '{0}' failed", manager.MigrationOwnerName); } SendUpgradeProgress(++currentMigrationStep, totalMigrationSteps); } //Scripts foreach (var manager in scriptManagers) { if (manager.MigrateData(transaction, curVersionMajor, curVersionMinor, DATABASE_VERSION_MAJOR, DATABASE_VERSION_MINOR)) { ServiceRegistration.Get <ILogger>().Info("DatabaseManager: Executed script '{0}'", manager.MigrationOwnerName); } else { ServiceRegistration.Get <ILogger>().Warn("DatabaseManager: Execution of script '{0}' failed", manager.MigrationOwnerName); } SendUpgradeProgress(++currentMigrationStep, totalMigrationSteps); } transaction.Commit(); SendUpgradeProgress(++currentMigrationStep, totalMigrationSteps); } SetDatabaseVersion(DATABASE_VERSION_MAJOR, DATABASE_VERSION_MINOR, true); if (!GetDatabaseVersion(out curVersionMajor, out curVersionMinor, true) || curVersionMajor != DATABASE_VERSION_MAJOR || curVersionMinor != DATABASE_VERSION_MINOR) { throw new IllegalCallException(string.Format("Unable to migrate database data to version {0}.{1}", DATABASE_VERSION_MAJOR, DATABASE_VERSION_MINOR)); } } database.DropBackupTables(BACKUP_TABLE_SUFFIX); ServiceRegistration.Get <ILogger>().Info("DatabaseManager: Successfully migrated database data to version {0}.{1}", DATABASE_VERSION_MAJOR, DATABASE_VERSION_MINOR); //Exit MediaLibrary maintenance mode if (ServiceRegistration.Get <IMediaLibrary>() is MediaLibrary.MediaLibrary mediaLibrary) { mediaLibrary.MaintenanceMode = false; } SendUpgradeProgress(totalMigrationSteps, totalMigrationSteps); return(true); } return(false); } finally { _upgradeInProgress = false; } }
protected DatabaseMigrationManager GetMiaMigrationManager(Guid miaId, string miaName) { if (_miaManagement == null) { _miaManagement = new MIA_Management(); } //Check if table for mia can be found var metaData = _miaManagement.GetMediaItemAspectMetadata(miaId); string tableName = _miaManagement.GetMIATableName(metaData); if (string.IsNullOrEmpty(tableName)) { return(null); } //Check if backup table exists ISQLDatabase database = ServiceRegistration.Get <ISQLDatabase>(false); if (!database.TableExists($"{tableName}{BACKUP_TABLE_SUFFIX}")) { return(null); } //Add main table IDictionary <string, IList <string> > defaultScriptPlaceholderTables = new Dictionary <string, IList <string> >(); defaultScriptPlaceholderTables.Add(MIA_TABLE_PLACEHOLDER, new List <string> { tableName }); //Add collection tables foreach (var attribute in metaData.AttributeSpecifications) { if (attribute.Value.IsCollectionAttribute) { if (attribute.Value.Cardinality == Common.MediaManagement.Cardinality.OneToMany || attribute.Value.Cardinality == Common.MediaManagement.Cardinality.ManyToMany) { tableName = _miaManagement.GetMIACollectionAttributeTableName(attribute.Value); if (string.IsNullOrEmpty(tableName)) { continue; } if (!database.TableExists($"{tableName}{BACKUP_TABLE_SUFFIX}")) { continue; } if (!defaultScriptPlaceholderTables.ContainsKey(MIA_V_TABLE_PLACEHOLDER)) { defaultScriptPlaceholderTables.Add(MIA_V_TABLE_PLACEHOLDER, new List <string>()); } defaultScriptPlaceholderTables[MIA_V_TABLE_PLACEHOLDER].Add(tableName); } if (attribute.Value.Cardinality == Common.MediaManagement.Cardinality.ManyToMany) { tableName = _miaManagement.GetMIACollectionAttributeNMTableName(attribute.Value); if (string.IsNullOrEmpty(tableName)) { continue; } if (!database.TableExists($"{tableName}{BACKUP_TABLE_SUFFIX}")) { continue; } if (!defaultScriptPlaceholderTables.ContainsKey(MIA_NM_TABLE_PLACEHOLDER)) { defaultScriptPlaceholderTables.Add(MIA_NM_TABLE_PLACEHOLDER, new List <string>()); } defaultScriptPlaceholderTables[MIA_NM_TABLE_PLACEHOLDER].Add(tableName); } } } DatabaseMigrationManager manager = new DatabaseMigrationManager(miaName, "DefaultAspect", defaultScriptPlaceholderTables); manager.AddDirectory(MediaPortal_Basis_Schema.DatabaseUpgradeScriptDirectory); return(manager); }