/// <summary> /// Checks if something in the Arary has changed, if yes, stores the change /// </summary> /// <param name="nnoi1"> The first Object meta representation (nnoi = NonNativeObjectInfo) </param> /// <param name="nnoi2"> The second object meta representation </param> /// <param name="fieldId"> The field index that this collection represents </param> /// <param name="aoi1"> The Meta representation of the array 1 (aoi = ArraybjectInfo) </param> /// <param name="aoi2"> The Meta representation of the array 2 </param> /// <param name="objectRecursionLevel"> </param> /// <returns> true if the 2 array representations are different </returns> private bool ManageArrayChanges(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int fieldId, ArrayObjectInfo aoi1, ArrayObjectInfo aoi2, int objectRecursionLevel) { var array1 = aoi1.GetArray(); var array2 = aoi2.GetArray(); if (array1.Length != array2.Length) { var buffer = new StringBuilder(); buffer.Append("Array size has changed oldsize=").Append(array1.Length).Append("/newsize=").Append( array2.Length); StoreChangedObject(nnoi1, nnoi2, fieldId, aoi1, aoi2, buffer.ToString(), objectRecursionLevel); return(true); } for (var i = 0; i < array1.Length; i++) { var value1 = (AbstractObjectInfo)array1[i]; var value2 = (AbstractObjectInfo)array2[i]; var localHasChanged = HasChanged(value1, value2, objectRecursionLevel); if (!localHasChanged) { continue; } _nbChanges++; return(true); } return(false); }
/// <summary>Checks if something in the Arary has changed, if yes, stores the change</summary> /// <param name="nnoi1"> /// The first Object meta representation (nnoi = /// NonNativeObjectInfo) /// </param> /// <param name="nnoi2">The second object meta representation</param> /// <param name="fieldIndex">The field index that this collection represents</param> /// <param name="aoi1">The Meta representation of the array 1 (aoi = ArraybjectInfo)</param> /// <param name="aoi2">The Meta representation of the array 2</param> /// <param name="objectRecursionLevel"></param> /// <returns>true if the 2 array representations are different</returns> private bool ManageArrayChanges(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int fieldId , ArrayObjectInfo aoi1, ArrayObjectInfo aoi2, int objectRecursionLevel) { object[] array1 = aoi1.GetArray(); object[] array2 = aoi2.GetArray(); if (array1.Length != array2.Length) { System.Text.StringBuilder buffer = new System.Text.StringBuilder(); buffer.Append("Array size has changed oldsize=").Append(array1.Length).Append("/newsize=" ).Append(array2.Length); StoreChangedObject(nnoi1, nnoi2, fieldId, aoi1, aoi2, buffer.ToString(), objectRecursionLevel ); supportInPlaceUpdate = false; return(true); } AbstractObjectInfo value1 = null; AbstractObjectInfo value2 = null; // check if this array supports in place update bool localSupportInPlaceUpdate = ODBType.HasFixSize (aoi2.GetComponentTypeId()); int index = 0; bool hasChanged = false; try { for (int i = 0; i < array1.Length; i++) { value1 = (AbstractObjectInfo)array1[i]; value2 = (AbstractObjectInfo)array2[i]; bool localHasChanged = this.HasChanged(value1, value2, objectRecursionLevel); if (localHasChanged) { StoreArrayChange(nnoi1, fieldId, i, value2, localSupportInPlaceUpdate); if (localSupportInPlaceUpdate) { hasChanged = true; } else { hasChanged = true; return(hasChanged); } } index++; } } finally { if (hasChanged && !localSupportInPlaceUpdate) { supportInPlaceUpdate = false; } } return(hasChanged); }
private AbstractObjectInfo GetNativeObjectInfoInternal(OdbType type, object o, bool recursive, IDictionary <object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { AbstractObjectInfo aoi = null; if (type.IsAtomicNative()) { if (o == null) { aoi = new NullNativeObjectInfo(type.Id); } else { aoi = new AtomicNativeObjectInfo(o, type.Id); } } else if (type.IsArray()) { if (o == null) { aoi = new ArrayObjectInfo(null); } else { // Gets the type of the elements of the array var realArrayClassName = OdbClassNameResolver.GetFullName(o.GetType().GetElementType()); var arrayObjectInfo = recursive ? IntrospectArray(o, alreadyReadObjects, type, callback) : new ArrayObjectInfo((object[])o); arrayObjectInfo.SetRealArrayComponentClassName(realArrayClassName); aoi = arrayObjectInfo; } } else if (type.IsEnum()) { var enumObject = (Enum)o; // Here we must check if the enum is already in the meta model. Enum must be stored in the meta // model to optimize its storing as we need to keep track of the enum class // for each enum stored. So instead of storing the enum class name, we can store enum class id, a long // instead of the full enum class name string var classInfo = GetClassInfo(enumObject.GetType()); var enumValue = enumObject.ToString(); aoi = new EnumNativeObjectInfo(classInfo, enumValue); } return(aoi); }
private AbstractObjectInfo GetNativeObjectInfoInternal(OdbType type, object o, bool recursive, IDictionary<object, NonNativeObjectInfo> alreadyReadObjects, IIntrospectionCallback callback) { AbstractObjectInfo aoi = null; if (type.IsAtomicNative()) { if (o == null) aoi = new NullNativeObjectInfo(type.Id); else aoi = new AtomicNativeObjectInfo(o, type.Id); } else if (type.IsArray()) { if (o == null) aoi = new ArrayObjectInfo(null); else { // Gets the type of the elements of the array var realArrayClassName = OdbClassNameResolver.GetFullName(o.GetType().GetElementType()); var arrayObjectInfo = recursive ? IntrospectArray(o, alreadyReadObjects, type, callback) : new ArrayObjectInfo((object[]) o); arrayObjectInfo.SetRealArrayComponentClassName(realArrayClassName); aoi = arrayObjectInfo; } } else if (type.IsEnum()) { var enumObject = (Enum) o; // Here we must check if the enum is already in the meta model. Enum must be stored in the meta // model to optimize its storing as we need to keep track of the enum class // for each enum stored. So instead of storing the enum class name, we can store enum class id, a long // instead of the full enum class name string var classInfo = GetClassInfo(enumObject.GetType()); var enumValue = enumObject.ToString(); aoi = new EnumNativeObjectInfo(classInfo, enumValue); } return aoi; }
/// <summary> /// Builds an instance of an array /// </summary> private object BuildArrayInstance(ArrayObjectInfo aoi) { // first check if array element type is native (int,short, for example) var type = OdbType.GetFromName(aoi.GetRealArrayComponentClassName()); var arrayClazz = type.GetNativeClass(); object array = Array.CreateInstance(arrayClazz, aoi.GetArray().Length); for (var i = 0; i < aoi.GetArrayLength(); i++) { var abstractObjectInfo = (AbstractObjectInfo)aoi.GetArray()[i]; if (abstractObjectInfo == null || abstractObjectInfo.IsDeletedObject() || abstractObjectInfo.IsNull()) { continue; } var instance = BuildOneInstance(abstractObjectInfo); ((Array)array).SetValue(instance, i); } return(array); }
/// <summary>Builds an instance of an array</summary> public virtual object BuildArrayInstance(ArrayObjectInfo aoi) { // first check if array element type is native (int,short, for example) ODBType type = ODBType.GetFromName(aoi.GetRealArrayComponentClassName()); System.Type arrayClazz = type.GetNativeClass(); object array = System.Array.CreateInstance(arrayClazz, aoi.GetArray().Length); object o = null; AbstractObjectInfo aboi = null; for (int i = 0; i < aoi.GetArrayLength(); i++) { aboi = (AbstractObjectInfo)aoi.GetArray()[i]; if (aboi != null && !aboi.IsDeletedObject() && !aboi.IsNull()) { o = BuildOneInstance(aboi); ((Array)array).SetValue(o, i); } } return(array); }
public override AbstractObjectInfo CreateCopy(IDictionary<OID, AbstractObjectInfo> cache, bool onlyData) { var array = GetArray(); var length = array.Length; var atomicNativeObjectInfos = new AtomicNativeObjectInfo[length]; for (var i = 0; i < length; i++) { var aoi = (AbstractObjectInfo) array[i]; atomicNativeObjectInfos[i] = aoi.CreateCopy(cache, onlyData) as AtomicNativeObjectInfo; } var arrayOfAoi = new ArrayObjectInfo(atomicNativeObjectInfos); arrayOfAoi.SetRealArrayComponentClassName(_realArrayComponentClassName); arrayOfAoi.SetComponentTypeId(_componentTypeId); return arrayOfAoi; }
/// <summary> /// Checks if something in the Arary has changed, if yes, stores the change /// </summary> /// <param name="nnoi1"> The first Object meta representation (nnoi = NonNativeObjectInfo) </param> /// <param name="nnoi2"> The second object meta representation </param> /// <param name="fieldId"> The field index that this collection represents </param> /// <param name="aoi1"> The Meta representation of the array 1 (aoi = ArraybjectInfo) </param> /// <param name="aoi2"> The Meta representation of the array 2 </param> /// <param name="objectRecursionLevel"> </param> /// <returns> true if the 2 array representations are different </returns> private bool ManageArrayChanges(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int fieldId, ArrayObjectInfo aoi1, ArrayObjectInfo aoi2, int objectRecursionLevel) { var array1 = aoi1.GetArray(); var array2 = aoi2.GetArray(); if (array1.Length != array2.Length) { var buffer = new StringBuilder(); buffer.Append("Array size has changed oldsize=").Append(array1.Length).Append("/newsize=").Append( array2.Length); StoreChangedObject(nnoi1, nnoi2, fieldId, aoi1, aoi2, buffer.ToString(), objectRecursionLevel); return true; } for (var i = 0; i < array1.Length; i++) { var value1 = (AbstractObjectInfo) array1[i]; var value2 = (AbstractObjectInfo) array2[i]; var localHasChanged = HasChanged(value1, value2, objectRecursionLevel); if (!localHasChanged) continue; _nbChanges++; return true; } return false; }
private bool HasChanged(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int objectRecursionLevel) { AbstractObjectInfo value1 = null; AbstractObjectInfo value2 = null; bool hasChanged = false; // If the object is already being checked, return false, this second // check will not affect the check int n = 0; alreadyCheckingObjects.TryGetValue(nnoi2, out n); if (n != 0) { return(false); } // Put the object in the temporary cache alreadyCheckingObjects[nnoi1] = 1; alreadyCheckingObjects[nnoi2] = 1; // Warning ID Start with 1 and not 0 for (int id = 1; id <= nnoi1.GetMaxNbattributes(); id++) { value1 = nnoi1.GetAttributeValueFromId(id); // Gets the value by the attribute id to be sure // Problem because a new object info may not have the right ids ? // Check if // the new oiD is ok. value2 = nnoi2.GetAttributeValueFromId(id); if (value2 == null) { // this means the object to have attribute id StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); hasChanged = true; continue; } if (value1 == null) { //throw new ODBRuntimeException("ObjectInfoComparator.hasChanged:attribute with id "+id+" does not exist on "+nnoi2); // This happens when this object was created with an version of ClassInfo (which has been refactored). // In this case,we simply tell that in place update is not supported so that the object will be rewritten with // new metamodel supportInPlaceUpdate = false; continue; } // If both are null, no effect if (value1.IsNull() && value2.IsNull()) { continue; } if (value1.IsNull() || value2.IsNull()) { supportInPlaceUpdate = false; hasChanged = true; StoreActionSetAttributetoNull(nnoi1, id, objectRecursionLevel); continue; } if (!ClassAreCompatible(value1, value2)) { if (value2 is NativeObjectInfo) { StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); StoreChangedAttributeAction(new ChangedNativeAttributeAction (nnoi1, nnoi2, nnoi1.GetHeader().GetAttributeIdentificationFromId(id), (NativeObjectInfo )value2, objectRecursionLevel, false, nnoi1.GetClassInfo().GetAttributeInfoFromId (id).GetName())); } if (value2 is ObjectReference) { NonNativeObjectInfo nnoi = (NonNativeObjectInfo )value1; ObjectReference oref = (ObjectReference )value2; if (!nnoi.GetOid().Equals(oref.GetOid())) { StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel); int attributeIdThatHasChanged = id; // this is the exact position where the object reference // definition is stored long attributeDefinitionPosition = nnoi2.GetAttributeDefinitionPosition(attributeIdThatHasChanged ); StoreChangedAttributeAction(new ChangedObjectReferenceAttributeAction (attributeDefinitionPosition, (ObjectReference )value2, objectRecursionLevel)); } else { continue; } } hasChanged = true; continue; } if (value1.IsAtomicNativeObject()) { if (!value1.Equals(value2)) { // storeChangedObject(nnoi1, nnoi2, id, // objectRecursionLevel); StoreChangedAttributeAction(new ChangedNativeAttributeAction (nnoi1, nnoi2, nnoi1.GetHeader().GetAttributeIdentificationFromId(id), (NativeObjectInfo )value2, objectRecursionLevel, false, nnoi1.GetClassInfo().GetAttributeInfoFromId (id).GetName())); hasChanged = true; continue; } continue; } if (value1.IsCollectionObject()) { CollectionObjectInfo coi1 = (CollectionObjectInfo)value1; CollectionObjectInfo coi2 = (CollectionObjectInfo)value2; bool collectionHasChanged = ManageCollectionChanges(nnoi1, nnoi2, id, coi1, coi2, objectRecursionLevel); hasChanged = hasChanged || collectionHasChanged; continue; } if (value1.IsArrayObject()) { ArrayObjectInfo aoi1 = (ArrayObjectInfo)value1; ArrayObjectInfo aoi2 = (ArrayObjectInfo)value2; bool arrayHasChanged = ManageArrayChanges(nnoi1, nnoi2, id, aoi1, aoi2, objectRecursionLevel ); hasChanged = hasChanged || arrayHasChanged; continue; } if (value1.IsMapObject()) { MapObjectInfo moi1 = (MapObjectInfo)value1; MapObjectInfo moi2 = (MapObjectInfo)value2; bool mapHasChanged = ManageMapChanges(nnoi1, nnoi2, id, moi1, moi2, objectRecursionLevel ); hasChanged = hasChanged || mapHasChanged; continue; } if (value1.IsEnumObject()) { EnumNativeObjectInfo enoi1 = (EnumNativeObjectInfo)value1; EnumNativeObjectInfo enoi2 = (EnumNativeObjectInfo)value2; bool enumHasChanged = !enoi1.GetEnumClassInfo().GetId().Equals(enoi2.GetEnumClassInfo ().GetId()) || !enoi1.GetEnumName().Equals(enoi2.GetEnumName()); hasChanged = hasChanged || enumHasChanged; continue; } if (value1.IsNonNativeObject()) { NonNativeObjectInfo oi1 = (NonNativeObjectInfo)value1; NonNativeObjectInfo oi2 = (NonNativeObjectInfo)value2; // If oids are equal, they are the same objects if (oi1.GetOid() != null && oi1.GetOid().Equals(oi2.GetOid())) { hasChanged = HasChanged(value1, value2, objectRecursionLevel + 1) || hasChanged; } else { // This means that an object reference has changed. hasChanged = true; // keep track of the position where the reference must be // updated long positionToUpdateReference = nnoi1.GetAttributeDefinitionPosition(id); StoreNewObjectReference(positionToUpdateReference, oi2, objectRecursionLevel, nnoi1 .GetClassInfo().GetAttributeInfoFromId(id).GetName()); objectRecursionLevel++; // Value2 may have change too AddPendingVerification(value2); } continue; } } int i1 = (int)alreadyCheckingObjects[nnoi1]; int i2 = (int)alreadyCheckingObjects[nnoi2]; if (i1 != null) { i1 = i1 - 1; } if (i2 != null) { i2 = i2 - 1; } if (i1 == 0) { alreadyCheckingObjects.Remove(nnoi1); } else { alreadyCheckingObjects.Add(nnoi1, i1); } if (i2 == 0) { alreadyCheckingObjects.Remove(nnoi2); } else { alreadyCheckingObjects.Add(nnoi2, i2); } return(hasChanged); }