4.1.10.6.10 UpdateObject
-
procedure UpdateObject( replEntinfList: REPLENTINFLIST, sourcePrefixTable: PrefixTable, nc: DSName, attributesAndStamps: set of AttributeAndStamp): DWORD
Informative summary of behavior: The UpdateObject procedure performs a replicated update by applying changes on an existing object in an NC replica. This procedure has the following input parameters:
replEntinfList: The replicated update to be applied.
sourcePrefixTable: The prefix table from the server to translate attribute IDs.
nc: The root of the NC replica that is replicated.
attributesAndStamps: The AttributeAndStamp set that corresponds to the replicated update.
The method returns a Windows error code if encounters an error while updating the object.
-
updateObject: DSName stampRemote: AttributeStamp stampLocal: AttributeStamp attribute: ATTRTYP nameAttrAndStamp: AttributeAndStamp attrAndStamp: AttributeAndStamp isDeletedAttrAndStamp: AttributeAndStamp dwResult: DWORD updateObject := replEntinfList.Entinf.pName^ /* Determine if attributesAndStamps indicates a rename operation. */ nameAttrAndStamp := select one e from attributesAndStamps where (e.attribute = name) if (nameAttrAndStamp = null) then stampRemote := null else stampRemote := nameAttrAndStamp.stamp endif stampLocal := AttrStamp(updateObject, name) if (not stampRemote = null) and (AttributeStampCompare(stampRemote, stampLocal) > 0) then /* This indicates that replEntinfList provides a more recent * DN for updateObject. It is important to note here that a change * in the name attribute is interpreted as a potential change in * the full DN, not just the RDN. */ /* The NameObject function will find an appropriate, unused, local * name for the object and modify the replEntInfList appropriately */ dwResult := NameObject(replEntInfList, sourcePrefixTable, nc, attributeAndStamps) if dwResult ≠ ERROR_SUCCESS then return dwResult endif /* Perform modify operation. */ /* Compare local and remote attribute stamps and update object * attribute only if the changes are more recent than what the * client has seen. */ for i := 0 to (replEntinfList.Entinf.AttrBlock.attrCount-1) attribute := LocalAttidFromRemoteAttid( sourcePrefixTable, replEntinfList.Entinf.AttrBlock.pAttr[i].attrTyp); attrAndStamp := select one e from attributeAndStamps where (e.attribute = attribute) stampRemote := attrAndStamp.stamp stampLocal := AttrStamp(updateObject, attribute) if (not stampLocal = null) and (AttributeStampCompare(stampRemote, stampLocal) <= 0) then /* This indicates the attribute on the object in the client is * more up to date. Do not apply the replicated update * corresponding to that attribute. */ ENTINF_SetValue(replEntinfList.Entinf, attribute, null, sourcePrefixTable) attributesAndStamps := attributesAndStamps - {attrAndStamp} endif endfor dwResult := PerformModifyOperation(replEntinfList.Entinf, updateObject, sourcePrefixTable ) if dwResult ≠ ERROR_SUCCESS then return dwResult endif /* Update attribute stamps on the object to those corresponding to * the replicated updates. */ for each e in attributesAndStamps do SetAttrStamp(updateObject, e.attribute, e.stamp) endfor if updateObject!isDeleted = true then if(crossRef in updateObject!objectClass) /* If this is a cross-ref being deleted, then the respective * sub-ref object, if any, must also be deleted.*/ DelSubRef (updateObject!ncName) endif /* There might be attribute values left on this object that do not * conform to the invariants of a tombstone or deleted-object (see * MS-ADTS section 3.1.1.5.5). Delete the object again to create an * originating change of any such attribute values that need it. * This originating change will affect the metadata of updateObject, * and can explicitly affect metadata just written to the database * in the above SetAttrStamp procedure. */ dwResult := RemoveObj(updateObject,false) else isDeletedAttrAndStamp := select one e from attributesAndStamps where (e.attribute = isDeleted) if(isDeletedAttrAndStamp != null and crossRef in updateObject!objectClass) /* If this is a cross-ref being undeleted, then we must also undelete * the respective sub-ref object. */ AddSubRef (updateObject!ncName) endif endif if updateObject!isRecycled = true and IsRecycleBinEnabled() then /* There might be attribute values left on this object that do * not conform to the invariants of a recycled-object (see MS-ADTS * section 3.1.1.5.5). Recycle the object again to create an originating * change of any such attribute values that need it. This * originating change will affect the metadata of updateObject, and * can explicitly affect metadata just written to the database in * the above SetAttrStamp procedure. */ dwResult := RecycleObj(updateObject) endif return dwResult