Пример #1
0
        public static void CopyDatabase(IDatabaseSource src, IDatabaseWriter dst, IProgressInfo progress, DatabaseCopyOptions copyOpts)
        {
            IDatabaseWriter dst2 = null;

            for (; ;)
            {
                dst2 = dst.GetRedirectedWriter();
                if (dst2 == null)
                {
                    break;
                }
                dst = dst2;
            }
            dst.SetSourceInfo(new DatabaseWriterSourceInfo
            {
                Dialect = src.Dialect,
                //CopyMode = copyOpts.Mode,
                SchemaMode = copyOpts.SchemaMode,
            });
            try
            {
                dst.ProgressInfo = progress;

                Async.SafeOpen(src.Connection);
                dst.OpenConnection();

                if (dst.DirectCopy(src))
                {
                    dst.RunDirectCopy(src, copyOpts);
                }
                else
                {
                    copyOpts.CopyMembers.IgnoreSystemObjects = true;
                    IDatabaseStructure tmpDb    = src.InvokeLoadStructure(copyOpts.CopyMembers, progress);
                    DatabaseStructure  sourceDb = new DatabaseStructure(tmpDb);
                    //sourceDb.AutoFillRefs();
                    DatabaseStructure targetDb = sourceDb.GetMappedDatabase(copyOpts, dst.Dialect);
                    if (dst.Dialect != null)
                    {
                        dst.Dialect.MigrateDatabase(targetDb, copyOpts.MigrationProfile, progress);
                    }

                    if (copyOpts.CopyStructure)
                    {
                        dst.WriteStructureBeforeData(targetDb);
                    }

                    bool copydata = copyOpts.DataMode != DbCopyDataMode.None && src.TableCaps.DataStoreForReading && dst.WriterCaps.AcceptData;
                    if (copydata)
                    {
                        dst.BeforeFillData();

                        foreach (var tbl in sourceDb.Tables.SortedByKey <ITableStructure, int>(tbl => copyOpts.DataCopyTables.IndexOf(tbl.FullName)))
                        {
                            if (!copyOpts.CopyTableData(tbl.FullName))
                            {
                                continue;
                            }
                            Logging.Debug("Copying table {0}", tbl);
                            if (progress != null)
                            {
                                progress.SetCurWork(String.Format("{0} {1}", Texts.Get("s_copying_table"), tbl));
                            }
                            GenericDataQueue queue = new GenericDataQueue(tbl, tbl, new IdentityTransform(tbl));
                            queue.ProgressInfo = progress;
                            if (dst.WriterCaps.ExecuteSql)
                            {
                                var ada = new RecordToDbAdapter(tbl, tbl, dst.Dialect, new DataFormatSettings());
                                ada.ProgressInfo = progress;
                                queue.AddOutputAdapter(ada);
                            }
                            ITableSource      tsrc           = src.GetTable(tbl.FullName);
                            ITabularDataStore srcds          = tsrc.GetDataStoreAndReuse();
                            IAsyncResult      async_src      = srcds.BeginRead(null, queue);
                            ITableStructure   newTableStruct = (ITableStructure)targetDb.FindByGroupId(tbl.GroupId);
                            dst.FillTable(newTableStruct, queue, copyOpts.TableOptions);
                            srcds.EndRead(async_src);
                        }
                        dst.AfterFillData();
                    }
                    if (copyOpts.CopyStructure)
                    {
                        dst.WriteStructureAfterData(targetDb);
                    }
                }
            }
            catch (Exception)
            {
                dst.ProcessFailed();
                throw;
            }
            finally
            {
                Async.SafeClose(src.Connection);
                dst.CloseConnection();
            }
        }