Click here to Skip to main content
15,885,767 members
Articles / Database Development / SQL Server

A SQL Management Console for MSSQL 2000 & 2005, MySQL 5.0,...

Rate me:
Please Sign up or sign in to vote.
4.86/5 (14 votes)
20 Apr 2008Ms-PL4 min read 68.4K   2.5K   68  
An article on a SQL IDE for different type of RDBMS databases
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Configuration; // ConfigurationManager
using System.Collections.Specialized;
using System.Collections; // Hashtable
using MySql.Data.MySqlClient;
using System.Data.Common;

namespace SQLMgtConsole.Database
{
    public partial class MySQL : UserControl, IToolWindow
    {
        #region Common Interface
        UserControl IToolWindow.View
        {
            get { return this; }
        }

        string IToolWindow.Name
        {
            get { return "MySQL"; }
        }

        string IToolWindow.Description
        {
            get { return "MySQL"; }
        }

        Image IToolWindow.Image
        {
            get { return null; }
        }

        // for IDE to get the data
        public DataTable GetData(string strSelectedDB, string strQuery, ref Exception exErrHandle)
        {
            DataTable dtResult = new DataTable();
            if (!strSelectedDB.Trim().Equals("") && !strQuery.Trim().Equals(""))
            {
                dtResult = dbfac.fnExecDBCommonQuery(m_strDBProvider,
                                                        fnCreateConnection(strSelectedDB),
                                                        strQuery, ref exErrHandle);
            }
            else
            {
                MessageBox.Show("No query executed");
                exErrHandle = null;
                dtResult = null;
            }
            return dtResult;
        }
        #endregion

        #region Constants
        private const string SERVICETYPE_DB = "Databases";

        private const string SYSOBJ_FUNC = "Scalar function";
        private const string SYSOBJ_PROC = "Stored procedure";
        private const string SYSOBJ_SYSTBL = "System table";
        //private const string SYSOBJ_TBLFUNC = "Table function";
        private const string SYSOBJ_TRIG = "Trigger";
        private const string SYSOBJ_USRTBL = "User table";
        private const string SYSOBJ_VIEW = "View";

        private const string SECURITY_USER = "Users";
        //private const string SECURITY_ROLE = "Roles";

        private const string SYSCOL_COL = "Columns";
        private const string SYSCOL_KEY = "Keys";
        //private const string SYSCOL_CONS = "Constraints";
        private const string SYSCOL_TRIG = "Triggers";
        //private const string SYSCOL_IND = "Indexes";

        private const string SYSSEC_PRIV = "Privilege";

        private const string DEFAULT_DB = "information_schema";

        public enum TreeLevel
        {
            Instance = 0,
            ServiceFolder = 1,
            Database = 2,
            SysObjFolder = 3,
            SystemObject = 4,
            SysColFolder = 5,
            SystemColumn = 6
        }

        public enum IconType
        {
            Instance = 0,
            Database = 1,
            FolderClosed = 2,
            FolderOpen = 3,
            SysObject = 4,
            SysColumn = 5
        }
        #endregion

        #region Private variables
        private RichTextBox rtbMySQL; // from host control
        private ToolStripComboBox tscbMySQLDBList; // from host control

        private string m_strConnectionString = "";
        private string m_strDBProvider = "";
        private string m_strDBInstanceName = ""; // init at fnCreateConnection()
        private string m_strDBVersion = ""; // init at fnCreateConnection()
        Hashtable htSProc = new Hashtable(); // from App.Config

        // This is for actual node selected on mouse-up/right-click
        private TreeNode m_CurrSelectNode = new TreeNode();
        // This is to capture on mouse-click, since context menu is loaded before treeView's mouse-up event
        private int m_CurrNodeLevel = 0;

        private DBFactory dbfac = new DBFactory();
        #endregion

        public MySQL(Control ctrlHostRTB, object ctrlDBList,
                        string strConnString, string strDataProvider)
        {
            InitializeComponent();

            // Controls setting
            this.rtbMySQL = ctrlHostRTB as RichTextBox;
            this.tscbMySQLDBList = ctrlDBList as ToolStripComboBox;
            this.AutoScroll = true;
            // will be overriden by user options
            this.rtbMySQL.Font = new Font("Courier New", 10, FontStyle.Regular);
            // ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxmclictl/html/cdeb42e1-86e8-410c-ba46-18aec264ef5f.htm
            this.rtbMySQL.WordWrap = false;

            m_strDBProvider = strDataProvider;
            m_strConnectionString = strConnString;

            fnGetAppSettings();
            fnInitTreeView();
        } 

