Beispiel #1
0
        public async Task Executes_migration_commands_with_transaction_suppressed_outside_of_transaction(bool async)
        {
            var fakeConnection = CreateConnection();
            var logger         = new FakeRelationalCommandDiagnosticsLogger();

            var commandList = new List <MigrationCommand>
            {
                new(CreateRelationalCommand(), null, logger, transactionSuppressed : true),
                new(CreateRelationalCommand(), null, logger, transactionSuppressed : true)
            };

            var migrationCommandExecutor = new MigrationCommandExecutor();

            if (async)
            {
                await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection);
            }
            else
            {
                migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection);
            }

            Assert.Equal(1, fakeConnection.DbConnections.Count);
            Assert.Equal(1, fakeConnection.DbConnections[0].OpenCount);
            Assert.Equal(1, fakeConnection.DbConnections[0].CloseCount);

            Assert.Equal(0, fakeConnection.DbConnections[0].DbTransactions.Count);

            Assert.Equal(2, fakeConnection.DbConnections[0].DbCommands.Count);
            Assert.Null(fakeConnection.DbConnections[0].DbCommands[0].Transaction);
            Assert.Null(fakeConnection.DbConnections[0].DbCommands[1].Transaction);
        }
Beispiel #2
0
        public async Task Executes_commands_in_order_regardless_of_transaction_suppression(bool async)
        {
            var fakeConnection = CreateConnection();
            var logger         = new FakeRelationalCommandDiagnosticsLogger();

            var commandList = new List <MigrationCommand>
            {
                new(CreateRelationalCommand(commandText: "First"), null, logger),
                new(CreateRelationalCommand(commandText: "Second"), null, logger, transactionSuppressed : true),
                new(CreateRelationalCommand(commandText : "Third"), null, logger)
            };

            var migrationCommandExecutor = new MigrationCommandExecutor();

            if (async)
            {
                await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection);
            }
            else
            {
                migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection);
            }

            Assert.Equal(1, fakeConnection.DbConnections.Count);
            Assert.Equal(1, fakeConnection.DbConnections[0].OpenCount);
            Assert.Equal(1, fakeConnection.DbConnections[0].CloseCount);

            Assert.Equal(2, fakeConnection.DbConnections[0].DbTransactions.Count);
            Assert.Equal(1, fakeConnection.DbConnections[0].DbTransactions[0].CommitCount);
            Assert.Equal(0, fakeConnection.DbConnections[0].DbTransactions[0].RollbackCount);
            Assert.Equal(1, fakeConnection.DbConnections[0].DbTransactions[1].CommitCount);
            Assert.Equal(0, fakeConnection.DbConnections[0].DbTransactions[1].RollbackCount);

            Assert.Equal(3, fakeConnection.DbConnections[0].DbCommands.Count);

            var command = fakeConnection.DbConnections[0].DbCommands[0];

            Assert.Same(
                fakeConnection.DbConnections[0].DbTransactions[0],
                command.Transaction);
            Assert.Equal(
                "First",
                command.CommandText);

            command = fakeConnection.DbConnections[0].DbCommands[1];

            Assert.Null(command.Transaction);
            Assert.Equal(
                "Second",
                command.CommandText);

            command = fakeConnection.DbConnections[0].DbCommands[2];

            Assert.Same(
                fakeConnection.DbConnections[0].DbTransactions[1],
                command.Transaction);
            Assert.Equal(
                "Third",
                command.CommandText);
        }
    private MigrationCommandListBuilder CreateBuilder()
    {
        var typeMappingSource = new TestRelationalTypeMappingSource(
            TestServiceFactory.Instance.Create <TypeMappingSourceDependencies>(),
            TestServiceFactory.Instance.Create <RelationalTypeMappingSourceDependencies>());

        var logger           = new FakeRelationalCommandDiagnosticsLogger();
        var migrationsLogger = new FakeDiagnosticsLogger <DbLoggerCategory.Migrations>();
        var generationHelper = new RelationalSqlGenerationHelper(new RelationalSqlGenerationHelperDependencies());

        return(new MigrationCommandListBuilder(
                   new MigrationsSqlGeneratorDependencies(
                       new RelationalCommandBuilderFactory(
                           new RelationalCommandBuilderDependencies(
                               typeMappingSource,
                               new ExceptionDetector())),
                       new FakeSqlGenerator(
                           new UpdateSqlGeneratorDependencies(
                               generationHelper,
                               typeMappingSource)),
                       generationHelper,
                       typeMappingSource,
                       new CurrentDbContext(new FakeDbContext()),
                       new ModificationCommandFactory(),
                       new LoggingOptions(),
                       logger,
                       migrationsLogger)));
    }
    public void AddCommand_returns_false_when_max_batch_size_is_reached()
    {
        var typeMapper = new SqlServerTypeMappingSource(
            TestServiceFactory.Instance.Create <TypeMappingSourceDependencies>(),
            TestServiceFactory.Instance.Create <RelationalTypeMappingSourceDependencies>());

        var logger = new FakeRelationalCommandDiagnosticsLogger();

        var batch = new SqlServerModificationCommandBatch(
            new ModificationCommandBatchFactoryDependencies(
                new RelationalCommandBuilderFactory(
                    new RelationalCommandBuilderDependencies(
                        typeMapper)),
                new SqlServerSqlGenerationHelper(
                    new RelationalSqlGenerationHelperDependencies()),
                new SqlServerUpdateSqlGenerator(
                    new UpdateSqlGeneratorDependencies(
                        new SqlServerSqlGenerationHelper(
                            new RelationalSqlGenerationHelperDependencies()),
                        typeMapper)),
                new TypedRelationalValueBufferFactoryFactory(
                    new RelationalValueBufferFactoryDependencies(
                        typeMapper, new CoreSingletonOptions())),
                new CurrentDbContext(new FakeDbContext()),
                logger),
            1);

        Assert.True(
            batch.AddCommand(
                CreateModificationCommand("T1", null, false)));
        Assert.False(
            batch.AddCommand(
                CreateModificationCommand("T1", null, false)));
    }
            private static ModificationCommandBatchFactoryDependencies CreateDependencies(
                IUpdateSqlGenerator sqlGenerator)
            {
                var typeMappingSource = new TestRelationalTypeMappingSource(
                    TestServiceFactory.Instance.Create <TypeMappingSourceDependencies>(),
                    TestServiceFactory.Instance.Create <RelationalTypeMappingSourceDependencies>());

                var logger = new FakeRelationalCommandDiagnosticsLogger();

                return(new ModificationCommandBatchFactoryDependencies(
                           new RelationalCommandBuilderFactory(
                               new RelationalCommandBuilderDependencies(
                                   typeMappingSource)),
                           new RelationalSqlGenerationHelper(
                               new RelationalSqlGenerationHelperDependencies()),
                           sqlGenerator
                           ?? new FakeSqlGenerator(
                               RelationalTestHelpers.Instance.CreateContextServices()
                               .GetRequiredService <UpdateSqlGeneratorDependencies>()),
                           new TypedRelationalValueBufferFactoryFactory(
                               new RelationalValueBufferFactoryDependencies(
                                   typeMappingSource,
                                   new CoreSingletonOptions())),
                           new CurrentDbContext(new FakeDbContext()),
                           logger));
            }
        private async Task <IEnumerable <List <long> > > GenerateValuesInMultipleThreads(int threadCount, int valueCount)
        {
            const int blockSize = 10;

            var serviceProvider = SqlServerTestHelpers.Instance.CreateServiceProvider();

            var sequence = ((IMutableModel) new Model()).AddSequence("Foo");

            sequence.IncrementBy = blockSize;
            var state = new SqlServerSequenceValueGeneratorState((ISequence)sequence);

            var executor     = new FakeRawSqlCommandBuilder(blockSize);
            var sqlGenerator = new SqlServerUpdateSqlGenerator(
                new UpdateSqlGeneratorDependencies(
                    new SqlServerSqlGenerationHelper(
                        new RelationalSqlGenerationHelperDependencies()),
                    new SqlServerTypeMappingSource(
                        TestServiceFactory.Instance.Create <TypeMappingSourceDependencies>(),
                        TestServiceFactory.Instance.Create <RelationalTypeMappingSourceDependencies>())));

            var logger = new FakeRelationalCommandDiagnosticsLogger();

            var tests           = new Func <Task> [threadCount];
            var generatedValues = new List <long> [threadCount];

            for (var i = 0; i < tests.Length; i++)
            {
                var testNumber = i;
                generatedValues[testNumber] = new List <long>();
                tests[testNumber]           = async() =>
                {
                    for (var j = 0; j < valueCount; j++)
                    {
                        var connection = CreateConnection(serviceProvider);
                        var generator  = new SqlServerSequenceHiLoValueGenerator <long>(executor, sqlGenerator, state, connection, logger);

                        var value = j % 2 == 0
                            ? await generator.NextAsync(null)
                            : generator.Next(null);

                        generatedValues[testNumber].Add(value);
                    }
                };
            }

            var tasks = tests.Select(Task.Run).ToArray();

            foreach (var t in tasks)
            {
                await t;
            }

            return(generatedValues);
        }
    public async Task Executes_transaction_suppressed_migration_commands_in_user_transaction(bool async)
    {
        var fakeConnection = CreateConnection();
        var logger         = new FakeRelationalCommandDiagnosticsLogger();

        var commandList = new List <MigrationCommand>
        {
            new(CreateRelationalCommand(), null, logger), new(CreateRelationalCommand(), null, logger, transactionSuppressed : true)
        };

        var migrationCommandExecutor = new MigrationCommandExecutor();

        IDbContextTransaction tx;

        using (tx = fakeConnection.BeginTransaction())
        {
            if (async)
            {
                Assert.Equal(
                    RelationalStrings.TransactionSuppressedMigrationInUserTransaction,
                    (await Assert.ThrowsAsync <NotSupportedException>(
                         async()
                         => await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection))).Message);
            }
            else
            {
                Assert.Equal(
                    RelationalStrings.TransactionSuppressedMigrationInUserTransaction,
                    Assert.Throws <NotSupportedException>(
                        ()
                        => migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection)).Message);
            }

            tx.Rollback();
        }

        Assert.Equal(1, fakeConnection.DbConnections.Count);
        Assert.Equal(1, fakeConnection.DbConnections[0].OpenCount);
        Assert.Equal(1, fakeConnection.DbConnections[0].CloseCount);

        Assert.Equal(1, fakeConnection.DbConnections[0].DbTransactions.Count);
        Assert.Equal(0, fakeConnection.DbConnections[0].DbTransactions[0].CommitCount);
        Assert.Equal(1, fakeConnection.DbConnections[0].DbTransactions[0].RollbackCount);

        Assert.Equal(0, fakeConnection.DbConnections[0].DbCommands.Count);
        Assert.Same(
            tx.GetDbTransaction(),
            fakeConnection.DbConnections[0].DbTransactions[0]);
    }
