/// <summary>
    /// Creates dictionaries that maps from types fullnames to 
    /// a suitable collection name. The resulting name is usually
    /// simple the name of the type. When there is more than
    /// one type with the same name, FullName is progressively
    /// prepended to name until there is no ambiguity.
    /// Two dictionaries are generated, one with pluralized last name
    /// and one with singular one.
    /// </summary>
    /// <param name="pPersistables">Types to be translated.</param>
    /// <param name="pSchema">Schema to add names dictionaries.</param>
    private static void CreateNamesDictionary(Type[] pPersistables, ref SchemaInfo pSchema)
    {
      Dictionary<string, string> lPlural;
      SortedSet<string> lSingular = new SortedSet<string>();

      // Initialy maps FullName to Name.
      lPlural = pPersistables.ToDictionary(lPersistable => lPersistable.ToGenericTypeString(), lPersistable => lPersistable.Name + "s");
      foreach (Type type in pPersistables)
        lSingular.Add(type.ToGenericTypeString());
      // Solve name clashes.
      pPersistables
          .ToLookup(lPersistable => lPersistable.Name)
          .Where(lGroup => lGroup.Count() > 1)
          .Select(lGroup => SolveNameClash(lGroup))
          .ToList()
          .ForEach(delegate(Dictionary<string, string[]> lSub)
          {
            foreach (KeyValuePair<string, string[]> lPair in lSub)
            {
              // Singular names just join names.
             // lSingular[lPair.Key] = String.Join("_", lPair.Value);
              // Last name gets pluralized for plural names.
              lPair.Value[lPair.Value.Count() - 1] = lPair.Value.Last() + "s";
              lPlural[lPair.Key] = String.Join("_", lPair.Value);

            }
          });
      pSchema.SingularNames = lSingular;
      pSchema.TypesNameToPluralName = lPlural;
    }
示例#2
0
        /// <summary>
        /// Load assemblies and get exported persistable types
        /// from them.
        /// </summary>
        /// <param name="pClassesFilenames">Filenames of all assemblies to
        /// load.</param>
        /// <param name="pAssemblies">Loaded assemblies.</param>
        /// <param name="pTypes">Types found.</param>
        private static void GetAssembliesAndTypes(string[] pClassFilenames, string[] pDependencyFilenames, ref SchemaInfo pSchema)
        {
            // Creates a SchemaExtractor instance on a new domain. This is done
            // so that no assembly is loaded on process start, and at the end,
            // only needed assemblies are loaded.
            //Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            AppDomain            lDomain = AppDomain.CreateDomain("User assemblies domain.");
            SchemaExtractor      lExtractor;
            OptimizedPersistable pObj = (OptimizedPersistable)lDomain.CreateInstanceFromAndUnwrap(typeof(OptimizedPersistable).Assembly.CodeBase, typeof(OptimizedPersistable).FullName);

            lExtractor = (SchemaExtractor)lDomain.CreateInstanceFromAndUnwrap(typeof(SchemaExtractor).Assembly.CodeBase, typeof(SchemaExtractor).FullName);
            // Load assemblies and types on the new domain.
            List <string> lTypeNames          = null;
            List <string> lAssemblyNames      = null;
            List <string> lActualDependencies = null;

            lExtractor.GetAssembliesAndTypesHelper(pClassFilenames, pDependencyFilenames, ref lAssemblyNames, ref lTypeNames, ref lActualDependencies);
            AppDomain.Unload(lDomain);

            // Load assemblies on this domain (to be able to access types).
            Assembly l;

            foreach (string lDep in lActualDependencies)
            {
                l = Assembly.LoadFrom(lDep);
            }

            // Obtain types from names and fill in schema.
            pSchema.PersistableTypes      = lTypeNames.Select(lTypeName => Type.GetType(lTypeName, true)).ToArray();
            pSchema.LoadedAssemblies      = lActualDependencies.ToArray();
            pSchema.LoadedAssembliesNames = lAssemblyNames.ToArray();
        }
