Beispiel #1
0
                GetAllSelectedAttributesFromVertex(SecurityToken mySecurityToken, 
                                                    Int64 myTransactionToken, 
                                                    IVertex myDBObject, 
                                                    IVertexType myDBType, 
                                                    Int64 myDepth, 
                                                    EdgeList myLevelKey, 
                                                    String myReference, 
                                                    Boolean myUsingGraph)
        {
            IDictionary<String, Object> properties = new Dictionary<string, object>();
            IDictionary<String, IEdgeView> edges = new Dictionary<string, IEdgeView>();

            var Attributes = new Tuple<IDictionary<string, object>, IDictionary<string, IEdgeView>>(properties, edges);
            Int64 Depth;

            var minDepth = 0;

            //save the already created LevelKey of the refernce type
            EdgeList levelKey = myLevelKey;

            IEnumerable<SelectionElement> attributeSelections = null;

            attributeSelections = getAttributeSelections(myReference, myLevelKey);

            if (attributeSelections.IsNullOrEmpty())
            {

                #region Get all attributes from the DBO if nothing special was selected
                if ((myDepth == -1) || (myDepth >= myLevelKey.Level))
                {
                    AddAttributesByDBO(mySecurityToken, 
                                        myTransactionToken, 
                                        ref Attributes, 
                                        myDBType, 
                                        myDBObject, 
                                        myDepth, 
                                        myLevelKey, 
                                        myReference, 
                                        myUsingGraph, 
                                        TypesOfSelect.Asterisk);
                }

                #endregion

            }
            else
            {

                foreach (var attrSel in attributeSelections)
                {

                    #region extract the selected infos

                    //myDepth = attrSel.EdgeList.Level;

                    #region Some kind of asterisk - return all attributes

                    if (attrSel.Selection == TypesOfSelect.Asterisk)
                    {

                        #region Asterisk (*), Rhomb (#), Minus (-), Ad (@) selection

                        Depth = GetDepth(myDepth, 0, myDBType);

                        AddAttributesByDBO(mySecurityToken, 
                                            myTransactionToken, 
                                            ref Attributes, 
                                            myDBType, 
                                            myDBObject, 
                                            Depth, 
                                            myLevelKey, 
                                            myReference, 
                                            myUsingGraph, 
                                            attrSel.Selection, 
                                            attrSel.TypeID);

                        #endregion

                        continue;

                    }

                    #endregion

                    #region Alias

                    String alias = String.Empty;

                    if (attrSel.Element == null)
                    {
                        alias = (attrSel.Alias == null) ? attrSel.RelatedIDChainDefinition.UndefinedAttribute : attrSel.Alias;
                    }
                    else
                    {
                        alias = (attrSel.Alias == null) ? attrSel.Element.Name : attrSel.Alias;
                    }

                    #endregion

                    if (Attributes.Item1.ContainsKey(alias) || Attributes.Item2.ContainsKey(alias))
                    {
                        // This is a bug in the attributeSelections add method. No attribute should be in the selected list twice. 
                        // If one attribute was selected more than one, these information will be stored in the next level.
                        //System.Diagnostics.Debug.Assert(false, "The attribute '" + alias + "' is selected twice in that level - this shouldnt!");
                        continue;
                    }

                    if (attrSel is SelectionElementFunction)
                    {

                        #region Select a function

                        var selectionElementFunction = (attrSel as SelectionElementFunction);

                        if (selectionElementFunction.SelectValueAssignment != null && 
                            selectionElementFunction.SelectValueAssignment.ValueAssignmentType == SelectValueAssignment.ValueAssignmentTypes.Always)
                        {
                            Attributes.Item1.Add(alias, (selectionElementFunction.SelectValueAssignment.TermDefinition as ValueDefinition).Value);
                            continue;
                        }

                        #region Get the CallingObject

                        Object callingObject = null;

                        if (myUsingGraph)
                        {
                            //a special attribute has no RelatedGraphDBTypeUUID. So use myDBType to create an EdgeKey
                            //EdgeKey key = (selectionElementFunction.Element is ASpecialTypeAttribute) ? new EdgeKey(myDBType.UUID, selectionElementFunction.Element.UUID) : new EdgeKey(selectionElementFunction.Element);
                            EdgeKey key = new EdgeKey(selectionElementFunction.Element.RelatedType.ID, selectionElementFunction.Element.ID);

                            //the levelKey is created with the type inside the select -- f.e. FROM User SELECT Friends.TOP(2) -- it is 'User'
                            //we have to check if the levelKey contains an edge of the VertexType which is equal to the related type of the selection element
                            //this is neccessary -- f.e. FROM User SELECT Friends.TOP(2) -- if the edge 'FRIENDS' is not defined on type User
                            //in this case we have to check if there is a parent type of the reference type which is equal to the related type of the selection element
                            if (levelKey.Edges.All(x => x.VertexTypeID != selectionElementFunction.Element.RelatedType.ID))
                            {
                                if (myDBType.GetAncestorVertexTypesAndSelf().Select(x => x.ID).Contains(selectionElementFunction.Element.RelatedType.ID))
                                {
                                    var typeID = myDBType.GetAncestorVertexTypesAndSelf().Select(x => x.ID).Where(x => x == selectionElementFunction.Element.RelatedType.ID).First();
                                    levelKey = new EdgeList(typeID);
                                }
                            }

                            myUsingGraph = _ExpressionGraph.IsGraphRelevant(new LevelKey((levelKey + key).Edges, _graphdb, mySecurityToken, myTransactionToken), myDBObject);
                        }

                        if (myUsingGraph && !(selectionElementFunction.Element.Kind != AttributeType.Property))
                        {
                            switch (selectionElementFunction.Element.Kind)
                            {
                                case AttributeType.IncomingEdge:
                                    #region incoming edge

                                    var incomingEdgeDefinition = (IIncomingEdgeDefinition)selectionElementFunction.Element;

                                    if (myDBObject.HasIncomingVertices(incomingEdgeDefinition.RelatedEdgeDefinition.RelatedType.ID, incomingEdgeDefinition.RelatedEdgeDefinition.ID))
                                    {
                                        callingObject = _ExpressionGraph.Select(
                                            new LevelKey(
                                                (myLevelKey + new EdgeKey(selectionElementFunction.Element.RelatedType.ID, selectionElementFunction.Element.ID)).Edges,
                                                _graphdb, mySecurityToken, myTransactionToken), myDBObject, true);
                                    }
                                    else
                                    {
                                        callingObject = null;
                                    }

                                    #endregion
                                    break;

                                case AttributeType.OutgoingEdge:
                                    #region outgoing edge

                                    if (myDBObject.HasOutgoingEdge(selectionElementFunction.Element.ID))
                                    {

                                        callingObject = _ExpressionGraph.Select(
                                            new LevelKey(
                                                (myLevelKey + new EdgeKey(selectionElementFunction.Element.RelatedType.ID, selectionElementFunction.Element.ID)).Edges,
                                                _graphdb, mySecurityToken, myTransactionToken), myDBObject, true);

                                    }
                                    else
                                    {
                                        callingObject = null;
                                    }

                                    #endregion

                                    break;

                                case AttributeType.Property:

                                    callingObject = GetCallingObject(myDBObject, selectionElementFunction.Element);
                                    break;

                                case AttributeType.BinaryProperty:
                                default:
                                    continue;
                            }
                        }
                        else
                        {
                            callingObject = GetCallingObject(myDBObject, selectionElementFunction.Element);
                        }

                        #endregion

                        #region Execute the function

                        var res = ExecuteFunction(selectionElementFunction, 
                                                    myDBObject, 
                                                    callingObject, 
                                                    myDepth, 
                                                    myReference, 
                                                    myDBType, 
                                                    myLevelKey, 
                                                    myUsingGraph, 
                                                    mySecurityToken, 
                                                    myTransactionToken);

                        if (res == null)
                        {
                            continue;
                        }

                        #endregion

                        #region Add function return value to attributes

                        if (res.Value is IEnumerable<IVertex>)
                        {

                            #region Reference edge

                            //minDepth = attrSel.EdgeList.Level + 1; // depth should be at least the depth of the selected element
                            minDepth = (attrSel.RelatedIDChainDefinition != null) ? attrSel.RelatedIDChainDefinition.Edges.Count - 1 : 0;
                            myUsingGraph = false;

                            Depth = GetDepth(myDepth, minDepth, myDBType);

                            var attr = (attrSel as SelectionElementFunction).Element;

                            //if (Depth > myLevelKey.Level || getAttributeSelections(myReference, myLevelKey + new EdgeKey(attr.RelatedType.ID, attr.ID)).IsNotNullOrEmpty())
                            if (Depth > levelKey.Level || getAttributeSelections(myReference, levelKey + new EdgeKey(attr.RelatedType.ID, attr.ID)).IsNotNullOrEmpty())
                            {

                                myUsingGraph = false;

                                #region Resolve DBReferences

                                Attributes.Item2.Add(alias,
                                                    ResolveAttributeValue((IOutgoingEdgeDefinition)attr, 
                                                                            (IEnumerable<IVertex>)res.Value, 
                                                                            Depth, 
                                                                            myLevelKey, 
                                                                            myDBObject, 
                                                                            myReference, 
                                                                            myUsingGraph, 
                                                                            mySecurityToken, 
                                                                            myTransactionToken));

                                #endregion

                            }
                            else
                            {
                                Attributes.Item2.Add(alias, GetNotResolvedReferenceEdgeAttributeValue((IEnumerable<IVertex>)res.Value));
                            }

                            #endregion

                        }
                        else if (res.Value is IVertexView)
                        {
                            //the result is one or multiple 'paths'
                            if ((res.Value as IVertexView).HasEdge("path"))
                            {
                                var pathHyperEdge = (res.Value as IVertexView).GetAllHyperEdges().First();

                                if (!String.IsNullOrWhiteSpace(attrSel.Alias))
                                {
                                    Attributes.Item2.Add(attrSel.Alias, pathHyperEdge.Edge);
                                }
                                else
                                    Attributes.Item2.Add(pathHyperEdge.EdgeName, pathHyperEdge.Edge);
                            }
                        }
                        else
                        {

                            Attributes.Item1.Add(alias, res.Value);

                        }

                        #endregion

                        #endregion

                    }
                    else if (attrSel.Element is UnstructuredProperty)
                    {

                        #region undefined attribute selection

                        var undef_alias = attrSel.Alias;

                        if (!Attributes.Item1.ContainsKey(undef_alias))
                        {
                            Object attrValue = null;

                            if (myDBObject.HasUnstructuredProperty(undef_alias))
                            {
                                Attributes.Item1.Add(undef_alias, attrValue);
                            }
                        }

                        #endregion

                    }
                    else
                    {

                        #region Attribute selection

                        minDepth = (attrSel.RelatedIDChainDefinition != null) ? attrSel.RelatedIDChainDefinition.Edges.Count - 1 : 0;

                        //var alias = (attrSel.Alias == null) ? (attrSel.Element as TypeAttribute).Name : attrSel.Alias;

                        Depth = GetDepth(myDepth, minDepth, myDBType, attrSel.Element);

                        Object attrValue = null;

                        if (GetAttributeValueAndResolve(mySecurityToken, myTransactionToken, myDBType, attrSel, myDBObject, Depth, myLevelKey, myReference, myUsingGraph, out attrValue))
                        {
                            if (attrValue is IEdgeView)
                            {
                                Attributes.Item2.Add(alias, (IEdgeView)attrValue);
                            }
                            else
                            {
                                Attributes.Item1.Add(alias, attrValue);
                            }
                        }

                        #endregion

                    }

                    #endregion

                }

            }

            return Attributes;
        }