Beispiel #8
0
        public async Task Executes_migration_commands_in_user_transaction(bool async)
        {
            var fakeConnection = CreateConnection();
            var logger         = new FakeRelationalCommandDiagnosticsLogger();

            var commandList = new List <MigrationCommand>
            {
                new(CreateRelationalCommand(), null, logger),
                new(CreateRelationalCommand(), null, logger)
            };

            var migrationCommandExecutor = new MigrationCommandExecutor();

            IDbContextTransaction tx;

            using (tx = fakeConnection.BeginTransaction())
            {
                if (async)
                {
                    await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection);
                }
                else
                {
                    migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection);
                }

                tx.Commit();
            }

            Assert.Equal(1, fakeConnection.DbConnections.Count);
            Assert.Equal(1, fakeConnection.DbConnections[0].OpenCount);
            Assert.Equal(1, fakeConnection.DbConnections[0].CloseCount);

            Assert.Equal(1, fakeConnection.DbConnections[0].DbTransactions.Count);
            Assert.Equal(1, fakeConnection.DbConnections[0].DbTransactions[0].CommitCount);
            Assert.Equal(0, fakeConnection.DbConnections[0].DbTransactions[0].RollbackCount);

            Assert.Equal(2, fakeConnection.DbConnections[0].DbCommands.Count);
            Assert.Same(
                fakeConnection.DbConnections[0].DbTransactions[0],
                fakeConnection.DbConnections[0].DbCommands[0].Transaction);
            Assert.Same(
                fakeConnection.DbConnections[0].DbTransactions[0],
                fakeConnection.DbConnections[0].DbCommands[1].Transaction);
            Assert.Same(
                tx.GetDbTransaction(),
                fakeConnection.DbConnections[0].DbTransactions[0]);
        }
