Пример #1
0
        protected override bool EqualKeys(PrioMembersKey key, MapEntry <PrioMembersKey, IdentityLinkedSet <Member> > entry)
        {
            PrioMembersKey other = entry.Key;

            if (key == other)
            {
                return(true);
            }
            IdentityLinkedSet <Member> key1      = key.Key1;
            IdentityLinkedSet <Member> otherKey1 = other.Key1;

            if (key1.Count != otherKey1.Count)
            {
                return(false);
            }
            foreach (Member item in key1)
            {
                if (!otherKey1.Contains(item))
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #2
0
        public void AddMembers(EntityMetaData metaData, IEntityConfig entityConfig)
        {
            Type realType = entityConfig.RealType;

            ISet <String>                      memberNamesToIgnore      = new HashSet <String>();
            ISet <String>                      explicitBasicMemberNames = new HashSet <String>();
            IList <IMemberConfig>              embeddedMembers          = new List <IMemberConfig>();
            IMap <String, IMemberConfig>       nameToMemberConfig       = new HashMap <String, IMemberConfig>();
            IMap <String, IRelationConfig>     nameToRelationConfig     = new HashMap <String, IRelationConfig>();
            IdentityLinkedMap <String, Member> nameToMemberMap          = new IdentityLinkedMap <String, Member>();

            FillNameCollections(entityConfig, memberNamesToIgnore, explicitBasicMemberNames, embeddedMembers, nameToMemberConfig, nameToRelationConfig);

            IdentityLinkedSet <PrimitiveMember> alternateIdMembers = new IdentityLinkedSet <PrimitiveMember>();
            IdentityLinkedSet <PrimitiveMember> primitiveMembers   = new IdentityLinkedSet <PrimitiveMember>();
            IdentityLinkedSet <RelationMember>  relationMembers    = new IdentityLinkedSet <RelationMember>();
            IdentityLinkedSet <Member>          notMergeRelevant   = new IdentityLinkedSet <Member>();

            IdentityLinkedSet <Member> containedInAlternateIdMember = new IdentityLinkedSet <Member>();

            IPropertyInfo[] properties = PropertyInfoProvider.GetProperties(realType);

            IdentityLinkedMap <String, Member> explicitlyConfiguredMemberNameToMember = new IdentityLinkedMap <String, Member>();

            HashMap <String, IOrmConfig> nameToConfigMap = new HashMap <String, IOrmConfig>();

            // Resolve members for all explicit configurations - both simple and composite ones, each with embedded
            // functionality (dot-member-path)
            foreach (IMemberConfig memberConfig in entityConfig.GetMemberConfigIterable())
            {
                PutNameToConfigMap(memberConfig, nameToConfigMap);
                if (memberConfig.Ignore)
                {
                    continue;
                }
                HandleMemberConfig(metaData, realType, memberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap);
            }
            foreach (IRelationConfig relationConfig in entityConfig.GetRelationConfigIterable())
            {
                PutNameToConfigMap(relationConfig, nameToConfigMap);
                HandleRelationConfig(realType, relationConfig, explicitlyConfiguredMemberNameToMember);
            }
            PutNameToConfigMap(entityConfig.IdMemberConfig, nameToConfigMap);
            PutNameToConfigMap(entityConfig.VersionMemberConfig, nameToConfigMap);
            PutNameToConfigMap(entityConfig.CreatedByMemberConfig, nameToConfigMap);
            PutNameToConfigMap(entityConfig.CreatedOnMemberConfig, nameToConfigMap);
            PutNameToConfigMap(entityConfig.UpdatedByMemberConfig, nameToConfigMap);
            PutNameToConfigMap(entityConfig.UpdatedOnMemberConfig, nameToConfigMap);

            metaData.IdMember        = HandleMemberConfig(metaData, realType, entityConfig.IdMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap);
            metaData.VersionMember   = HandleMemberConfig(metaData, realType, entityConfig.VersionMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap);
            metaData.CreatedByMember = HandleMemberConfig(metaData, realType, entityConfig.CreatedByMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap);
            metaData.CreatedOnMember = HandleMemberConfig(metaData, realType, entityConfig.CreatedOnMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap);
            metaData.UpdatedByMember = HandleMemberConfig(metaData, realType, entityConfig.UpdatedByMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap);
            metaData.UpdatedOnMember = HandleMemberConfig(metaData, realType, entityConfig.UpdatedOnMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap);

            IdentityHashSet <Member> idMembers = new IdentityHashSet <Member>();
            Member idMember = metaData.IdMember;

            if (idMember is CompositeIdMember)
            {
                idMembers.AddAll(((CompositeIdMember)idMember).Members);
            }
            else
            {
                idMembers.Add(idMember);
            }

            // Handle all explicitly configured members
            foreach (Entry <String, Member> entry in explicitlyConfiguredMemberNameToMember)
            {
                String     memberName = entry.Key;
                IOrmConfig ormConfig  = nameToConfigMap.Get(memberName);

                Member member = entry.Value;

                if (idMembers.Contains(member))
                {
                    continue;
                }
                if (ormConfig.ExplicitlyNotMergeRelevant)
                {
                    notMergeRelevant.Add(member);
                }
                if (ormConfig is IRelationConfig)
                {
                    if (!relationMembers.Add((RelationMember)member))
                    {
                        throw new Exception("Member has been registered as relation multiple times: " + member.Name);
                    }
                    continue;
                }
                if (!(ormConfig is IMemberConfig))
                {
                    continue;
                }
                if (((IMemberConfig)ormConfig).AlternateId)
                {
                    if (!alternateIdMembers.Add((PrimitiveMember)member))
                    {
                        throw new Exception("Member has been registered as alternate id multiple times: " + member.Name);
                    }
                    if (member is CompositeIdMember)
                    {
                        Member[] containedMembers = ((CompositeIdMember)member).Members;
                        containedInAlternateIdMember.AddAll(containedMembers);
                    }
                }
                if (!(member is CompositeIdMember) && metaData.VersionMember != member)
                {
                    // Alternate Ids are normally primitives, too. But Composite Alternate Ids not - only their composite
                    // items are primitives
                    primitiveMembers.Add((PrimitiveMember)member);
                }
            }
            IdentityHashSet <String> explicitTypeInfoItems = IdentityHashSet <String> .Create(explicitlyConfiguredMemberNameToMember.Count);

            foreach (Entry <String, Member> entry in explicitlyConfiguredMemberNameToMember)
            {
                Member member = entry.Value;
                explicitTypeInfoItems.Add(member.Name);
                if (member is IEmbeddedMember)
                {
                    explicitTypeInfoItems.Add(((IEmbeddedMember)member).GetMemberPath()[0].Name);
                }
            }
            // Go through the available members to look for potential auto-mapping (simple, no embedded)
            for (int i = 0; i < properties.Length; i++)
            {
                IPropertyInfo property   = properties[i];
                String        memberName = property.Name;
                if (memberNamesToIgnore.Contains(memberName))
                {
                    continue;
                }
                if (explicitTypeInfoItems.Contains(memberName))
                {
                    // already configured, no auto mapping needed for this member
                    continue;
                }

                MethodPropertyInfo mProperty = (MethodPropertyInfo)property;
                Type elementType             = TypeInfoItemUtil.GetElementTypeUsingReflection(mProperty.Getter.ReturnType, null);
                if ((nameToMemberMap.Get(property.Name) is RelationMember) || RelationProvider.IsEntityType(elementType))
                {
                    RelationMember member = GetRelationMember(metaData.EntityType, property, nameToMemberMap);
                    relationMembers.Add(member);
                    continue;
                }
                PrimitiveMember member2 = GetPrimitiveMember(metaData.EntityType, property, nameToMemberMap);
                if (metaData.IdMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_ID))
                {
                    metaData.IdMember = member2;
                    continue;
                }
                if (idMembers.Contains(member2) && !alternateIdMembers.Contains(member2) && !containedInAlternateIdMember.Contains(member2))
                {
                    continue;
                }
                if (member2.Equals(metaData.IdMember) || member2.Equals(metaData.VersionMember) || member2.Equals(metaData.CreatedByMember) ||
                    member2.Equals(metaData.CreatedOnMember) || member2.Equals(metaData.UpdatedByMember) || member2.Equals(metaData.UpdatedOnMember))
                {
                    continue;
                }
                if (metaData.VersionMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_VERSION))
                {
                    metaData.VersionMember = member2;
                    continue;
                }
                if (metaData.CreatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_BY))
                {
                    metaData.CreatedByMember = member2;
                }
                else if (metaData.CreatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_ON))
                {
                    metaData.CreatedOnMember = member2;
                }
                else if (metaData.UpdatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_BY))
                {
                    metaData.UpdatedByMember = member2;
                }
                else if (metaData.UpdatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_ON))
                {
                    metaData.UpdatedOnMember = member2;
                }
                primitiveMembers.Add(member2);
            }
            foreach (PrimitiveMember member in primitiveMembers)
            {
                String memberName = member.Name;
                if (explicitBasicMemberNames.Contains(memberName))
                {
                    // Even if the name would match, this member was explicitly configured as "basic"
                    continue;
                }
                if (metaData.CreatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_BY))
                {
                    metaData.CreatedByMember = member;
                }
                else if (metaData.CreatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_ON))
                {
                    metaData.CreatedOnMember = member;
                }
                else if (metaData.UpdatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_BY))
                {
                    metaData.UpdatedByMember = member;
                }
                else if (metaData.UpdatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_ON))
                {
                    metaData.UpdatedOnMember = member;
                }
            }
            FilterWrongRelationMappings(relationMembers);
            // Order of setter calls is important
            PrimitiveMember[] primitives   = primitiveMembers.ToArray();
            PrimitiveMember[] alternateIds = alternateIdMembers.ToArray();
            RelationMember[]  relations    = relationMembers.ToArray();
            Array.Sort(primitives);
            Array.Sort(alternateIds);
            Array.Sort(relations);
            metaData.PrimitiveMembers   = primitives;
            metaData.AlternateIdMembers = alternateIds;
            metaData.RelationMembers    = relations;

            foreach (Member member in notMergeRelevant)
            {
                metaData.SetMergeRelevant(member, false);
            }
            if (metaData.IdMember == null)
            {
                throw new Exception("No ID member could be resolved for entity of type " + metaData.RealType);
            }
        }
