/// <summary>
        /// Returns an <see cref="List{TEntity}"/> based on a custom <paramref name="filterFunc"/> applied to the query, as well as
        /// optional <paramref name="expand"/> and <paramref name="select"/> arguments, checking the user's READ permissions along the way.
        /// </summary>
        /// <param name="filterFunc">Allows any kind of filtering on the query</param>
        /// <param name="expand">Optional expand argument.</param>
        /// <param name="select">Optional select argument.</param>
        /// <param name="orderby">Optional orderby argument.</param>
        /// <param name="permissionsFilter">Optional filter argument, if null is passed the query uses the read permissions filter of the current user.</param>
        /// <param name="cancellation">The cancellation instruction.</param>
        protected async Task <List <TEntity> > GetEntitiesByCustomQuery(
            Func <EntityQuery <TEntity>, EntityQuery <TEntity> > filterFunc,
            ExpressionExpand expand,
            ExpressionSelect select,
            ExpressionOrderBy orderby,
            ExpressionFilter permissionsFilter,
            CancellationToken cancellation)
        {
            // Prepare a query of the result, and clone it
            var factory = QueryFactory();
            var query   = factory.EntityQuery <TEntity>();

            // Apply custom filter function
            query = filterFunc(query);

            // Apply read permissions
            permissionsFilter ??= await UserPermissionsFilter(PermissionActions.Read, cancellation);

            query = query.Filter(permissionsFilter);

            // Expand, Select and Order the result as specified in the Queryex agruments
            var expandedQuery = query.Expand(expand).Select(select).OrderBy(orderby ?? ExpressionOrderBy.Parse("Id")); // Required

            // Load the result into memory
            var data = await expandedQuery.ToListAsync(QueryContext(), cancellation); // this is potentially unordered, should that be a concern?

            // Return
            return(data);
        }
Example #2
0
        /// <summary>
        /// Returns an <see cref="List{TEntity}"/> based on a custom filtering function applied to the query, as well as
        /// optional select and expand arguments, checking the user READ permissions along the way
        /// </summary>
        /// <param name="filterFunc">Allows any kind of filtering on the query</param>
        /// <param name="expand">Optional expand argument</param>
        /// <param name="select">Optional select argument</param>
        /// <param name="orderby">Optional select argument</param>
        /// <param name="permissionsFilter">Optional filter argument, if null is passed the q</param>
        /// <param name="cancellation">Optional select argument</param>
        protected async Task <List <TEntity> > GetEntitiesByCustomQuery(
            Func <Query <TEntity>, Query <TEntity> > filterFunc,
            ExpressionExpand expand,
            ExpressionSelect select,
            ExpressionOrderBy orderby,
            ExpressionFilter permissionsFilter,
            CancellationToken cancellation)
        {
            // Prepare a query of the result, and clone it
            var repo  = GetRepository();
            var query = repo.Query <TEntity>();

            // Apply custom filter function
            query = filterFunc(query);

            // Apply read permissions
            permissionsFilter ??= await UserPermissionsFilter(Constants.Read, cancellation);

            query = query.Filter(permissionsFilter);

            // Expand, Select and Order the result as specified in the OData agruments
            var expandedQuery = query.Expand(expand).Select(select).OrderBy(orderby ?? ExpressionOrderBy.Parse("Id")); // Required

            // Load the result into memory
            var data = await expandedQuery.ToListAsync(cancellation); // this is potentially unordered, should that be a concern?

            // TODO: This is slow and unused
            // Apply the permission masks (setting restricted fields to null) and adjust the metadata accordingly
            // await ApplyReadPermissionsMask(data, query, permissions, GetDefaultMask(), cancellation);

            // Return
            return(data);
        }
