/// <summary> /// Create a copy oh this meta object /// </summary> /// <param name="cache"> </param> /// <param name="onlyData"> if true, only copy attributes values </param> /// <returns> </returns> public override AbstractObjectInfo CreateCopy(IDictionary <OID, AbstractObjectInfo> cache, bool onlyData) { NonNativeObjectInfo nnoi; if (_objectHeader.GetOid() != null && cache.ContainsKey(_objectHeader.GetOid())) { nnoi = (NonNativeObjectInfo)cache[_objectHeader.GetOid()]; if (nnoi != null) { return(nnoi); } } if (_theObject == null) { return(new NonNativeNullObjectInfo(_classInfo)); } if (onlyData) { var oih = new ObjectInfoHeader(); nnoi = new NonNativeObjectInfo(_theObject, _classInfo, null, oih.GetAttributesIdentification(), oih.GetAttributeIds()); } else { nnoi = new NonNativeObjectInfo(_theObject, _classInfo, null, _objectHeader.GetAttributesIdentification(), _objectHeader.GetAttributeIds()); nnoi.GetHeader().SetOid(GetHeader().GetOid()); } var newAttributeValues = new AbstractObjectInfo[_attributeValues.Length]; for (var i = 0; i < _attributeValues.Length; i++) { newAttributeValues[i] = _attributeValues[i].CreateCopy(cache, onlyData); } nnoi._attributeValues = newAttributeValues; if (_objectHeader.GetOid() != null) { cache.Add(_objectHeader.GetOid(), nnoi); } return(nnoi); }
private NonNativeObjectInfo(object @object, ClassInfo info, AbstractObjectInfo[] values, long[] attributesIdentification, int[] attributeIds) : base(OdbType.GetFromName(info.FullClassName)) { _theObject = @object; _classInfo = info; _attributeValues = values; _maxNbattributes = _classInfo.MaxAttributeId; if (_attributeValues == null) { _attributeValues = new AbstractObjectInfo[_maxNbattributes]; } _objectHeader = new ObjectInfoHeader(-1, null, null, (_classInfo != null ? _classInfo.ClassInfoId : null), attributesIdentification, attributeIds); }
public void SetObjectInfoHeader(ObjectInfoHeader objectInfoHeader) { _objectInfoHeader = objectInfoHeader; }
public void SetHeader(ObjectInfoHeader header) { _objectHeader = header; }
public OID Delete(ObjectInfoHeader header) { var lsession = _session; var cache = lsession.GetCache(); var objectPosition = header.GetPosition(); var classInfoId = header.GetClassInfoId(); var oid = header.GetOid(); // gets class info from in memory meta model var ci = _session.GetMetaModel().GetClassInfoFromId(classInfoId); var withIndex = !ci.GetIndexes().IsEmpty(); NonNativeObjectInfo nnoi = null; // When there is index,we must *always* load the old meta representation // to compute index keys if (withIndex) nnoi = _objectReader.ReadNonNativeObjectInfoFromPosition(ci, header.GetOid(), objectPosition, true, false); // a boolean value to indicate if object is in connected zone or not // This will be used to know if work can be done out of transaction // for unconnected object,changes can be written directly, else we must // use Transaction (using WriteAction) var objectIsInConnectedZone = cache.IsInCommitedZone(header.GetOid()); // triggers _triggerManager.ManageDeleteTriggerBefore(ci.UnderlyingType, null, header.GetOid()); var previousObjectOID = header.GetPreviousObjectOID(); var nextObjectOID = header.GetNextObjectOID(); if (OdbConfiguration.IsLoggingEnabled()) { var isInConnectedZone = objectIsInConnectedZone.ToString(); var hasIndex = withIndex.ToString(); DLogger.Debug("ObjectWriter: Deleting object with id " + header.GetOid() + " - In connected zone =" + isInConnectedZone + " - with index =" + hasIndex); var positionAsString = objectPosition.ToString(); DLogger.Debug("ObjectWriter: position = " + positionAsString + " | prev oid = " + previousObjectOID + " | next oid = " + nextObjectOID); } var isFirstObject = previousObjectOID == null; var isLastObject = nextObjectOID == null; var mustUpdatePreviousObjectPointers = false; var mustUpdateNextObjectPointers = false; var mustUpdateLastObjectOfClassInfo = false; if (isFirstObject || isLastObject) { if (isFirstObject) { // The deleted object is the first, must update first instance // OID field of the class if (objectIsInConnectedZone) { // update first object oid of the class info in memory ci.CommitedZoneInfo.First = nextObjectOID; } else { // update first object oid of the class info in memory ci.UncommittedZoneInfo.First = nextObjectOID; } if (nextObjectOID != null) { // Update next object 'previous object oid' to null UpdatePreviousObjectFieldOfObjectInfo(nextObjectOID, null, objectIsInConnectedZone); mustUpdateNextObjectPointers = true; } } // It can be first and last if (isLastObject) { // The deleted object is the last, must update last instance // OID field of the class // update last object position of the class info in memory if (objectIsInConnectedZone) { // the object is a committed object ci.CommitedZoneInfo.Last = previousObjectOID; } else { // The object is not committed and it is the last and is // being deleted ci.UncommittedZoneInfo.Last = previousObjectOID; } if (previousObjectOID != null) { // Update 'next object oid' of previous object to null // if we are in unconnected zone, change can be done // directly,else it must be done in transaction UpdateNextObjectFieldOfObjectInfo(previousObjectOID, null, objectIsInConnectedZone); // Now update data of the cache mustUpdatePreviousObjectPointers = true; mustUpdateLastObjectOfClassInfo = true; } } } else { // Normal case, the deleted object has previous and next object // pull the deleted object // Mark the 'next object oid field' of the previous object // pointing the next object UpdateNextObjectFieldOfObjectInfo(previousObjectOID, nextObjectOID, objectIsInConnectedZone); // Mark the 'previous object position field' of the next object // pointing the previous object UpdatePreviousObjectFieldOfObjectInfo(nextObjectOID, previousObjectOID, objectIsInConnectedZone); mustUpdateNextObjectPointers = true; mustUpdatePreviousObjectPointers = true; } if (mustUpdateNextObjectPointers) UpdateNextObjectPreviousPointersInCache(nextObjectOID, previousObjectOID, cache); if (mustUpdatePreviousObjectPointers) { var oih = UpdatePreviousObjectNextPointersInCache(nextObjectOID, previousObjectOID, cache); if (mustUpdateLastObjectOfClassInfo) ci.LastObjectInfoHeader = oih; } var metaModel = lsession.GetMetaModel(); // Saves the fact that something has changed in the class (number of // objects and/or last object oid) metaModel.AddChangedClass(ci); if (objectIsInConnectedZone) ci.CommitedZoneInfo.DecreaseNbObjects(); else ci.UncommittedZoneInfo.DecreaseNbObjects(); // Manage deleting the last object of the committed zone CIZoneInfo commitedZoneInfo = ci.CommitedZoneInfo; var isLastObjectOfCommitedZone = oid.Equals(commitedZoneInfo.Last); if (isLastObjectOfCommitedZone) { // Load the object info header of the last committed object var oih = _objectReader.ReadObjectInfoHeaderFromOid(oid, true); // Updates last committed object id of the committed zone. // Here, it can be null, but there is no problem commitedZoneInfo.Last = oih.GetPreviousObjectOID(); // A simple check, if commitedZI.last is null, nbObject must be 0 if (commitedZoneInfo.Last == null && commitedZoneInfo.HasObjects()) { var numberbOfObjectsAsString = commitedZoneInfo.GetNumberbOfObjects().ToString(); throw new OdbRuntimeException( NDatabaseError.InternalError.AddParameter( "The last object of the commited zone has been deleted but the Zone still have objects : nbobjects=" + numberbOfObjectsAsString)); } } // Manage deleting the first object of the uncommitted zone var uncommittedZoneInfo = ci.UncommittedZoneInfo; var isFirstObjectOfUncommitedZone = oid.Equals(uncommittedZoneInfo.First); if (isFirstObjectOfUncommitedZone) { if (uncommittedZoneInfo.HasObjects()) { // Load the object info header of the first uncommitted object var oih = _objectReader.ReadObjectInfoHeaderFromOid(oid, true); // Updates first uncommitted oid with the second uncommitted oid // Here, it can be null, but there is no problem uncommittedZoneInfo.First = oih.GetNextObjectOID(); } else uncommittedZoneInfo.First = null; } if (isFirstObject && isLastObject) { // The object was the first and the last object => it was the only // object // There is no more objects of this type => must set to null the // ClassInfo LastObjectOID ci.LastObjectInfoHeader = null; } GetIdManager().UpdateIdStatus(header.GetOid(), IDStatus.Deleted); // The update of the place must be done in transaction if object is in // committed zone, else it can be done directly in the file MarkAsDeleted(objectPosition, objectIsInConnectedZone); cache.MarkIdAsDeleted(header.GetOid()); if (withIndex) ManageIndexesForDelete(header.GetOid(), nnoi); // triggers _triggerManager.ManageDeleteTriggerAfter(ci.UnderlyingType, null, header.GetOid()); return header.GetOid(); }