Пример #3
0
        public IdentityLinkedSet <Member> GetPrioMembers(ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchPath,
                                                         List <PrefetchCommand> pendingPrefetchCommands, MergePrefetchPathsCache mergePrefetchPathsCache)
        {
            IdentityLinkedSet <Member> key1 = new IdentityLinkedSet <Member>();
            PrioMembersKey             key  = new PrioMembersKey(entityTypeToPrefetchPath, key1);

            for (int a = 0, size = pendingPrefetchCommands.Count; a < size; a++)
            {
                PrefetchCommand prefetchCommand = pendingPrefetchCommands[a];
                key1.Add(prefetchCommand.valueHolder.Member);
            }
            IdentityLinkedSet <Member> prioMembersMap = activeMembersToPrioMembersMap.Get(key);

            if (prioMembersMap != null)
            {
                return(prioMembersMap);
            }
            prioMembersMap = new IdentityLinkedSet <Member>(0.5f);
            Tuple2KeyHashMap <Type, PrefetchPath[], bool?> alreadyVisited = null;
            IdentityHashSet <Type> touchedTypesInPriority = null;

            if (mergePrefetchPathsCache == null)
            {
                mergePrefetchPathsCache = new MergePrefetchPathsCache(entityMetaDataProvider);
            }
            bool prio2Mode = true;

            foreach (PrefetchCommand prefetchCommand in pendingPrefetchCommands)
            {
                DirectValueHolderRef valueHolder   = prefetchCommand.valueHolder;
                PrefetchPath[]       prefetchPaths = prefetchCommand.prefetchPaths;
                RelationMember       member        = valueHolder.Member;

                Type targetEntityType = member.ElementType;
                // Merge the root prefetch path with the relative prefetch path
                prefetchPaths = mergePrefetchPathsCache.MergePrefetchPaths(targetEntityType, prefetchPaths, entityTypeToPrefetchPath);

                IEntityMetaData metaData = valueHolder.Vhc.Get__EntityMetaData();

                if (targetEntityType.Equals(metaData.EntityType))
                {
                    // prio1 overrides prio2
                    if (prio2Mode)
                    {
                        prio2Mode      = false;
                        alreadyVisited = null;
                        prioMembersMap.Clear();
                        if (touchedTypesInPriority != null)
                        {
                            touchedTypesInPriority.Clear();
                        }
                    }
                    prioMembersMap.Add(member);
                    if (touchedTypesInPriority == null)
                    {
                        touchedTypesInPriority = new IdentityHashSet <Type>();
                    }
                    touchedTypesInPriority.Add(member.EntityType);
                    touchedTypesInPriority.Add(targetEntityType);
                    continue;
                }
                if (prefetchPaths == null || !prio2Mode)
                {
                    continue;
                }
                if (alreadyVisited == null)
                {
                    alreadyVisited = new Tuple2KeyHashMap <Type, PrefetchPath[], bool?>();
                }
                if (IsPrio2Member(metaData, entityMetaDataProvider.GetMetaData(targetEntityType), prefetchPaths, entityTypeToPrefetchPath, alreadyVisited,
                                  mergePrefetchPathsCache))
                {
                    prioMembersMap.Add(member);
                    if (touchedTypesInPriority == null)
                    {
                        touchedTypesInPriority = new IdentityHashSet <Type>();
                    }
                    touchedTypesInPriority.Add(member.EntityType);
                    touchedTypesInPriority.Add(targetEntityType);
                }
            }
            if (prioMembersMap.Count > 0)
            {
                // check for out-of-order members which have nothing to do (and will never ever have in a transitive manner) with the priorized members
                foreach (PrefetchCommand prefetchCommand in pendingPrefetchCommands)
                {
                    DirectValueHolderRef valueHolder = prefetchCommand.valueHolder;
                    RelationMember       member      = valueHolder.Member;

                    if (prioMembersMap.Contains(member))
                    {
                        // already priorized
                        continue;
                    }
                    if (touchedTypesInPriority.Contains(member.EntityType) || touchedTypesInPriority.Contains(member.ElementType))
                    {
                        continue;
                    }
                    prioMembersMap.Add(member);
                }
            }
            Object writeLock = activeMembersToPrioMembersMap.GetWriteLock();

            lock (writeLock)
            {
                IdentityLinkedSet <Member> existingPrioMembersMap = activeMembersToPrioMembersMap.Get(key);
                if (existingPrioMembersMap != null)
                {
                    return(existingPrioMembersMap);
                }
                activeMembersToPrioMembersMap.Put(key, prioMembersMap);
                return(prioMembersMap);
            }
        }
