예제 #1
0
        private static void DistinctTest(Table table, string column, string where)
        {
            int iterations = 1000;

            DistinctQuery  query  = new DistinctQuery(column, where, 100);
            DistinctResult result = null;

            Trace.Write("Aggregating Bugs...");

            for (int i = 0; i < iterations; ++i)
            {
                result = table.Query(query);
            }

            ShowResult(result.Values);
        }
예제 #2
0
        public void ITable_Distinct(Func <ITable> factoryMethod)
        {
            // Define columns and add sample data
            ITable table = factoryMethod();

            AddSampleData(table);

            // Get Distinct Priority for all bugs, verify three (0, 1, 3)
            DistinctQuery  query  = new DistinctQuery("Priority", "", 5);
            DistinctResult result = table.Query(query);

            // sort the results because order is not garenteed by distinct query
            Array values = result.Values.GetColumn(0);

            Array.Sort(values);

            Assert.AreEqual("0, 1, 3", values.Join(", "));
            Assert.IsTrue(result.AllValuesReturned);

            // Verify the result converts to a dimension properly
            AggregationDimension dimension = result.ToAggregationDimension();

            Assert.AreEqual("Query [[Priority] = 0,[Priority] = 1,[Priority] = 3]", dimension.ToString());

            // Verify distinct priority where priority is not 1 has only two values
            query.Where = QueryParser.Parse("Priority != 1");
            result      = table.Query(query);

            // sort the results because order is not garenteed by distinct query
            values = result.Values.GetColumn(0);
            Array.Sort(values);

            Assert.AreEqual("0, 3", result.Values.GetColumn(0).Join(", "));
            Assert.IsTrue(result.AllValuesReturned);

            // Verify if we only ask for one value, query reports more values left
            query.Count = 1;
            result      = table.Query(query);

            // either value could come back, it's a race to whichever partition completes first
            Assert.IsTrue(
                ("0" == result.Values.GetColumn(0).Join(", ")) ||
                ("3" == result.Values.GetColumn(0).Join(", ")));

            Assert.IsFalse(result.AllValuesReturned);
        }
예제 #3
0
        protected void ApplyTableSecurity <T>(IQuery <T> query, Func <SecurityIdentity, bool> isCurrentUserIn, ExecutionDetails details)
        {
            SecurityPermissions security = this.Security(query.TableName);

            // If table has row restrictions and one matches, restrict rows and allow
            // NOTE: If restricted rows are returned, columns are NOT restricted.
            foreach (var rowRestriction in security.RowRestrictedUsers)
            {
                if (isCurrentUserIn(rowRestriction.Key))
                {
                    query.Where = new AndExpression(QueryParser.Parse(rowRestriction.Value), query.Where);
                    return;
                }
            }

            // If table has column restrictions, build a list of excluded columns
            IList <string> restrictedColumns = GetRestrictedColumns(query.TableName, isCurrentUserIn);

            // If no columns were restricted, return query as-is
            if (restrictedColumns == null)
            {
                return;
            }

            // Exclude disallowed columns from where clauses
            // If a disallowed column is requested specifically, block the query and return an error
            ColumnSecurityCorrector c = new ColumnSecurityCorrector(restrictedColumns);

            try
            {
                query.Correct(c);
            }
            catch (ArribaColumnAccessDeniedException e)
            {
                query.Where = new EmptyExpression();
                details.AddDeniedColumn(e.Message);
                details.AddError(ExecutionDetails.DisallowedColumnQuery, e.Message);
            }

            // If columns are excluded, remove those from the select list
            IQuery <T> primaryQuery = query;

            if (query is JoinQuery <T> )
            {
                primaryQuery = ((JoinQuery <T>)query).PrimaryQuery;
            }

            if (primaryQuery.GetType().Equals(typeof(SelectQuery)))
            {
                SelectQuery   sq = (SelectQuery)primaryQuery;
                List <string> filteredColumns = null;

                if (sq.Columns.Count == 1 && sq.Columns[0] == "*")
                {
                    filteredColumns = new List <string>();
                    foreach (ColumnDetails column in this[sq.TableName].ColumnDetails)
                    {
                        if (restrictedColumns.Contains(column.Name))
                        {
                            details.AddDeniedColumn(column.Name);
                        }
                        else
                        {
                            filteredColumns.Add(column.Name);
                        }
                    }
                }
                else
                {
                    foreach (string columnName in sq.Columns)
                    {
                        if (restrictedColumns.Contains(columnName))
                        {
                            if (filteredColumns == null)
                            {
                                filteredColumns = new List <string>(sq.Columns);
                            }
                            filteredColumns.Remove(columnName);

                            details.AddDeniedColumn(columnName);
                        }
                    }
                }

                if (filteredColumns != null)
                {
                    sq.Columns = filteredColumns;
                }
            }
            else if (primaryQuery.GetType().Equals(typeof(AggregationQuery)))
            {
                AggregationQuery aq = (AggregationQuery)primaryQuery;
                if (aq.AggregationColumns != null)
                {
                    foreach (string columnName in aq.AggregationColumns)
                    {
                        if (restrictedColumns.Contains(columnName))
                        {
                            details.AddDeniedColumn(columnName);
                            details.AddError(ExecutionDetails.DisallowedColumnQuery, columnName);
                            aq.Where = new EmptyExpression();
                        }
                    }
                }
            }
            else if (primaryQuery.GetType().Equals(typeof(DistinctQuery)))
            {
                DistinctQuery dq = (DistinctQuery)primaryQuery;
                if (restrictedColumns.Contains(dq.Column))
                {
                    details.AddDeniedColumn(dq.Column);
                    details.AddError(ExecutionDetails.DisallowedColumnQuery, dq.Column);
                    dq.Where = new EmptyExpression();
                }
            }
            else
            {
                // IQuery is extensible; there's no way to ensure that user-implemented
                // queries respect security rules.
                details.AddError(ExecutionDetails.DisallowedQuery, primaryQuery.GetType().Name);
                primaryQuery.Where = new EmptyExpression();
            }
        }
