Ejemplo n.º 1
0
 /// <summary>
 /// Compare two schema changes, used for unit tests to compare expected and actual schema change objects
 /// </summary>
 /// <param name="toCompare">The schema change to compare to</param>
 /// <returns>True if all properties are the same, false otherwise</returns>
 public bool Equals(SchemaChange toCompare)
 {
     return(DdeID == toCompare.DdeID &&
            EventType == toCompare.EventType &&
            SchemaName == toCompare.SchemaName &&
            TableName == toCompare.TableName &&
            ColumnName == toCompare.ColumnName &&
            NewColumnName == toCompare.NewColumnName &&
            DataType.Equals(DataType, toCompare.DataType));
 }
Ejemplo n.º 2
0
        public void TestEquals()
        {
            SchemaChange one = new SchemaChange(1, SchemaChangeType.Add, "sname", "tname", "cname", "ncname");
            SchemaChange two = new SchemaChange(1, SchemaChangeType.Add, "sname", "tname", "cname", "ncname");
            Assert.True(one.Equals(two));

            two = new SchemaChange(1, SchemaChangeType.Drop, "sname", "tname", "cname", "ncname");

            Assert.False(one.Equals(two));
            two = new SchemaChange(1, SchemaChangeType.Add, "asdf", "tname", "cname", "ncname");

            Assert.False(one.Equals(two));
            two = new SchemaChange(1, SchemaChangeType.Add, "sname", "tname", "asdf", "ncname");
            Assert.False(one.Equals(two));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Parse XML EVENTDATA and create zero or more SchemaChange objects from that
        /// </summary>
        /// <param name="tables">Array of table configuration objects</param>
        /// <param name="dbName">Database for retrieving data type info</param>
        public List<SchemaChange> Parse(IEnumerable<TableConf> tables, IDataUtils dataUtils, string dbName)
        {
            var schemaChanges = new List<SchemaChange>();
            string columnName;
            string tableName;
            SchemaChangeType changeType;
            DataType dataType;
            SchemaChange sc;
            string newColumnName;
            XmlNode node;
            var xml = new XmlDocument();
            xml.LoadXml(EventData);
            if (xml == null) {
                Console.WriteLine("XML failed to load");
                Console.WriteLine(EventData);
            }

            string eventType = xml.SelectSingleNode("EVENT_INSTANCE/EventType").InnerText;

            if (eventType == "ALTER_TABLE") {
                node = xml.SelectSingleNode("EVENT_INSTANCE/AlterTableActionList");
            } else if (eventType == "RENAME") {
                node = xml.SelectSingleNode("EVENT_INSTANCE/Parameters");
            } else {
                //this is a DDL event type that we don't care about publishing, so ignore it
                return schemaChanges;
            }

            if (node == null) {
                //we'll get here on events that do an ALTER_TABLE but don't change any columns,
                //such as "alter table enable change_tracking"
                return schemaChanges;
            }

            if (node.FirstChild.Name == "Param") {
                tableName = xml.SelectSingleNode("/EVENT_INSTANCE/TargetObjectName").InnerText;
            } else {
                tableName = xml.SelectSingleNode("/EVENT_INSTANCE/ObjectName").InnerText;
            }

            string schemaName = xml.SelectSingleNode("/EVENT_INSTANCE/SchemaName").InnerText;

            //String.Compare method returns 0 if the strings are equal, the third "true" flag is for a case insensitive comparison
            //Get table config object
            TableConf t = tables.SingleOrDefault(item => String.Compare(item.Name, tableName, ignoreCase: true) == 0);

            if (t == null) {
                //the DDL event applies to a table not in our so we just ignore it
                return schemaChanges;
            }

            switch (node.FirstChild.Name) {
                case "Param":
                    changeType = SchemaChangeType.Rename;
                    columnName = xml.SelectSingleNode("/EVENT_INSTANCE/ObjectName").InnerText;
                    newColumnName = xml.SelectSingleNode("/EVENT_INSTANCE/NewObjectName").InnerText;
                    if (t.ColumnList == null || t.ColumnList.Contains(columnName, StringComparer.OrdinalIgnoreCase)) {
                        sc = new SchemaChange(DdeID, changeType, schemaName, tableName, columnName, newColumnName);
                        schemaChanges.Add(sc);
                    }
                    break;
                case "Alter":
                    changeType = SchemaChangeType.Modify;
                    foreach (XmlNode xColumn in xml.SelectNodes("/EVENT_INSTANCE/AlterTableActionList/Alter/Columns/Name")) {
                        columnName = xColumn.InnerText;
                        if (t.ColumnList == null || t.ColumnList.Contains(columnName, StringComparer.OrdinalIgnoreCase)) {
                            try {
                                dataType = ParseDataType(dataUtils.GetDataType(dbName, tableName, schemaName, columnName));
                                sc = new SchemaChange(DdeID, changeType, schemaName, tableName, columnName, null, dataType);
                                schemaChanges.Add(sc);
                            } catch (DoesNotExistException) {
                                //if we get a does not exist exception, it generally means the column was created and then dropped,
                                //which is ok.
                                break;
                            }
                        }
                    }
                    break;
                case "Create":
                    changeType = SchemaChangeType.Add;
                    tableName = xml.SelectSingleNode("/EVENT_INSTANCE/ObjectName").InnerText;
                    foreach (XmlNode xColumn in xml.SelectNodes("/EVENT_INSTANCE/AlterTableActionList/Create/Columns/Name")) {
                        columnName = xColumn.InnerText;
                        //if column list is specified, only publish schema changes if the column is already in the list. we don't want
                        //slaves adding a new column that we don't plan to publish changes for.
                        //if column list is null, we want changes associated with all columns.
                        if (t.ColumnList == null || t.ColumnList.Contains(columnName, StringComparer.OrdinalIgnoreCase)) {
                            try {
                                var type = dataUtils.GetDataType(dbName, tableName, schemaName, columnName);
                                dataType = ParseDataType(type);
                                sc = new SchemaChange(DdeID, changeType, schemaName, tableName, columnName, null, dataType);
                                schemaChanges.Add(sc);
                            } catch (DoesNotExistException) {
                                //if we get a does not exist exception, it generally means the column was created and then dropped,
                                //which is ok.
                                break;
                            }
                        }
                    }
                    break;
                case "Drop":
                    changeType = SchemaChangeType.Drop;
                    tableName = xml.SelectSingleNode("/EVENT_INSTANCE/ObjectName").InnerText;
                    foreach (XmlNode xColumn in xml.SelectNodes("/EVENT_INSTANCE/AlterTableActionList/Drop/Columns/Name")) {
                        columnName = xColumn.InnerText;
                        if (t.ColumnList == null || t.ColumnList.Contains(columnName, StringComparer.OrdinalIgnoreCase)) {
                            sc = new SchemaChange(DdeID, changeType, schemaName, tableName, columnName, null, null);
                            schemaChanges.Add(sc);
                        }
                    }
                    break;
            }
            return schemaChanges;
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Compare two schema changes, used for unit tests to compare expected and actual schema change objects
 /// </summary>
 /// <param name="toCompare">The schema change to compare to</param>
 /// <returns>True if all properties are the same, false otherwise</returns>
 public bool Equals(SchemaChange toCompare)
 {
     return (DdeID == toCompare.DdeID
         && EventType == toCompare.EventType
         && SchemaName == toCompare.SchemaName
         && TableName == toCompare.TableName
         && ColumnName == toCompare.ColumnName
         && NewColumnName == toCompare.NewColumnName
         && DataType.Equals(DataType, toCompare.DataType));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Parse XML EVENTDATA and create zero or more SchemaChange objects from that
        /// </summary>
        /// <param name="tables">Array of table configuration objects</param>
        /// <param name="dbName">Database for retrieving data type info</param>
        public List <SchemaChange> Parse(IEnumerable <TableConf> tables, IDataUtils dataUtils, string dbName)
        {
            var              schemaChanges = new List <SchemaChange>();
            string           columnName;
            string           tableName;
            SchemaChangeType changeType;
            DataType         dataType;
            SchemaChange     sc;
            string           newColumnName;
            XmlNode          node;
            var              xml = new XmlDocument();

            xml.LoadXml(EventData);
            if (xml == null)
            {
                Console.WriteLine("XML failed to load");
                Console.WriteLine(EventData);
            }

            string eventType = xml.SelectSingleNode("EVENT_INSTANCE/EventType").InnerText;

            if (eventType == "ALTER_TABLE")
            {
                node = xml.SelectSingleNode("EVENT_INSTANCE/AlterTableActionList");
            }
            else if (eventType == "RENAME")
            {
                node = xml.SelectSingleNode("EVENT_INSTANCE/Parameters");
            }
            else
            {
                //this is a DDL event type that we don't care about publishing, so ignore it
                return(schemaChanges);
            }

            if (node == null)
            {
                //we'll get here on events that do an ALTER_TABLE but don't change any columns,
                //such as "alter table enable change_tracking"
                return(schemaChanges);
            }

            if (node.FirstChild.Name == "Param")
            {
                tableName = xml.SelectSingleNode("/EVENT_INSTANCE/TargetObjectName").InnerText;
            }
            else
            {
                tableName = xml.SelectSingleNode("/EVENT_INSTANCE/ObjectName").InnerText;
            }

            string schemaName = xml.SelectSingleNode("/EVENT_INSTANCE/SchemaName").InnerText;

            //String.Compare method returns 0 if the strings are equal, the third "true" flag is for a case insensitive comparison
            //Get table config object
            TableConf t = tables.SingleOrDefault(item => String.Compare(item.Name, tableName, ignoreCase: true) == 0);

            if (t == null)
            {
                //the DDL event applies to a table not in our so we just ignore it
                return(schemaChanges);
            }

            switch (node.FirstChild.Name)
            {
            case "Param":
                changeType    = SchemaChangeType.Rename;
                columnName    = xml.SelectSingleNode("/EVENT_INSTANCE/ObjectName").InnerText;
                newColumnName = xml.SelectSingleNode("/EVENT_INSTANCE/NewObjectName").InnerText;
                if (t.ColumnList == null || t.ColumnList.Contains(columnName, StringComparer.OrdinalIgnoreCase))
                {
                    sc = new SchemaChange(DdeID, changeType, schemaName, tableName, columnName, newColumnName);
                    schemaChanges.Add(sc);
                }
                break;

            case "Alter":
                changeType = SchemaChangeType.Modify;
                foreach (XmlNode xColumn in xml.SelectNodes("/EVENT_INSTANCE/AlterTableActionList/Alter/Columns/Name"))
                {
                    columnName = xColumn.InnerText;
                    if (t.ColumnList == null || t.ColumnList.Contains(columnName, StringComparer.OrdinalIgnoreCase))
                    {
                        try {
                            dataType = DataType.ParseDataType(dataUtils.GetDataType(dbName, tableName, schemaName, columnName));
                            sc       = new SchemaChange(DdeID, changeType, schemaName, tableName, columnName, null, dataType);
                            schemaChanges.Add(sc);
                        } catch (DoesNotExistException) {
                            //if we get a does not exist exception, it generally means the column was created and then dropped,
                            //which is ok.
                            break;
                        }
                    }
                }
                break;

            case "Create":
                changeType = SchemaChangeType.Add;
                tableName  = xml.SelectSingleNode("/EVENT_INSTANCE/ObjectName").InnerText;
                foreach (XmlNode xColumn in xml.SelectNodes("/EVENT_INSTANCE/AlterTableActionList/Create/Columns/Name"))
                {
                    columnName = xColumn.InnerText;
                    //if column list is specified, only publish schema changes if the column is already in the list. we don't want
                    //slaves adding a new column that we don't plan to publish changes for.
                    //if column list is null, we want changes associated with all columns.
                    if (t.ColumnList == null || t.ColumnList.Contains(columnName, StringComparer.OrdinalIgnoreCase))
                    {
                        try {
                            var type = dataUtils.GetDataType(dbName, tableName, schemaName, columnName);
                            dataType = DataType.ParseDataType(type);
                            sc       = new SchemaChange(DdeID, changeType, schemaName, tableName, columnName, null, dataType);
                            schemaChanges.Add(sc);
                        } catch (DoesNotExistException) {
                            //if we get a does not exist exception, it generally means the column was created and then dropped,
                            //which is ok.
                            break;
                        }
                    }
                }
                break;

            case "Drop":
                changeType = SchemaChangeType.Drop;
                tableName  = xml.SelectSingleNode("/EVENT_INSTANCE/ObjectName").InnerText;
                foreach (XmlNode xColumn in xml.SelectNodes("/EVENT_INSTANCE/AlterTableActionList/Drop/Columns/Name"))
                {
                    columnName = xColumn.InnerText;
                    if (t.ColumnList == null || t.ColumnList.Contains(columnName, StringComparer.OrdinalIgnoreCase))
                    {
                        sc = new SchemaChange(DdeID, changeType, schemaName, tableName, columnName, null, null);
                        schemaChanges.Add(sc);
                    }
                }
                break;
            }
            return(schemaChanges);
        }