Beispiel #1
0
        protected void WriteRUI(IRelationUpdateItem rui, IWriter writer, IncrementalMergeState state)
        {
            if (rui == null)
            {
                return;
            }
            IObjRef[] addedORIs   = rui.AddedORIs;
            IObjRef[] removedORIs = rui.RemovedORIs;

            if (addedORIs != null)
            {
                writer.WriteStartElement(rui.MemberName);
                writer.WriteAttribute("add", addedORIs.Length);
                writer.WriteStartElementEnd();
                WriteObjRefs(addedORIs, writer, state);
                writer.WriteCloseElement(rui.MemberName);
            }
            if (removedORIs != null)
            {
                writer.WriteStartElement(rui.MemberName);
                writer.WriteAttribute("remove", removedORIs.Length);
                writer.WriteStartElementEnd();
                WriteObjRefs(removedORIs, writer, state);
                writer.WriteCloseElement(rui.MemberName);
            }
        }
Beispiel #2
0
        protected IRelationUpdateItem CloneRelation(IRelationUpdateItem original)
        {
            RelationUpdateItem clone = new RelationUpdateItem();

            clone.MemberName  = original.MemberName;
            clone.AddedORIs   = CloneObjRefs(original.AddedORIs);
            clone.RemovedORIs = CloneObjRefs(original.RemovedORIs);
            return(clone);
        }
Beispiel #3
0
 public IRelationUpdateItem[] GetEnsureFullRUIs(IEntityMetaData metaData, IMap <Type, IRelationUpdateItem[]> entityTypeToFullRuis)
 {
     IRelationUpdateItem[] fullRuis = entityTypeToFullRuis.Get(metaData.EntityType);
     if (fullRuis == null)
     {
         fullRuis = new IRelationUpdateItem[metaData.RelationMembers.Length];
         entityTypeToFullRuis.Put(metaData.EntityType, fullRuis);
     }
     return(fullRuis);
 }
Beispiel #4
0
 protected IRelationUpdateItem[] CloneRelations(IRelationUpdateItem[] original)
 {
     if (original == null)
     {
         return(null);
     }
     IRelationUpdateItem[] clone = new IRelationUpdateItem[original.Length];
     for (int a = original.Length; a-- > 0;)
     {
         clone[a] = CloneRelation(original[a]);
     }
     return(clone);
 }
Beispiel #5
0
        protected virtual void AddOriModification(Object obj, String memberName, Object value, Object cloneValue, MergeHandle handle)
        {
            if (value is IList)
            {
                IList list = (IList)value;
                for (int a = 0, size = list.Count; a < size; a++)
                {
                    Object objItem = list[a];
                    MergeOrPersist(objItem, handle);
                }
            }
            else if (value is IEnumerable)
            {
                IEnumerator objEnumerator = ((IEnumerable)value).GetEnumerator();
                while (objEnumerator.MoveNext())
                {
                    Object objItem = objEnumerator.Current;
                    MergeOrPersist(objItem, handle);
                }
            }
            else
            {
                MergeOrPersist(value, handle);
            }
            try
            {
                IList <IObjRef> oldOriList = OriHelper.ExtractObjRefList(cloneValue, handle, handle.oldOriList);
                IList <IObjRef> newOriList = OriHelper.ExtractObjRefList(value, handle, handle.newOriList);

                IRelationUpdateItem oriModItem = CreateRUI(memberName, oldOriList, newOriList);
                if (oriModItem == null)
                {
                    return;
                }
                IList <IUpdateItem> modItemList = AddModification(obj, handle);

                modItemList.Add(oriModItem);
            }
            finally
            {
                handle.oldOriList.Clear();
                handle.newOriList.Clear();
            }
        }
