Exemple #1
0
        public Task Terms()
        {
            var name      = GetQueryStringValueAndAssertIfSingleAndNotEmpty("name");
            var field     = GetQueryStringValueAndAssertIfSingleAndNotEmpty("field");
            var fromValue = GetStringQueryString("fromValue", required: false);

            using (var token = CreateTimeLimitedOperationToken())
                using (Database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                    using (context.OpenReadTransaction())
                    {
                        var existingResultEtag = GetLongFromHeaders("If-None-Match");

                        var result = Database.QueryRunner.ExecuteGetTermsQuery(name, field, fromValue, existingResultEtag, GetPageSize(), context, token);

                        if (result.NotModified)
                        {
                            HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                            return(Task.CompletedTask);
                        }

                        HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

                        using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                        {
                            writer.WriteTermsQueryResult(context, result);
                        }

                        return(Task.CompletedTask);
                    }
        }
Exemple #2
0
        /// <summary>
        /// Gets the word in a switch from the current argument or parses a file.
        /// For example -foo, /foo, or --foo would return 'foo'.
        /// </summary>
        /// <param name="args">
        /// The command line parameters to be processed.
        /// </param>
        /// <param name="argIndex">
        /// The index in args to the argument to process.
        /// </param>
        /// <param name="parser">
        /// Used to parse files in the args.  If not supplied, Files will not be parsed.
        /// </param>
        /// <param name="noexitSeen">
        /// Used during parsing files.
        /// </param>
        /// <returns>
        /// Returns a Tuple:
        /// The first value is a String called SwitchKey with the word in a switch from the current argument or null.
        /// The second value is a bool called ShouldBreak, indicating if the parsing look should break.
        /// </returns>
        private static (string SwitchKey, bool ShouldBreak) GetSwitchKey(string[] args, ref int argIndex, CommandLineParameterParser parser, ref bool noexitSeen)
        {
            string switchKey = args[argIndex].Trim().ToLowerInvariant();

            if (string.IsNullOrEmpty(switchKey))
            {
                return(SwitchKey : null, ShouldBreak : false);
            }

            if (!CharExtensions.IsDash(switchKey[0]) && switchKey[0] != '/')
            {
                // then its a file
                if (parser != null)
                {
                    --argIndex;
                    parser.ParseFile(args, ref argIndex, noexitSeen);
                }

                return(SwitchKey : null, ShouldBreak : true);
            }

            // chop off the first character so that we're agnostic wrt specifying / or -
            // in front of the switch name.
            switchKey = switchKey.Substring(1);

            // chop off the second dash so we're agnostic wrt specifying - or --
            if (!string.IsNullOrEmpty(switchKey) && CharExtensions.IsDash(switchKey[0]))
            {
                switchKey = switchKey.Substring(1);
            }

            return(SwitchKey : switchKey, ShouldBreak : false);
        }
Exemple #3
0
        private void MoreLikeThis(DocumentsOperationContext context, OperationCancelToken token, HttpMethod method)
        {
            var existingResultEtag = GetLongFromHeaders("If-None-Match");

            var query  = GetMoreLikeThisQuery(context, method);
            var runner = new QueryRunner(Database, context);

            var result = runner.ExecuteMoreLikeThisQuery(query, context, existingResultEtag, token);

            if (result.NotModified)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                return;
            }

            HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

            int numberOfResults;

            using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
            {
                writer.WriteMoreLikeThisQueryResult(context, result, out numberOfResults);
            }

            AddPagingPerformanceHint(PagingOperationType.Queries, $"{nameof(MoreLikeThis)} ({query.Metadata.IndexName})", HttpContext, numberOfResults, query.PageSize, TimeSpan.FromMilliseconds(result.DurationInMs));
        }
Exemple #4
0
        /// <summary>
        /// Skips delimiters starting from the specified position. If retDelims
        /// is false, returns the index of the first non-delimiter character at or
        /// after startPos. If retDelims is true, startPos is returned.
        /// </summary>
        /// <param name="startPos"></param>
        /// <returns></returns>
        private int SkipDelimiters(int startPos)
        {
            if (delimiters == null)
            {
                throw new NullReferenceException();
            }

            int position = startPos;

            while (!retDelims && position < maxPosition)
            {
                if (!hasSurrogates)
                {
                    char c = str[position];
                    if ((c > maxDelimCodePoint) || (delimiters.IndexOf(c) < 0))
                    {
                        break;
                    }
                    position++;
                }
                else
                {
                    int c = str.CodePointAt(position);
                    if ((c > maxDelimCodePoint) || !IsDelimiter(c))
                    {
                        break;
                    }
                    position += CharExtensions.CharCount(c);
                }
            }
            return(position);
        }
Exemple #5
0
        private async Task FacetedQuery(DocumentsOperationContext context, OperationCancelToken token, HttpMethod method)
        {
            var query = await GetFacetQuery(context, method);

            if (query.FacetQuery.FacetSetupDoc == null && (query.FacetQuery.Facets == null || query.FacetQuery.Facets.Count == 0))
            {
                throw new InvalidOperationException("One of the required parameters (facetDoc or facets) was not specified.");
            }

            var existingResultEtag = GetLongFromHeaders("If-None-Match");

            var runner = new QueryRunner(Database, context);

            var result = await runner.ExecuteFacetedQuery(query.FacetQuery, query.FacetsEtag, existingResultEtag, token);

            if (result.NotModified)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                return;
            }

            HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

            using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
            {
                writer.WriteFacetedQueryResult(context, result);
            }

            Database.QueryMetadataCache.MaybeAddToCache(query.FacetQuery.Metadata, result.IndexName);
        }
