Пример #1
0
        public void UniquifyName_should_return_unique_name_when_conflict()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            var @namespace = "Migrations";

            var generatedMigration1
                = codeGenerator.Generate(
                      "201108162311111_Migration",
                      new MigrationOperation[] { },
                      "Source",
                      "Target",
                      @namespace,
                      "Migration");

            var generatedMigration2
                = codeGenerator.Generate(
                      "201108162311111_Migration1",
                      new MigrationOperation[] { },
                      "Source",
                      "Target",
                      @namespace,
                      "Migration1");

            var migrationAssembly
                = new MigrationAssembly(
                      new MigrationCompiler("cs")
                      .Compile(
                          @namespace,
                          generatedMigration1,
                          generatedMigration2),
                      @namespace);

            Assert.Equal("Migration2", migrationAssembly.UniquifyName("Migration"));
        }
        public void UniquifyName_should_return_unique_name_when_conflict()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            var @namespace = "Migrations";

            var generatedMigration1
                = codeGenerator.Generate(
                    "201108162311111_Migration",
                    new MigrationOperation[] { },
                    "Source",
                    "Target",
                    @namespace,
                    "Migration");

            var generatedMigration2
                = codeGenerator.Generate(
                    "201108162311111_Migration1",
                    new MigrationOperation[] { },
                    "Source",
                    "Target",
                    @namespace,
                    "Migration1");

            var migrationAssembly
                = new MigrationAssembly(
                    new MigrationCompiler("cs")
                        .Compile(
                            @namespace,
                            generatedMigration1,
                            generatedMigration2),
                    @namespace);

            Assert.Equal("Migration2", migrationAssembly.UniquifyName("Migration"));
        }