Beispiel #9
0
        public async Task Disposes_transaction_on_exception(bool async)
        {
            var fakeDbConnection =
                new FakeDbConnection(
                    ConnectionString,
                    new FakeCommandExecutor(
                        executeNonQuery: c => throw new InvalidOperationException(),
                        executeNonQueryAsync: (c, ct) => throw new InvalidOperationException()));

            var fakeConnection =
                CreateConnection(
                    CreateOptions(
                        new FakeRelationalOptionsExtension().WithConnection(fakeDbConnection)));

            var logger = new FakeRelationalCommandDiagnosticsLogger();

            var commandList = new List <MigrationCommand> {
                new(CreateRelationalCommand(), null, logger)
            };

            var migrationCommandExecutor = new MigrationCommandExecutor();

            if (async)
            {
                await Assert.ThrowsAsync <InvalidOperationException>(
                    async()
                    => await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection));
            }
            else
            {
                Assert.Throws <InvalidOperationException>(
                    ()
                    => migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection));
            }

            Assert.Equal(1, fakeDbConnection.OpenCount);
            Assert.Equal(1, fakeDbConnection.CloseCount);

            Assert.Equal(1, fakeDbConnection.DbTransactions.Count);
            Assert.Equal(1, fakeDbConnection.DbTransactions[0].DisposeCount);
            Assert.Equal(0, fakeDbConnection.DbTransactions[0].CommitCount);
            Assert.Equal(0, fakeDbConnection.DbTransactions[0].RollbackCount);
        }
    public void MaxBatchSize_is_optional()
    {
        var optionsBuilder = new DbContextOptionsBuilder();

        optionsBuilder.UseNpgsql("Database=Crunchie");

        var typeMapper = new NpgsqlTypeMappingSource(
            TestServiceFactory.Instance.Create <TypeMappingSourceDependencies>(),
            TestServiceFactory.Instance.Create <RelationalTypeMappingSourceDependencies>(),
            new NpgsqlSqlGenerationHelper(new RelationalSqlGenerationHelperDependencies()),
            new NpgsqlOptions());

        var logger = new FakeRelationalCommandDiagnosticsLogger();

        var factory = new NpgsqlModificationCommandBatchFactory(
            new ModificationCommandBatchFactoryDependencies(
                new RelationalCommandBuilderFactory(
                    new RelationalCommandBuilderDependencies(
                        typeMapper,
                        new ExceptionDetector())),
                new NpgsqlSqlGenerationHelper(
                    new RelationalSqlGenerationHelperDependencies()),
                new NpgsqlUpdateSqlGenerator(
                    new UpdateSqlGeneratorDependencies(
                        new NpgsqlSqlGenerationHelper(
                            new RelationalSqlGenerationHelperDependencies()),
                        typeMapper)),
                new TypedRelationalValueBufferFactoryFactory(
                    new RelationalValueBufferFactoryDependencies(
                        typeMapper, new CoreSingletonOptions())),
                new CurrentDbContext(new FakeDbContext()),
                logger),
            optionsBuilder.Options);

        var batch = factory.Create();

        Assert.True(batch.AddCommand(CreateModificationCommand("T1", null, false)));
        Assert.True(batch.AddCommand(CreateModificationCommand("T1", null, false)));
    }
