private SortOrder GetSortOrder(MapiTable table, SortBy[] sortColumns, GroupByAndOrder[] groupBy, int expandCount, ref List <PropTag> alteredProperties) { if ((sortColumns == null || sortColumns.Length == 0) && (groupBy == null || groupBy.Length == 0)) { return(null); } SortOrder sortOrder = new SortOrder(); if (groupBy != null) { for (int i = 0; i < groupBy.Length; i++) { NativeStorePropertyDefinition nativeGroupBy = InternalSchema.ToStorePropertyDefinition(groupBy[i].GroupByColumn).GetNativeGroupBy(); PropTag sortPropertyTag = this.GetSortPropertyTag(nativeGroupBy, ref alteredProperties); GroupSort nativeGroupSort = InternalSchema.ToStorePropertyDefinition(groupBy[i].GroupSortColumn.ColumnDefinition).GetNativeGroupSort(groupBy[i].GroupSortColumn.SortOrder, groupBy[i].GroupSortColumn.Aggregate); PropTag sortPropertyTag2 = this.GetSortPropertyTag((NativeStorePropertyDefinition)nativeGroupSort.ColumnDefinition, ref alteredProperties); SortFlags sortFlag; switch (nativeGroupSort.Aggregate) { case Aggregate.Min: sortFlag = SortFlags.CategoryMin; break; case Aggregate.Max: sortFlag = SortFlags.CategoryMax; break; default: throw new ArgumentOutOfRangeException("groupBy", nativeGroupSort.Aggregate, ServerStrings.ExInvalidAggregate); } sortOrder.AddCategory(sortPropertyTag, QueryExecutor.SortOrderToSortFlags(nativeGroupSort.SortOrder)); if (sortPropertyTag != sortPropertyTag2) { sortOrder.Add(sortPropertyTag2, sortFlag); } } sortOrder.ExpandCount = expandCount; } if (sortOrder.GetSortCount() > 4) { throw new ArgumentException(ServerStrings.ExTooComplexGroupSortParameter, "groupBy"); } if (sortColumns != null && sortColumns.Length > 0) { SortBy[] nativeSortBy = QueryExecutor.GetNativeSortBy(sortColumns); if (nativeSortBy.Length + sortOrder.GetSortCount() > 6) { throw new ArgumentOutOfRangeException("sortColumns", ServerStrings.ExTooManySortColumns); } for (int j = 0; j < nativeSortBy.Length; j++) { PropertyDefinition columnDefinition = nativeSortBy[j].ColumnDefinition; PropTag sortPropertyTag3 = this.GetSortPropertyTag((NativeStorePropertyDefinition)columnDefinition, ref alteredProperties); sortOrder.Add(sortPropertyTag3, QueryExecutor.SortOrderToSortFlags(nativeSortBy[j].SortOrder)); } } return(sortOrder); }
/// <summary>Adds a sort expression for the query</summary> /// <param name="sortExpression">The sort expression.</param> /// <param name="direction">The direction.</param> /// <typeparam name="T2">The type</typeparam> public IQueryFilter <T> AddSort <T2>( Expression <Func <T, T2> > sortExpression, SortDirection direction = SortDirection.Ascending) { SortOrder.Add(new Tuple <Expression, SortDirection>(sortExpression, direction)); return(this); }
protected override void ProcessJobs(MapiStore systemMbx, MapiTable contentsTable, RequestJobNamedPropertySet nps) { SortOrder sortOrder = new SortOrder(nps.PropTags[17], SortFlags.Descend); sortOrder.Add(nps.PropTags[7], SortFlags.Ascend); MrsTracer.Service.Debug("Searching for MRs to Rehome...", new object[0]); Restriction restriction = Restriction.And(new Restriction[] { Restriction.EQ(nps.PropTags[4], false), Restriction.EQ(nps.PropTags[20], true) }); MrsTracer.Service.Debug("Searching for MRs to Suspend...", new object[0]); base.ProcessJobsInBatches(restriction, false, sortOrder, contentsTable, systemMbx, null); Restriction restriction2 = Restriction.And(new Restriction[] { Restriction.BitMaskNonZero(nps.PropTags[10], 256), Restriction.EQ(nps.PropTags[4], false), Restriction.EQ(nps.PropTags[20], false), Restriction.NE(nps.PropTags[0], RequestStatus.Failed), Restriction.NE(nps.PropTags[0], RequestStatus.Suspended), Restriction.NE(nps.PropTags[0], RequestStatus.AutoSuspended), Restriction.NE(nps.PropTags[0], RequestStatus.Completed), Restriction.NE(nps.PropTags[0], RequestStatus.CompletedWithWarning) }); base.ProcessJobsInBatches(restriction2, false, sortOrder, contentsTable, systemMbx, null); MrsTracer.Service.Debug("Searching for MRs to Resume...", new object[0]); Restriction restriction3 = Restriction.And(new Restriction[] { Restriction.BitMaskZero(nps.PropTags[10], 256), Restriction.EQ(nps.PropTags[4], false), Restriction.EQ(nps.PropTags[20], false), Restriction.Or(new Restriction[] { Restriction.EQ(nps.PropTags[0], RequestStatus.Failed), Restriction.EQ(nps.PropTags[0], RequestStatus.Suspended), Restriction.EQ(nps.PropTags[0], RequestStatus.AutoSuspended) }) }); base.ProcessJobsInBatches(restriction3, false, sortOrder, contentsTable, systemMbx, null); SortOrder sort = new SortOrder(nps.PropTags[13], SortFlags.Ascend); DateTime utcNow = DateTime.UtcNow; MrsTracer.Service.Debug("Searching for Completed MRs to clean up...", new object[0]); Restriction restriction4 = Restriction.And(new Restriction[] { Restriction.EQ(nps.PropTags[20], false), Restriction.EQ(nps.PropTags[4], false), Restriction.EQ(nps.PropTags[0], RequestStatus.Completed), Restriction.NE(nps.PropTags[13], SystemMailboxLightJobs.defaultDoNotPickUntil) }); base.ProcessJobsInBatches(restriction4, false, sort, contentsTable, systemMbx, (MoveJob moveJob) => moveJob.DoNotPickUntilTimestamp > utcNow); }
protected override void ProcessJobs(MapiStore systemMbx, MapiTable contentsTable, RequestJobNamedPropertySet nps) { MrsTracer.Service.Debug("Initializing searches...", new object[0]); SortOrder sortOrder = new SortOrder(nps.PropTags[17], SortFlags.Descend); sortOrder.Add(nps.PropTags[7], SortFlags.Ascend); Restriction restriction = Restriction.And(new Restriction[] { Restriction.EQ(nps.PropTags[4], true), Restriction.EQ(nps.PropTags[20], false) }); Restriction restriction2 = Restriction.And(new Restriction[] { Restriction.BitMaskZero(nps.PropTags[10], 256), Restriction.EQ(nps.PropTags[4], false), Restriction.EQ(nps.PropTags[20], false), Restriction.Or(new Restriction[] { Restriction.EQ(nps.PropTags[0], RequestStatus.Queued), Restriction.EQ(nps.PropTags[0], RequestStatus.InProgress), Restriction.EQ(nps.PropTags[0], RequestStatus.CompletionInProgress) }) }); base.ProcessJobsInBatches(Restriction.Or(new Restriction[] { restriction2, restriction }), true, sortOrder, contentsTable, systemMbx, null); Restriction restriction3 = Restriction.And(new Restriction[] { Restriction.BitMaskZero(nps.PropTags[10], 256), Restriction.EQ(nps.PropTags[4], false), Restriction.EQ(nps.PropTags[20], false), Restriction.EQ(nps.PropTags[0], RequestStatus.Synced) }); SortOrder sort = new SortOrder(nps.PropTags[13], SortFlags.Ascend); DateTime utcNow = DateTime.UtcNow; base.ProcessJobsInBatches(restriction3, false, sort, contentsTable, systemMbx, (MoveJob moveJob) => moveJob.DoNotPickUntilTimestamp > utcNow); }
/// <summary> /// Runs <c>rtvs:::grid_data</c> for <paramref name="expression"/>, and validates that /// returned data matches expectations. /// </summary> /// <param name="expression">Expression to produce a data structure to retrieve grid data from.</param> /// <param name="firstRow">First row which should be retrieved; 1-based (as in R).</param> /// <param name="firstColumn">First column that should be retrieved; 1-based (as in R).</param> /// <param name="expected"> /// Expected values. This is a 2D array of strings. /// Element at <c>[0, 0]</c> must be <see langword="null"/>. /// Elements at <c>[0, 1]</c>, <c>[0, 2]</c> etc specify expected column names. /// Elements at <c>[1, 0]</c>, <c>[2, 0]</c> etc specify expected row names. /// All other elements specify expected values in the corresponding grid cells. /// </param> /// <param name="sort"> /// Indices of columns that the data should be sorted on; 1-based (as in R). /// A positive value indicates that the corresponding column should be sorted in ascending order. /// A negative value indicates that the corresponding column should be sorted in descending order. /// If <see langword="null"/>, no sorting is done. /// </param> /// <remarks> /// <para> /// The number of rows and columns that are fetched is the same as the number of elements /// in <paramref name="expected"/>, not counting the row and column headers. For example, /// if <paramref name="expected"/> is a 3x4 array, a 2x3 slice is fetched, with the top left /// corner specified by <paramref name="firstRow"/> and <paramref name="firstColumnt"/>. /// </para> /// <para> /// <c>rtvs:::grid_data</c> sorts the entire dataset first, and only then slices it. /// </para> /// <remarks> private async Task Test( string expression, int firstRow, int firstColumn, string[,] expected, int[] sort = null ) { int height = expected.GetUpperBound(0) + 1; int width = expected.GetUpperBound(1) + 1; height.Should().BeGreaterOrEqualTo(1); width.Should().BeGreaterOrEqualTo(1); expected[0, 0].Should().BeNull(); var expectedRowHeaders = new List <string>(); for (int y = 1; y < height; ++y) { expectedRowHeaders.Add(expected[y, 0]); } var expectedColumnHeaders = new List <string>(); for (int x = 1; x < width; ++x) { expectedColumnHeaders.Add(expected[0, x]); } var expectedValues = new string[height - 1, width - 1]; for (int y = 1; y < height; ++y) { for (int x = 1; x < width; ++x) { expectedValues[y - 1, x - 1] = expected[y, x]; } } var range = new GridRange( new Range(firstRow - 1, expectedRowHeaders.Count), new Range(firstColumn - 1, expectedColumnHeaders.Count)); SortOrder order = null; if (sort != null) { order = new SortOrder(); foreach (var x in sort) { order.Add(new ColumnSortOrder(Math.Abs(x) - 1, x < 0)); } } var data = await GridDataSource.GetGridDataAsync(_session, expression, range, order); ToEnumerable(data.RowHeader).Should().Equal(expectedRowHeaders); ToEnumerable(data.ColumnHeader).Should().Equal(expectedColumnHeaders); data.Grid.Range.Rows.Count.Should().Be(expectedRowHeaders.Count); data.Grid.Range.Columns.Count.Should().Be(expectedColumnHeaders.Count); ShouldEqual(data.Grid, expectedValues); }