From 5761b223dcab23b580ea74da0732cbb31348b8cc Mon Sep 17 00:00:00 2001 From: Felix Meisen Date: Fri, 14 Feb 2025 00:27:06 +0100 Subject: [PATCH] Reformatting the TextSearchQuery.cpp --- src/parser/TextSearchQuery.cpp | 211 ++++++++++++++++++--------------- src/parser/TextSearchQuery.h | 28 +++++ 2 files changed, 146 insertions(+), 93 deletions(-) diff --git a/src/parser/TextSearchQuery.cpp b/src/parser/TextSearchQuery.cpp index b8c72f1179..932fe22dbe 100644 --- a/src/parser/TextSearchQuery.cpp +++ b/src/parser/TextSearchQuery.cpp @@ -10,105 +10,135 @@ namespace parsedQuery { +// ____________________________________________________________________________ +void TextSearchQuery::throwSubjectVariableException( + std::string predString, const TripleComponent& subject) { + if (!subject.isVariable()) { + throw TextSearchException( + absl::StrCat("The predicate <", std::move(predString), + "> needs a Variable as Variable as subject.")); + } +} + +// ____________________________________________________________________________ +void TextSearchQuery::throwSubjectAndObjectVariableException( + std::string predString, const TripleComponent& subject, + const TripleComponent& object) { + if (!(subject.isVariable() && object.isVariable())) { + throw TextSearchException( + absl::StrCat("The predicate <", std::move(predString), + "> needs a Variable as subject and one as object.")); + } +} + +// ____________________________________________________________________________ +void TextSearchQuery::throwContainsWordOrEntity( + const TripleComponent& subject) { + if (configVarToConfigs_[subject.getVariable()].isWordSearch_.has_value()) { + throw TextSearchException( + "Each search should have exactly one occurrence of either " + " or "); + } +} + +// ____________________________________________________________________________ +void TextSearchQuery::predStringTextSearch(const Variable& subjectVar, + const Variable& objectVar) { + if (configVarToConfigs_[objectVar].textVar_.has_value()) { + throw TextSearchException( + absl::StrCat("Each search should only be linked to a single text " + "Variable. The text variable was: ", + configVarToConfigs_[objectVar].textVar_.value().name(), + "The config variable was: ", objectVar.name())); + } + configVarToConfigs_[objectVar].textVar_ = subjectVar; +} + +// ____________________________________________________________________________ +void TextSearchQuery::predStringContainsWord( + const Variable& subjectVar, const TripleComponent::Literal& objectLiteral) { + configVarToConfigs_[subjectVar].isWordSearch_ = true; + std::string_view literal = asStringViewUnsafe(objectLiteral.getContent()); + if (literal.empty()) { + throw TextSearchException( + "The predicate shouldn't have an empty literal as " + "object."); + } + configVarToConfigs_[subjectVar].word_ = literal; +} + +// ____________________________________________________________________________ +void TextSearchQuery::predStringContainsEntity(const TripleComponent& subject, + const TripleComponent& object) { + if (!subject.isVariable()) { + throw TextSearchException( + "The predicate needs a Variable as subject and a " + "Literal or Variable as object."); + } + throwContainsWordOrEntity(subject); + configVarToConfigs_[subject.getVariable()].isWordSearch_ = false; + if (object.isLiteral()) { + configVarToConfigs_[subject.getVariable()].entity_ = + std::string(asStringViewUnsafe(object.getLiteral().getContent())); + } else if (object.isVariable()) { + configVarToConfigs_[subject.getVariable()].entity_ = object.getVariable(); + } else { + throw TextSearchException( + "The predicate needs a Variable as subject and a " + "Literal or Variable as object."); + } +} + +// ____________________________________________________________________________ +void TextSearchQuery::predStringBindMatch(const Variable& subjectVar, + const Variable& objectVar) { + if (configVarToConfigs_[subjectVar].varToBindMatch_.has_value()) { + throw TextSearchException( + "A text search should only contain one ."); + } + configVarToConfigs_[subjectVar].varToBindMatch_ = objectVar; +} + +// ____________________________________________________________________________ +void TextSearchQuery::predStringBindScore(const Variable& subjectVar, + const Variable& objectVar) { + if (configVarToConfigs_[subjectVar].varToBindScore_.has_value()) { + throw TextSearchException( + "A text search should only contain one ."); + } + configVarToConfigs_[subjectVar].varToBindScore_ = objectVar; +} + // ____________________________________________________________________________ void TextSearchQuery::addParameter(const SparqlTriple& triple) { auto simpleTriple = triple.getSimple(); - TripleComponent subject = simpleTriple.s_; - TripleComponent predicate = simpleTriple.p_; - TripleComponent object = simpleTriple.o_; + const TripleComponent& subject = simpleTriple.s_; + const TripleComponent& predicate = simpleTriple.p_; + const TripleComponent& object = simpleTriple.o_; auto predString = extractParameterName(predicate, TEXT_SEARCH_IRI); - auto throwVariableException = [predString, subject, object]() { - if (!(subject.isVariable() && object.isVariable())) { - throw TextSearchException( - absl::StrCat("The predicate <", predString, - "> needs a Variable as subject and one as object.")); - } - }; - if (predString == "text-search") { - if (!(subject.isVariable() && object.isVariable())) { - throw TextSearchException( - "The predicate needs a Variable as subject and one as " - "object."); - } - if (configVarToConfigs_[object.getVariable()].textVar_.has_value()) { - throw TextSearchException( - "Each search should be linked to only on text Variable."); - } - configVarToConfigs_[object.getVariable()].textVar_ = subject.getVariable(); + throwSubjectAndObjectVariableException("text-search", subject, object); + predStringTextSearch(subject.getVariable(), object.getVariable()); } else if (predString == "contains-word") { - if (!(subject.isVariable() && object.isLiteral())) { - throw TextSearchException( - "The predicate needs a Variable as subject and a " - "Literal as object."); - } - if (configVarToConfigs_[subject.getVariable()].isWordSearch_.has_value()) { - if (configVarToConfigs_[subject.getVariable()].isWordSearch_.value()) { - throw TextSearchException( - "One search should only contain one ."); - } else { - throw TextSearchException( - "One search should contain either or " - "."); - } - } - configVarToConfigs_[subject.getVariable()].isWordSearch_ = true; - std::string_view literal = object.getLiteral().toStringRepresentation(); - literal = std::string(literal.substr(1, literal.size() - 2)); - if (literal.empty()) { + throwSubjectVariableException("contains-word", subject); + throwContainsWordOrEntity(subject); + if (!object.isLiteral()) { throw TextSearchException( - "The predicate shouldn't have an empty literal as " - "object."); + "The predicate only accepts a literal as object."); } - configVarToConfigs_[subject.getVariable()].word_ = literal; + predStringContainsWord(subject.getVariable(), object.getLiteral()); } else if (predString == "contains-entity") { - if (!subject.isVariable()) { - throw TextSearchException( - "The predicate needs a Variable as subject and a " - "Literal or Variable as object."); - } - if (configVarToConfigs_[subject.getVariable()].isWordSearch_.has_value()) { - if (configVarToConfigs_[subject.getVariable()].isWordSearch_.value()) { - throw TextSearchException( - "One search should contain either or " - "."); - } else { - throw TextSearchException( - "One search should only contain one ."); - } - } - configVarToConfigs_[subject.getVariable()].isWordSearch_ = false; - if (object.isLiteral()) { - std::string_view literal = object.getLiteral().toStringRepresentation(); - configVarToConfigs_[subject.getVariable()].entity_ = - std::string(literal.substr(1, literal.size() - 2)); - } else if (object.isVariable()) { - configVarToConfigs_[subject.getVariable()].entity_ = object.getVariable(); - } else { - throw TextSearchException( - "The predicate needs a Variable as subject and a " - "Literal or Variable as object."); - } + throwSubjectVariableException("contains-word", subject); + throwContainsWordOrEntity(subject); + predStringContainsEntity(subject, object); } else if (predString == "bind-match") { - throwVariableException(); - if (configVarToConfigs_[subject.getVariable()] - .varToBindMatch_.has_value()) { - throw TextSearchException( - "A text search should only contain one ."); - } - configVarToConfigs_[subject.getVariable()].varToBindMatch_ = - object.getVariable(); + throwSubjectAndObjectVariableException("bind-match", subject, object); + predStringBindMatch(subject.getVariable(), object.getVariable()); } else if (predString == "bind-score") { - throwVariableException(); - if (configVarToConfigs_[subject.getVariable()] - .varToBindScore_.has_value()) { - throw TextSearchException( - "A text search should only contain one ."); - } - configVarToConfigs_[subject.getVariable()].varToBindScore_ = - object.getVariable(); + throwSubjectAndObjectVariableException("bind-score", subject, object); + predStringBindScore(subject.getVariable(), object.getVariable()); } } @@ -132,13 +162,8 @@ TextSearchQuery::toConfigs(QueryExecutionContext* qec) const { "Text search service needs a text variable to search."); } if (conf.isWordSearch_.value()) { - auto it = potentialTermsForCvar.find(conf.textVar_.value()); - if (it == potentialTermsForCvar.end()) { - potentialTermsForCvar.insert( - {conf.textVar_.value(), {conf.word_.value()}}); - } else { - it->second.push_back(conf.word_.value()); - } + potentialTermsForCvar[conf.textVar_.value()].push_back( + conf.word_.value()); } } // Second pass to create all configs diff --git a/src/parser/TextSearchQuery.h b/src/parser/TextSearchQuery.h index 912ad896b6..e9e9d9753d 100644 --- a/src/parser/TextSearchQuery.h +++ b/src/parser/TextSearchQuery.h @@ -35,6 +35,34 @@ struct TextSearchQuery : MagicServiceQuery { std::vector> toConfigs(QueryExecutionContext* qec) const; + + // Helper functions for addParameter + + // Checks if subject is a variable. If not throws exception. + void throwSubjectVariableException(std::string predString, + const TripleComponent& subject); + // Checks if object and subject are variables. If not throws exception. + void throwSubjectAndObjectVariableException(std::string predString, + const TripleComponent& subject, + const TripleComponent& object); + // Checks if query already encountered or + // before this. If yes throws exception. + void throwContainsWordOrEntity(const TripleComponent& subject); + + void predStringTextSearch(const Variable& subjectVar, + const Variable& objectVar); + + void predStringContainsWord(const Variable& subjectVar, + const TripleComponent::Literal& objectLiteral); + + void predStringContainsEntity(const TripleComponent& subject, + const TripleComponent& object); + + void predStringBindMatch(const Variable& subjectVar, + const Variable& objectVar); + + void predStringBindScore(const Variable& subjectVar, + const Variable& objectVar); }; } // namespace parsedQuery