protected string Repr(object value) { if (value == null) { return("null"); } Type t = value.GetType(); if (t == typeof(int[])) { return("[" + String.Join(",", value as int[]) + "]"); } var tsString = value as ITsString; if (tsString != null) { return(ConvertFdoToMongoTsStrings.TextFromTsString(tsString, _cache.WritingSystemFactory)); } var multi = value as IMultiAccessorBase; if (multi != null) { int[] writingSystemIds; try { writingSystemIds = multi.AvailableWritingSystemIds; } catch (NotImplementedException) { // It's probably a VirtualStringAccessor, which we can't handle. Punt. return(value.ToString()); } var sb = new System.Text.StringBuilder(); sb.Append("{ "); foreach (int ws in multi.AvailableWritingSystemIds) { sb.Append(ws); sb.Append(": "); sb.Append(ConvertFdoToMongoTsStrings.TextFromTsString(multi.get_String(ws), _cache.WritingSystemFactory)); sb.Append(", "); } sb.Append("}"); return(sb.ToString()); } return(value.ToString()); }
protected IDictionary <string, Tuple <string, string> > GetFdoDifferences( FdoCache cache, IDictionary <int, object> fieldValuesBeforeTest, IDictionary <int, object> fieldValuesAfterTest ) { IFwMetaDataCacheManaged mdc = cache.ServiceLocator.MetaDataCache; var fieldNamesThatShouldBeDifferent = new string[] { }; var fieldNamesToSkip = new string[] { // These are ComObject or SIL.FieldWorks.FDO.DomainImpl.VirtualStringAccessor instances, which we can't compare // "FullReferenceName", // "HeadWord", // "HeadWordRef", // "HeadWordReversal", // "LexSenseOutline", // "MLHeadWord", // "MLOwnerOutlineName", // "ReversalEntriesBulkText", // "ReversalName", }; var differencesByName = new Dictionary <string, Tuple <string, string> >(); // Tuple of (before, after) foreach (int flid in fieldValuesBeforeTest.Keys) { if (mdc.IsCustom(flid)) { continue; } string fieldName = mdc.GetFieldNameOrNull(flid); if (String.IsNullOrEmpty(fieldName)) { continue; } object valueBeforeTest = fieldValuesBeforeTest[flid]; object valueAfterTest = fieldValuesAfterTest[flid]; // Some fields, like DateModified, *should* be different if (fieldNamesThatShouldBeDifferent.Contains(fieldName) || fieldNamesToSkip.Contains(fieldName)) { continue; } if ((valueAfterTest == null && valueBeforeTest == null)) { continue; } if (mdc.GetFieldType(flid) == (int)CellarPropertyType.String) { // Might not need this, see below } // Arrays need to be compared specially Type valueType = valueBeforeTest.GetType(); if (valueType == typeof(int[])) { int[] before = valueBeforeTest as int[]; int[] after = valueAfterTest as int[]; if (before.SequenceEqual(after)) { continue; } } // So do TsString objects var tsStringBeforeTest = valueBeforeTest as ITsString; var tsStringAfterTest = valueAfterTest as ITsString; if (tsStringBeforeTest != null && tsStringAfterTest != null) { TsStringDiffInfo diffInfo = TsStringUtils.GetDiffsInTsStrings(tsStringBeforeTest, tsStringAfterTest); if (diffInfo != null) { differencesByName[fieldName] = new Tuple <string, string>( ConvertFdoToMongoTsStrings.TextFromTsString(tsStringBeforeTest, _cache.WritingSystemFactory), ConvertFdoToMongoTsStrings.TextFromTsString(tsStringAfterTest, _cache.WritingSystemFactory) ); } continue; } // So do multistrings var multiStrBeforeTest = valueBeforeTest as IMultiAccessorBase; var multiStrAfterTest = valueAfterTest as IMultiAccessorBase; if (multiStrBeforeTest != null && multiStrAfterTest != null) { int[] wsIds; try { wsIds = multiStrBeforeTest.AvailableWritingSystemIds; } catch (NotImplementedException) { // This is a VirtualStringAccessor, which we can't easily compare. Punt. continue; } foreach (int wsId in wsIds) { string beforeStr = ConvertFdoToMongoTsStrings.TextFromTsString(multiStrBeforeTest.get_String(wsId), _cache.WritingSystemFactory); string afterStr = ConvertFdoToMongoTsStrings.TextFromTsString(multiStrAfterTest.get_String(wsId), _cache.WritingSystemFactory); if (beforeStr != afterStr) { string wsStr = cache.WritingSystemFactory.GetStrFromWs(wsId); differencesByName[fieldName + ":" + wsStr] = new Tuple <string, string>(beforeStr, afterStr); } } continue; } if (valueBeforeTest.Equals(valueAfterTest)) { continue; } // if (Repr(valueBeforeTest) == Repr(valueAfterTest)) // continue; // This should catch TsStrings // If we get this far, they're different var diff = new Tuple <string, string>(Repr(fieldValuesBeforeTest[flid]), Repr(fieldValuesAfterTest[flid])); differencesByName[fieldName] = diff; } return(differencesByName); }