예제 #1
0
        /// <summary>
        /// Find the list of data to populate the ListBox with
        /// </summary>
        /// <param name="context"></param>
        protected override void RetrieveDataList(ITypeDescriptorContext context)
        {
            DataListAttribute dataListAttribute = null;
            object            property          = null;

            // Find the Attribute that has the path to the List of Items
            foreach (Attribute attribute in context.PropertyDescriptor.Attributes)
            {
                if (attribute is DataListAttribute)
                {
                    dataListAttribute  = attribute as DataListAttribute;
                    base.ListAttribute = dataListAttribute;
                    break;
                }
            }

            // If we found the Attribute, find the Data List
            if (dataListAttribute != null)
            {
                // Split the path
                List <string> path = PathParser.GetPathParts(dataListAttribute.Path);

                // The path has 1 or more parts
                if ((path != null) && (path.Count > 0))
                {
                    if (dataListAttribute.IsStatic)
                    {
                        property = GetStaticProperty(dataListAttribute, path);
                    }
                    else
                    {
                        // Set the property to the current object
                        property = GetLocalProperty(path, context.Instance);
                    }
                }
            }

            // We don't have List of items
            if ((property == null) || (!(property is IList)))
            {
                base.DataList = null;
            }
            else
            {
                // Save the DataList
                base.DataList = property as IList;
            }
        }
