Exemple #1
0
        public T CompileField(FieldTerm field)
        {
            if (field == null)
            {
                throw new ArgumentNullException(nameof(field));
            }

            switch (field.Field)
            {
            case null:
                return(this.TextSearch(field.Value));

            case "@":
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                if (int.TryParse(field.Value, out var personId))
                {
                    if (personId == 0)
                    {
                        return(this.NoPerson());
                    }
                    else
                    {
                        return(this.PersonId(personId));
                    }
                }
                else
                {
                    return(this.PersonName(field.Value));
                }

            case "type":
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                var ix = field.Value.IndexOf('/');
                if (ix < 0)
                {
                    return(this.ParentCompiler.CompileDisjunction(new[]
                    {
                        this.TypeEquals(field.Value),
                        this.TypePrefixed(field.Value + "/"),
                    }));
                }
                else if (ix == field.Value.Length - 1)
                {
                    return(this.TypePrefixed(field.Value));
                }
                else
                {
                    return(this.TypeEquals(field.Value));
                }

            case "tag":
            {
                var tagInfo = this.TagEngine[field.Value];
                if (this.ExcludeHidden && (tagInfo.Tag == "hidden" || tagInfo.Ancestors.Contains("hidden")))
                {
                    this.ExcludeHidden = false;
                }

                var tags = tagInfo.RelatedTags(TagDialect.TagRelationships[field.Operator]);
                tags = tags.Union(tags.SelectMany(this.TagEngine.GetTagAliases));
                return(this.Tag(tags));
            }

            case "rejected":
            {
                var tagInfo = this.TagEngine[field.Value];
                var tags    = tagInfo.RelatedTags(TagDialect.TagRelationships[field.Operator]);
                tags = tags.Union(tags.SelectMany(this.TagEngine.GetTagAliases));
                return(this.RejectedTag(tags));
            }

            case "~":
            {
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                return(this.ParentCompiler.CompileConjunction(new[]
                    {
                        this.ParentCompiler.CompileNegation(this.CompileField(new FieldTerm("tag", FieldTerm.LessThanOrEqualOperator, field.Value))),
                        this.ParentCompiler.CompileNegation(this.CompileField(new FieldTerm("rejected", FieldTerm.GreaterThanOrEqualOperator, field.Value))),
                    }));
            }

            case "?":
            case "suggested":
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                return(this.CompileTagRelation(TagOperator.Suggestion, field.Value));

            case "^":
            case "missing":
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                return(this.CompileTagRelation(TagOperator.Implication, field.Value));

            case "similar":
            {
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                var visualHash = Convert.ToUInt64(field.Value, 16);
                return(this.ParentCompiler.CompileDisjunction(
                           AverageIntensityHash.Expand(visualHash, mode: 1).Select(h => this.Details(ImageDetailRecognizer.Properties.AverageIntensityHash, FieldTerm.EqualsOperator, (long)h))));
            }

            case "copies":
                if (!int.TryParse(field.Value, out var copies))
                {
                    throw new NotSupportedException($"Cannot use non-numeric value '{field.Value}' with field '{field.Field}'.");
                }

                return(this.Copies(field.Operator, copies));

            case "tags":
                if (!int.TryParse(field.Value, out var tagCount))
                {
                    throw new NotSupportedException($"Cannot use non-numeric value '{field.Value}' with field '{field.Field}'.");
                }

                return(this.TagCount(field.Operator, tagCount));

            case "people":
                if (!int.TryParse(field.Value, out var peopleCount))
                {
                    throw new NotSupportedException($"Cannot use non-numeric value '{field.Value}' with field '{field.Field}'.");
                }

                return(this.PersonCount(field.Operator, peopleCount));

            case "rating":
                if (!double.TryParse(field.Value, out var rating))
                {
                    throw new NotSupportedException($"Cannot use non-numeric value '{field.Value}' with field '{field.Field}'.");
                }

                return(this.Rating(field.Operator, rating));

            case "stars":
                if (!int.TryParse(field.Value, out var stars))
                {
                    throw new NotSupportedException($"Cannot use non-numeric value '{field.Value}' with field '{field.Field}'.");
                }
                else if (stars < 1 || stars > 5)
                {
                    throw new NotSupportedException($"Field '{field.Field}' expects a value between 1 and 5.");
                }

                return(this.Stars(field.Operator, stars));

            case "hash":
                return(this.Hash(field.Operator, field.Value));

            default:
                throw new NotSupportedException();
            }
        }
 /// <inheritdoc/>
 public override string CompileField(FieldTerm field)
 {
     return(this.dialect.CompileField(field));
 }
Exemple #3
0
        /// <inheritdoc/>
        public override string CompileField(FieldTerm field)
        {
            if (field == null)
            {
                throw new ArgumentNullException(nameof(field));
            }

            switch (field.Field)
            {
            case "@":
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                if (int.TryParse(field.Value, out var personId))
                {
                    if (personId == 0)
                    {
                        return($"NOT EXISTS (SELECT 1 FROM HashPerson p WHERE h.Hash = p.Hash)");
                    }
                    else
                    {
                        return($"EXISTS (SELECT 1 FROM HashPerson p WHERE h.Hash = p.Hash AND p.PersonId = {personId})");
                    }
                }
                else
                {
                    return($"EXISTS (SELECT 1 FROM HashPerson hp INNER JOIN Names p ON hp.PersonId = p.PersonId WHERE h.Hash = hp.Hash AND {Contains("p.Name", field.Value)})");
                }

            case "type":
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                var ix = field.Value.IndexOf('/');
                return
                    (ix < 0 ? $"FileType = {Literal(field.Value)} OR {StartsWith("FileType", field.Value + "/")}" :
                     ix == field.Value.Length - 1 ? StartsWith("FileType", field.Value) :
                     $"FileType = {Literal(field.Value)}");

            case "tag":
                if (field.Operator != FieldTerm.EqualsOperator)
                {
                    throw new NotSupportedException($"Cannot use operator '{field.Operator}' with field '{field.Field}'.");
                }

                if (this.excludeHidden && (field.Value == "hidden" || this.tagEngine.GetTagAncestors(field.Value).Contains("hidden")))
                {
                    this.excludeHidden = false;
                }

                var tags = this.tagEngine.GetTagDescendants(field.Value).Add(field.Value);
                return($"EXISTS (SELECT 1 FROM HashTag t WHERE h.Hash = t.Hash AND t.Tag IN ({string.Join(", ", tags.Select(Literal))}))");

            case "copies":
                this.joinCopies = true;
                if (!int.TryParse(field.Value, out var copies))
                {
                    throw new NotSupportedException($"Cannot use non-numeric value '{field.Value}' with field '{field.Field}'.");
                }

                return($"COALESCE(c.Copies, 0) {ConvertOperator(field.Operator)} {copies}");

            default:
                throw new NotSupportedException();
            }
        }
 /// <inheritdoc/>
 public override Predicate <SearchResult> CompileField(FieldTerm field)
 {
     return(this.dialect.CompileField(field));
 }