Exemplo n.º 1
0
        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;
            }
        }