Example #3
0
        /// <summary>
        /// Returns a list of dynamic rows and optionally their count as per the specifications in <paramref name="args"/>.
        /// </summary>
        public virtual async Task <FactResult> GetFact(FactArguments args, CancellationToken cancellation)
        {
            await Initialize(cancellation);

            // Parse the parameters
            var filter  = ExpressionFilter.Parse(args.Filter);
            var orderby = ExpressionOrderBy.Parse(args.OrderBy);
            var select  = ExpressionFactSelect.Parse(args.Select);

            // Prepare the query
            var query = QueryFactory().FactQuery <TEntity>();

            // Apply read permissions
            var permissionsFilter = await UserPermissionsFilter(PermissionActions.Read, cancellation);

            query = query.Filter(permissionsFilter);

            // Apply filter
            query = query.Filter(filter);

            // Apply orderby
            orderby ??= await DefaultOrderBy(cancellation);

            query = query.OrderBy(orderby);

            // Apply the paging (Protect against DOS attacks by enforcing a maximum page size)
            var top  = args.Top;
            var skip = args.Skip;

            top   = Math.Min(top, MaximumPageSize());
            query = query.Skip(skip).Top(top);

            // Apply the select
            query = query.Select(select);

            // Load the data and count in memory
            List <DynamicRow> data;
            int?count = null;

            if (args.CountEntities)
            {
                (data, count) = await query.ToListAndCountAsync(MaximumCount, QueryContext, cancellation);
            }
            else
            {
                data = await query.ToListAsync(QueryContext, cancellation);
            }

            // Return
            return(new FactResult(data, count));
        }
Example #4
0
        /// <summary>
        /// Returns a list of entities as per the specifications in the <see cref="GetChildrenArguments{TKey}"/>
        /// </summary>
        public virtual async Task <(List <TEntity>, Extras)> GetChildrenOf(GetChildrenArguments <TKey> args, CancellationToken cancellation)
        {
            // Parse the parameters
            var expand  = ExpressionExpand.Parse(args.Expand);
            var select  = ParseSelect(args.Select);
            var filter  = ExpressionFilter.Parse(args.Filter);
            var orderby = ExpressionOrderBy.Parse("Node");
            var ids     = args.I ?? new List <TKey>();

            // Load the data
            var data = await GetEntitiesByCustomQuery(q => q.FilterByParentIds(ids, args.Roots).Filter(filter), expand, select, orderby, null, cancellation);

            var extras = await GetExtras(data, cancellation);

            // Transform and Return
            return(data, extras);
        }
Example #5
0
        protected override ExpressionOrderBy DefaultOrderBy()
        {
            // By default: Order currencies by name
            var    tenantInfo   = _repo.GetTenantInfo();
            string nameProperty = nameof(Currency.Name);

            if (tenantInfo.SecondaryLanguageId == CultureInfo.CurrentUICulture.Name)
            {
                nameProperty = $"{nameof(Currency.Name2)},{nameof(Currency.Name)}";
            }
            else if (tenantInfo.TernaryLanguageId == CultureInfo.CurrentUICulture.Name)
            {
                nameProperty = $"{nameof(Currency.Name3)},{nameof(Currency.Name)}";
            }

            return(ExpressionOrderBy.Parse(nameProperty));
        }
Example #6
0
        private void ResolveColumnRefernecesInUnionOrderBy()
        {
            int orderLength = this.ExprSortAndSlice.GetOrderLength();

            if (orderLength != 0)
            {
                string[] columnNames = this.GetColumnNames();
                int      num2        = 0;
                while (num2 < orderLength)
                {
                    ExpressionOrderBy by       = this.ExprSortAndSlice.ExprList[num2];
                    Expression        leftNode = by.GetLeftNode();
                    if (leftNode.GetExprType() == 1)
                    {
                        if (leftNode.GetDataType().TypeCode != 4)
                        {
                            goto Label_00B0;
                        }
                        int num3 = Convert.ToInt32(leftNode.GetValue(null));
                        if ((0 >= num3) || (num3 > columnNames.Length))
                        {
                            goto Label_00B0;
                        }
                        by.GetLeftNode().QueryTableColumnIndex = num3 - 1;
                    }
                    else
                    {
                        if (leftNode.GetExprType() != 2)
                        {
                            goto Label_00B0;
                        }
                        int num4 = ArrayUtil.Find(columnNames, leftNode.GetColumnName());
                        if (num4 < 0)
                        {
                            goto Label_00B0;
                        }
                        by.GetLeftNode().QueryTableColumnIndex = num4;
                    }
                    num2++;
                    continue;
Label_00B0:
                    throw Error.GetError(0x15c8);
                }
                this.ExprSortAndSlice.Prepare(null);
            }
        }
