Exemple #1
0
        internal virtual void AutoMigrate(
            string migrationId, VersionedModel sourceModel, VersionedModel targetModel, bool downgrading)
        {
            DebugCheck.NotNull(targetModel);

            _this.AutoMigrate(migrationId, sourceModel, targetModel, downgrading);
        }
Exemple #2
0
 internal virtual void AutoMigrate(
     string migrationId,
     VersionedModel sourceModel,
     VersionedModel targetModel,
     bool downgrading)
 {
     this._this.AutoMigrate(migrationId, sourceModel, targetModel, downgrading);
 }
Exemple #3
0
 internal override void AutoMigrate(
     string migrationId,
     VersionedModel sourceModel,
     VersionedModel targetModel,
     bool downgrading)
 {
     this._logger.Info(downgrading ? Strings.LoggingRevertAutoMigrate((object)migrationId) : Strings.LoggingAutoMigrate((object)migrationId));
     base.AutoMigrate(migrationId, sourceModel, targetModel, downgrading);
 }
        internal override void AutoMigrate(
            string migrationId, VersionedModel sourceModel, VersionedModel targetModel, bool downgrading)
        {
            DebugCheck.NotEmpty(migrationId);

            _logger.Info(
                downgrading
                    ? Strings.LoggingRevertAutoMigrate(migrationId)
                    : Strings.LoggingAutoMigrate(migrationId));

            base.AutoMigrate(migrationId, sourceModel, targetModel, downgrading);
        }
        internal override void AutoMigrate(
            string migrationId, VersionedModel sourceModel, VersionedModel targetModel, bool downgrading)
        {
            DebugCheck.NotEmpty(migrationId);

            _logger.Info(
                downgrading
                    ? Strings.LoggingRevertAutoMigrate(migrationId)
                    : Strings.LoggingAutoMigrate(migrationId));

            base.AutoMigrate(migrationId, sourceModel, targetModel, downgrading);
        }
        public virtual MigrationOperation CreateInsertOperation(string migrationId, VersionedModel versionedModel)
        {
            DebugCheck.NotEmpty(migrationId);
            DebugCheck.NotNull(versionedModel);

            DbConnection connection = null;
            try
            {
                connection = CreateConnection();

                using (var context = CreateContext(connection))
                {
                    context.History.Add(
                        new HistoryRow
                            {
                                MigrationId = migrationId.RestrictTo(_migrationIdMaxLength),
                                ContextKey = _contextKey,
                                Model = new ModelCompressor().Compress(versionedModel.Model),
                                ProductVersion = versionedModel.Version ?? _productVersion
                            });

                    using (var commandTracer = new CommandTracer(context))
                    {
                        context.SaveChanges();

                        return new HistoryOperation(
                            commandTracer.CommandTrees.OfType<DbModificationCommandTree>().ToList());
                    }
                }
            }
            finally
            {
                DisposeConnection(connection);
            }
        }
        public void HasMigrations_should_return_true_when_table_has_migrations_for_key()
        {
            ResetDatabase();

            var historyRepository
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey", null, HistoryContext.DefaultFactory);

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    new[]
                        {
                            GetCreateHistoryTableOperation(),
                            historyRepository.CreateInsertOperation("Migration1", model)
                        });
            }

            Assert.True(historyRepository.HasMigrations());
        }
        internal virtual void AutoMigrate(
            string migrationId, VersionedModel sourceModel, VersionedModel targetModel, bool downgrading)
        {
            DebugCheck.NotNull(targetModel);

            _this.AutoMigrate(migrationId, sourceModel, targetModel, downgrading);
        }
        private HistoryRepository SetupHistoryRepositoryForOrderingTest()
        {
            ResetDatabase();

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                var clonedConnection = DbProviderServices.GetProviderFactory(context.Database.Connection).CreateConnection();
                clonedConnection.ConnectionString = context.Database.Connection.ConnectionString;

                using (var historyContext = new HistoryContext(clonedConnection, defaultSchema: null))
                {
                    context.InternalContext.MarkDatabaseInitialized();

                    context.Database.ExecuteSqlCommand(
                        ((IObjectContextAdapter)historyContext).ObjectContext.CreateDatabaseScript());

                    historyContext.History.Add(
                        new HistoryRow
                            {
                                MigrationId = "227309030010001_Migration1",
                                ContextKey = "MyKey",
                                Model = new ModelCompressor().Compress(model.Model),
                                ProductVersion = "",
                            });

                    historyContext.History.Add(
                        new HistoryRow
                            {
                                MigrationId = "227209030010001_Migration2",
                                ContextKey = "MyKey",
                                Model = new ModelCompressor().Compress(model.Model),
                                ProductVersion = "",
                            });

                    historyContext.SaveChanges();
                }
            }

            return new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey", null, HistoryContext.DefaultFactory);
        }
        public void GetModel_should_return_model_based_on_context_key()
        {
            ResetDatabase();

            var historyRepository1
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "Key1", null, HistoryContext.DefaultFactory);

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = context.GetModel();
                var versionedModel = new VersionedModel(model);

                ExecuteOperations(
                    GetCreateHistoryTableOperation(),
                    historyRepository1.CreateInsertOperation("Migration 1", versionedModel));

                var historyRepository2
                    = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "Key2", null, HistoryContext.DefaultFactory);

                ExecuteOperations(
                    new[] { historyRepository2.CreateInsertOperation("Migration 2", versionedModel) });

                string productVersion;
                model = historyRepository1.GetModel("Migration 1", out productVersion);

                Assert.NotNull(model);
                Assert.Equal(typeof(DbContext).Assembly().GetInformationalVersion(), productVersion);

                string _;
                model = historyRepository2.GetModel("Migration 2", out _);

                Assert.NotNull(model);
            }
        }
        public void GetMigrationId_should_match_by_context_key()
        {
            ResetDatabase();

            var historyRepository1
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey1", null, HistoryContext.DefaultFactory);

            var historyRepository2
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey2", null, HistoryContext.DefaultFactory);

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    new[]
                        {
                            GetCreateHistoryTableOperation(),
                            historyRepository1.CreateInsertOperation("201109192032331_Migration1", model),
                            historyRepository1.CreateInsertOperation("201109192032332_Migration2", model),
                            historyRepository2.CreateInsertOperation("201109192032331_Migration1", model),
                            historyRepository2.CreateInsertOperation("201109192032332_Migration2", model)
                        });
            }

            var migrationId = historyRepository1.GetMigrationId("Migration1");

            Assert.Equal("201109192032331_Migration1", migrationId);

            migrationId = historyRepository1.GetMigrationId("migrATIon2");

            Assert.Equal("201109192032332_Migration2", migrationId);
        }
        internal override void AutoMigrate(
            string migrationId, VersionedModel sourceModel, VersionedModel targetModel, bool downgrading)
        {
            var systemOperations = Enumerable.Empty<MigrationOperation>();

            if (!_historyRepository.IsShared())
            {
                if (ReferenceEquals(targetModel.Model, _emptyModel.Value))
                {
                    systemOperations
                        = _modelDiffer.Diff(GetHistoryModel(EdmModelExtensions.DefaultSchema), _emptyModel.Value);
                }
                else if (ReferenceEquals(sourceModel.Model, _emptyModel.Value))
                {
                    systemOperations
                        = _modelDiffer.Diff(
                            _emptyModel.Value,
                            _calledByCreateDatabase
                                ? GetHistoryModel(_defaultSchema)
                                : GetHistoryModel(EdmModelExtensions.DefaultSchema));
                }
            }

            var operations
                = _modelDiffer
                    .Diff(
                        sourceModel.Model,
                        targetModel.Model,
                        targetModel.Model == _currentModel
                            ? _modificationCommandTreeGenerator
                            : null,
                        SqlGenerator,
                        sourceModel.Version,
                        targetModel.Version)
                    .ToList();

            if (!_calledByCreateDatabase
                && ReferenceEquals(targetModel.Model, _currentModel))
            {
                var lastDefaultSchema = GetLastDefaultSchema(migrationId);

                if (!string.Equals(lastDefaultSchema, _defaultSchema, StringComparison.Ordinal))
                {
                    throw Error.UnableToMoveHistoryTableWithAuto();
                }
            }

            if (!_configuration.AutomaticMigrationDataLossAllowed
                && operations.Any(o => o.IsDestructiveChange))
            {
                throw Error.AutomaticDataLoss();
            }

            if ((targetModel.Model != _currentModel)
                && (operations.Any(o => o is ProcedureOperation)))
            {
                throw Error.AutomaticStaleFunctions(migrationId);
            }

            ExecuteOperations(migrationId, targetModel, operations, systemOperations, downgrading, auto: true);
        }
        public void GetPendingMigrations_should_ignore_InitialCreate_timestamps()
        {
            ResetDatabase();

            var historyRepository = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey", null, HistoryContext.DefaultFactory);

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    GetCreateHistoryTableOperation(),
                    historyRepository.CreateInsertOperation("000000000000001_InitialCreate", model));
            }

            var pendingMigrations = historyRepository.GetPendingMigrations(
                new[] { "000000000000002_InitialCreate", "Migration 1" });

            Assert.Equal("Migration 1", pendingMigrations.Single());
        }
        public void GetPendingMigrations_should_return_migrations_based_on_context_key()
        {
            ResetDatabase();

            var historyRepository1 = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey1", null, HistoryContext.DefaultFactory);
            var historyRepository2 = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey2", null, HistoryContext.DefaultFactory);

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    GetCreateHistoryTableOperation(),
                    historyRepository1.CreateInsertOperation("Migration 1", model),
                    historyRepository2.CreateInsertOperation("Migration 1", model),
                    historyRepository1.CreateInsertOperation("Migration 3", model),
                    historyRepository1.CreateInsertOperation("Migration 5", model));
            }

            var pendingMigrations =
                historyRepository1.GetPendingMigrations(
                    new[] { "Migration 1", "Migration 2", "Migration 3", "Migration 4", "Migration 5" });

            Assert.Equal("Migration 2", pendingMigrations.First());
            Assert.Equal("Migration 4", pendingMigrations.Last());
        }
        public void GetMigrationsSince_should_return_empty_when_target_valid_but_is_latest()
        {
            ResetDatabase();

            var historyRepository
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey", null, HistoryContext.DefaultFactory);

            ExecuteOperations(GetCreateHistoryTableOperation());

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    new[]
                        {
                            historyRepository.CreateInsertOperation("Migration1", model),
                            historyRepository.CreateInsertOperation("Migration2", model)
                        });
            }

            var migrations = historyRepository.GetMigrationsSince("Migration2");

            Assert.Equal(0, migrations.Count());
        }
        public void GetMigrationsSince_should_return_subset_based_on_context_key()
        {
            ResetDatabase();

            var historyRepository1
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey1", null, HistoryContext.DefaultFactory);

            var historyRepository2
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey2", null, HistoryContext.DefaultFactory);

            ExecuteOperations(GetCreateHistoryTableOperation());

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    new[]
                        {
                            historyRepository1.CreateInsertOperation("Migration1", model),
                            historyRepository1.CreateInsertOperation("Migration2", model),
                            historyRepository2.CreateInsertOperation("Migration1", model),
                            historyRepository2.CreateInsertOperation("Migration2", model)
                        });
            }

            var migrations = historyRepository1.GetMigrationsSince("Migration1");

            Assert.Equal(1, migrations.Count());
            Assert.Equal("Migration2", migrations.Single());
        }
        public void GetMigrationId_should_throw_when_name_ambiguous()
        {
            ResetDatabase();

            var historyRepository
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey", null, HistoryContext.DefaultFactory);

            ExecuteOperations(GetCreateHistoryTableOperation());

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    new[]
                        {
                            historyRepository.CreateInsertOperation("201109192032331_Migration", model),
                            historyRepository.CreateInsertOperation("201109192032332_Migration", model)
                        });
            }

            Assert.Equal(
                Strings.AmbiguousMigrationName("Migration"),
                Assert.Throws<MigrationsException>(() => historyRepository.GetMigrationId("Migration")).Message);
        }
        public virtual void BootstrapUsingEFProviderDdl(VersionedModel versionedModel)
        {
            DebugCheck.NotNull(versionedModel);

            DbConnection connection = null;
            try
            {
                connection = CreateConnection();

                using (var context = CreateContext(connection))
                {
                    context.Database.ExecuteSqlCommand(
                        ((IObjectContextAdapter)context).ObjectContext.CreateDatabaseScript());

                    context.History.Add(
                        new HistoryRow
                            {
                                MigrationId = MigrationAssembly
                                    .CreateMigrationId(Strings.InitialCreate)
                                    .RestrictTo(_migrationIdMaxLength),
                                ContextKey = _contextKey,
                                Model = new ModelCompressor().Compress(versionedModel.Model),
                                ProductVersion = versionedModel.Version ?? _productVersion
                            });

                    context.SaveChanges();
                }
            }
            finally
            {
                DisposeConnection(connection);
            }
        }
        public void GetLastModel_should_return_model_when_row()
        {
            ResetDatabase();

            var historyRepository = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey", null, HistoryContext.DefaultFactory);

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model1 = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    GetCreateHistoryTableOperation(),
                    historyRepository.CreateInsertOperation("Migration 1", model1));

                ExecuteOperations(
                    new[] { historyRepository.CreateInsertOperation("Migration 2", model1) });

                string migrationId, productVersion;
                var model2 = historyRepository.GetLastModel(out migrationId, out productVersion);

                Assert.NotNull(model2);
                Assert.True(XNode.DeepEquals(model1.Model, model2));
                Assert.Equal("Migration 2", migrationId);
                Assert.Equal(typeof(DbContext).Assembly().GetInformationalVersion(), productVersion);
            }
        }
        public void HasMigrations_should_return_false_when_context_key_not_matching()
        {
            ResetDatabase();

            var historyRepository1
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey1", null, HistoryContext.DefaultFactory);

            var historyRepository2
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "MyKey2", null, HistoryContext.DefaultFactory);

            ExecuteOperations(GetCreateHistoryTableOperation());

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = new VersionedModel(context.GetModel());

                ExecuteOperations(
                    new[]
                        {
                            historyRepository2.CreateInsertOperation("Migration2", model)
                        });
            }

            Assert.False(historyRepository1.HasMigrations());
        }
        private void ExecuteOperations(
            string migrationId,
            VersionedModel targetModel,
            IEnumerable<MigrationOperation> operations,
            IEnumerable<MigrationOperation> systemOperations,
            bool downgrading,
            bool auto = false)
        {
            DebugCheck.NotEmpty(migrationId);
            DebugCheck.NotNull(targetModel);
            DebugCheck.NotNull(operations);
            DebugCheck.NotNull(systemOperations);

            FillInForeignKeyOperations(operations, targetModel.Model);

            var newTableForeignKeys
                = (from ct in operations.OfType<CreateTableOperation>()
                    from afk in operations.OfType<AddForeignKeyOperation>()
                    where ct.Name.EqualsIgnoreCase(afk.DependentTable)
                    select afk)
                    .ToList();

            var orderedOperations
                = operations
                    .Except(newTableForeignKeys)
                    .Concat(newTableForeignKeys)
                    .Concat(systemOperations)
                    .ToList();

            var createHistoryOperation
                = systemOperations
                    .OfType<CreateTableOperation>()
                    .FirstOrDefault();

            if (createHistoryOperation != null)
            {
                _historyRepository.CurrentSchema
                    = DatabaseName.Parse(createHistoryOperation.Name).Schema;
            }

            var moveHistoryOperation
                = systemOperations
                    .OfType<MoveTableOperation>()
                    .FirstOrDefault();

            if (moveHistoryOperation != null)
            {
                _historyRepository.CurrentSchema = moveHistoryOperation.NewSchema;

                moveHistoryOperation.ContextKey = _configuration.ContextKey;
                moveHistoryOperation.IsSystem = true;
            }

            if (!downgrading)
            {
                orderedOperations.Add(_historyRepository.CreateInsertOperation(migrationId, targetModel));
            }
            else if (!systemOperations.Any(o => o is DropTableOperation))
            {
                orderedOperations.Add(_historyRepository.CreateDeleteOperation(migrationId));
            }

            var migrationStatements
                = base.GenerateStatements(orderedOperations, migrationId);

            if (auto)
            {
                // Filter duplicates when auto-migrating. Duplicates can be caused by
                // duplicates in the model such as shared FKs.
                migrationStatements
                    = migrationStatements
                        .Distinct((m1, m2) => string.Equals(m1.Sql, m2.Sql, StringComparison.Ordinal));
            }

            base.ExecuteStatements(migrationStatements);

            _historyRepository.ResetExists();
        }
        public void GetLastModel_should_return_model_based_on_passed_context_key_when_custom_default_schema()
        {
            ResetDatabase();

            var historyRepository
                = new HistoryRepository(Mock.Of<InternalContextForMock>(), ConnectionString, ProviderFactory, "LegacyKey", null, HistoryContext.DefaultFactory)
                      {
                          CurrentSchema = "foo"
                      };

            using (var context = CreateContext<ShopContext_v1>())
            {
                var model = context.GetModel();
                var versionedModel = new VersionedModel(model);

                ExecuteOperations(
                    GetCreateHistoryTableOperation(historyRepository.CurrentSchema),
                    historyRepository.CreateInsertOperation("Migration", versionedModel));

                historyRepository
                    = new HistoryRepository(Mock.Of<InternalContextForMock>(), 
                        ConnectionString,
                        ProviderFactory,
                        "NewKey",
                        null,
                        HistoryContext.DefaultFactory,
                        schemas: new[] { "foo" });

                string migrationId, _;
                model = historyRepository.GetLastModel(out migrationId, out _, "LegacyKey");

                Assert.NotNull(model);
                Assert.Equal("Migration", migrationId);
            }
        }