        private void fnGetAppSettings()
        {
            try
            {
                string[] arrStrAppKeys = ConfigurationManager.AppSettings.AllKeys;
                NameValueCollection nvcAppStgs = ConfigurationManager.AppSettings;
                for (int i = 0; i < nvcAppStgs.Count; i++)
                {
                    htSProc.Add(arrStrAppKeys[i], nvcAppStgs[i]);
                }
            }
            catch (ConfigurationErrorsException ConfigErr)
            {
                Console.WriteLine(ConfigErr.ToString());
            }
        }

        #region Construct MySQL treeview
        private void fnInitTreeView()
        {
            if (!m_strConnectionString.Trim().Equals(""))
            {
                // Assign the ImageList to the TreeView.
                tvMySQL.ImageList = ilPictures;
                // This is for database
                if (ilPictures.Images.Count >= (int)IconType.Instance + 1)
                {
                    // Set the TreeView control's default image and selected image indexes.
                    tvMySQL.ImageIndex = (int)IconType.Instance;
                    tvMySQL.SelectedImageIndex = (int)IconType.Instance;
                }

                MySqlConnection connSQL = fnCreateConnection("");

                if (connSQL != null)
                {
                    // To maintain performance while items are added one at a time to the TreeView, 
                    // call the BeginUpdate method. 
                    // The BeginUpdate method prevents the control from painting until the EndUpdate method is called.
                    tvMySQL.BeginUpdate();
                    tvMySQL.ShowPlusMinus = true;
                    // Level 0
                    tvMySQL.Nodes.Add(m_strDBInstanceName + " (" + m_strDBVersion + ")");
                    // Level 1 : Prepare for replication/notification
                    tvMySQL.Nodes[0].Nodes.Add(SERVICETYPE_DB);
                    tvMySQL.Nodes[0].Nodes[0].ImageIndex = (int)IconType.FolderClosed;
                    tvMySQL.Nodes[0].Nodes[0].SelectedImageIndex = (int)IconType.FolderClosed;
                    tvMySQL.EndUpdate();
                    tvMySQL.ContextMenuStrip = cmsRightClick;

                    fnAddDatabase(tvMySQL.Nodes[0].Nodes[0], false);
                }
            }
        }

        private void fnAddDatabase(TreeNode tnBaseNode, bool bRefresh)
        {
            // if it's the first time, force it to re-fill
            if (tnBaseNode.Nodes.Count == 0)
                bRefresh = true;

            if (bRefresh)
            {
                Exception exErrHandle = new Exception();
                DataTable dtAllDB = dbfac.fnExecDBCommonQuery(m_strDBProvider, fnCreateConnection(""), 
                                                                "SHOW DATABASES", ref exErrHandle);
                if (dtAllDB != null)
                {
                    tvMySQL.BeginUpdate();
                    foreach (DataRow drDatabase in dtAllDB.Rows)
                    {
                        // Level 2 : All DB
                        tnBaseNode.Nodes.Add(drDatabase["DATABASE"].ToString());
                    }
                    // assign icon
                    if (ilPictures.Images.Count >= (int)IconType.Database + 1)
                    {
                        foreach (TreeNode tnNode in tnBaseNode.Nodes)
                        {
                            tnNode.ImageIndex = (int)IconType.Database;
                            tnNode.SelectedImageIndex = (int)IconType.Database;
                        }
                    }
                    tvMySQL.EndUpdate();
                    // Update the available database on combobox
                    tscbMySQLDBList.BeginUpdate();
                    foreach (DataRow drDatabase in dtAllDB.Rows)
                    {
                        tscbMySQLDBList.Items.Add(drDatabase["DATABASE"].ToString());
                    }

                    // select the default system database
                    if (tscbMySQLDBList.Items.Count > 0)
                    {
                        if (tscbMySQLDBList.Items.Contains(DEFAULT_DB))
                            tscbMySQLDBList.SelectedIndex = tscbMySQLDBList.Items.IndexOf(DEFAULT_DB);
                        else
                            tscbMySQLDBList.SelectedIndex = 0;
                    }
                    tscbMySQLDBList.EndUpdate();
                }
            }
        }