Beispiel #6
0
 public IRelationUpdateItem[] CompactRUIs(IRelationUpdateItem[] fullRUIs, int ruiCount)
 {
     if (ruiCount == 0)
     {
         return(null);
     }
     IRelationUpdateItem[] ruis = new IRelationUpdateItem[ruiCount];
     for (int a = fullRUIs.Length; a-- > 0;)
     {
         IRelationUpdateItem rui = fullRUIs[a];
         if (rui == null)
         {
             continue;
         }
         fullRUIs[a]      = null;
         ruis[--ruiCount] = rui;
     }
     return(ruis);
 }
        public void AddRelation(IRelationUpdateItem rui)
        {
            IRelationUpdateItem[] fullRUIs = this.fullRUIs;
            if (fullRUIs == null)
            {
                fullRUIs      = new IRelationUpdateItem[relationNameToIndexMap.Count];
                this.fullRUIs = fullRUIs;
            }
            int?indexR = relationNameToIndexMap.Get(rui.MemberName);

            if (!indexR.HasValue)
            {
                throw new Exception("No relation member " + Reference.RealType.FullName + "." + rui.MemberName + " defined");
            }
            int index = indexR.Value;

            if (fullRUIs[index] == null)
            {
                ruiCount++;
            }
            fullRUIs[index] = rui;
        }
Beispiel #8
0
        public void ChangeObject(IObjRef objRef, IPrimitiveUpdateItem[] primitiveUpdates, IRelationUpdateItem[] relationUpdates, String changedBy, long changedOn)
        {
            writeLock.Lock();
            try
            {
                ILoadContainer loadContainer = refToObjectDict[objRef];

                IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(objRef.RealType);

                Object[] primitives = loadContainer.Primitives;
                if (loadContainer.Reference.Version == null)
                {
                    if (metaData.CreatedByMember != null)
                    {
                        primitives[GetPrimitiveMemberIndex(metaData, metaData.CreatedByMember.Name)] = changedBy;
                    }
                    if (metaData.CreatedOnMember != null)
                    {
                        primitives[GetPrimitiveMemberIndex(metaData, metaData.CreatedOnMember.Name)] = changedOn;
                    }
                }
                else
                {
                    if (metaData.UpdatedByMember != null)
                    {
                        primitives[GetPrimitiveMemberIndex(metaData, metaData.UpdatedByMember.Name)] = changedBy;
                    }
                    if (metaData.UpdatedOnMember != null)
                    {
                        primitives[GetPrimitiveMemberIndex(metaData, metaData.UpdatedOnMember.Name)] = changedOn;
                    }
                }

                loadContainer.Reference.Version = objRef.Version;

                if (primitiveUpdates != null)
                {
                    PrimitiveMember[] primitiveMembers = metaData.PrimitiveMembers;
                    for (int a = primitiveUpdates.Length; a-- > 0;)
                    {
                        IPrimitiveUpdateItem pui = primitiveUpdates[a];

                        Member member = metaData.GetMemberByName(pui.MemberName);
                        for (int b = primitiveMembers.Length; b-- > 0;)
                        {
                            if (primitiveMembers[b] == member)
                            {
                                primitives[b] = pui.NewValue;
                                break;
                            }
                        }
                    }
                }
                if (relationUpdates != null)
                {
                    IObjRef[][] relations = loadContainer.Relations;
                    for (int a = relationUpdates.Length; a-- > 0;)
                    {
                        IRelationUpdateItem rui = relationUpdates[a];

                        int memberIndex = metaData.GetIndexByRelationName(rui.MemberName);

                        IObjRef[] relation = relations[memberIndex];

                        List <IObjRef> newRelation = new List <IObjRef>();
                        if (relation != null)
                        {
                            for (int b = relation.Length; b-- > 0;)
                            {
                                newRelation.Add(relation[b]);
                            }
                        }
                        if (rui.RemovedORIs != null)
                        {
                            for (int b = rui.RemovedORIs.Length; b-- > 0;)
                            {
                                newRelation.Remove(rui.RemovedORIs[b]);
                            }
                        }
                        if (rui.AddedORIs != null)
                        {
                            for (int b = rui.AddedORIs.Length; b-- > 0;)
                            {
                                newRelation.Add(rui.AddedORIs[b]);
                            }
                        }
                        if (newRelation.Count == 0)
                        {
                            relations[a] = ObjRef.EMPTY_ARRAY;
                        }
                        else
                        {
                            relations[memberIndex] = newRelation.ToArray();
                        }
                    }
                }
            }
            finally
            {
                writeLock.Unlock();
            }
        }
