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; //VertexType currentType = null; EdgeKey myCurrentBackwardEdgekey = null; IAttributeDefinition currentAttribute = null; #endregion if (levelDistance >= 1) { if (myCurrentLevelKey.Level > 1) { myCurrentBackwardEdgekey = myCurrentLevelKey.Edges[myCurrentLevelKey.Level - 1]; } else { myCurrentBackwardEdgekey = myCurrentLevelKey.Edges[0]; } } else { throw new ExpressionGraphInternalException("Distances below 1 are not valid."); } IEnumerable<IVertex> referencedUUIDs = null; IVertexType tempVertexType = _iGraphDB.GetVertexType<IVertexType>( _securityToken, _transactionToken, new RequestGetVertexType(myCurrentBackwardEdgekey.VertexTypeID), (stats, vertexType) => vertexType); currentAttribute = tempVertexType.GetAttributeDefinition(myCurrentBackwardEdgekey.AttributeID); if (currentAttribute.Kind == AttributeType.IncomingEdge) { var incomingAttribite = (IIncomingEdgeDefinition)currentAttribute; var IVertex = myNode.GetIVertex(); if (IVertex.HasOutgoingEdge(incomingAttribite.RelatedEdgeDefinition.ID)) { referencedUUIDs = IVertex.GetOutgoingEdge(incomingAttribite.RelatedEdgeDefinition.ID).GetTargetVertices(); } } else { var outgoingAttribute = (IOutgoingEdgeDefinition)currentAttribute; if (myNode.BackwardEdges.ContainsKey(aLowerLevelKey.LastEdge)) { //take the edges that are already available List<IVertex> tempVertices = new List<IVertex>(); foreach (var aVertexInformation in myNode.BackwardEdges[aLowerLevelKey.LastEdge].Select(item => item.Destination)) { tempVertices.Add(_iGraphDB.GetVertex<IVertex>( _securityToken, _transactionToken, new RequestGetVertex(aVertexInformation.VertexTypeID, aVertexInformation.VertexID), (stats, vertices) => vertices)); } referencedUUIDs = tempVertices; } else { var aVertex = myNode.GetIVertex(); if (aVertex.HasIncomingVertices(myCurrentBackwardEdgekey.VertexTypeID, myCurrentBackwardEdgekey.AttributeID)) { referencedUUIDs = aVertex.GetIncomingVertices(myCurrentBackwardEdgekey.VertexTypeID, myCurrentBackwardEdgekey.AttributeID); } } } 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]; } foreach (var aVertex in referencedUUIDs) { AddNodeRecursiveBackward(aVertex, myNode.VertexInformation, myCurrentLevelKey, aLowerLevelKey, lowerLevelKeys, myGraph); myNode.AddBackwardEdge(edgeKeyForBackwardEdge, GenerateVertexInfoFromLevelKeyAndVertexID(aVertex.VertexTypeID, aVertex.VertexID), null); } } } } } }
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); } } } } } } }