예제 #2
0
        public void BaselineTest()
        {
            foreach (byte[] test in new[]
            {
                Properties.Resources.BaselineTest_PathParser,
                Properties.Resources.BaselineTest_PathParser_Extra,
            })
            {
                using (Stream stream = new MemoryStream(test))
                {
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        List <TestData> testData = JsonConvert.DeserializeObject <List <TestData> >(reader.ReadToEnd());

                        foreach (TestData data in testData)
                        {
                            Assert.IsTrue(Enumerable.SequenceEqual(PathParser.GetPathParts(data.Path), data.Parts));
                        }
                    }
                }
            }
        }
        internal PartitionedQueryExecutionInfoInternal GetPartitionedQueryExecutionInfoInternal(
            SqlQuerySpec querySpec,
            PartitionKeyDefinition partitionKeyDefinition,
            bool requireFormattableOrderByQuery,
            bool isContinuationExpected)
        {
            if (querySpec == null || partitionKeyDefinition == null)
            {
                return(DefaultInfoInternal);
            }

            string queryText = JsonConvert.SerializeObject(querySpec);

            List <string> paths = new List <string>(partitionKeyDefinition.Paths);

            List <string[]> pathParts = new List <string[]>();

            paths.ForEach(path =>
            {
                pathParts.Add(PathParser.GetPathParts(path).ToArray());
            });

            string[] allParts     = pathParts.SelectMany(parts => parts).ToArray();
            uint[]   partsLengths = pathParts.Select(parts => (uint)parts.Length).ToArray();

            PartitionKind partitionKind = partitionKeyDefinition.Kind;

            this.Initialize();

            byte[] buffer = new byte[InitialBufferSize];
            uint   errorCode;
            uint   serializedQueryExecutionInfoResultLength;

            unsafe
            {
                fixed(byte *bytePtr = buffer)
                {
                    errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery(
                        this.serviceProvider,
                        queryText,
                        requireFormattableOrderByQuery,
                        isContinuationExpected,
                        allParts,
                        partsLengths,
                        (uint)partitionKeyDefinition.Paths.Count,
                        partitionKind,
                        new IntPtr(bytePtr),
                        (uint)buffer.Length,
                        out serializedQueryExecutionInfoResultLength);

                    if (errorCode == DISP_E_BUFFERTOOSMALL)
                    {
                        buffer = new byte[serializedQueryExecutionInfoResultLength];
                        fixed(byte *bytePtr2 = buffer)
                        {
                            errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery(
                                this.serviceProvider,
                                queryText,
                                requireFormattableOrderByQuery,
                                isContinuationExpected,
                                allParts,
                                partsLengths,
                                (uint)partitionKeyDefinition.Paths.Count,
                                partitionKind,
                                new IntPtr(bytePtr2),
                                (uint)buffer.Length,
                                out serializedQueryExecutionInfoResultLength);
                        }
                    }
                }
            }

            string serializedQueryExecutionInfo = Encoding.UTF8.GetString(buffer, 0, (int)serializedQueryExecutionInfoResultLength);

            Exception exception = Marshal.GetExceptionForHR((int)errorCode);

            if (exception != null)
            {
                DefaultTrace.TraceInformation("QueryEngineConfiguration: " + this.queryengineConfiguration);
                throw new BadRequestException(
                          "Message: " + serializedQueryExecutionInfo,
                          exception);
            }

            PartitionedQueryExecutionInfoInternal queryInfoInternal =
                JsonConvert.DeserializeObject <PartitionedQueryExecutionInfoInternal>(
                    serializedQueryExecutionInfo,
                    new JsonSerializerSettings {
                DateParseHandling = DateParseHandling.None
            });

            return(queryInfoInternal);
        }
        internal TryCatch <PartitionedQueryExecutionInfoInternal> TryGetPartitionedQueryExecutionInfoInternal(
            SqlQuerySpec querySpec,
            PartitionKeyDefinition partitionKeyDefinition,
            bool requireFormattableOrderByQuery,
            bool isContinuationExpected,
            bool allowNonValueAggregateQuery,
            bool hasLogicalPartitionKey,
            bool allowDCount)
        {
            if (querySpec == null || partitionKeyDefinition == null)
            {
                return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromResult(DefaultInfoInternal));
            }

            string queryText = JsonConvert.SerializeObject(querySpec);

            List <string> paths = new List <string>(partitionKeyDefinition.Paths);
            List <IReadOnlyList <string> > pathPartsList = new List <IReadOnlyList <string> >(paths.Count);

            uint[] partsLengths   = new uint[paths.Count];
            int    allPartsLength = 0;

            for (int i = 0; i < paths.Count; i++)
            {
                IReadOnlyList <string> pathParts = PathParser.GetPathParts(paths[i]);
                partsLengths[i] = (uint)pathParts.Count;
                pathPartsList.Add(pathParts);
                allPartsLength += pathParts.Count;
            }

            string[] allParts      = new string[allPartsLength];
            int      allPartsIndex = 0;

            foreach (IReadOnlyList <string> pathParts in pathPartsList)
            {
                foreach (string part in pathParts)
                {
                    allParts[allPartsIndex++] = part;
                }
            }

            PartitionKind partitionKind = partitionKeyDefinition.Kind;

            this.Initialize();

            Span <byte> buffer = stackalloc byte[QueryPartitionProvider.InitialBufferSize];
            uint        errorCode;
            uint        serializedQueryExecutionInfoResultLength;

            unsafe
            {
                fixed(byte *bytePtr = buffer)
                {
                    errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery2(
                        this.serviceProvider,
                        queryText,
                        requireFormattableOrderByQuery,
                        isContinuationExpected,
                        allowNonValueAggregateQuery,
                        hasLogicalPartitionKey,
                        allowDCount,
                        allParts,
                        partsLengths,
                        (uint)partitionKeyDefinition.Paths.Count,
                        partitionKind,
                        new IntPtr(bytePtr),
                        (uint)buffer.Length,
                        out serializedQueryExecutionInfoResultLength);

                    if (errorCode == DISP_E_BUFFERTOOSMALL)
                    {
                        // Allocate on stack for smaller arrays, otherwise use heap.
                        buffer = serializedQueryExecutionInfoResultLength < 4096
                            ? stackalloc byte[(int)serializedQueryExecutionInfoResultLength]
                            : new byte[serializedQueryExecutionInfoResultLength];

                        fixed(byte *bytePtr2 = buffer)
                        {
                            errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery2(
                                this.serviceProvider,
                                queryText,
                                requireFormattableOrderByQuery,
                                isContinuationExpected,
                                allowNonValueAggregateQuery,
                                hasLogicalPartitionKey, // has logical partition key
                                allowDCount,
                                allParts,
                                partsLengths,
                                (uint)partitionKeyDefinition.Paths.Count,
                                partitionKind,
                                new IntPtr(bytePtr2),
                                (uint)buffer.Length,
                                out serializedQueryExecutionInfoResultLength);
                        }
                    }
                }
            }

            string serializedQueryExecutionInfo = Encoding.UTF8.GetString(buffer.Slice(0, (int)serializedQueryExecutionInfoResultLength));

            Exception exception = Marshal.GetExceptionForHR((int)errorCode);

            if (exception != null)
            {
                QueryPartitionProviderException queryPartitionProviderException;
                if (string.IsNullOrEmpty(serializedQueryExecutionInfo))
                {
                    queryPartitionProviderException = new UnexpectedQueryPartitionProviderException(
                        "Query service interop parsing hit an unexpected exception",
                        exception);
                }
                else
                {
                    queryPartitionProviderException = new ExpectedQueryPartitionProviderException(
                        serializedQueryExecutionInfo,
                        exception);
                }

                return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromException(
                           queryPartitionProviderException));
            }

            PartitionedQueryExecutionInfoInternal queryInfoInternal =
                JsonConvert.DeserializeObject <PartitionedQueryExecutionInfoInternal>(
                    serializedQueryExecutionInfo,
                    new JsonSerializerSettings
            {
                DateParseHandling = DateParseHandling.None
            });

            return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromResult(queryInfoInternal));
        }
        internal TryCatch <PartitionedQueryExecutionInfoInternal> TryGetPartitionedQueryExecutionInfoInternal(
            SqlQuerySpec querySpec,
            PartitionKeyDefinition partitionKeyDefinition,
            bool requireFormattableOrderByQuery,
            bool isContinuationExpected,
            bool allowNonValueAggregateQuery,
            bool hasLogicalPartitionKey)
        {
            if (querySpec == null || partitionKeyDefinition == null)
            {
                return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromResult(DefaultInfoInternal));
            }

            string queryText = JsonConvert.SerializeObject(querySpec);

            List <string> paths = new List <string>(partitionKeyDefinition.Paths);

            List <string[]> pathParts = new List <string[]>();

            paths.ForEach(path =>
            {
                pathParts.Add(PathParser.GetPathParts(path));
            });

            string[] allParts     = pathParts.SelectMany(parts => parts).ToArray();
            uint[]   partsLengths = pathParts.Select(parts => (uint)parts.Length).ToArray();

            PartitionKind partitionKind = partitionKeyDefinition.Kind;

            this.Initialize();

            byte[] buffer = new byte[InitialBufferSize];
            uint   errorCode;
            uint   serializedQueryExecutionInfoResultLength;

            unsafe
            {
                fixed(byte *bytePtr = buffer)
                {
                    errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery(
                        this.serviceProvider,
                        queryText,
                        requireFormattableOrderByQuery,
                        isContinuationExpected,
                        allowNonValueAggregateQuery,
                        hasLogicalPartitionKey,
                        allParts,
                        partsLengths,
                        (uint)partitionKeyDefinition.Paths.Count,
                        partitionKind,
                        new IntPtr(bytePtr),
                        (uint)buffer.Length,
                        out serializedQueryExecutionInfoResultLength);

                    if (errorCode == DISP_E_BUFFERTOOSMALL)
                    {
                        buffer = new byte[serializedQueryExecutionInfoResultLength];
                        fixed(byte *bytePtr2 = buffer)
                        {
                            errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery(
                                this.serviceProvider,
                                queryText,
                                requireFormattableOrderByQuery,
                                isContinuationExpected,
                                allowNonValueAggregateQuery,
                                hasLogicalPartitionKey, // has logical partition key
                                allParts,
                                partsLengths,
                                (uint)partitionKeyDefinition.Paths.Count,
                                partitionKind,
                                new IntPtr(bytePtr2),
                                (uint)buffer.Length,
                                out serializedQueryExecutionInfoResultLength);
                        }
                    }
                }
            }

            string serializedQueryExecutionInfo = Encoding.UTF8.GetString(buffer, 0, (int)serializedQueryExecutionInfoResultLength);

            Exception exception = Marshal.GetExceptionForHR((int)errorCode);

            if (exception != null)
            {
                QueryPartitionProviderException queryPartitionProviderException;
                if (string.IsNullOrEmpty(serializedQueryExecutionInfo))
                {
                    queryPartitionProviderException = new UnexpectedQueryPartitionProviderException(
                        "Query service interop parsing hit an unexpected exception",
                        exception);
                }
                else
                {
                    queryPartitionProviderException = new ExpectedQueryPartitionProviderException(
                        serializedQueryExecutionInfo,
                        exception);
                }

                return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromException(
                           queryPartitionProviderException));
            }

            PartitionedQueryExecutionInfoInternal queryInfoInternal =
                JsonConvert.DeserializeObject <PartitionedQueryExecutionInfoInternal>(
                    serializedQueryExecutionInfo,
                    new JsonSerializerSettings
            {
                DateParseHandling = DateParseHandling.None
            });

            return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromResult(queryInfoInternal));
        }
        internal TryCatch <PartitionedQueryExecutionInfoInternal> TryGetPartitionedQueryExecutionInfoInternal(
            string querySpecJsonString,
            PartitionKeyDefinition partitionKeyDefinition,
            bool requireFormattableOrderByQuery,
            bool isContinuationExpected,
            bool allowNonValueAggregateQuery,
            bool hasLogicalPartitionKey,
            bool allowDCount,
            bool useSystemPrefix)
        {
            if (querySpecJsonString == null || partitionKeyDefinition == null)
            {
                return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromResult(DefaultInfoInternal));
            }

            List <string> paths = new List <string>(partitionKeyDefinition.Paths);
            List <IReadOnlyList <string> > pathPartsList = new List <IReadOnlyList <string> >(paths.Count);

            uint[] partsLengths   = new uint[paths.Count];
            int    allPartsLength = 0;

            for (int i = 0; i < paths.Count; i++)
            {
                IReadOnlyList <string> pathParts = PathParser.GetPathParts(paths[i]);
                partsLengths[i] = (uint)pathParts.Count;
                pathPartsList.Add(pathParts);
                allPartsLength += pathParts.Count;
            }

            string[] allParts      = new string[allPartsLength];
            int      allPartsIndex = 0;

            foreach (IReadOnlyList <string> pathParts in pathPartsList)
            {
                foreach (string part in pathParts)
                {
                    allParts[allPartsIndex++] = part;
                }
            }

            PartitionKind  partitionKind        = partitionKeyDefinition.Kind;
            GeospatialType defaultGeopatialType = GeospatialType.Geography;

            this.Initialize();

            Span <byte> buffer = stackalloc byte[QueryPartitionProvider.InitialBufferSize];
            uint        errorCode;
            uint        serializedQueryExecutionInfoResultLength;

            unsafe
            {
                ServiceInteropWrapper.PartitionKeyRangesApiOptions partitionKeyRangesApiOptions =
                    new ServiceInteropWrapper.PartitionKeyRangesApiOptions()
                {
                    bAllowDCount = Convert.ToInt32(allowDCount),
                    bAllowNonValueAggregateQuery    = Convert.ToInt32(allowNonValueAggregateQuery),
                    bHasLogicalPartitionKey         = Convert.ToInt32(hasLogicalPartitionKey),
                    bIsContinuationExpected         = Convert.ToInt32(isContinuationExpected),
                    bRequireFormattableOrderByQuery = Convert.ToInt32(requireFormattableOrderByQuery),
                    bUseSystemPrefix = Convert.ToInt32(useSystemPrefix),
                    eGeospatialType  = Convert.ToInt32(defaultGeopatialType),
                    ePartitionKind   = Convert.ToInt32(partitionKind)
                };

                fixed(byte *bytePtr = buffer)
                {
                    errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery3(
                        this.serviceProvider,
                        querySpecJsonString,
                        partitionKeyRangesApiOptions,
                        allParts,
                        partsLengths,
                        (uint)partitionKeyDefinition.Paths.Count,
                        new IntPtr(bytePtr),
                        (uint)buffer.Length,
                        out serializedQueryExecutionInfoResultLength);

                    if (errorCode == DISP_E_BUFFERTOOSMALL)
                    {
                        // Allocate on stack for smaller arrays, otherwise use heap.
                        buffer = serializedQueryExecutionInfoResultLength < 4096
                            ? stackalloc byte[(int)serializedQueryExecutionInfoResultLength]
                            : new byte[serializedQueryExecutionInfoResultLength];

                        fixed(byte *bytePtr2 = buffer)
                        {
                            errorCode = ServiceInteropWrapper.GetPartitionKeyRangesFromQuery3(
                                this.serviceProvider,
                                querySpecJsonString,
                                partitionKeyRangesApiOptions,
                                allParts,
                                partsLengths,
                                (uint)partitionKeyDefinition.Paths.Count,
                                new IntPtr(bytePtr2),
                                (uint)buffer.Length,
                                out serializedQueryExecutionInfoResultLength);
                        }
                    }
                }
            }

            string serializedQueryExecutionInfo = Encoding.UTF8.GetString(buffer.Slice(0, (int)serializedQueryExecutionInfoResultLength));

            Exception exception = Marshal.GetExceptionForHR((int)errorCode);

            if (exception != null)
            {
                QueryPartitionProviderException queryPartitionProviderException;
                if (string.IsNullOrEmpty(serializedQueryExecutionInfo))
                {
                    queryPartitionProviderException = new UnexpectedQueryPartitionProviderException(
                        "Query service interop parsing hit an unexpected exception",
                        exception);
                }
                else
                {
                    queryPartitionProviderException = new ExpectedQueryPartitionProviderException(
                        serializedQueryExecutionInfo,
                        exception);
                }

                return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromException(
                           queryPartitionProviderException));
            }

            PartitionedQueryExecutionInfoInternal queryInfoInternal =
                JsonConvert.DeserializeObject <PartitionedQueryExecutionInfoInternal>(
                    serializedQueryExecutionInfo,
                    new JsonSerializerSettings
            {
                DateParseHandling = DateParseHandling.None,
                MaxDepth          = 64, // https://github.com/advisories/GHSA-5crp-9r3c-p9vr
            });

            return(TryCatch <PartitionedQueryExecutionInfoInternal> .FromResult(queryInfoInternal));
        }