Exemple #6
0
        private async Task Query(DocumentsOperationContext context, OperationCancelToken token, RequestTimeTracker tracker, HttpMethod method)
        {
            var indexQuery = await GetIndexQuery(context, method, tracker);

            if (TrafficWatchManager.HasRegisteredClients)
            {
                TrafficWatchQuery(indexQuery);
            }

            var existingResultEtag = GetLongFromHeaders("If-None-Match");

            if (indexQuery.Metadata.HasFacet)
            {
                await FacetedQuery(indexQuery, context, token);

                return;
            }

            if (indexQuery.Metadata.HasSuggest)
            {
                await SuggestQuery(indexQuery, context, token);

                return;
            }

            var metadataOnly = GetBoolValueQueryString("metadataOnly", required: false) ?? false;

            DocumentQueryResult result;

            try
            {
                result = await Database.QueryRunner.ExecuteQuery(indexQuery, context, existingResultEtag, token).ConfigureAwait(false);
            }
            catch (IndexDoesNotExistException)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
                return;
            }

            if (result.NotModified)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                return;
            }

            HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

            int numberOfResults;

            using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBodyStream(), Database.DatabaseShutdown))
            {
                result.Timings  = indexQuery.Timings?.ToTimings();
                numberOfResults = await writer.WriteDocumentQueryResultAsync(context, result, metadataOnly);

                await writer.OuterFlushAsync();
            }

            Database.QueryMetadataCache.MaybeAddToCache(indexQuery.Metadata, result.IndexName);
            AddPagingPerformanceHint(PagingOperationType.Queries, $"{nameof(Query)} ({result.IndexName})", indexQuery.Query, numberOfResults, indexQuery.PageSize, result.DurationInMs);
        }
        internal static bool SplitCmdletName(string name, out string verb, out string noun)
        {
            noun = verb = string.Empty;
            if (string.IsNullOrEmpty(name))
            {
                return(false);
            }

            int index = 0;

            for (int i = 0; i < name.Length; i++)
            {
                if (CharExtensions.IsDash(name[i]))
                {
                    index = i;
                    break;
                }
            }

            if (index > 0)
            {
                verb = name.Substring(0, index);
                noun = name.Substring(index + 1);
                return(true);
            }

            return(false);
        }
Exemple #8
0
        private (string switchKey, bool shouldBreak) GetSwitchKey(string[] args, ref int argIndex, ref bool noexitSeen)
        {
            string switchKey = args[argIndex].Trim();

            if (string.IsNullOrEmpty(switchKey))
            {
                return(switchKey : string.Empty, shouldBreak : false);
            }

            char firstChar = switchKey[0];

            if (!CharExtensions.IsDash(firstChar) && firstChar != '/')
            {
                // then it's a file
                --argIndex;
                ParseFile(args, ref argIndex, noexitSeen);

                return(switchKey : string.Empty, shouldBreak : true);
            }

            // chop off the first character so that we're agnostic wrt specifying / or -
            // in front of the switch name.
            switchKey = switchKey.Substring(1);

            // chop off the second dash so we're agnostic wrt specifying - or --
            if (!string.IsNullOrEmpty(switchKey) && CharExtensions.IsDash(firstChar) && switchKey[0] == firstChar)
            {
                switchKey = switchKey.Substring(1);
            }

            return(switchKey : switchKey, shouldBreak : false);
        }
Exemple #9
0
        private async Task FacetedQuery(IndexQueryServerSide indexQuery, QueryOperationContext queryContext, OperationCancelToken token)
        {
            var existingResultEtag = GetLongFromHeaders("If-None-Match");

            var result = await Database.QueryRunner.ExecuteFacetedQuery(indexQuery, existingResultEtag, queryContext, token);

            if (result.NotModified)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                return;
            }

            HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

            long numberOfResults;

            await using (var writer = new AsyncBlittableJsonTextWriter(queryContext.Documents, ResponseBodyStream()))
            {
                numberOfResults = await writer.WriteFacetedQueryResultAsync(queryContext.Documents, result, token.Token);
            }

            Database.QueryMetadataCache.MaybeAddToCache(indexQuery.Metadata, result.IndexName);

            if (ShouldAddPagingPerformanceHint(numberOfResults))
            {
                AddPagingPerformanceHint(PagingOperationType.Queries, $"{nameof(FacetedQuery)} ({result.IndexName})", $"{indexQuery.Metadata.QueryText}\n{indexQuery.QueryParameters}", numberOfResults, indexQuery.PageSize, result.DurationInMs, -1);
            }
        }
Exemple #10
0
        private async Task SuggestQuery(IndexQueryServerSide indexQuery, QueryOperationContext queryContext, OperationCancelToken token)
        {
            var existingResultEtag = GetLongFromHeaders("If-None-Match");
            var result             = await Database.QueryRunner.ExecuteSuggestionQuery(indexQuery, queryContext, existingResultEtag, token);

            if (result.NotModified)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                return;
            }

            HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

            long numberOfResults;
            long totalDocumentsSizeInBytes;

            await using (var writer = new AsyncBlittableJsonTextWriter(queryContext.Documents, ResponseBodyStream()))
            {
                (numberOfResults, totalDocumentsSizeInBytes) = await writer.WriteSuggestionQueryResultAsync(queryContext.Documents, result, token.Token);
            }

            if (ShouldAddPagingPerformanceHint(numberOfResults))
            {
                AddPagingPerformanceHint(PagingOperationType.Queries, $"{nameof(SuggestQuery)} ({result.IndexName})", indexQuery.Query, numberOfResults, indexQuery.PageSize, result.DurationInMs, totalDocumentsSizeInBytes);
            }
        }
Exemple #11
0
        /// <summary>
        /// Remove all white spaces until colon is found
        /// </summary>
        protected virtual bool Name_After()
        {
            while (CharExtensions.IsWhiteSpace(Current) || Current == ':')
            {
                MoveNext();
            }

            _parserMethod = Value_Before;
            return(true);
        }
Exemple #12
0
        /// <summary>
        /// Parse state method, remove all white spaces before the cookie name
        /// </summary>
        protected bool Name_Before()
        {
            while (CharExtensions.IsWhiteSpace(Current))
            {
                MoveNext();
            }

            _parserMethod = Name;
            return(true);
        }