示例#3
0
        private async void GenerateScripts()
        {
            SchemaInfo schemaInfo = this.tvDbObjects.GetSchemaInfo();

            if (!this.Validate(schemaInfo))
            {
                return;
            }

            this.isBusy = true;
            this.btnGenerate.Enabled = false;

            DatabaseType dbType = this.useConnector ? this.dbConnectionProfile.DatabaseType : this.databaseType;

            DbInterpreterOption option = new DbInterpreterOption()
            {
                ScriptOutputMode       = GenerateScriptOutputMode.WriteToFile,
                SortObjectsByReference = true,
                GetTableAllObjects     = true
            };

            if (this.chkTreatBytesAsNull.Checked)
            {
                option.TreatBytesAsNullForReading   = true;
                option.TreatBytesAsNullForExecuting = true;
            }
            else
            {
                if (dbType == DatabaseType.Oracle)
                {
                    option.TreatBytesAsNullForReading   = true;
                    option.TreatBytesAsNullForExecuting = true;
                }
                else
                {
                    option.TreatBytesAsHexStringForFile = true;
                }
            }

            this.SetGenerateScriptOption(option);

            GenerateScriptMode scriptMode = this.GetGenerateScriptMode();

            if (scriptMode == GenerateScriptMode.None)
            {
                MessageBox.Show("Please specify the script mode.");
                return;
            }

            this.dbInterpreter = DbInterpreterHelper.GetDbInterpreter(dbType, this.connectionInfo, option);

            SchemaInfoFilter filter = new SchemaInfoFilter();

            SchemaInfoHelper.SetSchemaInfoFilterValues(filter, schemaInfo);

            try
            {
                schemaInfo = await this.dbInterpreter.GetSchemaInfoAsync(filter);

                this.dbInterpreter.Subscribe(this);

                GenerateScriptMode mode = GenerateScriptMode.None;

                DbScriptGenerator dbScriptGenerator = DbScriptGeneratorHelper.GetDbScriptGenerator(this.dbInterpreter);

                if (scriptMode.HasFlag(GenerateScriptMode.Schema))
                {
                    mode = GenerateScriptMode.Schema;
                    dbScriptGenerator.GenerateSchemaScripts(schemaInfo);
                }

                if (scriptMode.HasFlag(GenerateScriptMode.Data))
                {
                    mode = GenerateScriptMode.Data;
                    await dbScriptGenerator.GenerateDataScriptsAsync(schemaInfo);
                }

                this.isBusy = false;
                ManagerUtil.OpenInExplorer(dbScriptGenerator.GetScriptOutputFilePath(mode));

                MessageBox.Show(DONE, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                this.HandleException(ex);
            }

            this.btnGenerate.Enabled = true;
        }
        private async Task Convert()
        {
            SchemaInfo schemaInfo = this.tvDbObjects.GetSchemaInfo();

            if (!this.ValidateSource(schemaInfo))
            {
                return;
            }

            if (this.targetDbConnectionInfo == null)
            {
                MessageBox.Show("Target connection info is null.");
                return;
            }

            if (this.sourceDbConnectionInfo.Server == this.targetDbConnectionInfo.Server && this.sourceDbConnectionInfo.Database == this.targetDbConnectionInfo.Database)
            {
                MessageBox.Show("Source database cannot be equal to the target database.");
                return;
            }

            DatabaseType sourceDbType = this.useSourceConnector ? this.sourceDbProfile.DatabaseType : this.sourceDatabaseType;
            DatabaseType targetDbType = this.targetDbProfile.DatabaseType;

            DbInterpreterOption sourceScriptOption = new DbInterpreterOption()
            {
                ScriptOutputMode = GenerateScriptOutputMode.None, SortObjectsByReference = true, GetTableAllObjects = true
            };
            DbInterpreterOption targetScriptOption = new DbInterpreterOption()
            {
                ScriptOutputMode = (GenerateScriptOutputMode.WriteToString)
            };

            this.SetGenerateScriptOption(sourceScriptOption, targetScriptOption);

            if (this.chkGenerateSourceScripts.Checked)
            {
                sourceScriptOption.ScriptOutputMode = sourceScriptOption.ScriptOutputMode | GenerateScriptOutputMode.WriteToFile;
            }

            if (this.chkOutputScripts.Checked)
            {
                targetScriptOption.ScriptOutputMode = targetScriptOption.ScriptOutputMode | GenerateScriptOutputMode.WriteToFile;
            }

            if (this.chkTreatBytesAsNull.Checked)
            {
                sourceScriptOption.TreatBytesAsNullForReading   = true;
                targetScriptOption.TreatBytesAsNullForExecuting = true;
            }

            targetScriptOption.TableScriptsGenerateOption.GenerateIdentity = this.chkGenerateIdentity.Checked;

            GenerateScriptMode scriptMode = this.GetGenerateScriptMode();

            if (scriptMode == GenerateScriptMode.None)
            {
                MessageBox.Show("Please specify the script mode.");
                return;
            }

            DbConveterInfo source = new DbConveterInfo()
            {
                DbInterpreter = DbInterpreterHelper.GetDbInterpreter(sourceDbType, this.sourceDbConnectionInfo, sourceScriptOption)
            };
            DbConveterInfo target = new DbConveterInfo()
            {
                DbInterpreter = DbInterpreterHelper.GetDbInterpreter(targetDbType, this.targetDbConnectionInfo, targetScriptOption)
            };

            try
            {
                using (this.dbConverter = new DbConverter(source, target))
                {
                    this.dbConverter.Option.GenerateScriptMode                         = scriptMode;
                    this.dbConverter.Option.BulkCopy                                   = this.chkBulkCopy.Checked;
                    this.dbConverter.Option.ExecuteScriptOnTargetServer                = this.chkExecuteOnTarget.Checked;
                    this.dbConverter.Option.UseTransaction                             = this.chkUseTransaction.Checked;
                    this.dbConverter.Option.SkipScriptError                            = this.chkSkipScriptError.Checked;
                    this.dbConverter.Option.PickupTable                                = this.chkPickup.Checked;
                    this.dbConverter.Option.ConvertComputeColumnExpression             = this.chkComputeColumn.Checked;
                    this.dbConverter.Option.OnlyCommentComputeColumnExpressionInScript = this.chkOnlyCommentComputeExpression.Checked;

                    this.dbConverter.Subscribe(this);

                    if (sourceDbType == DatabaseType.MySql)
                    {
                        source.DbInterpreter.Option.InQueryItemLimitCount = 2000;
                    }

                    if (targetDbType == DatabaseType.SqlServer)
                    {
                        target.DbOwner = this.txtTargetDbOwner.Text ?? "dbo";
                    }
                    else if (targetDbType == DatabaseType.MySql)
                    {
                        target.DbInterpreter.Option.RemoveEmoji = true;
                    }

                    this.dbConverter.Option.SplitScriptsToExecute = true;

                    this.btnExecute.Enabled = false;
                    this.btnCancel.Enabled  = true;

                    await this.dbConverter.Convert(schemaInfo);

                    if (!this.hasError && !this.dbConverter.HasError && !source.DbInterpreter.HasError && !target.DbInterpreter.HasError)
                    {
                        this.btnExecute.Enabled = true;
                        this.btnCancel.Enabled  = false;

                        if (!this.dbConverter.CancelRequested)
                        {
                            this.txtMessage.AppendText(Environment.NewLine + DONE);
                            MessageBox.Show(DONE, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                            MessageBox.Show("Task has been canceled.");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.hasError = true;
                this.HandleException(ex);
            }
        }
 /// <summary>
 /// Extract schema information from assemblies.
 /// </summary>
 /// <param name="pClassesFilenames">Assemblies containing 
 /// desired persistable types.</param>
 /// <param name="pDependenciesFilenames">Assemblies required by
 /// pClassesFilenames Assemblies.</param>
 /// <returns></returns>
 public static SchemaInfo Extract(string[] pClassesFilenames, string[] pDependenciesFilenames)
 {
   // Create schema, get persistable types, loaded assemblies and
   // loaded assemblies names, and finally create names for each type.
   SchemaInfo lSchema = new SchemaInfo()
   {
     UserClassesFiles = pClassesFilenames,
     UserDependenciesFiles = pDependenciesFilenames
   };
   // Already loaded assemblies sometimes get not found! register
   // resolver.
   AppDomain.CurrentDomain.AssemblyResolve += SchemaExtractor.AssemblyResolve;
   GetAssembliesAndTypes(pClassesFilenames, pDependenciesFilenames, ref lSchema);
   CreateNamesDictionary(lSchema.PersistableTypes, ref lSchema);
   AppDomain.CurrentDomain.AssemblyResolve -= SchemaExtractor.AssemblyResolve;
   return lSchema;
 }
    /// <summary>
    /// Load assemblies and get exported persistable types 
    /// from them.
    /// </summary>
    /// <param name="pClassesFilenames">Filenames of all assemblies to 
    /// load.</param>
    /// <param name="pAssemblies">Loaded assemblies.</param>
    /// <param name="pTypes">Types found.</param>
    private static void GetAssembliesAndTypes(string[] pClassFilenames, string[] pDependencyFilenames,ref SchemaInfo pSchema)
    {
      // Creates a SchemaExtractor instance on a new domain. This is done
      // so that no assembly is loaded on process start, and at the end,
      // only needed assemblies are loaded.
      //Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
      AppDomain lDomain = AppDomain.CreateDomain("User assemblies domain.");
      SchemaExtractor lExtractor;
      OptimizedPersistable pObj = (OptimizedPersistable)lDomain.CreateInstanceFromAndUnwrap(typeof(OptimizedPersistable).Assembly.CodeBase, typeof(OptimizedPersistable).FullName);
      lExtractor = (SchemaExtractor)lDomain.CreateInstanceFromAndUnwrap(typeof(SchemaExtractor).Assembly.CodeBase,typeof(SchemaExtractor).FullName);
      // Load assemblies and types on the new domain.
      List<string> lTypeNames = null;
      List<string> lAssemblyNames = null;
      List<string> lActualDependencies = null;
      lExtractor.GetAssembliesAndTypesHelper(pClassFilenames, pDependencyFilenames, ref lAssemblyNames, ref lTypeNames, ref lActualDependencies);
      AppDomain.Unload(lDomain);

      // Load assemblies on this domain (to be able to access types).
      Assembly l;
      foreach (string lDep in lActualDependencies)
      {
        l = Assembly.LoadFrom(lDep);
      }

      // Obtain types from names and fill in schema.
      pSchema.PersistableTypes = lTypeNames.Select(lTypeName => Type.GetType(lTypeName, true)).ToArray();
      pSchema.LoadedAssemblies = lActualDependencies.ToArray();
      pSchema.LoadedAssembliesNames = lAssemblyNames.ToArray();
    }
示例#7
0
        private async Task CopyTable()
        {
            string name = this.txtName.Text.Trim();

            if (!this.ValidateInputs())
            {
                return;
            }

            try
            {
                GenerateScriptMode scriptMode = this.GetGenerateScriptMode();

                bool isTableExisted = false;

                if (scriptMode.HasFlag(GenerateScriptMode.Schema))
                {
                    isTableExisted = await this.IsNameExisted();
                }

                if (isTableExisted)
                {
                    name = name + "_copy";
                }

                SchemaInfo schemaInfo = new SchemaInfo();
                schemaInfo.Tables.Add(this.Table);

                DatabaseType   targetDatabaseType   = this.rbAnotherDatabase.Checked ? this.ucConnection.DatabaseType : this.DatabaseType;
                ConnectionInfo targetConnectionInfo = this.rbAnotherDatabase.Checked ? this.targetDbConnectionInfo : this.ConnectionInfo;

                DbInterpreterOption sourceOption = new DbInterpreterOption();
                DbInterpreterOption targetOption = new DbInterpreterOption();

                targetOption.TableScriptsGenerateOption.GenerateIdentity = this.chkGenerateIdentity.Checked;

                DbConveterInfo source = new DbConveterInfo()
                {
                    DbInterpreter = DbInterpreterHelper.GetDbInterpreter(this.DatabaseType, this.ConnectionInfo, sourceOption)
                };
                DbConveterInfo target = new DbConveterInfo()
                {
                    DbInterpreter = DbInterpreterHelper.GetDbInterpreter(targetDatabaseType, targetConnectionInfo, targetOption)
                };

                source.TableNameMappings.Add(this.Table.Name, name);

                this.btnExecute.Enabled = false;

                using (this.dbConverter = new DbConverter(source, target))
                {
                    this.dbConverter.Option.RenameTableChildren            = isTableExisted || this.rbSameDatabase.Checked;
                    this.dbConverter.Option.GenerateScriptMode             = scriptMode;
                    this.dbConverter.Option.BulkCopy                       = true;
                    this.dbConverter.Option.UseTransaction                 = true;
                    this.dbConverter.Option.ConvertComputeColumnExpression = true;
                    this.dbConverter.Option.IgnoreNotSelfForeignKey        = true;

                    this.dbConverter.Subscribe(this);

                    if (this.DatabaseType == DatabaseType.MySql)
                    {
                        source.DbInterpreter.Option.InQueryItemLimitCount = 2000;
                    }

                    if (this.DatabaseType != targetDatabaseType)
                    {
                        if (targetDatabaseType == DatabaseType.SqlServer)
                        {
                            target.DbOwner = "dbo";
                        }
                        else if (targetDatabaseType == DatabaseType.MySql)
                        {
                            target.DbInterpreter.Option.RemoveEmoji = true;
                        }
                    }
                    else
                    {
                        target.DbOwner = this.Table.Owner;
                    }

                    this.dbConverter.Option.SplitScriptsToExecute = true;

                    await this.dbConverter.Convert(schemaInfo);

                    if (!this.hasError && !this.dbConverter.HasError && !source.DbInterpreter.HasError && !target.DbInterpreter.HasError)
                    {
                        if (!this.dbConverter.CancelRequested)
                        {
                            MessageBox.Show("Copy finished", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                            MessageBox.Show("Task has been canceled.");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.hasError = true;
                this.HandleException(ex);
            }
            finally
            {
                this.btnExecute.Enabled = true;
            }
        }
        private async void Compare(DatabaseObjectType databaseObjectType)
        {
            DatabaseType dbType;

            if (this.useSourceConnector)
            {
                dbType = this.sourceDbProfile.DatabaseType;

                if (!this.sourceDbProfile.IsDbTypeSelected())
                {
                    MessageBox.Show("Please select a source database type.");
                    return;
                }

                if (!this.sourceDbProfile.IsProfileSelected())
                {
                    MessageBox.Show("Please select a source database profile.");
                    return;
                }

                if (!this.sourceDbConnectionInfo.IntegratedSecurity && string.IsNullOrEmpty(this.sourceDbConnectionInfo.Password))
                {
                    MessageBox.Show("Please specify password for the source database.");
                    this.sourceDbProfile.ConfigConnection(true);
                    return;
                }
            }
            else
            {
                dbType = this.sourceDatabaseType;
            }

            if (this.sourceDbConnectionInfo == null)
            {
                MessageBox.Show("Source connection is null.");
                return;
            }

            if (this.targetDbConnectionInfo == null)
            {
                MessageBox.Show("Target connection info is null.");
                return;
            }

            if (dbType != this.targetDbProfile.DatabaseType)
            {
                MessageBox.Show("Target database type must be same as source database type.");
                return;
            }

            if (this.sourceDbConnectionInfo.Server == this.targetDbConnectionInfo.Server && this.sourceDbConnectionInfo.Database == this.targetDbConnectionInfo.Database)
            {
                MessageBox.Show("Source database cannot be equal to the target database.");
                return;
            }

            this.btnCompare.Text    = "...";
            this.btnCompare.Enabled = false;

            try
            {
                DbInterpreterOption sourceOption = new DbInterpreterOption();
                DbInterpreterOption targetOption = new DbInterpreterOption();
                SchemaInfoFilter    sourceFilter = new SchemaInfoFilter()
                {
                    DatabaseObjectType = databaseObjectType
                };
                SchemaInfoFilter targetFilter = new SchemaInfoFilter()
                {
                    DatabaseObjectType = databaseObjectType
                };

                if (databaseObjectType.HasFlag(DatabaseObjectType.Table))
                {
                    sourceOption.GetTableAllObjects = true;
                    targetOption.GetTableAllObjects = true;
                }

                this.sourceInterpreter     = DbInterpreterHelper.GetDbInterpreter(dbType, this.sourceDbConnectionInfo, sourceOption);
                this.targetInterpreter     = DbInterpreterHelper.GetDbInterpreter(this.targetDbProfile.DatabaseType, this.targetDbConnectionInfo, targetOption);
                this.sourceScriptGenerator = DbScriptGeneratorHelper.GetDbScriptGenerator(this.sourceInterpreter);
                this.targetScriptGenerator = DbScriptGeneratorHelper.GetDbScriptGenerator(this.targetInterpreter);

                this.sourceInterpreter.Subscribe(this);
                this.targetInterpreter.Subscribe(this);

                this.sourceSchemaInfo = await this.sourceInterpreter.GetSchemaInfoAsync(sourceFilter);

                this.targetSchemaInfo = await this.targetInterpreter.GetSchemaInfoAsync(targetFilter);

                DbCompare dbCompare = new DbCompare(sourceSchemaInfo, targetSchemaInfo);

                this.Feedback("Begin to compare...");

                this.differences = dbCompare.Compare();

                this.Feedback("End compare.");

                this.LoadData();
            }
            catch (Exception ex)
            {
                string message = ExceptionHelper.GetExceptionDetails(ex);

                LogHelper.LogError(message);

                MessageBox.Show("Error:" + message);
            }
            finally
            {
                this.btnCompare.Text    = "Compare";
                this.btnCompare.Enabled = true;
            }
        }