private NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo IntropectAtomicNativeArray (object array, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type) { int length = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayLength(array); NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo anoi = null; object[] arrayCopy = new object[length]; int typeId = 0; for (int i = 0; i < length; i++) { object o = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayElement(array, i); if (o != null) { // If object is not null, try to get the exact type typeId = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.GetFromClass(o.GetType()).GetId (); anoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, typeId); arrayCopy[i] = anoi; } else { // Else take the declared type arrayCopy[i] = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type .GetId()); } } NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo (arrayCopy, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.Array, type.GetId()); return(aoi); }
private NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo IntrospectArray(object array, bool introspect, System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType valueType, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback callback) { int length = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayLength(array); System.Type elementType = array.GetType().GetElementType(); NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType .GetFromClass(elementType); if (type.IsAtomicNative()) { return(IntropectAtomicNativeArray(array, type)); } if (!introspect) { return(new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])array)); } object[] arrayCopy = new object[length]; for (int i = 0; i < length; i++) { object o = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayElement(array, i); NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = null; if (o != null) { ci = GetClassInfo(OdbClassUtil.GetFullName(o.GetType())); NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = GetObjectInfo(o, ci , introspect, alreadyReadObjects, callback); arrayCopy[i] = aoi; } else { arrayCopy[i] = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeNullObjectInfo(); } } NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo arrayOfAoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo (arrayCopy, valueType, type.GetId()); 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="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; }
protected virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo GetNativeObjectInfoInternal (NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, object o, bool recursive , System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback callback) { NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null; if (type.IsAtomicNative()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetId()); } else { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, type .GetId()); } } else { if (type.IsCollection()) { aoi = IntrospectCollection((System.Collections.ICollection)o, recursive, alreadyReadObjects , type, callback); } else { if (type.IsArray()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo(null); } else { // Gets the type of the elements of the array string realArrayClassName = OdbClassUtil.GetFullName(o.GetType().GetElementType()); NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aroi = null; if (recursive) { aroi = IntrospectArray(o, recursive, alreadyReadObjects, type, callback); } else { aroi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])o ); } aroi.SetRealArrayComponentClassName(realArrayClassName); aoi = aroi; } } else { if (type.IsMap()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.MapObjectInfo(null, type, type.GetDefaultInstanciationClass ().FullName); } else { MapObjectInfo moi = null; string realMapClassName = OdbClassUtil.GetFullName(o.GetType()); bool isGeneric = o.GetType().IsGenericType; if (isGeneric) { moi = new MapObjectInfo(IntrospectGenericMap((System.Collections.Generic.IDictionary <object, object>)o, recursive, alreadyReadObjects, callback), type, realMapClassName); } else { moi = new MapObjectInfo(IntrospectNonGenericMap((System.Collections.IDictionary)o, recursive, alreadyReadObjects, callback), type, realMapClassName); } if (realMapClassName.IndexOf("$") != -1) { moi.SetRealMapClassName(OdbClassUtil.GetFullName(type.GetDefaultInstanciationClass())); } aoi = moi; } } else { if (type.IsEnum()) { System.Enum enumObject = (System.Enum)o; if (enumObject == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetSize( )); } else { Type t = enumObject.GetType(); string enumClassName = enumObject == null ? null : OdbClassUtil.GetFullName(enumObject.GetType()); // 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 NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = GetClassInfo(enumClassName); string enumValue = enumObject == null ? null : enumObject.ToString(); aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.EnumNativeObjectInfo(ci, enumValue ); } } } } } } return(aoi); }
/// <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; }
private NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo IntropectAtomicNativeArray (object array, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type) { int length = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayLength(array); NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo anoi = null; object[] arrayCopy = new object[length]; int typeId = 0; for (int i = 0; i < length; i++) { object o = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayElement(array, i); if (o != null) { // If object is not null, try to get the exact type typeId = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.GetFromClass(o.GetType()).GetId (); anoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, typeId); arrayCopy[i] = anoi; } else { // Else take the declared type arrayCopy[i] = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type .GetId()); } } NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo (arrayCopy, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.Array, type.GetId()); return aoi; }
protected virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo GetNativeObjectInfoInternal (NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, object o, bool recursive , System.Collections.Generic.IDictionary<object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback callback) { NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null; if (type.IsAtomicNative()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetId()); } else { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, type .GetId()); } } else { if (type.IsCollection()) { aoi = IntrospectCollection((System.Collections.ICollection)o, recursive, alreadyReadObjects , type, callback); } else { if (type.IsArray()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo(null); } else { // Gets the type of the elements of the array string realArrayClassName = OdbClassUtil.GetFullName(o.GetType().GetElementType()); NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aroi = null; if (recursive) { aroi = IntrospectArray(o, recursive, alreadyReadObjects, type, callback); } else { aroi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])o ); } aroi.SetRealArrayComponentClassName(realArrayClassName); aoi = aroi; } } else { if (type.IsMap()) { if (o == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.MapObjectInfo(null, type, type.GetDefaultInstanciationClass ().FullName); } else { MapObjectInfo moi = null; string realMapClassName = OdbClassUtil.GetFullName(o.GetType()); bool isGeneric = o.GetType().IsGenericType; if (isGeneric) { moi = new MapObjectInfo(IntrospectGenericMap((System.Collections.Generic.IDictionary<object,object>)o, recursive, alreadyReadObjects, callback), type, realMapClassName); } else { moi = new MapObjectInfo(IntrospectNonGenericMap((System.Collections.IDictionary)o, recursive, alreadyReadObjects, callback), type, realMapClassName); } if (realMapClassName.IndexOf("$") != -1) { moi.SetRealMapClassName(OdbClassUtil.GetFullName(type.GetDefaultInstanciationClass())); } aoi = moi; } } else { if (type.IsEnum()) { System.Enum enumObject = (System.Enum)o; if (enumObject == null) { aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetSize( )); } else { Type t = enumObject.GetType(); string enumClassName = enumObject == null ? null : OdbClassUtil.GetFullName(enumObject.GetType()); // 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 NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = GetClassInfo(enumClassName); string enumValue = enumObject == null ? null : enumObject.ToString(); aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.EnumNativeObjectInfo(ci, enumValue ); } } } } } } return aoi; }
private NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo IntrospectArray(object array, bool introspect, System.Collections.Generic.IDictionary<object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType valueType, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback callback) { int length = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayLength(array); System.Type elementType = array.GetType().GetElementType(); NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType .GetFromClass(elementType); if (type.IsAtomicNative()) { return IntropectAtomicNativeArray(array, type); } if (!introspect) { return new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])array); } object[] arrayCopy = new object[length]; for (int i = 0; i < length; i++) { object o = NeoDatis.Tool.Wrappers.OdbReflection.GetArrayElement(array, i); NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = null; if (o != null) { ci = GetClassInfo(OdbClassUtil.GetFullName(o.GetType())); NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = GetObjectInfo(o, ci , introspect, alreadyReadObjects, callback); arrayCopy[i] = aoi; } else { arrayCopy[i] = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeNullObjectInfo(); } } NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo arrayOfAoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo (arrayCopy, valueType, type.GetId()); return arrayOfAoi; }
/// <summary> /// <pre> /// Write an array to the database /// This is done by writing : /// - the array type : array /// - the array element type (String if it os a String []) /// - the position of the non native type, if element are non java / C# native /// - the number of element s and then the position of all elements. /// </summary> /// <remarks> /// <pre> /// Write an array to the database /// This is done by writing : /// - the array type : array /// - the array element type (String if it os a String []) /// - the position of the non native type, if element are non java / C# native /// - the number of element s and then the position of all elements. /// Example : an array with two string element : 'ola' and 'chico' /// write 22 : array /// write 20 : array of STRING /// write 0 : it is a java native object /// write 2 (as an int) : the number of elements /// write two times 0 (as long) to reserve the space for the elements positions /// then write the string 'ola', and keeps its position in the 'positions' array of long /// then write the string 'chico' and keeps its position in the 'positions' array of long /// Then write back all the positions (in this case , 2 positions) after the size of the array /// Example : an array with two User element : user1 and user2 /// write 22 : array /// write 23 : array of NON NATIVE Objects /// write 251 : if 250 is the position of the user class info in database /// write 2 (as an int) : the number of elements /// write two times 0 (as long) to reserve the space for the elements positions /// then write the user user1, and keeps its position in the 'positions' array of long /// then write the user user2 and keeps its position in the 'positions' array of long /// <pre> /// @param object /// @param odbType /// @param position /// @param writeInTransaction /// @ /// </remarks> private long WriteArray(ArrayObjectInfo aoi, bool writeInTransaction) { long firstObjectPosition = 0; long[] attributeIdentifications; long startPosition = fsi.GetPosition(); WriteNativeObjectHeader(aoi.GetOdbTypeId(), aoi.IsNull(), NeoDatis.Odb.Impl.Core.Layers.Layer3.Block.BlockTypes .BlockTypeArrayObject, writeInTransaction); if (aoi.IsNull()) { return startPosition; } object[] array = aoi.GetArray(); int arraySize = array.Length; // Writes the fact that it is an array fsi.WriteString(aoi.GetRealArrayComponentClassName(), false, writeInTransaction); // write the size of the array fsi.WriteInt(arraySize, writeInTransaction, "array size"); // build a n array to store all element positions attributeIdentifications = new long[arraySize]; // Gets the current position, to know later where to put the // references firstObjectPosition = fsi.GetPosition(); // reserve space for object positions : write 'arraySize' long // with zero to store each object position for (int i = 0; i < arraySize; i++) { fsi.WriteLong(0, writeInTransaction, "array element pos ", NeoDatis.Odb.Impl.Core.Transaction.DefaultWriteAction .DataWriteAction); } NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo element = null; for (int i = 0; i < arraySize; i++) { element = (NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo)array[i]; if (element == null || element.IsNull()) { // TODO Check this attributeIdentifications[i] = NeoDatis.Odb.Impl.Core.Layers.Layer3.Engine.StorageEngineConstant .NullObjectIdId; continue; } attributeIdentifications[i] = InternalStoreObjectWrapper(element); } long positionAfterWrite = fsi.GetPosition(); // now that all objects have been stored, sets their position in the // space that have been reserved fsi.SetWritePosition(firstObjectPosition, writeInTransaction); for (int i = 0; i < arraySize; i++) { fsi.WriteLong(attributeIdentifications[i], writeInTransaction, "array real element pos" , NeoDatis.Odb.Impl.Core.Transaction.DefaultWriteAction.DataWriteAction); } // Gos back to the end of the array fsi.SetWritePosition(positionAfterWrite, writeInTransaction); return startPosition; }