Exemple #13
0
        public Task Terms()
        {
            var field = GetQueryStringValueAndAssertIfSingleAndNotEmpty("field");

            using (var token = CreateTimeLimitedOperationToken())
                using (Database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                    using (context.OpenReadTransaction())
                    {
                        var name = GetIndexNameFromCollectionAndField(field) ?? GetQueryStringValueAndAssertIfSingleAndNotEmpty("name");

                        var fromValue          = GetStringQueryString("fromValue", required: false);
                        var existingResultEtag = GetLongFromHeaders("If-None-Match");

                        var result = Database.QueryRunner.ExecuteGetTermsQuery(name, field, fromValue, existingResultEtag, GetPageSize(), context, token, out var index);

                        if (result.NotModified)
                        {
                            HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                            return(Task.CompletedTask);
                        }

                        HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

                        using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                        {
                            if (field.EndsWith("__minX") ||
                                field.EndsWith("__minY") ||
                                field.EndsWith("__maxX") ||
                                field.EndsWith("__maxY"))
                            {
                                if (index.Definition.IndexFields != null &&
                                    index.Definition.IndexFields.TryGetValue(field.Substring(0, field.Length - 6), out var indexField) == true)
                                {
                                    if (indexField.Spatial?.Strategy == Client.Documents.Indexes.Spatial.SpatialSearchStrategy.BoundingBox)
                                    {
                                        // Term-values for 'Spatial Index Fields' with 'BoundingBox' are encoded in Lucene as 'prefixCoded bytes'
                                        // Need to convert to numbers for the Studio
                                        var readableTerms = new HashSet <string>();
                                        foreach (var item in result.Terms)
                                        {
                                            var num = Lucene.Net.Util.NumericUtils.PrefixCodedToDouble(item);
                                            readableTerms.Add(NumberUtil.NumberToString(num));
                                        }

                                        result.Terms = readableTerms;
                                    }
                                }
                            }

                            writer.WriteTermsQueryResult(context, result);
                        }

                        return(Task.CompletedTask);
                    }
        }
Exemple #14
0
 private int CurrentLineIndent(TextBuilder tb)
 {
     for (int i = tb.Length - 1; i >= 0; i--)
     {
         if (CharExtensions.IsLineBreak(tb.Text[i]))
         {
             return(IndentBuilder.TextIndentInSpaces(tb.Text.Substring(i + 1), _options.TabSize));
         }
     }
     return(0);
 }
Exemple #15
0
        /// <summary>
        /// Read cookie name until white space or equals are found
        /// </summary>
        protected virtual bool Name()
        {
            while (!CharExtensions.IsWhiteSpace(Current) && Current != '=')
            {
                _cookieName += Current;
                MoveNext();
            }

            _parserMethod = Name_After;
            return(true);
        }
Exemple #16
0
 /// <summary>
 /// Determines indentation based on the leading whitespace in the current line.
 /// </summary>
 public static int GetLineIndentSize(TextBuilder tb, int position, int tabSize)
 {
     for (var i = position - 1; i >= 0; i--)
     {
         if (CharExtensions.IsLineBreak(tb.Text[i]))
         {
             return(TextIndentInSpaces(tb.Text.Substring(i + 1), tabSize));
         }
     }
     return(0);
 }
Exemple #17
0
        private async Task Query(DocumentsOperationContext context, OperationCancelToken token, HttpMethod method)
        {
            var indexQuery = await GetIndexQuery(context, method);

            var existingResultEtag = GetLongFromHeaders("If-None-Match");

            if (indexQuery.Metadata.IsFacet)
            {
                await FacetedQuery(indexQuery, context, token);

                return;
            }

            if (indexQuery.Metadata.IsSuggest)
            {
                await SuggestQuery(indexQuery, context, token);

                return;
            }

            var metadataOnly = GetBoolValueQueryString("metadata-only", required: false) ?? false;

            DocumentQueryResult result;

            try
            {
                result = await Database.QueryRunner.ExecuteQuery(indexQuery, context, existingResultEtag, token).ConfigureAwait(false);
            }
            catch (IndexDoesNotExistException)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
                return;
            }

            if (result.NotModified)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                return;
            }

            HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

            int numberOfResults;

            using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
            {
                writer.WriteDocumentQueryResult(context, result, metadataOnly, out numberOfResults);
            }

            Database.QueryMetadataCache.MaybeAddToCache(indexQuery.Metadata, result.IndexName);
            AddPagingPerformanceHint(PagingOperationType.Queries, $"{nameof(Query)} ({indexQuery.Metadata.IndexName})", HttpContext, numberOfResults, indexQuery.PageSize, TimeSpan.FromMilliseconds(result.DurationInMs));
        }
Exemple #18
0
        private bool Value_After()
        {
            OnCookie(_cookieName, _cookieValue);
            _cookieName  = "";
            _cookieValue = "";
            while (CharExtensions.IsWhiteSpace(Current) || Current == ';')
            {
                MoveNext();
            }

            _parserMethod = Name_Before;
            return(true);
        }
Exemple #19
0
        /**
         * Skips ahead from startPos and returns the index of the next delimiter
         * character encountered, or maxPosition if no such delimiter is found.
         */
        private int ScanToken(int startPos)
        {
            int position = startPos;

            while (position < maxPosition)
            {
                if (!hasSurrogates)
                {
                    char c = str[position];
                    if ((c <= maxDelimCodePoint) && (delimiters.IndexOf(c) >= 0))
                    {
                        break;
                    }
                    position++;
                }
                else
                {
                    int c = str.CodePointAt(position);
                    if ((c <= maxDelimCodePoint) && IsDelimiter(c))
                    {
                        break;
                    }
                    position += CharExtensions.CharCount(c);
                }
            }
            if (retDelims && (startPos == position))
            {
                if (!hasSurrogates)
                {
                    char c = str[position];
                    if ((c <= maxDelimCodePoint) && (delimiters.IndexOf(c) >= 0))
                    {
                        position++;
                    }
                }
                else
                {
                    int c = str.CodePointAt(position);
                    if ((c <= maxDelimCodePoint) && IsDelimiter(c))
                    {
                        position += CharExtensions.CharCount(c);
                    }
                }
            }
            return(position);
        }
