public override void RunJob() { Logger.DebugFormat("begin restore data for module {0}", _module.ModuleName); SetStepsCount(_module.Tables.Count(t => !IgnoredTables.Contains(t.Name))); using (var connection = _factory.OpenConnection()) { foreach (var table in _module.GetTablesOrdered().Where(t => !IgnoredTables.Contains(t.Name) && t.InsertMethod != InsertMethod.None)) { Logger.DebugFormat("begin restore table {0}", table.Name); var transactionsCommited = 0; var rowsInserted = 0; ActionInvoker.Try( state => RestoreTable(connection.Fix(), (TableInfo)state, ref transactionsCommited, ref rowsInserted), table, 5, onAttemptFailure: error => _columnMapper.Rollback(), onFailure: error => { throw ThrowHelper.CantRestoreTable(table.Name, error); }); SetStepCompleted(); Logger.DebugFormat("{0} rows inserted for table {1}", rowsInserted, table.Name); } } Logger.DebugFormat("end restore data for module {0}", _module.ModuleName); }
private void RestoreTable(DbConnection connection, TableInfo tableInfo, ref int transactionsCommited, ref int rowsInserted) { SetColumns(connection, tableInfo); using var stream = Reader.GetEntry(KeyHelper.GetTableZipKey(Module, tableInfo.Name)); var lowImportanceRelations = Module .TableRelations .Where( r => string.Equals(r.ParentTable, tableInfo.Name, StringComparison.InvariantCultureIgnoreCase)) .Where(r => r.Importance == RelationImportance.Low && !r.IsSelfRelation()) .Select(r => Tuple.Create(r, Module.Tables.Single(t => t.Name == r.ChildTable))) .ToList(); foreach ( var rows in GetRows(tableInfo, stream) .Skip(transactionsCommited * TransactionLength) .MakeParts(TransactionLength)) { using var transaction = connection.BeginTransaction(); var rowsSuccess = 0; foreach (var row in rows) { if (ReplaceDate) { foreach (var column in tableInfo.DateColumns) { ColumnMapper.SetDateMapping(tableInfo.Name, column, row[column.Key]); } } object oldIdValue = null; object newIdValue = null; if (tableInfo.HasIdColumn()) { oldIdValue = row[tableInfo.IdColumn]; newIdValue = ColumnMapper.GetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue); if (newIdValue == null) { if (tableInfo.IdType == IdType.Guid) { newIdValue = Guid.NewGuid().ToString("D"); } else if (tableInfo.IdType == IdType.Integer) { var command = connection.CreateCommand(); command.CommandText = string.Format("select max({0}) from {1};", tableInfo.IdColumn, tableInfo.Name); newIdValue = (int)command.WithTimeout(120).ExecuteScalar() + 1; } } if (newIdValue != null) { ColumnMapper.SetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue, newIdValue); } } var insertCommand = Module.CreateInsertCommand(Dump, connection, ColumnMapper, tableInfo, row); if (insertCommand == null) { Logger.WarnFormat("Can't create command to insert row to {0} with values [{1}]", tableInfo, row); ColumnMapper.Rollback(); continue; } insertCommand.WithTimeout(120).ExecuteNonQuery(); rowsSuccess++; if (tableInfo.HasIdColumn() && tableInfo.IdType == IdType.Autoincrement) { var lastIdCommand = DbFactory.CreateLastInsertIdCommand(); lastIdCommand.Connection = connection; newIdValue = Convert.ToInt32(lastIdCommand.ExecuteScalar()); ColumnMapper.SetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue, newIdValue); } ColumnMapper.Commit(); foreach (var relation in lowImportanceRelations) { if (!relation.Item2.HasTenantColumn()) { Logger.WarnFormat( "Table {0} does not contain tenant id column. Can't apply low importance relations on such tables.", relation.Item2.Name); continue; } var oldValue = row[relation.Item1.ParentColumn]; var newValue = ColumnMapper.GetMapping(relation.Item1.ParentTable, relation.Item1.ParentColumn, oldValue); var command = connection.CreateCommand(); command.CommandText = string.Format("update {0} set {1} = {2} where {1} = {3} and {4} = {5}", relation.Item1.ChildTable, relation.Item1.ChildColumn, newValue is string? "'" + newValue + "'" : newValue, oldValue is string? "'" + oldValue + "'" : oldValue, relation.Item2.TenantColumn, ColumnMapper.GetTenantMapping()); command.WithTimeout(120).ExecuteNonQuery(); } } transaction.Commit(); transactionsCommited++; rowsInserted += rowsSuccess; } }