Пример #4
0
        protected void LoadAndAddOrels(ICacheIntern cache, IMap <IObjRelation, bool> orelsToLoad, IList <Object> hardRefList,
                                       IMap <ICacheIntern, IISet <IObjRelation> > cacheToOrelsLoadedHistory, ILinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisToLoad,
                                       IdentityLinkedSet <Member> prioMembers)
        {
            IList <IObjRelation> objRelList;

            if (prioMembers.Count > 0)
            {
                objRelList = new List <IObjRelation>(orelsToLoad.Count);
                IEntityMetaDataProvider entityMetaDataProvider = this.EntityMetaDataProvider;
                foreach (Entry <IObjRelation, Boolean> entry in orelsToLoad)
                {
                    IObjRelation    objRel       = entry.Key;
                    IEntityMetaData metaData     = entityMetaDataProvider.GetMetaData(objRel.RealType);
                    RelationMember  memberByName = (RelationMember)metaData.GetMemberByName(objRel.MemberName);
                    if (!prioMembers.Contains(memberByName))
                    {
                        continue;
                    }
                    objRelList.Add(objRel);
                }
            }
            else
            {
                objRelList = orelsToLoad.KeyList();
            }
            IList <IObjRelationResult> objRelResults = cache.GetObjRelations(objRelList, cache, CacheDirective.ReturnMisses);

            IISet <IObjRef> orisToLoad = null;

            for (int a = 0, size = objRelResults.Count; a < size; a++)
            {
                IObjRelation       objRel       = objRelList[a];
                IObjRelationResult objRelResult = objRelResults[a];
                bool objRefsOnly = orelsToLoad.Remove(objRel);
                if (objRelResult == null)
                {
                    continue;
                }
                if (orelsToLoad.Get(objRel))
                {
                    // fetch only the objRefs, not the objects themselves
                    continue;
                }
                IObjRef[] relations = objRelResult.Relations;

                if (relations.Length == 0 || objRefsOnly)
                {
                    // fetch only the objRefs, not the objects themselves
                    continue;
                }
                if (orisToLoad == null)
                {
                    orisToLoad = cacheToOrisToLoad.Get(cache);
                    if (orisToLoad == null)
                    {
                        orisToLoad = new CHashSet <IObjRef>();
                        cacheToOrisToLoad.Put(cache, orisToLoad);
                    }
                }
                orisToLoad.AddAll(relations);
            }
            IISet <IObjRelation> orelsLoadedHistory = cacheToOrelsLoadedHistory.Get(cache);

            if (orelsLoadedHistory == null)
            {
                orelsLoadedHistory = new CHashSet <IObjRelation>();
                cacheToOrelsLoadedHistory.Put(cache, orelsLoadedHistory);
            }
            orelsLoadedHistory.AddAll(objRelList);
        }