Example #7
0
        protected override ExpressionOrderBy DefaultOrderBy()
        {
            // By default: Order dashboard definitions by name
            var    tenantInfo = _repo.GetTenantInfo();
            string orderby    = $"{nameof(DashboardDefinition.Title)},{nameof(DashboardDefinition.Id)}";

            if (tenantInfo.SecondaryLanguageId == CultureInfo.CurrentUICulture.Name)
            {
                orderby = $"{nameof(DashboardDefinition.Title2)},{nameof(DashboardDefinition.Title)},{nameof(DashboardDefinition.Id)}";
            }
            else if (tenantInfo.TernaryLanguageId == CultureInfo.CurrentUICulture.Name)
            {
                orderby = $"{nameof(DashboardDefinition.Title3)},{nameof(DashboardDefinition.Title)},{nameof(DashboardDefinition.Id)}";
            }

            return(ExpressionOrderBy.Parse(orderby));
        }
        protected override async Task <ExpressionOrderBy> DefaultOrderBy(CancellationToken cancellation)
        {
            // By default: Order dashboard definitions by title
            var settings = await _behavior.Settings(cancellation);

            string orderby = $"{nameof(DashboardDefinition.Title)},{nameof(DashboardDefinition.Id)}";

            if (settings.SecondaryLanguageId == CultureInfo.CurrentUICulture.Name)
            {
                orderby = $"{nameof(DashboardDefinition.Title2)},{nameof(DashboardDefinition.Title)},{nameof(DashboardDefinition.Id)}";
            }
            else if (settings.TernaryLanguageId == CultureInfo.CurrentUICulture.Name)
            {
                orderby = $"{nameof(DashboardDefinition.Title3)},{nameof(DashboardDefinition.Title)},{nameof(DashboardDefinition.Id)}";
            }

            return(ExpressionOrderBy.Parse(orderby));
        }
Example #9
0
 public void Prepare(QuerySpecification select)
 {
     this.ColumnCount = this.ExprList.Count;
     if (this.ColumnCount != 0)
     {
         this.SortOrder      = new int[this.ColumnCount];
         this.SortDescending = new bool[this.ColumnCount];
         this.SortNullsLast  = new bool[this.ColumnCount];
         for (int i = 0; i < this.ColumnCount; i++)
         {
             ExpressionOrderBy by = this.ExprList[i];
             if (by.GetLeftNode().QueryTableColumnIndex == -1)
             {
                 this.SortOrder[i] = select.IndexStartOrderBy + i;
             }
             else
             {
                 this.SortOrder[i] = by.GetLeftNode().QueryTableColumnIndex;
             }
             this.SortDescending[i] = by.IsDescending();
             this.SortNullsLast[i]  = by.IsNullsLast();
             this.HasNullsLast     |= this.SortNullsLast[i];
         }
         if (((select != null) && !this.HasNullsLast) && (!select.IsDistinctSelect && !(select.IsGrouped | select.IsAggregated)))
         {
             int[] numArray = new int[this.ColumnCount];
             for (int j = 0; j < this.ColumnCount; j++)
             {
                 Expression leftNode = this.ExprList[j].GetLeftNode();
                 if (leftNode.GetExprType() != 2)
                 {
                     return;
                 }
                 if (leftNode.GetRangeVariable() != select.RangeVariables[0])
                 {
                     return;
                 }
                 numArray[j] = leftNode.ColumnIndex;
             }
             this._columnIndexes = numArray;
         }
     }
 }
