public override NeoDatis.Odb.OID WriteObjectInfo(NeoDatis.Odb.OID oid, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo aoi, long position, bool updatePointers) { // TODO check if it must be written in transaction return(objectWriter.WriteNonNativeObjectInfo(oid, aoi, position, updatePointers, true)); }
public virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo BuildNnoi (object o, NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo classInfo, NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo [] values, long[] attributesIdentification, int[] attributeIds, System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo> alreadyReadObjects ) { NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo (o, classInfo, values, attributesIdentification, attributeIds); if (storageEngine != null) { // for unit test purpose NeoDatis.Odb.Core.Transaction.ICache cache = storageEngine.GetSession(true).GetCache (); // Check if object is in the cache, if so sets its oid NeoDatis.Odb.OID oid = cache.GetOid(o, false); if (oid != null) { nnoi.SetOid(oid); // Sets some values to the new header to keep track of the infos // when // executing NeoDatis without closing it, just committing. // Bug reported by Andy NeoDatis.Odb.Core.Layers.Layer2.Meta.ObjectInfoHeader oih = cache.GetObjectInfoHeaderFromOid (oid, true); nnoi.GetHeader().SetObjectVersion(oih.GetObjectVersion()); nnoi.GetHeader().SetUpdateDate(oih.GetUpdateDate()); nnoi.GetHeader().SetCreationDate(oih.GetCreationDate()); } } return(nnoi); }
public override object GetObjectFromOid(NeoDatis.Odb.OID oid) { if (oid == null) { throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.CanNotGetObjectFromNullOid ); } NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi = GetObjectReader() .ReadNonNativeObjectInfoFromOid(null, oid, true, true); if (nnoi.IsDeletedObject()) { throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.ObjectIsMarkedAsDeletedForOid .AddParameter(oid)); } object o = nnoi.GetObject(); if (o == null) { o = GetObjectReader().GetInstanceBuilder().BuildOneInstance(nnoi); } NeoDatis.Odb.Core.Transaction.ISession lsession = GetSession(true); // Here oid can be different from nnoi.getOid(). This is the case when // the oid is an external oid. That`s why we use // nnoi.getOid() to put in the cache lsession.GetCache().AddObject(nnoi.GetOid(), o, nnoi.GetHeader()); lsession.GetTmpCache().ClearObjectInfos(); return(o); }
public virtual void StartReadingObjectInfoWithOid(NeoDatis.Odb.OID oid, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo objectInfo) { if (oid == null) { throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.CacheNullOid ); } object[] objects = null; readingObjectInfo.TryGetValue(oid, out objects); // TODO : use a value object instead of an array! if (objects == null) { // The key is the oid, the value is an array of 2 objects : // 1-the read count, 2-The object info // Here we are saying that the object with oid 'oid' is // being read for the first time object[] values = new object[] { (short)1, objectInfo }; readingObjectInfo[oid] = values; } else { // Here the object is already being read. It is necessary to // increase the read count short currentReadCount = ((short)objects[0]); objects[0] = (short)(currentReadCount + 1); } }
public override NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo GetMetaObjectFromOid (NeoDatis.Odb.OID oid) { NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi = GetObjectReader() .ReadNonNativeObjectInfoFromOid(null, oid, true, false); GetSession(true).GetTmpCache().ClearObjectInfos(); return(nnoi); }
public virtual object GetCurrentInstance(NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi) { //FIXME no need if (nnoi.GetObject() != null) { return(nnoi.GetObject()); } return(instanceBuilder.BuildOneInstance(nnoi)); }
private void StoreNewObjectReference(long positionToUpdateReference, NonNativeObjectInfo oi2, int objectRecursionLevel, string attributeName) { NewNonNativeObjectAction nnnoa = new NewNonNativeObjectAction(positionToUpdateReference , oi2, objectRecursionLevel, attributeName); newObjectMetaRepresentations.Add(nnnoa); nbChanges++; }
/// <summary> /// Build a meta representation of an object /// <pre> /// warning: When an object has two fields with the same name (a private field with the same name in a parent class, the deeper field (of the parent) is ignored!) /// </pre> /// </summary> /// <param name="o"></param> /// <param name="ci"></param> /// <param name="recursive"></param> /// <returns>The ObjectInfo</returns> protected virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo GetObjectInfoInternal (NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo nnoi, object o, NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci, bool recursive, System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback callback) { object value = null; if (o == null) { return(NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo.GetInstance()); } System.Type clazz = o.GetType(); NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType .GetFromClass(clazz); string className = OdbClassUtil.GetFullName(clazz); if (type.IsNative()) { return(GetNativeObjectInfoInternal(type, o, recursive, alreadyReadObjects, callback)); } // sometimes the clazz.getName() may not match the ci.getClassName() // It happens when the attribute is an interface or superclass of the // real attribute class // In this case, ci must be updated to the real class info if (ci != null && !clazz.FullName.Equals(ci.GetFullClassName())) { ci = GetClassInfo(className); nnoi = null; } NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo mainAoi = (NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo )nnoi; bool isRootObject = false; if (alreadyReadObjects == null) { alreadyReadObjects = new NeoDatis.Tool.Wrappers.Map.OdbHashMap <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo >(); isRootObject = true; } if (o != null) { NonNativeObjectInfo cachedNnoi = null; alreadyReadObjects.TryGetValue(o, out cachedNnoi); if (cachedNnoi != null) { ObjectReference or = new ObjectReference(cachedNnoi); return(or); } if (callback != null) { callback.ObjectFound(o); } } if (mainAoi == null) { mainAoi = BuildNnoi(o, ci, null, null, null, alreadyReadObjects); } alreadyReadObjects[o] = mainAoi; NeoDatis.Tool.Wrappers.List.IOdbList <System.Reflection.FieldInfo> fields = classIntrospector.GetAllFields(className); NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null; int attributeId = -1; // For all fields for (int i = 0; i < fields.Count; i++) { System.Reflection.FieldInfo field = fields[i]; try { value = field.GetValue(o); attributeId = ci.GetAttributeId(field.Name); if (attributeId == -1) { throw new ODBRuntimeException(NeoDatisError.ObjectIntrospectorNoFieldWithName.AddParameter(ci.GetFullClassName()).AddParameter(field.Name)); } ODBType valueType = null; if (value == null) { // If value is null, take the type from the field type // declared in the class valueType = ODBType.GetFromClass(field.FieldType); } else { // Else take the real attribute type! valueType = ODBType.GetFromClass(value.GetType()); } // for native fields if (valueType.IsNative()) { aoi = GetNativeObjectInfoInternal(valueType, value, recursive, alreadyReadObjects, callback); mainAoi.SetAttributeValue(attributeId, aoi); } else { //callback.objectFound(value); // Non Native Objects if (value == null) { ClassInfo clai = GetClassInfo(OdbClassUtil.GetFullName(field.GetType())); aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeNullObjectInfo(clai); mainAoi.SetAttributeValue(attributeId, aoi); } else { ClassInfo clai = GetClassInfo(OdbClassUtil.GetFullName(value.GetType())); if (recursive) { aoi = GetObjectInfoInternal(null, value, clai, recursive, alreadyReadObjects, callback ); mainAoi.SetAttributeValue(attributeId, aoi); } else { // When it is not recursive, simply add the object // values.add(value); throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.InternalError .AddParameter("Should not enter here - ObjectIntrospector - 'simply add the object'" )); } } } } catch (System.ArgumentException e) { throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.InternalError .AddParameter("in getObjectInfoInternal"), e); } catch (System.MemberAccessException e) { throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.InternalError .AddParameter("getObjectInfoInternal"), e); } } if (isRootObject) { alreadyReadObjects.Clear(); alreadyReadObjects = null; } return(mainAoi); }
/// <summary>Checks if something in the Map 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 map represents</param> /// <param name="moi1">The Meta representation of the map 1 (moi = MapObjectInfo)</param> /// <param name="moi2">The Meta representation of the map 2</param> /// <param name="objectRecursionLevel"></param> /// <returns>true if the 2 map representations are different</returns> private bool ManageMapChanges(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int fieldId , MapObjectInfo moi1, MapObjectInfo moi2, int objectRecursionLevel) { if (true) { return true; } IDictionary<AbstractObjectInfo , AbstractObjectInfo> map1 = moi1.GetMap(); IDictionary<AbstractObjectInfo , AbstractObjectInfo> map2 = moi2.GetMap(); if (map1.Count != map2.Count) { System.Text.StringBuilder buffer = new System.Text.StringBuilder(); buffer.Append("Map size has changed oldsize=").Append(map1.Count).Append("/newsize=" ).Append(map2.Count); StoreChangedObject(nnoi1, nnoi2, fieldId, moi1, moi2, buffer.ToString(), objectRecursionLevel ); return true; } IEnumerator<AbstractObjectInfo > keys1 = map1.Keys.GetEnumerator(); IEnumerator<AbstractObjectInfo > keys2 = map2.Keys.GetEnumerator(); AbstractObjectInfo key1 = null; AbstractObjectInfo key2 = null; AbstractObjectInfo value1 = null; AbstractObjectInfo value2 = null; int index = 0; while (keys1.MoveNext()) { keys2.MoveNext(); key1 = keys1.Current; key2 = keys2.Current; bool keysHaveChanged = this.HasChanged(key1, key2, objectRecursionLevel); if (keysHaveChanged) { StoreChangedObject(nnoi1, nnoi2, fieldId, key1, key2, "Map key index " + index + " has changed", objectRecursionLevel); return true; } value1 = map1[key1]; value2 = map2[key2]; bool valuesHaveChanged = this.HasChanged(value1, value2, objectRecursionLevel); if (valuesHaveChanged) { StoreChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "Map value index " + index + " has changed", objectRecursionLevel); return true; } index++; } return false; }
/// <summary> /// Checks if something in the Collection 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="coi1"> /// The Meta representation of the collection 1 (coi = /// CollectionObjectInfo) /// </param> /// <param name="coi2">The Meta representation of the collection 2</param> /// <param name="objectRecursionLevel"></param> /// <returns>true if 2 collection representation are different</returns> private bool ManageCollectionChanges(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int fieldId , CollectionObjectInfo coi1, CollectionObjectInfo coi2, int objectRecursionLevel) { ICollection<AbstractObjectInfo > collection1 = coi1.GetCollection(); ICollection<AbstractObjectInfo > collection2 = coi2.GetCollection(); if (collection1.Count != collection2.Count) { System.Text.StringBuilder buffer = new System.Text.StringBuilder(); buffer.Append("Collection size has changed oldsize=").Append(collection1.Count).Append ("/newsize=").Append(collection2.Count); StoreChangedObject(nnoi1, nnoi2, fieldId, coi1, coi2, buffer.ToString(), objectRecursionLevel ); return true; } System.Collections.IEnumerator iterator1 = collection1.GetEnumerator(); System.Collections.IEnumerator iterator2 = collection2.GetEnumerator(); AbstractObjectInfo value1 = null; AbstractObjectInfo value2 = null; int index = 0; while (iterator1.MoveNext()) { iterator2.MoveNext(); value1 = (AbstractObjectInfo)iterator1.Current; value2 = (AbstractObjectInfo)iterator2.Current; bool hasChanged = this.HasChanged(value1, value2, objectRecursionLevel); if (hasChanged) { // We consider collection has changed only if object are // different, If objects are the same instance, but something in // the object has changed, then the collection has not // changed,only the object if (value1.IsNonNativeObject() && value2.IsNonNativeObject()) { NonNativeObjectInfo nnoia = (NonNativeObjectInfo )value1; NonNativeObjectInfo nnoib = (NonNativeObjectInfo )value2; if (nnoia.GetOid() != null && !nnoia.GetOid().Equals(nnoi2.GetOid())) { // Objects are not the same instance -> the collection // has changed StoreChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "List element index " + index + " has changed", objectRecursionLevel); } } else { supportInPlaceUpdate = false; nbChanges++; } //storeChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "List element index " + index + " has changed", objectRecursionLevel); return true; } index++; } return false; }
private void StoreChangedObject(NonNativeObjectInfo aoi1, NonNativeObjectInfo aoi2, int fieldId , AbstractObjectInfo oldValue, AbstractObjectInfo newValue, string message, int objectRecursionLevel) { if (aoi1 != null && aoi2 != null) { if (aoi1.GetOid() != null && aoi1.GetOid().Equals(aoi2.GetOid())) { changedObjectMetaRepresentations.Add(aoi2); changes.Add(new ChangedObjectInfo(aoi1 .GetClassInfo(), aoi2.GetClassInfo(), fieldId, oldValue, newValue, message, objectRecursionLevel )); // also the max recursion level if (objectRecursionLevel > maxObjectRecursionLevel) { maxObjectRecursionLevel = objectRecursionLevel; } nbChanges++; } else { newObjects.Add(aoi2.GetObject()); string fieldName = aoi1.GetClassInfo().GetAttributeInfoFromId(fieldId).GetName(); // keep track of the position where the reference must be // updated - use aoi1 to get position, because aoi2 do not have position defined yet long positionToUpdateReference = aoi1.GetAttributeDefinitionPosition(fieldId); StoreNewObjectReference(positionToUpdateReference, aoi2, objectRecursionLevel, fieldName ); } } else { //newObjectMetaRepresentations.add(aoi2); NeoDatis.Tool.DLogger.Info("Non native object with null object"); } }
public virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo BuildNnoi (object o, NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo classInfo, NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo [] values, long[] attributesIdentification, int[] attributeIds, System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo> alreadyReadObjects ) { NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo (o, classInfo, values, attributesIdentification, attributeIds); if (storageEngine != null) { // for unit test purpose NeoDatis.Odb.Core.Transaction.ICache cache = storageEngine.GetSession(true).GetCache (); // Check if object is in the cache, if so sets its oid NeoDatis.Odb.OID oid = cache.GetOid(o, false); if (oid != null) { nnoi.SetOid(oid); // Sets some values to the new header to keep track of the infos // when // executing NeoDatis without closing it, just committing. // Bug reported by Andy NeoDatis.Odb.Core.Layers.Layer2.Meta.ObjectInfoHeader oih = cache.GetObjectInfoHeaderFromOid (oid, true); nnoi.GetHeader().SetObjectVersion(oih.GetObjectVersion()); nnoi.GetHeader().SetUpdateDate(oih.GetUpdateDate()); nnoi.GetHeader().SetCreationDate(oih.GetCreationDate()); } } return nnoi; }
public virtual void StartReadingObjectInfoWithOid(NeoDatis.Odb.OID oid, NonNativeObjectInfo objectInfo) { if (oid == null) { throw new ODBRuntimeException(NeoDatisError.CacheNullOid); } object[] objects = (object[])readingObjectInfo[oid]; if (objects == null) { // The key is the oid, the value is an array of 2 objects : // 1-the read count, 2-The object info // Here we are saying that the object with oid 'oid' is // being read for the first time object[] values = new object[] { (short)1, objectInfo }; readingObjectInfo[oid] = values; } else { // Here the object is already being read. It is necessary to // increase the read count short currentReadCount = ((short)objects[0]); objects[0] = (short)(currentReadCount + 1); } }
//throw new ODBRuntimeException(Error.CACHE_IS_FULL.addParameter(objectInfoPointersCacheFromOid.size()).addParameter(OdbConfiguration.getMaxNumberOfObjectInCache())); public virtual void StartInsertingObjectWithOid(object o, NeoDatis.Odb.OID oid, NonNativeObjectInfo nnoi) { // In this case oid can be -1,because object is beeing inserted and do // not have yet a defined oid. if (o == null) { return; } ObjectInsertingInfo oii = null; insertingObjects.TryGetValue(o,out oii); if (oii == null) { insertingObjects[o] = new ObjectInsertingInfo(oid, 1); } else { oii.level++; } }
public override NeoDatis.Odb.OID UpdateObject(NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo nnoi, bool forceUpdate) { return(objectWriter.UpdateNonNativeObjectInfo(nnoi, forceUpdate)); }
private void StoreActionSetAttributetoNull(NonNativeObjectInfo nnoi, int id, int objectRecursionLevel) { nbChanges++; SetAttributeToNullAction action = new SetAttributeToNullAction(nnoi, id); attributeToSetToNull.Add(action); }
private void StoreArrayChange(NonNativeObjectInfo nnoi, int arrayAttributeId, int arrayIndex, AbstractObjectInfo value, bool supportInPlaceUpdate) { nbChanges++; ArrayModifyElement ame = new ArrayModifyElement (nnoi, arrayAttributeId, arrayIndex, value, supportInPlaceUpdate); arrayChanges.Add(ame); }
public virtual object BuildOneInstance(NonNativeObjectInfo objectInfo) { ICache cache = GetSession().GetCache(); // verify if the object is check to delete if (objectInfo.IsDeletedObject()) { throw new ODBRuntimeException(NeoDatisError.ObjectIsMarkedAsDeletedForOid.AddParameter(objectInfo.GetOid())); } // Then check if object is in cache object o = cache.GetObjectWithOid(objectInfo.GetOid()); if (o != null) { return o; } Type instanceClazz = null; instanceClazz = classPool.GetClass(objectInfo.GetClassInfo().GetFullClassName()); try { o = classIntrospector.NewInstanceOf(instanceClazz); } catch (System.Exception e) { throw new ODBRuntimeException(NeoDatisError.InstanciationError.AddParameter(objectInfo.GetClassInfo().GetFullClassName()), e); } // This can happen if ODB can not create the instance // TODO Check if returning null is correct if (o == null) { return null; } // Keep the initial hash code. In some cases, when the class redefines // the hash code method // Hash code can return wrong values when attributes are not set (when // hash code depends on attribute values) // Hash codes are used as the key of the map, // So at the end of this method, if hash codes are different, object // will be removed from the cache and inserted back bool hashCodeIsOk = true; int initialHashCode = 0; try { initialHashCode = o.GetHashCode(); } catch (System.Exception) { hashCodeIsOk = false; } // Adds this incomplete instance in the cache to manage cyclic reference if (hashCodeIsOk) { cache.AddObject(objectInfo.GetOid(), o, objectInfo.GetHeader()); } ClassInfo ci = objectInfo.GetClassInfo(); IOdbList<FieldInfo> fields = classIntrospector.GetAllFields(ci.GetFullClassName()); FieldInfo field = null; AbstractObjectInfo aoi = null; object value = null; for (int i = 0; i < fields.Count; i++) { field = fields[i]; // Gets the id of this field int attributeId = ci.GetAttributeId(field.Name); if (OdbConfiguration.IsDebugEnabled(LogIdDebug)) { DLogger.Debug("getting field with name " + field.Name + ", attribute id is "+ attributeId); } aoi = objectInfo.GetAttributeValueFromId(attributeId); // Check consistency // ensureClassCompatibily(field, // instanceInfo.getClassInfo().getAttributeinfo(i).getFullClassname()); if (aoi != null && (!aoi.IsNull())) { if (aoi.IsNative()) { if (aoi.IsAtomicNativeObject()) { if (aoi.IsNull()) { value = null; } else { value = aoi.GetObject(); } } if (aoi.IsCollectionObject()) { value = BuildCollectionInstance((CollectionObjectInfo)aoi); // Manage a specific case of Set /* if (typeof(Java.Util.Set).IsAssignableFrom(field.GetType()) && typeof(ICollection).IsAssignableFrom(value.GetType())) { Java.Util.Set s = new Java.Util.HashSet(); s.AddAll((System.Collections.ICollection)value); value = s; }*/ } if (aoi.IsArrayObject()) { value = BuildArrayInstance((ArrayObjectInfo)aoi); } if (aoi.IsMapObject()) { value = BuildMapInstance((MapObjectInfo)aoi); } if (aoi.IsEnumObject()) { value = BuildEnumInstance((EnumNativeObjectInfo)aoi, field.FieldType); } } else { if (aoi.IsNonNativeObject()) { if (aoi.IsDeletedObject()) { if (NeoDatis.Odb.OdbConfiguration.DisplayWarnings()) { IError warning = NeoDatisError.AttributeReferencesADeletedObject .AddParameter(objectInfo.GetClassInfo().GetFullClassName()) .AddParameter(objectInfo.GetOid()).AddParameter(field.Name); DLogger.Info(warning.ToString()); } value = null; } else { value = BuildOneInstance((NonNativeObjectInfo)aoi); } } } if (value != null) { if (OdbConfiguration.IsDebugEnabled(LogIdDebug)) { DLogger.Debug("Setting field " + field.Name + "(" + field.GetType().FullName + ") to " + value + " / " + value.GetType().FullName); } try { field.SetValue(o, value); } catch (System.Exception e) { throw new ODBRuntimeException(NeoDatisError.InstanceBuilderWrongObjectContainerType .AddParameter(objectInfo.GetClassInfo().GetFullClassName()) .AddParameter(value.GetType().FullName).AddParameter(field.GetType().FullName), e); } } } } if (o != null && !OdbClassUtil.GetFullName(o.GetType()).Equals(objectInfo.GetClassInfo().GetFullClassName())) { new ODBRuntimeException(NeoDatisError.InstanceBuilderWrongObjectType .AddParameter(objectInfo.GetClassInfo().GetFullClassName()) .AddParameter(o.GetType().FullName)); } if (hashCodeIsOk || initialHashCode != o.GetHashCode()) { // Bug (sf bug id=1875544 )detected by glsender // This can happen when an object has redefined its own hashcode // method and depends on the field values // Then, we have to remove object from the cache and re-insert to // correct map hash code cache.RemoveObjectWithOid(objectInfo.GetOid()); // re-Adds instance in the cache cache.AddObject(objectInfo.GetOid(), o, objectInfo.GetHeader()); } if (triggerManager != null) { triggerManager.ManageSelectTriggerAfter(objectInfo.GetClassInfo().GetFullClassName (), objectInfo, objectInfo.GetOid()); } if (OdbConfiguration.ReconnectObjectsToSession()) { ICrossSessionCache crossSessionCache = CacheFactory.GetCrossSessionCache(engine.GetBaseIdentification().GetIdentification()); crossSessionCache.AddObject(o, objectInfo.GetOid()); } return o; }
private void StoreChangedObject(NonNativeObjectInfo aoi1, NonNativeObjectInfo aoi2, int fieldId , int objectRecursionLevel) { nbChanges++; if (aoi1 != null && aoi2 != null) { changes.Add(new ChangedObjectInfo(aoi1 .GetClassInfo(), aoi2.GetClassInfo(), fieldId, aoi1.GetAttributeValueFromId(fieldId ), aoi2.GetAttributeValueFromId(fieldId), objectRecursionLevel)); // also the max recursion level if (objectRecursionLevel > maxObjectRecursionLevel) { maxObjectRecursionLevel = objectRecursionLevel; } } else { NeoDatis.Tool.DLogger.Info("Non native object with null object"); } }
public virtual object NewFullInstanceOf(System.Type clazz, NonNativeObjectInfo nnoi) { string className = clazz.FullName; NeoDatis.Odb.Core.Layers.Layer2.Instance.FullInstantiationHelper helper = (NeoDatis.Odb.Core.Layers.Layer2.Instance.FullInstantiationHelper )fullInstantiationHelpers[className]; if (helper != null) { object o = helper.Instantiate(nnoi); if (o != null) { return o; } } return null; }
/// <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; }
public override object BuildOneInstance(NonNativeObjectInfo objectInfo) { return objectInfo; }
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; }
public NeoDatisDbObject(NonNativeObjectInfo nnoi) { this.nnoi = nnoi; Fields = nnoi.GetAttributeValues().Select(attr => attr.GetObject()).ToArray(); }