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> /// 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> /// 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; }
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; }
public virtual NeoDatis.Odb.OID WriteNonNativeObjectInfo(NeoDatis.Odb.OID existingOid , NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo objectInfo, long position , bool writeDataInTransaction, bool isNewObject) { NeoDatis.Odb.Core.Transaction.ISession lsession = GetSession(); NeoDatis.Odb.Core.Transaction.ICache cache = lsession.GetCache(); bool hasObject = objectInfo.GetObject() != null; // Insert triggers for CS Mode, local mode insert triggers are called in the DefaultInstrumentationCallbackForStore class if (isNewObject && !isLocalMode) { triggerManager.ManageInsertTriggerBefore(objectInfo.GetClassInfo().GetFullClassName (), objectInfo); } // Checks if object is null,for null objects,there is nothing to do if (objectInfo.IsNull()) { return NeoDatis.Odb.Impl.Core.Layers.Layer3.Engine.StorageEngineConstant.NullObjectId; } NeoDatis.Odb.Core.Layers.Layer2.Meta.MetaModel metaModel = lsession.GetMetaModel( ); // first checks if the class of this object already exist in the // metamodel if (!metaModel.ExistClass(objectInfo.GetClassInfo().GetFullClassName())) { AddClass(objectInfo.GetClassInfo(), true); } // if position is -1, gets the position where to write the object if (position == -1) { // Write at the end of the file position = fsi.GetAvailablePosition(); // Updates the meta object position objectInfo.SetPosition(position); } // Gets the object id NeoDatis.Odb.OID oid = existingOid; if (oid == null) { // If, to get the next id, a new id block must be created, then // there is an extra work // to update the current object position if (idManager.MustShift()) { oid = idManager.GetNextObjectId(position); // The id manager wrote in the file so the position for the // object must be re-computed position = fsi.GetAvailablePosition(); // The oid must be associated to this new position - id // operations are always out of transaction // in this case, the update is done out of the transaction as a // rollback won t need to // undo this. We are just creating the id // => third parameter(write in transaction) = false idManager.UpdateObjectPositionForOid(oid, position, false); } else { oid = idManager.GetNextObjectId(position); } } else { // If an oid was passed, it is because object already exist and // is being updated. So we // must update the object position // Here the update of the position of the id must be done in // transaction as the object // position of the id is being updated, and a rollback should undo // this // => third parameter(write in transaction) = true idManager.UpdateObjectPositionForOid(oid, position, true); // Keep the relation of id and position in the cache until the // commit cache.SavePositionOfObjectWithOid(oid, position); } // Sets the oid of the object in the inserting cache cache.UpdateIdOfInsertingObject(objectInfo.GetObject(), oid); // Only add the oid to unconnected zone if it is a new object if (isNewObject) { cache.AddOIDToUnconnectedZone(oid); if (NeoDatis.Odb.OdbConfiguration.ReconnectObjectsToSession()) { NeoDatis.Odb.Core.Transaction.ICrossSessionCache crossSessionCache = NeoDatis.Odb.Impl.Core.Transaction.CacheFactory .GetCrossSessionCache(storageEngine.GetBaseIdentification().GetIdentification()); crossSessionCache.AddObject(objectInfo.GetObject(), oid); } } objectInfo.SetOid(oid); if (NeoDatis.Odb.OdbConfiguration.IsDebugEnabled(LogId)) { NeoDatis.Tool.DLogger.Debug(DepthToSpaces() + "Start Writing non native object of type " + objectInfo.GetClassInfo().GetFullClassName() + " at " + position + " , oid = " + oid + " : " + objectInfo.ToString()); } if (objectInfo.GetClassInfo() == null || objectInfo.GetClassInfo().GetId() == null) { if (objectInfo.GetClassInfo() != null) { NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo clinfo = storageEngine.GetSession( true).GetMetaModel().GetClassInfo(objectInfo.GetClassInfo().GetFullClassName(), true); objectInfo.SetClassInfo(clinfo); } else { throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.UndefinedClassInfo .AddParameter(objectInfo.ToString())); } } // updates the meta model - If class already exist, it returns the // metamodel class, which contains // a bit more informations NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo classInfo = AddClass(objectInfo.GetClassInfo (), true); objectInfo.SetClassInfo(classInfo); // if (isNewObject) { ManageNewObjectPointers(objectInfo, classInfo, position, metaModel); } if (NeoDatis.Odb.OdbConfiguration.SaveHistory()) { classInfo.AddHistory(new NeoDatis.Odb.Impl.Core.Layers.Layer2.Meta.History.InsertHistoryInfo ("insert", oid, position, objectInfo.GetPreviousObjectOID(), objectInfo.GetNextObjectOID ())); } fsi.SetWritePosition(position, writeDataInTransaction); objectInfo.SetPosition(position); int nbAttributes = objectInfo.GetClassInfo().GetAttributes().Count; // compute the size of the array of byte needed till the attibute // positions // BlockSize + Block Type + ObjectId + ClassInfoId + Previous + Next + // CreatDate + UpdateDate + VersionNumber + ObjectRef + isSync + NbAttri // + Attributes // Int + Int + Long + Long + Long + Long + Long + Long + int + Long + // Bool + int + variable // 7 Longs + 4Ints + 1Bool + variable int tsize = 7 * NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.SizeOfLong + 3 * NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType .SizeOfInt + 2 * NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.SizeOfByte; byte[] bytes = new byte[tsize]; // Block size byteArrayConverter.IntToByteArray(0, bytes, 0); // Block type bytes[4] = NeoDatis.Odb.Impl.Core.Layers.Layer3.Block.BlockTypes.BlockTypeNonNativeObject; // fsi.writeInt(BlockTypes.BLOCK_TYPE_NON_NATIVE_OBJECT, // writeDataInTransaction, "block size"); // The object id EncodeOid(oid, bytes, 5); // fsi.writeLong(oid.getObjectId(), writeDataInTransaction, "oid", // DefaultWriteAction.DATA_WRITE_ACTION); // Class info id byteArrayConverter.LongToByteArray(classInfo.GetId().GetObjectId(), bytes, 13); // fsi.writeLong(classInfo.getId().getObjectId(), // writeDataInTransaction, "class info id", // DefaultWriteAction.DATA_WRITE_ACTION); // previous instance EncodeOid(objectInfo.GetPreviousObjectOID(), bytes, 21); // writeOid(objectInfo.getPreviousObjectOID(), writeDataInTransaction, // "prev instance", DefaultWriteAction.DATA_WRITE_ACTION); // next instance EncodeOid(objectInfo.GetNextObjectOID(), bytes, 29); // writeOid(objectInfo.getNextObjectOID(), writeDataInTransaction, // "next instance", DefaultWriteAction.DATA_WRITE_ACTION); // creation date, for update operation must be the original one byteArrayConverter.LongToByteArray(objectInfo.GetHeader().GetCreationDate(), bytes , 37); // fsi.writeLong(objectInfo.getHeader().getCreationDate(), // writeDataInTransaction, "creation date", // DefaultWriteAction.DATA_WRITE_ACTION); byteArrayConverter.LongToByteArray(NeoDatis.Tool.Wrappers.OdbTime.GetCurrentTimeInMs (), bytes, 45); // fsi.writeLong(OdbTime.getCurrentTimeInMs(), writeDataInTransaction, // "update date", DefaultWriteAction.DATA_WRITE_ACTION); // TODO check next version number byteArrayConverter.IntToByteArray(objectInfo.GetHeader().GetObjectVersion(), bytes , 53); // fsi.writeInt(objectInfo.getHeader().getObjectVersion(), // writeDataInTransaction, "object version number"); // not used yet. But it will point to an internal object of type // ObjectReference that will have details on the references: // All the objects that point to it: to enable object integrity byteArrayConverter.LongToByteArray(-1, bytes, 57); // fsi.writeLong(-1, writeDataInTransaction, "object reference pointer", // DefaultWriteAction.DATA_WRITE_ACTION); // True if this object have been synchronized with main database, else // false byteArrayConverter.BooleanToByteArray(false, bytes, 65); // fsi.writeBoolean(false, writeDataInTransaction, // "is syncronized with external db"); // now write the number of attributes and the position of all // attributes, we do not know them yet, so write 00 but at the end // of the write operation // These positions will be updated // The positions that is going to be written are 'int' representing // the offset position of the attribute // first write the number of attributes // fsi.writeInt(nbAttributes, writeDataInTransaction, "nb attr"); byteArrayConverter.IntToByteArray(nbAttributes, bytes, 66); // Then write the array of bytes fsi.WriteBytes(bytes, writeDataInTransaction, "NonNativeObjectInfoHeader"); // Store the position long attributePositionStart = fsi.GetPosition(); int attributeSize = NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.SizeOfInt + NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType .SizeOfLong; byte[] abytes = new byte[nbAttributes * (attributeSize)]; // here, just write an empty (0) array, as real values will be set at // the end fsi.WriteBytes(abytes, writeDataInTransaction, "Empty Attributes"); long[] attributesIdentification = new long[nbAttributes]; int[] attributeIds = new int[nbAttributes]; // Puts the object info in the cache // storageEngine.getSession().getCache().addObject(position, // aoi.getObject(), objectInfo.getHeader()); NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassAttributeInfo cai = null; NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi2 = null; long nativeAttributePosition = -1; NeoDatis.Odb.OID nonNativeAttributeOid = null; long maxWritePosition = fsi.GetPosition(); // Loop on all attributes for (int i = 0; i < nbAttributes; i++) { // Gets the attribute meta description cai = classInfo.GetAttributeInfo(i); // Gets the id of the attribute attributeIds[i] = cai.GetId(); // Gets the attribute data aoi2 = objectInfo.GetAttributeValueFromId(cai.GetId()); if (aoi2 == null) { // This only happens in 1 case : when a class has a field with // the same name of one of is superclass. In this, the deeper // attribute is null if (cai.IsNative()) { aoi2 = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(cai.GetAttributeType ().GetId()); } else { aoi2 = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeNullObjectInfo(cai.GetClassInfo ()); } } if (aoi2.IsNative()) { nativeAttributePosition = InternalStoreObject((NeoDatis.Odb.Core.Layers.Layer2.Meta.NativeObjectInfo )aoi2); // For native objects , odb stores their position attributesIdentification[i] = nativeAttributePosition; } else { if (aoi2.IsObjectReference()) { NeoDatis.Odb.Core.Layers.Layer2.Meta.ObjectReference or = (NeoDatis.Odb.Core.Layers.Layer2.Meta.ObjectReference )aoi2; nonNativeAttributeOid = or.GetOid(); } else { nonNativeAttributeOid = StoreObject(null, (NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo )aoi2); } // For non native objects , odb stores its oid as a negative // number!!u if (nonNativeAttributeOid != null) { attributesIdentification[i] = -nonNativeAttributeOid.GetObjectId(); } else { attributesIdentification[i] = NeoDatis.Odb.Impl.Core.Layers.Layer3.Engine.StorageEngineConstant .NullObjectIdId; } } long p = fsi.GetPosition(); if (p > maxWritePosition) { maxWritePosition = p; } } // Updates attributes identification in the object info header objectInfo.GetHeader().SetAttributesIdentification(attributesIdentification); objectInfo.GetHeader().SetAttributesIds(attributeIds); long positionAfterWrite = maxWritePosition; // Now writes back the attribute positions fsi.SetWritePosition(attributePositionStart, writeDataInTransaction); abytes = new byte[attributesIdentification.Length * (attributeSize)]; for (int i = 0; i < attributesIdentification.Length; i++) { byteArrayConverter.IntToByteArray(attributeIds[i], abytes, i * attributeSize); byteArrayConverter.LongToByteArray(attributesIdentification[i], abytes, i * (attributeSize ) + NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType.SizeOfInt); // fsi.writeInt(attributeIds[i], writeDataInTransaction, "attr id"); // fsi.writeLong(attributesIdentification[i], // writeDataInTransaction, "att real pos", // DefaultWriteAction.DATA_WRITE_ACTION); // if (classInfo.getAttributeInfo(i).isNonNative() && // attributesIdentification[i] > 0) { if (objectInfo.GetAttributeValueFromId(attributeIds[i]).IsNonNativeObject() && attributesIdentification [i] > 0) { throw new NeoDatis.Odb.ODBRuntimeException(NeoDatis.Odb.Core.NeoDatisError.NonNativeAttributeStoredByPositionInsteadOfOid .AddParameter(classInfo.GetAttributeInfo(i).GetName()).AddParameter(classInfo.GetFullClassName ()).AddParameter(attributesIdentification[i])); } } fsi.WriteBytes(abytes, writeDataInTransaction, "Filled Attributes"); fsi.SetWritePosition(positionAfterWrite, writeDataInTransaction); int blockSize = (int)(positionAfterWrite - position); try { WriteBlockSizeAt(position, blockSize, writeDataInTransaction, objectInfo); } catch (NeoDatis.Odb.ODBRuntimeException e) { NeoDatis.Tool.DLogger.Debug("Error while writing block size. pos after write " + positionAfterWrite + " / start pos = " + position); // throw new ODBRuntimeException(storageEngine,"Error while writing // block size. pos after write " + positionAfterWrite + " / start // pos = " + position,e); throw; } if (NeoDatis.Odb.OdbConfiguration.IsDebugEnabled(LogId)) { NeoDatis.Tool.DLogger.Debug(DepthToSpaces() + " Attributes positions of object with oid " + oid + " are " + NeoDatis.Tool.DisplayUtility.LongArrayToString(attributesIdentification )); NeoDatis.Tool.DLogger.Debug(DepthToSpaces() + "End Writing non native object at " + position + " with oid " + oid + " - prev oid=" + objectInfo.GetPreviousObjectOID () + " / next oid=" + objectInfo.GetNextObjectOID()); if (NeoDatis.Odb.OdbConfiguration.IsDebugEnabled(LogIdDebug)) { NeoDatis.Tool.DLogger.Debug(" - current buffer : " + fsi.GetIo().ToString()); } } // Only insert in index for new objects if (isNewObject) { // insert object id in indexes, if exist ManageIndexesForInsert(oid, objectInfo); if (hasObject) { triggerManager.ManageInsertTriggerAfter(objectInfo.GetClassInfo().GetFullClassName (), objectInfo.GetObject(), oid); } else { // triggers triggerManager.ManageInsertTriggerAfter(objectInfo.GetClassInfo().GetFullClassName (), objectInfo, oid); } } return oid; }