        private void fnAddSysObjFolder(TreeNode tnBaseNode, bool bRefresh)
        {
            // if it's the first time, force it to re-fill
            if (tnBaseNode.Nodes.Count == 0)
                bRefresh = true;

            if (bRefresh)
            {
                // add folder to hold system objects 
                // Display a wait cursor while the TreeNodes are being created.
                Cursor.Current = Cursors.WaitCursor;

                tvMySQL.BeginUpdate();
                // Clear all children
                tnBaseNode.Nodes.Clear();
                // Level 3 : SysObj folder
                tnBaseNode.Nodes.Add(SYSOBJ_FUNC);
                tnBaseNode.Nodes.Add(SYSOBJ_PROC);
                tnBaseNode.Nodes.Add(SYSOBJ_SYSTBL);
                //tnBaseNode.Nodes.Add(SYSOBJ_TBLFUNC);
                tnBaseNode.Nodes.Add(SYSOBJ_TRIG);
                tnBaseNode.Nodes.Add(SYSOBJ_USRTBL);
                tnBaseNode.Nodes.Add(SYSOBJ_VIEW);
                tnBaseNode.Nodes.Add(SECURITY_USER);
                //tnBaseNode.Nodes.Add(SECURITY_ROLE);
                // Will be overwritten on treeview's AfterExpand & AfterCollapse events
                if (ilPictures.Images.Count >= (int)IconType.FolderClosed + 1)
                {
                    foreach (TreeNode tnNode in tnBaseNode.Nodes)
                    {
                        tnNode.ImageIndex = (int)IconType.FolderClosed;
                        tnNode.SelectedImageIndex = (int)IconType.FolderClosed;
                    }
                }
                tvMySQL.EndUpdate();
                // Reset the cursor to the default for all controls.
                Cursor.Current = Cursors.Default;
            }
        }

