示例#1
0
 private Task <List <SchemaInfoTuple> > LoadSchemaFromFile(String path)
 {
     return(Task.Run(() =>
     {
         return SchemaAssistor.LoadSchemaInfos(path);
     }));
 }
示例#2
0
        private async void _tsmiSaveSchemaToFile_Click(object sender, EventArgs e)
        {
            var dialogResult = this._sfdSaveSchema.ShowDialog();

            if (dialogResult != DialogResult.OK)
            {
                return;
            }
            var savePath = this._sfdSaveSchema.FileName;

            //选择存储路径
            //补全结构信息
            //序列化到文件中
            this.EnableContol(false);
            try
            {
                List <SchemaInfoTuple> schemaInfos = this._schemaInfoTable.Values.ToList();
                switch (this.CurrentSchemaLoadType)
                {
                case SchemaLoadType.Connection:
                {
                    //补全所有尚未获取的元数据信息
                    foreach (var schemaInfo in schemaInfos)
                    {
                        if (schemaInfo.ColumnSchemas == null)
                        {
                            await this.CompleteSchema(schemaInfo);
                        }
                    }
                }
                break;

                case SchemaLoadType.SchemaFile:
                {
                }
                break;
                }
                this.ShowTipInformation("正在保存结构信息到文件中...");
                try
                {
                    await Task.Run(() =>
                    {
                        SchemaAssistor.SaveSchemaInfos(savePath, schemaInfos);
                    });

                    String message = "已保存当前的所有结构信息!";
                    MessageBox.Show(this, message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.ShowTipInformation(message);
                }
                catch (Exception exc)
                {
                    this.ShowTipInformation();
                    MessageBox.Show(this, "保存失败!" + exc.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            finally
            {
                this.EnableContol(true);
            }
        }
示例#3
0
        private async void Export()
        {
            this.EnableContol(false);
            try
            {
                IList <SchemaInfoTuple> schemaInfos = null;
                switch (this.CurrentSchemaLoadType)
                {
                case SchemaLoadType.Connection:
                {
                    //补全所有尚未获取的元数据信息
                    schemaInfos = new List <SchemaInfoTuple>();
                    foreach (var tableSchema in this.CheckedTableSchemas)
                    {
                        var schemaInfo = this._schemaInfoTable[tableSchema];
                        if (SchemaAssistor.IsRequiredCompleteSchema(schemaInfo))
                        {
                            this.ShowTipInformation(String.Format("正在补全 [{0}] 的结构信息...", schemaInfo.ObjectSchema.Name));
                            await this.CompleteSchema(schemaInfo);
                        }
                        schemaInfos.Add(schemaInfo);
                    }
                }
                break;

                case SchemaLoadType.SchemaFile:
                {
                    foreach (var tableSchema in this.CheckedTableSchemas)
                    {
                        var schemaInfo = this._schemaInfoTable[tableSchema];
                        schemaInfos.Add(schemaInfo);
                    }
                }
                break;
                }

                this.ShowTipInformation("正在导出结构信息...");
                //获取所有选择的导出定向器
                var targeters = this.GetCheckedExportTargeters();
                await Task.Run(() =>
                {
                    this.CurrentSchemaExporter.Export(targeters, schemaInfos, this.CurrentExportConfig);
                });


                String exportCompleted = "导出完成!";
                this.ShowTipInformation(exportCompleted);
                this.ShowDialogTipInformation(exportCompleted);
            }
            catch (Exception exc)
            {
                this.ShowErrorInformation("导出时发生异常!" + exc.Message);
                MessageBox.Show(exc.ToString(), Resources.Exception_Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                this.EnableContol(true);
            }
        }
        private async Task CompleteSchema(SchemaInfoTuple schemaInfo)
        {
            this.ShowTipInformation($"正在补全 [{schemaInfo.ObjectSchema.Name}] 的结构信息...");
            await Task.Run(() =>
            {
                SchemaAssistor.CompleteSchema(this.CurrentSchemaProvider, schemaInfo);
            });

            this.ShowTipInformation();
        }
示例#5
0
        private async Task CompareSchema()
        {
            this.ShowTipInformation("正在比较结构的差异...");
            try
            {
                List <SchemaDifferenceInfo> differenceInfos = null;
                try
                {
                    differenceInfos = await Task.Run(() => SchemaAssistor.CompareSchemaInfo(this.SourceSchemaInfos, this.TargetSchemaInfos));
                }
                catch (Exception exc)
                {
                    MessageBox.Show(this, "获取信息差异时发生错误!" + exc.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }


                this.ShowTipInformation("正在准备差异数据...");

                this.ObjectSchemaDifferenceTable = differenceInfos.ToDictionary(t => t.Schema, t => t.DifferenceType);
                //从源中获取目标结构中没有的信息
                var targetSchemaTable = this.TargetSchemaInfos.ToDictionary(t => t.ObjectSchema.Name);
                foreach (var schema in this.SourceSchemaInfos)
                {
                    if (!targetSchemaTable.ContainsKey(schema.ObjectSchema.Name))
                    {
                        this.TargetSchemaInfos.Add(schema);
                    }
                }


                try
                {
                    this.RenderingSchemaTree(this.SourceSchemaInfos, this._tvSourceSchema, false);
                    this.RenderingSchemaTree(this.TargetSchemaInfos, this._tvTargetSchema, true);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(this, "绘制差异时发生错误!" + exc.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(this, "比较差异信息时发生错误!" + exc.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            finally
            {
                this.ShowTipInformation();
            }
        }
 private async void _btnCompare_Click(object sender, EventArgs e)
 {
     if (this._schemaInfoTable.Count <= 0)
     {
         this.CanContinue = false;
         MessageBox.Show(this, "当前尚未加载结构信息!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
         return;
     }
     this.EnableContol(false);
     try
     {
         //补全所有尚未获取的元数据信息
         IList <SchemaInfoTuple> schemaInfos = this._schemaInfoTable.Values.ToList();
         foreach (var schemaInfo in schemaInfos)
         {
             if (SchemaAssistor.IsRequiredCompleteSchema(schemaInfo))
             {
                 this.ShowTipInformation(String.Format("正在补全 [{0}] 的结构信息...", schemaInfo.ObjectSchema.Name));
                 await this.CompleteSchema(schemaInfo);
             }
         }
         var dialogResult = MessageBox.Show(this, "信息补全完成,是否开始比较?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
         if (dialogResult != DialogResult.Yes)
         {
             return;
         }
         this.CanContinue = true;
         this.Close();
     }
     catch (Exception exc)
     {
         this.CanContinue = false;
         MessageBox.Show(this, "补全目标结构信息时发生异常,操作已停止!" + exc.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
     finally
     {
         this.EnableContol(true);
     }
 }
        private async void _tvSchema_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (_isLoadingColumnSchema)
            {
                return;
            }
            this._isLoadingColumnSchema = true;
            this._tvSchema.Enabled      = false;
            try
            {
                var node = e.Node;
                if (node.Parent != null)
                {
                    var schemaData = e.Node.Tag as IObjectSchema;
                    var schemaInfo = this._schemaInfoTable[schemaData];
                    if (SchemaAssistor.IsRequiredCompleteSchema(schemaInfo))
                    {
                        _waitColumnSchemaLoad.IsRolled = true;
                        _waitColumnSchemaLoad.Visible  = true;
                        try
                        {
                            await this.CompleteSchema(schemaInfo);
                        }
                        finally
                        {
                            _waitColumnSchemaLoad.IsRolled = false;
                            _waitColumnSchemaLoad.Visible  = false;
                        }
                    }

                    switch (schemaInfo.SchemaType)
                    {
                    case SchemaType.Table:
                    {
                        this._tabSchemaShow.SelectedTab       = this._pageColumnSchema;
                        this._pnlSchemaDefine.Visible         = false;
                        this._pnlColumnSchema.Visible         = true;
                        this._dgvColumnSchema.DataSource      = schemaInfo.ColumnSchemas;
                        this._dgvIndexColumnSchema.DataSource = schemaInfo.IndexColumnSchemas;
                    }
                    break;

                    case SchemaType.View:
                    {
                        this._pnlColumnSchema.Visible         = true;
                        this._pnlSchemaDefine.Visible         = false;
                        this._tabSchemaShow.SelectedTab       = this._pageColumnSchema;
                        this._dgvColumnSchema.DataSource      = schemaInfo.ColumnSchemas;
                        this._dgvIndexColumnSchema.DataSource = null;
                    }
                    break;

                    case SchemaType.Procedure:
                    {
                        this._pnlColumnSchema.Visible   = false;
                        this._pnlSchemaDefine.Visible   = true;
                        this._tabSchemaShow.SelectedTab = this._pageDefine;
                        this._richTbSchemaDefine.Text   = ((ProcedureSchema)schemaData).Definition;
                    }
                    break;

                    case SchemaType.Function:
                    {
                        this._pnlColumnSchema.Visible   = false;
                        this._pnlSchemaDefine.Visible   = true;
                        this._tabSchemaShow.SelectedTab = this._pageDefine;
                        this._richTbSchemaDefine.Text   = ((FunctionSchema)schemaData).Definition;
                    }
                    break;
                    }
                }
            }
            finally
            {
                _isLoadingColumnSchema = false;
                this._tvSchema.Enabled = true;
            }
        }
示例#8
0
        private async void CompareSchema(SchemaCompareTargetType targetType)
        {
            if (this.IsBusyingState(true))
            {
                return;
            }
            this.EnableContol(false);
            this.EnterBusyingState();
            try
            {
                //准备源结构信息
                #region 准备源结构信息
                //如果当前结构的加载方式是连接,则需要补全结构明细信息
                List <SchemaInfoTuple> sourceSchemaInfos = this._schemaInfoTable.Values.ToList();
                switch (this.CurrentSchemaLoadType)
                {
                case SchemaLoadType.Connection:
                {
                    var requriedResult = SchemaAssistor.IsRequiredCompleteSchema(sourceSchemaInfos);
                    if (requriedResult.requried)
                    {
                        var dialogResult = MessageBox.Show(this, "系统需要补全源结构信息以用于比较,是否继续?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                        if (dialogResult != DialogResult.Yes)
                        {
                            return;
                        }
                        foreach (var schema in requriedResult.requiredSchemas)
                        {
                            await this.CompleteSchema(schema);
                        }
                    }
                }
                break;

                case SchemaLoadType.SchemaFile:
                {
                }
                break;
                }

                #endregion

                //准备目标结构信息
                #region 准备目标结构信息
                List <SchemaInfoTuple> targetSchemaInfos = null;
                switch (targetType)
                {
                case SchemaCompareTargetType.SchemaFile:
                {
                    String targetSchemaFilePath = null;
                    var    selectResult         = this._ofdLoadSchema.ShowDialog();
                    if (selectResult != DialogResult.OK)
                    {
                        return;
                    }
                    targetSchemaFilePath = this._ofdLoadSchema.FileName;
                    try
                    {
                        this.ShowTipInformation("正在从文件中获取目标结构的信息...");
                        targetSchemaInfos = await this.LoadSchemaFromFile(targetSchemaFilePath);

                        if (targetSchemaInfos == null || targetSchemaInfos.Count == 0)
                        {
                            String message = "操作已停止,目标结构无有效信息!";
                            this.ShowTipInformation();
                            MessageBox.Show(this, message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return;
                        }
                        //开始比较
                        SchemaCompareForm compareForm = new SchemaCompareForm(sourceSchemaInfos, targetSchemaInfos);
                        //  String fileName = Path.GetFileName(targetSchemaFilePath);
                        compareForm.Text = $"与文件 [{targetSchemaFilePath}] 中的结构信息比较";
                        compareForm.Show(this);
                    }
                    catch (Exception exc)
                    {
                        String message = "操作已终止,目标结构加载失败!";
                        this.ShowErrorInformation(message);
                        MessageBox.Show(this, message + exc.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                break;

                case SchemaCompareTargetType.Connection:
                {
                    ConnectionSchemaForm schemaForm = new ConnectionSchemaForm();
                    schemaForm.ShowDialog(this);
                    if (!schemaForm.CanContinue)
                    {
                        this.ShowTipInformation("比较操作已取消!");
                        return;
                    }
                    targetSchemaInfos = schemaForm.SchemaInfoTuples;
                    SchemaCompareForm compareForm = new SchemaCompareForm(sourceSchemaInfos, targetSchemaInfos);
                    //  String fileName = Path.GetFileName(targetSchemaFilePath);
                    compareForm.Text = $"与从数据连接 [{ schemaForm.ConnectionString}] 获取的结构信息比较";
                    compareForm.Show(this);
                }
                break;
                }

                #endregion



                this.ShowTipInformation();
            }
            finally
            {
                this.EnableContol(true);
                this.LeaveBusyingState();
            }
        }
示例#9
0
        /// <summary>
        /// 比较两个结构信息集合,并返回之间的差异(包含相同的信息项)
        /// </summary>
        /// <remarks>两个集合中的信息的 <see cref="SchemaInfoTuple.SchemaType"/> 值需要相同 </remarks>
        /// <param name="sourceSchemas"></param>
        /// <param name="targetSchemas"></param>
        /// <returns></returns>
        public static List <SchemaDifferenceInfo> CompareSchemaInfo(IEnumerable <SchemaInfoTuple> sourceSchemas, IEnumerable <SchemaInfoTuple> targetSchemas)
        {
            List <SchemaDifferenceInfo> differenceInfos = new List <SchemaDifferenceInfo>();

            //层1:表、视图、函数、存储过程
            //层2:列、索引


            //比较层1
            var sourceTopSchemas = sourceSchemas.Select(t => t.ObjectSchema).ToList();
            var targetTopSchemas = targetSchemas.Select(t => t.ObjectSchema).ToList();

            var topSchemaDifferenceInfos     = CompareObjectSchemas(sourceTopSchemas, targetTopSchemas, out var topChangeFlag);
            var topSchemaDifferenceTypeTable = topSchemaDifferenceInfos.ToDictionary(t => t.Schema);

            differenceInfos.AddRange(topSchemaDifferenceInfos);

            Dictionary <String, SchemaInfoTuple> targetSchemaInfoTable = new Dictionary <String, SchemaInfoTuple>();

            foreach (var schema in targetSchemas)
            {
                targetSchemaInfoTable.Add(schema.ObjectSchema.Name, schema);
            }

            //比较层2
            foreach (var sourceSchema in sourceSchemas)
            {
                SchemaInfoTuple targetSchema = null;
                if (targetSchemaInfoTable.ContainsKey(sourceSchema.ObjectSchema.Name))
                {
                    targetSchema = targetSchemaInfoTable[sourceSchema.ObjectSchema.Name];
                }
                switch (sourceSchema.SchemaType)
                {
                case SchemaType.Table:
                {
                    //比较列
                    var columnDifferenceInfos = SchemaAssistor.CompareObjectSchemas(
                        sourceSchema.ColumnSchemas.Cast <IObjectSchema>(),
                        targetSchema?.ColumnSchemas.Cast <IObjectSchema>(), out var changeFlag);
                    differenceInfos.AddRange(columnDifferenceInfos);
                    //将变化中删除的列添加至目标结构中
                    var deletedColumnSchemas = columnDifferenceInfos.Where(t => t.DifferenceType == SchemaDifferenceType.Delete).Select(t => t.Schema).Cast <ColumnSchemaExtend>();
                    targetSchema?.ColumnSchemas.AddRange(deletedColumnSchemas);
                    //如果第二层的信息发生了变化,则信息所属的父结点也应该被标记为变化
                    //改变可能是删除、新增、修改。当改变是新增与修改时,表中一定会存在
                    if (changeFlag)
                    {
                        if (topSchemaDifferenceTypeTable[targetSchema.ObjectSchema].DifferenceType != SchemaDifferenceType.Delete)
                        {
                            topSchemaDifferenceTypeTable[targetSchema.ObjectSchema].DifferenceType = SchemaDifferenceType.Modify;
                        }
                    }
                    //比较索引
                    var indexDifferenceInfos = SchemaAssistor.CompareObjectSchemas(
                        sourceSchema.IndexColumnSchemas.Cast <IObjectSchema>(),
                        targetSchema?.IndexColumnSchemas.Cast <IObjectSchema>(), out changeFlag);
                    differenceInfos.AddRange(indexDifferenceInfos);
                    //将变化中删除的索引添加至目标结构中
                    var deletedIndexColumnSchemas = indexDifferenceInfos.Where(t => t.DifferenceType == SchemaDifferenceType.Delete).Select(t => t.Schema).Cast <IndexSchema>();
                    targetSchema?.IndexColumnSchemas.AddRange(deletedIndexColumnSchemas);
                    //如果第二层的信息发生了变化
                    if (changeFlag)
                    {
                        if (topSchemaDifferenceTypeTable[targetSchema.ObjectSchema].DifferenceType != SchemaDifferenceType.Delete)
                        {
                            topSchemaDifferenceTypeTable[targetSchema.ObjectSchema].DifferenceType = SchemaDifferenceType.Modify;
                        }
                    }
                }
                break;

                case SchemaType.View:
                {
                    //比较列
                    var columnDifferenceInfos = SchemaAssistor.CompareObjectSchemas(
                        sourceSchema.ColumnSchemas.Cast <IObjectSchema>(),
                        targetSchema?.ColumnSchemas.Cast <IObjectSchema>(), out var changeFlag);
                    differenceInfos.AddRange(columnDifferenceInfos);
                    //将变化中删除的列添加至目标结构中
                    var deletedIndexColumnSchemas = columnDifferenceInfos.Where(t => t.DifferenceType == SchemaDifferenceType.Delete).Select(t => t.Schema).Cast <ColumnSchemaExtend>();
                    targetSchema?.ColumnSchemas.AddRange(deletedIndexColumnSchemas);
                    //如果第二层的信息发生了变化
                    if (changeFlag)
                    {
                        if (topSchemaDifferenceTypeTable[targetSchema.ObjectSchema].DifferenceType != SchemaDifferenceType.Delete)
                        {
                            topSchemaDifferenceTypeTable[targetSchema.ObjectSchema].DifferenceType = SchemaDifferenceType.Modify;
                        }
                    }
                }
                break;

                case SchemaType.Procedure:
                {
                }
                break;

                case SchemaType.Function:
                {
                }
                break;
                }
            }

            //获取新增的结构信息,上面的遍历是以源结构为集合的,所以目标结构新增的信息是遍历不到的
            var addSchemaInfos = topSchemaDifferenceInfos.Where(t => t.DifferenceType == SchemaDifferenceType.Add);

            foreach (var addSchema in addSchemaInfos)
            {
                var targetSchema = targetSchemaInfoTable[addSchema.Schema.Name];
                switch (targetSchema.SchemaType)
                {
                case SchemaType.Table:
                {
                    //新增列
                    var columnDifferenceInfos = SchemaAssistor.CompareObjectSchemas(
                        null,
                        targetSchema?.ColumnSchemas.Cast <IObjectSchema>(), out var changeFlag);
                    differenceInfos.AddRange(columnDifferenceInfos);

                    //新增索引
                    var indexDifferenceInfos = SchemaAssistor.CompareObjectSchemas(
                        null,
                        targetSchema?.IndexColumnSchemas.Cast <IObjectSchema>(), out changeFlag);
                    differenceInfos.AddRange(indexDifferenceInfos);
                }
                break;

                case SchemaType.View:
                {
                    //新增列
                    var columnDifferenceInfos = SchemaAssistor.CompareObjectSchemas(
                        null,
                        targetSchema?.ColumnSchemas.Cast <IObjectSchema>(), out var changeFlag);
                    differenceInfos.AddRange(columnDifferenceInfos);
                }
                break;

                case SchemaType.Procedure:
                {
                    //
                }
                break;

                case SchemaType.Function:
                {
                    //
                }
                break;
                }
            }
            return(differenceInfos);
        }
示例#10
0
        /// <summary>
        /// 比较两个集合的结构信息,并指示两个集合中结构信息整体上是否有差异
        /// </summary>
        /// <param name="sourceSchemas"></param>
        /// <param name="targetSchemas"></param>
        /// <param name="changeFlag">结构信息整体上是否有差异</param>
        /// <returns></returns>
        private static List <SchemaDifferenceInfo> CompareObjectSchemas(IEnumerable <IObjectSchema> sourceSchemas, IEnumerable <IObjectSchema> targetSchemas, out Boolean changeFlag)
        {
            List <SchemaDifferenceInfo> differenceInfos = new List <SchemaDifferenceInfo>();

            changeFlag    = false;
            sourceSchemas = sourceSchemas ?? new List <IObjectSchema>();
            targetSchemas = targetSchemas ?? new List <IObjectSchema>();

            Dictionary <String, IObjectSchema> targetSchemaInfoTable = new Dictionary <String, IObjectSchema>();

            foreach (var schema in targetSchemas)
            {
                targetSchemaInfoTable.Add(schema.Name, schema);
            }

            foreach (var sourceSchema in sourceSchemas)
            {
                //此结构在比较目标中不存在,则标记为删除
                if (!targetSchemaInfoTable.ContainsKey(sourceSchema.Name))
                {
                    SchemaDifferenceInfo deletedInfo = new SchemaDifferenceInfo
                    {
                        Schema         = sourceSchema,
                        DifferenceType = SchemaDifferenceType.Delete
                    };
                    changeFlag = true;
                    differenceInfos.Add(deletedInfo);
                    continue;
                }
                //如果存在
                else
                {
                    var  targetSchema = targetSchemaInfoTable[sourceSchema.Name];
                    Type type         = sourceSchema.GetType();
                    SchemaDifferenceInfo differenceInfo = new SchemaDifferenceInfo();

                    differenceInfo.Schema         = targetSchema;
                    differenceInfo.DifferenceType = SchemaDifferenceType.None;

                    var equalizer = SchemaAssistor.GetSchemaEqualizer(type);

                    //若不相等则就是修改的
                    if (!equalizer.Equal(sourceSchema, targetSchema))
                    {
                        changeFlag = true;
                        differenceInfo.DifferenceType = SchemaDifferenceType.Modify;
                    }
                    differenceInfos.Add(differenceInfo);
                    targetSchemaInfoTable.Remove(targetSchema.Name);
                }
            }
            //剩余的都是新增的
            foreach (var schemaItem in targetSchemaInfoTable)
            {
                SchemaDifferenceInfo addInfo = new SchemaDifferenceInfo();
                addInfo.DifferenceType = SchemaDifferenceType.Add;
                addInfo.Schema         = schemaItem.Value;
                differenceInfos.Add(addInfo);
                changeFlag = true;
            }
            return(differenceInfos);
        }