From 76f1e8900fc3b82ff424f2361ed202b70473d941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20L=2E=20Charlier?= Date: Thu, 14 Nov 2019 00:11:20 +0100 Subject: [PATCH 1/3] Huge refactoring for IResultSetFilter including usage of Context for aliases and expressions --- NBi.Core/Calculation/BaseRankingFilter.cs | 20 +- .../AndCombinationPredicateFilter.cs | 35 -- .../BaseCombinationPredicateFilter.cs | 43 --- .../OrCombinationPredicateFilter.cs | 35 -- .../XOrCombinationPredicateFilter.cs | 34 -- NBi.Core/Calculation/FilterGroupByFilter.cs | 47 --- .../Grouping/CaseBased/GroupByCase.cs | 42 +++ .../AbstractByColumnGrouping.cs | 9 +- .../{ => ColumnBased}/NameByColumnGrouping.cs | 2 +- .../OrdinalByColumnGrouping.cs | 2 +- ...mnGroupingFactory.cs => GroupByFactory.cs} | 9 +- .../{IByColumnGrouping.cs => IGroupBy.cs} | 2 +- NBi.Core/Calculation/Grouping/NoneGrouping.cs | 4 +- .../Predication/AndCombinationPredication.cs | 28 ++ .../Predication/BaseCombinationPredication.cs | 51 +++ .../Calculation/Predication/IPredication.cs | 16 + .../Predication/OrCombinationPredication.cs | 30 ++ .../Predication/PredicationFactory.cs | 32 ++ .../Predication/SinglePredication.cs | 37 +++ .../Predication/XOrCombinationPredication.cs | 31 ++ .../Calculation/Ranking/AbstractRanking.cs | 4 +- .../Calculation/ResultSetFilterFactory.cs | 78 ----- ...redicateFilter.cs => RowValueExtractor.cs} | 67 +--- NBi.Core/Calculation/SinglePredicateFilter.cs | 74 +++-- NBi.Core/NBi.Core.csproj | 37 ++- .../Alteration/Reshaping/UnstackEngine.cs | 2 +- .../Summarization/SummarizeEngine.cs | 2 +- NBi.Core/ResultSet/Filtering/BaseFilter.cs | 56 ++++ NBi.Core/ResultSet/Filtering/GroupByFilter.cs | 41 +++ .../Filtering}/IResultSetFilter.cs | 10 +- .../Filtering}/NoneFilter.cs | 16 +- .../ResultSet/Filtering/PredicationFilter.cs | 25 ++ .../Filtering}/ResultSetFilter.cs | 2 +- .../Filtering/ResultSetFilterFactory.cs | 76 +++++ .../KeyCollectionEqualityComparer.cs | 16 + NBi.Core/Variable/Context.cs | 18 +- .../Builder/Helper/ResultSetSystemHelper.cs | 13 +- NBi.NUnit/Builder/ResultSetNoRowsBuilder.cs | 19 +- NBi.NUnit/Builder/ResultSetRowCountBuilder.cs | 15 +- NBi.NUnit/Query/AllRowsConstraint.cs | 1 + NBi.NUnit/Query/NoRowsConstraint.cs | 1 + NBi.NUnit/Query/RowCountFilterConstraint.cs | 4 +- .../RowCountFilterPercentageConstraint.cs | 1 + NBi.NUnit/Query/SingleRowConstraint.cs | 1 + NBi.NUnit/Query/SomeRowsConstraint.cs | 1 + .../NameByColumnGroupingTest.cs | 3 +- .../OrdinalByColumnGroupingTest.cs | 3 +- .../CultureSensitivePredicateMatchesTest.cs | 2 +- .../AndCombinationPredicationTest.cs | 94 ++++++ .../OrCombinationPredicationTest.cs | 112 +++++++ .../XOrCombinationPredicationTest.cs | 109 +++++++ .../Calculation/Ranking/BottomRankingTest.cs | 1 + .../Calculation/Ranking/TopRankingTest.cs | 1 + .../Calculation/SinglePredicateFilterTest.cs | 303 ------------------ NBi.Testing.Core/NBi.Testing.Core.csproj | 14 +- .../Filtering/GroupByFilterTest.cs} | 11 +- .../Filtering/PredicationFilterTest.cs} | 29 +- .../Resolver/ContextScalarResolverTest.cs | 6 +- .../Resolver/ScalarResolverFactoryTest.cs | 2 +- .../TransformationProviderTest.cs | 12 +- .../Helper/PredicateArgsBuilderTest.cs | 2 +- .../Helper/ScalarResolverArgsBuilderTest.cs | 6 +- .../AllRowsConstraintTest.cs | 38 +-- .../NoRowsConstraintTest.cs | 40 +-- .../SingleRowConstraintTest.cs | 40 +-- .../SomeRowsConstraintTest.cs | 46 ++- 66 files changed, 1067 insertions(+), 896 deletions(-) delete mode 100644 NBi.Core/Calculation/Combination/AndCombinationPredicateFilter.cs delete mode 100644 NBi.Core/Calculation/Combination/BaseCombinationPredicateFilter.cs delete mode 100644 NBi.Core/Calculation/Combination/OrCombinationPredicateFilter.cs delete mode 100644 NBi.Core/Calculation/Combination/XOrCombinationPredicateFilter.cs delete mode 100644 NBi.Core/Calculation/FilterGroupByFilter.cs create mode 100644 NBi.Core/Calculation/Grouping/CaseBased/GroupByCase.cs rename NBi.Core/Calculation/Grouping/{ => ColumnBased}/AbstractByColumnGrouping.cs (77%) rename NBi.Core/Calculation/Grouping/{ => ColumnBased}/NameByColumnGrouping.cs (91%) rename NBi.Core/Calculation/Grouping/{ => ColumnBased}/OrdinalByColumnGrouping.cs (92%) rename NBi.Core/Calculation/Grouping/{ByColumnGroupingFactory.cs => GroupByFactory.cs} (90%) rename NBi.Core/Calculation/Grouping/{IByColumnGrouping.cs => IGroupBy.cs} (88%) create mode 100644 NBi.Core/Calculation/Predication/AndCombinationPredication.cs create mode 100644 NBi.Core/Calculation/Predication/BaseCombinationPredication.cs create mode 100644 NBi.Core/Calculation/Predication/IPredication.cs create mode 100644 NBi.Core/Calculation/Predication/OrCombinationPredication.cs create mode 100644 NBi.Core/Calculation/Predication/PredicationFactory.cs create mode 100644 NBi.Core/Calculation/Predication/SinglePredication.cs create mode 100644 NBi.Core/Calculation/Predication/XOrCombinationPredication.cs delete mode 100644 NBi.Core/Calculation/ResultSetFilterFactory.cs rename NBi.Core/Calculation/{BasePredicateFilter.cs => RowValueExtractor.cs} (60%) create mode 100644 NBi.Core/ResultSet/Filtering/BaseFilter.cs create mode 100644 NBi.Core/ResultSet/Filtering/GroupByFilter.cs rename NBi.Core/{Calculation => ResultSet/Filtering}/IResultSetFilter.cs (51%) rename NBi.Core/{Calculation => ResultSet/Filtering}/NoneFilter.cs (60%) create mode 100644 NBi.Core/ResultSet/Filtering/PredicationFilter.cs rename NBi.Core/{Calculation => ResultSet/Filtering}/ResultSetFilter.cs (86%) create mode 100644 NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs create mode 100644 NBi.Core/ResultSet/KeyCollectionEqualityComparer.cs rename NBi.Testing.Core/Calculation/Grouping/{ => ColumnBased}/NameByColumnGroupingTest.cs (97%) rename NBi.Testing.Core/Calculation/Grouping/{ => ColumnBased}/OrdinalByColumnGroupingTest.cs (97%) rename NBi.Testing.Core/Calculation/{ => Predicate}/CultureSensitivePredicateMatchesTest.cs (98%) create mode 100644 NBi.Testing.Core/Calculation/Predication/AndCombinationPredicationTest.cs create mode 100644 NBi.Testing.Core/Calculation/Predication/OrCombinationPredicationTest.cs create mode 100644 NBi.Testing.Core/Calculation/Predication/XOrCombinationPredicationTest.cs delete mode 100644 NBi.Testing.Core/Calculation/SinglePredicateFilterTest.cs rename NBi.Testing.Core/{Calculation/FilterGroupByFilterTest.cs => ResultSet/Filtering/GroupByFilterTest.cs} (87%) rename NBi.Testing.Core/{Calculation/CombinationPredicateFilterTest.cs => ResultSet/Filtering/PredicationFilterTest.cs} (87%) diff --git a/NBi.Core/Calculation/BaseRankingFilter.cs b/NBi.Core/Calculation/BaseRankingFilter.cs index 53d098fbb..20d9cc432 100644 --- a/NBi.Core/Calculation/BaseRankingFilter.cs +++ b/NBi.Core/Calculation/BaseRankingFilter.cs @@ -2,6 +2,8 @@ using NBi.Core.Calculation.Ranking.Scoring; using NBi.Core.Evaluate; using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Filtering; +using NBi.Core.Variable; using System; using System.Collections.Generic; using System.Data; @@ -13,17 +15,17 @@ namespace NBi.Core.Calculation { public abstract class BaseRankingFilter : IResultSetFilter { - protected readonly IColumnIdentifier operand; - protected readonly ColumnType columnType; - protected readonly IEnumerable aliases; - protected readonly IEnumerable expressions; + protected IColumnIdentifier Operand { get; } + protected ColumnType ColumnType { get; } + protected IEnumerable Aliases { get; } + protected IEnumerable Expressions { get; } protected BaseRankingFilter(IColumnIdentifier operand, ColumnType columnType, IEnumerable aliases, IEnumerable expressions) { - this.operand = operand; - this.columnType = columnType; - this.aliases = aliases; - this.expressions = expressions; + this.Operand = operand; + this.ColumnType = columnType; + this.Aliases = aliases; + this.Expressions = expressions; } public ResultSet.ResultSet AntiApply(ResultSet.ResultSet rs) @@ -32,7 +34,7 @@ public ResultSet.ResultSet AntiApply(ResultSet.ResultSet rs) public ResultSet.ResultSet Apply(ResultSet.ResultSet rs) { IList subset = new List(); - var scorer = new DataRowScorer(operand, aliases, expressions); + var scorer = new DataRowScorer(Operand, Aliases, Expressions); foreach (DataRow row in rs.Rows) { var score = scorer.Execute(row); diff --git a/NBi.Core/Calculation/Combination/AndCombinationPredicateFilter.cs b/NBi.Core/Calculation/Combination/AndCombinationPredicateFilter.cs deleted file mode 100644 index ebafa1fd7..000000000 --- a/NBi.Core/Calculation/Combination/AndCombinationPredicateFilter.cs +++ /dev/null @@ -1,35 +0,0 @@ -using NBi.Core.Calculation.Predicate; -using NBi.Core.Evaluate; -using NBi.Core.Injection; -using NBi.Core.Variable; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NBi.Core.Calculation.Predicate.Combination -{ - class AndCombinationPredicateFilter : BaseCombinationPredicateFilter - { - public override string Description { get => "and"; } - - public AndCombinationPredicateFilter(ServiceLocator serviceLocator, Context context, IEnumerable aliases, IEnumerable expressions, IEnumerable predications) - : base(serviceLocator, context, aliases, expressions, predications) - { } - - protected override bool RowApply(Context context) - { - var result = true; - var enumerator = predications.GetEnumerator(); - while (enumerator.MoveNext() && result) - { - var value = GetValueFromRow(context, enumerator.Current.Operand); - result = enumerator.Current.Predicate.Execute(value); - } - return result; - } - - } -} diff --git a/NBi.Core/Calculation/Combination/BaseCombinationPredicateFilter.cs b/NBi.Core/Calculation/Combination/BaseCombinationPredicateFilter.cs deleted file mode 100644 index 000da24cb..000000000 --- a/NBi.Core/Calculation/Combination/BaseCombinationPredicateFilter.cs +++ /dev/null @@ -1,43 +0,0 @@ -using NBi.Core.Calculation.Predicate; -using NBi.Core.Evaluate; -using NBi.Core.Injection; -using NBi.Core.Variable; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NBi.Core.Calculation.Predicate.Combination -{ - abstract class BaseCombinationPredicateFilter : BasePredicateFilter - { - protected readonly IEnumerable predications; - - public abstract string Description { get; } - - internal BaseCombinationPredicateFilter(ServiceLocator serviceLocator, Context context, IEnumerable aliases, IEnumerable expressions, IEnumerable predications) - : base(serviceLocator, context, aliases, expressions) - { - this.predications = predications; - } - - public override string Describe() - { - var sb = new StringBuilder(); - foreach (var predication in predications) - { - sb.Append(predication.Operand); - sb.Append(" "); - sb.Append(predication.Predicate.ToString()); - sb.Append(" "); - sb.Append(this.Description); - sb.Append(" "); - } - sb.Remove(sb.Length - this.Description.Length - 2, this.Description.Length + 2); - sb.Append("."); - return sb.ToString(); - } - } -} diff --git a/NBi.Core/Calculation/Combination/OrCombinationPredicateFilter.cs b/NBi.Core/Calculation/Combination/OrCombinationPredicateFilter.cs deleted file mode 100644 index 6e32a42bf..000000000 --- a/NBi.Core/Calculation/Combination/OrCombinationPredicateFilter.cs +++ /dev/null @@ -1,35 +0,0 @@ -using NBi.Core.Calculation.Predicate; -using NBi.Core.Evaluate; -using NBi.Core.Injection; -using NBi.Core.Variable; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NBi.Core.Calculation.Predicate.Combination -{ - class OrCombinationPredicateFilter : BaseCombinationPredicateFilter - { - public override string Description { get => "or"; } - - public OrCombinationPredicateFilter(ServiceLocator serviceLocator, Context context, IEnumerable aliases, IEnumerable expressions, IEnumerable predications) - : base(serviceLocator, context, aliases, expressions, predications) - { } - - protected override bool RowApply(Context context) - { - var result = false; - var enumerator = predications.GetEnumerator(); - while (enumerator.MoveNext() && !result) - { - var value = GetValueFromRow(context, enumerator.Current.Operand); - result = enumerator.Current.Predicate.Execute(value); - } - return result; - } - - } -} diff --git a/NBi.Core/Calculation/Combination/XOrCombinationPredicateFilter.cs b/NBi.Core/Calculation/Combination/XOrCombinationPredicateFilter.cs deleted file mode 100644 index a317b8196..000000000 --- a/NBi.Core/Calculation/Combination/XOrCombinationPredicateFilter.cs +++ /dev/null @@ -1,34 +0,0 @@ -using NBi.Core.Calculation.Predicate; -using NBi.Core.Evaluate; -using NBi.Core.Injection; -using NBi.Core.Variable; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NBi.Core.Calculation.Predicate.Combination -{ - class XOrCombinationPredicateFilter : BaseCombinationPredicateFilter - { - public override string Description { get => "or"; } - - public XOrCombinationPredicateFilter(ServiceLocator serviceLocator, Context context, IEnumerable aliases, IEnumerable expressions, IEnumerable predications) - : base(serviceLocator, context, aliases, expressions, predications) - { } - - protected override bool RowApply(Context context) - { - var result = false; - foreach (var predication in predications) - { - var value = GetValueFromRow(context, predication.Operand); - result ^= predication.Predicate.Execute(value); - } - return result; - } - - } -} diff --git a/NBi.Core/Calculation/FilterGroupByFilter.cs b/NBi.Core/Calculation/FilterGroupByFilter.cs deleted file mode 100644 index 49d487fc5..000000000 --- a/NBi.Core/Calculation/FilterGroupByFilter.cs +++ /dev/null @@ -1,47 +0,0 @@ -using NBi.Core.Calculation.Grouping; -using NBi.Core.ResultSet; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NBi.Core.Calculation -{ - class FilterGroupByFilter: IResultSetFilter - { - private readonly IResultSetFilter filter; - private readonly IByColumnGrouping groupBy; - - public FilterGroupByFilter(IResultSetFilter filter, IByColumnGrouping groupBy) - { - this.filter = filter; - this.groupBy = groupBy; - } - - public ResultSet.ResultSet Apply(ResultSet.ResultSet rs) - { - var newRs = rs.Clone(); - var groups = groupBy.Execute(rs); - foreach (var group in groups) - { - var groupRs = new ResultSet.ResultSet(); - groupRs.Load(group.Value); - var filtered = filter.Apply(groupRs); - newRs.AddRange(filtered.Rows.Cast()); - } - return newRs; - } - - public ResultSet.ResultSet AntiApply(ResultSet.ResultSet rs) - { - throw new NotImplementedException(); - } - - public string Describe() - { - throw new NotImplementedException(); - } - } -} diff --git a/NBi.Core/Calculation/Grouping/CaseBased/GroupByCase.cs b/NBi.Core/Calculation/Grouping/CaseBased/GroupByCase.cs new file mode 100644 index 000000000..baaaf92c8 --- /dev/null +++ b/NBi.Core/Calculation/Grouping/CaseBased/GroupByCase.cs @@ -0,0 +1,42 @@ +using NBi.Core.Calculation.Predication; +using NBi.Core.Variable; +using NBi.Extensibility; +using System; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Grouping.CaseBased +{ + class GroupByCase + { + protected IEnumerable Cases { get; } + + public GroupByCase(IEnumerable cases) + => Cases = cases; + + public IDictionary Execute(ResultSet.ResultSet resultSet, Context context) + { + var stopWatch = new Stopwatch(); + var dico = new Dictionary(); + stopWatch.Start(); + + foreach (DataRow row in resultSet.Rows) + { + context.Switch(row); + var predication = Cases.FirstOrDefault(p => p.Execute(context)); + + if (!dico.ContainsKey(predication)) + dico.Add(predication, row.Table.Clone()); + dico[predication].ImportRow(row); + } + + Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, $"Building rows' groups by cases: {dico.Count} [{stopWatch.Elapsed.ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s")}"); + return dico; + + } + } +} diff --git a/NBi.Core/Calculation/Grouping/AbstractByColumnGrouping.cs b/NBi.Core/Calculation/Grouping/ColumnBased/AbstractByColumnGrouping.cs similarity index 77% rename from NBi.Core/Calculation/Grouping/AbstractByColumnGrouping.cs rename to NBi.Core/Calculation/Grouping/ColumnBased/AbstractByColumnGrouping.cs index 17c27418c..a1ad0a825 100644 --- a/NBi.Core/Calculation/Grouping/AbstractByColumnGrouping.cs +++ b/NBi.Core/Calculation/Grouping/ColumnBased/AbstractByColumnGrouping.cs @@ -8,9 +8,9 @@ using System.Text; using System.Threading.Tasks; -namespace NBi.Core.Calculation.Grouping +namespace NBi.Core.Calculation.Grouping.ColumnBased { - public abstract class AbstractByColumnGrouping : IByColumnGrouping + public abstract class AbstractByColumnGrouping : IGroupBy { protected ISettingsResultSet Settings { get; } @@ -22,7 +22,7 @@ public AbstractByColumnGrouping(ISettingsResultSet settings) public IDictionary Execute(ResultSet.ResultSet resultSet) { var stopWatch = new Stopwatch(); - var dico = new Dictionary(); + var dico = new Dictionary(new KeyCollectionEqualityComparer()); var keyComparer = BuildDataRowsKeyComparer(resultSet.Table); stopWatch.Start(); @@ -33,8 +33,7 @@ public IDictionary Execute(ResultSet.ResultSet resultS dico.Add(key, row.Table.Clone()); dico[key].ImportRow(row); } - Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, string.Format("Building rows' groups: {0} [{1}]", dico.Count, stopWatch.Elapsed.ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s"))); - + Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, $"Building rows' groups: {dico.Count} [{stopWatch.Elapsed.ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s")})]"); return dico; } diff --git a/NBi.Core/Calculation/Grouping/NameByColumnGrouping.cs b/NBi.Core/Calculation/Grouping/ColumnBased/NameByColumnGrouping.cs similarity index 91% rename from NBi.Core/Calculation/Grouping/NameByColumnGrouping.cs rename to NBi.Core/Calculation/Grouping/ColumnBased/NameByColumnGrouping.cs index dfbfff06d..d82d0b280 100644 --- a/NBi.Core/Calculation/Grouping/NameByColumnGrouping.cs +++ b/NBi.Core/Calculation/Grouping/ColumnBased/NameByColumnGrouping.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using NBi.Core.ResultSet; -namespace NBi.Core.Calculation.Grouping +namespace NBi.Core.Calculation.Grouping.ColumnBased { class NameByColumnGrouping : AbstractByColumnGrouping { diff --git a/NBi.Core/Calculation/Grouping/OrdinalByColumnGrouping.cs b/NBi.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGrouping.cs similarity index 92% rename from NBi.Core/Calculation/Grouping/OrdinalByColumnGrouping.cs rename to NBi.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGrouping.cs index d8ecc1a53..f811ac84b 100644 --- a/NBi.Core/Calculation/Grouping/OrdinalByColumnGrouping.cs +++ b/NBi.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGrouping.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using NBi.Core.ResultSet; -namespace NBi.Core.Calculation.Grouping +namespace NBi.Core.Calculation.Grouping.ColumnBased { class OrdinalByColumnGrouping : AbstractByColumnGrouping { diff --git a/NBi.Core/Calculation/Grouping/ByColumnGroupingFactory.cs b/NBi.Core/Calculation/Grouping/GroupByFactory.cs similarity index 90% rename from NBi.Core/Calculation/Grouping/ByColumnGroupingFactory.cs rename to NBi.Core/Calculation/Grouping/GroupByFactory.cs index c74922c8f..933d0c4c9 100644 --- a/NBi.Core/Calculation/Grouping/ByColumnGroupingFactory.cs +++ b/NBi.Core/Calculation/Grouping/GroupByFactory.cs @@ -1,4 +1,5 @@ -using NBi.Core.ResultSet; +using NBi.Core.Calculation.Grouping.ColumnBased; +using NBi.Core.ResultSet; using NBi.Core.ResultSet.Equivalence; using NBi.Core.Scalar.Comparer; using NBi.Core.Transformation; @@ -11,11 +12,11 @@ namespace NBi.Core.Calculation.Grouping { - public class ByColumnGroupingFactory + public class GroupByFactory { - public IByColumnGrouping None() => new NoneGrouping(); + public IGroupBy None() => new NoneGrouping(); - public IByColumnGrouping Instantiate(IEnumerable columns) + public IGroupBy Instantiate(IEnumerable columns) { if ((columns?.Count() ?? 0) == 0) return new NoneGrouping(); diff --git a/NBi.Core/Calculation/Grouping/IByColumnGrouping.cs b/NBi.Core/Calculation/Grouping/IGroupBy.cs similarity index 88% rename from NBi.Core/Calculation/Grouping/IByColumnGrouping.cs rename to NBi.Core/Calculation/Grouping/IGroupBy.cs index 674486e1d..25363ad11 100644 --- a/NBi.Core/Calculation/Grouping/IByColumnGrouping.cs +++ b/NBi.Core/Calculation/Grouping/IGroupBy.cs @@ -8,7 +8,7 @@ namespace NBi.Core.Calculation.Grouping { - public interface IByColumnGrouping + public interface IGroupBy { IDictionary Execute(ResultSet.ResultSet resultSet); } diff --git a/NBi.Core/Calculation/Grouping/NoneGrouping.cs b/NBi.Core/Calculation/Grouping/NoneGrouping.cs index f56823efc..6734f342f 100644 --- a/NBi.Core/Calculation/Grouping/NoneGrouping.cs +++ b/NBi.Core/Calculation/Grouping/NoneGrouping.cs @@ -8,13 +8,13 @@ namespace NBi.Core.Calculation.Grouping { - sealed class NoneGrouping : IByColumnGrouping + sealed class NoneGrouping : IGroupBy { public IDictionary Execute(ResultSet.ResultSet resultSet) { return new Dictionary() { - { new KeyCollection(new object[]{ }), resultSet.Table } + { new KeyCollection(Array.Empty()), resultSet.Table } }; } } diff --git a/NBi.Core/Calculation/Predication/AndCombinationPredication.cs b/NBi.Core/Calculation/Predication/AndCombinationPredication.cs new file mode 100644 index 000000000..c60207fee --- /dev/null +++ b/NBi.Core/Calculation/Predication/AndCombinationPredication.cs @@ -0,0 +1,28 @@ +using NBi.Core.Calculation.Predicate; +using NBi.Core.Evaluate; +using NBi.Core.Injection; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Predication +{ + class AndCombinationPredication : BaseCombinationPredication + { + public override string Description { get => "and"; } + + public AndCombinationPredication(IEnumerable predications) + : base(predications) + { } + + protected override bool ContinueCondition(bool state) + => state; + + protected override bool StartState() + => true; + } +} diff --git a/NBi.Core/Calculation/Predication/BaseCombinationPredication.cs b/NBi.Core/Calculation/Predication/BaseCombinationPredication.cs new file mode 100644 index 000000000..a4df1d0cf --- /dev/null +++ b/NBi.Core/Calculation/Predication/BaseCombinationPredication.cs @@ -0,0 +1,51 @@ +using NBi.Core.Calculation.Predicate; +using NBi.Core.Evaluate; +using NBi.Core.Injection; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Predication +{ + abstract class BaseCombinationPredication : ReadOnlyCollection, IPredication + { + + public abstract string Description { get; } + + internal BaseCombinationPredication(IEnumerable predications) + : base(predications.ToList()) { } + + public string Describe() + { + var sb = new StringBuilder(); + foreach (var predication in this) + { + sb.Append(predication.Describe()); + sb.Append(" "); + sb.Append(this.Description); + sb.Append(" "); + } + sb.Remove(sb.Length - this.Description.Length - 2, this.Description.Length + 2); + sb.Append("."); + return sb.ToString(); + } + + public bool Execute(Context context) + { + var state = StartState(); + var enumerator = this.GetEnumerator(); + while (enumerator.MoveNext() && ContinueCondition(state)) + state = Calculate(state, enumerator.Current.Execute(context)); + return state; + } + + protected abstract bool ContinueCondition(bool state); + protected abstract bool StartState(); + protected virtual bool Calculate(bool previousState, bool currentResult) => currentResult; + } +} diff --git a/NBi.Core/Calculation/Predication/IPredication.cs b/NBi.Core/Calculation/Predication/IPredication.cs new file mode 100644 index 000000000..ce42ca8cf --- /dev/null +++ b/NBi.Core/Calculation/Predication/IPredication.cs @@ -0,0 +1,16 @@ +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Predication +{ + public interface IPredication + { + bool Execute(Context context); + string Describe(); + } +} diff --git a/NBi.Core/Calculation/Predication/OrCombinationPredication.cs b/NBi.Core/Calculation/Predication/OrCombinationPredication.cs new file mode 100644 index 000000000..8b7f6756e --- /dev/null +++ b/NBi.Core/Calculation/Predication/OrCombinationPredication.cs @@ -0,0 +1,30 @@ +using NBi.Core.Calculation.Predicate; +using NBi.Core.Evaluate; +using NBi.Core.Injection; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Predication +{ + class OrCombinationPredication : BaseCombinationPredication + { + public override string Description { get => "or"; } + + public OrCombinationPredication(IEnumerable predications) + : base(predications) + { } + + + protected override bool ContinueCondition(bool state) + => !state; + + protected override bool StartState() + => false; + + } +} diff --git a/NBi.Core/Calculation/Predication/PredicationFactory.cs b/NBi.Core/Calculation/Predication/PredicationFactory.cs new file mode 100644 index 000000000..6b2a94d76 --- /dev/null +++ b/NBi.Core/Calculation/Predication/PredicationFactory.cs @@ -0,0 +1,32 @@ +using NBi.Core.Calculation.Predicate; +using NBi.Core.Evaluate; +using NBi.Core.ResultSet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Predication +{ + class PredicationFactory + { + public IPredication Instantiate(IPredicate predicate, IColumnIdentifier operand) + => new SinglePredication(predicate, operand); + + public IPredication Instantiate(IEnumerable predications, CombinationOperator combinationOperator) + { + switch (combinationOperator) + { + case CombinationOperator.Or: + return new OrCombinationPredication(predications); + case CombinationOperator.XOr: + return new XOrCombinationPredication(predications); + case CombinationOperator.And: + return new AndCombinationPredication(predications); + default: + throw new ArgumentOutOfRangeException(nameof(combinationOperator)); + } + } + } +} diff --git a/NBi.Core/Calculation/Predication/SinglePredication.cs b/NBi.Core/Calculation/Predication/SinglePredication.cs new file mode 100644 index 000000000..05039e25e --- /dev/null +++ b/NBi.Core/Calculation/Predication/SinglePredication.cs @@ -0,0 +1,37 @@ +using NBi.Core.Calculation.Predicate; +using NBi.Core.Evaluate; +using NBi.Core.Injection; +using NBi.Core.ResultSet; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Predication +{ + class SinglePredication : IPredication + { + public IPredicate Predicate { get; } + public IColumnIdentifier Operand { get; } + protected internal RowValueExtractor Extractor { get; } = new RowValueExtractor(new ServiceLocator()); + + public SinglePredication(IPredicate predicate, IColumnIdentifier operand) + => (Predicate, Operand) = (predicate, operand); + + public bool Execute(Context context) + => Predicate.Execute(Extractor.Execute(context, Operand)); + + public virtual string Describe() + { + var sb = new StringBuilder(); + sb.Append(Operand.Label); + sb.Append(" "); + sb.Append(Predicate.ToString()); + sb.Append("."); + return sb.ToString(); + } + } +} diff --git a/NBi.Core/Calculation/Predication/XOrCombinationPredication.cs b/NBi.Core/Calculation/Predication/XOrCombinationPredication.cs new file mode 100644 index 000000000..b614efb72 --- /dev/null +++ b/NBi.Core/Calculation/Predication/XOrCombinationPredication.cs @@ -0,0 +1,31 @@ +using NBi.Core.Calculation.Predicate; +using NBi.Core.Evaluate; +using NBi.Core.Injection; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Predication +{ + class XOrCombinationPredication : BaseCombinationPredication + { + public override string Description { get => "xor"; } + + public XOrCombinationPredication(IEnumerable predications) + : base(predications) + { } + + protected override bool ContinueCondition(bool state) + => true; + + protected override bool StartState() + => false; + + protected override bool Calculate(bool currentState, bool lastResult) + => currentState ^ lastResult; + } +} diff --git a/NBi.Core/Calculation/Ranking/AbstractRanking.cs b/NBi.Core/Calculation/Ranking/AbstractRanking.cs index a2196766e..5ee34b278 100644 --- a/NBi.Core/Calculation/Ranking/AbstractRanking.cs +++ b/NBi.Core/Calculation/Ranking/AbstractRanking.cs @@ -50,7 +50,7 @@ protected override void InsertRow(ScoredObject newObj, ref IList l protected virtual bool RowCompare(ScoredObject oldObj, ScoredObject newObj) { - switch (columnType) + switch (ColumnType) { case ColumnType.Text: return RowCompare(oldObj, newObj); case ColumnType.Numeric: return RowCompare(oldObj, newObj); @@ -65,7 +65,7 @@ protected virtual bool RowCompare(ScoredObject oldObj, ScoredObject newObj) var factory = new PredicateFactory(); var predicateArgs = new ReferencePredicateArgs() { - ColumnType = columnType, + ColumnType = ColumnType, ComparerType = GetComparerType(), Reference = new LiteralScalarResolver(oldObj.Score) }; diff --git a/NBi.Core/Calculation/ResultSetFilterFactory.cs b/NBi.Core/Calculation/ResultSetFilterFactory.cs deleted file mode 100644 index 3a4486bac..000000000 --- a/NBi.Core/Calculation/ResultSetFilterFactory.cs +++ /dev/null @@ -1,78 +0,0 @@ -using NBi.Core.Calculation.Grouping; -using NBi.Core.Calculation.Predicate; -using NBi.Core.Calculation.Predicate.Combination; -using NBi.Core.Calculation.Ranking; -using NBi.Core.Evaluate; -using NBi.Core.Injection; -using NBi.Core.ResultSet; -using NBi.Core.Variable; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NBi.Core.Calculation -{ - public class ResultSetFilterFactory - { - private ServiceLocator ServiceLocator { get; } - private Context Context { get; } - - public ResultSetFilterFactory(ServiceLocator serviceLocator, Context context) - => (ServiceLocator, Context) = (serviceLocator, context); - - public IResultSetFilter Instantiate(IEnumerable aliases, IEnumerable expressions, PredicationArgs predicationArgs) - { - if (predicationArgs.Identifier == null) - throw new ArgumentException("You must specify an operand for a predication. The operand is the column or alias or expression on which the predicate will be evaluated."); - - var factory = new PredicateFactory(); - var predicate = factory.Instantiate(predicationArgs.Predicate); - - var pf = new SinglePredicateFilter(ServiceLocator, Context, aliases, expressions, predicationArgs.Identifier, predicate.Execute, predicate.ToString); - - return pf; - } - - public IResultSetFilter Instantiate(IEnumerable aliases, IEnumerable expressions, CombinationOperator combinationOperator, IEnumerable predicationArgs) - { - var predications = new List(); - - var factory = new PredicateFactory(); - foreach (var predicationArg in predicationArgs) - { - if (predicationArg.Identifier == null) - throw new ArgumentException("You must specify an operand for a predicate. The operand is the column or alias or expression on which the predicate will be evaluated."); - - var predicate = factory.Instantiate(predicationArg.Predicate); - predications.Add(new Predication(predicate, predicationArg.Identifier)); - } - - switch (combinationOperator) - { - case CombinationOperator.Or: - return new OrCombinationPredicateFilter(ServiceLocator, Context, aliases, expressions, predications); - case CombinationOperator.XOr: - return new XOrCombinationPredicateFilter(ServiceLocator, Context, aliases, expressions, predications); - case CombinationOperator.And: - return new AndCombinationPredicateFilter(ServiceLocator, Context, aliases, expressions, predications); - default: - throw new ArgumentOutOfRangeException(nameof(combinationOperator)); - } - } - - - public IResultSetFilter Instantiate(IRankingInfo rankingInfo, IEnumerable columns) - { - var groupingFactory = new ByColumnGroupingFactory(); - var grouping = groupingFactory.Instantiate(columns); - - var rankingFactory = new RankingFactory(); - var ranking = rankingFactory.Instantiate(rankingInfo); - - return new FilterGroupByFilter(ranking, grouping); - } - } -} diff --git a/NBi.Core/Calculation/BasePredicateFilter.cs b/NBi.Core/Calculation/RowValueExtractor.cs similarity index 60% rename from NBi.Core/Calculation/BasePredicateFilter.cs rename to NBi.Core/Calculation/RowValueExtractor.cs index 9a332f5f4..a116d75a3 100644 --- a/NBi.Core/Calculation/BasePredicateFilter.cs +++ b/NBi.Core/Calculation/RowValueExtractor.cs @@ -14,59 +14,14 @@ namespace NBi.Core.Calculation { - public abstract class BasePredicateFilter : IResultSetFilter + public class RowValueExtractor { private ServiceLocator ServiceLocator { get; } - private Context Context { get; } - protected readonly IEnumerable expressions; - protected readonly IEnumerable aliases; - protected BasePredicateFilter(ServiceLocator serviceLocator, Context context, IEnumerable aliases, IEnumerable expressions) - => (ServiceLocator, Context, this.aliases, this.expressions) = (serviceLocator, context, aliases, expressions); + public RowValueExtractor(ServiceLocator serviceLocator) + => (ServiceLocator) = (serviceLocator); - public ResultSet.ResultSet AntiApply(ResultSet.ResultSet rs) - { - return Apply(rs, (x => !x)); - } - - public ResultSet.ResultSet Apply(ResultSet.ResultSet rs) - { - return Apply(rs, (x => x)); - } - - protected ResultSet.ResultSet Apply(ResultSet.ResultSet rs, Func onApply) - { - var filteredRs = new ResultSet.ResultSet(); - var table = rs.Table.Clone(); - filteredRs.Load(table); - filteredRs.Table.Clear(); - - foreach (DataRow row in rs.Rows) - { - Context.Switch(row); - if (onApply(RowApply(Context))) - { - if (filteredRs.Rows.Count == 0 && filteredRs.Columns.Count != row.Table.Columns.Count) - { - foreach (DataColumn column in row.Table.Columns) - { - if (!filteredRs.Columns.Cast().Any(x => x.ColumnName == column.ColumnName)) - filteredRs.Columns.Add(column.ColumnName, typeof(object)); - } - } - filteredRs.Table.ImportRow(row); - } - } - - filteredRs.Table.AcceptChanges(); - return filteredRs; - } - - protected abstract bool RowApply(Context context); - public bool Execute(Context context) => RowApply(context); - - - protected object GetValueFromRow(Context context, IColumnIdentifier identifier) + public object Execute(Context context, IColumnIdentifier identifier) { if (identifier is ColumnOrdinalIdentifier) { @@ -78,11 +33,11 @@ protected object GetValueFromRow(Context context, IColumnIdentifier identifier) } var name = (identifier as ColumnNameIdentifier).Name; - var alias = aliases.SingleOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); + var alias = context.Aliases?.SingleOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); if (alias != null) return context.CurrentRow.ItemArray[alias.Column]; - var expression = expressions.SingleOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); + var expression = context.Expressions?.SingleOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)); if (expression != null) { var result = EvaluateExpression(expression, context); @@ -102,8 +57,8 @@ protected object GetValueFromRow(Context context, IColumnIdentifier identifier) return context.CurrentRow[column.ColumnName]; var existingNames = context.CurrentRow.Table.Columns.Cast().Select(x => x.ColumnName) - .Union(aliases.Select(x => x.Name) - .Union(expressions.Select(x => x.Name))); + .Union(context.Aliases.Select(x => x.Name) + .Union(context.Expressions.Select(x => x.Name))); throw new ArgumentException($"The value '{name}' is not recognized as a column position, a column name, a column alias or an expression. Possible arguments are: '{string.Join("', '", existingNames.ToArray())}'"); } @@ -117,7 +72,7 @@ protected object EvaluateExpression(IColumnExpression expression, Context contex exp.EvaluateParameter += delegate (string name, NCalc.ParameterArgs args) { - args.Result = GetValueFromRow(context, factory.Instantiate(name)); + args.Result = Execute(context, factory.Instantiate(name)); }; return exp.Evaluate(); @@ -126,7 +81,7 @@ protected object EvaluateExpression(IColumnExpression expression, Context contex { var parse = expression.Value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); var variable = new ColumnIdentifierFactory().Instantiate(parse.ElementAt(0)); - var value = GetValueFromRow(context, variable); + var value = Execute(context, variable); foreach (var nativeFunction in parse.Skip(1)) { @@ -141,8 +96,6 @@ protected object EvaluateExpression(IColumnExpression expression, Context contex throw new ArgumentOutOfRangeException($"The language {expression.Language} is not supported during the evaluation of an expression."); } - public abstract string Describe(); - private class TransformationInfo : ITransformationInfo { public ColumnType OriginalType { get; set; } diff --git a/NBi.Core/Calculation/SinglePredicateFilter.cs b/NBi.Core/Calculation/SinglePredicateFilter.cs index 3daa1cc65..599bbbd86 100644 --- a/NBi.Core/Calculation/SinglePredicateFilter.cs +++ b/NBi.Core/Calculation/SinglePredicateFilter.cs @@ -1,42 +1,40 @@ -using NBi.Core.Calculation.Predicate; -using NBi.Core.Evaluate; -using NBi.Core.Injection; -using NBi.Core.ResultSet; -using NBi.Core.Variable; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +//using NBi.Core.Calculation.Predicate; +//using NBi.Core.Evaluate; +//using NBi.Core.Injection; +//using NBi.Core.ResultSet; +//using NBi.Core.Variable; +//using System; +//using System.Collections.Generic; +//using System.Data; +//using System.Linq; +//using System.Text; +//using System.Threading.Tasks; -namespace NBi.Core.Calculation -{ - class SinglePredicateFilter : BasePredicateFilter - { - private readonly Func implementation; - private readonly IColumnIdentifier operand; - private readonly Func describeFunction; +//namespace NBi.Core.Calculation +//{ +// class SinglePredicateFilter : RowValueExtractor +// { +// private readonly Func implementation; +// private readonly IColumnIdentifier operand; +// private readonly Func describeFunction; - public SinglePredicateFilter(ServiceLocator serviceLocator, Context context, IEnumerable aliases, IEnumerable expressions, IColumnIdentifier operand, Func implementation, Func describeFunction) - : base(serviceLocator, context, aliases, expressions) - { - this.operand = operand; - this.implementation = implementation; - this.describeFunction = describeFunction; - } +// public SinglePredicateFilter(ServiceLocator serviceLocator, Context context, IEnumerable aliases, IEnumerable expressions, IColumnIdentifier operand, Func implementation, Func describeFunction) +// : base(serviceLocator, context, aliases, expressions) +// { +// this.operand = operand; +// this.implementation = implementation; +// this.describeFunction = describeFunction; +// } - protected override bool RowApply(Context context) - { - var value = GetValueFromRow(context, operand); - return implementation(value); - } +// protected override bool RowApply(Context context) +// { +// var value = GetValueFromRow(context, operand); +// return implementation(value); +// } - - - public override string Describe() - { - return $"{operand.Label} {describeFunction()}."; - } - } -} +// public override string Describe() +// { +// return $"{operand.Label} {describeFunction()}."; +// } +// } +//} diff --git a/NBi.Core/NBi.Core.csproj b/NBi.Core/NBi.Core.csproj index c63d2b1fe..ca659aa92 100644 --- a/NBi.Core/NBi.Core.csproj +++ b/NBi.Core/NBi.Core.csproj @@ -145,20 +145,24 @@ - - + + + + + - - + + + - - - - - - + + + + + + - + @@ -210,7 +214,7 @@ - + @@ -221,9 +225,9 @@ - - - + + + @@ -504,6 +508,9 @@ + + + diff --git a/NBi.Core/ResultSet/Alteration/Reshaping/UnstackEngine.cs b/NBi.Core/ResultSet/Alteration/Reshaping/UnstackEngine.cs index 3ba87f6af..64ae7e27c 100644 --- a/NBi.Core/ResultSet/Alteration/Reshaping/UnstackEngine.cs +++ b/NBi.Core/ResultSet/Alteration/Reshaping/UnstackEngine.cs @@ -47,7 +47,7 @@ public ResultSet Execute(ResultSet rs) dataTable.Columns.Add(new DataColumn(namingStrategy.Execute(headerValue, valueColumn.ColumnName), typeof(object))); - var groupbyFactory = new ByColumnGroupingFactory(); + var groupbyFactory = new GroupByFactory(); var groupbyEngine = groupbyFactory.Instantiate(Args.GroupBys); var groups = groupbyEngine.Execute(rs); foreach (var group in groups) diff --git a/NBi.Core/ResultSet/Alteration/Summarization/SummarizeEngine.cs b/NBi.Core/ResultSet/Alteration/Summarization/SummarizeEngine.cs index 4b68734c5..90af3014e 100644 --- a/NBi.Core/ResultSet/Alteration/Summarization/SummarizeEngine.cs +++ b/NBi.Core/ResultSet/Alteration/Summarization/SummarizeEngine.cs @@ -41,7 +41,7 @@ public ResultSet Execute(ResultSet rs) aggregations.Add(factory.Instantiate(aggregation)); } - var groupbyFactory = new ByColumnGroupingFactory(); + var groupbyFactory = new GroupByFactory(); var groupbyEngine = groupbyFactory.Instantiate(Args.GroupBys); var groups = groupbyEngine.Execute(rs); foreach (var group in groups) diff --git a/NBi.Core/ResultSet/Filtering/BaseFilter.cs b/NBi.Core/ResultSet/Filtering/BaseFilter.cs new file mode 100644 index 000000000..1a358a148 --- /dev/null +++ b/NBi.Core/ResultSet/Filtering/BaseFilter.cs @@ -0,0 +1,56 @@ +using NBi.Core.Calculation.Predicate; +using NBi.Core.Evaluate; +using NBi.Core.ResultSet; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.ResultSet.Filtering +{ + public abstract class BaseFilter : IResultSetFilter + { + protected Context Context { get; } + protected BaseFilter(Context context) + => Context = context; + + public ResultSet AntiApply(ResultSet rs) => Apply(rs, (x => !x)); + + public ResultSet Apply(ResultSet rs) => Apply(rs, (x => x)); + + protected ResultSet Apply(ResultSet rs, Func onApply) + { + var filteredRs = new ResultSet(); + var table = rs.Table.Clone(); + filteredRs.Load(table); + filteredRs.Table.Clear(); + + foreach (DataRow row in rs.Rows) + { + Context.Switch(row); + if (onApply(RowApply(Context))) + { + if (filteredRs.Rows.Count == 0 && filteredRs.Columns.Count != row.Table.Columns.Count) + { + foreach (DataColumn column in row.Table.Columns) + { + if (!filteredRs.Columns.Cast().Any(x => x.ColumnName == column.ColumnName)) + filteredRs.Columns.Add(column.ColumnName, typeof(object)); + } + } + filteredRs.Table.ImportRow(row); + } + } + + filteredRs.Table.AcceptChanges(); + return filteredRs; + } + + protected abstract bool RowApply(Context context); + + public abstract string Describe(); + } +} \ No newline at end of file diff --git a/NBi.Core/ResultSet/Filtering/GroupByFilter.cs b/NBi.Core/ResultSet/Filtering/GroupByFilter.cs new file mode 100644 index 000000000..aa8135cc6 --- /dev/null +++ b/NBi.Core/ResultSet/Filtering/GroupByFilter.cs @@ -0,0 +1,41 @@ +using NBi.Core.Calculation.Grouping; +using NBi.Core.ResultSet; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.ResultSet.Filtering +{ + class GroupByFilter: IResultSetFilter + { + private IResultSetFilter Filter { get; } + private IGroupBy GroupBy { get; } + + public GroupByFilter(IResultSetFilter filter, IGroupBy groupBy) + => (Filter, GroupBy) = (filter, groupBy); + + public ResultSet Apply(ResultSet rs) + { + var newRs = rs.Clone(); + var groups = GroupBy.Execute(rs); + foreach (var group in groups) + { + var groupRs = new ResultSet(); + groupRs.Load(group.Value); + var filtered = Filter.Apply(groupRs); + newRs.AddRange(filtered.Rows.Cast()); + } + return newRs; + } + + public ResultSet AntiApply(ResultSet rs) + => throw new NotImplementedException(); + + public string Describe() + => throw new NotImplementedException(); + } +} diff --git a/NBi.Core/Calculation/IResultSetFilter.cs b/NBi.Core/ResultSet/Filtering/IResultSetFilter.cs similarity index 51% rename from NBi.Core/Calculation/IResultSetFilter.cs rename to NBi.Core/ResultSet/Filtering/IResultSetFilter.cs index 1b6e86f5a..835966744 100644 --- a/NBi.Core/Calculation/IResultSetFilter.cs +++ b/NBi.Core/ResultSet/Filtering/IResultSetFilter.cs @@ -1,16 +1,16 @@ -using System; +using NBi.Core.Variable; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using RS = NBi.Core.ResultSet; -namespace NBi.Core.Calculation +namespace NBi.Core.ResultSet.Filtering { public interface IResultSetFilter { - RS.ResultSet Apply(RS.ResultSet rs); - RS.ResultSet AntiApply(RS.ResultSet rs); + ResultSet Apply(ResultSet rs); + ResultSet AntiApply(ResultSet rs); string Describe(); } diff --git a/NBi.Core/Calculation/NoneFilter.cs b/NBi.Core/ResultSet/Filtering/NoneFilter.cs similarity index 60% rename from NBi.Core/Calculation/NoneFilter.cs rename to NBi.Core/ResultSet/Filtering/NoneFilter.cs index 39dc53e43..7395183d6 100644 --- a/NBi.Core/Calculation/NoneFilter.cs +++ b/NBi.Core/ResultSet/Filtering/NoneFilter.cs @@ -1,34 +1,32 @@ -using System; +using NBi.Core.Variable; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace NBi.Core.Calculation +namespace NBi.Core.ResultSet.Filtering { class NoneFilter : IResultSetFilter { - public ResultSet.ResultSet Apply(ResultSet.ResultSet rs) + public ResultSet Apply(ResultSet rs) { if (rs == null) throw new ArgumentNullException(); return rs; } - public ResultSet.ResultSet AntiApply(ResultSet.ResultSet rs) + public ResultSet AntiApply(ResultSet rs) { if (rs == null) throw new ArgumentNullException(); - var filteredRs = new ResultSet.ResultSet(); + var filteredRs = new ResultSet(); var table = rs.Table.Clone(); filteredRs.Load(table); return filteredRs; } - public string Describe() - { - return "none"; - } + public string Describe() => "none"; } } diff --git a/NBi.Core/ResultSet/Filtering/PredicationFilter.cs b/NBi.Core/ResultSet/Filtering/PredicationFilter.cs new file mode 100644 index 000000000..e504de1a8 --- /dev/null +++ b/NBi.Core/ResultSet/Filtering/PredicationFilter.cs @@ -0,0 +1,25 @@ +using NBi.Core.Calculation.Predication; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.ResultSet.Filtering +{ + class PredicationFilter : BaseFilter + { + private IPredication Predication { get; } + + public PredicationFilter(IPredication predication, Context context) + : base(context) => Predication = predication; + + protected override bool RowApply(Context context) + => Predication.Execute(context); + + public override string Describe() + => $"{Predication.Describe()}"; + } +} diff --git a/NBi.Core/Calculation/ResultSetFilter.cs b/NBi.Core/ResultSet/Filtering/ResultSetFilter.cs similarity index 86% rename from NBi.Core/Calculation/ResultSetFilter.cs rename to NBi.Core/ResultSet/Filtering/ResultSetFilter.cs index 9f8b00a64..63a6e8818 100644 --- a/NBi.Core/Calculation/ResultSetFilter.cs +++ b/NBi.Core/ResultSet/Filtering/ResultSetFilter.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace NBi.Core.Calculation +namespace NBi.Core.ResultSet.Filtering { public abstract class ResultSetFilter { diff --git a/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs b/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs new file mode 100644 index 000000000..850b891ef --- /dev/null +++ b/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs @@ -0,0 +1,76 @@ +using NBi.Core.Calculation; +using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Predicate; +using NBi.Core.Calculation.Predicate.Combination; +using NBi.Core.Calculation.Predication; +using NBi.Core.Calculation.Ranking; +using NBi.Core.Evaluate; +using NBi.Core.Injection; +using NBi.Core.ResultSet; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.ResultSet.Filtering +{ + public class ResultSetFilterFactory + { + private ServiceLocator ServiceLocator { get; } + + public ResultSetFilterFactory(ServiceLocator serviceLocator) + => (ServiceLocator) = (serviceLocator); + + public IResultSetFilter Instantiate(PredicationArgs predicationArgs, Context context) + { + if (predicationArgs.Identifier == null) + throw new ArgumentException("You must specify an operand for a predication. The operand is the column or alias or expression on which the predicate will be evaluated."); + + var factory = new PredicateFactory(); + var predicate = factory.Instantiate(predicationArgs.Predicate); + + var predicationFactory = new PredicationFactory(); + var predication = predicationFactory.Instantiate(predicate, predicationArgs.Identifier); + + var filter = new PredicationFilter(predication, context); + return filter; + } + + public IResultSetFilter Instantiate(CombinationOperator combinationOperator, IEnumerable predicationArgs, Context context) + { + var predications = new List(); + + var predicateFactory = new PredicateFactory(); + var predicationFactory = new PredicationFactory(); + + foreach (var predicationArg in predicationArgs) + { + if (predicationArg.Identifier == null) + throw new ArgumentException("You must specify an operand for a predicate. The operand is the column or alias or expression on which the predicate will be evaluated."); + + var predicate = predicateFactory.Instantiate(predicationArg.Predicate); + var localPredication = predicationFactory.Instantiate(predicate, predicationArg.Identifier); + predications.Add(localPredication); + } + + var predication = predicationFactory.Instantiate(predications, combinationOperator); + var filter = new PredicationFilter(predication, context); + return filter; + } + + + public IResultSetFilter Instantiate(IRankingInfo rankingInfo, IEnumerable columns) + { + var groupingFactory = new GroupByFactory(); + var grouping = groupingFactory.Instantiate(columns); + + var rankingFactory = new RankingFactory(); + var ranking = rankingFactory.Instantiate(rankingInfo); + + return new GroupByFilter(ranking, grouping); + } + } +} diff --git a/NBi.Core/ResultSet/KeyCollectionEqualityComparer.cs b/NBi.Core/ResultSet/KeyCollectionEqualityComparer.cs new file mode 100644 index 000000000..cd3590d7d --- /dev/null +++ b/NBi.Core/ResultSet/KeyCollectionEqualityComparer.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.ResultSet +{ + class KeyCollectionEqualityComparer : IEqualityComparer + { + public int GetHashCode(object x) + => (x as KeyCollection)?.GetHashCode() ?? 0; + public new bool Equals(object x, object y) + => (x as KeyCollection)?.Equals(y as KeyCollection) ?? false; + } +} diff --git a/NBi.Core/Variable/Context.cs b/NBi.Core/Variable/Context.cs index 64a644d4f..41b0e2d91 100644 --- a/NBi.Core/Variable/Context.cs +++ b/NBi.Core/Variable/Context.cs @@ -1,4 +1,5 @@ -using System; +using NBi.Core.Evaluate; +using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -9,15 +10,24 @@ namespace NBi.Core.Variable { public class Context { - public IDictionary Variables { get; } + + public IEnumerable Aliases { get; } = new List(); + public IEnumerable Expressions { get; } = new List(); + + public IDictionary Variables { get; } = new Dictionary(); public DataRow CurrentRow { get; private set; } + public static Context None { get; } = new Context(); + + private Context() { } + public Context(IDictionary variables) => Variables = variables; + public Context(IDictionary variables, IEnumerable aliases, IEnumerable expressions) + : this(variables) => (Aliases, Expressions) = (aliases, expressions); + public void Switch(DataRow currentRow) => CurrentRow = currentRow; - - } } diff --git a/NBi.NUnit/Builder/Helper/ResultSetSystemHelper.cs b/NBi.NUnit/Builder/Helper/ResultSetSystemHelper.cs index 38bc3b8fa..4b75b1250 100644 --- a/NBi.NUnit/Builder/Helper/ResultSetSystemHelper.cs +++ b/NBi.NUnit/Builder/Helper/ResultSetSystemHelper.cs @@ -34,6 +34,7 @@ using NBi.Core.ResultSet.Lookup; using NBi.Core.ResultSet.Alteration.Lookup.Strategies.Missing; using NBi.Core.ResultSet.Alteration.Renaming.Strategies.Missing; +using NBi.Core.ResultSet.Filtering; namespace NBi.NUnit.Builder.Helper { @@ -84,7 +85,7 @@ public IEnumerable InstantiateAlterations(ResultSetSystemXml resultSetXml private Alter InstantiateFilter(FilterXml filterXml) { var context = new Context(Variables); - var factory = new ResultSetFilterFactory(ServiceLocator, context); + var factory = new ResultSetFilterFactory(ServiceLocator); if (filterXml.Ranking == null) { @@ -99,9 +100,8 @@ private Alter InstantiateFilter(FilterXml filterXml) return factory.Instantiate ( - filterXml.Aliases - , expressions - , new PredicationArgs(filterXml.Predication.Operand, args) + new PredicationArgs(filterXml.Predication.Operand, args) + , context ).Apply; } if (filterXml.Combination != null) @@ -116,10 +116,9 @@ private Alter InstantiateFilter(FilterXml filterXml) return factory.Instantiate ( - filterXml.Aliases - , expressions - , filterXml.Combination.Operator + filterXml.Combination.Operator , predicationArgs + , context ).Apply; } throw new ArgumentException(); diff --git a/NBi.NUnit/Builder/ResultSetNoRowsBuilder.cs b/NBi.NUnit/Builder/ResultSetNoRowsBuilder.cs index 13bdee84d..aec1c374f 100644 --- a/NBi.NUnit/Builder/ResultSetNoRowsBuilder.cs +++ b/NBi.NUnit/Builder/ResultSetNoRowsBuilder.cs @@ -11,6 +11,7 @@ using NBi.Core.Calculation.Predicate; using NBi.Core.ResultSet; using NBi.Core.Variable; +using NBi.Core.ResultSet.Filtering; namespace NBi.NUnit.Builder { @@ -40,12 +41,8 @@ protected virtual NBiConstraint InstantiateConstraint() protected IResultSetFilter InstantiateFilter() { - var expressions = new List(); - if (ConstraintXml.Expressions != null) - expressions.AddRange(ConstraintXml.Expressions); - - var context = new Context(Variables); - var factory = new ResultSetFilterFactory(ServiceLocator, context); + var context = new Context(Variables, ConstraintXml.Aliases, ConstraintXml.Expressions); + var factory = new ResultSetFilterFactory(ServiceLocator); if (ConstraintXml.Predication != null) { var helper = new PredicateArgsBuilder(ServiceLocator, context); @@ -53,9 +50,8 @@ protected IResultSetFilter InstantiateFilter() return factory.Instantiate ( - ConstraintXml.Aliases - , expressions - , new PredicationArgs(ConstraintXml.Predication.Operand, args) + new PredicationArgs(ConstraintXml.Predication.Operand, args) + , context ); } else if (ConstraintXml.Combination != null) @@ -71,10 +67,9 @@ protected IResultSetFilter InstantiateFilter() return factory.Instantiate ( - ConstraintXml.Aliases - , expressions - , ConstraintXml.Combination.Operator + ConstraintXml.Combination.Operator , predicationArgs + , context ); } else diff --git a/NBi.NUnit/Builder/ResultSetRowCountBuilder.cs b/NBi.NUnit/Builder/ResultSetRowCountBuilder.cs index 72efd9551..8594e9365 100644 --- a/NBi.NUnit/Builder/ResultSetRowCountBuilder.cs +++ b/NBi.NUnit/Builder/ResultSetRowCountBuilder.cs @@ -14,6 +14,7 @@ using NBi.Core.Scalar; using NBi.Core.Calculation.Predicate; using NBi.Core.Variable; +using NBi.Core.ResultSet.Filtering; namespace NBi.NUnit.Builder { @@ -55,8 +56,8 @@ protected NBiConstraint InstantiateConstraint() var value = EvaluatePotentialVariable(comparer.Reference.ToString().Replace(" ", "")); - var context = new Context(Variables); - var factory = new ResultSetFilterFactory(ServiceLocator, context); + var context = new Context(Variables, filterXml.Aliases, expressions); + var factory = new ResultSetFilterFactory(ServiceLocator); if (filterXml.Predication != null) { var helper = new PredicateArgsBuilder(ServiceLocator, context); @@ -64,9 +65,8 @@ protected NBiConstraint InstantiateConstraint() filter = factory.Instantiate ( - filterXml.Aliases - , expressions - , new PredicationArgs(filterXml.Predication.Operand, args) + new PredicationArgs(filterXml.Predication.Operand, args) + , context ); } @@ -82,10 +82,9 @@ protected NBiConstraint InstantiateConstraint() filter = factory.Instantiate ( - filterXml.Aliases - , expressions - , filterXml.Combination.Operator + filterXml.Combination.Operator , predicationArgs + , context ); } if ((value is string & (value as string).EndsWith("%"))) diff --git a/NBi.NUnit/Query/AllRowsConstraint.cs b/NBi.NUnit/Query/AllRowsConstraint.cs index b8d44a7ba..17dcd86cd 100644 --- a/NBi.NUnit/Query/AllRowsConstraint.cs +++ b/NBi.NUnit/Query/AllRowsConstraint.cs @@ -8,6 +8,7 @@ using NUnitCtr = NUnit.Framework.Constraints; using NBi.Framework; using NBi.Core.Configuration.FailureReport; +using NBi.Core.ResultSet.Filtering; namespace NBi.NUnit.Query { diff --git a/NBi.NUnit/Query/NoRowsConstraint.cs b/NBi.NUnit/Query/NoRowsConstraint.cs index 4f78095ec..cd4e7a49c 100644 --- a/NBi.NUnit/Query/NoRowsConstraint.cs +++ b/NBi.NUnit/Query/NoRowsConstraint.cs @@ -8,6 +8,7 @@ using NUnitCtr = NUnit.Framework.Constraints; using NBi.Framework; using NBi.Core.Configuration.FailureReport; +using NBi.Core.ResultSet.Filtering; namespace NBi.NUnit.Query { diff --git a/NBi.NUnit/Query/RowCountFilterConstraint.cs b/NBi.NUnit/Query/RowCountFilterConstraint.cs index 031e34a96..12f1e7292 100644 --- a/NBi.NUnit/Query/RowCountFilterConstraint.cs +++ b/NBi.NUnit/Query/RowCountFilterConstraint.cs @@ -9,6 +9,8 @@ using NBi.Framework.FailureMessage.Markdown; using NBi.Framework; using NBi.Core.Configuration.FailureReport; +using NBi.Core.ResultSet.Filtering; +using NBi.Core.Variable; namespace NBi.NUnit.Query { @@ -38,7 +40,7 @@ protected override IDataRowsMessageFormatter BuildFailure() protected override bool doMatch(ResultSet actual) { - actualResultSet = (ResultSet)actual; + actualResultSet = actual; filterResultSet = filterFunction(actualResultSet); return Matches(filterResultSet.Rows.Count); } diff --git a/NBi.NUnit/Query/RowCountFilterPercentageConstraint.cs b/NBi.NUnit/Query/RowCountFilterPercentageConstraint.cs index 95d83d7d7..8a1443aa9 100644 --- a/NBi.NUnit/Query/RowCountFilterPercentageConstraint.cs +++ b/NBi.NUnit/Query/RowCountFilterPercentageConstraint.cs @@ -5,6 +5,7 @@ using NBi.Core.ResultSet; using System.Data; using NBi.Core.Calculation; +using NBi.Core.ResultSet.Filtering; namespace NBi.NUnit.Query { diff --git a/NBi.NUnit/Query/SingleRowConstraint.cs b/NBi.NUnit/Query/SingleRowConstraint.cs index 5d86d6b5c..066befb57 100644 --- a/NBi.NUnit/Query/SingleRowConstraint.cs +++ b/NBi.NUnit/Query/SingleRowConstraint.cs @@ -8,6 +8,7 @@ using NUnitCtr = NUnit.Framework.Constraints; using NBi.Framework; using NBi.Core.Configuration.FailureReport; +using NBi.Core.ResultSet.Filtering; namespace NBi.NUnit.Query { diff --git a/NBi.NUnit/Query/SomeRowsConstraint.cs b/NBi.NUnit/Query/SomeRowsConstraint.cs index c04ee073b..101c10a57 100644 --- a/NBi.NUnit/Query/SomeRowsConstraint.cs +++ b/NBi.NUnit/Query/SomeRowsConstraint.cs @@ -8,6 +8,7 @@ using NUnitCtr = NUnit.Framework.Constraints; using NBi.Framework; using NBi.Core.Configuration.FailureReport; +using NBi.Core.ResultSet.Filtering; namespace NBi.NUnit.Query { diff --git a/NBi.Testing.Core/Calculation/Grouping/NameByColumnGroupingTest.cs b/NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameByColumnGroupingTest.cs similarity index 97% rename from NBi.Testing.Core/Calculation/Grouping/NameByColumnGroupingTest.cs rename to NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameByColumnGroupingTest.cs index 377ec4caf..c48eb9016 100644 --- a/NBi.Testing.Core/Calculation/Grouping/NameByColumnGroupingTest.cs +++ b/NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameByColumnGroupingTest.cs @@ -1,4 +1,5 @@ using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Grouping.ColumnBased; using NBi.Core.ResultSet; using NBi.Core.ResultSet.Resolver; using NBi.Core.Scalar.Comparer; @@ -10,7 +11,7 @@ using System.Threading.Tasks; using static NBi.Core.ResultSet.SettingsOrdinalResultSet; -namespace NBi.Testing.Core.Calculation.Grouping +namespace NBi.Testing.Core.Calculation.Grouping.ColumnBased { public class NameByColumnGroupingTest { diff --git a/NBi.Testing.Core/Calculation/Grouping/OrdinalByColumnGroupingTest.cs b/NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGroupingTest.cs similarity index 97% rename from NBi.Testing.Core/Calculation/Grouping/OrdinalByColumnGroupingTest.cs rename to NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGroupingTest.cs index 9b6e554bb..3e18010df 100644 --- a/NBi.Testing.Core/Calculation/Grouping/OrdinalByColumnGroupingTest.cs +++ b/NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGroupingTest.cs @@ -1,4 +1,5 @@ using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Grouping.ColumnBased; using NBi.Core.ResultSet; using NBi.Core.ResultSet.Resolver; using NBi.Core.Scalar.Comparer; @@ -10,7 +11,7 @@ using System.Threading.Tasks; using static NBi.Core.ResultSet.SettingsOrdinalResultSet; -namespace NBi.Testing.Core.Calculation.Grouping +namespace NBi.Testing.Core.Calculation.Grouping.ColumnBased { public class OrdinalByColumnGroupingTest { diff --git a/NBi.Testing.Core/Calculation/CultureSensitivePredicateMatchesTest.cs b/NBi.Testing.Core/Calculation/Predicate/CultureSensitivePredicateMatchesTest.cs similarity index 98% rename from NBi.Testing.Core/Calculation/CultureSensitivePredicateMatchesTest.cs rename to NBi.Testing.Core/Calculation/Predicate/CultureSensitivePredicateMatchesTest.cs index b1ab94e3e..4c3d91b12 100644 --- a/NBi.Testing.Core/Calculation/CultureSensitivePredicateMatchesTest.cs +++ b/NBi.Testing.Core/Calculation/Predicate/CultureSensitivePredicateMatchesTest.cs @@ -9,7 +9,7 @@ using System.Text; using System.Threading.Tasks; -namespace NBi.Testing.Core.Calculation +namespace NBi.Testing.Core.Calculation.Predicate { public class CultureSensitivePredicateMatchesTest { diff --git a/NBi.Testing.Core/Calculation/Predication/AndCombinationPredicationTest.cs b/NBi.Testing.Core/Calculation/Predication/AndCombinationPredicationTest.cs new file mode 100644 index 000000000..3cc1b1567 --- /dev/null +++ b/NBi.Testing.Core/Calculation/Predication/AndCombinationPredicationTest.cs @@ -0,0 +1,94 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NBi.Core; +using NBi.Core.Calculation; +using Moq; +using NBi.Core.Evaluate; +using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Resolver; +using System.Data; +using NBi.Core.Calculation.Predicate; +using NBi.Core.Calculation.Predication; +using NBi.Core.Variable; + +namespace NBi.Testing.Unit.Core.Calculation.Predication +{ + public class AndCombinationPredicationTest + { + [Test] + public void Execute_TwoTrue_True() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.And); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + + Assert.That(predication.Execute(context), Is.True); + } + + [Test] + public void Execute_TrueFalse_False() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.And); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + + Assert.That(predication.Execute(context), Is.False); + } + + [Test] + public void Execute_FalseTrue_False() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.And); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + + Assert.That(predication.Execute(context), Is.False); + } + + [Test] + public void Execute_FalseTrue_StopOnFirst() + { + var leftPredicationMock = new Mock(); + leftPredicationMock.Setup(x => x.Execute(It.IsAny())).Returns(false); + var rightPredicationMock = new Mock(); + rightPredicationMock.Setup(x => x.Execute(It.IsAny())).Returns(true); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredicationMock.Object, rightPredicationMock.Object }, CombinationOperator.And); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + predication.Execute(context); + + leftPredicationMock.Verify(x => x.Execute(context), Times.Once); + rightPredicationMock.Verify(x => x.Execute(It.IsAny()), Times.Never); + } + } +} \ No newline at end of file diff --git a/NBi.Testing.Core/Calculation/Predication/OrCombinationPredicationTest.cs b/NBi.Testing.Core/Calculation/Predication/OrCombinationPredicationTest.cs new file mode 100644 index 000000000..e891af53c --- /dev/null +++ b/NBi.Testing.Core/Calculation/Predication/OrCombinationPredicationTest.cs @@ -0,0 +1,112 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NBi.Core; +using NBi.Core.Calculation; +using Moq; +using NBi.Core.Evaluate; +using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Resolver; +using System.Data; +using NBi.Core.Calculation.Predicate; +using NBi.Core.Calculation.Predication; +using NBi.Core.Variable; + +namespace NBi.Testing.Unit.Core.Calculation.Predication +{ + public class OrCombinationPredicationTest + { + [Test] + public void Execute_TwoTrue_True() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.Or); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + + Assert.That(predication.Execute(context), Is.True); + } + + [Test] + public void Execute_TrueFalse_True() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.Or); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + + Assert.That(predication.Execute(context), Is.True); + } + + [Test] + public void Execute_FalseTrue_True() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.Or); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + + Assert.That(predication.Execute(context), Is.True); + } + + + [Test] + public void Execute_FalseFalse_False() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.Or); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + + Assert.That(predication.Execute(context), Is.False); + } + + [Test] + public void Execute_TrueFalse_StopOnFirst() + { + var leftPredicationMock = new Mock(); + leftPredicationMock.Setup(x => x.Execute(It.IsAny())).Returns(true); + var rightPredicationMock = new Mock(); + rightPredicationMock.Setup(x => x.Execute(It.IsAny())).Returns(false); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredicationMock.Object, rightPredicationMock.Object }, CombinationOperator.Or); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + context.Switch(row); + predication.Execute(context); + + leftPredicationMock.Verify(x => x.Execute(context), Times.Once); + rightPredicationMock.Verify(x => x.Execute(It.IsAny()), Times.Never); + } + } +} \ No newline at end of file diff --git a/NBi.Testing.Core/Calculation/Predication/XOrCombinationPredicationTest.cs b/NBi.Testing.Core/Calculation/Predication/XOrCombinationPredicationTest.cs new file mode 100644 index 000000000..f889cbcde --- /dev/null +++ b/NBi.Testing.Core/Calculation/Predication/XOrCombinationPredicationTest.cs @@ -0,0 +1,109 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using NBi.Core; +using NBi.Core.Calculation; +using Moq; +using NBi.Core.Evaluate; +using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Resolver; +using System.Data; +using NBi.Core.Calculation.Predicate; +using NBi.Core.Calculation.Predication; +using NBi.Core.Variable; + +namespace NBi.Testing.Unit.Core.Calculation.Predication +{ + public class XOrCombinationPredicationTest + { + [Test] + public void Execute_TwoTrue_False() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.XOr); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + + Assert.That(predication.Execute(context), Is.False); + } + + [Test] + public void Execute_TwoFalse_False() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.XOr); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + + Assert.That(predication.Execute(context), Is.False); + } + + [Test] + public void Execute_TrueFalse_True() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.XOr); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + + Assert.That(predication.Execute(context), Is.True); + } + + [Test] + public void Execute_FalseTrue_True() + { + var leftPredication = Mock.Of(x => x.Execute(It.IsAny()) == false); + var RightPredication = Mock.Of(x => x.Execute(It.IsAny()) == true); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { leftPredication, RightPredication }, CombinationOperator.XOr); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + + Assert.That(predication.Execute(context), Is.True); + } + + [Test] + public void Execute_TrueFalseTrue_GoUntilTheEnd() + { + var predicationMock1 = new Mock(); + predicationMock1.Setup(x => x.Execute(It.IsAny())).Returns(true); + var predicationMock2 = new Mock(); + predicationMock2.Setup(x => x.Execute(It.IsAny())).Returns(false); + var predicationMock3 = new Mock(); + predicationMock3.Setup(x => x.Execute(It.IsAny())).Returns(false); + + var factory = new PredicationFactory(); + var predication = factory.Instantiate(new[] { predicationMock1.Object, predicationMock2.Object, predicationMock3.Object }, CombinationOperator.XOr); + + var context = Context.None; + var dt = new DataTable(); + var row = dt.NewRow(); + predication.Execute(context); + + predicationMock1.Verify(x => x.Execute(context), Times.Once); + predicationMock2.Verify(x => x.Execute(context), Times.Once); + predicationMock3.Verify(x => x.Execute(context), Times.Once); + } + } +} \ No newline at end of file diff --git a/NBi.Testing.Core/Calculation/Ranking/BottomRankingTest.cs b/NBi.Testing.Core/Calculation/Ranking/BottomRankingTest.cs index cdc0fe64f..b3fef70ab 100644 --- a/NBi.Testing.Core/Calculation/Ranking/BottomRankingTest.cs +++ b/NBi.Testing.Core/Calculation/Ranking/BottomRankingTest.cs @@ -5,6 +5,7 @@ using NBi.Core.Evaluate; using NBi.Core.ResultSet; using NBi.Core.ResultSet.Resolver; +using NBi.Core.Variable; using NUnit.Framework; using System; using System.Collections.Generic; diff --git a/NBi.Testing.Core/Calculation/Ranking/TopRankingTest.cs b/NBi.Testing.Core/Calculation/Ranking/TopRankingTest.cs index eb7b4c3a6..7fbb6ba00 100644 --- a/NBi.Testing.Core/Calculation/Ranking/TopRankingTest.cs +++ b/NBi.Testing.Core/Calculation/Ranking/TopRankingTest.cs @@ -5,6 +5,7 @@ using NBi.Core.Evaluate; using NBi.Core.ResultSet; using NBi.Core.ResultSet.Resolver; +using NBi.Core.Variable; using NUnit.Framework; using System; using System.Collections.Generic; diff --git a/NBi.Testing.Core/Calculation/SinglePredicateFilterTest.cs b/NBi.Testing.Core/Calculation/SinglePredicateFilterTest.cs deleted file mode 100644 index d10cc3569..000000000 --- a/NBi.Testing.Core/Calculation/SinglePredicateFilterTest.cs +++ /dev/null @@ -1,303 +0,0 @@ -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using NBi.Core; -using NBi.Core.Calculation; -using Moq; -using NBi.Core.Evaluate; -using NBi.Core.ResultSet; -using NBi.Core.ResultSet.Resolver; -using NBi.Core.Transformation; -using NBi.Core.Scalar.Resolver; -using NBi.Core.Calculation.Predicate; -using NBi.Core.Injection; -using NBi.Core.Variable; - -namespace NBi.Testing.Core.Calculation -{ - public class SinglePredicateFilterTest - { - - [Test] - public void Apply_Variable_CorrectResult() - { - var service = new ObjectsResultSetResolver( - new ObjectsResultSetResolverArgs( - new [] - { - new object[] { "(null)", 10, 100 }, - new object[] { "(empty)", 2, 75 }, - new object[] { "C", 5, 50 } - })); - - var rs = service.Execute(); - - var aliases = new[] { Mock.Of(v => v.Column == 0 && v.Name == "a") }; - - var predicate = new Mock(); - predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.Text); - predicate.SetupGet(p => p.ComparerType).Returns(ComparerType.NullOrEmpty); - - var predication = new Mock(); - predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("a")); - predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(aliases, new IColumnExpression[0], predication.Object); - var result = filter.Apply(rs); - - Assert.That(result.Rows, Has.Count.EqualTo(2)); - } - - [Test] - public void Apply_ColumnOrdinal_CorrectResult() - { - var service = new ObjectsResultSetResolver( - new ObjectsResultSetResolverArgs( - new [] - { - new object[] { "(null)", 10, 100 }, - new object[] { "(empty)", 2, 75 }, - new object[] { "C", 5, 50 } - })); - var rs = service.Execute(); - - var predicate = new Mock(); - predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.Text); - predicate.SetupGet(p => p.ComparerType).Returns(ComparerType.NullOrEmpty); - var predication = new Mock(); - predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(0)); - predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(new IColumnAlias[0], new IColumnExpression[0], predication.Object); - var result = filter.Apply(rs); - - Assert.That(result.Rows, Has.Count.EqualTo(2)); - Assert.That(filter.Describe(), Does.Contain("null").And.Contain("or empty")); - } - - [Test] - public void Apply_ColumnName_CorrectResult() - { - var service = new ObjectsResultSetResolver( - new ObjectsResultSetResolverArgs( - new [] - { - new object[] { "(null)", 10, 100 }, - new object[] { "(empty)", 2, 75 }, - new object[] { "C", 5, 50 } - })); - var rs = service.Execute(); - rs.Table.Columns[0].ColumnName = "first"; - - var predicate = new Mock(); - predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.Text); - predicate.SetupGet(p => p.ComparerType).Returns(ComparerType.NullOrEmpty); - var predication = new Mock(); - predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("first")); - predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(new IColumnAlias[0], new IColumnExpression[0], predication.Object); - var result = filter.Apply(rs); - - Assert.That(result.Rows, Has.Count.EqualTo(2)); - } - - [Test] - public void Apply_ColumnNameCaseNotMatching_CorrectResult() - { - var service = new ObjectsResultSetResolver( - new ObjectsResultSetResolverArgs( - new [] - { - new object[] { "(null)", 10, 100 }, - new object[] { "(empty)", 2, 75 }, - new object[] { "C", 5, 50 } - })); - var rs = service.Execute(); - rs.Table.Columns[0].ColumnName = "first"; - - var predicate = new Mock(); - predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.Text); - predicate.SetupGet(p => p.ComparerType).Returns(ComparerType.NullOrEmpty); - - var predication = new Mock(); - predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("FirSt")); - predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(new IColumnAlias[0], new IColumnExpression[0], predication.Object); - var result = filter.Apply(rs); - - Assert.That(result.Rows, Has.Count.EqualTo(2)); - } - - - [Test] - public void Apply_UnexistingColumnName_CorrectResult() - { - var service = new ObjectsResultSetResolver( - new ObjectsResultSetResolverArgs( - new [] - { - new object[] { "(null)", 10, 100 }, - new object[] { "(empty)", 2, 75 }, - new object[] { "C", 5, 50 } - })); - var rs = service.Execute(); - rs.Table.Columns[0].ColumnName = "first"; - rs.Table.Columns[1].ColumnName = "second"; - rs.Table.Columns[2].ColumnName = "third"; - - var predicate = new Mock(); - predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.Text); - predicate.SetupGet(p => p.ComparerType).Returns(ComparerType.NullOrEmpty); - predicate.SetupGet(p => p.Reference).Returns(new LiteralScalarResolver(200)); - - var predication = new Mock(); - predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("Unexisting")); - predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(new IColumnAlias[0], new IColumnExpression[0], predication.Object); - var ex = Assert.Throws(() => filter.Apply(rs)); - Assert.That(ex.Message, Does.Contain("first")); - Assert.That(ex.Message, Does.Contain("second")); - Assert.That(ex.Message, Does.Contain("third")); - } - - [Test] - public void Apply_NestedExpression_CorrectResult() - { - var service = new ObjectsResultSetResolver( - new ObjectsResultSetResolverArgs( - new [] - { - new object[] { 1, 10, 100 }, - new object[] { 2, 2, 75 }, - new object[] { 3, 5, 50 } - })); - var rs = service.Execute(); - - var aliases = new List() - { - Mock.Of(v => v.Column == 0 && v.Name == "a"), - Mock.Of(v => v.Column == 1 && v.Name == "b"), - Mock.Of(v => v.Column == 2 && v.Name == "c") - }; - - var expressions = new List() - { - Mock.Of(e => e.Value == "Abs([a])+[e]" && e.Name == "d" && e.Language == LanguageType.NCalc), - Mock.Of(e => e.Value == "[b]*[c]" && e.Name == "e" && e.Language == LanguageType.NCalc) - }; - - var predicate = new Mock(); - predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.Numeric); - predicate.SetupGet(p => p.ComparerType).Returns(ComparerType.MoreThanOrEqual); - predicate.SetupGet(p => p.Reference).Returns(new LiteralScalarResolver(200)); - - var predication = new Mock(); - predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("d")); - predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(aliases, expressions, predication.Object); - var result = filter.Apply(rs); - - Assert.That(result.Rows, Has.Count.EqualTo(2)); - } - - [Test] - public void Apply_MixedExpression_CorrectResult() - { - var service = new ObjectsResultSetResolver( - new ObjectsResultSetResolverArgs( - new [] - { - new object[] { 1, 10, 100 }, - new object[] { 2, 2, 75 }, - new object[] { 3, 5, 50 } - })); - var rs = service.Execute(); - rs.Table.Columns[2].ColumnName = "c1"; - - var aliases = new List() - { - Mock.Of(v => v.Column == 0 && v.Name == "a"), - }; - - var expressions = new List() - { - Mock.Of(e => e.Value == "Abs([a])+[e]" && e.Name == "d" && e.Language == LanguageType.NCalc), - Mock.Of(e => e.Value == "[#1]*[c1]" && e.Name == "e" && e.Language == LanguageType.NCalc) - }; - - var predicate = new Mock(); - predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.Numeric); - predicate.SetupGet(p => p.ComparerType).Returns(ComparerType.MoreThanOrEqual); - predicate.SetupGet(p => p.Reference).Returns(new LiteralScalarResolver(200)); - - var predication = new Mock(); - predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("d")); - predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(aliases, expressions, predication.Object); - var result = filter.Apply(rs); - - Assert.That(result.Rows, Has.Count.EqualTo(2)); - } - - [Test] - public void Apply_NativeExpression_CorrectResult() - { - var service = new ObjectsResultSetResolver( - new ObjectsResultSetResolverArgs( - new [] - { - new object[] { new DateTime(2019, 10, 01, 8, 0, 0), 10, 100 }, - new object[] { new DateTime(2019, 10, 01, 23, 0, 0), 2, 75 }, - new object[] { new DateTime(2019, 10, 02, 05, 0, 0), 5, 50 } - })); - var rs = service.Execute(); - rs.Table.Columns[0].ColumnName = "a"; - - var aliases = new List() - { - Mock.Of(v => v.Column == 0 && v.Name == "x"), - }; - - var expressions = new List() - { - Mock.Of( - e => e.Value == "a | utc-to-local(Brussels) | dateTime-to-date" - && e.Name == "d" - && e.Language == LanguageType.Native - && e.Type==ColumnType.DateTime), - }; - - var predicate = new Mock(); - predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.DateTime); - predicate.SetupGet(p => p.ComparerType).Returns(ComparerType.MoreThanOrEqual); - predicate.SetupGet(p => p.Reference).Returns(new LiteralScalarResolver(new DateTime(2019, 10, 2))); - - var predication = new Mock(); - predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("d")); - predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - - - var factory = new ResultSetFilterFactory(new ServiceLocator(), new Context(null)); - var filter = factory.Instantiate(aliases, expressions, predication.Object); - var result = filter.Apply(rs); - - Assert.That(result.Rows, Has.Count.EqualTo(2)); - } - - } -} diff --git a/NBi.Testing.Core/NBi.Testing.Core.csproj b/NBi.Testing.Core/NBi.Testing.Core.csproj index c76983a3f..e23ca2ef3 100644 --- a/NBi.Testing.Core/NBi.Testing.Core.csproj +++ b/NBi.Testing.Core/NBi.Testing.Core.csproj @@ -102,18 +102,20 @@ - - - - - + + + + + + + + - diff --git a/NBi.Testing.Core/Calculation/FilterGroupByFilterTest.cs b/NBi.Testing.Core/ResultSet/Filtering/GroupByFilterTest.cs similarity index 87% rename from NBi.Testing.Core/Calculation/FilterGroupByFilterTest.cs rename to NBi.Testing.Core/ResultSet/Filtering/GroupByFilterTest.cs index 0d451157a..66c5e16ab 100644 --- a/NBi.Testing.Core/Calculation/FilterGroupByFilterTest.cs +++ b/NBi.Testing.Core/ResultSet/Filtering/GroupByFilterTest.cs @@ -1,9 +1,12 @@ using NBi.Core.Calculation; using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Grouping.ColumnBased; using NBi.Core.Calculation.Ranking; using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Filtering; using NBi.Core.ResultSet.Resolver; using NBi.Core.Scalar.Comparer; +using NBi.Core.Variable; using NUnit.Framework; using System; using System.Collections.Generic; @@ -13,9 +16,9 @@ using System.Threading.Tasks; using static NBi.Core.ResultSet.SettingsOrdinalResultSet; -namespace NBi.Testing.Core.Calculation +namespace NBi.Testing.Core.ResultSet.Filtering { - public class FilterGroupByFilterTest + public class GroupByFilterTest { [Test] public void Execute_Top2OneKey_ResultSetReduced() @@ -29,7 +32,7 @@ public void Execute_Top2OneKey_ResultSetReduced() var filter = new TopRanking(2, new ColumnOrdinalIdentifier(1), ColumnType.Numeric); - var rankingByGroup = new FilterGroupByFilter(filter, grouping); + var rankingByGroup = new GroupByFilter(filter, grouping); var result = rankingByGroup.Apply(rs); Assert.That(result.Table.Rows, Has.Count.EqualTo(3)); @@ -46,7 +49,7 @@ public void Execute_Top2None_ResultSetReduced() var filter = new TopRanking(2, new ColumnOrdinalIdentifier(1), ColumnType.Numeric); - var rankingByGroup = new FilterGroupByFilter(filter, new NoneGrouping()); + var rankingByGroup = new GroupByFilter(filter, new NoneGrouping()); var result = rankingByGroup.Apply(rs); Assert.That(result.Table.Rows, Has.Count.EqualTo(2)); diff --git a/NBi.Testing.Core/Calculation/CombinationPredicateFilterTest.cs b/NBi.Testing.Core/ResultSet/Filtering/PredicationFilterTest.cs similarity index 87% rename from NBi.Testing.Core/Calculation/CombinationPredicateFilterTest.cs rename to NBi.Testing.Core/ResultSet/Filtering/PredicationFilterTest.cs index a683db392..1131401e1 100644 --- a/NBi.Testing.Core/Calculation/CombinationPredicateFilterTest.cs +++ b/NBi.Testing.Core/ResultSet/Filtering/PredicationFilterTest.cs @@ -13,10 +13,11 @@ using NBi.Core.Scalar.Resolver; using NBi.Core.Calculation.Predicate; using NBi.Core.Variable; +using NBi.Core.ResultSet.Filtering; -namespace NBi.Testing.Core.Calculation +namespace NBi.Testing.Core.ResultSet.Filtering { - public class CombinationPredicateFilterTest + public class PredicationFilterTest { [Test] @@ -52,10 +53,10 @@ public void Apply_And_CorrectResult() var predication2 = new Mock(); predication2.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication2.SetupGet(p => p.Predicate).Returns(predicate2.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(aliases, new IColumnExpression[0], CombinationOperator.And , new[] { predication1.Object, predication2.Object }); + + var factory = new ResultSetFilterFactory(null); + var filter = factory.Instantiate(CombinationOperator.And, new[] { predication1.Object, predication2.Object }, new Context(null, aliases, Array.Empty())); var result = filter.Apply(rs); Assert.That(result.Rows, Has.Count.EqualTo(2)); @@ -96,8 +97,8 @@ public void Apply_AndWillNotEvaluateAll_CorrectResult() predication2.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(0)); predication2.SetupGet(p => p.Predicate).Returns(predicate2.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(aliases, new IColumnExpression[0], CombinationOperator.And, new[] { predication1.Object, predication2.Object }); + var factory = new ResultSetFilterFactory(null); + var filter = factory.Instantiate(CombinationOperator.And, new[] { predication1.Object, predication2.Object }, new Context(null, aliases, Array.Empty())); var result = filter.Apply(rs); Assert.That(result.Rows, Has.Count.EqualTo(1)); @@ -135,10 +136,10 @@ public void Apply_Or_CorrectResult() var predication2 = new Mock(); predication2.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication2.SetupGet(p => p.Predicate).Returns(predicate2.Object); - - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(aliases, new IColumnExpression[0], CombinationOperator.Or, new[] { predication1.Object, predication2.Object }); + + var factory = new ResultSetFilterFactory(null); + var filter = factory.Instantiate(CombinationOperator.Or, new[] { predication1.Object, predication2.Object }, new Context(null, aliases, Array.Empty())); var result = filter.Apply(rs); Assert.That(result.Rows, Has.Count.EqualTo(4)); @@ -177,8 +178,8 @@ public void Apply_OrWillNotEvaluateAll_CorrectResult() predication2.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(0)); predication2.SetupGet(p => p.Predicate).Returns(predicate2.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(aliases, new IColumnExpression[0], CombinationOperator.Or, new[] { predication1.Object, predication2.Object }); + var factory = new ResultSetFilterFactory(null); + var filter = factory.Instantiate(CombinationOperator.Or, new[] { predication1.Object, predication2.Object }, new Context(null, aliases, Array.Empty())); var result = filter.Apply(rs); Assert.That(result.Rows, Has.Count.EqualTo(3)); @@ -217,8 +218,8 @@ public void Apply_XOr_CorrectResult() predication2.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication2.SetupGet(p => p.Predicate).Returns(predicate1.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); - var filter = factory.Instantiate(aliases, new IColumnExpression[0], CombinationOperator.XOr, new[] { predication1.Object, predication2.Object }); + var factory = new ResultSetFilterFactory(null); + var filter = factory.Instantiate(CombinationOperator.XOr, new[] { predication1.Object, predication2.Object }, new Context(null, aliases, Array.Empty())); var result = filter.Apply(rs); Assert.That(result.Rows, Has.Count.EqualTo(3)); diff --git a/NBi.Testing.Core/Scalar/Resolver/ContextScalarResolverTest.cs b/NBi.Testing.Core/Scalar/Resolver/ContextScalarResolverTest.cs index 4af1ac98c..d4034dce6 100644 --- a/NBi.Testing.Core/Scalar/Resolver/ContextScalarResolverTest.cs +++ b/NBi.Testing.Core/Scalar/Resolver/ContextScalarResolverTest.cs @@ -21,7 +21,7 @@ public void Execute_FirstRowByName_CorrectEvaluation() rs.Load(new[] { new object[] { "a", 1 }, new object[] { "b", 2 } }); rs.Columns[0].ColumnName = "Foo"; - var context = new Context(null); + var context = Context.None; var args = new ContextScalarResolverArgs(context, new ColumnNameIdentifier("Foo")); var resolver = new ContextScalarResolver(args); @@ -35,7 +35,7 @@ public void Execute_FirstRowByOrdinal_CorrectEvaluation() var rs = new NBi.Core.ResultSet.ResultSet(); rs.Load(new[] { new object[] { "a", 1 }, new object[] { "b", 2 } }); - var context = new Context(null); + var context = Context.None; var args = new ContextScalarResolverArgs(context, new ColumnOrdinalIdentifier(0)); var resolver = new ContextScalarResolver(args); @@ -50,7 +50,7 @@ public void Execute_SecondRow_CorrectEvaluation() rs.Load(new[] { new object[] { "a", 1 }, new object[] { "b", 2 } }); rs.Columns[0].ColumnName = "Foo"; - var context = new Context(null); + var context = Context.None; var args = new ContextScalarResolverArgs(context, new ColumnNameIdentifier("Foo")); var resolver = new ContextScalarResolver(args); diff --git a/NBi.Testing.Core/Scalar/Resolver/ScalarResolverFactoryTest.cs b/NBi.Testing.Core/Scalar/Resolver/ScalarResolverFactoryTest.cs index e35646ae2..9c9450405 100644 --- a/NBi.Testing.Core/Scalar/Resolver/ScalarResolverFactoryTest.cs +++ b/NBi.Testing.Core/Scalar/Resolver/ScalarResolverFactoryTest.cs @@ -45,7 +45,7 @@ public void Instantiate_ContextArgs_ContextResolver() { using (var dt = new DataTable()) { - var context = new Context(null); + var context = Context.None; context.Switch(dt.NewRow()); var args = new ContextScalarResolverArgs(context, new ColumnOrdinalIdentifier(0)); diff --git a/NBi.Testing.Core/Transformation/TransformationProviderTest.cs b/NBi.Testing.Core/Transformation/TransformationProviderTest.cs index a5c30f3ee..d3aa02f68 100644 --- a/NBi.Testing.Core/Transformation/TransformationProviderTest.cs +++ b/NBi.Testing.Core/Transformation/TransformationProviderTest.cs @@ -31,7 +31,7 @@ public void Transform_SimpleTranformation_CorrectHandlingOfColumnNames() && t.Code == "value.Substring(0,1)" ); - var provider = new TransformationProvider(new ServiceLocator(), new Context(null)); + var provider = new TransformationProvider(new ServiceLocator(), Context.None); provider.Add(new ColumnOrdinalIdentifier(0), transformation); provider.Transform(resultSet); @@ -53,7 +53,7 @@ public void Transform_SimpleTranformation_Correct() && t.Code == "value.Substring(0,1)" ); - var provider = new TransformationProvider(new ServiceLocator(), new Context(null)); + var provider = new TransformationProvider(new ServiceLocator(), Context.None); provider.Add(new ColumnOrdinalIdentifier(0), transformation); provider.Transform(resultSet); @@ -73,7 +73,7 @@ public void Transform_NativeTranformationTrim_Correct() && t.Code == "text-to-trim" ); - var provider = new TransformationProvider(new ServiceLocator(), new Context(null)); + var provider = new TransformationProvider(new ServiceLocator(), Context.None); provider.Add(new ColumnOrdinalIdentifier(0), transformation); provider.Transform(resultSet); @@ -93,7 +93,7 @@ public void Transform_NativeTranformationFirstCharWithContext_Correct() && t.Code == "text-to-first-chars(#1)" ); - var provider = new TransformationProvider(new ServiceLocator(), new Context(null)); + var provider = new TransformationProvider(new ServiceLocator(), Context.None); provider.Add(new ColumnOrdinalIdentifier(0), transformation); provider.Transform(resultSet); @@ -114,7 +114,7 @@ public void Transform_NativeTranformationBlankToNull_Correct() && t.Code == "blank-to-null" ); - var provider = new TransformationProvider(new ServiceLocator(), new Context(null)); + var provider = new TransformationProvider(new ServiceLocator(), Context.None); provider.Add(new ColumnOrdinalIdentifier(0), transformation); provider.Transform(resultSet); @@ -154,7 +154,7 @@ public void Transform_TypeSwitch_Correct() && t.Code == "value.Month + (value.Year-2000)*12" ); - var provider = new TransformationProvider(new ServiceLocator(), new Context(null)); + var provider = new TransformationProvider(new ServiceLocator(), Context.None); provider.Add(new ColumnOrdinalIdentifier(0), transformation); provider.Transform(resultSet); diff --git a/NBi.Testing/Unit/NUnit/Builder/Helper/PredicateArgsBuilderTest.cs b/NBi.Testing/Unit/NUnit/Builder/Helper/PredicateArgsBuilderTest.cs index f66e1d37c..d4bf258be 100644 --- a/NBi.Testing/Unit/NUnit/Builder/Helper/PredicateArgsBuilderTest.cs +++ b/NBi.Testing/Unit/NUnit/Builder/Helper/PredicateArgsBuilderTest.cs @@ -23,7 +23,7 @@ public void Build_VariableAndFunctions_FunctionScalarResolverArgs() Reference = "#12 | text-to-upper | text-to-first-chars([ColA])" }; - var builder = new PredicateArgsBuilder(new ServiceLocator(), new Context(null)); + var builder = new PredicateArgsBuilder(new ServiceLocator(), Context.None); var args = builder.Execute(Core.ResultSet.ColumnType.Text, predicateXml); Assert.That(args, Is.AssignableTo()); diff --git a/NBi.Testing/Unit/NUnit/Builder/Helper/ScalarResolverArgsBuilderTest.cs b/NBi.Testing/Unit/NUnit/Builder/Helper/ScalarResolverArgsBuilderTest.cs index 43213ad97..572ca0438 100644 --- a/NBi.Testing/Unit/NUnit/Builder/Helper/ScalarResolverArgsBuilderTest.cs +++ b/NBi.Testing/Unit/NUnit/Builder/Helper/ScalarResolverArgsBuilderTest.cs @@ -43,7 +43,7 @@ public void Build_Variable_GlobalVariableScalarResolverArgs() [Test] public void Build_ContextColumnName_ContextScalarResolverArgs() { - var builder = new ScalarResolverArgsBuilder(new ServiceLocator(), new Context(null)); + var builder = new ScalarResolverArgsBuilder(new ServiceLocator(), Context.None); builder.Setup("[ColA]"); builder.Build(); var args = builder.GetArgs(); @@ -53,7 +53,7 @@ public void Build_ContextColumnName_ContextScalarResolverArgs() [Test] public void Build_ContextColumnOrdinal_ContextScalarResolverArgs() { - var builder = new ScalarResolverArgsBuilder(new ServiceLocator(), new Context(null)); + var builder = new ScalarResolverArgsBuilder(new ServiceLocator(), Context.None); builder.Setup("#12"); builder.Build(); var args = builder.GetArgs(); @@ -63,7 +63,7 @@ public void Build_ContextColumnOrdinal_ContextScalarResolverArgs() [Test] public void Build_ContextColumnOrdinalFollowedByNativeTransformations_ContextScalarResolverArgs() { - var builder = new ScalarResolverArgsBuilder(new ServiceLocator(), new Context(null)); + var builder = new ScalarResolverArgsBuilder(new ServiceLocator(), Context.None); builder.Setup("#12 | text-to-upper | text-to-first-chars([ColA])"); builder.Build(); var args = builder.GetArgs(); diff --git a/NBi.Testing/Unit/NUnit/ResultSetComparison/AllRowsConstraintTest.cs b/NBi.Testing/Unit/NUnit/ResultSetComparison/AllRowsConstraintTest.cs index 9178a0965..1b104e41a 100644 --- a/NBi.Testing/Unit/NUnit/ResultSetComparison/AllRowsConstraintTest.cs +++ b/NBi.Testing/Unit/NUnit/ResultSetComparison/AllRowsConstraintTest.cs @@ -14,6 +14,7 @@ using NBi.Core.Scalar.Resolver; using NBi.Core.Calculation.Predicate; using NBi.Core.Variable; +using NBi.Core.ResultSet.Filtering; namespace NBi.Testing.Unit.NUnit.ResultSetComparison { @@ -57,12 +58,11 @@ public void Matches_ResultSetService_CallToExecuteOnce() predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("Value")); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate - ( - new List() { alias } - , new List() { } - , predication.Object + ( + predication.Object + , new Context(null, new List() { alias }, Array.Empty()) ); var rowCount = new AllRowsConstraint(filter); @@ -89,12 +89,11 @@ public void Matches_AllValidatePredicate_True() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new AllRowsConstraint(filter); @@ -116,12 +115,11 @@ public void Matches_NoneValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new AllRowsConstraint(filter); @@ -143,12 +141,11 @@ public void Matches_FewValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new AllRowsConstraint(filter); @@ -170,12 +167,11 @@ public void Matches_SingleValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new AllRowsConstraint(filter); diff --git a/NBi.Testing/Unit/NUnit/ResultSetComparison/NoRowsConstraintTest.cs b/NBi.Testing/Unit/NUnit/ResultSetComparison/NoRowsConstraintTest.cs index 38b9f04c3..0d66e3e37 100644 --- a/NBi.Testing/Unit/NUnit/ResultSetComparison/NoRowsConstraintTest.cs +++ b/NBi.Testing/Unit/NUnit/ResultSetComparison/NoRowsConstraintTest.cs @@ -1,19 +1,16 @@ using System; using System.Linq; using Moq; -using NBi.Core; using NBi.NUnit.Query; using NBi.Core.ResultSet; -using System.Data.SqlClient; -using NUnitCtr = NUnit.Framework.Constraints; using NBi.Core.Calculation; using NBi.Core.Evaluate; using System.Collections.Generic; using NUnit.Framework; -using NBi.Core.ResultSet.Resolver; using NBi.Core.Scalar.Resolver; using NBi.Core.Calculation.Predicate; using NBi.Core.Variable; +using NBi.Core.ResultSet.Filtering; namespace NBi.Testing.Unit.NUnit.ResultSetComparison { @@ -58,12 +55,11 @@ public void Matches_ResultSetService_CallToExecuteOnce() predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("Value")); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() { alias } - , new List() { } - , predication.Object + predication.Object + , new Context(null, new List() { alias }, Array.Empty()) ); var rowCount = new NoRowsConstraint(filter); @@ -90,12 +86,11 @@ public void Matches_AllValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new NoRowsConstraint(filter); @@ -117,12 +112,11 @@ public void Matches_NoneValidatePredicate_True() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new NoRowsConstraint(filter); @@ -144,12 +138,11 @@ public void Matches_FewValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new NoRowsConstraint(filter); @@ -171,12 +164,11 @@ public void Matches_SingleValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new NoRowsConstraint(filter); diff --git a/NBi.Testing/Unit/NUnit/ResultSetComparison/SingleRowConstraintTest.cs b/NBi.Testing/Unit/NUnit/ResultSetComparison/SingleRowConstraintTest.cs index 1af457462..fd615932e 100644 --- a/NBi.Testing/Unit/NUnit/ResultSetComparison/SingleRowConstraintTest.cs +++ b/NBi.Testing/Unit/NUnit/ResultSetComparison/SingleRowConstraintTest.cs @@ -1,19 +1,16 @@ using System; using System.Linq; using Moq; -using NBi.Core; using NBi.NUnit.Query; using NBi.Core.ResultSet; -using System.Data.SqlClient; -using NUnitCtr = NUnit.Framework.Constraints; using NBi.Core.Calculation; using NBi.Core.Evaluate; using System.Collections.Generic; using NUnit.Framework; -using NBi.Core.ResultSet.Resolver; using NBi.Core.Scalar.Resolver; using NBi.Core.Calculation.Predicate; using NBi.Core.Variable; +using NBi.Core.ResultSet.Filtering; namespace NBi.Testing.Unit.NUnit.ResultSetComparison { @@ -59,12 +56,11 @@ public void Matches_ResultSetService_CallToExecuteOnce() predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("Value")); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() { alias } - , new List() { } - , predication.Object + predication.Object + , new Context(null, new List() { alias }, Array.Empty()) ); var singleRowCtr = new SingleRowConstraint(filter); @@ -92,12 +88,11 @@ public void Matches_AllValidatePredicate_False() predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new SingleRowConstraint(filter); @@ -119,12 +114,11 @@ public void Matches_NoneValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new SingleRowConstraint(filter); @@ -146,12 +140,11 @@ public void Matches_FewValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new SingleRowConstraint(filter); @@ -173,12 +166,11 @@ public void Matches_SingleValidatePredicate_True() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var singleRowCtr = new SingleRowConstraint(filter); diff --git a/NBi.Testing/Unit/NUnit/ResultSetComparison/SomeRowsConstraintTest.cs b/NBi.Testing/Unit/NUnit/ResultSetComparison/SomeRowsConstraintTest.cs index 37e782c11..f7c3ab370 100644 --- a/NBi.Testing/Unit/NUnit/ResultSetComparison/SomeRowsConstraintTest.cs +++ b/NBi.Testing/Unit/NUnit/ResultSetComparison/SomeRowsConstraintTest.cs @@ -1,32 +1,29 @@ using System; using System.Linq; using Moq; -using NBi.Core; using NBi.NUnit.Query; using NBi.Core.ResultSet; -using System.Data.SqlClient; -using NUnitCtr = NUnit.Framework.Constraints; using NBi.Core.Calculation; using NBi.Core.Evaluate; using System.Collections.Generic; using NUnit.Framework; -using NBi.Core.ResultSet.Resolver; using NBi.Core.Scalar.Resolver; using NBi.Core.Calculation.Predicate; using NBi.Core.Variable; +using NBi.Core.ResultSet.Filtering; namespace NBi.Testing.Unit.NUnit.ResultSetComparison { [TestFixture] public class SomeRowsConstraintTest { - + #region Setup & Teardown [SetUp] public void SetUp() { - + } [TearDown] @@ -57,12 +54,11 @@ public void Matches_ResultSetService_CallToExecuteOnce() predication.SetupGet(p => p.Identifier).Returns(new ColumnNameIdentifier("Value")); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() { alias } - , new List() { } - , predication.Object + predication.Object + , new Context(null, new List() { alias }, Array.Empty()) ); var someRowCtr = new SomeRowsConstraint(filter); @@ -78,7 +74,7 @@ public void Matches_ResultSetService_CallToExecuteOnce() public void Matches_AllValidatePredicate_True() { var rs = new ResultSet(); - rs.Load(new[] { new object[] {"a", -1}, new object[] { "b", -2 }, new object[] { "c", -3 } }); + rs.Load(new[] { new object[] { "a", -1 }, new object[] { "b", -2 }, new object[] { "c", -3 } }); var predicate = new Mock(); predicate.SetupGet(p => p.ColumnType).Returns(ColumnType.Numeric); @@ -89,12 +85,11 @@ public void Matches_AllValidatePredicate_True() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var someRowCtr = new SomeRowsConstraint(filter); @@ -116,12 +111,11 @@ public void Matches_NoneValidatePredicate_False() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var someRowCtr = new SomeRowsConstraint(filter); @@ -143,12 +137,11 @@ public void Matches_FewValidatePredicate_True() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var someRowCtr = new SomeRowsConstraint(filter); @@ -170,12 +163,11 @@ public void Matches_SingleValidatePredicate_True() predication.SetupGet(p => p.Identifier).Returns(new ColumnOrdinalIdentifier(1)); predication.SetupGet(p => p.Predicate).Returns(predicate.Object); - var factory = new ResultSetFilterFactory(null, new Context(null)); + var factory = new ResultSetFilterFactory(null); var filter = factory.Instantiate ( - new List() - , new List() - , predication.Object + predication.Object + , Context.None ); var someRowCtr = new SomeRowsConstraint(filter); From 691bf1e905367f770d21a67ea7517da4f63755be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20L=2E=20Charlier?= Date: Thu, 14 Nov 2019 02:09:48 +0100 Subject: [PATCH 2/3] Add CaseGroupBy --- .../Grouping/CaseBased/CaseGroupByArgs.cs | 16 ++++ .../Grouping/CaseBased/CaseGrouping.cs | 44 ++++++++++ .../Grouping/CaseBased/GroupByCase.cs | 42 ---------- .../Grouping/ColumnBased/ColumnGroupByArgs.cs | 20 +++++ ...tByColumnGrouping.cs => ColumnGrouping.cs} | 11 +-- ...olumnGrouping.cs => NameColumnGrouping.cs} | 7 +- ...mnGrouping.cs => OrdinalColumnGrouping.cs} | 7 +- .../Calculation/Grouping/GroupByFactory.cs | 23 +++-- NBi.Core/Calculation/Grouping/IGroupByArgs.cs | 11 +++ NBi.Core/Calculation/SinglePredicateFilter.cs | 40 --------- NBi.Core/NBi.Core.csproj | 12 +-- .../Alteration/Reshaping/UnstackEngine.cs | 4 +- .../Summarization/SummarizeEngine.cs | 4 +- NBi.Core/ResultSet/Filtering/NoneFilter.cs | 11 +-- .../Filtering/ResultSetFilterFactory.cs | 4 +- .../Grouping/CaseBased/CaseGroupingTest.cs | 83 +++++++++++++++++++ ...upingTest.cs => NameColumnGroupingTest.cs} | 9 +- ...ngTest.cs => OrdinalColumnGroupingTest.cs} | 9 +- NBi.Testing.Core/NBi.Testing.Core.csproj | 5 +- .../ResultSet/Filtering/GroupByFilterTest.cs | 2 +- 20 files changed, 238 insertions(+), 126 deletions(-) create mode 100644 NBi.Core/Calculation/Grouping/CaseBased/CaseGroupByArgs.cs create mode 100644 NBi.Core/Calculation/Grouping/CaseBased/CaseGrouping.cs delete mode 100644 NBi.Core/Calculation/Grouping/CaseBased/GroupByCase.cs create mode 100644 NBi.Core/Calculation/Grouping/ColumnBased/ColumnGroupByArgs.cs rename NBi.Core/Calculation/Grouping/ColumnBased/{AbstractByColumnGrouping.cs => ColumnGrouping.cs} (81%) rename NBi.Core/Calculation/Grouping/ColumnBased/{NameByColumnGrouping.cs => NameColumnGrouping.cs} (71%) rename NBi.Core/Calculation/Grouping/ColumnBased/{OrdinalByColumnGrouping.cs => OrdinalColumnGrouping.cs} (71%) create mode 100644 NBi.Core/Calculation/Grouping/IGroupByArgs.cs delete mode 100644 NBi.Core/Calculation/SinglePredicateFilter.cs create mode 100644 NBi.Testing.Core/Calculation/Grouping/CaseBased/CaseGroupingTest.cs rename NBi.Testing.Core/Calculation/Grouping/ColumnBased/{NameByColumnGroupingTest.cs => NameColumnGroupingTest.cs} (93%) rename NBi.Testing.Core/Calculation/Grouping/ColumnBased/{OrdinalByColumnGroupingTest.cs => OrdinalColumnGroupingTest.cs} (91%) diff --git a/NBi.Core/Calculation/Grouping/CaseBased/CaseGroupByArgs.cs b/NBi.Core/Calculation/Grouping/CaseBased/CaseGroupByArgs.cs new file mode 100644 index 000000000..be6c06ff0 --- /dev/null +++ b/NBi.Core/Calculation/Grouping/CaseBased/CaseGroupByArgs.cs @@ -0,0 +1,16 @@ +using NBi.Core.Calculation.Predication; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Grouping.CaseBased +{ + public class CaseGroupByArgs : IGroupByArgs + { + public IEnumerable Cases { get; set; } + public Context Context { get; set; } + } +} diff --git a/NBi.Core/Calculation/Grouping/CaseBased/CaseGrouping.cs b/NBi.Core/Calculation/Grouping/CaseBased/CaseGrouping.cs new file mode 100644 index 000000000..8f9628425 --- /dev/null +++ b/NBi.Core/Calculation/Grouping/CaseBased/CaseGrouping.cs @@ -0,0 +1,44 @@ +using NBi.Core.Calculation.Predication; +using NBi.Core.Variable; +using NBi.Extensibility; +using System; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Grouping.CaseBased +{ + class CaseGrouping : IGroupBy + { + protected IEnumerable Cases { get; } + protected Context Context { get; } + + public CaseGrouping(IEnumerable cases, Context context) + => (Cases, Context) = (cases, context); + + public IDictionary Execute(ResultSet.ResultSet resultSet) + { + var stopWatch = new Stopwatch(); + var dico = new Dictionary(); + stopWatch.Start(); + + foreach (DataRow row in resultSet.Rows) + { + Context.Switch(row); + var index = Cases.Select((p, i) => new { Predication = p, Index = i }) + .FirstOrDefault(x => x.Predication.Execute(Context)) + ?.Index ?? -1; + var key = new ResultSet.KeyCollection(new object[] { index }); + if (!dico.ContainsKey(key)) + dico.Add(key, row.Table.Clone()); + dico[key].ImportRow(row); + } + + Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, $"Building rows' groups by cases: {dico.Count} [{stopWatch.Elapsed.ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s")}"); + return dico; + } + } +} diff --git a/NBi.Core/Calculation/Grouping/CaseBased/GroupByCase.cs b/NBi.Core/Calculation/Grouping/CaseBased/GroupByCase.cs deleted file mode 100644 index baaaf92c8..000000000 --- a/NBi.Core/Calculation/Grouping/CaseBased/GroupByCase.cs +++ /dev/null @@ -1,42 +0,0 @@ -using NBi.Core.Calculation.Predication; -using NBi.Core.Variable; -using NBi.Extensibility; -using System; -using System.Collections.Generic; -using System.Data; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace NBi.Core.Calculation.Grouping.CaseBased -{ - class GroupByCase - { - protected IEnumerable Cases { get; } - - public GroupByCase(IEnumerable cases) - => Cases = cases; - - public IDictionary Execute(ResultSet.ResultSet resultSet, Context context) - { - var stopWatch = new Stopwatch(); - var dico = new Dictionary(); - stopWatch.Start(); - - foreach (DataRow row in resultSet.Rows) - { - context.Switch(row); - var predication = Cases.FirstOrDefault(p => p.Execute(context)); - - if (!dico.ContainsKey(predication)) - dico.Add(predication, row.Table.Clone()); - dico[predication].ImportRow(row); - } - - Trace.WriteLineIf(NBiTraceSwitch.TraceInfo, $"Building rows' groups by cases: {dico.Count} [{stopWatch.Elapsed.ToString(@"d\d\.hh\h\:mm\m\:ss\s\ \+fff\m\s")}"); - return dico; - - } - } -} diff --git a/NBi.Core/Calculation/Grouping/ColumnBased/ColumnGroupByArgs.cs b/NBi.Core/Calculation/Grouping/ColumnBased/ColumnGroupByArgs.cs new file mode 100644 index 000000000..2315b873b --- /dev/null +++ b/NBi.Core/Calculation/Grouping/ColumnBased/ColumnGroupByArgs.cs @@ -0,0 +1,20 @@ +using NBi.Core.ResultSet; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Grouping.ColumnBased +{ + public class ColumnGroupByArgs : IGroupByArgs + { + + public IEnumerable Columns { get; set; } + public Context Context { get; set; } + + public ColumnGroupByArgs(IEnumerable columns, Context context) + => (Columns, Context) = (columns, context); + } +} diff --git a/NBi.Core/Calculation/Grouping/ColumnBased/AbstractByColumnGrouping.cs b/NBi.Core/Calculation/Grouping/ColumnBased/ColumnGrouping.cs similarity index 81% rename from NBi.Core/Calculation/Grouping/ColumnBased/AbstractByColumnGrouping.cs rename to NBi.Core/Calculation/Grouping/ColumnBased/ColumnGrouping.cs index a1ad0a825..058befa36 100644 --- a/NBi.Core/Calculation/Grouping/ColumnBased/AbstractByColumnGrouping.cs +++ b/NBi.Core/Calculation/Grouping/ColumnBased/ColumnGrouping.cs @@ -1,4 +1,5 @@ using NBi.Core.ResultSet; +using NBi.Core.Variable; using NBi.Extensibility; using System; using System.Collections.Generic; @@ -10,14 +11,13 @@ namespace NBi.Core.Calculation.Grouping.ColumnBased { - public abstract class AbstractByColumnGrouping : IGroupBy + public abstract class ColumnGrouping : IGroupBy { protected ISettingsResultSet Settings { get; } + protected Context Context { get; } - public AbstractByColumnGrouping(ISettingsResultSet settings) - { - Settings = settings; - } + protected ColumnGrouping(ISettingsResultSet settings, Context context) + => (Settings, Context) = (settings, context); public IDictionary Execute(ResultSet.ResultSet resultSet) { @@ -28,6 +28,7 @@ public IDictionary Execute(ResultSet.ResultSet resultS stopWatch.Start(); foreach (DataRow row in resultSet.Rows) { + Context.Switch(row); var key = keyComparer.GetKeys(row); if (!dico.ContainsKey(key)) dico.Add(key, row.Table.Clone()); diff --git a/NBi.Core/Calculation/Grouping/ColumnBased/NameByColumnGrouping.cs b/NBi.Core/Calculation/Grouping/ColumnBased/NameColumnGrouping.cs similarity index 71% rename from NBi.Core/Calculation/Grouping/ColumnBased/NameByColumnGrouping.cs rename to NBi.Core/Calculation/Grouping/ColumnBased/NameColumnGrouping.cs index d82d0b280..b73a11c00 100644 --- a/NBi.Core/Calculation/Grouping/ColumnBased/NameByColumnGrouping.cs +++ b/NBi.Core/Calculation/Grouping/ColumnBased/NameColumnGrouping.cs @@ -5,15 +5,16 @@ using System.Text; using System.Threading.Tasks; using NBi.Core.ResultSet; +using NBi.Core.Variable; namespace NBi.Core.Calculation.Grouping.ColumnBased { - class NameByColumnGrouping : AbstractByColumnGrouping + class NameColumnGrouping : ColumnGrouping { protected new SettingsNameResultSet Settings { get => base.Settings as SettingsNameResultSet; } - public NameByColumnGrouping(SettingsNameResultSet settings) - : base(settings) { } + public NameColumnGrouping(SettingsNameResultSet settings, Context context) + : base(settings, context) { } protected override DataRowKeysComparer BuildDataRowsKeyComparer(DataTable x) => new DataRowKeysComparerByName(Settings); diff --git a/NBi.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGrouping.cs b/NBi.Core/Calculation/Grouping/ColumnBased/OrdinalColumnGrouping.cs similarity index 71% rename from NBi.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGrouping.cs rename to NBi.Core/Calculation/Grouping/ColumnBased/OrdinalColumnGrouping.cs index f811ac84b..fa505fb52 100644 --- a/NBi.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGrouping.cs +++ b/NBi.Core/Calculation/Grouping/ColumnBased/OrdinalColumnGrouping.cs @@ -5,15 +5,16 @@ using System.Text; using System.Threading.Tasks; using NBi.Core.ResultSet; +using NBi.Core.Variable; namespace NBi.Core.Calculation.Grouping.ColumnBased { - class OrdinalByColumnGrouping : AbstractByColumnGrouping + class OrdinalColumnGrouping : ColumnGrouping { protected new SettingsOrdinalResultSet Settings { get => base.Settings as SettingsOrdinalResultSet; } - public OrdinalByColumnGrouping(SettingsOrdinalResultSet settings) - : base(settings) { } + public OrdinalColumnGrouping(SettingsOrdinalResultSet settings, Context context) + : base(settings, context) { } protected override DataRowKeysComparer BuildDataRowsKeyComparer(DataTable x) => new DataRowKeysComparerByOrdinal(Settings, x.Columns.Count); diff --git a/NBi.Core/Calculation/Grouping/GroupByFactory.cs b/NBi.Core/Calculation/Grouping/GroupByFactory.cs index 933d0c4c9..d167f2ab9 100644 --- a/NBi.Core/Calculation/Grouping/GroupByFactory.cs +++ b/NBi.Core/Calculation/Grouping/GroupByFactory.cs @@ -1,8 +1,11 @@ -using NBi.Core.Calculation.Grouping.ColumnBased; +using NBi.Core.Calculation.Grouping.CaseBased; +using NBi.Core.Calculation.Grouping.ColumnBased; +using NBi.Core.Calculation.Predication; using NBi.Core.ResultSet; using NBi.Core.ResultSet.Equivalence; using NBi.Core.Scalar.Comparer; using NBi.Core.Transformation; +using NBi.Core.Variable; using System; using System.Collections.Generic; using System.Linq; @@ -14,9 +17,19 @@ namespace NBi.Core.Calculation.Grouping { public class GroupByFactory { - public IGroupBy None() => new NoneGrouping(); + public static IGroupBy None() => new NoneGrouping(); - public IGroupBy Instantiate(IEnumerable columns) + public IGroupBy Instantiate(IGroupByArgs args) + { + switch (args) + { + case ColumnGroupByArgs x: return Instantiate(x.Columns, x.Context); + case CaseGroupByArgs x: return new CaseGrouping(x.Cases, x.Context); + default: throw new ArgumentOutOfRangeException(); + } + } + + private IGroupBy Instantiate(IEnumerable columns, Context context) { if ((columns?.Count() ?? 0) == 0) return new NoneGrouping(); @@ -39,10 +52,10 @@ public IGroupBy Instantiate(IEnumerable columns) var settings = builder.GetSettings(); if (settings is SettingsOrdinalResultSet) - return new OrdinalByColumnGrouping(settings as SettingsOrdinalResultSet); + return new OrdinalColumnGrouping(settings as SettingsOrdinalResultSet, context); else if (settings is SettingsNameResultSet) - return new NameByColumnGrouping(settings as SettingsNameResultSet); + return new NameColumnGrouping(settings as SettingsNameResultSet, context); throw new ArgumentOutOfRangeException(nameof(settings)); } diff --git a/NBi.Core/Calculation/Grouping/IGroupByArgs.cs b/NBi.Core/Calculation/Grouping/IGroupByArgs.cs new file mode 100644 index 000000000..779d85c96 --- /dev/null +++ b/NBi.Core/Calculation/Grouping/IGroupByArgs.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Grouping +{ + public interface IGroupByArgs + { } +} diff --git a/NBi.Core/Calculation/SinglePredicateFilter.cs b/NBi.Core/Calculation/SinglePredicateFilter.cs deleted file mode 100644 index 599bbbd86..000000000 --- a/NBi.Core/Calculation/SinglePredicateFilter.cs +++ /dev/null @@ -1,40 +0,0 @@ -//using NBi.Core.Calculation.Predicate; -//using NBi.Core.Evaluate; -//using NBi.Core.Injection; -//using NBi.Core.ResultSet; -//using NBi.Core.Variable; -//using System; -//using System.Collections.Generic; -//using System.Data; -//using System.Linq; -//using System.Text; -//using System.Threading.Tasks; - -//namespace NBi.Core.Calculation -//{ -// class SinglePredicateFilter : RowValueExtractor -// { -// private readonly Func implementation; -// private readonly IColumnIdentifier operand; -// private readonly Func describeFunction; - -// public SinglePredicateFilter(ServiceLocator serviceLocator, Context context, IEnumerable aliases, IEnumerable expressions, IColumnIdentifier operand, Func implementation, Func describeFunction) -// : base(serviceLocator, context, aliases, expressions) -// { -// this.operand = operand; -// this.implementation = implementation; -// this.describeFunction = describeFunction; -// } - -// protected override bool RowApply(Context context) -// { -// var value = GetValueFromRow(context, operand); -// return implementation(value); -// } - -// public override string Describe() -// { -// return $"{operand.Label} {describeFunction()}."; -// } -// } -//} diff --git a/NBi.Core/NBi.Core.csproj b/NBi.Core/NBi.Core.csproj index ca659aa92..70a68c095 100644 --- a/NBi.Core/NBi.Core.csproj +++ b/NBi.Core/NBi.Core.csproj @@ -145,19 +145,22 @@ + + + - + - + - - + + @@ -224,7 +227,6 @@ - diff --git a/NBi.Core/ResultSet/Alteration/Reshaping/UnstackEngine.cs b/NBi.Core/ResultSet/Alteration/Reshaping/UnstackEngine.cs index 64ae7e27c..e3920e5bb 100644 --- a/NBi.Core/ResultSet/Alteration/Reshaping/UnstackEngine.cs +++ b/NBi.Core/ResultSet/Alteration/Reshaping/UnstackEngine.cs @@ -1,6 +1,8 @@ using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Grouping.ColumnBased; using NBi.Core.Scalar.Resolver; using NBi.Core.Sequence.Transformation.Aggregation; +using NBi.Core.Variable; using System; using System.Collections.Generic; using System.Data; @@ -48,7 +50,7 @@ public ResultSet Execute(ResultSet rs) var groupbyFactory = new GroupByFactory(); - var groupbyEngine = groupbyFactory.Instantiate(Args.GroupBys); + var groupbyEngine = groupbyFactory.Instantiate(new ColumnGroupByArgs(Args.GroupBys, Context.None)); var groups = groupbyEngine.Execute(rs); foreach (var group in groups) { diff --git a/NBi.Core/ResultSet/Alteration/Summarization/SummarizeEngine.cs b/NBi.Core/ResultSet/Alteration/Summarization/SummarizeEngine.cs index 90af3014e..86b1d4078 100644 --- a/NBi.Core/ResultSet/Alteration/Summarization/SummarizeEngine.cs +++ b/NBi.Core/ResultSet/Alteration/Summarization/SummarizeEngine.cs @@ -1,6 +1,8 @@ using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Grouping.ColumnBased; using NBi.Core.Scalar.Resolver; using NBi.Core.Sequence.Transformation.Aggregation; +using NBi.Core.Variable; using System; using System.Collections.Generic; using System.Data; @@ -42,7 +44,7 @@ public ResultSet Execute(ResultSet rs) } var groupbyFactory = new GroupByFactory(); - var groupbyEngine = groupbyFactory.Instantiate(Args.GroupBys); + var groupbyEngine = groupbyFactory.Instantiate(new ColumnGroupByArgs(Args.GroupBys, Context.None)); var groups = groupbyEngine.Execute(rs); foreach (var group in groups) { diff --git a/NBi.Core/ResultSet/Filtering/NoneFilter.cs b/NBi.Core/ResultSet/Filtering/NoneFilter.cs index 7395183d6..6c31dda0f 100644 --- a/NBi.Core/ResultSet/Filtering/NoneFilter.cs +++ b/NBi.Core/ResultSet/Filtering/NoneFilter.cs @@ -10,19 +10,12 @@ namespace NBi.Core.ResultSet.Filtering class NoneFilter : IResultSetFilter { public ResultSet Apply(ResultSet rs) - { - if (rs == null) - throw new ArgumentNullException(); - return rs; - } + => rs ?? throw new ArgumentNullException(); public ResultSet AntiApply(ResultSet rs) { - if (rs == null) - throw new ArgumentNullException(); - + var table = rs?.Table?.Clone() ?? throw new ArgumentNullException(); var filteredRs = new ResultSet(); - var table = rs.Table.Clone(); filteredRs.Load(table); return filteredRs; } diff --git a/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs b/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs index 850b891ef..8059bed94 100644 --- a/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs +++ b/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs @@ -1,5 +1,6 @@ using NBi.Core.Calculation; using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Grouping.ColumnBased; using NBi.Core.Calculation.Predicate; using NBi.Core.Calculation.Predicate.Combination; using NBi.Core.Calculation.Predication; @@ -65,7 +66,8 @@ public IResultSetFilter Instantiate(CombinationOperator combinationOperator, IEn public IResultSetFilter Instantiate(IRankingInfo rankingInfo, IEnumerable columns) { var groupingFactory = new GroupByFactory(); - var grouping = groupingFactory.Instantiate(columns); + var groupingArgs = new ColumnGroupByArgs(columns, Context.None); + var grouping = groupingFactory.Instantiate(groupingArgs); var rankingFactory = new RankingFactory(); var ranking = rankingFactory.Instantiate(rankingInfo); diff --git a/NBi.Testing.Core/Calculation/Grouping/CaseBased/CaseGroupingTest.cs b/NBi.Testing.Core/Calculation/Grouping/CaseBased/CaseGroupingTest.cs new file mode 100644 index 000000000..ebec9915d --- /dev/null +++ b/NBi.Testing.Core/Calculation/Grouping/CaseBased/CaseGroupingTest.cs @@ -0,0 +1,83 @@ +using NBi.Core.Calculation.Grouping.CaseBased; +using NBi.Core.Calculation.Predicate.Text; +using NBi.Core.Calculation.Predication; +using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Resolver; +using NBi.Core.Scalar.Resolver; +using NBi.Core.Variable; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Testing.Core.Calculation.Grouping.ColumnBased +{ + public class CaseGroupingTest + { + [Test] + public void Execute_SingleColumn_TwoGroups() + { + var args = new ObjectsResultSetResolverArgs(new[] { new object[] { "alpha", 1 }, new object[] { "beta", 2 }, new object[] { "BETA", 3 }, new object[] { "alpha", 4 } }); + var resolver = new ObjectsResultSetResolver(args); + var rs = resolver.Execute(); + var lowerCase = new SinglePredication(new TextLowerCase(false), new ColumnOrdinalIdentifier(0)); + var upperCase = new SinglePredication(new TextUpperCase(false), new ColumnOrdinalIdentifier(0)); + + var grouping = new CaseGrouping(new IPredication[] { lowerCase, upperCase }, Context.None); + + var result = grouping.Execute(rs); + Assert.That(result, Has.Count.EqualTo(2)); + Assert.That(result.ElementAt(0).Value.Rows, Has.Count.EqualTo(3)); + Assert.That(result.ElementAt(1).Value.Rows, Has.Count.EqualTo(1)); + } + + [Test] + public void Execute_TwoColumns_ThreeGroups() + { + var args = new ObjectsResultSetResolverArgs(new[] { new object[] { "alpha", "1", 10 }, new object[] { "ALPHA", "1", 20 }, new object[] { "beta", "2", 30 }, new object[] { "ALPHA", "2", 40 } }); + var resolver = new ObjectsResultSetResolver(args); + var rs = resolver.Execute(); + var lowerCase = new SinglePredication(new TextLowerCase(false), new ColumnOrdinalIdentifier(0)); + var upperCase = new AndCombinationPredication(new List() + { + new SinglePredication(new TextUpperCase(false), new ColumnOrdinalIdentifier(0)), + new SinglePredication(new TextEqual(false, new LiteralScalarResolver("1")), new ColumnOrdinalIdentifier(1)), + }); + + var grouping = new CaseGrouping(new IPredication[] { lowerCase, upperCase }, Context.None); + + var result = grouping.Execute(rs); + Assert.That(result, Has.Count.EqualTo(3)); + Assert.That(result.ElementAt(0).Value.Rows, Has.Count.EqualTo(2)); + Assert.That(result.ElementAt(1).Value.Rows, Has.Count.EqualTo(1)); + Assert.That(result.ElementAt(2).Value.Rows, Has.Count.EqualTo(1)); + } + + [Test] + public void Execute_TwoColumnsWithContext_ThreeGroups() + { + var args = new ObjectsResultSetResolverArgs(new[] { new object[] { "alpha", "1", "1" }, new object[] { "ALPHA", "1", "1" }, new object[] { "beta", "2", "2" }, new object[] { "ALPHA", "2", "4" } }); + var resolver = new ObjectsResultSetResolver(args); + var rs = resolver.Execute(); + + var context = new Context(null); + var lowerCase = new SinglePredication(new TextLowerCase(false), new ColumnOrdinalIdentifier(0)); + var contextArgs = new ContextScalarResolverArgs(context, new ColumnOrdinalIdentifier(2)); + var upperCase = new AndCombinationPredication(new List() + { + new SinglePredication(new TextUpperCase(false), new ColumnOrdinalIdentifier(0)), + new SinglePredication(new TextEqual(false, new ContextScalarResolver(contextArgs)), new ColumnOrdinalIdentifier(1)), + }); + + var grouping = new CaseGrouping(new IPredication[] { lowerCase, upperCase }, context); + + var result = grouping.Execute(rs); + Assert.That(result, Has.Count.EqualTo(3)); + Assert.That(result.ElementAt(0).Value.Rows, Has.Count.EqualTo(2)); + Assert.That(result.ElementAt(1).Value.Rows, Has.Count.EqualTo(1)); + Assert.That(result.ElementAt(2).Value.Rows, Has.Count.EqualTo(1)); + } + } +} diff --git a/NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameByColumnGroupingTest.cs b/NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameColumnGroupingTest.cs similarity index 93% rename from NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameByColumnGroupingTest.cs rename to NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameColumnGroupingTest.cs index c48eb9016..34c8656cb 100644 --- a/NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameByColumnGroupingTest.cs +++ b/NBi.Testing.Core/Calculation/Grouping/ColumnBased/NameColumnGroupingTest.cs @@ -3,6 +3,7 @@ using NBi.Core.ResultSet; using NBi.Core.ResultSet.Resolver; using NBi.Core.Scalar.Comparer; +using NBi.Core.Variable; using NUnit.Framework; using System; using System.Collections.Generic; @@ -13,7 +14,7 @@ namespace NBi.Testing.Core.Calculation.Grouping.ColumnBased { - public class NameByColumnGroupingTest + public class NameColumnGroupingTest { [Test] public void Execute_SingleColumn_TwoGroups() @@ -28,7 +29,7 @@ public void Execute_SingleColumn_TwoGroups() new Column() { Identifier = new ColumnNameIdentifier("first"), Role = ColumnRole.Key, Type = ColumnType.Text }, } ); - var grouping = new NameByColumnGrouping(settings); + var grouping = new NameColumnGrouping(settings, Context.None); var result = grouping.Execute(rs); Assert.That(result, Has.Count.EqualTo(2)); @@ -51,7 +52,7 @@ public void Execute_TwoColumns_ThreeGroups() new Column() { Identifier = new ColumnNameIdentifier("second"), Role = ColumnRole.Key, Type = ColumnType.Text }, } ); - var grouping = new NameByColumnGrouping(settings); + var grouping = new NameColumnGrouping(settings, Context.None); var result = grouping.Execute(rs); Assert.That(result, Has.Count.EqualTo(3)); @@ -76,7 +77,7 @@ public void Execute_TwoCustomColumns_ThreeGroups() new Column() { Identifier = new ColumnNameIdentifier("second"), Role = ColumnRole.Key, Type = ColumnType.Numeric }, } ); - var grouping = new NameByColumnGrouping(settings); + var grouping = new NameColumnGrouping(settings, Context.None); var result = grouping.Execute(rs); Assert.That(result, Has.Count.EqualTo(3)); diff --git a/NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGroupingTest.cs b/NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalColumnGroupingTest.cs similarity index 91% rename from NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGroupingTest.cs rename to NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalColumnGroupingTest.cs index 3e18010df..f63d5c37c 100644 --- a/NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalByColumnGroupingTest.cs +++ b/NBi.Testing.Core/Calculation/Grouping/ColumnBased/OrdinalColumnGroupingTest.cs @@ -3,6 +3,7 @@ using NBi.Core.ResultSet; using NBi.Core.ResultSet.Resolver; using NBi.Core.Scalar.Comparer; +using NBi.Core.Variable; using NUnit.Framework; using System; using System.Collections.Generic; @@ -13,7 +14,7 @@ namespace NBi.Testing.Core.Calculation.Grouping.ColumnBased { - public class OrdinalByColumnGroupingTest + public class OrdinalColumnGroupingTest { [Test] public void Execute_SingleColumn_TwoGroups() @@ -23,7 +24,7 @@ public void Execute_SingleColumn_TwoGroups() var rs = resolver.Execute(); var settings = new SettingsOrdinalResultSet(KeysChoice.First, ValuesChoice.None, NumericAbsoluteTolerance.None); - var grouping = new OrdinalByColumnGrouping(settings); + var grouping = new OrdinalColumnGrouping(settings, Context.None); var result = grouping.Execute(rs); Assert.That(result, Has.Count.EqualTo(2)); @@ -39,7 +40,7 @@ public void Execute_TwoColumns_ThreeGroups() var rs = resolver.Execute(); var settings = new SettingsOrdinalResultSet(KeysChoice.AllExpectLast, ValuesChoice.None, NumericAbsoluteTolerance.None); - var grouping = new OrdinalByColumnGrouping(settings); + var grouping = new OrdinalColumnGrouping(settings, Context.None); var result = grouping.Execute(rs); Assert.That(result, Has.Count.EqualTo(3)); @@ -61,7 +62,7 @@ public void Execute_TwoCustomColumns_ThreeGroups() new Column() { Identifier = new ColumnOrdinalIdentifier(1), Role = ColumnRole.Key, Type = ColumnType.Numeric }, } ); - var grouping = new OrdinalByColumnGrouping(settings); + var grouping = new OrdinalColumnGrouping(settings, Context.None); var result = grouping.Execute(rs); Assert.That(result, Has.Count.EqualTo(3)); diff --git a/NBi.Testing.Core/NBi.Testing.Core.csproj b/NBi.Testing.Core/NBi.Testing.Core.csproj index e23ca2ef3..804ad143f 100644 --- a/NBi.Testing.Core/NBi.Testing.Core.csproj +++ b/NBi.Testing.Core/NBi.Testing.Core.csproj @@ -102,14 +102,15 @@ + - - + + diff --git a/NBi.Testing.Core/ResultSet/Filtering/GroupByFilterTest.cs b/NBi.Testing.Core/ResultSet/Filtering/GroupByFilterTest.cs index 66c5e16ab..5587fc474 100644 --- a/NBi.Testing.Core/ResultSet/Filtering/GroupByFilterTest.cs +++ b/NBi.Testing.Core/ResultSet/Filtering/GroupByFilterTest.cs @@ -28,7 +28,7 @@ public void Execute_Top2OneKey_ResultSetReduced() var rs = resolver.Execute(); var settings = new SettingsOrdinalResultSet(KeysChoice.First, ValuesChoice.None, NumericAbsoluteTolerance.None); - var grouping = new OrdinalByColumnGrouping(settings); + var grouping = new OrdinalColumnGrouping(settings, Context.None); var filter = new TopRanking(2, new ColumnOrdinalIdentifier(1), ColumnType.Numeric); From ecb907e0b6e76d9355ff3701ecc59cf228e8c10a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20L=2E=20Charlier?= Date: Mon, 18 Nov 2019 21:42:27 +0100 Subject: [PATCH 3/3] [WIP] Serialization and Mapping --- .../Grouping/CaseBased/CaseGroupByArgs.cs | 3 + .../Calculation/Grouping/GroupByFactory.cs | 1 + .../GroupByFactory.cs~Stashed changes | 81 +++++++++++++++++++ .../Calculation/Grouping/NoneGroupByArgs.cs | 11 +++ .../Calculation/Predicate/PredicateArgs.cs | 12 +-- .../Predication/PredicationFactory.cs | 2 +- NBi.Core/Calculation/Ranking/RankingArgs.cs | 23 ++++++ .../Calculation/Ranking/RankingFactory.cs | 8 +- NBi.Core/NBi.Core.csproj | 5 ++ NBi.Core/ResultSet/Filtering/GroupByFilter.cs | 2 +- .../ResultSet/Filtering/IFilteringArgs.cs | 11 +++ .../ResultSet/Filtering/PredicationArgs.cs | 20 +++++ .../ResultSet/Filtering/RankingGroupByArgs.cs | 18 +++++ .../Filtering/ResultSetFilterFactory.cs | 32 ++++---- .../Builder/Helper/ResultSetSystemHelper.cs | 43 +++++++++- NBi.NUnit/NBi.NUnit.csproj | 2 +- NBi.Testing.Xml/Constraints/AllRowsXmlTest.cs | 40 ++++----- .../Items/Calculation/PredicateXmlTest.cs | 4 +- .../Items/Calculation/RankingXmlTest.cs | 36 +++++++++ .../Resources/RankingXmlTestSuite.xml | 40 +++++++++ .../Positive/ResultSetConstraint.nbits | 70 ++++++++++++++-- .../Builder/ResultSetAllRowsBuilderTest.cs | 10 +-- .../Builder/ResultSetRowCountBuilderTest.cs | 4 +- .../Builder/ResultSetSingleRowBuilderTest.cs | 10 +-- .../Builder/ResultSetSomeRowsBuilderTest.cs | 10 +-- NBi.Xml/Constraints/NoRowsXml.cs | 4 +- NBi.Xml/Items/AbstractPredicationXml.cs | 11 +++ ...ateXml.cs => CombinationPredicationXml.cs} | 4 +- NBi.Xml/Items/Calculation/FilterXml.cs | 4 +- NBi.Xml/Items/Calculation/Grouping/CaseXml.cs | 16 ++++ .../Items/Calculation/Grouping/GroupByxml.cs | 3 + ...dicationXml.cs => SinglePredicationXml.cs} | 4 +- NBi.Xml/NBi.Xml.csproj | 6 +- NBi.Xml/Schema/BaseType.xsd | 17 +++- .../SerializationOption/ReadOnlyAttributes.cs | 4 +- 35 files changed, 474 insertions(+), 97 deletions(-) create mode 100644 NBi.Core/Calculation/Grouping/GroupByFactory.cs~Stashed changes create mode 100644 NBi.Core/Calculation/Grouping/NoneGroupByArgs.cs create mode 100644 NBi.Core/Calculation/Ranking/RankingArgs.cs create mode 100644 NBi.Core/ResultSet/Filtering/IFilteringArgs.cs create mode 100644 NBi.Core/ResultSet/Filtering/PredicationArgs.cs create mode 100644 NBi.Core/ResultSet/Filtering/RankingGroupByArgs.cs create mode 100644 NBi.Xml/Items/AbstractPredicationXml.cs rename NBi.Xml/Items/Calculation/{CombinationPredicateXml.cs => CombinationPredicationXml.cs} (81%) create mode 100644 NBi.Xml/Items/Calculation/Grouping/CaseXml.cs rename NBi.Xml/Items/Calculation/{PredicationXml.cs => SinglePredicationXml.cs} (96%) diff --git a/NBi.Core/Calculation/Grouping/CaseBased/CaseGroupByArgs.cs b/NBi.Core/Calculation/Grouping/CaseBased/CaseGroupByArgs.cs index be6c06ff0..7adbac851 100644 --- a/NBi.Core/Calculation/Grouping/CaseBased/CaseGroupByArgs.cs +++ b/NBi.Core/Calculation/Grouping/CaseBased/CaseGroupByArgs.cs @@ -12,5 +12,8 @@ public class CaseGroupByArgs : IGroupByArgs { public IEnumerable Cases { get; set; } public Context Context { get; set; } + + public CaseGroupByArgs(IEnumerable cases, Context context) + => (Cases, Context) = (cases, context); } } diff --git a/NBi.Core/Calculation/Grouping/GroupByFactory.cs b/NBi.Core/Calculation/Grouping/GroupByFactory.cs index d167f2ab9..5cc5d8cab 100644 --- a/NBi.Core/Calculation/Grouping/GroupByFactory.cs +++ b/NBi.Core/Calculation/Grouping/GroupByFactory.cs @@ -23,6 +23,7 @@ public IGroupBy Instantiate(IGroupByArgs args) { switch (args) { + case NoneGroupByArgs x: return None(); case ColumnGroupByArgs x: return Instantiate(x.Columns, x.Context); case CaseGroupByArgs x: return new CaseGrouping(x.Cases, x.Context); default: throw new ArgumentOutOfRangeException(); diff --git a/NBi.Core/Calculation/Grouping/GroupByFactory.cs~Stashed changes b/NBi.Core/Calculation/Grouping/GroupByFactory.cs~Stashed changes new file mode 100644 index 000000000..02fa051fd --- /dev/null +++ b/NBi.Core/Calculation/Grouping/GroupByFactory.cs~Stashed changes @@ -0,0 +1,81 @@ +using NBi.Core.Calculation.Grouping.CaseBased; +using NBi.Core.Calculation.Grouping.ColumnBased; +using NBi.Core.Calculation.Predication; +using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Equivalence; +using NBi.Core.Scalar.Comparer; +using NBi.Core.Transformation; +using NBi.Core.Variable; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static NBi.Core.ResultSet.SettingsOrdinalResultSet; + +namespace NBi.Core.Calculation.Grouping +{ + public class GroupByFactory + { + public static IGroupBy None() => new NoneGrouping(); + + public IGroupBy Instantiate(IGroupByArgs args) + { + switch (args) + { + case NoneGroupByArgs _: return None(); + case ColumnGroupByArgs x: return Instantiate(x.Columns, x.Context); + case CaseGroupByArgs x: return new CaseGrouping(x.Cases, x.Context); + default: throw new ArgumentOutOfRangeException(); + } + } + + private IGroupBy Instantiate(IEnumerable columns, Context context) + { + if ((columns?.Count() ?? 0) == 0) + return new NoneGrouping(); + + var definitions = new List(); + foreach (var column in columns) + { + var definition = new ColumnDefinition() + { + Identifier = column.Identifier, + Type = column.Type + }; + definitions.Add(definition); + } + + var builder = new SettingsEquivalerBuilder(); + builder.Setup(KeysChoice.None, ValuesChoice.None); + builder.Setup(definitions); + builder.Build(); + + var settings = builder.GetSettings(); + if (settings is SettingsOrdinalResultSet) + return new OrdinalColumnGrouping(settings as SettingsOrdinalResultSet, context); + + else if (settings is SettingsNameResultSet) + return new NameColumnGrouping(settings as SettingsNameResultSet, context); + + throw new ArgumentOutOfRangeException(nameof(settings)); + } + + private class ColumnDefinition : IColumnDefinition + { + public IColumnIdentifier Identifier { get; set; } + public ColumnRole Role { get => ColumnRole.Key; set => throw new NotImplementedException(); } + public ColumnType Type { get; set; } + + + public string Tolerance { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public bool IsToleranceSpecified => false; + + public Rounding.RoundingStyle RoundingStyle { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public string RoundingStep { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public ITransformationInfo Transformation => throw new NotImplementedException(); + } + } +} diff --git a/NBi.Core/Calculation/Grouping/NoneGroupByArgs.cs b/NBi.Core/Calculation/Grouping/NoneGroupByArgs.cs new file mode 100644 index 000000000..969e840c9 --- /dev/null +++ b/NBi.Core/Calculation/Grouping/NoneGroupByArgs.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Grouping +{ + public class NoneGroupByArgs : IGroupByArgs + { } +} diff --git a/NBi.Core/Calculation/Predicate/PredicateArgs.cs b/NBi.Core/Calculation/Predicate/PredicateArgs.cs index 6d3f68e3b..9dd3cb91a 100644 --- a/NBi.Core/Calculation/Predicate/PredicateArgs.cs +++ b/NBi.Core/Calculation/Predicate/PredicateArgs.cs @@ -1,4 +1,5 @@ using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Filtering; using System; using System.Collections.Generic; using System.Linq; @@ -33,15 +34,4 @@ public class CultureSensitivePredicateArgs : PredicateArgs { public virtual string Culture { get; set; } } - - public class PredicationArgs - { - public PredicationArgs() { } - - public PredicationArgs(IColumnIdentifier identifier, PredicateArgs predicate) - => (Identifier, Predicate) = (identifier, predicate); - - public virtual PredicateArgs Predicate { get; set; } - public virtual IColumnIdentifier Identifier { get; set; } - } } diff --git a/NBi.Core/Calculation/Predication/PredicationFactory.cs b/NBi.Core/Calculation/Predication/PredicationFactory.cs index 6b2a94d76..23a2ef8f5 100644 --- a/NBi.Core/Calculation/Predication/PredicationFactory.cs +++ b/NBi.Core/Calculation/Predication/PredicationFactory.cs @@ -9,7 +9,7 @@ namespace NBi.Core.Calculation.Predication { - class PredicationFactory + public class PredicationFactory { public IPredication Instantiate(IPredicate predicate, IColumnIdentifier operand) => new SinglePredication(predicate, operand); diff --git a/NBi.Core/Calculation/Ranking/RankingArgs.cs b/NBi.Core/Calculation/Ranking/RankingArgs.cs new file mode 100644 index 000000000..f70a9c474 --- /dev/null +++ b/NBi.Core/Calculation/Ranking/RankingArgs.cs @@ -0,0 +1,23 @@ +using NBi.Core.ResultSet; +using NBi.Core.ResultSet.Filtering; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.Calculation.Ranking +{ + public class RankingArgs : IRankingInfo + { + public RankingOption Option { get; } + + public int Count { get; } + + public IColumnIdentifier Operand { get; set; } + public ColumnType Type { get; set; } + + public RankingArgs(RankingOption option, int count, IColumnIdentifier operand, ColumnType type) + => (Option, Count, Operand, Type) = (option, count, operand, type); + } +} diff --git a/NBi.Core/Calculation/Ranking/RankingFactory.cs b/NBi.Core/Calculation/Ranking/RankingFactory.cs index 6ae1e7f67..634f50936 100644 --- a/NBi.Core/Calculation/Ranking/RankingFactory.cs +++ b/NBi.Core/Calculation/Ranking/RankingFactory.cs @@ -8,14 +8,14 @@ namespace NBi.Core.Calculation.Ranking { public class RankingFactory { - public AbstractRanking Instantiate(IRankingInfo info) + public AbstractRanking Instantiate(RankingArgs args) { - switch (info.Option) + switch (args.Option) { case RankingOption.Top: - return new TopRanking(info.Count, info.Operand, info.Type); + return new TopRanking(args.Count, args.Operand, args.Type); case RankingOption.Bottom: - return new BottomRanking(info.Count, info.Operand, info.Type); + return new BottomRanking(args.Count, args.Operand, args.Type); default: throw new ArgumentOutOfRangeException(); } diff --git a/NBi.Core/NBi.Core.csproj b/NBi.Core/NBi.Core.csproj index 70a68c095..595d5c3ad 100644 --- a/NBi.Core/NBi.Core.csproj +++ b/NBi.Core/NBi.Core.csproj @@ -148,6 +148,9 @@ + + + @@ -163,8 +166,10 @@ + + diff --git a/NBi.Core/ResultSet/Filtering/GroupByFilter.cs b/NBi.Core/ResultSet/Filtering/GroupByFilter.cs index aa8135cc6..ca3b4fd6c 100644 --- a/NBi.Core/ResultSet/Filtering/GroupByFilter.cs +++ b/NBi.Core/ResultSet/Filtering/GroupByFilter.cs @@ -36,6 +36,6 @@ public ResultSet AntiApply(ResultSet rs) => throw new NotImplementedException(); public string Describe() - => throw new NotImplementedException(); + => $"{Filter.Describe()} after grouping by {GroupBy.ToString()}"; } } diff --git a/NBi.Core/ResultSet/Filtering/IFilteringArgs.cs b/NBi.Core/ResultSet/Filtering/IFilteringArgs.cs new file mode 100644 index 000000000..51f41b2da --- /dev/null +++ b/NBi.Core/ResultSet/Filtering/IFilteringArgs.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.ResultSet.Filtering +{ + public interface IFilteringArgs + { } +} diff --git a/NBi.Core/ResultSet/Filtering/PredicationArgs.cs b/NBi.Core/ResultSet/Filtering/PredicationArgs.cs new file mode 100644 index 000000000..cafff4ccd --- /dev/null +++ b/NBi.Core/ResultSet/Filtering/PredicationArgs.cs @@ -0,0 +1,20 @@ +using NBi.Core.Calculation.Predicate; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.ResultSet.Filtering +{ + public class PredicationArgs : IFilteringArgs + { + public PredicationArgs() { } + + public PredicationArgs(IColumnIdentifier identifier, PredicateArgs predicate) + => (Identifier, Predicate) = (identifier, predicate); + + public virtual PredicateArgs Predicate { get; set; } + public virtual IColumnIdentifier Identifier { get; set; } + } +} diff --git a/NBi.Core/ResultSet/Filtering/RankingGroupByArgs.cs b/NBi.Core/ResultSet/Filtering/RankingGroupByArgs.cs new file mode 100644 index 000000000..c1d06b387 --- /dev/null +++ b/NBi.Core/ResultSet/Filtering/RankingGroupByArgs.cs @@ -0,0 +1,18 @@ +using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Ranking; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Core.ResultSet.Filtering +{ + public class RankingGroupByArgs : RankingArgs, IFilteringArgs + { + public IGroupBy GroupBy { get; } + + public RankingGroupByArgs(IGroupBy groupBy, RankingOption option, int count, IColumnIdentifier operand, ColumnType type) + : base (option, count, operand, type) => GroupBy = groupBy; + } +} diff --git a/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs b/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs index 8059bed94..4b719a0e6 100644 --- a/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs +++ b/NBi.Core/ResultSet/Filtering/ResultSetFilterFactory.cs @@ -1,5 +1,6 @@ using NBi.Core.Calculation; using NBi.Core.Calculation.Grouping; +using NBi.Core.Calculation.Grouping.CaseBased; using NBi.Core.Calculation.Grouping.ColumnBased; using NBi.Core.Calculation.Predicate; using NBi.Core.Calculation.Predicate.Combination; @@ -25,7 +26,17 @@ public class ResultSetFilterFactory public ResultSetFilterFactory(ServiceLocator serviceLocator) => (ServiceLocator) = (serviceLocator); - public IResultSetFilter Instantiate(PredicationArgs predicationArgs, Context context) + public IResultSetFilter Instantiate(IFilteringArgs filteringArgs, Context context) + { + switch (filteringArgs) + { + case PredicationArgs args: return InstantiatePredication(args, context); + case RankingGroupByArgs args: return InstantiateRanking(args, context); + default: throw new ArgumentOutOfRangeException(); + } + } + + private IResultSetFilter InstantiatePredication(PredicationArgs predicationArgs, Context context) { if (predicationArgs.Identifier == null) throw new ArgumentException("You must specify an operand for a predication. The operand is the column or alias or expression on which the predicate will be evaluated."); @@ -40,6 +51,12 @@ public IResultSetFilter Instantiate(PredicationArgs predicationArgs, Context con return filter; } + private IResultSetFilter InstantiateRanking(RankingGroupByArgs args, Context context) + { + var ranking = new RankingFactory().Instantiate(args); + return new GroupByFilter(ranking, args.GroupBy); + } + public IResultSetFilter Instantiate(CombinationOperator combinationOperator, IEnumerable predicationArgs, Context context) { var predications = new List(); @@ -61,18 +78,5 @@ public IResultSetFilter Instantiate(CombinationOperator combinationOperator, IEn var filter = new PredicationFilter(predication, context); return filter; } - - - public IResultSetFilter Instantiate(IRankingInfo rankingInfo, IEnumerable columns) - { - var groupingFactory = new GroupByFactory(); - var groupingArgs = new ColumnGroupByArgs(columns, Context.None); - var grouping = groupingFactory.Instantiate(groupingArgs); - - var rankingFactory = new RankingFactory(); - var ranking = rankingFactory.Instantiate(rankingInfo); - - return new GroupByFilter(ranking, grouping); - } } } diff --git a/NBi.NUnit/Builder/Helper/ResultSetSystemHelper.cs b/NBi.NUnit/Builder/Helper/ResultSetSystemHelper.cs index 4b75b1250..ecb3fd00b 100644 --- a/NBi.NUnit/Builder/Helper/ResultSetSystemHelper.cs +++ b/NBi.NUnit/Builder/Helper/ResultSetSystemHelper.cs @@ -35,6 +35,11 @@ using NBi.Core.ResultSet.Alteration.Lookup.Strategies.Missing; using NBi.Core.ResultSet.Alteration.Renaming.Strategies.Missing; using NBi.Core.ResultSet.Filtering; +using NBi.Core.Calculation.Grouping; +using NBi.Xml.Items.Calculation.Grouping; +using NBi.Core.Calculation.Grouping.ColumnBased; +using NBi.Core.Calculation.Grouping.CaseBased; +using NBi.Core.Calculation.Predication; namespace NBi.NUnit.Builder.Helper { @@ -125,11 +130,41 @@ private Alter InstantiateFilter(FilterXml filterXml) } else { - return factory.Instantiate( - filterXml.Ranking, - filterXml.Ranking?.GroupBy?.Columns - ).Apply; + var groupByArgs = BuildGroupByArgs(filterXml.Ranking.GroupBy, context); + var groupByFactory = new GroupByFactory(); + var groupBy = groupByFactory.Instantiate(groupByArgs); + + var rankingGroupByArgs = new RankingGroupByArgs(groupBy, filterXml.Ranking.Option, filterXml.Ranking.Count, filterXml.Ranking.Operand, filterXml.Ranking.Type); + return factory.Instantiate(rankingGroupByArgs, context).Apply; + } + } + + private IGroupByArgs BuildGroupByArgs(GroupByXml xml, Context context) + { + if (xml == null) + return new NoneGroupByArgs(); + if ((xml?.Columns?.Count ?? 0) > 0) + return new ColumnGroupByArgs(xml.Columns, context); + if ((xml?.Cases?.Count ?? 0) > 0) + { + var builder = new PredicateArgsBuilder(ServiceLocator, context); + var predications = new List(); + foreach (var caseXml in xml.Cases) + { + if (caseXml.Predication is SinglePredicationXml) + { + var predicationXml = (caseXml.Predication) as SinglePredicationXml; + var args = builder.Execute(predicationXml.ColumnType, predicationXml.Predicate); + var predicate = new PredicateFactory().Instantiate(args); + var predicationFactory = new PredicationFactory(); + predications.Add(predicationFactory.Instantiate(predicate, predicationXml.Operand)); + + } + } + + return new CaseGroupByArgs(predications, context); } + throw new ArgumentOutOfRangeException(); } private Alter InstantiateConvert(ConvertXml convertXml) diff --git a/NBi.NUnit/NBi.NUnit.csproj b/NBi.NUnit/NBi.NUnit.csproj index ee4cb991e..961256e54 100644 --- a/NBi.NUnit/NBi.NUnit.csproj +++ b/NBi.NUnit/NBi.NUnit.csproj @@ -189,7 +189,7 @@ NBi.Framework - {3A9822B3-CCE4-441B-9C3E-D52817A994CA} + {3a9822b3-cce4-441b-9c3e-d52817a994ca} NBi.Xml diff --git a/NBi.Testing.Xml/Constraints/AllRowsXmlTest.cs b/NBi.Testing.Xml/Constraints/AllRowsXmlTest.cs index 2f84924d7..f32ebc403 100644 --- a/NBi.Testing.Xml/Constraints/AllRowsXmlTest.cs +++ b/NBi.Testing.Xml/Constraints/AllRowsXmlTest.cs @@ -305,7 +305,7 @@ public void Serialize_AllRowsXml_OnlyAliasNoVariable() new AliasXml() {Column = 1, Name="Col1"}, new AliasXml() {Column = 0, Name="Col2"} }, - Predication = new PredicationXml() + Predication = new SinglePredicationXml() }; #pragma warning restore 0618 @@ -328,7 +328,7 @@ public void Serialize_AllRowsXml_AnyOfXml() { var allRowsXml = new AllRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new AnyOfXml() { @@ -423,7 +423,7 @@ public void Serialize_ExecutionAndAliasesXml_AliasesBeforeExecution() } }, - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Operand = new ColumnNameIdentifier("calculate"), ColumnType = ColumnType.Numeric, @@ -464,7 +464,7 @@ public void Serialize_UnspecifiedExpression_NoScript() } }, - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Operand = new ColumnNameIdentifier("calculate"), ColumnType = ColumnType.Numeric, @@ -503,7 +503,7 @@ public void Serialize_NCalcExpression_NoScript() } }, - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Operand = new ColumnNameIdentifier("calculate"), ColumnType = ColumnType.Numeric, @@ -542,7 +542,7 @@ public void Serialize_NativeExpression_ScriptIsAvailable() } }, - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Operand = new ColumnNameIdentifier("calculate"), ColumnType = ColumnType.Numeric, @@ -571,7 +571,7 @@ public void Serialize_NativeExpression_ScriptIsAvailable() [Test] public void Serialize_MatchesRegex_WithCDATA() { - var root = new PredicationXml() + var root = new SinglePredicationXml() { Predicate = new MatchesRegexXml { Reference = "<|>|&" } }; @@ -591,12 +591,12 @@ public void Serialize_MatchesRegex_WithCDATA() [Test] public void Deserialize_MatchesRegex_WithCDATA() { - var xml = "|&]]>"; + var xml = "|&]]>"; var manager = new XmlManager(); var overrides = new ReadOnlyAttributes(); overrides.Build(); - var objectData = manager.XmlDeserializeTo(xml, overrides); - Assert.That(objectData, Is.TypeOf()); + var objectData = manager.XmlDeserializeTo(xml, overrides); + Assert.That(objectData, Is.TypeOf()); Assert.That(objectData, Is.Not.Null); Assert.That(objectData.Predicate, Is.TypeOf()); var predicate = objectData.Predicate as MatchesRegexXml; @@ -607,12 +607,12 @@ public void Deserialize_MatchesRegex_WithCDATA() [Test] public void Deserialize_MatchesRegex_WithoutCDATA() { - var xml = "<|>|&"; + var xml = "<|>|&"; var manager = new XmlManager(); var overrides = new ReadOnlyAttributes(); overrides.Build(); - var objectData = manager.XmlDeserializeTo(xml, overrides); - Assert.That(objectData, Is.TypeOf()); + var objectData = manager.XmlDeserializeTo(xml, overrides); + Assert.That(objectData, Is.TypeOf()); Assert.That(objectData, Is.Not.Null); Assert.That(objectData.Predicate, Is.TypeOf()); var predicate = objectData.Predicate as MatchesRegexXml; @@ -623,7 +623,7 @@ public void Deserialize_MatchesRegex_WithoutCDATA() [Test] public void Serialize_Equal_WithoutCDATAButWithZero() { - var root = new PredicationXml() + var root = new SinglePredicationXml() { Predicate = new EqualXml() { Reference = "0" } }; @@ -641,12 +641,12 @@ public void Serialize_Equal_WithoutCDATAButWithZero() [Test] public void Deserialize_Equal_WithCDATA() { - var xml = "|&]]>"; + var xml = "|&]]>"; var manager = new XmlManager(); var overrides = new ReadOnlyAttributes(); overrides.Build(); - var objectData = manager.XmlDeserializeTo(xml, overrides); - Assert.That(objectData, Is.TypeOf()); + var objectData = manager.XmlDeserializeTo(xml, overrides); + Assert.That(objectData, Is.TypeOf()); Assert.That(objectData, Is.Not.Null); Assert.That(objectData.Predicate, Is.TypeOf()); var predicate = objectData.Predicate as EqualXml; @@ -657,12 +657,12 @@ public void Deserialize_Equal_WithCDATA() [Test] public void Deserialize_Equal_WithoutCDATA() { - var xml = "<|>|&"; + var xml = "<|>|&"; var manager = new XmlManager(); var overrides = new ReadOnlyAttributes(); overrides.Build(); - var objectData = manager.XmlDeserializeTo(xml, overrides); - Assert.That(objectData, Is.TypeOf()); + var objectData = manager.XmlDeserializeTo(xml, overrides); + Assert.That(objectData, Is.TypeOf()); Assert.That(objectData, Is.Not.Null); Assert.That(objectData.Predicate, Is.TypeOf()); var predicate = objectData.Predicate as EqualXml; diff --git a/NBi.Testing.Xml/Items/Calculation/PredicateXmlTest.cs b/NBi.Testing.Xml/Items/Calculation/PredicateXmlTest.cs index 6e73767cd..1eae4339a 100644 --- a/NBi.Testing.Xml/Items/Calculation/PredicateXmlTest.cs +++ b/NBi.Testing.Xml/Items/Calculation/PredicateXmlTest.cs @@ -66,7 +66,7 @@ public void Serialize_PredicateXml_OnlyOperandNoName() { var allRowsXml = new AllRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Operand = new ColumnOrdinalIdentifier(1), Predicate = new FalseXml() @@ -92,7 +92,7 @@ public void Serialize_ModuloXml_AllPredicateInfoCorrectlySerialized() { var allRowsXml = new AllRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Operand = new ColumnOrdinalIdentifier(1), Predicate = new ModuloXml() { SecondOperand = "10", Reference = "5" } diff --git a/NBi.Testing.Xml/Items/Calculation/RankingXmlTest.cs b/NBi.Testing.Xml/Items/Calculation/RankingXmlTest.cs index bbff15ede..368d08e26 100644 --- a/NBi.Testing.Xml/Items/Calculation/RankingXmlTest.cs +++ b/NBi.Testing.Xml/Items/Calculation/RankingXmlTest.cs @@ -198,5 +198,41 @@ public void Serialize_WithGroupBy_RankingXml() Assert.That(content, Does.Contain("bar")); Assert.That(content, Does.Not.Contain("text")); } + + [Test] + public void Deserialize_RankingWithCases_CaseGrouping() + { + int testNr = 2; + + // Create an instance of the XmlSerializer specifying type and namespace. + TestSuiteXml ts = DeserializeSample(); + + Assert.That(ts.Tests[testNr].Systems[0], Is.TypeOf()); + var alterations = (ts.Tests[testNr].Systems[0] as ResultSetSystemXml).Alterations; + var filter = alterations[0] as FilterXml; + Assert.That(filter, Is.Not.Null); + Assert.That(filter.Ranking.GroupBy, Is.Not.Null); + Assert.That(filter.Ranking.GroupBy.Cases, Is.Not.Null); + Assert.That(filter.Ranking.GroupBy.Cases.Count, Is.EqualTo(2)); + } + + [Test] + public void Deserialize_RankingWithCases_PredicateOrCombination() + { + int testNr = 2; + + // Create an instance of the XmlSerializer specifying type and namespace. + TestSuiteXml ts = DeserializeSample(); + + Assert.That(ts.Tests[testNr].Systems[0], Is.TypeOf()); + var alterations = (ts.Tests[testNr].Systems[0] as ResultSetSystemXml).Alterations; + var filter = alterations[0] as FilterXml; + Assert.That(filter, Is.Not.Null); + Assert.That(filter.Ranking.GroupBy.Cases[0].Predication, Is.Not.Null); + Assert.That(filter.Ranking.GroupBy.Cases[0].Predication, Is.TypeOf()); + Assert.That(filter.Ranking.GroupBy.Cases[1].Predication, Is.Not.Null); + Assert.That(filter.Ranking.GroupBy.Cases[1].Predication, Is.TypeOf()); + } + } } diff --git a/NBi.Testing.Xml/Resources/RankingXmlTestSuite.xml b/NBi.Testing.Xml/Resources/RankingXmlTestSuite.xml index 636f05090..c7ca3c59e 100644 --- a/NBi.Testing.Xml/Resources/RankingXmlTestSuite.xml +++ b/NBi.Testing.Xml/Resources/RankingXmlTestSuite.xml @@ -50,4 +50,44 @@ + + + + + select row_count as DeptId, [Name], [GroupName] from [HumanResources].[Department] order by Name + + + + + + + + + + + + + + + + + + 10 + + + + + + + + + + + + + 10 + + + + diff --git a/NBi.Testing/Acceptance/Resources/Positive/ResultSetConstraint.nbits b/NBi.Testing/Acceptance/Resources/Positive/ResultSetConstraint.nbits index 9543094bf..6d320c101 100644 --- a/NBi.Testing/Acceptance/Resources/Positive/ResultSetConstraint.nbits +++ b/NBi.Testing/Acceptance/Resources/Positive/ResultSetConstraint.nbits @@ -29,7 +29,7 @@ - + + --> + + + + + + + + + + + + CUST0003 + + + + + 100 + + + + + CUST0001 + + + + + + + + + + + + + + + + + CUST0001 + 80 + + + CUST0001 + 100 + + + CUST0002 + 80 + + + CUST0003 + 55 + + + + - + \ No newline at end of file diff --git a/NBi.Testing/Unit/NUnit/Builder/ResultSetAllRowsBuilderTest.cs b/NBi.Testing/Unit/NUnit/Builder/ResultSetAllRowsBuilderTest.cs index 6fc4cc474..de5d7cad4 100644 --- a/NBi.Testing/Unit/NUnit/Builder/ResultSetAllRowsBuilderTest.cs +++ b/NBi.Testing/Unit/NUnit/Builder/ResultSetAllRowsBuilderTest.cs @@ -67,7 +67,7 @@ public void GetConstraint_BuildWithResultSet_CorrectConstraint() var ctrXml = new AllRowsXml { - Predication = new PredicationXml() { + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "100" }, Operand = new ColumnOrdinalIdentifier(0) } @@ -96,7 +96,7 @@ public void GetConstraint_Build_DontEvaluateVariable() var ctrXml = new AllRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml { Reference = "@year" }, Operand = new ColumnOrdinalIdentifier(0) @@ -133,7 +133,7 @@ public void GetConstraint_BuildWithVariables_DontEvaluateThem() var ctrXml = new AllRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "@year" }, Operand = new ColumnOrdinalIdentifier(0) @@ -171,7 +171,7 @@ public void GetSystemUnderTest_ExecutionXml_IResultSetService() var ctrXml = new AllRowsXml() { - Predication = new PredicationXml() { + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "10" }, Operand = new ColumnOrdinalIdentifier(0) } @@ -195,7 +195,7 @@ public void GetSystemUnderTest_ResultSetSystemXml_IResultSetService() var ctrXml = new AllRowsXml() { - Predication = new PredicationXml() { + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "10" }, Operand = new ColumnOrdinalIdentifier(0) } diff --git a/NBi.Testing/Unit/NUnit/Builder/ResultSetRowCountBuilderTest.cs b/NBi.Testing/Unit/NUnit/Builder/ResultSetRowCountBuilderTest.cs index 151523cfe..b096a7580 100644 --- a/NBi.Testing/Unit/NUnit/Builder/ResultSetRowCountBuilderTest.cs +++ b/NBi.Testing/Unit/NUnit/Builder/ResultSetRowCountBuilderTest.cs @@ -95,7 +95,7 @@ public void GetConstraint_RowCountFiltered_CorrectConstraint() Filter = new FilterXml() }; ctrXml.Filter.InternalAliases.Add(new AliasXml()); - ctrXml.Filter.Predication = new PredicationXml() { Predicate = new NullXml(), Operand = new ColumnNameIdentifier("myColumn") }; + ctrXml.Filter.Predication = new SinglePredicationXml() { Predicate = new NullXml(), Operand = new ColumnNameIdentifier("myColumn") }; var builder = new ResultSetRowCountBuilder(); builder.Setup(sutXml, ctrXml, null, null, new ServiceLocator()); @@ -124,7 +124,7 @@ public void GetConstraint_PercentageForRowCount_CorrectConstraint() Filter = new FilterXml() { InternalAliases = new List() { new AliasXml()}, - Predication = new PredicationXml() { Predicate = new NullXml(), Operand = new ColumnNameIdentifier("myColumn") } + Predication = new SinglePredicationXml() { Predicate = new NullXml(), Operand = new ColumnNameIdentifier("myColumn") } } }; diff --git a/NBi.Testing/Unit/NUnit/Builder/ResultSetSingleRowBuilderTest.cs b/NBi.Testing/Unit/NUnit/Builder/ResultSetSingleRowBuilderTest.cs index 2fae9904a..4e6fda5e2 100644 --- a/NBi.Testing/Unit/NUnit/Builder/ResultSetSingleRowBuilderTest.cs +++ b/NBi.Testing/Unit/NUnit/Builder/ResultSetSingleRowBuilderTest.cs @@ -67,7 +67,7 @@ public void GetConstraint_BuildWithResultSet_CorrectConstraint() var ctrXml = new SingleRowXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "100" }, Operand = new ColumnOrdinalIdentifier(0) @@ -97,7 +97,7 @@ public void GetConstraint_Build_DontEvaluateVariable() var ctrXml = new SingleRowXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "@year" }, Operand = new ColumnOrdinalIdentifier(0) @@ -133,7 +133,7 @@ public void GetConstraint_BuildWithVariables_DontEvaluateThem() var ctrXml = new SingleRowXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "@year" }, Operand = new ColumnOrdinalIdentifier(0) @@ -171,7 +171,7 @@ public void GetSystemUnderTest_ExecutionXml_IResultSetService() var ctrXml = new SingleRowXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "100" }, Operand = new ColumnOrdinalIdentifier(0) @@ -196,7 +196,7 @@ public void GetSystemUnderTest_ResultSetSystemXml_IResultSetService() var ctrXml = new SingleRowXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "100" }, Operand = new ColumnOrdinalIdentifier(0) diff --git a/NBi.Testing/Unit/NUnit/Builder/ResultSetSomeRowsBuilderTest.cs b/NBi.Testing/Unit/NUnit/Builder/ResultSetSomeRowsBuilderTest.cs index e6d615927..fe70e578b 100644 --- a/NBi.Testing/Unit/NUnit/Builder/ResultSetSomeRowsBuilderTest.cs +++ b/NBi.Testing/Unit/NUnit/Builder/ResultSetSomeRowsBuilderTest.cs @@ -67,7 +67,7 @@ public void GetConstraint_BuildWithResultSet_CorrectConstraint() var ctrXml = new SomeRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "100" }, Operand = new ColumnOrdinalIdentifier(0) @@ -97,7 +97,7 @@ public void GetConstraint_Build_DontEvaluateVariable() var ctrXml = new SomeRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "@year" }, Operand = new ColumnOrdinalIdentifier(0) @@ -133,7 +133,7 @@ public void GetConstraint_BuildWithVariables_DontEvaluateThem() var ctrXml = new SomeRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "@year" }, Operand = new ColumnOrdinalIdentifier(0) @@ -171,7 +171,7 @@ public void GetSystemUnderTest_ExecutionXml_IResultSetService() var ctrXml = new SomeRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "100" }, Operand = new ColumnOrdinalIdentifier(0) @@ -196,7 +196,7 @@ public void GetSystemUnderTest_ResultSetSystemXml_IResultSetService() var ctrXml = new SomeRowsXml { - Predication = new PredicationXml() + Predication = new SinglePredicationXml() { Predicate = new MoreThanXml() { Reference = "100" }, Operand = new ColumnOrdinalIdentifier(0) diff --git a/NBi.Xml/Constraints/NoRowsXml.cs b/NBi.Xml/Constraints/NoRowsXml.cs index 1317aab6f..dfe21906a 100644 --- a/NBi.Xml/Constraints/NoRowsXml.cs +++ b/NBi.Xml/Constraints/NoRowsXml.cs @@ -46,10 +46,10 @@ public List InternalAliasesOld private List internalAliases; [XmlElement("predicate", Order = 4)] - public PredicationXml Predication { get; set; } + public SinglePredicationXml Predication { get; set; } [XmlElement("combination", Order = 5)] - public CombinationPredicateXml Combination { get; set; } + public CombinationPredicationXml Combination { get; set; } public NoRowsXml() { diff --git a/NBi.Xml/Items/AbstractPredicationXml.cs b/NBi.Xml/Items/AbstractPredicationXml.cs new file mode 100644 index 000000000..3b18ab0a7 --- /dev/null +++ b/NBi.Xml/Items/AbstractPredicationXml.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NBi.Xml.Items +{ + public abstract class AbstractPredicationXml + { } +} diff --git a/NBi.Xml/Items/Calculation/CombinationPredicateXml.cs b/NBi.Xml/Items/Calculation/CombinationPredicationXml.cs similarity index 81% rename from NBi.Xml/Items/Calculation/CombinationPredicateXml.cs rename to NBi.Xml/Items/Calculation/CombinationPredicationXml.cs index ce765da92..ea07fe541 100644 --- a/NBi.Xml/Items/Calculation/CombinationPredicateXml.cs +++ b/NBi.Xml/Items/Calculation/CombinationPredicationXml.cs @@ -12,7 +12,7 @@ namespace NBi.Xml.Items.Calculation { - public class CombinationPredicateXml + public class CombinationPredicationXml : AbstractPredicationXml { [XmlAttribute("operator")] public CombinationOperator Operator { get; set; } @@ -22,6 +22,6 @@ public class CombinationPredicateXml public bool Not { get; set; } [XmlElement("predicate")] - public List Predications { get; set; } + public List Predications { get; set; } } } diff --git a/NBi.Xml/Items/Calculation/FilterXml.cs b/NBi.Xml/Items/Calculation/FilterXml.cs index f6768f14a..51b8accc2 100644 --- a/NBi.Xml/Items/Calculation/FilterXml.cs +++ b/NBi.Xml/Items/Calculation/FilterXml.cs @@ -44,13 +44,13 @@ public List InternalAliasesOld public ExpressionXml Expression { get; set; } [XmlElement("predicate")] - public PredicationXml Predication { get; set; } + public SinglePredicationXml Predication { get; set; } [XmlElement("ranking")] public RankingXml Ranking { get; set; } [XmlElement("combination")] - public CombinationPredicateXml Combination { get; set; } + public CombinationPredicationXml Combination { get; set; } //[XmlElement("ranking")] //public RankingXml Ranking { get; set; } diff --git a/NBi.Xml/Items/Calculation/Grouping/CaseXml.cs b/NBi.Xml/Items/Calculation/Grouping/CaseXml.cs new file mode 100644 index 000000000..b3914c583 --- /dev/null +++ b/NBi.Xml/Items/Calculation/Grouping/CaseXml.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace NBi.Xml.Items.Calculation.Grouping +{ + public class CaseXml + { + [XmlElement(Type = typeof(SinglePredicationXml), ElementName = "predicate"), + XmlElement(Type = typeof(CombinationPredicationXml), ElementName = "combination"),] + public AbstractPredicationXml Predication { get; set; } + } +} diff --git a/NBi.Xml/Items/Calculation/Grouping/GroupByxml.cs b/NBi.Xml/Items/Calculation/Grouping/GroupByxml.cs index 41ccd2213..068f64bea 100644 --- a/NBi.Xml/Items/Calculation/Grouping/GroupByxml.cs +++ b/NBi.Xml/Items/Calculation/Grouping/GroupByxml.cs @@ -13,6 +13,9 @@ public class GroupByXml { [XmlElement("column")] public List Columns { get; set; } = new List(); + + [XmlElement("case")] + public List Cases { get; set; } public static GroupByXml None { get; } = new GroupByNone(); diff --git a/NBi.Xml/Items/Calculation/PredicationXml.cs b/NBi.Xml/Items/Calculation/SinglePredicationXml.cs similarity index 96% rename from NBi.Xml/Items/Calculation/PredicationXml.cs rename to NBi.Xml/Items/Calculation/SinglePredicationXml.cs index 66122b4e4..c9969af79 100644 --- a/NBi.Xml/Items/Calculation/PredicationXml.cs +++ b/NBi.Xml/Items/Calculation/SinglePredicationXml.cs @@ -13,7 +13,7 @@ namespace NBi.Xml.Items.Calculation { - public class PredicationXml : BasePredicationXml + public class SinglePredicationXml : BasePredicationXml { [XmlIgnore()] [XmlAttribute("column-index")] @@ -41,7 +41,7 @@ public string OperandSerialized } - public abstract class BasePredicationXml + public abstract class BasePredicationXml : AbstractPredicationXml { public BasePredicationXml() { diff --git a/NBi.Xml/NBi.Xml.csproj b/NBi.Xml/NBi.Xml.csproj index 156259326..2d3384c94 100644 --- a/NBi.Xml/NBi.Xml.csproj +++ b/NBi.Xml/NBi.Xml.csproj @@ -150,6 +150,7 @@ + @@ -180,7 +181,8 @@ - + + @@ -266,7 +268,7 @@ - + diff --git a/NBi.Xml/Schema/BaseType.xsd b/NBi.Xml/Schema/BaseType.xsd index 24db9a51e..51a4e7bb8 100644 --- a/NBi.Xml/Schema/BaseType.xsd +++ b/NBi.Xml/Schema/BaseType.xsd @@ -1453,9 +1453,20 @@ - - - + + + + + + + + + + + + + + diff --git a/NBi.Xml/SerializationOption/ReadOnlyAttributes.cs b/NBi.Xml/SerializationOption/ReadOnlyAttributes.cs index f47910e5a..1c348d85e 100644 --- a/NBi.Xml/SerializationOption/ReadOnlyAttributes.cs +++ b/NBi.Xml/SerializationOption/ReadOnlyAttributes.cs @@ -33,7 +33,7 @@ protected override void AdditionalBuild() AddAsAttribute((ConnectionWaitXml c) => c.SpecificConnectionStringOld, "connectionString"); AddAsAttribute((DataManipulationAbstractXml x) => x.SpecificConnectionStringOld, "connectionString"); AddAsAttribute((SqlRunXml x) => x.SpecificConnectionStringOld, "connectionString"); - AddAsAttribute((PredicationXml p) => p.Name, "name"); + AddAsAttribute((SinglePredicationXml p) => p.Name, "name"); AddAsAttribute((ResultSetSystemXml r) => r.FilePath, "file"); AddAsElement((NoRowsXml c) => c.InternalAliasesOld, "variable", 2); @@ -44,7 +44,7 @@ protected override void AdditionalBuild() AddAsText((FileXml x) => x.Value); - AddToElements((PredicationXml p) => p.Predicate, "within-list", typeof(WithinListXml)); + AddToElements((SinglePredicationXml p) => p.Predicate, "within-list", typeof(WithinListXml)); AddToElements((ProjectionOldXml x) => x.ResultSetOld, "resultSet", typeof(ResultSetSystemXml)); AddToElements((LookupExistsXml x) => x.ResultSetOld, "resultSet", typeof(ResultSetSystemXml));