public void AddBackwardEdgesToNode(LevelKey myPath, ObjectUUID myObjectUUID, EdgeKey backwardDestination, Dictionary<ObjectUUID, ADBBaseObject> validUUIDs) { lock (_Content) { if (_Content.ContainsKey(myPath)) { //the level exists if (_Content[myPath].Nodes.ContainsKey(myObjectUUID)) { //Node exists _Content[myPath].Nodes[myObjectUUID].AddBackwardEdges(backwardDestination, validUUIDs); } else { //Node does not exist throw new GraphDBException(new Error_ExpressionGraphInternal(new System.Diagnostics.StackTrace(true), "The node does not exist in this LevelKey.")); } } else { //LevelKey does not exist throw new GraphDBException(new Error_ExpressionGraphInternal(new System.Diagnostics.StackTrace(true), "The LevelKey does not exist in this ExpressionLevel.")); } } }
public bool ContainsLevelKey(LevelKey levelKey) { if (this.Levels.ContainsKey(levelKey.Level)) { if (this.Levels[levelKey.Level].ExpressionLevels.ContainsKey(levelKey)) { return true; } else { return false; } } else { return false; } }
public IEnumerable<Exceptional<DBObjectStream>> SelectDBObjectsForLevelKey(LevelKey myLevelKey, DBContext dbContext) { GraphDBType typeOfDBObjects = null; if (myLevelKey.Level == 0) { typeOfDBObjects = _typeManager.GetTypeByUUID(myLevelKey.Edges[0].TypeUUID); var subTypes = _typeManager.GetAllSubtypes(typeOfDBObjects, true); if (subTypes.IsNullOrEmpty()) { var idx = typeOfDBObjects.GetUUIDIndex(dbContext.DBTypeManager); var currentIndexType = dbContext.DBTypeManager.GetTypeByUUID(idx.IndexRelatedTypeUUID); foreach (var aDBO in LoadListOfDBObjectStreams(typeOfDBObjects, idx.GetAllUUIDs(currentIndexType, dbContext))) { yield return aDBO; } } else { foreach (var aType in subTypes) { if (aType.AttributeIndices.Count != 0) { var idx = aType.GetUUIDIndex(dbContext.DBTypeManager); var currentIndexType = dbContext.DBTypeManager.GetTypeByUUID(idx.IndexRelatedTypeUUID); foreach (var aDBO in LoadListOfDBObjectStreams(aType, idx.GetAllUUIDs(currentIndexType, dbContext))) { yield return aDBO; } } } } } else { #region data TypeAttribute lastAttributeOfLevelKey = null; #endregion #region find the correct attribute lastAttributeOfLevelKey = _typeManager.GetTypeByUUID(myLevelKey.LastEdge.TypeUUID).GetTypeAttributeByUUID(myLevelKey.LastEdge.AttrUUID); if (lastAttributeOfLevelKey == null) { throw new GraphDBException(new Error_InvalidAttribute(String.Format("The attribute with UUID \"{0}\" is not valid for type with UUID \"{1}\".", myLevelKey.LastEdge.AttrUUID, myLevelKey.LastEdge.TypeUUID))); } #endregion #region find out which type we need if (lastAttributeOfLevelKey.GetDBType(dbContext.DBTypeManager).IsUserDefined) { typeOfDBObjects = lastAttributeOfLevelKey.GetDBType(dbContext.DBTypeManager); } else { if (lastAttributeOfLevelKey.IsBackwardEdge) { typeOfDBObjects = _typeManager.GetTypeByUUID(lastAttributeOfLevelKey.BackwardEdgeDefinition.TypeUUID); } else { typeOfDBObjects = _typeManager.GetTypeByUUID(myLevelKey.LastEdge.TypeUUID); } } #endregion #region yield dbos var idx = typeOfDBObjects.GetUUIDIndex(dbContext.DBTypeManager); var currentIndexType = dbContext.DBTypeManager.GetTypeByUUID(idx.IndexRelatedTypeUUID); foreach (var aDBO in LoadListOfDBObjectStreams(typeOfDBObjects, idx.GetAllUUIDs(currentIndexType, dbContext))) { if (IsValidDBObjectForLevelKey(aDBO, myLevelKey, typeOfDBObjects)) { yield return aDBO; } } } yield break; #endregion }
private void CleanLowerLevel(LevelKey myLevelKey, DBContext dbContext, DBObjectCache dbObjectCache, IExpressionGraph myGraph) { if (myLevelKey.Level > 0) { var previousLevelKey = myLevelKey.GetPredecessorLevel(dbContext.DBTypeManager); HashSet<ObjectUUID> toBeDeletedNodes = new HashSet<ObjectUUID>(); foreach (var aLowerDBO in myGraph.Select(previousLevelKey, null, false)) { if(aLowerDBO.Failed()) { throw new GraphDBException(new Error_ExpressionGraphInternal(new System.Diagnostics.StackTrace(true), "Could not load DBObjectStream from lower level.")); } foreach (var aReferenceUUID in ((IReferenceEdge)aLowerDBO.Value.GetAttribute(myLevelKey.LastEdge.AttrUUID)).GetAllReferenceIDs()) { if (!myGraph.GetLevel(myLevelKey.Level).ExpressionLevels[myLevelKey].Nodes.ContainsKey(aReferenceUUID)) { //a reference occurred that is not in the higher level --> found a Zoidberg toBeDeletedNodes.Add(aLowerDBO.Value.ObjectUUID); break; } } } foreach (var aToBeDeletedNode in toBeDeletedNodes) { myGraph.GetLevel(previousLevelKey.Level).RemoveNode(previousLevelKey, aToBeDeletedNode); } } }
private Exceptional<object> IntegrateUUID(DataContainer data, DBContext dbContext, DBObjectCache dbObjectCache, TypesOfBinaryExpression typeOfBinExpr, IExpressionGraph resultGraph, SessionSettings mySessionToken, LevelKey myLevelKey, IEnumerable<Exceptional<DBObjectStream>> myDBObjects) { foreach (var aDBO in myDBObjects) { if (aDBO.Failed()) { return new Exceptional<object>(aDBO); } if (IsValidDBObjectStreamForBinExpr(aDBO.Value, data.IDChainDefinitions.Item1.LastAttribute, dbContext.DBTypeManager)) { //check and integrate var result = CheckAndIntegrateDBObjectStream(data, dbContext, dbObjectCache, typeOfBinExpr, resultGraph, aDBO.Value, myLevelKey, mySessionToken); if(!result.Success()) { return new Exceptional<object>(result); } } } return new Exceptional<object>(); }
public Error_InvalidLevelKeyOperation(LevelKey myLevelKeyA, LevelKey myLevelKeyB, String myOperation) { LevelKeyA = myLevelKeyA; LevelKeyB = myLevelKeyB; Operation = myOperation; }
private Edge GetNotResolvedBackwardEdgeReferenceAttributeValue(DBObjectStream myDBObject, TypeAttribute myTypeAttribute, EdgeKey edgeKey, EdgeList currentEdgeList, Boolean myUsingGraph, DBContext _DBContext) { IObject attrValue = null; if (myUsingGraph) { var interestingLevelKey = new LevelKey((currentEdgeList + new EdgeKey(myTypeAttribute.RelatedGraphDBTypeUUID, myTypeAttribute.UUID)).Edges, _DBContext.DBTypeManager); attrValue = new EdgeTypeSetOfReferences(_ExpressionGraph.SelectUUIDs(interestingLevelKey, myDBObject), myTypeAttribute.DBTypeUUID); } else { var attrValueException = myDBObject.GetBackwardEdges(edgeKey, _DBContext, _DBContext.DBObjectCache, myTypeAttribute.GetDBType(_DBContext.DBTypeManager)); if (attrValueException.Failed()) { throw new GraphDBException(attrValueException.IErrors); } attrValue = attrValueException.Value; } if (attrValue == null) { return null; } else if (!(attrValue is IReferenceEdge)) { throw new GraphDBException(new Error_InvalidEdgeType(attrValue.GetType(), typeof(IReferenceEdge))); } var readouts = new List<Vertex>(); var typeName = _DBContext.DBTypeManager.GetTypeByUUID(edgeKey.TypeUUID).Name; foreach (var reference in (attrValue as IReferenceEdge).GetAllReferenceIDs()) { var specialAttributes = new Dictionary<string, object>(); specialAttributes.Add(SpecialTypeAttribute_UUID.AttributeName, reference); specialAttributes.Add(SpecialTypeAttribute_TYPE.AttributeName, typeName); readouts.Add(new Vertex(specialAttributes)); } return new Edge(null, readouts, _DBContext.DBTypeManager.GetTypeAttributeByEdge(edgeKey).GetDBType(_DBContext.DBTypeManager).Name); }
/// <summary> /// This method adds a Node to a Level. /// </summary> /// <param name="myNode">The Node that is going to be added</param> /// <param name="myPath">The place where the node is going to be added.</param> private void AddNodeToLevel(IExpressionNode myNode, LevelKey myPath) { lock (_Levels) { AddEmptyLevel(myPath); _Levels[myPath.Level].AddNode(myPath, myNode); } }
private void MergeNodeIntoGraph(IExpressionGraph destinationGraph, LevelKey levelKey, IExpressionNode aNode, IExpressionGraph sourceGraph) { if (destinationGraph.Levels[levelKey.Level].ExpressionLevels[levelKey].Nodes.ContainsKey(aNode.GetObjectUUID())) { if (levelKey.Level != 0) { //check if the node has backward edes if ((aNode.BackwardEdges.Count != 0) || (destinationGraph.Levels[levelKey.Level].ExpressionLevels[levelKey].Nodes[aNode.GetObjectUUID()].BackwardEdges.Count != 0)) { //check if the node has backward edes destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode); } } else { //nothing has to be checked destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode); } } else { //the node does not exist if (levelKey.Level != 0) { if (aNode.BackwardEdges.Exists(item => item.Value.Count != 0)) { //check if the node has backward edes destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode); } else { //remove the backward edge from the upper level RemoveReferenceFromUpperLevel(aNode, levelKey, sourceGraph); } } else { //nothing has to be checked destinationGraph.Levels[levelKey.Level].AddNode(levelKey, aNode); } } }
private bool IsValidLevelKeyNeighbourship(LevelKey myShorterLevelKey, LevelKey myLongerLevelKey) { if (myShorterLevelKey.Level <= myLongerLevelKey.Level) { if (myShorterLevelKey.Level == 0) { if (myLongerLevelKey.Level == 0) { if (myLongerLevelKey == myShorterLevelKey) { return true; } else { return false; } } else { if (myLongerLevelKey.Edges[0].TypeUUID == myShorterLevelKey.Edges[0].TypeUUID) { return true; } else { return false; } } } else { int counter = 0; foreach (var aEntry in myLongerLevelKey.Edges.Take(myShorterLevelKey.Level)) { if (aEntry != myShorterLevelKey.Edges[counter]) { return false; } counter++; } return true; } } else { return false; } }
public override void AddNodesWithComplexRelation(Exceptional<DBObjectStream> leftDBObject, LevelKey leftLevelKey, Exceptional<DBObjectStream> rightDBObject, LevelKey rightLevelKey, DBObjectCache dbObjectCache, int backwardResolutiondepth) { lock (_Levels) { if ((AddNodeIfValid(leftDBObject.Value, leftLevelKey, 0, leftDBObject.Value.ObjectUUID, backwardResolutiondepth)) && (AddNodeIfValid(rightDBObject.Value, rightLevelKey, 0, rightDBObject.Value.ObjectUUID, backwardResolutiondepth))) { //both nodes have been inserted correctly //--> create a connection between both _Levels[leftLevelKey.Level].ExpressionLevels[leftLevelKey].Nodes[leftDBObject.Value.ObjectUUID].AddComplexConnection(rightLevelKey, rightDBObject.Value.ObjectUUID); _Levels[rightLevelKey.Level].ExpressionLevels[rightLevelKey].Nodes[rightDBObject.Value.ObjectUUID].AddComplexConnection(leftLevelKey, leftDBObject.Value.ObjectUUID); } else { #region remove both nodes if (ContainsLevelKey(leftLevelKey)) { _Levels[leftLevelKey.Level].RemoveNode(leftLevelKey, leftDBObject.Value.ObjectUUID); } if (ContainsLevelKey(leftLevelKey)) { _Levels[rightLevelKey.Level].RemoveNode(rightLevelKey, rightDBObject.Value.ObjectUUID); } #endregion } } }
private HashSet<LevelKey> GetUpperLevelKeys(IExpressionGraph aGraph, LevelKey myLevelKey) { HashSet<LevelKey> result = new HashSet<LevelKey>(); lock (aGraph) { foreach (var aLevel in aGraph.Levels.Where(aaLevel => aaLevel.Key > myLevelKey.Level).OrderBy(item => item.Key)) { foreach (var aLevelPayLoad in aLevel.Value.ExpressionLevels) { if (IsValidLevelKeyNeighbourship(myLevelKey, aLevelPayLoad.Key)) { result.Add(aLevelPayLoad.Key); } } if (result.Count > 0) { break; } } } return result; }
public override void AddNodes(IEnumerable<IExpressionNode> iEnumerable, LevelKey myPath) { foreach (var aNode in iEnumerable) { AddNodeToLevel(aNode, myPath); } }
public override void AddNode(DBObjectStream myDBObjectStream, LevelKey myLevelKey) { AddNode(myDBObjectStream, myLevelKey, 0); }
private LevelKey GetNextLowerLevel(IExpressionGraph anotherGraph, LevelKey aLevelKey) { return (from aLowerExpressionLevel in anotherGraph.Levels[aLevelKey.Level - 1].ExpressionLevels where IsValidLevelKeyNeighbourship(aLowerExpressionLevel.Key, aLevelKey) select aLowerExpressionLevel.Key).OrderByDescending(item => item.Level).Select(item => item).FirstOrDefault(); }
/// <summary> /// This method adds a DBOBjectStream to a Level if it is valid for a LevelKey. /// </summary> /// <param name="aDBObject">The Object that is going to be added</param> /// <param name="myLevelKey">The LevelKey which is needed for validation.</param> /// <param name="currentBackwardResolution">The current backward resolution (initially 0)</param> /// <param name="source">The ObjectUUID of the </param> /// <returns>True if it was valid or false otherwise.</returns> private bool AddNodeIfValid(DBObjectStream aDBObject, LevelKey myLevelKey, int currentBackwardResolution, ObjectUUID source, int backwardResolutiondepth) { #region data Exceptional<BackwardEdgeStream> beStream = null; TypeAttribute tempTypeAttribute = null; IEnumerable<ObjectUUID> referenceUUIDs = null; GraphDBType referenceType = null; #endregion if ((myLevelKey.Level - currentBackwardResolution) > 0) { #region level > 0 int desiredBackwardEdgeLevel = myLevelKey.Level - currentBackwardResolution - 1; tempTypeAttribute = _DBContext.DBTypeManager.GetTypeByUUID(myLevelKey.Edges[desiredBackwardEdgeLevel].TypeUUID).GetTypeAttributeByUUID(myLevelKey.Edges[desiredBackwardEdgeLevel].AttrUUID); #region get reference UUIDs if (tempTypeAttribute.IsBackwardEdge) { #region backward edge handling referenceType = _DBContext.DBTypeManager.GetTypeByUUID(tempTypeAttribute.BackwardEdgeDefinition.TypeUUID).GetTypeAttributeByUUID(tempTypeAttribute.BackwardEdgeDefinition.AttrUUID).GetDBType(_DBContext.DBTypeManager); if (aDBObject.HasAttribute(tempTypeAttribute.BackwardEdgeDefinition.AttrUUID, _DBContext.DBTypeManager.GetTypeByUUID(tempTypeAttribute.BackwardEdgeDefinition.TypeUUID))) { referenceUUIDs = GetUUIDsForAttribute(aDBObject, tempTypeAttribute.BackwardEdgeDefinition.GetTypeAndAttributeInformation(_DBContext.DBTypeManager).Item2, _DBContext.DBTypeManager.GetTypeByUUID(aDBObject.TypeUUID)); } #endregion } else { #region forward edge handling beStream = _DBObjectCache.LoadDBBackwardEdgeStream(tempTypeAttribute.GetDBType(_DBContext.DBTypeManager), aDBObject.ObjectUUID); if (beStream.Failed()) { throw new GraphDBException(new Error_CouldNotLoadBackwardEdge(aDBObject, tempTypeAttribute, beStream.IErrors)); } var tempEdgeKey = GetBackwardEdgeKey(myLevelKey, desiredBackwardEdgeLevel, _DBContext); if (!beStream.Value.ContainsBackwardEdge(tempEdgeKey)) { return false; } referenceUUIDs = beStream.Value.GetBackwardEdgeUUIDs(tempEdgeKey); referenceType = tempTypeAttribute.GetRelatedType(_DBContext.DBTypeManager); #endregion } #endregion if (referenceUUIDs != null) { #region references Exceptional<DBObjectStream> tempDbo = null; Dictionary<ObjectUUID, ADBBaseObject> validUUIDs = new Dictionary<ObjectUUID, ADBBaseObject>(); SettingInvalidReferenceHandling invalidReferenceSetting = null; #region process references recursivly foreach (var aReferenceUUID in referenceUUIDs) { tempDbo = _DBObjectCache.LoadDBObjectStream(referenceType, aReferenceUUID); if (!tempDbo.Success()) { #region error if (invalidReferenceSetting == null) { invalidReferenceSetting = (SettingInvalidReferenceHandling)_DBContext.DBSettingsManager.GetSetting(SettingInvalidReferenceHandling.UUID, _DBContext, TypesSettingScope.ATTRIBUTE, referenceType, tempTypeAttribute).Value; } switch (invalidReferenceSetting.Behaviour) { case BehaviourOnInvalidReference.ignore: #region ignore //insert if the next lower level is 0 if ((myLevelKey.Level - currentBackwardResolution) == 0) { if (currentBackwardResolution <= backwardResolutiondepth) { #region fill graph LevelKey newLevelKey = new LevelKey(myLevelKey.Edges.First().TypeUUID, _DBContext.DBTypeManager); if (currentBackwardResolution > 0) { //we have to add forwardEdges and (if not already there) add nodes AddEmptyLevel(newLevelKey); Levels[0].AddNode(newLevelKey, new ExpressionNode(aReferenceUUID, null)); Levels[0].AddForwardEdgeToNode(newLevelKey, aReferenceUUID, new EdgeKey(myLevelKey.Edges[0].TypeUUID, myLevelKey.Edges[0].AttrUUID), aDBObject.ObjectUUID, null); } else { //we are in the lowest level and are the first time in this method... so there's no need for adding forward-edges to nodes AddEmptyLevel(newLevelKey); Levels[0].AddNode(newLevelKey, new ExpressionNode(aReferenceUUID, null)); } #endregion } //add to valid uuids be validUUIDs.Add(tempDbo.Value.ObjectUUID, null); } #endregion break; case BehaviourOnInvalidReference.log: AddWarning(new Warning_EdgeToNonExistingNode(aDBObject, tempTypeAttribute.GetDBType(_DBContext.DBTypeManager), tempTypeAttribute, tempDbo.IErrors)); break; default: throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace())); } #endregion } else { if (AddNodeIfValid(tempDbo.Value, myLevelKey, currentBackwardResolution + 1, aDBObject.ObjectUUID, backwardResolutiondepth)) { validUUIDs.Add(tempDbo.Value.ObjectUUID, null); } } } #endregion if (validUUIDs.Count > 0) { //some valid uuids if (currentBackwardResolution <= backwardResolutiondepth) { #region fill graph FillGraph(aDBObject, myLevelKey, currentBackwardResolution, source, myLevelKey.Edges[desiredBackwardEdgeLevel], validUUIDs); #endregion } return true; } else { //not valid return false; } #endregion } else { #region no references return false; #endregion } #endregion } else { #region Level 0 if (currentBackwardResolution <= backwardResolutiondepth) { #region fill graph LevelKey newLevelKey = new LevelKey(myLevelKey.Edges.First().TypeUUID, _DBContext.DBTypeManager); if (currentBackwardResolution > 0) { //we have to add forwardEdges and (if not already there) add nodes AddEmptyLevel(newLevelKey); Levels[0].AddNode(newLevelKey, new ExpressionNode(aDBObject, null)); Levels[0].AddForwardEdgeToNode(newLevelKey, aDBObject.ObjectUUID, new EdgeKey(myLevelKey.Edges[0].TypeUUID, myLevelKey.Edges[0].AttrUUID), source, null); } else { //we are in the lowest level and are the first time in this method... so there's no need for adding forward-edges to nodes AddEmptyLevel(newLevelKey); Levels[0].AddNode(newLevelKey, new ExpressionNode(aDBObject, null)); } #endregion } return true; #endregion } }
private void AddNodeRecursiveBackward(ObjectUUID myNewObjectUUID, ObjectUUID mySourceUUID, LevelKey mySourceLevelKey, LevelKey myNewNodeLevelKey, List<LevelKey> lowerLevelKeys, IExpressionGraph myGraph) { lock (myGraph) { #region add node //add node and the node's backwardEdge //in this point we are shure that the level reall exists if (!myGraph.Levels[myNewNodeLevelKey.Level].ExpressionLevels[myNewNodeLevelKey].Nodes.ContainsKey(myNewObjectUUID)) { myGraph.Levels[myNewNodeLevelKey.Level].ExpressionLevels[myNewNodeLevelKey].Nodes.Add(myNewObjectUUID, new ExpressionNode(myNewObjectUUID, null)); } myGraph.Levels[myNewNodeLevelKey.Level].AddForwardEdgeToNode(myNewNodeLevelKey, myNewObjectUUID, mySourceLevelKey.LastEdge, mySourceUUID, null); #endregion #region recursion if (lowerLevelKeys != null) { UpdateLowerLevels(myGraph.Levels[myNewNodeLevelKey.Level].ExpressionLevels[myNewNodeLevelKey].Nodes[myNewObjectUUID], myNewNodeLevelKey, lowerLevelKeys, myGraph); } #endregion } }
private void RemoveNodeReferncesFromGraph(IExpressionNode myExpressionNode, LevelKey mylevelKey, IExpressionGraph myGraph, HashSet<LevelKey> integratedByAnOtherGraph) { #region remove complex connection foreach (var aComplexConnection in myExpressionNode.ComplexConnection) { var expressionLevelEntry = myGraph.Levels[aComplexConnection.Key.Level].ExpressionLevels[aComplexConnection.Key]; foreach (var aReference in aComplexConnection.Value) { if (expressionLevelEntry.Nodes.ContainsKey(aReference)) { expressionLevelEntry.Nodes[aReference].RemoveComplexConnection(mylevelKey, myExpressionNode.GetObjectUUID()); RemoveNodeReferncesFromGraph(expressionLevelEntry.Nodes[aReference], aComplexConnection.Key, myGraph, integratedByAnOtherGraph); } if (myGraph.Levels.ContainsKey(aComplexConnection.Key.Level - 1)) { foreach (var aBackwardEdgeSet in expressionLevelEntry.Nodes[aReference].BackwardEdges) { //go to every object the backwardEdge points to and remove the forward reference var backwardLevelKey = GetBackwardLevelKey(aComplexConnection.Key, aBackwardEdgeSet.Key, _DBContext.DBTypeManager); if (myGraph.ContainsLevelKey(backwardLevelKey)) { foreach (var aBackwardEdge in aBackwardEdgeSet.Value) { if (myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes.ContainsKey(aBackwardEdge.Destination)) { myGraph.Levels[backwardLevelKey.Level].RemoveNode(backwardLevelKey, aBackwardEdge.Destination); } } } } } myGraph.Levels[aComplexConnection.Key.Level].RemoveNode(aComplexConnection.Key, aReference); } } #endregion #region remove reference from lower level if (mylevelKey.Level != 0) { if (myGraph.Levels.ContainsKey(mylevelKey.Level - 1)) { foreach (var aBackwardEdgeSet in myExpressionNode.BackwardEdges) { //go to every object the backwardEdge points to and remove the forward reference var backwardLevelKey = GetBackwardLevelKey(mylevelKey, aBackwardEdgeSet.Key, _DBContext.DBTypeManager); if (myGraph.ContainsLevelKey(backwardLevelKey)) { foreach (var aBackwardEdge in aBackwardEdgeSet.Value) { if (myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes.ContainsKey(aBackwardEdge.Destination)) { myGraph.Levels[backwardLevelKey.Level].ExpressionLevels[backwardLevelKey].Nodes[aBackwardEdge.Destination].RemoveForwardEdge(mylevelKey.LastEdge, myExpressionNode.GetObjectUUID()); } } } } } } #endregion RemoveReferenceFromUpperLevel(myExpressionNode, mylevelKey, myGraph); }
/// <summary> /// Get the attribute value of <paramref name="myTypeAttribute"/> and calls GetNotResolvedReferenceEdgeAttributeValue with the edge /// </summary> /// <param name="myDBObjectStream"></param> /// <param name="myTypeAttribute"></param> /// <param name="myGraphDBType"></param> /// <param name="myCurrentEdgeList"></param> /// <param name="myUsingGraph"></param> /// <param name="myDBContext"></param> /// <returns></returns> private Edge GetNotResolvedReferenceAttributeValue(DBObjectStream myDBObjectStream, TypeAttribute myTypeAttribute, GraphDBType myGraphDBType, EdgeList myCurrentEdgeList, Boolean myUsingGraph, DBContext myDBContext) { IObject attrValue = null; if (myUsingGraph) { var interestingLevelKey = new LevelKey((myCurrentEdgeList + new EdgeKey(myGraphDBType.UUID, myTypeAttribute.UUID)).Edges, myDBContext.DBTypeManager); var interestingUUIDs = _ExpressionGraph.SelectUUIDs(interestingLevelKey, myDBObjectStream); attrValue = ((IReferenceEdge)myDBObjectStream.GetAttribute(myTypeAttribute.UUID, myGraphDBType, myDBContext)).GetNewInstance(interestingUUIDs, myGraphDBType.UUID); } else { attrValue = myDBObjectStream.GetAttribute(myTypeAttribute.UUID, myGraphDBType, myDBContext); } if (attrValue == null) { return null; } var typeName = myTypeAttribute.GetDBType(myDBContext.DBTypeManager).Name; return GetNotResolvedReferenceEdgeAttributeValue(attrValue as IReferenceEdge, myTypeAttribute.GetDBType(myDBContext.DBTypeManager), myDBContext); }
private void RemoveReferenceFromUpperLevel(IExpressionNode myExpressionNode, LevelKey mylevelKey, IExpressionGraph myGraph) { #region remove reference from upper level if (myGraph.Levels.ContainsKey(mylevelKey.Level + 1)) { foreach (var aForwardEdgeSet in myExpressionNode.ForwardEdges) { var forwardLevelKey = GetForwardLevelKey(mylevelKey, aForwardEdgeSet.Key, _DBContext.DBTypeManager); if (myGraph.ContainsLevelKey(forwardLevelKey)) { //go to every object the forwardEdge points to and remove the backward reference foreach (var aForwardEdge in aForwardEdgeSet.Value) { if (myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes.ContainsKey(aForwardEdge.Destination)) { myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination].RemoveBackwardEdge(mylevelKey.LastEdge, myExpressionNode.GetObjectUUID()); if (!myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination].BackwardEdges.Exists(item => item.Value.Count > 0)) { //the current object has no backward Edges... delete it //remove upper references RemoveReferenceFromUpperLevel(myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes[aForwardEdge.Destination], forwardLevelKey, myGraph); //remove the node itself myGraph.Levels[forwardLevelKey.Level].ExpressionLevels[forwardLevelKey].Nodes.Remove(aForwardEdge.Destination); } } } } } } #endregion }
public Error_InvalidLevelKeyOperation(LevelKey myLevelKey, EdgeKey myEdgeKey, String myOperation) { LevelKeyA = myLevelKey; EdgeKeyA = myEdgeKey; Operation = myOperation; }
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); } } } } } } }
private void IntegrateInGraph(DBObjectStream myDBObjectStream, IExpressionGraph myExpressionGraph, LevelKey myLevelKey, DBContext myTypeManager, DBObjectCache myQueryCache) { if (this.Type == TypesOfOperators.AffectsLowerLevels) { myExpressionGraph.AddNode(myDBObjectStream, myLevelKey, 1); } else { myExpressionGraph.AddNode(myDBObjectStream, myLevelKey, 0); } }
public override void GatherEdgeWeight(LevelKey StartLevel, LevelKey EndLevel) { throw new NotImplementedException(); }
/// <summary> /// This method checks and integrates a DBObjectStream into the result graph. /// </summary> /// <param name="myData">The DataContainer.</param> /// <param name="myTypeManager">The TypeManager of the database.</param> /// <param name="myQueryCache">The current query cache.</param> /// <param name="myTypeOfBinExpr">The kind of the binary expression.</param> /// <param name="myResultGraph">The resulting IExpressionGraph.</param> /// <param name="myDBObjectStream">The DBObjectStream.</param> private Exceptional<object> CheckAndIntegrateDBObjectStream(DataContainer myData, DBContext myTypeManager, DBObjectCache myQueryCache, TypesOfBinaryExpression myTypeOfBinExpr, IExpressionGraph myResultGraph, DBObjectStream myDBObjectStream, LevelKey myLevelKey, SessionSettings mySessionToken) { //get the operand var operand = GetOperand(myData.IDChainDefinitions.Item1, myData.Extraordinaries.Item1, myTypeManager, myDBObjectStream, myQueryCache, mySessionToken); if(operand == null) { return new Exceptional<object>(); } if (operand.Failed()) { return new Exceptional<object>(operand); } Exceptional<AOperationDefinition> tempSimpleOperationResult; switch (myTypeOfBinExpr) { case TypesOfBinaryExpression.LeftComplex: tempSimpleOperationResult = this.SimpleOperation(operand.Value, ((AOperationDefinition)myData.Operands.Item1), myTypeOfBinExpr); break; case TypesOfBinaryExpression.RightComplex: tempSimpleOperationResult = this.SimpleOperation(((AOperationDefinition)myData.Operands.Item1), operand.Value, myTypeOfBinExpr); break; case TypesOfBinaryExpression.Complex: case TypesOfBinaryExpression.Atom: default: throw new ArgumentException(); } if (tempSimpleOperationResult.Failed()) { return new Exceptional<object>(tempSimpleOperationResult); } var tempOperatorResult = ((ValueDefinition)tempSimpleOperationResult.Value); if ((Boolean)tempOperatorResult.Value.Value) { IntegrateInGraph(myDBObjectStream, myResultGraph, myLevelKey, myTypeManager, myQueryCache); } //else //{ // /// We need to add an empty level in case, the DBO should not be integerated. Otherwise the select does not know, either the level was never touched or // /// not added due to an expression // ExcludeFromGraph(myDBObjectStream, myResultGraph, myLevelKey, myTypeManager, myQueryCache); //} return new Exceptional<object>(); }
public override Boolean IsGraphRelevant(LevelKey myLevelKey, DBObjectStream mySourceDBObject) { lock (_Levels) { if (!this.ContainsLevelKey(myLevelKey)) { return false; } if (myLevelKey.Level == 0) { return this._Levels[myLevelKey.Level].ExpressionLevels[myLevelKey].Nodes.ContainsKey(mySourceDBObject.ObjectUUID); } else { if (mySourceDBObject != null) { var predecessorLevelKey = myLevelKey.GetPredecessorLevel(_DBContext.DBTypeManager); if (!this.ContainsLevelKey(predecessorLevelKey)) { var interestingEdge = new ExpressionEdge(mySourceDBObject.ObjectUUID, null, predecessorLevelKey.LastEdge); //take the backwardEdges return this._Levels[myLevelKey.Level].ExpressionLevels[myLevelKey].Nodes.Exists(item => item.Value.BackwardEdges[predecessorLevelKey.LastEdge].Contains(interestingEdge)); } else { if (this._Levels[predecessorLevelKey.Level].ExpressionLevels[predecessorLevelKey].Nodes[mySourceDBObject.ObjectUUID].ForwardEdges.ContainsKey(myLevelKey.LastEdge)) { if (this._Levels[predecessorLevelKey.Level].ExpressionLevels[predecessorLevelKey].Nodes[mySourceDBObject.ObjectUUID].ForwardEdges[myLevelKey.LastEdge].Count > 0) { return true; } else { return false; } } else { return false; } } } else { throw new GraphDBException(new Error_ExpressionGraphInternal(new System.Diagnostics.StackTrace(true), "No DBObjectStream givon for graph relevance test in a higher level.")); } } } }
/// <summary> /// We need to add an empty level in case, the DBO should not be integerated. Otherwise the select does not know, either the level was never touched or /// not added due to an expression /// </summary> /// <param name="myDBObjectStream"></param> /// <param name="myExpressionGraph"></param> /// <param name="myLevelKey"></param> /// <param name="myTypeManager"></param> /// <param name="myQueryCache"></param> private void ExcludeFromGraph(DBObjectStream myDBObjectStream, IExpressionGraph myExpressionGraph, LevelKey myLevelKey, DBContext myTypeManager, DBObjectCache myQueryCache) { myExpressionGraph.AddEmptyLevel(myLevelKey); }
public override IEnumerable<Exceptional<DBObjectStream>> Select(LevelKey myLevelKey, DBObjectStream mySourceDBObject = null, Boolean doLevelGeneration = true) { lock (_Levels) { if (doLevelGeneration) { if (!this.ContainsLevelKey(myLevelKey)) { //the graph does not contain the LevelKey, so create it #region create LevelKey GenerateLevel(myLevelKey); #endregion } } if (myLevelKey.Level == 0) { if (this.ContainsLevelKey(myLevelKey)) { //return all Objects of this levelKey foreach (var aNode in this._Levels[myLevelKey.Level].ExpressionLevels[myLevelKey].Nodes) { yield return new Exceptional<DBObjectStream>(aNode.Value.GetDBObjectStream(_DBObjectCache, myLevelKey.LastEdge.TypeUUID)); } } else { yield break; } } else { if (mySourceDBObject != null) { var predecessorLevelKey = myLevelKey.GetPredecessorLevel(_DBContext.DBTypeManager); if (!this.ContainsLevelKey(predecessorLevelKey)) { //take the backwardEdges foreach (var aNode in this._Levels[myLevelKey.Level].ExpressionLevels[myLevelKey].Nodes.Where(item => item.Value.BackwardEdges[predecessorLevelKey.LastEdge].Exists(aBackWardEdge => aBackWardEdge.Destination == mySourceDBObject.ObjectUUID))) { yield return new Exceptional<DBObjectStream>(aNode.Value.GetDBObjectStream(_DBObjectCache, myLevelKey.LastEdge.TypeUUID)); } } else { //take the forwardEdges TypeAttribute currentAttribute = _DBContext.DBTypeManager.GetTypeByUUID(myLevelKey.LastEdge.TypeUUID).GetTypeAttributeByUUID(myLevelKey.LastEdge.AttrUUID); GraphDBType myType = GetTypeOfAttribute(currentAttribute.GetRelatedType(_DBContext.DBTypeManager), currentAttribute); foreach (var aDBO in _DBObjectCache.LoadListOfDBObjectStreams(myType, this._Levels[predecessorLevelKey.Level].ExpressionLevels[predecessorLevelKey].Nodes[mySourceDBObject.ObjectUUID].ForwardEdges[myLevelKey.LastEdge].Select(item => item.Destination))) { if (aDBO.Failed()) { AddWarning(new Warning_CouldNotLoadDBObject(aDBO.IErrors, new System.Diagnostics.StackTrace(true))); } else { yield return aDBO; } } } } else { //there is no sourceObject given, so return the complete level foreach (var aNode in this._Levels[myLevelKey.Level].ExpressionLevels[myLevelKey].Nodes) { yield return new Exceptional<DBObjectStream>(aNode.Value.GetDBObjectStream(_DBObjectCache, myLevelKey.LastEdge.TypeUUID)); } } } } //all done yield break; }
private bool IsValidDBObjectForLevelKey(Exceptional<DBObjectStream> aDBO, LevelKey myLevelKey, GraphDBType typeOfDBO) { if (myLevelKey.Level == 0) { return true; } else { Boolean isValidDBO = false; EdgeKey backwardEdgeKey = myLevelKey.LastEdge; TypeAttribute currentAttribute = _typeManager.GetTypeByUUID(backwardEdgeKey.TypeUUID).GetTypeAttributeByUUID(backwardEdgeKey.AttrUUID); IEnumerable<Exceptional<DBObjectStream>> dbobjects = null; GraphDBType typeOfBackwardDBOs = null; if (currentAttribute.IsBackwardEdge) { backwardEdgeKey = currentAttribute.BackwardEdgeDefinition; currentAttribute = _typeManager.GetTypeByUUID(backwardEdgeKey.TypeUUID).GetTypeAttributeByUUID(backwardEdgeKey.AttrUUID); typeOfBackwardDBOs = currentAttribute.GetDBType(_typeManager); if (aDBO.Value.HasAttribute(backwardEdgeKey.AttrUUID, typeOfDBO)) { dbobjects = GetReferenceObjects(aDBO.Value, currentAttribute, typeOfDBO, _typeManager); } } else { BackwardEdgeStream beStreamOfDBO = LoadDBBackwardEdgeStream(typeOfDBO, aDBO.Value.ObjectUUID).Value; typeOfBackwardDBOs = _typeManager.GetTypeByUUID(backwardEdgeKey.TypeUUID); if (beStreamOfDBO.ContainsBackwardEdge(backwardEdgeKey)) { dbobjects = LoadListOfDBObjectStreams(typeOfBackwardDBOs, beStreamOfDBO.GetBackwardEdgeUUIDs(backwardEdgeKey)); } } if (dbobjects != null) { LevelKey myLevelKeyPred = myLevelKey.GetPredecessorLevel(_typeManager); foreach (var aBackwardDBO in dbobjects) { if (aBackwardDBO.Success()) { if (IsValidDBObjectForLevelKey(aBackwardDBO, myLevelKeyPred, typeOfBackwardDBOs)) { isValidDBO = true; break; } } } } else { return false; } return isValidDBO; } }
public override IEnumerable<ObjectUUID> SelectUUIDs(LevelKey myLevelKey, DBObjectStream mySourceDBObject = null, Boolean doLevelGeneration = true) { lock (_Levels) { if (doLevelGeneration) { if (!this.ContainsLevelKey(myLevelKey)) { //the graph does not contain the LevelKey, so create it #region create LevelKey GenerateLevel(myLevelKey); #endregion } } if (myLevelKey.Level == 0) { if (this.ContainsLevelKey(myLevelKey)) { //return all Objects of this levelKey foreach (var aNode in this._Levels[myLevelKey.Level].ExpressionLevels[myLevelKey].Nodes) { yield return aNode.Value.GetObjectUUID(); } } else { yield break; } } else { if (mySourceDBObject != null) { var predecessorLevelKey = myLevelKey.GetPredecessorLevel(_DBContext.DBTypeManager); if (!this.ContainsLevelKey(predecessorLevelKey)) { //take the backwardEdges foreach (var aNode in this._Levels[myLevelKey.Level].ExpressionLevels[myLevelKey].Nodes.Where(item => item.Value.BackwardEdges[predecessorLevelKey.LastEdge].Exists(aBackWardEdge => aBackWardEdge.Destination == mySourceDBObject.ObjectUUID))) { yield return aNode.Value.GetObjectUUID(); } } else { //take the forwardEdges TypeAttribute currentAttribute = _DBContext.DBTypeManager.GetTypeByUUID(myLevelKey.LastEdge.TypeUUID).GetTypeAttributeByUUID(myLevelKey.LastEdge.AttrUUID); GraphDBType myType = GetTypeOfAttribute(currentAttribute.GetRelatedType(_DBContext.DBTypeManager), currentAttribute); if (this._Levels[predecessorLevelKey.Level].ExpressionLevels[predecessorLevelKey].Nodes[mySourceDBObject.ObjectUUID].ForwardEdges.ContainsKey(myLevelKey.LastEdge)) { foreach (var aUUID in this._Levels[predecessorLevelKey.Level].ExpressionLevels[predecessorLevelKey].Nodes[mySourceDBObject.ObjectUUID].ForwardEdges[myLevelKey.LastEdge].Select(item => item.Destination)) { yield return aUUID; } } else { AddNode(mySourceDBObject, myLevelKey); //var attrVal = mySourceDBObject.GetAttribute(myLevelKey.LastEdge.AttrUUID); } } } else { //there is no sourceObject given, so return the complete level foreach (var aNode in this._Levels[myLevelKey.Level].ExpressionLevels[myLevelKey].Nodes) { yield return aNode.Value.GetObjectUUID(); } } } } //all done yield break; }