예제 #4
0
 public async Task <DistinctResult> Distinct(DistinctQuery query)
 {
     return(await _client.SendObjectAsync <DistinctResult>(HttpMethod.Post, String.Format("table/{0}?action=distinct", _tableName), value : query));
 }
예제 #5
0
        /// <summary>
        /// Processes the specified DistinctQuery.
        /// </summary>
        /// <param name="distinctQuery">The DistinctQuery.</param>
        /// <param name="messageContext">The message context.</param>
        /// <param name="storeContext">The store context.</param>
        /// <returns>DistinctQueryResult</returns>
        internal static DistinctQueryResult Process(DistinctQuery distinctQuery, MessageContext messageContext, IndexStoreContext storeContext)
        {
            DistinctQueryResult      distinctQueryResult;
            Dictionary <byte[], int> distinctValueCountMapping = null;
            bool indexExists = false;

            try
            {
                IndexTypeMapping indexTypeMapping = storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId];
                Index            targetIndexInfo  = indexTypeMapping.IndexCollection[distinctQuery.TargetIndexName];

                #region Prepare Result

                CacheIndexInternal targetIndex = IndexServerUtils.GetCacheIndexInternal(storeContext,
                                                                                        messageContext.TypeId,
                                                                                        messageContext.PrimaryId,
                                                                                        distinctQuery.IndexId,
                                                                                        targetIndexInfo.ExtendedIdSuffix,
                                                                                        distinctQuery.TargetIndexName,
                                                                                        (distinctQuery.ItemsToLookUp != null ? (int)distinctQuery.ItemsToLookUp : Int32.MaxValue),
                                                                                        null,
                                                                                        true,
                                                                                        distinctQuery.IndexCondition,
                                                                                        false,
                                                                                        false,
                                                                                        targetIndexInfo.PrimarySortInfo,
                                                                                        targetIndexInfo.LocalIdentityTagList,
                                                                                        targetIndexInfo.StringHashCodeDictionary,
                                                                                        null,
                                                                                        targetIndexInfo.IsMetadataPropertyCollection,
                                                                                        null,
                                                                                        DomainSpecificProcessingType.None,
                                                                                        storeContext.DomainSpecificConfig,
                                                                                        distinctQuery.FieldName,
                                                                                        null,
                                                                                        true);

                #endregion

                if (targetIndex != null)
                {
                    indexExists = true;

                    // update perf counter
                    PerformanceCounters.Instance.SetCounterValue(PerformanceCounterEnum.NumOfItemsInIndexPerDistinctQuery,
                                                                 messageContext.TypeId,
                                                                 targetIndex.OutDeserializationContext.TotalCount);

                    PerformanceCounters.Instance.SetCounterValue(PerformanceCounterEnum.NumOfItemsReadPerDistinctQuery,
                                                                 messageContext.TypeId,
                                                                 targetIndex.OutDeserializationContext.ReadItemCount);

                    distinctValueCountMapping = targetIndex.OutDeserializationContext.DistinctValueCountMapping;
                }

                distinctQueryResult = new DistinctQueryResult
                {
                    DistinctValueCountMapping = distinctValueCountMapping,
                    IndexExists = indexExists,
                };
            }
            catch (Exception ex)
            {
                distinctQueryResult = new DistinctQueryResult
                {
                    DistinctValueCountMapping = null,
                    IndexExists   = false,
                    ExceptionInfo = ex.Message
                };
                LoggingUtil.Log.ErrorFormat("TypeId {0} -- Error processing DistinctQuery : {1}", messageContext.TypeId, ex);
            }
            return(distinctQueryResult);
        }