public async Task ExecuteAsync_calls_Commit_if_no_transaction() { var sqlGenerator = new Mock <ISqlGenerator>().Object; var mockModificationCommandBatch = new Mock <ModificationCommandBatch>(sqlGenerator); var mockRelationalConnection = new Mock <IRelationalConnection>(); var transactionMock = new Mock <RelationalTransaction>( mockRelationalConnection.Object, Mock.Of <DbTransaction>(), false, Mock.Of <ILogger>()); RelationalTransaction currentTransaction = null; mockRelationalConnection.Setup(m => m.BeginTransaction()).Returns(() => currentTransaction = transactionMock.Object); mockRelationalConnection.Setup(m => m.Transaction).Returns(() => currentTransaction); var cancellationToken = new CancellationTokenSource().Token; var relationalTypeMapper = new RelationalTypeMapper(); var batchExecutor = new BatchExecutorForTest(relationalTypeMapper); await batchExecutor.ExecuteAsync(new[] { mockModificationCommandBatch.Object }, mockRelationalConnection.Object, cancellationToken); mockRelationalConnection.Verify(rc => rc.OpenAsync(cancellationToken)); mockRelationalConnection.Verify(rc => rc.Close()); transactionMock.Verify(t => t.Commit()); mockModificationCommandBatch.Verify(mcb => mcb.ExecuteAsync( It.IsAny <RelationalTransaction>(), relationalTypeMapper, It.IsAny <DbContext>(), null, cancellationToken)); }
public async Task ExecuteAsync_calls_Commit_if_no_transaction() { var mockModificationCommandBatch = new Mock<ModificationCommandBatch>(); var transactionMock = new Mock<RelationalTransaction>(); var mockRelationalConnection = new Mock<IRelationalConnection>(); RelationalTransaction currentTransaction = null; mockRelationalConnection.Setup(m => m.BeginTransaction()).Returns(() => currentTransaction = transactionMock.Object); mockRelationalConnection.Setup(m => m.Transaction).Returns(() => currentTransaction); var cancellationToken = new CancellationTokenSource().Token; var relationalTypeMapper = new RelationalTypeMapper(); var batchExecutor = new BatchExecutorForTest(relationalTypeMapper); await batchExecutor.ExecuteAsync(new[] { mockModificationCommandBatch.Object }, mockRelationalConnection.Object, cancellationToken); mockRelationalConnection.Verify(rc => rc.OpenAsync(cancellationToken)); mockRelationalConnection.Verify(rc => rc.Close()); transactionMock.Verify(t => t.Commit()); mockModificationCommandBatch.Verify(mcb => mcb.ExecuteAsync( It.IsAny<RelationalTransaction>(), relationalTypeMapper, It.IsAny<DbContext>(), null, cancellationToken)); }
public async Task ExecuteAsync_does_not_call_Commit_if_existing_transaction() { var mockModificationCommandBatch = new Mock <ModificationCommandBatch>(); var transactionMock = new Mock <RelationalTransaction>(); var mockRelationalConnection = new Mock <IRelationalConnection>(); mockRelationalConnection.Setup(m => m.Transaction).Returns(transactionMock.Object); var cancellationToken = new CancellationTokenSource().Token; var relationalTypeMapper = new RelationalTypeMapper(); var batchExecutor = new BatchExecutorForTest(relationalTypeMapper); await batchExecutor.ExecuteAsync(new[] { mockModificationCommandBatch.Object }, mockRelationalConnection.Object, cancellationToken); mockRelationalConnection.Verify(rc => rc.OpenAsync(cancellationToken)); mockRelationalConnection.Verify(rc => rc.Close()); mockRelationalConnection.Verify(rc => rc.BeginTransaction(), Times.Never); transactionMock.Verify(t => t.Commit(), Times.Never); mockModificationCommandBatch.Verify(mcb => mcb.ExecuteAsync( It.IsAny <RelationalTransaction>(), relationalTypeMapper, It.IsAny <DbContext>(), null, cancellationToken)); }
public BatchExecutor( [NotNull] RelationalTypeMapper typeMapper) { Check.NotNull(typeMapper, "typeMapper"); _typeMapper = typeMapper; }
public async Task ExecuteAsync_does_not_call_Commit_if_existing_transaction() { var sqlGenerator = new Mock<ISqlGenerator>().Object; var mockModificationCommandBatch = new Mock<ModificationCommandBatch>(sqlGenerator); var mockRelationalConnection = new Mock<IRelationalConnection>(); var transactionMock = new Mock<RelationalTransaction>( mockRelationalConnection.Object, Mock.Of<DbTransaction>(), false, Mock.Of<ILogger>()); mockRelationalConnection.Setup(m => m.Transaction).Returns(transactionMock.Object); var cancellationToken = new CancellationTokenSource().Token; var relationalTypeMapper = new RelationalTypeMapper(); var batchExecutor = new BatchExecutorForTest(relationalTypeMapper); await batchExecutor.ExecuteAsync(new[] { mockModificationCommandBatch.Object }, mockRelationalConnection.Object, cancellationToken); mockRelationalConnection.Verify(rc => rc.OpenAsync(cancellationToken)); mockRelationalConnection.Verify(rc => rc.Close()); mockRelationalConnection.Verify(rc => rc.BeginTransaction(), Times.Never); transactionMock.Verify(t => t.Commit(), Times.Never); mockModificationCommandBatch.Verify(mcb => mcb.ExecuteAsync( It.IsAny<RelationalTransaction>(), relationalTypeMapper, It.IsAny<DbContext>(), null, cancellationToken)); }
public override int Execute( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILogger logger) { Check.NotNull(transaction, nameof(transaction)); Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(context, nameof(context)); Check.NotNull(logger, nameof(logger)); var commandText = GetCommandText(); using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout)) { if (logger.IsEnabled(LogLevel.Verbose)) { // RelationalLoggerExtensions.LogCommand can't be called because the class // is internal... //logger.LogCommand(storeCommand); } try { using (var reader = storeCommand.ExecuteReader()) { var actualResultSetCount = 0; do { actualResultSetCount++; }while (reader.NextResult()); Debug.Assert(actualResultSetCount == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + actualResultSetCount); if (reader.RecordsAffected != ModificationCommands.Count) { throw new DbUpdateConcurrencyException( Microsoft.Data.Entity.Relational.Strings.UpdateConcurrencyException(ModificationCommands.Count, reader.RecordsAffected), context, new List <InternalEntityEntry>() // TODO ); } } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Microsoft.Data.Entity.Relational.Strings.UpdateStoreException, context, ex, new InternalEntityEntry[0]); } } return(ModificationCommands.Count); }
public virtual async Task <int> ExecuteAsync( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(transaction, "transaction"); Check.NotNull(typeMapper, "typeMapper"); using (var storeCommand = CreateStoreCommand(transaction.DbTransaction, typeMapper)) { var commandIndex = 0; try { using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false)) { do { var tableModification = ModificationCommands[commandIndex]; if (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { if (tableModification.RequiresResultPropagation) { tableModification.PropagateResults(new RelationalTypedValueReader(reader)); } else { var rowsAffected = reader.GetFieldValue <int>(0); if (rowsAffected != 1) { throw new DbUpdateConcurrencyException(string.Format(Strings.FormatUpdateConcurrencyException(1, rowsAffected)), tableModification.StateEntries); } } } else { throw new DbUpdateConcurrencyException(string.Format(Strings.FormatUpdateConcurrencyException(1, 0)), tableModification.StateEntries); } commandIndex++; }while (await reader.NextResultAsync(cancellationToken).ConfigureAwait(false)); } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.FormatUpdateStoreException(), ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : null); } } // TODO Return the actual results once we can get them return(1); }
private static ModelDiffer CreateModelDiffer() { var extensionProvider = RelationalTestHelpers.ExtensionProvider(); var typeMapper = new RelationalTypeMapper(); var operationFactory = new MigrationOperationFactory(extensionProvider); var operationProcessor = new MigrationOperationProcessor(extensionProvider, typeMapper, operationFactory); return(new ModelDiffer(extensionProvider, typeMapper, operationFactory, operationProcessor)); }
public override Task <int> ExecuteAsync( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILogger logger, CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException("No async here yet"); }
protected MigrationOperationSqlGenerator( [NotNull] IRelationalMetadataExtensionProvider extensionProvider, [NotNull] RelationalTypeMapper typeMapper) { Check.NotNull(extensionProvider, "extensionProvider"); Check.NotNull(typeMapper, "typeMapper"); _extensionProvider = extensionProvider; _typeMapper = typeMapper; }
public BatchExecutor( [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContextConfiguration contextConfiguration) { Check.NotNull(typeMapper, "typeMapper"); Check.NotNull(contextConfiguration, "contextConfiguration"); _typeMapper = typeMapper; _context = contextConfiguration.Context; _logger = new LazyRef <ILogger>(() => (_context.Configuration.LoggerFactory.Create(GetType().Name))); }
public BatchExecutor( [NotNull] SqlGenerator sqlGenerator, [NotNull] RelationalConnection connection, [NotNull] RelationalTypeMapper typeMapper) { Check.NotNull(sqlGenerator, "sqlGenerator"); Check.NotNull(connection, "connection"); Check.NotNull(typeMapper, "typeMapper"); _sqlGenerator = sqlGenerator; _connection = connection; _typeMapper = typeMapper; }
public MigrationOperationProcessor( [NotNull] IRelationalMetadataExtensionProvider extensionProvider, [NotNull] RelationalTypeMapper typeMapper, [NotNull] MigrationOperationFactory operationFactory) { Check.NotNull(extensionProvider, "extensionProvider"); Check.NotNull(typeMapper, "typeMapper"); Check.NotNull(operationFactory, "operationFactory"); _extensionProvider = extensionProvider; _typeMapper = typeMapper; _operationFactory = operationFactory; }
public BatchExecutor( [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContextService <DbContext> context, [NotNull] ILoggerFactory loggerFactory) { Check.NotNull(typeMapper, "typeMapper"); Check.NotNull(context, "context"); Check.NotNull(loggerFactory, "loggerFactory"); _typeMapper = typeMapper; _context = context; _logger = new LazyRef <ILogger>(() => (loggerFactory.Create <BatchExecutor>())); }
public BatchExecutor( [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILoggerFactory loggerFactory) { Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(context, nameof(context)); Check.NotNull(loggerFactory, nameof(loggerFactory)); _typeMapper = typeMapper; _context = context; _logger = new LazyRef <ILogger>(() => (loggerFactory.CreateLogger <BatchExecutor>())); }
public BatchExecutor( [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILoggerFactory loggerFactory) { Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(context, nameof(context)); Check.NotNull(loggerFactory, nameof(loggerFactory)); _typeMapper = typeMapper; _context = context; _logger = new LazyRef<ILogger>(() => (loggerFactory.CreateLogger<BatchExecutor>())); }
protected virtual DbCommand CreateStoreCommand( [NotNull] DbTransaction transaction, [NotNull] RelationalTypeMapper typeMapper) { var command = transaction.Connection.CreateCommand(); command.CommandType = CommandType.Text; command.CommandText = _sql; command.Transaction = transaction; foreach (var columnModification in ModificationCommands.SelectMany(t => t.ColumnModifications)) { PopulateParameters(command, columnModification, typeMapper); } return(command); }
protected virtual DbCommand CreateStoreCommand( [NotNull] DbTransaction transaction, [NotNull] RelationalTypeMapper typeMapper) { var command = transaction.Connection.CreateCommand(); command.CommandType = CommandType.Text; command.CommandText = _sql; command.Transaction = transaction; foreach (var columnModification in ModificationCommands.SelectMany(t => t.ColumnModifications)) { if (columnModification.ParameterName != null || columnModification.OriginalParameterName != null) { // TODO: It would be nice to just pass IProperty to the type mapper, but Migrations uses its own // store model for which there is no easy way to get an IProperty. var property = columnModification.Property; // TODO: Perf: Avoid doing Contains check everywhere we need to know if a property is part of a foreign key var isKey = columnModification.IsKey || property.IsForeignKey(); var typeMapping = typeMapper .GetTypeMapping( property.ColumnType(), property.ColumnName(), property.PropertyType, isKey, property.IsConcurrencyToken); if (columnModification.ParameterName != null) { command.Parameters.Add(typeMapping.CreateParameter(command, columnModification, useOriginalValue: false)); } if (columnModification.OriginalParameterName != null) { command.Parameters.Add(typeMapping.CreateParameter(command, columnModification, useOriginalValue: true)); } } } return(command); }
protected virtual DbCommand CreateStoreCommand( [NotNull] string commandText, [NotNull] DbTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, int?commandTimeout) { var command = transaction.Connection.CreateCommand(); command.CommandType = CommandType.Text; command.CommandText = commandText; command.Transaction = transaction; if (commandTimeout != null) { command.CommandTimeout = (int)commandTimeout; } foreach (var columnModification in ModificationCommands.SelectMany(t => t.ColumnModifications)) { PopulateParameters(command, columnModification, typeMapper); } return(command); }
public ModelDiffer([NotNull] RelationalTypeMapper typeMapper) { Check.NotNull(typeMapper, nameof(typeMapper)); TypeMapper = typeMapper; }
public MigrationOperationSqlGenerator([NotNull] RelationalTypeMapper typeMapper) { Check.NotNull(typeMapper, "typeMapper"); _typeMapper = typeMapper; }
public override async Task<int> ExecuteAsync( RelationalTransaction transaction, RelationalTypeMapper typeMapper, DbContext context, ILogger logger, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(transaction, nameof(transaction)); Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(context, nameof(context)); Check.NotNull(logger, nameof(logger)); var commandText = GetCommandText(); Debug.Assert(ResultSetEnds.Count == ModificationCommands.Count); var commandIndex = 0; using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout)) { if (logger.IsEnabled(LogLevel.Verbose)) { logger.LogCommand(storeCommand); } try { using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).WithCurrentCulture()) { var actualResultSetCount = 0; do { commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation ? await ConsumeResultSetWithPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture() : await ConsumeResultSetWithoutPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture(); actualResultSetCount++; } while (commandIndex < ResultSetEnds.Count && await reader.NextResultAsync(cancellationToken).WithCurrentCulture()); Debug.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex); #if DEBUG var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e); expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0; Debug.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount); #endif } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.UpdateStoreException, context, ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].Entries : new InternalEntityEntry[0]); } } return commandIndex; }
protected virtual void PopulateParameters(DbCommand command, ColumnModification columnModification, RelationalTypeMapper typeMapper) { if (columnModification.ParameterName != null || columnModification.OriginalParameterName != null) { var property = columnModification.Property; var isKey = columnModification.IsKey || property.IsKey() || property.IsForeignKey(); // TODO: It would be nice to just pass IProperty to the type mapper, but Migrations uses its own // store model for which there is no easy way to get an IProperty. // Issue #769 var extensions = GetPropertyExtensions(property); var typeMapping = typeMapper .GetTypeMapping(extensions.ColumnType, extensions.Column, property.ClrType, isKey, property.IsConcurrencyToken); if (columnModification.ParameterName != null) { command.Parameters.Add(typeMapping.CreateParameter(command, columnModification, false)); } if (columnModification.OriginalParameterName != null) { command.Parameters.Add(typeMapping.CreateParameter(command, columnModification, true)); } } }
public BatchExecutorForTest(RelationalTypeMapper typeMapper) : base(typeMapper, TestHelpers.Instance.CreateContext(), new LoggerFactory()) { }
public virtual DbCommand CreateStoreCommandBase(DbTransaction transaction, RelationalTypeMapper typeMapper) { return(base.CreateStoreCommand(transaction, typeMapper)); }
public void PopulateParametersBase(DbCommand command, ColumnModification columnModification, RelationalTypeMapper typeMapper) { base.PopulateParameters(command, columnModification, typeMapper); }
protected override void PopulateParameters(DbCommand command, ColumnModification columnModification, RelationalTypeMapper typeMapper) { PopulateParameterCalls++; }
public DbCommand CreateStoreCommandBase(string commandText, DbTransaction transaction, RelationalTypeMapper typeMapper) { return(base.CreateStoreCommand(commandText, transaction, typeMapper)); }
protected override DbCommand CreateStoreCommand(string commandText, DbTransaction transaction, RelationalTypeMapper typeMapper) { return(CreateDbCommandMock(_reader).Object); }
public abstract Task <int> ExecuteAsync( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILogger logger, CancellationToken cancellationToken = default(CancellationToken));
public virtual DbCommand CreateStoreCommandProtected(DbTransaction transaction, RelationalTypeMapper typeMapper) { return(CreateDbCommandMock(_reader).Object); }
protected MigrationOperationSqlGenerator([NotNull] RelationalTypeMapper typeMapper) { Check.NotNull(typeMapper, "typeMapper"); _typeMapper = typeMapper; }
public override async Task <int> ExecuteAsync( RelationalTransaction transaction, RelationalTypeMapper typeMapper, DbContext context, ILogger logger, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(transaction, nameof(transaction)); Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(context, nameof(context)); Check.NotNull(logger, nameof(logger)); var commandText = GetCommandText(); Debug.Assert(ResultSetEnds.Count == ModificationCommands.Count); var commandIndex = 0; using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout)) { if (logger.IsEnabled(LogLevel.Verbose)) { logger.LogCommand(storeCommand); } try { using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).WithCurrentCulture()) { var actualResultSetCount = 0; do { commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation ? await ConsumeResultSetWithPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture() : await ConsumeResultSetWithoutPropagationAsync(commandIndex, reader, context, cancellationToken) .WithCurrentCulture(); actualResultSetCount++; }while (commandIndex < ResultSetEnds.Count && await reader.NextResultAsync(cancellationToken).WithCurrentCulture()); Debug.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex); #if DEBUG var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e); expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0; Debug.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount); #endif } } catch (DbUpdateException) { throw; } catch (Exception ex) { throw new DbUpdateException( Strings.UpdateStoreException, context, ex, commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].Entries : new InternalEntityEntry[0]); } } return(commandIndex); }
public abstract int Execute( [NotNull] RelationalTransaction transaction, [NotNull] RelationalTypeMapper typeMapper, [NotNull] DbContext context, [NotNull] ILogger logger);
protected override DbCommand CreateStoreCommand(DbTransaction transaction, RelationalTypeMapper typeMapper) { return(CreateStoreCommandProtected(transaction, typeMapper)); }