/// <summary> /// Go through each DBO and aggregate them /// </summary> /// <param name="myAggregates"></param> /// <param name="mySelections"></param> /// <param name="myDBOs"></param> /// <param name="myReferencedDBType"></param> /// <returns></returns> private IEnumerable<Vertex> ExamineDBO_Aggregates(IEnumerable<Exceptional<DBObjectStream>> myDBOs, List<SelectionElementAggregate> myAggregates, List<SelectionElement> mySelections, GraphDBType myReferencedDBType, Boolean myUsingGraph) { #region Aggregate if (mySelections.CountIsGreater(0)) { #region Grouping - each selection is grouped (checked prior) var aggregatedGroupings = new Dictionary<GroupingKey, SelectionElementAggregate>(); #region Create groupings using the ILookup var groupedDBOs = myDBOs.ToLookup((dbo) => { CheckLoadedDBObjectStream(dbo, myReferencedDBType); #region Create GroupingKey based on the group values and attributes Dictionary<GroupingValuesKey, IObject> groupingVals = new Dictionary<GroupingValuesKey, IObject>(); foreach (var selection in mySelections) { var attrValue = dbo.Value.GetAttribute(selection.Element, myReferencedDBType, _DBContext); if (attrValue.Failed()) { throw new GraphDBException(attrValue.IErrors); } groupingVals.Add(new GroupingValuesKey(selection.Element, selection.Alias), attrValue.Value); } GroupingKey groupingKey = new GroupingKey(groupingVals); #endregion return groupingKey; }, (dbo) => { CheckLoadedDBObjectStream(dbo, myReferencedDBType); return dbo.Value; }); #endregion foreach (var group in groupedDBOs) { #region Create group readouts var aggregatedAttributes = new Dictionary<String, Object>(); foreach (var aggr in myAggregates) { var aggrResult = aggr.Aggregate.Aggregate(group as IEnumerable<DBObjectStream>, aggr.Element, _DBContext); if (aggrResult.Failed()) { throw new GraphDBException(aggrResult.IErrors); } aggregatedAttributes.Add(aggr.Alias, aggrResult.Value.GetReadoutValue()); } foreach (var groupingKeyVal in group.Key.Values) { aggregatedAttributes.Add(groupingKeyVal.Key.AttributeAlias, groupingKeyVal.Value.GetReadoutValue()); } var dbObjectReadout = new VertexGroup(aggregatedAttributes, (group as IEnumerable<DBObjectStream>).Select(dbo => new Vertex(GetAllSelectedAttributesFromVertex(dbo, myReferencedDBType, -1, null, null, false, true)))); #endregion #region Evaluate having if exist and yield return if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(dbObjectReadout, _DBContext); if (res.Failed()) throw new GraphDBException(res.IErrors); else if (res.Value) yield return dbObjectReadout; } else { yield return dbObjectReadout; } #endregion } yield break; #endregion } else { #region No grouping, just aggregates var aggregatedAttributes = new Dictionary<String, Object>(); Vertex _Vertex; if (!myUsingGraph && myAggregates.All(a => a.IndexAggregate != null)) { #region Index aggregates foreach (var aggr in myAggregates) { var idxAggrResult = aggr.Aggregate.Aggregate(aggr.IndexAggregate, myReferencedDBType, _DBContext); if (idxAggrResult.Failed()) { throw new GraphDBException(idxAggrResult.IErrors); } aggregatedAttributes.Add(aggr.Alias, idxAggrResult.Value.GetReadoutValue()); } _Vertex = new Vertex(aggregatedAttributes); #endregion } else { #region OR Attribute aggregates foreach (var aggr in myAggregates) { var curType = _DBContext.DBTypeManager.GetTypeByUUID(aggr.EdgeList.LastEdge.TypeUUID); var curAttr = curType.GetTypeAttributeByUUID(aggr.EdgeList.LastEdge.AttrUUID); var aggrResult = aggr.Aggregate.Aggregate(myDBOs.Select(dbo => { CheckLoadedDBObjectStream(dbo, curType, curAttr); return dbo.Value; }), aggr.Element, _DBContext); if (aggrResult.Failed()) { throw new GraphDBException(aggrResult.IErrors); } aggregatedAttributes.Add(aggr.Alias, aggrResult.Value.GetReadoutValue()); } _Vertex = new Vertex(aggregatedAttributes); #endregion } #region Check having expression and yield return value if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(_Vertex, _DBContext); if (res.Failed()) throw new GraphDBException(res.IErrors); else if (res.Value) yield return _Vertex; } else { yield return _Vertex; } #endregion yield break; #endregion } #endregion }
private List<GraphDBType> ResolveSubTypes(GraphDBType myGraphDBType, List<GraphDBType> resultList, List<GraphDBType> listToVisit) { listToVisit.Remove(myGraphDBType); var subTypes = _UserDefinedTypes.Values.Where(item => item.ParentTypeUUID == myGraphDBType.UUID); var nextType = subTypes.FirstOrDefault(); if (subTypes.CountIsGreater(0)) { listToVisit.AddRange(subTypes); resultList.AddRange(subTypes); } if (nextType == null && listToVisit.CountIsGreater(0)) { nextType = listToVisit.First(); } if (nextType == null || nextType == myGraphDBType) { return resultList; } return ResolveSubTypes(nextType, resultList, listToVisit); }
/// <summary> /// Go through each DBO and aggregate them /// </summary> /// <param name="myAggregates"></param> /// <param name="mySelections"></param> /// <param name="myDBOs"></param> /// <param name="myReferencedDBType"></param> /// <returns></returns> private IEnumerable<IVertexView> ExamineDBO_Aggregates(Int64 myTransactionToken, SecurityToken mySecurityToken, IEnumerable<IVertex> myDBOs, List<SelectionElementAggregate> myAggregates, List<SelectionElement> mySelections, Boolean myUsingGraph, Int64 myDepth) { #region Aggregate if (mySelections.CountIsGreater(0)) { #region Grouping - each selection is grouped (checked prior) var aggregatedGroupings = new Dictionary<GroupingKey, SelectionElementAggregate>(); #region Create groupings using the ILookup var groupedDBOs = myDBOs.ToLookup((dbo) => { #region Create GroupingKey based on the group values and attributes Dictionary<GroupingValuesKey, IComparable> groupingVals = new Dictionary<GroupingValuesKey, IComparable>(); foreach (var selection in mySelections) { var attrValue = (selection.Element as IPropertyDefinition).GetValue(dbo); groupingVals.Add(new GroupingValuesKey(selection.Element, selection.Alias), attrValue); } GroupingKey groupingKey = new GroupingKey(groupingVals); #endregion return groupingKey; }, (dbo) => { return dbo; }); #endregion foreach (var group in groupedDBOs) { #region Create group readouts var aggregatedAttributes = new Dictionary<String, Object>(); foreach (var aggr in myAggregates) { var aggrResult = aggr.Aggregate.Aggregate( (group).Select( aVertex => (aggr.Element as IPropertyDefinition).GetValue(aVertex)), (IPropertyDefinition)aggr.Element); if (aggrResult.Value != null) { //aggregatedAttributes.Add(aggr.Alias, aggrResult.Value.Value.GetReadoutValue()); aggregatedAttributes.Add(aggr.Alias, ResolveAggregateResult(aggrResult, myDepth)); } } foreach (var groupingKeyVal in group.Key.Values) { aggregatedAttributes.Add(groupingKeyVal.Key.AttributeAlias, groupingKeyVal.Value); } var dbObjectReadout = new VertexView(aggregatedAttributes, null); #endregion #region Evaluate having if exist and yield return if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(dbObjectReadout); if (res) yield return dbObjectReadout; } else { yield return dbObjectReadout; } #endregion } yield break; #endregion } else { #region No grouping, just aggregates var aggregatedAttributes = new Dictionary<String, Object>(); VertexView _Vertex; #region OR Attribute aggregates foreach (var aggr in myAggregates) { FuncParameter aggrResult = null; if (aggr.Aggregate.PluginShortName == "count" && aggr.RelatedIDChainDefinition.SelectType == TypesOfSelect.Asterisk) { aggrResult = new FuncParameter(_graphdb.GetVertexCount<UInt64>(mySecurityToken, myTransactionToken, new RequestGetVertexCount(aggr.EdgeList.LastEdge.VertexTypeID), (stats, count) => count)); } else { aggrResult = aggr.Aggregate.Aggregate( myDBOs.Where(aVertex => (aggr.Element as IPropertyDefinition).HasValue(aVertex)).Select( dbo => (aggr.Element as IPropertyDefinition).GetValue(dbo)), (IPropertyDefinition)aggr.Element); } //aggregatedAttributes.Add(aggr.Alias, aggrResult.Value.GetReadoutValue()); if (aggrResult.Value != null) { aggregatedAttributes.Add(aggr.Alias, ResolveAggregateResult(aggrResult, myDepth)); } } _Vertex = new VertexView(aggregatedAttributes, null); #endregion #region Check having expression and yield return value if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(_Vertex); if (res) yield return _Vertex; } else { yield return _Vertex; } #endregion yield break; #endregion } #endregion }