Пример #1
0
        public Object DiffMatchPatch(string firstString, string secondString, float timeOut = 0)
        {
            //Garbage Collector Clearification
            GC.Collect();
            GC.WaitForPendingFinalizers();

            DateTime       timeStart = DateTime.Now;
            DiffMatchPatch dmp       = new DiffMatchPatch();

            dmp.DiffTimeout = timeOut;

            // Execute one reverse diff as a warmup.
            List <Diff> diff = dmp.DiffMain(firstString, secondString);

            return(new {
                CalculationTime = (DateTime.Now - timeStart),
                AllDifferences = diff,
                PrettyHtml = dmp.DiffPrettyHtml(diff)
            });
        }
Пример #2
0
        public bool Execute(MeterDataSet meterDataSet)
        {
            if (meterDataSet.Type != DataSetType.EmaxEventHis)
            {
                return(false);
            }

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                // get metadata for file
                FileInfo fi = new FileInfo(meterDataSet.FilePath);

                // read lines from file
                string[] data = File.ReadAllLines(meterDataSet.FilePath);

                // instantiate records object
                List <EMAXEventHisRecord> records = new List <EMAXEventHisRecord>();

                // retrieve last change for this file
                EmaxDiagnosticFileChanges lastChanges = new TableOperations <EmaxDiagnosticFileChanges>(connection).QueryRecord("LastWriteTime DESC", new RecordRestriction("MeterID = {0} AND FileName = {1}", meterDataSet.Meter.ID, fi.Name));

                // if record doesn't exist, use default
                if (lastChanges == null)
                {
                    lastChanges = new EmaxDiagnosticFileChanges();
                }

                // parse each line
                foreach (string line in data)
                {
                    if (line == string.Empty)
                    {
                        continue;
                    }
                    string[]           section   = line.Split(new[] { ". " }, StringSplitOptions.RemoveEmptyEntries);
                    EMAXEventHisRecord newRecord = new EMAXEventHisRecord();

                    // date has 2 spaces if date is a single digit to keep specific column width
                    string format = "ddd MMM d HH:mm:ss yyyy";
                    if (section[0].Contains("  "))
                    {
                        format = "ddd MMM  d HH:mm:ss yyyy";
                    }

                    newRecord.Line = line;
                    newRecord.Time = DateTime.ParseExact(section[0], format, CultureInfo.InvariantCulture);
                    if (newRecord.Time > TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")))
                    {
                        newRecord.Time  = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"));
                        newRecord.Line += ". MiMD Parsing Alarm: DFR time set in the future.\n";
                    }

                    newRecord.Version = section[1];
                    records.Add(newRecord);
                }


                // if no records, or if the last record is same or before record in database, stop.  There was probably an error.
                if (!records.Any() || records.Last().Time <= lastChanges.LastWriteTime)
                {
                    return(false);
                }

                List <EMAXEventHisRecord> newRecords = records.Where(x => x.Time > lastChanges.LastWriteTime).ToList();
                // instantiate new changes object
                EmaxDiagnosticFileChanges fileChanges = new EmaxDiagnosticFileChanges();

                // create new record
                fileChanges.MeterID       = meterDataSet.Meter.ID;
                fileChanges.FileName      = fi.Name;
                fileChanges.FileSize      = (int)(fi.Length / 1000);
                fileChanges.LastWriteTime = newRecords.Last().Time;
                fileChanges.Span          = (newRecords.Last().Time - newRecords.First().Time).Days;
                fileChanges.NewRecords    = newRecords.Count();
                fileChanges.Alarms        = 0;

                for (int i = 0; i < newRecords.Count; ++i)
                {
                    if (newRecords[i].Line.ToLower().Contains("operation alarm"))
                    {
                    }
                    else if (newRecords[i].Line.ToLower().Contains("offline. system offline"))
                    {
                        fileChanges.Alarms++;
                    }
                    else if (newRecords[i].Line.ToLower().Contains("buffer full"))
                    {
                        fileChanges.Alarms++;
                    }
                    else if (newRecords[i].Line.ToLower().Contains("error"))
                    {
                        fileChanges.Alarms++;
                    }
                    else if (newRecords[i].Line.ToLower().Contains("alarm"))
                    {
                        if (newRecords[i].Line.ToLower().Contains("time sync failed"))
                        {
                            if (newRecords.Where(x => x.Line.ToLower().Contains("system started") && newRecords[i].Time.Subtract(x.Time).TotalSeconds <= 60).Any())
                            {
                            }
                            else
                            {
                                fileChanges.Alarms++;
                            }
                        }
                        else
                        {
                            fileChanges.Alarms++;
                        }
                    }
                }


                // get html of new changes
                DiffMatchPatch dmp  = new DiffMatchPatch();
                List <Diff>    diff = dmp.DiffMain("", string.Join("\n", records.Where(x => x.Time > lastChanges.LastWriteTime).Select(x => x.Line)));
                dmp.DiffCleanupSemantic(diff);
                fileChanges.Html = dmp.DiffPrettyHtml(diff).Replace("&para;", "");

                // write new record to db
                meterDataSet.DiagnosticAlarms = fileChanges.Alarms;

                new TableOperations <EmaxDiagnosticFileChanges>(connection).AddNewRecord(fileChanges);
                return(true);
            }
        }
        public bool Execute(MeterDataSet meterDataSet)
        {
            if (meterDataSet.Type != DataSetType.AppStatus)
            {
                return(false);
            }

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                // get metadata for file
                FileInfo fi            = new FileInfo(meterDataSet.FilePath);
                DateTime lastWriteTime = TimeZoneInfo.ConvertTimeFromUtc(fi.LastWriteTime.ToUniversalTime(), TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"));
                // read lines from file
                string[] data = File.ReadAllLines(meterDataSet.FilePath);

                // instantiate records object
                AppStatusFileChanges newRecord = new AppStatusFileChanges();

                // retrieve last change for this file
                AppStatusFileChanges lastChanges = new TableOperations <AppStatusFileChanges>(connection).QueryRecord("LastWriteTime DESC", new RecordRestriction("MeterID = {0} AND FileName = {1}", meterDataSet.Meter.ID, fi.Name));

                // if record doesn't exist, use default
                if (lastChanges == null)
                {
                    lastChanges = new AppStatusFileChanges();
                }

                // if lastChanges LastWriteTime equals new LastWriteTime return
                if (lastChanges.LastWriteTime.ToString("MM/dd/yyyy HH:mm:ss") == lastWriteTime.ToString("MM/dd/yyyy HH:mm:ss"))
                {
                    return(false);
                }

                newRecord.MeterID       = meterDataSet.Meter.ID;
                newRecord.FileName      = fi.Name;
                newRecord.LastWriteTime = lastWriteTime;
                newRecord.FileSize      = (int)(fi.Length / 1000);
                newRecord.Text          = meterDataSet.Text;
                newRecord.Alarms        = 0;

                if (lastChanges.LastWriteTime > TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")))
                {
                    newRecord.LastWriteTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"));
                    newRecord.Alarms       += 1;
                    newRecord.Text         += "\nMiMD Parsing Alarm: DFR time set in the future.\n";
                }
                // parse each line
                foreach (string line in data)
                {
                    // if line is empty go to the next line
                    if (line == string.Empty)
                    {
                        continue;
                    }

                    string[] section = line.Split(new[] { "=" }, StringSplitOptions.RemoveEmptyEntries);

                    if (section[0].ToLower() == "recorder")
                    {
                        newRecord.Version = section[1];
                    }
                    else if (section[0].ToLower() == "dfr")
                    {
                        newRecord.DFR = section[1];
                        if (newRecord.DFR.ToLower() != "online")
                        {
                            newRecord.Alarms += 1;
                            newRecord.Text   += "\nMiMD Parsing Alarm: DFR not set to ONLINE.\n";
                        }
                    }
                    else if (section[0].ToLower() == "pc_time")
                    {
                        try
                        {
                            newRecord.PCTime = DateTime.ParseExact(section[1], "MM/dd/yyyy-HH:mm:ss", CultureInfo.InvariantCulture);
                        }
                        catch (Exception ex)
                        {
                            newRecord.PCTime  = DateTime.MinValue;
                            newRecord.Alarms += 1;
                            newRecord.Text   += "\nMiMD Parsing Alarm: Incorrect date format for PC_Time.\n";
                        }
                    }
                    else if (section[0].ToLower() == "time_mark_source")
                    {
                        newRecord.TimeMarkSource = section[1];
                        if (newRecord.TimeMarkSource.ToLower() == "irig-b")
                        {
                        }
                        else if (newRecord.TimeMarkSource.ToLower() == "pc")
                        {
                        }
                        else
                        {
                            newRecord.Alarms += 1;
                            newRecord.Text   += "\nMiMD Parsing Alarm: TIME_MARK_SOURCE not set to IRIG-B.\n";
                        }
                    }
                    else if (section[0].ToLower() == "time_mark_time")
                    {
                        try
                        {
                            newRecord.TimeMarkTime = DateTime.ParseExact(section[1], "MM/dd/yyyy-HH:mm:ss.ffffff", CultureInfo.InvariantCulture);

                            if (newRecord.TimeMarkTime.Subtract(newRecord.PCTime).TotalSeconds > 2)
                            {
                                newRecord.Alarms += 1;
                                newRecord.Text   += "\nMiMD Parsing Alarm: Time_Mark_Time and PC_Time difference greater than 2 seconds.";
                            }
                        }
                        catch (Exception ex)
                        {
                            newRecord.TimeMarkTime = DateTime.MinValue;
                            newRecord.Alarms      += 1;
                            newRecord.Text        += "\nMiMD Parsing Alarm: Incorrect date format for Time_Mark_Time.";
                        }
                    }
                    else if (section[0].ToLower() == "clock")
                    {
                        if (section[1].ToLower() == "sync(lock)")
                        {
                        }
                        else if (section[1].ToLower() == "unsync(unknown)" && newRecord.TimeMarkSource.ToLower() == "pc")
                        {
                            int count = connection.ExecuteScalar <int>(@"
                                with cte as 
                                (SELECT TOP 1 * FROM AppStatusFileChanges 
                                where meterid = {0} 
                                order by LastWriteTime desc)
                                SELECT COUNT(*) FROM cte WHERE Text LIKE '%TIME_MARK_SOURCE=PC%' AND Text LIKE '%Clock=UNSYNC(unknown)%'
                            ", meterDataSet.Meter.ID);

                            if (count > 0)
                            {
                                newRecord.Alarms += 1;
                                newRecord.Text   += "\nMiMD Parsing Alarm: Time_Mark_Source Set to PC and Clock set to UNSYNC(unknown) in consecutive files.\n";
                            }
                        }
                        else
                        {
                            newRecord.Alarms += 1;
                            newRecord.Text   += "\nMiMD Parsing Alarm: Clock not set to SYNC(lock).\n";
                        }
                    }
                    else if (section[0].ToLower() == "data_drive")
                    {
                        try
                        {
                            string[] values = section[1].Replace("GB", "").Split('/');
                            newRecord.DataDriveUsage = double.Parse(values[0]) / double.Parse(values[1]);
                        }
                        catch (Exception ex)
                        {
                            newRecord.DataDriveUsage = 0;
                            newRecord.Alarms        += 1;
                            newRecord.Text          += "\nMiMD Parsing Alarm: Incorrect format for Data_Drive.\n";
                        }
                    }
                    else if (section[0].ToLower() == "chassis_not_comm")
                    {
                        newRecord.Alarms += 1;
                        newRecord.Text   += "\nMiMD Parsing Alarm: CHASSIS_NOT_COMM field present.\n";
                    }
                    else if (section[0].ToLower() == "timemark")
                    {
                        // sometimes this lines ends in a comma, remove it
                        string timeString = section[1];

                        IEnumerable <string> times = timeString.Split(',').Where(x => !Regex.IsMatch(x, "\\s*") && x != string.Empty);
                        bool flag = times.Distinct().Count() > 1;

                        if (flag)
                        {
                            int count = connection.RetrieveData(@"
                                with cte as 
                                (SELECT TOP 14 * FROM AppStatusFileChanges 
                                where meterid = {0} 
                                order by LastWriteTime desc)
                                SELECT * FROM cte WHERE Text LIKE '%TimeMark values not equal%'
                            ", meterDataSet.Meter.ID).Rows.Count;

                            newRecord.Text += "\nMiMD Parsing Warning: TimeMark values not equal.\n";

                            if (count == 14)
                            {
                                newRecord.Alarms += 1;
                                newRecord.Text   += "\nMiMD Parsing Alarm: TimeMark values not equal in 15 consecutive files.\n";
                            }
                        }
                    }
                    else if (section[0].ToLower() == "dsp_board")
                    {
                        newRecord.DSPBoard = section[1];
                    }
                    else if (section[0].ToLower() == "dsp_revision")
                    {
                        newRecord.DSPRevision = section[1];
                    }
                    else if (section[0].ToLower().Contains("packet"))
                    {
                        newRecord.Packet = section[1];
                    }
                    else if (section[0].ToLower().Contains("recovery"))
                    {
                        newRecord.Recovery = section[1];
                    }
                    else if (section[0].ToLower() == "(>65c,c)")
                    {
                        newRecord.BoardTemp = section[1];
                    }
                    else if (section[0].ToLower() == "speedfan")
                    {
                        newRecord.SpeedFan = section[1].Replace("\"", "").Replace(" ", "");
                    }
                    else if (section[0].ToLower() == "alarmon" || section[0].ToLower() == "anfail")
                    {
                        newRecord.Alarms += 1;
                    }
                }


                // get html of new changes
                DiffMatchPatch dmp  = new DiffMatchPatch();
                List <Diff>    diff = dmp.DiffMain(lastChanges.Text ?? "", newRecord.Text);
                dmp.DiffCleanupSemantic(diff);
                newRecord.Html = dmp.DiffPrettyHtml(diff).Replace("&para;", "");

                // write new record to db
                meterDataSet.DiagnosticAlarms = newRecord.Alarms;
                new TableOperations <AppStatusFileChanges>(connection).AddNewRecord(newRecord);
                return(true);
            }
        }
        public bool Execute(MeterDataSet meterDataSet)
        {
            if (meterDataSet.Type != DataSetType.AppTrace)
            {
                return(false);
            }

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                // get metadata for file
                FileInfo fi = new FileInfo(meterDataSet.FilePath);

                // read lines from file
                string[] data = File.ReadAllLines(meterDataSet.FilePath);

                // instantiate records object
                List <AppTraceRecord> records = new List <AppTraceRecord>();

                // retrieve last change for this file
                AppTraceFileChanges lastChanges = new TableOperations <AppTraceFileChanges>(connection).QueryRecord("LastWriteTime DESC", new RecordRestriction("MeterID = {0} AND FileName = {1}", meterDataSet.Meter.ID, fi.Name));

                // if record doesn't exist, use default
                if (lastChanges == null)
                {
                    lastChanges = new AppTraceFileChanges();
                }

                // parse each line
                foreach (string line in data)
                {
                    if (line == string.Empty)
                    {
                        continue;
                    }
                    string[]       section   = line.Split(new[] { ". " }, StringSplitOptions.RemoveEmptyEntries);
                    AppTraceRecord newRecord = new AppTraceRecord();

                    // date has 2 spaces if date is a single digit to keep specific column width
                    string   regex   = @"(\[\d+\/\d+\/\d+\s\d+:\d+:\d+\s[AP]M\])";
                    string[] results = Regex.Split(line, regex);
                    string   format  = "[M/d/yyyy h:mm:ss tt]";

                    if (results.Length <= 1)
                    {
                        regex   = @"(\[\d+\/\d+\/\d+\])";
                        results = Regex.Split(line, regex);
                        format  = "[M/d/yyyy]";
                    }

                    newRecord.Line = line;
                    newRecord.Time = DateTime.ParseExact(results[1], format, CultureInfo.InvariantCulture);

                    if (newRecord.Time > TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")))
                    {
                        newRecord.Time  = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"));
                        newRecord.Line += ". MiMD Parsing Alarm: DFR time set in the future.\n";
                    }

                    newRecord.Description = results[2];
                    records.Add(newRecord);
                }

                // if no records, or if the last record is same or before record in database, stop.  There was probably an error.
                if (!records.Any() || records.Last().Time <= lastChanges.LastWriteTime)
                {
                    return(false);
                }

                // instantiate new changes object
                AppTraceFileChanges fileChanges   = new AppTraceFileChanges();
                List <string>       alarmKeyWords = new List <string> {
                    "unsync<invalid(no signal)>", "[alarmon]", "sync loss", "chassis comm. error", "disk full", "master comm. error", "dsp board temperature", "analog fail", "pc health", "offline", "time in future"
                };
                IEnumerable <AppTraceRecord> newRecords = records.Where(x => x.Time > lastChanges.LastWriteTime);
                // create new record
                fileChanges.MeterID       = meterDataSet.Meter.ID;
                fileChanges.FileName      = fi.Name;
                fileChanges.FileSize      = (int)(fi.Length / 1000);
                fileChanges.LastWriteTime = records.Last().Time;
                fileChanges.Span          = (records.Last().Time - records.First().Time).Days;
                fileChanges.NewRecords    = newRecords.Count();
                fileChanges.Alarms        = newRecords.Where(x => alarmKeyWords.Contains(x.Line.ToLower())).Count();

                if (records.Where(x => x.Line.ToLower().Contains("fault f")).Any())
                {
                    fileChanges.LastFaultTime = records.Where(x => x.Line.ToLower().Contains("fault f")).Last().Time;
                }
                else
                {
                    fileChanges.LastFaultTime = lastChanges.LastFaultTime;
                }

                fileChanges.FaultCount48hr = records.Where(x => x.Line.ToLower().Contains("fault f") && x.Time >= fileChanges.LastWriteTime.AddHours(-48)).Count();

                // get html of new changes
                DiffMatchPatch dmp  = new DiffMatchPatch();
                List <Diff>    diff = dmp.DiffMain("", string.Join("\n", records.Where(x => x.Time > lastChanges.LastWriteTime).Select(x => x.Line)));
                dmp.DiffCleanupSemantic(diff);
                fileChanges.Html = dmp.DiffPrettyHtml(diff).Replace("&para;", "");

                // write new record to db
                meterDataSet.DiagnosticAlarms = fileChanges.Alarms;
                new TableOperations <AppTraceFileChanges>(connection).AddNewRecord(fileChanges);
                return(true);
            }
        }
        public bool Execute(MeterDataSet meterDataSet)
        {
            if (meterDataSet.Type != DataSetType.BENConfig)
            {
                return(false);
            }

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                FileInfo fi = new FileInfo(meterDataSet.FilePath);

                DateTime lastWriteTime = DateTime.ParseExact(string.Join(",", fi.Name.Split(',').Take(2)), "yyMMdd,HHmmssfff", CultureInfo.InvariantCulture);
                // see if there is already a record that matches this file
                ConfigFileChanges configFileChanges = new TableOperations <ConfigFileChanges>(connection).QueryRecordWhere("MeterID = {0} AND FileName = {1} AND LastWriteTime = {2}", meterDataSet.Meter.ID, $"{meterDataSet.Meter.AssetKey}.cfg", lastWriteTime);

                // if a record already exists for this file skip it.  There was probably an error.
                if (configFileChanges != null)
                {
                    return(false);
                }
                configFileChanges = new ConfigFileChanges();

                // create new record
                configFileChanges.MeterID       = meterDataSet.Meter.ID;
                configFileChanges.FileName      = $"{meterDataSet.Meter.AssetKey}.cfg";
                configFileChanges.LastWriteTime = lastWriteTime;
                configFileChanges.Text          = meterDataSet.Text.Replace("\r", "");


                string[] data          = File.ReadAllLines(meterDataSet.FilePath);
                int[]    channelCounts = data[1].Split(',').Select(x => int.Parse(x.Replace("A", "").Replace("D", ""))).ToArray();
                int      totalChannels = channelCounts[0];

                // get portion of cfg file that contains channel mappings
                string relevantPortion = string.Join("\n", data.Take(2 + totalChannels));


                // get the previous record for this file
                ConfigFileChanges lastChanges = new TableOperations <ConfigFileChanges>(connection).QueryRecord("LastWriteTime DESC", new RecordRestriction("MeterID = {0} AND FileName = {1} AND LastWriteTime < {2}", meterDataSet.Meter.ID, $"{meterDataSet.Meter.AssetKey}.cfg", lastWriteTime));

                // if there were no previous records for this file
                if (lastChanges == null)
                {
                    lastChanges      = new ConfigFileChanges();
                    lastChanges.Text = configFileChanges.Text.Replace("\r", "");
                    // make diffs
                    DiffMatchPatch dmp  = new DiffMatchPatch();
                    List <Diff>    diff = dmp.DiffMain(relevantPortion, relevantPortion);

                    dmp.DiffCleanupSemantic(diff);
                    configFileChanges.Html    = dmp.DiffPrettyHtml(diff).Replace("&para;", "");
                    configFileChanges.Changes = 0;
                }
                else
                {
                    string[] data2          = lastChanges.Text.Split('\n');
                    int[]    channelCounts2 = data2[1].Split(',').Select(x => int.Parse(x.Replace("A", "").Replace("D", ""))).ToArray();
                    int      totalChannels2 = channelCounts2[0];

                    // get portion of cfg file that contains channel mappings
                    string relevantPortion2 = string.Join("\n", data2.Take(2 + totalChannels2));



                    // make diffs
                    DiffMatchPatch dmp   = new DiffMatchPatch();
                    List <Diff>    diff  = dmp.DiffMain(relevantPortion2, relevantPortion);
                    List <Patch>   patch = dmp.PatchMake(relevantPortion2, relevantPortion);

                    dmp.DiffCleanupSemantic(diff);
                    configFileChanges.Html    = dmp.DiffPrettyHtml(diff).Replace("&para;", "");
                    configFileChanges.Changes = patch.Count;

                    if (patch.Count == 0)
                    {
                        return(false);
                    }
                }

                // write new record to db
                meterDataSet.ConfigChanges = configFileChanges.Changes;

                new TableOperations <ConfigFileChanges>(connection).AddNewRecord(configFileChanges);
                return(true);
            }
        }
        public bool Execute(MeterDataSet meterDataSet)
        {
            if (meterDataSet.Type != DataSetType.Config)
            {
                return(false);
            }

            using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
            {
                FileInfo fi = new FileInfo(meterDataSet.FilePath);

                // see if there is already a record that matches this file
                ConfigFileChanges configFileChanges = new TableOperations <ConfigFileChanges>(connection).QueryRecordWhere("MeterID = {0} AND FileName = {1} AND LastWriteTime = {2}", meterDataSet.Meter.ID, fi.Name, fi.LastWriteTime);

                // if a record already exists for this file skip it.  There was probably an error.
                if (configFileChanges != null)
                {
                    return(false);
                }
                configFileChanges = new ConfigFileChanges();

                // create new record
                configFileChanges.MeterID       = meterDataSet.Meter.ID;
                configFileChanges.FileName      = fi.Name;
                configFileChanges.LastWriteTime = fi.LastWriteTime;
                configFileChanges.Text          = meterDataSet.Text;

                // get the previous record for this file
                ConfigFileChanges lastChanges = new TableOperations <ConfigFileChanges>(connection).QueryRecord("LastWriteTime DESC", new RecordRestriction("MeterID = {0} AND FileName = {1} AND LastWriteTime < {2}", meterDataSet.Meter.ID, fi.Name, fi.LastWriteTime));

                // if there were no previous records for this file, just diff it against itself because we need an intial record.
                if (lastChanges == null)
                {
                    lastChanges      = new ConfigFileChanges();
                    lastChanges.Text = meterDataSet.Text;
                    DiffMatchPatch dmp   = new DiffMatchPatch();
                    List <Diff>    diff  = dmp.DiffMain(lastChanges.Text, configFileChanges.Text);
                    List <Patch>   patch = dmp.PatchMake(lastChanges.Text, configFileChanges.Text);

                    dmp.DiffCleanupSemantic(diff);
                    configFileChanges.Html    = dmp.DiffPrettyHtml(diff).Replace("&para;", "");
                    configFileChanges.Changes = patch.Count;

                    // write new record to db
                    meterDataSet.ConfigChanges = configFileChanges.Changes;
                }
                else
                {
                    // make diffs
                    DiffMatchPatch dmp   = new DiffMatchPatch();
                    List <Diff>    diff  = dmp.DiffMain(lastChanges.Text, configFileChanges.Text);
                    List <Patch>   patch = dmp.PatchMake(lastChanges.Text, configFileChanges.Text);

                    if (patch.Count == 0)
                    {
                        return(false);
                    }

                    dmp.DiffCleanupSemantic(diff);
                    configFileChanges.Html    = dmp.DiffPrettyHtml(diff).Replace("&para;", "");
                    configFileChanges.Changes = patch.Count;

                    // write new record to db
                    meterDataSet.ConfigChanges = configFileChanges.Changes;
                }
                new TableOperations <ConfigFileChanges>(connection).AddNewRecord(configFileChanges);

                return(true);
            }
        }