Пример #3
0
        public void MigrationIds_should_not_return_migration_when_not_subclass_of_db_migration()
        {
            var mockType     = new MockType("20110816231110_Migration", @namespace: "Migrations");
            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #4
0
        public void MigrationIds_should_not_return_migration_when_name_does_not_match_pattern()
        {
            var mockType     = new MockType("Z0110816231110_Migration", @namespace: "Migrations");
            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #5
0
        public void MigrationIds_should_not_return_migration_when_no_default_ctor()
        {
            var mockType     = new MockType("20110816231110_Migration", hasDefaultCtor: false, @namespace: "Migrations");
            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #6
0
        public void MigrationIds_should_not_return_migration_when_abstract()
        {
            var mockType
                = new MockType("20110816231110_Migration", @namespace: "Migrations")
                  .TypeAttributes(TypeAttributes.Abstract);

            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #7
0
        public void MigrationIds_should_not_return_migration_when_nested()
        {
            var mockType = new MockType("20110816231110_Migration", @namespace: "Migrations");

            mockType.SetupGet(t => t.DeclaringType).Returns(typeof(object));

            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #8
0
        public void MigrationIds_should_not_return_migration_when_generic()
        {
            var mockType = new MockType("20110816231110_Migration", @namespace: "Migrations");

            mockType.SetupGet(t => t.IsGenericType).Returns(true);

            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #9
0
 // <summary>
 // For testing.
 // </summary>
 internal DbMigrator(
     DbContext usersContext = null,
     DbProviderFactory providerFactory = null,
     MigrationAssembly migrationAssembly = null)
     : base(null)
 {
     _usersContext = usersContext;
     _providerFactory = providerFactory;
     _migrationAssembly = migrationAssembly;
     _usersContextInfo = new DbContextInfo(typeof(DbContext));
     _configuration = new DbMigrationsConfiguration();
     _calledByCreateDatabase = true;
 }
Пример #10
0
        public void MigrationIds_should_order_migrations()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            var @namespace = "Migrations";

            var generatedMigration1
                = codeGenerator.Generate(
                      "201108162311111_Migration1",
                      new MigrationOperation[] { },
                      "Source",
                      "Target",
                      @namespace,
                      "Migration1");

            var generatedMigration2
                = codeGenerator.Generate(
                      "201108162311111_Migration2",
                      new MigrationOperation[] { },
                      "Source",
                      "Target",
                      @namespace,
                      "Migration2");

            var generatedMigration3
                = codeGenerator.Generate(
                      "201108162311111_Migration3",
                      new MigrationOperation[] { },
                      "Source",
                      "Target",
                      @namespace,
                      "Migration3");

            var migrationAssembly
                = new MigrationAssembly(
                      new MigrationCompiler("cs")
                      .Compile(
                          @namespace,
                          generatedMigration1,
                          generatedMigration2,
                          generatedMigration3),
                      @namespace);

            Assert.Equal(3, migrationAssembly.MigrationIds.Count());
            Assert.Equal("201108162311111_Migration1", migrationAssembly.MigrationIds.First());
            Assert.Equal("201108162311111_Migration3", migrationAssembly.MigrationIds.Last());
        }
Пример #11
0
        public void GetMigration_should_perform_pr()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            const string @namespace = "Migrations";

            var generatedMigration
                = codeGenerator.Generate(
                    "201108162311111_Migration",
                    new MigrationOperation[] { },
                    "Source",
                    "Target",
                    @namespace,
                    "Migration");

            var migrationAssembly = new MigrationAssembly(
                new MigrationCompiler("cs").Compile(@namespace, generatedMigration),
                @namespace);

            Assert.NotNull(migrationAssembly.GetMigration("201108162311111_M"));
        }
Пример #12
0
        public void MigrationIds_should_return_id_when_migration_is_valid()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            var @namespace = "Migrations";

            var generatedMigration
                = codeGenerator.Generate(
                      "201108162311111_Migration",
                      new MigrationOperation[] { },
                      "Source",
                      "Target",
                      @namespace,
                      "Migration");

            var migrationAssembly = new MigrationAssembly(
                new MigrationCompiler("cs").Compile(@namespace, generatedMigration),
                @namespace);

            Assert.Equal(1, migrationAssembly.MigrationIds.Count());
        }
Пример #13
0
        public void MigrationIds_should_not_return_migration_in_wrong_namespace()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            var @namespace = "CorrectNamespace";

            var generatedMigration
                = codeGenerator.Generate(
                      "201108162311111_Migration",
                      new MigrationOperation[] { },
                      "Source",
                      "Target",
                      @namespace,
                      "Migration");

            var migrationAssembly = new MigrationAssembly(
                new MigrationCompiler("cs").Compile(@namespace, generatedMigration),
                "WrongNamespace");

            Assert.Equal(0, migrationAssembly.MigrationIds.Count());
        }
        public void GetMigration_should_perform_pr()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            const string @namespace = "Migrations";

            var generatedMigration
                = codeGenerator.Generate(
                      "201108162311111_Migration",
                      new MigrationOperation[] { },
                      "Source",
                      "Target",
                      @namespace,
                      "Migration");

            var migrationAssembly = new MigrationAssembly(
                new MigrationCompiler("cs").Compile(@namespace, generatedMigration),
                @namespace);

            Assert.NotNull(migrationAssembly.GetMigration("201108162311111_M"));
        }
        public void MigrationIds_should_return_id_when_migration_is_valid()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            var @namespace = "Migrations";

            var generatedMigration
                = codeGenerator.Generate(
                    "201108162311111_Migration",
                    new MigrationOperation[] { },
                    "Source",
                    "Target",
                    @namespace,
                    "Migration");

            var migrationAssembly = new MigrationAssembly(
                new MigrationCompiler("cs").Compile(@namespace, generatedMigration),
                @namespace);

            Assert.Equal(1, migrationAssembly.MigrationIds.Count());
        }
Пример #16
0
        public void CreateMigrationId_should_returned_timestamped_name()
        {
            var migrationId = MigrationAssembly.CreateMigrationId("Foo");

            Assert.True(new Regex(@"^\d{15}_[\w ]+$").IsMatch(migrationId));
        }