        private void fnChannelSysObj(TreeNode tnBaseNode, bool bRefresh)
        {
            switch (tnBaseNode.Text)
            {
                case SYSOBJ_USRTBL:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.TABLES " +
                                        " where Table_Schema = '" + tnBaseNode.Parent.Text + 
                                        "' and Table_Type in ('Base Table')",
                                        new string[] { "TABLE_NAME" },
                                        IconType.SysObject, false);
                    break;
                case SYSOBJ_VIEW:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.TABLES " +
                                        " where Table_Schema = '" + tnBaseNode.Parent.Text + 
                                        "' and Table_Type = 'View'",
                                        new string[] { "TABLE_NAME" },
                                        IconType.SysObject, false);
                    break;
                //----------------------------------------------------------------
                case SYSOBJ_FUNC:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.ROUTINES " +
                                        " where ROUTINE_Schema = '" + tnBaseNode.Parent.Text + 
                                        "' and ROUTINE_Type = 'FUNCTION'",
                                        new string[] { "SPECIFIC_NAME" },
                                        IconType.SysObject, false);
                    break;
                case SYSOBJ_PROC:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.ROUTINES " +
                                        " where ROUTINE_Schema = '" + tnBaseNode.Parent.Text + 
                                        "' and ROUTINE_Type = 'PROCEDURE'",
                                        new string[] { "SPECIFIC_NAME" },
                                        IconType.SysObject, false);
                    break;
                case SYSOBJ_SYSTBL:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.TABLES " +
                                        " where Table_Schema = '" + tnBaseNode.Parent.Text + 
                                        "' and Table_Type in ('SYSTEM VIEW')",
                                        new string[] { "TABLE_NAME" },
                                        IconType.SysObject, false);
                    break;
                //case SYSOBJ_TBLFUNC:
                //    strXType = "'TF'";
                //    break;
                case SYSOBJ_TRIG:
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select * from INFORMATION_SCHEMA.TRIGGERS " +
                                        " where TRIGGER_Schema = '" + tnBaseNode.Parent.Text + "' ",
                                        new string[] { "TRIGGER_NAME" },
                                        IconType.SysObject, false);
                    break;
                //----------------------------------------------------------------
                case SECURITY_USER:
                    // assume root user have the access of all tables
                    fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Text, bRefresh,
                                        "Select GRANTEE from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES " +
                                        "where TABLE_SCHEMA = '" + tnBaseNode.Parent.Text + "' " +
                                        "group by GRANTEE " +
                                        "UNION " +
                                        "SELECT CONCAT('''', usr.User, '''@''',  usr.Host, '''') as GRANTEE " +
                                        "FROM mysql.user usr where User = 'root'",
                                        new string[] { "GRANTEE" }, IconType.SysObject, false);
                    break;
                default:
                    break;
            }
        }

        private void fnAddSysObj_SysCol(TreeNode tnBaseNode, string strDBName, bool bRefresh,
                                        string strQuery, string[] arrStrFullName,
                                        IconType itIcon, bool bAddDescription)
        {
            // if it's the first time, force it to re-fill
            if (tnBaseNode.Nodes.Count == 0)
                bRefresh = true;

            if (bRefresh)
            {
                Exception exErrHandle = new Exception();
                DataTable dtSysObj = dbfac.fnExecDBCommonQuery(m_strDBProvider, fnCreateConnection(strDBName),
                                                                strQuery, ref exErrHandle);
                if (dtSysObj != null)
                {
                    // Display a wait cursor while the TreeNodes are being created.
                    Cursor.Current = Cursors.WaitCursor;

                    tvMySQL.BeginUpdate();
                    // Clear all children
                    tnBaseNode.Nodes.Clear();
                    // use generic to sort particular treenode instead of whole treeview
                    List<string> lstStrSortedNode = new List<string>();
                    // Level 4 : All System objects
                    foreach (DataRow drSysObj in dtSysObj.Rows)
                    {
                        string strNodeName = "";
                        if (arrStrFullName != null)
                        {
                            foreach (string strColumnName in arrStrFullName)
                            {
                                if (strNodeName.Trim().Equals(""))
                                {
                                    strNodeName = drSysObj[strColumnName].ToString();
                                }
                                else
                                {
                                    strNodeName = strNodeName + "." + drSysObj[strColumnName].ToString();
                                }
                            }
                        }
                        else
                        {
                            strNodeName = drSysObj["name"].ToString();
                        }

                        if (bAddDescription)
                        {
                            // Get the DataTable of a DataRow
                            DataTable dtFindColumn = drSysObj.Table;
                            if (dtFindColumn.Columns.IndexOf("COLUMN_NAME") > 0)
                            {
                                strNodeName = strNodeName + " (" + drSysObj["COLUMN_NAME"].ToString() + ")";
                            }
                            // For SYSSEC_PRIV
                            if (dtFindColumn.Columns.IndexOf("IS_GRANTABLE") > 0)
                            {
                                if (drSysObj["IS_GRANTABLE"].ToString().ToUpper().Equals("YES"))
                                {
                                    strNodeName = strNodeName + " (Grantable)";
                                }
                                else
                                {
                                    strNodeName = strNodeName + " (Not Grantable)";
                                }
                            }
                        }
                        lstStrSortedNode.Add(strNodeName);
                        //tnBaseNode.Nodes.Add(strNodeName);
                    }

                    lstStrSortedNode.Sort();
                    foreach (string item in lstStrSortedNode)
                    {
                        tnBaseNode.Nodes.Add(item.ToString());
                    }

                    // This is for SysObject
                    if (ilPictures.Images.Count >= (int)itIcon + 1)
                    {
                        foreach (TreeNode tnNode in tnBaseNode.Nodes)
                        {
                            tnNode.ImageIndex = (int)itIcon;
                            tnNode.SelectedImageIndex = (int)itIcon;
                        }
                    }

                    // Need to be sorted since TABLE_SCHEMA is important; Resource-hunger??
                    //tnBaseNode.Sort();
                    tvMySQL.EndUpdate();
                    // Reset the cursor to the default for all controls.
                    Cursor.Current = Cursors.Default;
                }
            }
        }

        private void fnAddSysColFolder(TreeNode tnBaseNode, bool bRefresh)
        {
            // if it's the first time, force it to re-fill
            if (tnBaseNode.Nodes.Count == 0)
                bRefresh = true;

            if (bRefresh)
            {
                // Level 5 : All SysColumns
                switch (tnBaseNode.Parent.Text)
                {
                    case SYSOBJ_USRTBL:
                        tvMySQL.BeginUpdate();
                        tnBaseNode.Nodes.Clear();

                        tnBaseNode.Nodes.Add(SYSCOL_COL);
                        tnBaseNode.Nodes.Add(SYSCOL_KEY);
                        //tnBaseNode.Nodes.Add(SYSCOL_CONS);
                        tnBaseNode.Nodes.Add(SYSCOL_TRIG);
                        //tnBaseNode.Nodes.Add(SYSCOL_IND);

                        if (ilPictures.Images.Count >= (int)IconType.FolderClosed + 1)
                        {
                            foreach (TreeNode tnNode in tnBaseNode.Nodes)
                            {
                                tnNode.ImageIndex = (int)IconType.FolderClosed;
                                tnNode.SelectedImageIndex = (int)IconType.FolderClosed;
                            }
                        }
                        tvMySQL.EndUpdate();
                        break;
                    //case SYSOBJ_VIEW:
                    //    break;
                    case SECURITY_USER:
                        tvMySQL.BeginUpdate();
                        tnBaseNode.Nodes.Clear();

                        tnBaseNode.Nodes.Add(SYSSEC_PRIV);

                        if (ilPictures.Images.Count >= (int)IconType.FolderClosed + 1)
                        {
                            foreach (TreeNode tnNode in tnBaseNode.Nodes)
                            {
                                tnNode.ImageIndex = (int)IconType.FolderClosed;
                                tnNode.SelectedImageIndex = (int)IconType.FolderClosed;
                            }
                        }
                        tvMySQL.EndUpdate();
                        break;
                    default:
                        break;
                }
            }
        }

        private void fnChannelSysCol(TreeNode tnBaseNode, bool bRefresh)
        {
            // if it's the first time, force it to re-fill
            if (tnBaseNode.Nodes.Count == 0)
                bRefresh = true;

            if (bRefresh)
            {
                // Already declare constant, no need .Trim().ToUpper()
                switch (tnBaseNode.Text)
                {
                    case SYSCOL_COL:
                        fnAddSysColumn(tnBaseNode, tnBaseNode.Parent.Parent.Parent.Text, bRefresh);
                        break;
                    case SYSCOL_KEY:
                        fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Parent.Parent.Text, bRefresh,
                                            "Select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE " +
                                            " where TABLE_SCHEMA = '" + tnBaseNode.Parent.Parent.Parent.Text + "'" +
                                            " and TABLE_NAME = '" + tnBaseNode.Parent.Text + "'",
                                            new string[] { "CONSTRAINT_NAME" }, IconType.SysColumn, true);
                        break;
                    //case SYSCOL_CONS:
                    //    break;
                    case SYSCOL_TRIG:
                        fnAddTrigIndex(tnBaseNode, tnBaseNode.Parent.Parent.Parent.Text, bRefresh);
                        break;
                    //case SYSCOL_IND:
                    //    break;
                    case SYSSEC_PRIV:
                        string strQuery = "";
                        if (tnBaseNode.Parent.Text.Equals("'root'@'localhost'") || tnBaseNode.Parent.Text.Equals("'root'@'%'"))
                        {
                            strQuery = "Select * from INFORMATION_SCHEMA.USER_PRIVILEGES " +
                                        " where GRANTEE = '" + tnBaseNode.Parent.Text.Replace("'", "''") + "'";
                        }
                        else
                        {
                            strQuery = "Select * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES " +
                                        " where TABLE_SCHEMA = '" + tnBaseNode.Parent.Parent.Parent.Text + "'" +
                                        " and GRANTEE = '" + tnBaseNode.Parent.Text.Replace("'", "''") + "'";
                        }
                        fnAddSysObj_SysCol(tnBaseNode, tnBaseNode.Parent.Parent.Parent.Text, bRefresh,
                                            strQuery, new string[] { "PRIVILEGE_TYPE" }, IconType.SysColumn, true);
                        break;
                    default:
                        break;
                }
            }
        }

        private void fnAddSysColumn(TreeNode tnBaseNode, string strDBName, bool bRefresh)
        {
            // if it's the first time, force it to re-fill
            if (tnBaseNode.Nodes.Count == 0)
                bRefresh = true;

            if (bRefresh)
            {
                string strNodeText = ""; 
                string strTableName = tnBaseNode.Parent.Text;
                Exception exErrHandle = new Exception();
                DataTable dtSystemColumn = dbfac.fnExecDBCommonQuery(m_strDBProvider, fnCreateConnection(strDBName),
                                                                        "SHOW COLUMNS FROM " + strDBName + "." + strTableName,
                                                                        ref exErrHandle);
                if (dtSystemColumn != null)
                {
                    tvMySQL.BeginUpdate();
                    tnBaseNode.Nodes.Clear();
                    // Level 6 : All System Columns
                    foreach (DataRow drSpecificSysCol in dtSystemColumn.Rows)
                    {
                        strNodeText = drSpecificSysCol["Field"].ToString() + " (" +
                                        drSpecificSysCol["TYPE"].ToString();

                        if (drSpecificSysCol["Key"].ToString().ToUpper().Equals("PRI"))
                        {
                            strNodeText = strNodeText + ", (PRI)";
                        }

                        if (drSpecificSysCol["NULL"].ToString().ToUpper().Equals("NO"))
                        {
                            strNodeText = strNodeText + ", not null)";
                        }
                        else
                        {
                            strNodeText = strNodeText + ", null)";
                        }
                        tnBaseNode.Nodes.Add(strNodeText);
                    }

                    if (ilPictures.Images.Count >= (int)IconType.SysColumn + 1)
                    {
                        foreach (TreeNode tnNode in tnBaseNode.Nodes)
                        {
                            tnNode.ImageIndex = (int)IconType.SysColumn;
                            tnNode.SelectedImageIndex = (int)IconType.SysColumn;
                        }
                    }
                    tvMySQL.EndUpdate();
                }
            }
        }

        private void fnAddTrigIndex(TreeNode tnBaseNode, string strDBName, bool bRefresh)
        {
            // if it's the first time, force it to re-fill
            if (tnBaseNode.Nodes.Count == 0)
                bRefresh = true;

            if (bRefresh)
            {
                string strNodeText = "";
                string strTableName = tnBaseNode.Parent.Text;
                Exception exErrHandle = new Exception();
                DataTable dtSystemColumn = dbfac.fnExecDBCommonQuery(m_strDBProvider, fnCreateConnection(strDBName),
                                                                        "SELECT * FROM INFORMATION_SCHEMA.TRIGGERS " 
                                                                        + " where Trigger_Schema = '" +strDBName + "'"
                                                                        + " and EVENT_OBJECT_TABLE = '" + strTableName + "'",
                                                                        ref exErrHandle);
                if (dtSystemColumn != null)
                {
                    tvMySQL.BeginUpdate();
                    tnBaseNode.Nodes.Clear();
                    // Level 6 : All Triggers
                    foreach (DataRow drSpecificSysCol in dtSystemColumn.Rows)
                    {
                        strNodeText = drSpecificSysCol["TRIGGER_NAME"].ToString() + " (" +
                                        drSpecificSysCol["ACTION_TIMING"].ToString() + ", " +
                                        drSpecificSysCol["EVENT_MANIPULATION"].ToString() + ")"; 
                         
                        tnBaseNode.Nodes.Add(strNodeText);
                    }

                    if (ilPictures.Images.Count >= (int)IconType.SysColumn + 1)
                    {
                        foreach (TreeNode tnNode in tnBaseNode.Nodes)
                        {
                            tnNode.ImageIndex = (int)IconType.SysColumn;
                            tnNode.SelectedImageIndex = (int)IconType.SysColumn;
                        }
                    }
                    tvMySQL.EndUpdate();
                }
            }
        }
        #endregion

        #region DB properties
        public MySqlConnection fnCreateConnection(string strDBName)
        {
            MySqlConnection sqlConnect = new MySqlConnection();
            try
            {
                DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
                // if search for a particular database
                if (!strDBName.Trim().Equals(""))
                {
                    builder.ConnectionString = m_strConnectionString + ";initial catalog=" + strDBName.Trim();
                }
                else
                {
                    builder.ConnectionString = m_strConnectionString;
                }
                sqlConnect = new MySqlConnection(builder.ConnectionString);
                // need to open conenction to get server version
                // just need to get once
                if (m_strDBInstanceName.Trim().Equals("") &&
                    m_strDBVersion.Trim().Equals("") && sqlConnect != null)
                {
                    sqlConnect.Open();
                    // Maybe this need to be retrieved only when needed
                    //m_strDBInstanceName = sqlConnect.WorkstationId;
                    m_strDBVersion = sqlConnect.ServerVersion;
                    sqlConnect.Close();
                }
            }
            catch (MySqlException mymsqlEx)
            {
                MessageBox.Show("mymsqlEx : " + mymsqlEx.Message + Environment.NewLine + mymsqlEx.StackTrace);
                sqlConnect = null;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ex : " + ex.Message + Environment.NewLine + ex.StackTrace);
                sqlConnect = null;
            }
            finally
            {

            }
            return sqlConnect;
        } 
        #endregion

        #region Control events
        private void tvMySQL_MouseUp(object sender, MouseEventArgs e)
        {
            // Show menu only if Right Mouse button is clicked
            if (e.Button == MouseButtons.Right)
            {
                // Point where mouse is clicked
                Point ptClick = new Point(e.X, e.Y);

                // Go to the node that the user clicked
                TreeNode node = tvMySQL.GetNodeAt(ptClick);
                if (node != null)
                {
                    m_CurrSelectNode = node;
                    // Highlight the node that the user clicked.
                    // The node is highlighted until the Menu is displayed on the screen
                    tvMySQL.SelectedNode = node;
                }
            }
        }

        private void tvMySQL_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            Console.WriteLine("e.Node from NodeMouseClick: " + e.Node.Text);
            // keep a copy for context-menu loading
            m_CurrNodeLevel = e.Node.Level;
            // Will fail to capture sometimes if user clicks on the plus sign; flicker if do in tvMSSQL_AfterExpand()
            if (e.Button == MouseButtons.Left)
            {
                switch (e.Node.Level)
                {
                    case (int)TreeLevel.ServiceFolder:
                        // add sysobj folder
                        foreach (TreeNode tnChild in e.Node.Nodes)
                        {
                            fnAddSysObjFolder(tnChild, false);
                        }
                        break;
                    case (int)TreeLevel.Database:
                        // add system object
                        foreach (TreeNode tnChild in e.Node.Nodes)
                        {
                            fnChannelSysObj(tnChild, false);
                        }
                        break;
                    case (int)TreeLevel.SysObjFolder:
                        // add syscol folder
                        foreach (TreeNode tnChild in e.Node.Nodes)
                        {
                            fnAddSysColFolder(tnChild, false);
                        }
                        break;
                    case (int)TreeLevel.SystemObject:
                        // get columns, PKs, constraints, triggers
                        foreach (TreeNode tnChild in e.Node.Nodes)
                        {
                            fnChannelSysCol(tnChild, false);
                        }
                        break;
                    default:
                        break;
                }
            }
            else if (e.Button == MouseButtons.Right)
            {
                m_CurrSelectNode = e.Node;
            }
        }

        private void tvMySQL_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.IsExpanded)
            {
                tvMySQL_NodeMouseClick(sender, e);
            }
        }

        private void tvMySQL_AfterCollapse(object sender, TreeViewEventArgs e)
        {
            // use closed Folder
            if (e.Node.Level == (int)TreeLevel.SysObjFolder
                || e.Node.Level == (int)TreeLevel.ServiceFolder
                || e.Node.Level == (int)TreeLevel.SysColFolder
                && !e.Node.IsExpanded
                && ilPictures.Images.Count >= (int)IconType.FolderClosed + 1)
            {
                e.Node.ImageIndex = (int)IconType.FolderClosed;
                e.Node.SelectedImageIndex = (int)IconType.FolderClosed;
            }
        }

        private void tvMySQL_AfterExpand(object sender, TreeViewEventArgs e)
        {
            Console.WriteLine("e.Node from AfterExpand: " + e.Node.Text);
            if (e.Node.Level == (int)TreeLevel.SysObjFolder
                || e.Node.Level == (int)TreeLevel.ServiceFolder
                || e.Node.Level == (int)TreeLevel.SysColFolder
                && e.Node.IsExpanded
                && ilPictures.Images.Count >= (int)IconType.FolderOpen + 1)
            {
                e.Node.ImageIndex = (int)IconType.FolderOpen;
                e.Node.SelectedImageIndex = (int)IconType.FolderOpen;
            }
        }
        #endregion

        #region Menu & Context-Menu
        private void cmsRightClick_Opening(object sender, CancelEventArgs e)
        {
            // Only PROC/FUNC/TBLFUNC/TRIG/VIEW need "ScriptToEditor" button
            if (m_CurrNodeLevel == (int)TreeLevel.SystemObject)
            {
                if (m_CurrSelectNode != null && m_CurrSelectNode.Parent != null
                    && m_CurrSelectNode.Parent.Text.Trim().Equals(SYSOBJ_PROC)
                    || m_CurrSelectNode.Parent.Text.Trim().Equals(SYSOBJ_FUNC)
                    || m_CurrSelectNode.Parent.Text.Trim().Equals(SYSOBJ_TRIG)
                    || m_CurrSelectNode.Parent.Text.Trim().Equals(SYSOBJ_VIEW))
                {
                    tsmiScriptToEditor.Visible = true;
                }
                else
                {
                    tsmiScriptToEditor.Visible = false;
                }
            }
            else
            {
                tsmiScriptToEditor.Visible = false;
            }
        }

        private void tsmiScriptToEditor_Click(object sender, EventArgs e)
        {
            if (m_CurrSelectNode != null)
            {
                string strQuery = "";
                switch (m_CurrSelectNode.Parent.Text)
                {
                    case SYSOBJ_FUNC:
                        strQuery = "Select ROUTINE_DEFINITION as Text from INFORMATION_SCHEMA.ROUTINES " +
                                    " where ROUTINE_SCHEMA = '" + m_CurrSelectNode.Parent.Parent.Text +
                                    "' and ROUTINE_TYPE = 'FUNCTION' " +
                                    "and ROUTINE_NAME = '" + m_CurrSelectNode.Text + "'";
                        break;
                    case SYSOBJ_PROC:
                        strQuery = "Select ROUTINE_DEFINITION as Text from INFORMATION_SCHEMA.ROUTINES " +
                                    " where ROUTINE_SCHEMA = '" + m_CurrSelectNode.Parent.Parent.Text + 
                                    "' and ROUTINE_TYPE = 'PROCEDURE' " +
                                    " and ROUTINE_NAME = '" + m_CurrSelectNode.Text + "'";
                        break;
                    //case SYSOBJ_TBLFUNC:
                    //    strXType = "TF";
                    //    break;
                    case SYSOBJ_TRIG:
                        strQuery = "Select ACTION_STATEMENT as Text from INFORMATION_SCHEMA.TRIGGERS " +
                                    " where TRIGGER_SCHEMA = '" + m_CurrSelectNode.Parent.Parent.Text +
                                    "' and TRIGGER_NAME = '" + m_CurrSelectNode.Text + "'";
                        break;
                    case SYSOBJ_VIEW:
                        strQuery = "SELECT VIEW_DEFINITION as Text FROM INFORMATION_SCHEMA.VIEWS " +
                                    " where TABLE_SCHEMA = '" + m_CurrSelectNode.Parent.Parent.Text + 
                                    "' and TABLE_NAME = '" + m_CurrSelectNode.Text + "'";
                        break;
                    default:
                        return;
                }

                Exception exErrHandle = new Exception();
                DataTable dtGetText = dbfac.fnExecDBCommonQuery(m_strDBProvider,
                                                                fnCreateConnection(m_CurrSelectNode.Parent.Parent.Text),
                                                                strQuery, ref exErrHandle);
                if (dtGetText != null)
                {
                    // should be one line only
                    StringBuilder sbContent = new StringBuilder();
                    String strLine = "";
                    foreach (DataRow drGetText in dtGetText.Rows)
                    {
                        strLine = drGetText["Text"].ToString();
                        if (!strLine.Trim().Equals(""))
                        {
                            sbContent.Append(strLine);
                        }
                    }
                    rtbMySQL.Text = sbContent.ToString();
                }
            }
        }

        private void tsmiRefresh_Click(object sender, EventArgs e)
        {
            //TODO : Solve the one in MSSQL first
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Software Developer
Malaysia Malaysia
My blog: http://start-coding.blogspot.com/

Comments and Discussions