Beispiel #9
0
        protected void ApplyRelationUpdateItem(IObjRefContainer entity, IRelationUpdateItem rui, bool isUpdate,
                                               IEntityMetaData metaData, IList <DirectValueHolderRef> toPrefetch, List <IObjRef> toFetchFromCache, bool checkBaseState,
                                               IList <IBackgroundWorkerDelegate> runnables)
        {
            IObjRefHelper  objRefHelper   = this.ObjRefHelper;
            String         memberName     = rui.MemberName;
            int            relationIndex  = metaData.GetIndexByRelationName(memberName);
            RelationMember relationMember = metaData.RelationMembers[relationIndex];

            IObjRef[] existingORIs;
            if (entity.Is__Initialized(relationIndex))
            {
                existingORIs = ListUtil.ToArray(ObjRefHelper.ExtractObjRefList(relationMember.GetValue(entity), null));
            }
            else
            {
                existingORIs = entity.Get__ObjRefs(relationIndex);
                if (existingORIs == null)
                {
                    toPrefetch.Add(new DirectValueHolderRef(entity, relationMember, true));
                    runnables.Add(new IBackgroundWorkerDelegate(delegate()
                    {
                        ApplyRelationUpdateItem(entity, rui, isUpdate, metaData, toPrefetch, toFetchFromCache, checkBaseState, runnables);
                    }));
                    return;
                }
            }
            IObjRef[] addedORIs   = rui.AddedORIs;
            IObjRef[] removedORIs = rui.RemovedORIs;

            IObjRef[] newORIs;
            if (existingORIs.Length == 0)
            {
                if (checkBaseState && removedORIs != null)
                {
                    throw new Exception("Removing from empty member");
                }
                newORIs = addedORIs != null ? (IObjRef[])addedORIs.Clone() : ObjRef.EMPTY_ARRAY;
                for (int a = newORIs.Length; a-- > 0;)
                {
                    newORIs[a] = CloneObjRef(newORIs[a], false);
                }
            }
            else
            {
                // Set to efficiently remove entries
                LinkedHashSet <IObjRef> existingORIsSet = new LinkedHashSet <IObjRef>(existingORIs);
                if (removedORIs != null)
                {
                    foreach (IObjRef removedORI in removedORIs)
                    {
                        IObjRef clonedObjRef = CloneObjRef(removedORI, false);
                        if (existingORIsSet.Remove(clonedObjRef) || !checkBaseState)
                        {
                            continue;
                        }
                        throw OptimisticLockUtil.ThrowModified(objRefHelper.EntityToObjRef(entity), null, entity);
                    }
                }
                if (addedORIs != null)
                {
                    foreach (IObjRef addedORI in addedORIs)
                    {
                        IObjRef clonedObjRef = CloneObjRef(addedORI, false);
                        if (existingORIsSet.Add(clonedObjRef) || !checkBaseState)
                        {
                            continue;
                        }
                        throw OptimisticLockUtil.ThrowModified(objRefHelper.EntityToObjRef(entity), null, entity);
                    }
                }
                if (existingORIsSet.Count == 0)
                {
                    newORIs = ObjRef.EMPTY_ARRAY;
                }
                else
                {
                    newORIs = existingORIsSet.ToArray();
                }
            }
            if (!entity.Is__Initialized(relationIndex))
            {
                entity.Set__ObjRefs(relationIndex, newORIs);
                return;
            }
            toFetchFromCache.AddRange(newORIs);
            runnables.Add(new IBackgroundWorkerDelegate(delegate()
            {
                ICache stateCache      = cloneStateTL.Value.incrementalState.GetStateCache();
                IList <Object> objects = stateCache.GetObjects(newORIs, CacheDirective.FailEarly);
                Object value;
                if (relationMember.IsToMany)
                {
                    // To-many relation
                    Object coll = ListUtil.CreateObservableCollectionOfType(relationMember.RealType, objects.Count);
                    ListUtil.FillList(coll, objects);
                    value = coll;
                }
                else
                {
                    // To-one relation
                    value = objects.Count > 0 ? objects[0] : null;
                }
                relationMember.SetValue(entity, value);
            }));
        }
