Esempio n. 1
0
        private void UpdateLowerLevels(IExpressionNode myNode, LevelKey myCurrentLevelKey, IEnumerable<LevelKey> myLowerLevelKeys, IExpressionGraph myGraph)
        {
            if (myCurrentLevelKey.Level > 0)
            {
                lock (myGraph)
                {
                    //iterate the next lower LevelKeys
                    foreach (var aLowerLevelKey in myLowerLevelKeys)
                    {
                        #region data

                        //get next lower attribute (might be more than one step away)
                        int levelDistance = myCurrentLevelKey.Level - aLowerLevelKey.Level;
                        //GraphDBType currentType = null;
                        EdgeKey myCurrentBackwardEdgekey = null;
                        TypeAttribute currentAttribute = null;
                        SettingInvalidReferenceHandling invalidReferenceSetting = null;

                        #endregion

                        if (levelDistance >= 1)
                        {
                            if (myCurrentLevelKey.Level > 1)
                            {
                                myCurrentBackwardEdgekey = myCurrentLevelKey.Edges[myCurrentLevelKey.Level - 1];
                            }
                            else
                            {
                                myCurrentBackwardEdgekey = myCurrentLevelKey.Edges[0];
                            }
                        }
                        else
                        {
                            throw new GraphDBException(new Error_ExpressionGraphInternal(new System.Diagnostics.StackTrace(true), "Distances below 1 are not valid."));
                        }

                        IEnumerable<ObjectUUID> referencedUUIDs = null;
                        GraphDBType referencedType = null;
                        currentAttribute = _DBContext.DBTypeManager.GetTypeByUUID(myCurrentBackwardEdgekey.TypeUUID).GetTypeAttributeByUUID(myCurrentBackwardEdgekey.AttrUUID);

                        if (currentAttribute.IsBackwardEdge)
                        {
                            var backwardEdgeTypeInfo = currentAttribute.BackwardEdgeDefinition.GetTypeAndAttributeInformation(_DBContext.DBTypeManager);

                            var dbObjectStream = myNode.GetDBObjectStream(_DBObjectCache, backwardEdgeTypeInfo.Item1.UUID);

                            referencedType = backwardEdgeTypeInfo.Item2.GetDBType(_DBContext.DBTypeManager);

                            if (dbObjectStream.HasAttribute(backwardEdgeTypeInfo.Item2.UUID, backwardEdgeTypeInfo.Item1))
                            {
                                referencedUUIDs = GetUUIDsForAttribute(dbObjectStream, backwardEdgeTypeInfo.Item2, backwardEdgeTypeInfo.Item1);
                            }
                        }
                        else
                        {
                            referencedType = currentAttribute.GetRelatedType(_DBContext.DBTypeManager);

                            if (myNode.BackwardEdges.ContainsKey(aLowerLevelKey.LastEdge))
                            {
                                //take the edges that are already available

                                referencedUUIDs = myNode.BackwardEdges[aLowerLevelKey.LastEdge].Select(item => item.Destination);
                            }
                            else
                            {
                                //load the backward edge stream
                                var currentBackwardEdgeStream = _DBObjectCache.LoadDBBackwardEdgeStream(currentAttribute.GetDBType(_DBContext.DBTypeManager), myNode.GetObjectUUID());

                                if (currentBackwardEdgeStream.Failed())
                                {
                                    throw new GraphDBException(new Error_CouldNotLoadBackwardEdge(myNode.GetDBObjectStream(_DBObjectCache, currentAttribute.GetRelatedType(_DBContext.DBTypeManager).UUID), currentAttribute, currentBackwardEdgeStream.IErrors));
                                }

                                if (currentBackwardEdgeStream.Value.ContainsBackwardEdge(myCurrentBackwardEdgekey))
                                {
                                    referencedUUIDs = currentBackwardEdgeStream.Value.GetBackwardEdgeUUIDs(myCurrentBackwardEdgekey);
                                }

                            }
                        }

                        if (referencedUUIDs != null)
                        {
                            var lowerLevelKeys = ExtractLowerLevelKeys(GetPreviousLevel(aLowerLevelKey.Level, myGraph.Levels), aLowerLevelKey, myGraph);

                            EdgeKey edgeKeyForBackwardEdge = null;
                            //get edgeKey for backwardEdge
                            if (myCurrentLevelKey.Level == 1)
                            {
                                edgeKeyForBackwardEdge = aLowerLevelKey.LastEdge;
                            }
                            else
                            {
                                edgeKeyForBackwardEdge = aLowerLevelKey.Edges[aLowerLevelKey.Level - 1];
                            }

                            Exceptional<DBObjectStream> referencedDBObject = null;

                            foreach (var aReferenceObjectUUID in referencedUUIDs)
                            {
                                referencedDBObject = _DBObjectCache.LoadDBObjectStream(referencedType, aReferenceObjectUUID);

                                if (!referencedDBObject.Success())
                                {
                                    #region error

                                    if (invalidReferenceSetting == null)
                                    {
                                        invalidReferenceSetting = (SettingInvalidReferenceHandling)_DBContext.DBSettingsManager.GetSetting(SettingInvalidReferenceHandling.UUID, _DBContext, Enums.TypesSettingScope.ATTRIBUTE, referencedType, currentAttribute).Value;
                                    }

                                    switch (invalidReferenceSetting.Behaviour)
                                    {
                                        case BehaviourOnInvalidReference.ignore:
                                            #region ignore

                                            //set lower levelKeys to null because it is not possible to go any lower
                                            AddNodeRecursiveBackward(aReferenceObjectUUID, myNode.GetObjectUUID(), myCurrentLevelKey, aLowerLevelKey, null, myGraph);
                                            myNode.AddBackwardEdge(edgeKeyForBackwardEdge, aReferenceObjectUUID, null);

                                            #endregion
                                            break;
                                        case BehaviourOnInvalidReference.log:

                                            AddWarning(new Warning_EdgeToNonExistingNode(myNode.GetDBObjectStream(_DBObjectCache, referencedType.UUID), currentAttribute.GetDBType(_DBContext.DBTypeManager), currentAttribute, referencedDBObject.IErrors));

                                            break;

                                        default:

                                            throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace()));
                                    }

                                    #endregion

                                }
                                else
                                {
                                    AddNodeRecursiveBackward(aReferenceObjectUUID, myNode.GetObjectUUID(), myCurrentLevelKey, aLowerLevelKey, lowerLevelKeys, myGraph);
                                    myNode.AddBackwardEdge(edgeKeyForBackwardEdge, aReferenceObjectUUID, null);
                                }
                            }
                        }
                    }
                }
            }
        }