Exemple #20
0
        /// <summary>
        /// Calculates position of a end of a single-line scope.
        /// The simple scope ends at a line break or at opening
        /// or closing curly brace.
        /// </summary>
        /// <returns></returns>
        private int GetSingleLineScopeEnd()
        {
            int closeBraceIndex = TokenBraceCounter <RToken> .GetMatchingBrace(
                _tokens,
                new RToken(RTokenType.OpenCurlyBrace),
                new RToken(RTokenType.CloseCurlyBrace),
                new RTokenTypeComparer());

            int end = closeBraceIndex < 0 ? _textProvider.Length : _tokens[closeBraceIndex].End;

            for (int i = _tokens.CurrentToken.End; i < end; i++)
            {
                if (CharExtensions.IsLineBreak(_textProvider[i]))
                {
                    return(-1);
                }
            }

            return(end);
        }
Exemple #21
0
        /// <summary>
        /// Escapes content so that it is safe for inclusion in a single-quoted string.
        /// For example: "'" + EscapeSingleQuotedStringContent(userContent) + "'"
        /// </summary>
        /// <param name="value">The content to be included in a single-quoted string.</param>
        /// <returns>Content with all single-quotes escaped.</returns>
        public static string EscapeSingleQuotedStringContent(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return(string.Empty);
            }

            StringBuilder sb = new StringBuilder(value.Length);

            foreach (char c in value)
            {
                sb.Append(c);
                if (CharExtensions.IsSingleQuote(c))
                {
                    // double-up quotes to escape them
                    sb.Append(c);
                }
            }

            return(sb.ToString());
        }
Exemple #22
0
        /// <summary>
        /// Escapes content so that it is safe for inclusion in a string that will later be used as a
        /// format string. If this is to be embedded inside of a single-quoted string, be sure to also
        /// call EscapeSingleQuotedStringContent.
        /// For example: "'" + EscapeSingleQuotedStringContent(EscapeFormatStringContent(userContent)) + "'" -f $args.
        /// </summary>
        /// <param name="value">The content to be included in a format string.</param>
        /// <returns>Content with all curly braces escaped.</returns>
        public static string EscapeFormatStringContent(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return(string.Empty);
            }

            StringBuilder sb = new StringBuilder(value.Length);

            foreach (char c in value)
            {
                sb.Append(c);
                if (CharExtensions.IsCurlyBracket(c))
                {
                    // double-up curly brackets to escape them
                    sb.Append(c);
                }
            }

            return(sb.ToString());
        }
Exemple #23
0
        private async Task IndexEntries(DocumentsOperationContext context, OperationCancelToken token, RequestTimeTracker tracker, HttpMethod method)
        {
            var indexQuery = await GetIndexQuery(context, method, tracker);

            var existingResultEtag = GetLongFromHeaders("If-None-Match");

            var result = await Database.QueryRunner.ExecuteIndexEntriesQuery(indexQuery, context, existingResultEtag, token);

            if (result.NotModified)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                return;
            }

            HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

            using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
            {
                writer.WriteIndexEntriesQueryResult(context, result);
            }
        }
Exemple #24
0
        /// <summary>
        /// Set MaxDelimCodePoint to the highest char in the delimiter set.
        /// </summary>
        private void SetMaxDelimCodePoint()
        {
            if (delimiters == null)
            {
                maxDelimCodePoint = 0;
                return;
            }

            int m = 0;
            int c;
            int count = 0;

            for (int i = 0; i < delimiters.Length; i += CharExtensions.CharCount(c))
            {
                c = delimiters[i];
                if (c >= CharExtensions.MIN_HIGH_SURROGATE && c <= CharExtensions.MAX_LOW_SURROGATE)
                {
                    c             = delimiters.CodePointAt(i);
                    hasSurrogates = true;
                }
                if (m < c)
                {
                    m = c;
                }
                count++;
            }
            maxDelimCodePoint = m;

            if (hasSurrogates)
            {
                delimiterCodePoints = new int[count];
                for (int i = 0, j = 0; i < count; i++, j += CharExtensions.CharCount(c))
                {
                    c = delimiters.CodePointAt(j);
                    delimiterCodePoints[i] = c;
                }
            }
        }