Beispiel #10
0
        protected bool EqualsRUI(CUDResultDiff cudResultDiff, IRelationUpdateItem left, IRelationUpdateItem right)
        {
            // we do NOT have to check each relational ObjRef because IF an objRef is in the scope it must not be removed afterwards
            // so we know by design that the arrays can only grow

            try
            {
                IObjRef[] leftORIs  = left.AddedORIs;
                IObjRef[] rightORIs = right.AddedORIs;

                if (leftORIs == null)
                {
                    if (rightORIs != null)
                    {
                        if (!cudResultDiff.doFullDiff)
                        {
                            return(false);
                        }
                        RelationUpdateItemBuild relationBuild = cudResultDiff.UpdateRelationBuild();
                        relationBuild.AddObjRefs(rightORIs);
                    }
                }
                else if (rightORIs == null)
                {
                    throw new Exception("Must never happen");
                }
                else if (leftORIs.Length != rightORIs.Length)
                {
                    if (!cudResultDiff.doFullDiff)
                    {
                        return(false);
                    }
                    throw new Exception("Not yet implemented");
                }
                leftORIs  = left.RemovedORIs;
                rightORIs = right.RemovedORIs;
                if (leftORIs == null)
                {
                    if (rightORIs != null)
                    {
                        if (!cudResultDiff.doFullDiff)
                        {
                            return(false);
                        }
                        RelationUpdateItemBuild relationBuild = cudResultDiff.UpdateRelationBuild();
                        relationBuild.RemoveObjRefs(rightORIs);
                    }
                }
                else if (rightORIs == null)
                {
                    throw new Exception("Must never happen");
                }
                else if (leftORIs.Length != rightORIs.Length)
                {
                    if (!cudResultDiff.doFullDiff)
                    {
                        return(false);
                    }
                    throw new Exception("Not yet implemented");
                }
                return(true);
            }
            finally
            {
                cudResultDiff.relationBuild = null;
            }
        }
Beispiel #11
0
        protected bool EqualsRUIs(CUDResultDiff cudResultDiff, IRelationUpdateItem[] left, IRelationUpdateItem[] right)
        {
            if (left == null || left.Length == 0)
            {
                if (right == null || right.Length == 0)
                {
                    return(true);
                }
                if (cudResultDiff.doFullDiff)
                {
                    CreateOrUpdateContainerBuild containerBuild = cudResultDiff.UpdateContainerBuild();
                    foreach (IRelationUpdateItem rightRui in right)
                    {
                        containerBuild.AddRelation(rightRui);
                    }
                }
                return(false);
            }
            if (right == null || right.Length == 0)
            {
                throw new Exception("Must never happen");
            }
            if (left.Length != right.Length)
            {
                if (!cudResultDiff.doFullDiff)
                {
                    return(false);
                }
                int leftIndex = left.Length - 1;
                for (int rightIndex = right.Length; rightIndex-- > 0;)
                {
                    IRelationUpdateItem leftRui  = leftIndex >= 0 ? left[leftIndex] : null;
                    IRelationUpdateItem rightRui = right[rightIndex];
                    if (leftRui == null || !leftRui.MemberName.Equals(rightRui.MemberName))
                    {
                        CreateOrUpdateContainerBuild containerBuild = cudResultDiff.UpdateContainerBuild();
                        containerBuild.AddRelation(rightRui);
                        continue;
                    }
                    if (!EqualsRUI(cudResultDiff, leftRui, rightRui))
                    {
                        if (!cudResultDiff.doFullDiff)
                        {
                            return(false);
                        }
                    }
                    leftIndex--;
                }
                return(false);
            }
            bool isEqual = true;

            for (int a = left.Length; a-- > 0;)
            {
                IRelationUpdateItem rightPui = right[a];
                if (!EqualsRUI(cudResultDiff, left[a], rightPui))
                {
                    if (!cudResultDiff.doFullDiff)
                    {
                        return(false);
                    }
                    isEqual = false;
                }
            }
            return(isEqual);
        }