Beispiel #11
0
        public void Uses_MaxBatchSize_specified_in_NpgsqlOptionsExtension()
        {
            var optionsBuilder = new DbContextOptionsBuilder();

            optionsBuilder.UseNpgsql("Database=Crunchie", b => b.MaxBatchSize(1));

            var typeMapper = new NpgsqlTypeMappingSource(
                TestServiceFactory.Instance.Create <TypeMappingSourceDependencies>(),
                TestServiceFactory.Instance.Create <RelationalTypeMappingSourceDependencies>(),
                new NpgsqlSqlGenerationHelper(new RelationalSqlGenerationHelperDependencies()),
                new NpgsqlOptions());

            var logger = new FakeRelationalCommandDiagnosticsLogger();

            var factory = new NpgsqlModificationCommandBatchFactory(
                new ModificationCommandBatchFactoryDependencies(
                    new RelationalCommandBuilderFactory(
                        new RelationalCommandBuilderDependencies(
                            typeMapper)),
                    new NpgsqlSqlGenerationHelper(
                        new RelationalSqlGenerationHelperDependencies()),
                    new NpgsqlUpdateSqlGenerator(
                        new UpdateSqlGeneratorDependencies(
                            new NpgsqlSqlGenerationHelper(
                                new RelationalSqlGenerationHelperDependencies()),
                            typeMapper)),
                    new TypedRelationalValueBufferFactoryFactory(
                        new RelationalValueBufferFactoryDependencies(
                            typeMapper, new CoreSingletonOptions())),
                    new CurrentDbContext(new FakeDbContext()),
                    logger),
                optionsBuilder.Options);

            var batch = factory.Create();

            Assert.True(batch.AddCommand(new ModificationCommand("T1", null, new ParameterNameGenerator().GenerateNext, false, null)));
            Assert.False(batch.AddCommand(new ModificationCommand("T1", null, new ParameterNameGenerator().GenerateNext, false, null)));
        }