Exemple #25
0
        private async Task SuggestQuery(IndexQueryServerSide indexQuery, DocumentsOperationContext context, OperationCancelToken token)
        {
            var existingResultEtag = GetLongFromHeaders("If-None-Match");

            var result = await Database.QueryRunner.ExecuteSuggestionQuery(indexQuery, context, existingResultEtag, token);

            if (result.NotModified)
            {
                HttpContext.Response.StatusCode = (int)HttpStatusCode.NotModified;
                return;
            }

            HttpContext.Response.Headers[Constants.Headers.Etag] = CharExtensions.ToInvariantString(result.ResultEtag);

            int numberOfResults;

            using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
            {
                writer.WriteSuggestionQueryResult(context, result, numberOfResults: out numberOfResults);
            }

            AddPagingPerformanceHint(PagingOperationType.Queries, $"{nameof(SuggestQuery)} ({indexQuery.Metadata.IndexName})", HttpContext, numberOfResults, indexQuery.PageSize, TimeSpan.FromMilliseconds(result.DurationInMs));
        }
        /// <summary>
        /// Gets the parameters by matching its name.
        /// </summary>
        /// <param name="name">
        /// The name of the parameter.
        /// </param>
        /// <param name="throwOnParameterNotFound">
        /// If true and a matching parameter is not found, an exception will be
        /// throw. If false and a matching parameter is not found, null is returned.
        /// </param>
        /// <param name="tryExactMatching">
        /// If true we do exact matching, otherwise we do not.
        /// </param>
        /// <param name="invocationInfo">
        /// The invocation information about the code being run.
        /// </param>
        /// <returns>
        /// The a collection of the metadata associated with the parameters that
        /// match the specified name. If no matches were found, an empty collection
        /// is returned.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// If <paramref name="name"/> is null or empty.
        /// </exception>
        internal MergedCompiledCommandParameter GetMatchingParameter(
            string name,
            bool throwOnParameterNotFound,
            bool tryExactMatching,
            InvocationInfo invocationInfo)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw PSTraceSource.NewArgumentException("name");
            }

            Collection <MergedCompiledCommandParameter> matchingParameters =
                new Collection <MergedCompiledCommandParameter>();

            // Skip the leading '-' if present
            if (name.Length > 0 && CharExtensions.IsDash(name[0]))
            {
                name = name.Substring(1);
            }

            // First try to match the bindable parameters

            foreach (string parameterName in _bindableParameters.Keys)
            {
                if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase))
                {
                    // If it is an exact match then only return the exact match
                    // as the result

                    if (tryExactMatching && string.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase))
                    {
                        return(_bindableParameters[parameterName]);
                    }
                    else
                    {
                        matchingParameters.Add(_bindableParameters[parameterName]);
                    }
                }
            }

            // Now check the aliases

            foreach (string parameterName in _aliasedParameters.Keys)
            {
                if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase))
                {
                    // If it is an exact match then only return the exact match
                    // as the result

                    if (tryExactMatching && string.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase))
                    {
                        return(_aliasedParameters[parameterName]);
                    }
                    else
                    {
                        if (!matchingParameters.Contains(_aliasedParameters[parameterName]))
                        {
                            matchingParameters.Add(_aliasedParameters[parameterName]);
                        }
                    }
                }
            }

            if (matchingParameters.Count > 1)
            {
                // Prefer parameters in the cmdlet over common parameters
                Collection <MergedCompiledCommandParameter> filteredParameters =
                    new Collection <MergedCompiledCommandParameter>();

                foreach (MergedCompiledCommandParameter matchingParameter in matchingParameters)
                {
                    if ((matchingParameter.BinderAssociation == ParameterBinderAssociation.DeclaredFormalParameters) ||
                        (matchingParameter.BinderAssociation == ParameterBinderAssociation.DynamicParameters))
                    {
                        filteredParameters.Add(matchingParameter);
                    }
                }

                if (tryExactMatching && filteredParameters.Count == 1)
                {
                    matchingParameters = filteredParameters;
                }
                else
                {
                    StringBuilder possibleMatches = new StringBuilder();

                    foreach (MergedCompiledCommandParameter matchingParameter in matchingParameters)
                    {
                        possibleMatches.Append(" -");
                        possibleMatches.Append(matchingParameter.Parameter.Name);
                    }

                    ParameterBindingException exception =
                        new ParameterBindingException(
                            ErrorCategory.InvalidArgument,
                            invocationInfo,
                            null,
                            name,
                            null,
                            null,
                            ParameterBinderStrings.AmbiguousParameter,
                            "AmbiguousParameter",
                            possibleMatches);

                    throw exception;
                }
            }
            else if (matchingParameters.Count == 0)
            {
                if (throwOnParameterNotFound)
                {
                    ParameterBindingException exception =
                        new ParameterBindingException(
                            ErrorCategory.InvalidArgument,
                            invocationInfo,
                            null,
                            name,
                            null,
                            null,
                            ParameterBinderStrings.NamedParameterNotFound,
                            "NamedParameterNotFound");

                    throw exception;
                }
            }

            MergedCompiledCommandParameter result = null;

            if (matchingParameters.Count > 0)
            {
                result = matchingParameters[0];
            }

            return(result);
        }
Exemple #27
0
        private void ParseHelper(string[] args)
        {
            Dbg.Assert(args != null, "Argument 'args' to ParseHelper should never be null");
            bool noexitSeen = false;

            for (int i = 0; i < args.Length; ++i)
            {
                (string SwitchKey, bool ShouldBreak)switchKeyResults = GetSwitchKey(args, ref i, this, ref noexitSeen);
                if (switchKeyResults.ShouldBreak)
                {
                    break;
                }

                string switchKey = switchKeyResults.SwitchKey;

                // If version is in the commandline, don't continue to look at any other parameters
                if (MatchSwitch(switchKey, "version", "v"))
                {
                    _showVersion   = true;
                    _showBanner    = false;
                    _noInteractive = true;
                    _skipUserInit  = true;
                    _noExit        = false;
                    break;
                }

                if (MatchSwitch(switchKey, "help", "h") || MatchSwitch(switchKey, "?", "?"))
                {
                    _showHelp         = true;
                    _showExtendedHelp = true;
                    _abortStartup     = true;
                }
                else if (MatchSwitch(switchKey, "login", "l"))
                {
                    // This handles -Login on Windows only, where it does nothing.
                    // On *nix, -Login is handled much earlier to improve startup performance.
                }
                else if (MatchSwitch(switchKey, "noexit", "noe"))
                {
                    _noExit    = true;
                    noexitSeen = true;
                }
                else if (MatchSwitch(switchKey, "noprofile", "nop"))
                {
                    _skipUserInit = true;
                }
                else if (MatchSwitch(switchKey, "nologo", "nol"))
                {
                    _showBanner = false;
                }
                else if (MatchSwitch(switchKey, "noninteractive", "noni"))
                {
                    _noInteractive = true;
                }
                else if (MatchSwitch(switchKey, "socketservermode", "so"))
                {
                    _socketServerMode = true;
                }
                else if (MatchSwitch(switchKey, "servermode", "s"))
                {
                    _serverMode = true;
                }
                else if (MatchSwitch(switchKey, "namedpipeservermode", "nam"))
                {
                    _namedPipeServerMode = true;
                }
                else if (MatchSwitch(switchKey, "sshservermode", "sshs"))
                {
                    _sshServerMode = true;
                }
                else if (MatchSwitch(switchKey, "interactive", "i"))
                {
                    _noInteractive = false;
                }
                else if (MatchSwitch(switchKey, "configurationname", "config"))
                {
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingConfigurationNameArgument);
                        break;
                    }

                    _configurationName = args[i];
                }
                else if (MatchSwitch(switchKey, "custompipename", "cus"))
                {
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingCustomPipeNameArgument);
                        break;
                    }

                    if (!Platform.IsWindows)
                    {
                        int maxNameLength = (Platform.IsLinux ? MaxPipePathLengthLinux : MaxPipePathLengthMacOS) - Path.GetTempPath().Length;
                        if (args[i].Length > maxNameLength)
                        {
                            WriteCommandLineError(
                                string.Format(
                                    CommandLineParameterParserStrings.CustomPipeNameTooLong,
                                    maxNameLength,
                                    args[i],
                                    args[i].Length));
                            break;
                        }
                    }

                    _customPipeName = args[i];
                }
                else if (MatchSwitch(switchKey, "command", "c"))
                {
                    if (!ParseCommand(args, ref i, noexitSeen, false))
                    {
                        break;
                    }
                }
                else if (MatchSwitch(switchKey, "windowstyle", "w"))
                {
#if UNIX
                    WriteCommandLineError(
                        CommandLineParameterParserStrings.WindowStyleArgumentNotImplemented);
                    break;
#else
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingWindowStyleArgument);
                        break;
                    }

                    try
                    {
                        ProcessWindowStyle style = (ProcessWindowStyle)LanguagePrimitives.ConvertTo(
                            args[i], typeof(ProcessWindowStyle), CultureInfo.InvariantCulture);
                        ConsoleControl.SetConsoleMode(style);
                    }
                    catch (PSInvalidCastException e)
                    {
                        WriteCommandLineError(
                            string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidWindowStyleArgument, args[i], e.Message));
                        break;
                    }