Example #10
0
 public void AddOrderExpression(ExpressionOrderBy e)
 {
     this.ExprList.Add(e);
 }
Example #11
0
 protected override ExpressionOrderBy DefaultOrderBy()
 {
     return(ExpressionOrderBy.Parse(nameof(Account.Code)));
 }
 protected override Task <ExpressionOrderBy> DefaultOrderBy(CancellationToken _)
 {
     return(Task.FromResult(ExpressionOrderBy.Parse("Id desc")));
 }
Example #13
0
 protected override ExpressionOrderBy DefaultOrderBy()
 {
     return(ExpressionOrderBy.Parse(nameof(ExchangeRate.ValidAsOf) + " desc"));
 }
Example #14
0
        /// <summary>
        /// Returns a list of entities and optionally their count as per the specifications in <paramref name="args"/>.
        /// </summary>
        public virtual async Task <TEntitiesResult> GetEntities(GetArguments args, CancellationToken cancellation)
        {
            await Initialize(cancellation);

            // Parse the parameters
            var filter  = ExpressionFilter.Parse(args.Filter);
            var orderby = ExpressionOrderBy.Parse(args.OrderBy);
            var expand  = ExpressionExpand.Parse(args.Expand);
            var select  = ParseSelect(args.Select);

            // Prepare the query
            var query = QueryFactory().EntityQuery <TEntity>();

            // Apply read permissions
            var permissionsFilter = await UserPermissionsFilter(PermissionActions.Read, cancellation);

            query = query.Filter(permissionsFilter);

            // Apply search
            query = await Search(query, args, cancellation);

            // Apply filter
            query = query.Filter(filter);

            // Apply orderby
            orderby ??= await DefaultOrderBy(cancellation);

            query = query.OrderBy(orderby);

            // Apply the paging (Protect against DOS attacks by enforcing a maximum page size)
            var top  = args.Top;
            var skip = args.Skip;

            top   = Math.Min(top, MaximumPageSize());
            query = query.Skip(skip).Top(top);

            // Apply the expand, which has the general format 'Expand=A,B.C,D'
            query = query.Expand(expand);

            // Apply the select, which has the general format 'Select=A,B.C,D'
            query = query.Select(select);

            // Load the data and count in memory
            List <TEntity> data;
            int?           count = null;

            if (args.CountEntities)
            {
                var output = await query.ToListAndCountAsync(MaximumCount, QueryContext, cancellation);

                data  = output.Entities;
                count = output.Count;
            }
            else
            {
                data = await query.ToListAsync(QueryContext, cancellation);
            }

            // Return
            return(await ToEntitiesResult(data, count, cancellation));
        }
Example #15
0
        protected override Task <ExpressionOrderBy> DefaultOrderBy(CancellationToken _)
        {
            var result = ExpressionOrderBy.Parse(nameof(PrintingTemplate.Name));

            return(Task.FromResult(result));
        }
Example #16
0
        protected override Task <ExpressionOrderBy> DefaultOrderBy(CancellationToken _)
        {
            var result = ExpressionOrderBy.Parse("CreatedAt desc");

            return(Task.FromResult(result));
        }
Example #17
0
        protected override Task <ExpressionOrderBy> DefaultOrderBy(CancellationToken _)
        {
            var result = ExpressionOrderBy.Parse(nameof(ExchangeRate.ValidAsOf) + " desc");

            return(Task.FromResult(result));
        }
Example #18
0
        protected override Task <ExpressionOrderBy> DefaultOrderBy(CancellationToken _)
        {
            var result = ExpressionOrderBy.Parse(nameof(DetailsEntry.AccountId));

            return(Task.FromResult(result));
        }
Example #19
0
 protected override ExpressionOrderBy DefaultOrderBy()
 {
     return(ExpressionOrderBy.Parse("Id desc"));
 }
Example #20
0
 protected override ExpressionOrderBy DefaultOrderBy()
 {
     return(ExpressionOrderBy.Parse(nameof(DetailsEntry.AccountId)));
 }