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);
        }
Beispiel #2
0
        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;
            }
        }