Пример #5
0
        protected void ProcessPendingOrelsAndObjRefs(ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchPath,
                                                     AlreadyHandledSet alreadyHandledSet, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisLoadedHistory,
                                                     IdentityLinkedMap <ICacheIntern, IISet <IObjRelation> > cacheToOrelsLoadedHistory, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisToLoad,
                                                     IdentityLinkedMap <ICacheIntern, IMap <IObjRelation, bool> > cacheToOrelsToLoad, List <PrefetchCommand> pendingPrefetchCommands,
                                                     List <Object> hardRefList)
        {
            // all relation members where at least one instance of the owning entity type needs a prefetch on this member in the immediate next step
            MergePrefetchPathsCache mergePrefetchPathsCache = new MergePrefetchPathsCache(EntityMetaDataProvider);

            IdentityLinkedSet <Member> prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache);

            LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers);
            LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory);

            while (pendingPrefetchCommands.Count > 0)
            {
                PrefetchCommand[] currentPrefetchCommands = pendingPrefetchCommands.ToArray();
                // Clear the items to be ready for cascaded items in new batch recursion step
                pendingPrefetchCommands.Clear();
                if (prioMembers.Count > 0)
                {
                    for (int a = 0, size = currentPrefetchCommands.Length; a < size; a++)
                    {
                        PrefetchCommand      prefetchCommand = currentPrefetchCommands[a];
                        DirectValueHolderRef valueHolder     = prefetchCommand.valueHolder;
                        if (!prioMembers.Contains(valueHolder.Member))
                        {
                            currentPrefetchCommands[a] = null;
                            pendingPrefetchCommands.Add(prefetchCommand);
                        }
                    }
                }
                GuiThreadHelper.InvokeInGuiAndWait(delegate()
                {
                    ICacheModification cacheModification = CacheModification;
                    ValueHolderContainerMixin valueHolderContainerMixin = ValueHolderContainerMixin;
                    bool oldActive = cacheModification.Active;
                    if (!oldActive)
                    {
                        cacheModification.Active = true;
                    }
                    try
                    {
                        foreach (PrefetchCommand prefetchCommand in currentPrefetchCommands)
                        {
                            if (prefetchCommand == null)
                            {
                                continue;
                            }
                            DirectValueHolderRef valueHolder = prefetchCommand.valueHolder;
                            PrefetchPath[] cachePaths        = prefetchCommand.prefetchPaths;

                            RelationMember member = valueHolder.Member;
                            // Merge the root prefetch path with the relative prefetch path
                            cachePaths = mergePrefetchPathsCache.MergePrefetchPaths(member.ElementType, cachePaths, entityTypeToPrefetchPath);

                            IObjRefContainer vhc = valueHolder.Vhc;
                            ICacheIntern targetCache;
                            bool doSetValue = false;
                            if (valueHolder is IndirectValueHolderRef)
                            {
                                IndirectValueHolderRef valueHolderKey = (IndirectValueHolderRef)valueHolder;
                                targetCache = valueHolderKey.RootCache;
                            }
                            else
                            {
                                targetCache = ((IValueHolderContainer)vhc).__TargetCache;
                                doSetValue  = true;
                            }
                            int relationIndex = vhc.Get__EntityMetaData().GetIndexByRelation(member);
                            IObjRef[] objRefs = vhc.Get__ObjRefs(relationIndex);
                            Object obj        = valueHolderContainerMixin.GetValue(vhc, relationIndex, member, targetCache, objRefs, CacheDirective.FailEarly);
                            if (doSetValue && obj != null)
                            {
                                member.SetValue(vhc, obj);
                            }
                            EnsureInitializedRelationsIntern3(obj, cachePaths, entityTypeToPrefetchPath, cacheToOrisToLoad, cacheToOrelsToLoad, cacheToOrisLoadedHistory,
                                                              cacheToOrelsLoadedHistory, alreadyHandledSet, pendingPrefetchCommands);
                        }
                    }
                    finally
                    {
                        if (!oldActive)
                        {
                            cacheModification.Active = false;
                        }
                    }
                });
                // Remove all oris which have already been tried to load before
                if (cacheToOrisToLoad.Count == 0 && cacheToOrelsToLoad.Count == 0 && pendingPrefetchCommands.Count == 0)
                {
                    return;
                }
                prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache);
                LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers);
                LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory);
            }
        }