Beispiel #12
0
        protected virtual void RemoveUnpersistedDeletedObjectsFromCudResult(IList <IChangeContainer> allChanges, IList <Object> originalRefs, IList <Object> unpersistedObjectsToDelete)
        {
            ISet <IObjRef> removedDirectObjRefs = null;

            for (int a = allChanges.Count; a-- > 0;)
            {
                IChangeContainer changeContainer = allChanges[a];
                IObjRef          objRef          = changeContainer.Reference;
                if (!(changeContainer is DeleteContainer) || objRef.Id != null)
                {
                    continue;
                }
                if (removedDirectObjRefs == null)
                {
                    removedDirectObjRefs = new IdentityHashSet <IObjRef>();
                }
                IDirectObjRef dirObjRef = (IDirectObjRef)objRef;
                // These are objects without an id but are marked as deleted. They will be deleted locally without transfer to the service
                allChanges.RemoveAt(a);
                originalRefs.RemoveAt(a);
                unpersistedObjectsToDelete.Add(dirObjRef.Direct);
                removedDirectObjRefs.Add(dirObjRef);
            }
            if (removedDirectObjRefs == null)
            {
                return;
            }
            // Scan all other changeContainer if they refer to the removed DeleteContainers of unpersisted entities
            for (int a = allChanges.Count; a-- > 0;)
            {
                IChangeContainer      changeContainer = allChanges[a];
                IRelationUpdateItem[] relations;
                if (changeContainer is CreateContainer)
                {
                    relations = ((CreateContainer)changeContainer).Relations;
                }
                else if (changeContainer is UpdateContainer)
                {
                    relations = ((UpdateContainer)changeContainer).Relations;
                }
                else
                {
                    // DeleteContainers can not refer anything beside themselves
                    continue;
                }
                if (relations == null)
                {
                    continue;
                }
                for (int b = relations.Length; b-- > 0;)
                {
                    IRelationUpdateItem childItem = relations[b];
                    IObjRef[]           addedOris = childItem.AddedORIs;
                    if (addedOris == null)
                    {
                        continue;
                    }
                    for (int c = addedOris.Length; c-- > 0;)
                    {
                        IObjRef addedOri = addedOris[c];
                        if (!removedDirectObjRefs.Contains(addedOri))
                        {
                            continue;
                        }
                        if (addedOris.Length == 1)
                        {
                            if (childItem.RemovedORIs != null)
                            {
                                ((RelationUpdateItem)childItem).AddedORIs = null;
                            }
                            else
                            {
                                if (relations.Length == 1)
                                {
                                    allChanges.RemoveAt(a);
                                    originalRefs.RemoveAt(a);
                                    relations = null;
                                    break;
                                }
                                IRelationUpdateItem[] newChildItems = new IRelationUpdateItem[relations.Length - 1];
                                Array.Copy(relations, 0, newChildItems, 0, b);
                                Array.Copy(relations, b + 1, newChildItems, b, relations.Length - b - 1);
                                relations = newChildItems;
                                if (changeContainer is CreateContainer)
                                {
                                    ((CreateContainer)changeContainer).Relations = relations;
                                }
                                else
                                {
                                    ((UpdateContainer)changeContainer).Relations = relations;
                                }
                            }
                            break;
                        }
                        IObjRef[] newAddedOris = new IObjRef[addedOris.Length - 1];
                        Array.Copy(addedOris, 0, newAddedOris, 0, c);
                        Array.Copy(addedOris, c + 1, newAddedOris, c, addedOris.Length - c - 1);
                        addedOris = newAddedOris;
                        ((RelationUpdateItem)childItem).AddedORIs = addedOris;
                    }
                    if (relations == null)
                    {
                        break;
                    }
                }
            }
        }