/// <summary> /// Group all DBOs and return the readouts /// </summary> /// <param name="myDBObjectStreams"></param> /// <param name="mySelections"></param> /// <param name="myReferencedDBType"></param> /// <returns></returns> private IEnumerable<Vertex> ExamineDBO_Groupings(IEnumerable<Exceptional<DBObjectStream>> myDBObjectStreams, List<SelectionElement> mySelections, GraphDBType myReferencedDBType) { #region Create groupings using the ILookup var _GroupedVertices = myDBObjectStreams.ToLookup((dbo) => { CheckLoadedDBObjectStream(dbo, myReferencedDBType); #region Create GroupingKey based on the group values and attributes var groupingVals = new Dictionary<GroupingValuesKey, IObject>(); foreach (var selection in mySelections) { if (!dbo.Value.HasAttribute(selection.Element, _DBContext)) { continue; } 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 _GroupedVertices) { #region No valid grouping keys found if (group.Key.Values.IsNullOrEmpty()) { continue; } #endregion var groupedAttributes = new Dictionary<String, Object>(); foreach (var groupingKeyVal in group.Key.Values) { groupedAttributes.Add(groupingKeyVal.Key.AttributeAlias, groupingKeyVal.Value.GetReadoutValue()); } var _VertexGroup = new VertexGroup(groupedAttributes, group.Select(_DBObjectStream => new Vertex(GetAllSelectedAttributesFromVertex(_DBObjectStream, myReferencedDBType, -1, null, null, false, true)))); #region Check having if (_HavingExpression != null) { var res = _HavingExpression.IsSatisfyHaving(_VertexGroup, _DBContext); if (res.Failed()) throw new GraphDBException(res.IErrors); else if (res.Value) yield return _VertexGroup; } else { yield return _VertexGroup; } #endregion } }
/// <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 }