#endif
                }
                else if (MatchSwitch(switchKey, "file", "f"))
                {
                    if (!ParseFile(args, ref i, noexitSeen))
                    {
                        break;
                    }
                }
#if DEBUG
                // this option is useful when debugging ConsoleHost remotely using VS remote debugging, as you can only
                // attach to an already running process with that debugger.
                else if (MatchSwitch(switchKey, "wait", "w"))
                {
                    // This does not need to be localized: its chk only

                    ((ConsoleHostUserInterface)_hostUI).WriteToConsole("Waiting - type enter to continue:", false);
                    _hostUI.ReadLine();
                }

                // this option is useful for testing the initial InitialSessionState experience
                else if (MatchSwitch(switchKey, "iss", "iss"))
                {
                    // Just toss this option, it was processed earlier...
                }

                // this option is useful for testing the initial InitialSessionState experience
                // this is independent of the normal wait switch because configuration processing
                // happens so early in the cycle...
                else if (MatchSwitch(switchKey, "isswait", "isswait"))
                {
                    // Just toss this option, it was processed earlier...
                }

                else if (MatchSwitch(switchKey, "modules", "mod"))
                {
                    if (ConsoleHost.DefaultInitialSessionState == null)
                    {
                        WriteCommandLineError(
                            "The -module option can only be specified with the -iss option.",
                            showHelp: true,
                            showBanner: false);
                        break;
                    }

                    ++i;
                    int moduleCount = 0;
                    // Accumulate the arguments to this script...
                    while (i < args.Length)
                    {
                        string arg = args[i];

                        if (!string.IsNullOrEmpty(arg) && CharExtensions.IsDash(arg[0]))
                        {
                            break;
                        }
                        else
                        {
                            ConsoleHost.DefaultInitialSessionState.ImportPSModule(new string[] { arg });
                            moduleCount++;
                        }

                        ++i;
                    }

                    if (moduleCount < 1)
                    {
                        _hostUI.WriteErrorLine("No modules specified for -module option");
                    }
                }
#endif
                else if (MatchSwitch(switchKey, "outputformat", "o") || MatchSwitch(switchKey, "of", "o"))
                {
                    ParseFormat(args, ref i, ref _outFormat, CommandLineParameterParserStrings.MissingOutputFormatParameter);
                    _outputFormatSpecified = true;
                }
                else if (MatchSwitch(switchKey, "inputformat", "in") || MatchSwitch(switchKey, "if", "if"))
                {
                    ParseFormat(args, ref i, ref _inFormat, CommandLineParameterParserStrings.MissingInputFormatParameter);
                }
                else if (MatchSwitch(switchKey, "executionpolicy", "ex") || MatchSwitch(switchKey, "ep", "ep"))
                {
                    ParseExecutionPolicy(args, ref i, ref _executionPolicy, CommandLineParameterParserStrings.MissingExecutionPolicyParameter);
                }
                else if (MatchSwitch(switchKey, "encodedcommand", "e") || MatchSwitch(switchKey, "ec", "e"))
                {
                    _wasCommandEncoded = true;
                    if (!ParseCommand(args, ref i, noexitSeen, true))
                    {
                        break;
                    }
                }
                else if (MatchSwitch(switchKey, "encodedarguments", "encodeda") || MatchSwitch(switchKey, "ea", "ea"))
                {
                    if (!CollectArgs(args, ref i))
                    {
                        break;
                    }
                }
                else if (MatchSwitch(switchKey, "settingsfile", "settings"))
                {
                    // Parse setting file arg and write error
                    if (!TryParseSettingFileHelper(args, ++i, this))
                    {
                        break;
                    }
                }
                else if (MatchSwitch(switchKey, "sta", "s"))
                {
                    if (!Platform.IsWindowsDesktop)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.STANotImplemented);
                        break;
                    }

                    if (_staMode.HasValue)
                    {
                        // -sta and -mta are mutually exclusive.
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
                        break;
                    }

                    _staMode = true;
                }
                else if (MatchSwitch(switchKey, "mta", "mta"))
                {
                    if (!Platform.IsWindowsDesktop)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MTANotImplemented);
                        break;
                    }

                    if (_staMode.HasValue)
                    {
                        // -sta and -mta are mutually exclusive.
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
                        break;
                    }

                    _staMode = false;
                }
                else if (MatchSwitch(switchKey, "workingdirectory", "wo") || MatchSwitch(switchKey, "wd", "wd"))
                {
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingWorkingDirectoryArgument);
                        break;
                    }

                    _workingDirectory = args[i];
                }
#if !UNIX
                else if (MatchSwitch(switchKey, "removeworkingdirectorytrailingcharacter", "removeworkingdirectorytrailingcharacter"))
                {
                    _removeWorkingDirectoryTrailingCharacter = true;
                }
