public void AddFollowingFunction(SelectionElementFunction myFollowingFunction) { var curFunc = this; while (curFunc.FollowingFunction != null) { curFunc = curFunc.FollowingFunction; } curFunc.FollowingFunction = myFollowingFunction; }
/// <summary> /// Executes the function and return the result - for concatenated functions this will be done recursively /// </summary> private FuncParameter ExecuteFunction(SelectionElementFunction mySelectionElementFunction, IVertex myDBObject, object myCallingObject, Int64 myDepth, String myReference, IVertexType myReferencedDBType, EdgeList myLevelKey, Boolean myUsingGraph, SecurityToken mySecurityToken, Int64 myTransactionToken) { #region Function if (myCallingObject == null) // DBObject does not have the attribute { if (mySelectionElementFunction.SelectValueAssignment != null) { return new FuncParameter((mySelectionElementFunction.SelectValueAssignment.TermDefinition as ValueDefinition).Value); } return null; } #region Get the FunctionNode and validate the Element var func = mySelectionElementFunction.Function; if (mySelectionElementFunction.Element == null) { return null; } #endregion #region Execute the function var parameters = func.Execute(myReferencedDBType, myDBObject, myReference, _pluginManager, _graphdb, mySecurityToken, myTransactionToken); var result = func.Function.ExecFunc(mySelectionElementFunction.Element, myCallingObject, myDBObject, _graphdb, mySecurityToken, myTransactionToken, parameters.ToArray()); if (result.Value == null) { return null; // no result for this object because of not set attribute value } if (mySelectionElementFunction.FollowingFunction != null) { return ExecuteFunction(mySelectionElementFunction.FollowingFunction, myDBObject, result.Value, myDepth, myReference, myReferencedDBType, myLevelKey, myUsingGraph, mySecurityToken, myTransactionToken); } else { return result; } #endregion #endregion }
/// <summary> /// Single IDNode selection attribute /// </summary> public void AddElementToSelection(string myAlias, String myReference, IDChainDefinition myIDChainDefinition, Boolean myIsGroupedOrAggregated, SelectValueAssignment mySelectValueAssignment = null) { SelectionElement lastElem = null; var curLevel = new EdgeList(); EdgeList preLevel = null; if (myReference != null && _Selections.ContainsKey(myReference) && _Selections[myReference].Any(kv => kv.Value.Any(se => se.RelatedIDChainDefinition == myIDChainDefinition && se.Alias == myAlias))) { throw new DuplicateAttributeSelectionException(myAlias); } foreach (var nodeEdgeKey in myIDChainDefinition) { if (nodeEdgeKey is ChainPartTypeOrAttributeDefinition) { #region Usual attribute preLevel = null; var selElem = new SelectionElement(myAlias, curLevel, myIsGroupedOrAggregated, myIDChainDefinition); var typeOrAttr = (nodeEdgeKey as ChainPartTypeOrAttributeDefinition); if (true || typeOrAttr.DBType != null && typeOrAttr.TypeAttribute != null) { #region defined var edgeKey = typeOrAttr.EdgeKey; selElem.Element = typeOrAttr.TypeAttribute; //_DBContext.DBTypeManager.GetTypeAttributeByEdge(edgeKey); if (String.IsNullOrEmpty(selElem.Alias) || (nodeEdgeKey.Next != null && !(nodeEdgeKey.Next is ChainPartFuncDefinition))) { selElem.Alias = typeOrAttr.TypeAttribute.Name;//_DBContext.DBTypeManager.GetTypeAttributeByEdge(edgeKey).Name; } curLevel += edgeKey; preLevel = curLevel.GetPredecessorLevel(); #endregion } else { #region undefined attribute if (myIDChainDefinition.Level == 0) { preLevel = new EdgeList(myIDChainDefinition.LastType.ID); } else { var element = _Selections[myReference].Last(); preLevel = curLevel.GetPredecessorLevel(); //preLevel = curLevel; } selElem.Alias = typeOrAttr.TypeOrAttributeName; selElem.Element = new UnstructuredProperty(typeOrAttr.TypeOrAttributeName); #endregion } #region Add to _Selections if valid if (!_Selections.ContainsKey(myReference)) { _Selections.Add(myReference, new Dictionary<EdgeList, List<SelectionElement>>()); } if (!_Selections[myReference].ContainsKey(preLevel)) { _Selections[myReference].Add(preLevel, new List<SelectionElement>()); } /// /// Duplicate AttributeSelection is: "U.Name, U.Name" or "U.Name.TOUPPER(), U.Name" but not "U.Friends.TOP(1).Name, U.Friends.TOP(1).Age" if ((nodeEdgeKey.Next == null || (nodeEdgeKey.Next is ChainPartFuncDefinition && nodeEdgeKey.Next.Next == null)) // U.Name, U.Name U.Name.TOUPPER, U.Name && _Selections[myReference][preLevel].Exists(item => item.Alias == selElem.Alias && selElem.EdgeList.Level == item.EdgeList.Level && item.RelatedIDChainDefinition.Depth == selElem.RelatedIDChainDefinition.Depth && item.Element != null) && !myIsGroupedOrAggregated) { throw new DuplicateAttributeSelectionException(selElem.Alias); } // Do not add again if: // - it is a defined attribute and there is an asterisk selection at this level // - it is not the last part AND // - there is already an item of this part with the same alias and the same Depth if (nodeEdgeKey.Next == null || _Selections[myReference][preLevel].Count == 0 || _Selections[myReference][preLevel].Any(item => IsNewSelectionElement(item, selElem))) { _Selections[myReference][preLevel].Add(selElem); } #endregion lastElem = selElem; #endregion } else if (nodeEdgeKey is ChainPartFuncDefinition) { var chainPartFuncDefinition = (nodeEdgeKey as ChainPartFuncDefinition); #region Function if (myReference == null) { #region Type independent functions var selElem = new SelectionElement(myAlias, myIDChainDefinition); if (String.IsNullOrEmpty(selElem.Alias)) { selElem.Alias = chainPartFuncDefinition.SourceParsedString; } var funcElem = new SelectionElementFunction(selElem, chainPartFuncDefinition, chainPartFuncDefinition.Parameters); if (lastElem is SelectionElementFunction) { (lastElem as SelectionElementFunction).AddFollowingFunction(funcElem); lastElem = funcElem; } else { if (_SelectionElementsTypeIndependend.Any(se => se.Alias == funcElem.Alias)) { throw new DuplicateAttributeSelectionException(funcElem.Alias); } _SelectionElementsTypeIndependend.Add(funcElem); lastElem = funcElem; } #endregion } else { #region Type dependent function var funcElem = new SelectionElementFunction(lastElem, (nodeEdgeKey as ChainPartFuncDefinition), (nodeEdgeKey as ChainPartFuncDefinition).Parameters); funcElem.RelatedIDChainDefinition = myIDChainDefinition; if (!String.IsNullOrEmpty(myAlias) && nodeEdgeKey.Next == null) { funcElem.Alias = myAlias; } if (lastElem is SelectionElementFunction) { (lastElem as SelectionElementFunction).AddFollowingFunction(funcElem); } else if (_Selections[myReference][preLevel].Contains(lastElem)) { #region Add function to the last selection element (replace it) _Selections[myReference][preLevel].Remove(lastElem); //lastElem = new SelectionElementFunction(lastElem, (nodeEdgeKey as ChainPartFuncDefinition), (nodeEdgeKey as ChainPartFuncDefinition).Parameters); //lastElem.RelatedIDChainDefinition = myIDChainDefinition; //if (!String.IsNullOrEmpty(alias) && nodeEdgeKey.Next == null) //{ // lastElem.Alias = alias; //} if (!_Selections[myReference][preLevel].Contains(funcElem)) // In case this Element with func is already in the selection list do nothing. { _Selections[myReference][preLevel].Add(funcElem); } #endregion } //functions are not equal && it is the end of a function sequence else if (!_Selections[myReference][preLevel].Contains(funcElem) && !(nodeEdgeKey.Next is ChainPartFuncDefinition)) { #region In this case we have a similar function but NOT THE SAME. Since we don't know what to do, return error. throw new InvalidVertexAttributeSelectionException(myIDChainDefinition.ContentString); #endregion } //always assign funcElem to lastElem, otherwise the part of add following functions doesn't work lastElem = funcElem; #endregion } #endregion } } #region Set the SelectValueAssignment for the last element if (lastElem != null && mySelectValueAssignment != null) { #region Error handling System.Diagnostics.Debug.Assert(lastElem.Element != null); if (lastElem.Element.Kind != AttributeType.Property && lastElem.Element.Kind != AttributeType.BinaryProperty) { throw new InvalidSelectValueAssignmentException(lastElem.Element.Name); } if (!(mySelectValueAssignment.TermDefinition is ValueDefinition)) { throw new NotImplementedQLException(""); } #endregion #region Validate datatype if the attribute is a defined attribute //if (!(lastElem.Element is UnstructuredProperty)) //{ // if (!lastElem.Element.GetADBBaseObjectType(_DBContext.DBTypeManager).IsValidValue((mySelectValueAssignment.TermDefinition as ValueDefinition).Value.Value)) // { // return new Exceptional(new Error_SelectValueAssignmentDataTypeDoesNotMatch(lastElem.Element.GetADBBaseObjectType(_DBContext.DBTypeManager).ObjectName, (mySelectValueAssignment.TermDefinition as ValueDefinition).Value.ObjectName)); // } // var typedValue = new ValueDefinition(lastElem.Element.GetADBBaseObjectType(_DBContext.DBTypeManager).Clone((mySelectValueAssignment.TermDefinition as ValueDefinition).Value.Value)); // mySelectValueAssignment.TermDefinition = typedValue; //} #endregion lastElem.SelectValueAssignment = mySelectValueAssignment; } #endregion }