public async Task UpdateAsync(string feature)
        {
            if (_processedFeatures.Contains(feature))
            {
                return;
            }

            _processedFeatures.Add(feature);

            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation("Updating feature: {0}", feature);
            }

            // proceed with dependent features first, whatever the module it's in
            var dependencies = _extensionManager.AvailableFeatures()
                               .Where(f => String.Equals(f.Id, feature, StringComparison.OrdinalIgnoreCase))
                               .Where(f => f.Dependencies != null)
                               .SelectMany(f => f.Dependencies)
                               .ToList();

            foreach (var dependency in dependencies)
            {
                await UpdateAsync(dependency);
            }

            var migrations = GetDataMigrations(feature);

            // apply update methods to each migration class for the module
            foreach (var migration in migrations)
            {
                _session.ExecuteMigration(schemaBuilder =>
                {
                    migration.SchemaBuilder = schemaBuilder;

                    // copy the object for the Linq query
                    var tempMigration = migration;

                    // get current version for this migration
                    var dataMigrationRecord = GetDataMigrationRecordAsync(tempMigration).Result;

                    var current = 0;
                    if (dataMigrationRecord != null)
                    {
                        current = dataMigrationRecord.Version.Value;
                    }
                    else
                    {
                        dataMigrationRecord = new Records.DataMigration {
                            DataMigrationClass = migration.GetType().FullName
                        };
                        _dataMigrationRecord.DataMigrations.Add(dataMigrationRecord);
                    }

                    try
                    {
                        // do we need to call Create() ?
                        if (current == 0)
                        {
                            // try to resolve a Create method

                            var createMethod = GetCreateMethod(migration);
                            if (createMethod != null)
                            {
                                current = (int)createMethod.Invoke(migration, new object[0]);
                            }
                        }

                        var lookupTable = CreateUpgradeLookupTable(migration);

                        while (lookupTable.ContainsKey(current))
                        {
                            try
                            {
                                if (_logger.IsEnabled(LogLevel.Information))
                                {
                                    _logger.LogInformation("Applying migration for {0} from version {1}.", feature, current);
                                }
                                current = (int)lookupTable[current].Invoke(migration, new object[0]);
                            }
                            catch (Exception ex)
                            {
                                if (ex.IsFatal())
                                {
                                    throw;
                                }
                                _logger.LogError(0, "An unexpected error occurred while applying migration on {0} from version {1}.", feature, current);
                                throw;
                            }
                        }

                        // if current is 0, it means no upgrade/create method was found or succeeded
                        if (current == 0)
                        {
                            return;
                        }

                        dataMigrationRecord.Version = current;
                    }
                    catch (Exception ex)
                    {
                        if (ex.IsFatal())
                        {
                            throw;
                        }
                        _logger.LogError(0, "Error while running migration version {0} for {1}.", current, feature);
                        _session.Cancel();
                        throw new OrchardException(T("Error while running migration version {0} for {1}.", current, feature), ex);
                    }
                    finally
                    {
                        // Persist data migrations
                        _session.Save(_dataMigrationRecord);
                    }
                });
            }
        }
Ejemplo n.º 2
0
        public async Task UpdateAsync(string feature)
        {
            if (_processedFeatures.Contains(feature))
            {
                return;
            }

            _processedFeatures.Add(feature);

            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation("Updating feature: {0}", feature);
            }

            // proceed with dependent features first, whatever the module it's in
            var dependencies = _extensionManager.AvailableFeatures()
                .Where(f => String.Equals(f.Id, feature, StringComparison.OrdinalIgnoreCase))
                .Where(f => f.Dependencies != null)
                .SelectMany(f => f.Dependencies)
                .ToList();

            foreach (var dependency in dependencies)
            {
                await UpdateAsync(dependency);
            }

            var migrations = GetDataMigrations(feature);

            // apply update methods to each migration class for the module
            foreach (var migration in migrations)
            {
                _session.ExecuteMigration(schemaBuilder =>
                {
                    migration.SchemaBuilder = schemaBuilder;

                    // copy the object for the Linq query
                    var tempMigration = migration;

                    // get current version for this migration
                    var dataMigrationRecord = GetDataMigrationRecordAsync(tempMigration).Result;

                    var current = 0;
                    if (dataMigrationRecord != null)
                    {
                        current = dataMigrationRecord.Version.Value;
                    }
                    else
                    {
                        dataMigrationRecord = new DataMigration { DataMigrationClass = migration.GetType().FullName };
                        _dataMigrationRecord.DataMigrations.Add(dataMigrationRecord);
                    }

                    try
                    {
                        // do we need to call Create() ?
                        if (current == 0)
                        {
                            // try to resolve a Create method

                            var createMethod = GetCreateMethod(migration);
                            if (createMethod != null)
                            {
                                current = (int)createMethod.Invoke(migration, new object[0]);
                            }
                        }

                        var lookupTable = CreateUpgradeLookupTable(migration);

                        while (lookupTable.ContainsKey(current))
                        {
                            try
                            {
                                if (_logger.IsEnabled(LogLevel.Information))
                                {
                                    _logger.LogInformation("Applying migration for {0} from version {1}.", feature, current);
                                }
                                current = (int)lookupTable[current].Invoke(migration, new object[0]);
                            }
                            catch (Exception ex)
                            {
                                if (ex.IsFatal())
                                {
                                    throw;
                                }
                                _logger.LogError(0, "An unexpected error occurred while applying migration on {0} from version {1}.", feature, current);
                                throw;
                            }
                        }

                        // if current is 0, it means no upgrade/create method was found or succeeded
                        if (current == 0)
                        {
                            return;
                        }

                        dataMigrationRecord.Version = current;
                    }
                    catch (Exception ex)
                    {
                        if (ex.IsFatal())
                        {
                            throw;
                        }
                        _logger.LogError(0, "Error while running migration version {0} for {1}.", current, feature);
                        _session.Cancel();
                        throw new OrchardException(T("Error while running migration version {0} for {1}.", current, feature), ex);
                    }
                    finally
                    {
                        // Persist data migrations
                        _session.Save(_dataMigrationRecord);
                    }
                });
            }
        }