Beispiel #12
0
        public async Task Begins_new_transaction_when_transaction_nolonger_suppressed(bool async)
        {
            var fakeConnection = CreateConnection();
            var logger         = new FakeRelationalCommandDiagnosticsLogger();

            var commandList = new List <MigrationCommand>
            {
                new(CreateRelationalCommand(), null, logger, transactionSuppressed : true),
                new(CreateRelationalCommand(), null, logger)
            };

            var migrationCommandExecutor = new MigrationCommandExecutor();

            if (async)
            {
                await migrationCommandExecutor.ExecuteNonQueryAsync(commandList, fakeConnection);
            }
            else
            {
                migrationCommandExecutor.ExecuteNonQuery(commandList, fakeConnection);
            }

            Assert.Equal(1, fakeConnection.DbConnections.Count);
            Assert.Equal(1, fakeConnection.DbConnections[0].OpenCount);
            Assert.Equal(1, fakeConnection.DbConnections[0].CloseCount);

            Assert.Equal(1, fakeConnection.DbConnections[0].DbTransactions.Count);
            Assert.Equal(1, fakeConnection.DbConnections[0].DbTransactions[0].CommitCount);
            Assert.Equal(0, fakeConnection.DbConnections[0].DbTransactions[0].RollbackCount);

            Assert.Equal(2, fakeConnection.DbConnections[0].DbCommands.Count);
            Assert.Null(
                fakeConnection.DbConnections[0].DbCommands[0].Transaction);
            Assert.Same(
                fakeConnection.DbConnections[0].DbTransactions[0],
                fakeConnection.DbConnections[0].DbCommands[1].Transaction);
        }