Esempio 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;
            }
        }
Esempio n. 2
0
        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);
        }