public IEnumerable <IChange> Compare() { var changes = new List <IChange>(); var prevKeys = _PreviousSheet.Cast <IRow>().Select(_ => _.Key).ToArray(); var updatedKeys = _UpdatedSheet.Cast <IRow>().Select(_ => _.Key).ToArray(); changes.AddRange(updatedKeys.Except(prevKeys).Select(_ => new RowAdded(_UpdatedDefinition.Name, _))); changes.AddRange(prevKeys.Except(updatedKeys).Select(_ => new RowRemoved(_PreviousDefinition.Name, _))); var columns = _UpdatedDefinition.GetAllColumnNames().Select(_ => { var previousColumn = _PreviousDefinition.FindColumn(_); var newColumn = _UpdatedDefinition.FindColumn(_); if (!previousColumn.HasValue || !newColumn.HasValue) { throw new InvalidDataException(); } return(new ColumnMap { Name = _, PreviousIndex = previousColumn.Value, NewIndex = newColumn.Value }); }).ToArray(); var prevIsMulti = _PreviousSheet is IMultiSheet; var upIsMulti = _UpdatedSheet is IMultiSheet; if (prevIsMulti == upIsMulti) { if (prevIsMulti) { var prevMulti = (IMultiSheet)_PreviousSheet; var prevLang = _PreviousSheet.Header.AvailableLanguages; var upMulti = (IMultiSheet)_UpdatedSheet; var upLang = _UpdatedSheet.Header.AvailableLanguages; changes.AddRange(upLang.Except(prevLang).Select(_ => new SheetLanguageAdded(_UpdatedSheet.Name, _))); changes.AddRange( prevLang.Except(upLang) .Select(_ => new SheetLanguageRemoved(_PreviousDefinition.Name, _))); foreach (var lang in prevLang.Intersect(upLang)) { var prevSheet = prevMulti.GetLocalisedSheet(lang); var upSheet = upMulti.GetLocalisedSheet(lang); changes.AddRange(Compare(prevSheet, upSheet, lang, columns)); } } else { changes.AddRange(Compare(_PreviousSheet, _UpdatedSheet, Language.None, columns)); } } else { changes.Add(new SheetTypeChanged(_UpdatedDefinition.Name)); System.Console.Error.WriteLine("Type of sheet {0} has changed, unable to detect changes.", _UpdatedDefinition.Name); } return(changes); }
public IEnumerable <IChange> Compare() { List <IChange> changes = new List <IChange>(); int[] prevKeys = _PreviousSheet.Cast <IRow>().Select(_ => _.Key).ToArray(); int[] updatedKeys = _UpdatedSheet.Cast <IRow>().Select(_ => _.Key).ToArray(); changes.AddRange(updatedKeys.Except(prevKeys).Select(_ => new RowAdded(_UpdatedDefinition.Name, _))); changes.AddRange(prevKeys.Except(updatedKeys).Select(_ => new RowRemoved(_PreviousDefinition.Name, _))); ColumnMap[] columns = _UpdatedDefinition.GetAllColumnNames().Select(_ => { int?previousColumn = _PreviousDefinition.FindColumn(_); int?newColumn = _UpdatedDefinition.FindColumn(_); if (!previousColumn.HasValue || !newColumn.HasValue) { throw new InvalidDataException(); } return(new ColumnMap { Name = _, PreviousIndex = previousColumn.Value, NewIndex = newColumn.Value }); }).ToArray(); bool prevIsMulti = _PreviousSheet is IMultiSheet; bool upIsMulti = _UpdatedSheet is IMultiSheet; if (prevIsMulti == upIsMulti) { if (prevIsMulti) { IMultiSheet prevMulti = (IMultiSheet)_PreviousSheet; IEnumerable <Language> prevLang = _PreviousSheet.Header.AvailableLanguages; IMultiSheet upMulti = (IMultiSheet)_UpdatedSheet; IEnumerable <Language> upLang = _UpdatedSheet.Header.AvailableLanguages; changes.AddRange(upLang.Except(prevLang).Select(_ => new SheetLanguageAdded(_UpdatedSheet.Name, _))); changes.AddRange( prevLang.Except(upLang) .Select(_ => new SheetLanguageRemoved(_PreviousDefinition.Name, _))); foreach (Language lang in prevLang.Intersect(upLang)) { // Do not compare languages marked unavailable elsewhere. if (_unavailableLanguages.ContainsKey(lang)) { continue; } ISheet prevSheet = prevMulti.GetLocalisedSheet(lang); ISheet upSheet = upMulti.GetLocalisedSheet(lang); try { changes.AddRange(Compare(prevSheet, upSheet, lang, columns)); } catch (System.IO.FileNotFoundException) { // Usually caused by one language ahead of another // in patches, or that language data is not found. // Skip it and mark unavailable for other comparisons. _unavailableLanguages.TryAdd(lang, true); continue; } } } else { changes.AddRange(Compare(_PreviousSheet, _UpdatedSheet, Language.None, columns)); } } else { changes.Add(new SheetTypeChanged(_UpdatedDefinition.Name)); System.Console.Error.WriteLine("Type of sheet {0} has changed, unable to detect changes.", _UpdatedDefinition.Name); } return(changes); }