Пример #17
0
        public void MigrationIds_should_be_empty_when_no_migrations_exist()
        {
            var migrationAssembly = new MigrationAssembly(new MockAssembly(), "MockNamespace");

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #18
0
        internal DbMigrator(DbMigrationsConfiguration configuration, DbContext usersContext)
            : base(null)
        {
            Check.NotNull(configuration, "configuration");
            Check.NotNull(configuration.ContextType, "configuration.ContextType");

            _configuration = configuration;
            _calledByCreateDatabase = usersContext != null;

            // If DbContext CreateDatabase is using Migrations then the user has not opted out of initializers
            // and if we disable the initializer here then future calls to Initialize the database (for this or
            // a different connection) will fail. So only disable the initializer if Migrations are being used
            // explicitly.
            if (usersContext == null)
            {
                DisableInitializer(_configuration.ContextType);
            }

            if (_calledByCreateDatabase)
            {
                _usersContextInfo = new DbContextInfo(usersContext);
            }
            else
            {
                _usersContextInfo
                    = configuration.TargetDatabase == null
                          ? new DbContextInfo(configuration.ContextType)
                          : new DbContextInfo(configuration.ContextType, configuration.TargetDatabase);

                if (!_usersContextInfo.IsConstructible)
                {
                    throw Error.ContextNotConstructible(configuration.ContextType);
                }
            }

            _modelDiffer = _configuration.ModelDiffer;

            var context = usersContext ?? _usersContextInfo.CreateInstance();
            _contextForInterception = context;

            try
            {
                _migrationAssembly
                    = new MigrationAssembly(
                        _configuration.MigrationsAssembly,
                        _configuration.MigrationsNamespace);

                _currentModel = context.GetModel();

                var connection = context.Database.Connection;

                _providerFactory = DbProviderServices.GetProviderFactory(connection);

                _defaultSchema
                    = context.InternalContext.DefaultSchema
                      ?? EdmModelExtensions.DefaultSchema;

                _historyRepository
                    = new HistoryRepository(
                        _usersContextInfo.ConnectionString,
                        _providerFactory,
                        _configuration.ContextKey,
                        _configuration.CommandTimeout,
                        new[] { _defaultSchema }.Concat(GetHistorySchemas()),
                        _configuration.HistoryContextFactory);

                _providerManifestToken
                    = context.InternalContext.ModelProviderInfo != null
                          ? context.InternalContext.ModelProviderInfo.ProviderManifestToken
                          : DbConfiguration
                                .GetService<IManifestTokenService>()
                                .GetProviderManifestToken(connection);

                _modificationCommandTreeGenerator
                    = new ModificationCommandTreeGenerator(
                        context.GetDynamicUpdateModel(
                            new DbProviderInfo(
                                _usersContextInfo.ConnectionProviderName,
                                _providerManifestToken)),
                        CreateConnection());

                _targetDatabase
                    = Strings.LoggingTargetDatabaseFormat(
                        connection.DataSource,
                        connection.Database,
                        _usersContextInfo.ConnectionProviderName,
                        _usersContextInfo.ConnectionStringOrigin == DbConnectionStringOrigin.DbContextInfo
                            ? Strings.LoggingExplicit
                            : _usersContextInfo.ConnectionStringOrigin.ToString());

                _legacyContextKey = context.InternalContext.ContextKey;
                _emptyModel = GetEmptyModel();
            }
            finally
            {
                if (usersContext == null)
                {
                    _contextForInterception = null;
                    context.Dispose();
                }
            }
        }
        public void UniquifyName_should_return_name_when_already_unique()
        {
            var migrationAssembly = new MigrationAssembly(new MockAssembly(), "MockNamespace");

            Assert.Equal("Foo", migrationAssembly.UniquifyName("Foo"));
        }
        public void MigrationIds_should_not_return_migration_in_wrong_namespace()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            var @namespace = "CorrectNamespace";

            var generatedMigration
                = codeGenerator.Generate(
                    "201108162311111_Migration",
                    new MigrationOperation[] { },
                    "Source",
                    "Target",
                    @namespace,
                    "Migration");

            var migrationAssembly = new MigrationAssembly(
                new MigrationCompiler("cs").Compile(@namespace, generatedMigration),
                "WrongNamespace");

            Assert.Equal(0, migrationAssembly.MigrationIds.Count());
        }
        public void MigrationIds_should_not_return_migration_when_not_subclass_of_db_migration()
        {
            var mockType = new MockType("20110816231110_Migration", @namespace: "Migrations");
            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
        public void MigrationIds_should_not_return_migration_when_name_does_not_match_pattern()
        {
            var mockType = new MockType("Z0110816231110_Migration", @namespace: "Migrations");
            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
        public void MigrationIds_should_not_return_migration_when_no_default_ctor()
        {
            var mockType = new MockType("20110816231110_Migration", hasDefaultCtor: false, @namespace: "Migrations");
            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
        public void MigrationIds_should_not_return_migration_when_abstract()
        {
            var mockType
                = new MockType("20110816231110_Migration", @namespace: "Migrations")
                    .TypeAttributes(TypeAttributes.Abstract);

            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #25
0
        internal DbMigrator(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, bool calledByCreateDatabase)
            : base(null)
        {
            Check.NotNull(configuration, "configuration");
            Check.NotNull(configuration.ContextType, "configuration.ContextType");

            _configuration = configuration;
            _calledByCreateDatabase = calledByCreateDatabase;
            _existenceState = existenceState;

            if (usersContext != null)
            {
                _usersContextInfo = new DbContextInfo(usersContext);
            }
            else
            {
                _usersContextInfo
                    = configuration.TargetDatabase == null
                        ? new DbContextInfo(configuration.ContextType)
                        : new DbContextInfo(configuration.ContextType, configuration.TargetDatabase);

                if (!_usersContextInfo.IsConstructible)
                {
                    throw Error.ContextNotConstructible(configuration.ContextType);
                }
            }

            _modelDiffer = _configuration.ModelDiffer;

            var context = usersContext ?? _usersContextInfo.CreateInstance();
            _usersContext = context;

            try
            {
                _migrationAssembly
                    = new MigrationAssembly(
                        _configuration.MigrationsAssembly,
                        _configuration.MigrationsNamespace);

                _currentModel = context.GetModel();

                _connection = context.Database.Connection;

                _providerFactory = DbProviderServices.GetProviderFactory(_connection);

                _defaultSchema
                    = context.InternalContext.DefaultSchema
                      ?? EdmModelExtensions.DefaultSchema;

                _historyContextFactory
                    = _configuration
                        .GetHistoryContextFactory(_usersContextInfo.ConnectionProviderName);

                _historyRepository
                    = new HistoryRepository(
                        context.InternalContext,
                        _usersContextInfo.ConnectionString,
                        _providerFactory,
                        _configuration.ContextKey,
                        _configuration.CommandTimeout,
                        _historyContextFactory,
                        schemas: new[] { _defaultSchema }.Concat(GetHistorySchemas()),
                        contextForInterception: _usersContext,
                        initialExistence: _existenceState);

                _providerManifestToken
                    = context.InternalContext.ModelProviderInfo != null
                        ? context.InternalContext.ModelProviderInfo.ProviderManifestToken
                        : DbConfiguration
                            .DependencyResolver
                            .GetService<IManifestTokenResolver>()
                            .ResolveManifestToken(_connection);

                var modelBuilder
                    = context.InternalContext.CodeFirstModel.CachedModelBuilder;

                _modificationCommandTreeGenerator
                    = new Lazy<ModificationCommandTreeGenerator>(
                        () =>
                            new ModificationCommandTreeGenerator(
                                modelBuilder.BuildDynamicUpdateModel(
                                    new DbProviderInfo(
                                        _usersContextInfo.ConnectionProviderName,
                                        _providerManifestToken)),
                                CreateConnection()));

                var interceptionContext = new DbInterceptionContext();
                interceptionContext = interceptionContext.WithDbContext(_usersContext);

                _targetDatabase
                    = Strings.LoggingTargetDatabaseFormat(
                        DbInterception.Dispatch.Connection.GetDataSource(_connection, interceptionContext),
                        DbInterception.Dispatch.Connection.GetDatabase(_connection, interceptionContext),
                        _usersContextInfo.ConnectionProviderName,
                        _usersContextInfo.ConnectionStringOrigin == DbConnectionStringOrigin.DbContextInfo
                            ? Strings.LoggingExplicit
                            : _usersContextInfo.ConnectionStringOrigin.ToString());

                _legacyContextKey = context.InternalContext.DefaultContextKey;
                _emptyModel = GetEmptyModel();
            }
            finally
            {
                if (usersContext == null)
                {
                    _usersContext = null;
                    context.Dispose();
                }
            }
        }
        public void MigrationIds_should_not_return_migration_when_nested()
        {
            var mockType = new MockType("20110816231110_Migration", @namespace: "Migrations");
            mockType.SetupGet(t => t.DeclaringType).Returns(typeof(object));

            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
        public void MigrationIds_should_be_empty_when_no_migrations_exist()
        {
            var migrationAssembly = new MigrationAssembly(new MockAssembly(), "MockNamespace");

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
        public void MigrationIds_should_not_return_migration_when_generic()
        {
            var mockType = new MockType("20110816231110_Migration", @namespace: "Migrations");
            mockType.SetupGet(t => t.IsGenericType).Returns(true);

            var mockAssembly = new MockAssembly(mockType);

            var migrationAssembly = new MigrationAssembly(mockAssembly, mockType.Object.Namespace);

            Assert.False(migrationAssembly.MigrationIds.Any());
        }
Пример #29
0
        internal DbMigrator(DbMigrationsConfiguration configuration, DbContext usersContext)
            : base(null)
        {
            Contract.Requires(configuration != null);
            Contract.Requires(configuration.ContextType != null);

            _configuration = configuration;
            _calledByCreateDatabase = usersContext != null;

            // If DbContext CreateDatabase is using Migrations then the user has not opted out of initializers
            // and if we disable the initializer here then future calls to Initialize the database (for this or
            // a different connection) will fail. So only disable the initializer if Migrations are being used
            // explicitly.
            if (usersContext == null)
            {
                DisableInitializer(_configuration.ContextType);
            }

            if (_calledByCreateDatabase)
            {
                _usersContextInfo = new DbContextInfo(usersContext);
            }
            else
            {
                _usersContextInfo
                    = configuration.TargetDatabase == null
                          ? new DbContextInfo(configuration.ContextType)
                          : new DbContextInfo(configuration.ContextType, configuration.TargetDatabase);

                if (!_usersContextInfo.IsConstructible)
                {
                    throw Error.ContextNotConstructible(configuration.ContextType);
                }
            }

            _modelDiffer = _configuration.ModelDiffer;

            var context = usersContext ?? _usersContextInfo.CreateInstance();
            try
            {
                _migrationAssembly
                    = new MigrationAssembly(_configuration.MigrationsAssembly, _configuration.MigrationsNamespace);

                _currentModel = context.GetModel();

                var connection = context.Database.Connection;

                _providerFactory = DbProviderServices.GetProviderFactory(connection);

                _defaultSchema = context.InternalContext.DefaultSchema;

                var historySchemas = GetHistorySchemas();

                if (!string.IsNullOrWhiteSpace(_defaultSchema))
                {
                    historySchemas = historySchemas.Concat(new[] { _defaultSchema });
                }

                _historyRepository
                    = new HistoryRepository(_usersContextInfo.ConnectionString, _providerFactory, historySchemas);

                _providerManifestToken
                    = context.InternalContext.ModelProviderInfo != null
                          ? context.InternalContext.ModelProviderInfo.ProviderManifestToken
                          : DbProviderServices.GetProviderServices(connection).
                                GetProviderManifestTokenChecked(connection);
                _targetDatabase
                    = Strings.LoggingTargetDatabaseFormat(
                        connection.DataSource,
                        connection.Database,
                        _usersContextInfo.ConnectionProviderName,
                        _usersContextInfo.ConnectionStringOrigin == DbConnectionStringOrigin.DbContextInfo
                            ? Strings.LoggingExplicit
                            : _usersContextInfo.ConnectionStringOrigin.ToString());
            }
            finally
            {
                if (usersContext == null)
                {
                    context.Dispose();
                }
            }

            var providerInfo
                = new DbProviderInfo(_usersContextInfo.ConnectionProviderName, _providerManifestToken);

            _emptyModel = new Lazy<XDocument>(() => new DbModelBuilder().Build(providerInfo).GetModel());

            _historyRepository.AppendHistoryModel(_currentModel, providerInfo);
        }
        public void MigrationIds_should_order_migrations()
        {
            var codeGenerator = new CSharpMigrationCodeGenerator();

            var @namespace = "Migrations";

            var generatedMigration1
                = codeGenerator.Generate(
                    "201108162311111_Migration1",
                    new MigrationOperation[] { },
                    "Source",
                    "Target",
                    @namespace,
                    "Migration1");

            var generatedMigration2
                = codeGenerator.Generate(
                    "201108162311111_Migration2",
                    new MigrationOperation[] { },
                    "Source",
                    "Target",
                    @namespace,
                    "Migration2");

            var generatedMigration3
                = codeGenerator.Generate(
                    "201108162311111_Migration3",
                    new MigrationOperation[] { },
                    "Source",
                    "Target",
                    @namespace,
                    "Migration3");

            var migrationAssembly
                = new MigrationAssembly(
                    new MigrationCompiler("cs")
                        .Compile(
                            @namespace,
                            generatedMigration1,
                            generatedMigration2,
                            generatedMigration3),
                    @namespace);

            Assert.Equal(3, migrationAssembly.MigrationIds.Count());
            Assert.Equal("201108162311111_Migration1", migrationAssembly.MigrationIds.First());
            Assert.Equal("201108162311111_Migration3", migrationAssembly.MigrationIds.Last());
        }
Пример #31
0
        public void UniquifyName_should_return_name_when_already_unique()
        {
            var migrationAssembly = new MigrationAssembly(new MockAssembly(), "MockNamespace");

            Assert.Equal("Foo", migrationAssembly.UniquifyName("Foo"));
        }
Пример #32
0
        internal DbMigrator(DbMigrationsConfiguration configuration, DbContext usersContext)
            : base(null)
        {
            Check.NotNull(configuration, "configuration");
            Check.NotNull(configuration.ContextType, "configuration.ContextType");

            _configuration = configuration;
            _calledByCreateDatabase = usersContext != null;

            // If DbContext CreateDatabase is using Migrations then the user has not opted out of initializers
            // and if we disable the initializer here then future calls to Initialize the database (for this or
            // a different connection) will fail. So only disable the initializer if Migrations are being used
            // explicitly.
            if (usersContext == null)
            {
                DisableInitializer(_configuration.ContextType);
            }

            if (_calledByCreateDatabase)
            {
                _usersContextInfo = new DbContextInfo(usersContext);
            }
            else
            {
                _usersContextInfo
                    = configuration.TargetDatabase == null
                          ? new DbContextInfo(configuration.ContextType)
                          : new DbContextInfo(configuration.ContextType, configuration.TargetDatabase);

                if (!_usersContextInfo.IsConstructible)
                {
                    throw Error.ContextNotConstructible(configuration.ContextType);
                }
            }

            _modelDiffer = _configuration.ModelDiffer;

            var context = usersContext ?? _usersContextInfo.CreateInstance();
            try
            {
                _migrationAssembly
                    = new MigrationAssembly(_configuration.MigrationsAssembly, _configuration.MigrationsNamespace);

                _currentModel = context.GetModel();

                var connection = context.Database.Connection;

                _providerFactory = DbProviderServices.GetProviderFactory(connection);

                var defaultSchema = context.InternalContext.DefaultSchema;
                var historySchemas = GetHistorySchemas();

                if (!string.IsNullOrWhiteSpace(defaultSchema))
                {
                    historySchemas
                        = historySchemas.Concat(new[] { defaultSchema });
                }

                _historyRepository
                    = new HistoryRepository(
                        _usersContextInfo.ConnectionString,
                        _providerFactory,
                        _configuration.ContextKey,
                        historySchemas,
                        _migrationAssembly.MigrationIds.Any()
                            ? _configuration.HistoryContextFactory
                            : null);

                _providerManifestToken
                    = context.InternalContext.ModelProviderInfo != null
                          ? context.InternalContext.ModelProviderInfo.ProviderManifestToken
                          : DbConfiguration
                                .GetService<IManifestTokenService>()
                                .GetProviderManifestToken(connection);

                _targetDatabase
                    = Strings.LoggingTargetDatabaseFormat(
                        connection.DataSource,
                        connection.Database,
                        _usersContextInfo.ConnectionProviderName,
                        _usersContextInfo.ConnectionStringOrigin == DbConnectionStringOrigin.DbContextInfo
                            ? Strings.LoggingExplicit
                            : _usersContextInfo.ConnectionStringOrigin.ToString());

                _legacyContextKey = context.InternalContext.ContextKey;

                _currentHistoryModel = GetCurrentHistoryModel(defaultSchema);
                _initialHistoryModel = GetInitialHistoryModel();
                _emptyModel = GetEmptyModel();

                AttachHistoryModel(_currentModel);
            }
            finally
            {
                if (usersContext == null)
                {
                    context.Dispose();
                }
            }
        }