Example #1
0
        /// <summary>
        ///  Each of the query words must be found in at least one field ∀w ∃f
        /// </summary>
        public SearchResult IsMatch(BaseNode node)
        {
            SearchResult result = null;

            if (node == null)
            {
                return(null);
            }

            if (NodeIndex > -1)
            {
                if (node is TimedNode timedNode && timedNode.Index == NodeIndex)
                {
                    result = new SearchResult(node);
                    var prefix = "Node id: ";
                    result.AddMatch(prefix + NodeIndex.ToString(), NodeIndex.ToString());
                    return(result);
                }
            }

            var searchFields = PopulateSearchFields(node);

            if (TypeKeyword != null)
            {
                // zeroth field is always the type
                if (string.Equals(TypeKeyword, searchFields.array[0], StringComparison.OrdinalIgnoreCase) ||
                    // special case for types derived from Task, $task should still work
                    (TypeKeyword == "task" && searchFields.count > 1 && searchFields.array[1] == "Task"))
                {
                    // this node is of the type that we need, search other fields
                    if (result == null)
                    {
                        result = new SearchResult(node, IncludeDuration, IncludeStart, IncludeEnd);
                    }

                    result.AddMatchByNodeType();
                }
                else
                {
                    return(null);
                }
            }

            bool nameMatched  = false;
            bool valueMatched = false;

            for (int i = 0; i < Words.Count; i++)
            {
                bool anyFieldMatched = false;
                var  term            = Words[i];
                var  word            = term.Word;

                for (int j = 0; j < searchFields.count; j++)
                {
                    var field = searchFields.array[j];

                    //if (!stringCache.Contains(field))
                    //{
                    //}

                    if (!term.IsMatch(field, MatchesInStrings[i]))
                    {
                        continue;
                    }

                    if (result == null)
                    {
                        result = new SearchResult(node, IncludeDuration, IncludeStart, IncludeEnd);
                    }

                    // if matched on the type of the node (always field 0), special case it
                    if (j == 0)
                    {
                        result.AddMatchByNodeType();
                    }
                    else
                    {
                        string fullText      = field;
                        var    nameValueNode = node as NameValueNode;

                        // NameValueNode is a special case: have to check in which field to search
                        if (nameValueNode != null && (nameToSearch != default || valueToSearch != default))
                        {
                            if (j == 1 && term == nameToSearch)
                            {
                                result.AddMatch(fullText, word, addAtBeginning: true);
                                nameMatched     = true;
                                anyFieldMatched = true;
                                break;
                            }

                            if (j == 2 && term == valueToSearch)
                            {
                                result.AddMatch(fullText, word);
                                valueMatched    = true;
                                anyFieldMatched = true;
                                break;
                            }
                        }
                        else
                        {
                            result.AddMatch(fullText, word);
                            anyFieldMatched = true;
                            break;
                        }
                    }
                }

                if (!anyFieldMatched)
                {
                    return(null);
                }
            }

            if (result == null)
            {
                return(null);
            }

            if (nameToSearch != default && valueToSearch != default && (!nameMatched || !valueMatched))
            {
                return(null);
            }

            bool showResult = IncludeMatchers.Count == 0;

            foreach (NodeQueryMatcher matcher in IncludeMatchers)
            {
                if (!showResult)
                {
                    showResult = IsUnder(matcher, result);
                }
            }

            if (!showResult)
            {
                return(null);
            }

            foreach (NodeQueryMatcher matcher in ExcludeMatchers)
            {
                if (IsUnder(matcher, result))
                {
                    return(null);
                }
            }

            return(result);
        }