#endif
                else
                {
                    // The first parameter we fail to recognize marks the beginning of the file string.

                    --i;
                    if (!ParseFile(args, ref i, noexitSeen))
                    {
                        break;
                    }
                }
            }

            if (_showHelp)
            {
                ShowHelp();
            }

            if (_showBanner && !_showHelp)
            {
                DisplayBanner();

                if (UpdatesNotification.CanNotifyUpdates)
                {
                    UpdatesNotification.ShowUpdateNotification(_hostUI);
                }
            }

            Dbg.Assert(
                ((_exitCode == ConsoleHost.ExitCodeBadCommandLineParameter) && _abortStartup) ||
                (_exitCode == ConsoleHost.ExitCodeSuccess),
                "if exit code is failure, then abortstartup should be true");
        }
Exemple #28
0
        private bool ParseFile(string[] args, ref int i, bool noexitSeen)
        {
            // Process file execution. We don't need to worry about checking -command
            // since if -command comes before -file, -file will be treated as part
            // of the script to evaluate. If -file comes before -command, it will
            // treat -command as an argument to the script...

            bool TryGetBoolValue(string arg, out bool boolValue)
            {
                if (arg.Equals("$true", StringComparison.OrdinalIgnoreCase) || arg.Equals("true", StringComparison.OrdinalIgnoreCase))
                {
                    boolValue = true;
                    return(true);
                }
                else if (arg.Equals("$false", StringComparison.OrdinalIgnoreCase) || arg.Equals("false", StringComparison.OrdinalIgnoreCase))
                {
                    boolValue = false;
                    return(true);
                }

                boolValue = false;
                return(false);
            }

            ++i;
            if (i >= args.Length)
            {
                WriteCommandLineError(
                    CommandLineParameterParserStrings.MissingFileArgument,
                    showHelp: true,
                    showBanner: false);
                return(false);
            }

            // Don't show the startup banner unless -noexit has been specified.
            if (!noexitSeen)
            {
                _showBanner = false;
            }

            // Process interactive input...
            if (args[i] == "-")
            {
                // the arg to -file is -, which is secret code for "read the commands from stdin with prompts"

                _explicitReadCommandsFromStdin = true;
                _noPrompt = false;
            }
            else
            {
                // Exit on script completion unless -noexit was specified...
                if (!noexitSeen)
                {
                    _noExit = false;
                }

                // We need to get the full path to the script because it will be
                // executed after the profiles are run and they may change the current
                // directory.
                string exceptionMessage = null;
                try
                {
                    _file = NormalizeFilePath(args[i]);
                }
                catch (Exception e)
                {
                    // Catch all exceptions - we're just going to exit anyway so there's
                    // no issue of the system being destabilized.
                    exceptionMessage = e.Message;
                }

                if (exceptionMessage != null)
                {
                    WriteCommandLineError(
                        string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidFileArgument, args[i], exceptionMessage),
                        showBanner: false);
                    return(false);
                }

                if (!System.IO.File.Exists(_file))
                {
                    if (args[i].StartsWith('-') && args[i].Length > 1)
                    {
                        string        param = args[i].Substring(1, args[i].Length - 1).ToLower();
                        StringBuilder possibleParameters = new StringBuilder();
                        foreach (string validParameter in validParameters)
                        {
                            if (validParameter.Contains(param))
                            {
                                possibleParameters.Append("\n  -");
                                possibleParameters.Append(validParameter);
                            }
                        }

                        if (possibleParameters.Length > 0)
                        {
                            WriteCommandLineError(
                                string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidArgument, args[i]),
                                showBanner: false);
                            WriteCommandLineError(possibleParameters.ToString(), showBanner: false);
                            return(false);
                        }
                    }

                    WriteCommandLineError(
                        string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.ArgumentFileDoesNotExist, args[i]),
                        showHelp: true);
                    return(false);
                }

                i++;

                string pendingParameter = null;

                // Accumulate the arguments to this script...
                while (i < args.Length)
                {
                    string arg = args[i];

                    // If there was a pending parameter, add a named parameter
                    // using the pending parameter and current argument
                    if (pendingParameter != null)
                    {
                        _collectedArgs.Add(new CommandParameter(pendingParameter, arg));
                        pendingParameter = null;
                    }
                    else if (!string.IsNullOrEmpty(arg) && CharExtensions.IsDash(arg[0]) && arg.Length > 1)
                    {
                        int offset = arg.IndexOf(':');
                        if (offset >= 0)
                        {
                            if (offset == arg.Length - 1)
                            {
                                pendingParameter = arg.TrimEnd(':');
                            }
                            else
                            {
                                string argValue = arg.Substring(offset + 1);
                                string argName  = arg.Substring(0, offset);
                                if (TryGetBoolValue(argValue, out bool boolValue))
                                {
                                    _collectedArgs.Add(new CommandParameter(argName, boolValue));
                                }
                                else
                                {
                                    _collectedArgs.Add(new CommandParameter(argName, argValue));
                                }
                            }
                        }
                        else
                        {
                            _collectedArgs.Add(new CommandParameter(arg));
                        }
                    }
                    else
                    {
                        _collectedArgs.Add(new CommandParameter(null, arg));
                    }

                    ++i;
                }
            }

            return(true);
        }
        private static void WriteIndexFieldOptions(this BlittableJsonTextWriter writer, JsonOperationContext context, IndexFieldOptions options, bool removeAnalyzers)
        {
            writer.WriteStartObject();

            writer.WritePropertyName(nameof(options.Analyzer));
            if (string.IsNullOrWhiteSpace(options.Analyzer) == false && !removeAnalyzers)
            {
                writer.WriteString(options.Analyzer);
            }
            else
            {
                writer.WriteNull();
            }
            writer.WriteComma();

            writer.WritePropertyName(nameof(options.Indexing));
            if (options.Indexing.HasValue)
            {
                writer.WriteString(options.Indexing.ToString());
            }
            else
            {
                writer.WriteNull();
            }
            writer.WriteComma();

            writer.WritePropertyName(nameof(options.Storage));
            if (options.Storage.HasValue)
            {
                writer.WriteString(options.Storage.ToString());
            }
            else
            {
                writer.WriteNull();
            }
            writer.WriteComma();

            writer.WritePropertyName(nameof(options.Suggestions));
            if (options.Suggestions.HasValue)
            {
                writer.WriteBool(options.Suggestions.Value);
            }
            else
            {
                writer.WriteNull();
            }
            writer.WriteComma();

            writer.WritePropertyName(nameof(options.TermVector));
            if (options.TermVector.HasValue)
            {
                writer.WriteString(options.TermVector.ToString());
            }
            else
            {
                writer.WriteNull();
            }
            writer.WriteComma();

            writer.WritePropertyName(nameof(options.Spatial));
            if (options.Spatial != null)
            {
                writer.WriteStartObject();

                writer.WritePropertyName(nameof(options.Spatial.Type));
                writer.WriteString(options.Spatial.Type.ToString());
                writer.WriteComma();

                writer.WritePropertyName(nameof(options.Spatial.MaxTreeLevel));
                writer.WriteInteger(options.Spatial.MaxTreeLevel);
                writer.WriteComma();

                writer.WritePropertyName(nameof(options.Spatial.MaxX));
                LazyStringValue lazyStringValue;
                using (lazyStringValue = context.GetLazyString(CharExtensions.ToInvariantString(options.Spatial.MaxX)))
                    writer.WriteDouble(new LazyNumberValue(lazyStringValue));
                writer.WriteComma();

                writer.WritePropertyName(nameof(options.Spatial.MaxY));
                using (lazyStringValue = context.GetLazyString(CharExtensions.ToInvariantString(options.Spatial.MaxY)))
                    writer.WriteDouble(new LazyNumberValue(lazyStringValue));
                writer.WriteComma();

                writer.WritePropertyName(nameof(options.Spatial.MinX));
                using (lazyStringValue = context.GetLazyString(CharExtensions.ToInvariantString(options.Spatial.MinX)))
                    writer.WriteDouble(new LazyNumberValue(lazyStringValue));
                writer.WriteComma();

                writer.WritePropertyName(nameof(options.Spatial.MinY));
                using (lazyStringValue = context.GetLazyString(CharExtensions.ToInvariantString(options.Spatial.MinY)))
                    writer.WriteDouble(new LazyNumberValue(lazyStringValue));
                writer.WriteComma();

                writer.WritePropertyName(nameof(options.Spatial.Strategy));
                writer.WriteString(options.Spatial.Strategy.ToString());
                writer.WriteComma();

                writer.WritePropertyName(nameof(options.Spatial.Units));
                writer.WriteString(options.Spatial.Units.ToString());

                writer.WriteEndObject();
            }
            else
            {
                writer.WriteNull();
            }

            writer.WriteEndObject();
        }
        /// <summary>
        /// Should this key commit a completion session?
        /// </summary>
        public override bool IsCommitChar(char typedChar)
        {
            if (HasActiveCompletionSession && typedChar != 0)
            {
                // only ( completes keywords
                CompletionSet completionSet  = CompletionSession.SelectedCompletionSet;
                string        completionText = completionSet.SelectionStatus.Completion.InsertionText;

                if (completionText == "else" || completionText == "repeat")
                {
                    // { after 'else' or 'repeat' completes keyword
                    if (typedChar == '{')
                    {
                        return(true);
                    }

                    // Space completes if selection is unique
                    if (char.IsWhiteSpace(typedChar) && completionSet.SelectionStatus.IsUnique)
                    {
                        return(true);
                    }

                    return(false);
                }

                // ';' completes after next or break keyword
                if (completionText == "break" || completionText == "next")
                {
                    if (typedChar == ';')
                    {
                        return(true);
                    }

                    // Space completes if selection is unique
                    if (char.IsWhiteSpace(typedChar) && completionSet.SelectionStatus.IsUnique)
                    {
                        return(true);
                    }
                }

                // Handle ( after keyword that is usually followed by expression in braces
                // such as for(), if(), library(), ...
                if (completionText == "if" || completionText == "for" || completionText == "while" ||
                    completionText == "return" || completionText == "library" || completionText == "require")
                {
                    return(typedChar == '(' || typedChar == '\t' || (char.IsWhiteSpace(typedChar) && completionSet.SelectionStatus.IsUnique));
                }

                if (typedChar == '=')
                {
                    var rset = completionSet as RCompletionSet;
                    rset?.Filter(typedChar);
                    rset?.SelectBestMatch();
                }

                bool unique = completionSet.SelectionStatus.IsUnique;
                switch (typedChar)
                {
                case '=':
                case '<':
                case '>':
                case '+':
                case '-':
                case '*':
                case '^':
                case '%':
                case '|':
                case '&':
                case '!':
                case '@':
                case '$':
                case '(':
                case '[':
                case '{':
                case ')':
                case ']':
                case '}':
                case ';':
                    return(unique);

                case ':':
                    // : completes only if not preceded by another :
                    // so we can avoid false positive when user is typing stats:::
                    var caretPosition = TextView.Caret.Position.BufferPosition;
                    if (caretPosition > 0)
                    {
                        unique &= TextView.TextBuffer.CurrentSnapshot[caretPosition - 1] != ':';
                    }
                    return(unique);
                }

                if (typedChar == ' ' && !_settings.CommitOnSpace)
                {
                    return(false);
                }

                if (CharExtensions.IsLineBreak(typedChar))
                {
                    // Complete on Enter but only if selection does not exactly match
                    // applicable span. for example, if span is X and selection is X123
                    // then we do complete. However, if selection is X then text is already
                    // fully typed and Enter should be adding new line as with regular typing.
                    if (completionSet.SelectionStatus.IsSelected)
                    {
                        var typedText = completionSet.ApplicableTo.GetText(_textBuffer.CurrentSnapshot).Trim();
                        return(completionText.Length > typedText.Length);
                    }
                }

                return(char.IsWhiteSpace(typedChar));
            }

            return(false);
        }