11#include <boost/filesystem.hpp>
12#include <boost/regex.hpp>
55 lQueryStringWordList);
56 if (lQueryStringWordList.size() == 1) {
62 WordSet_T::const_iterator itWord = ioWordSet.find (iQueryString);
63 if (shouldBeKept ==
true && itWord == ioWordSet.end()) {
64 ioWordSet.insert (iQueryString);
65 ioWordList.push_back (iQueryString);
80 for (ResultList_T::const_iterator itResult = lResultList.begin();
81 itResult != lResultList.end(); ++itResult) {
83 const Result* lResult_ptr = *itResult;
84 assert (lResult_ptr != NULL);
91 if (hasFullTextMatched ==
false) {
94 assert (hasFullTextMatched ==
true);
132 const Xapian::Database& iDatabase,
143 for (StringPartition::StringPartition_T::const_iterator itSet =
145 itSet != iStringPartition.
_partition.end(); ++itSet) {
161 for (StringSet::StringSet_T::const_iterator itString =
162 lStringSet.
_set.begin();
163 itString != lStringSet.
_set.end(); ++itString) {
165 const std::string lQueryString (*itString);
180 const std::string& lMatchedString =
185 if (lMatchedString.empty() ==
true) {
192 <<
"========================================="
193 << std::endl <<
"Result holder: "
194 << lResultHolder.
toString() << std::endl
195 <<
"========================================="
196 << std::endl << std::endl);
202 }
catch (
const Xapian::Error& error) {
229 const bool doesBestMatchingResultHolderExist =
232 if (doesBestMatchingResultHolderExist ==
true) {
242 <<
", and has got a weight of "
244 <<
"%. The corrected string set is: "
245 << lCorrectedStringSet);
255 bool RequestInterpreter::areAllCodeOrGeoID (
const TravelQuery_T& iQueryString,
257 bool areAllWordsCodes =
true;
261 for (WordList_T::const_iterator itWord = ioWordList.begin();
262 itWord != ioWordList.end(); ++itWord) {
263 const std::string& lWord = *itWord;
266 const boost::regex lIATACodeExp (
"^[[:alpha:]]{3}$");
267 const bool lMatchesWithIATACode = regex_match (lWord, lIATACodeExp);
270 const boost::regex lICAOCodeExp (
"^([[:alpha:]]|[[:digit:]]){4}$");
271 const bool lMatchesWithICAOCode = regex_match (lWord, lICAOCodeExp);
275 lUNLOCodeExp (
"^[[:alpha:]]{2}([[:alpha:]]|[[:digit:]]){3}$");
276 const bool lMatchesWithUNLOCode = regex_match (lWord, lUNLOCodeExp);
279 const boost::regex lGeoIDCodeExp (
"^[[:digit:]]{1,12}$");
280 const bool lMatchesWithGeoID = regex_match (lWord, lGeoIDCodeExp);
286 if (lMatchesWithIATACode ==
false && lMatchesWithICAOCode ==
false
287 && lMatchesWithUNLOCode ==
false && lMatchesWithGeoID ==
false) {
288 areAllWordsCodes =
false;
293 return areAllWordsCodes;
307 for (LocationList_T::const_iterator itLocation = iLocationList.begin();
308 itLocation != iLocationList.end(); ++itLocation) {
309 const Location& lLocation = *itLocation;
313 if (lPageRank > lMaxPageRank) {
314 lMaxPageRank = lPageRank;
315 oLocation = lLocation;
344 soci::session* lSociSession_ptr =
346 if (lSociSession_ptr == NULL) {
347 std::ostringstream oStr;
348 oStr <<
"The " << iSQLDBType.
describe()
349 <<
" database is not accessible. Connection string: "
350 << iSQLDBConnStr << std::endl
351 <<
"Hint: launch the 'opentrep-dbmgr' program and "
352 <<
"see the 'tutorial' command.";
356 assert (lSociSession_ptr != NULL);
359 for (WordList_T::const_iterator itWord = iCodeList.begin();
360 itWord != iCodeList.end(); ++itWord) {
361 const std::string& lWord = *itWord;
364 const boost::regex lIATACodeExp (
"^[[:alpha:]]{3}$");
365 const bool lMatchesWithIATACode = regex_match (lWord, lIATACodeExp);
366 if (lMatchesWithIATACode ==
true) {
369 const bool lUniqueEntry =
true;
372 ioLocationList, lUniqueEntry);
373 oNbOfMatches += lNbOfEntries;
378 const boost::regex lICAOCodeExp (
"^([[:alpha:]]|[[:digit:]]){4}$");
379 const bool lMatchesWithICAOCode = regex_match (lWord, lICAOCodeExp);
380 if (lMatchesWithICAOCode ==
true) {
386 oNbOfMatches += lNbOfEntries;
392 lUNLOCodeExp (
"^[[:alpha:]]{2}([[:alpha:]]|[[:digit:]]){3}$");
393 const bool lMatchesWithUNLOCode = regex_match (lWord, lUNLOCodeExp);
394 if (lMatchesWithUNLOCode ==
true) {
397 const bool lUniqueEntry =
true;
400 ioLocationList, lUniqueEntry);
401 oNbOfMatches += lNbOfEntries;
406 const boost::regex lGeoIDCodeExp (
"^[[:digit:]]{1,12}$");
407 const bool lMatchesWithGeoID = regex_match (lWord, lGeoIDCodeExp);
408 if (lMatchesWithGeoID ==
true) {
412 boost::lexical_cast<GeonamesID_T> (lWord);
418 oNbOfMatches += lNbOfEntries;
420 }
catch (boost::bad_lexical_cast& eCast) {
422 <<
"') cannot be understood.");
432 interpretTravelRequest (
const TravelDBFilePath_T& iTravelDBFilePath,
433 const DBType& iSQLDBType,
434 const SQLDBConnectionString_T& iSQLDBConnStr,
438 const OTransliterator& iTransliterator) {
442 assert (iTravelQuery.empty() ==
false);
446 boost::filesystem::path lTravelDBFilePath (iTravelDBFilePath.begin(),
447 iTravelDBFilePath.end());
448 if (!(boost::filesystem::exists (lTravelDBFilePath)
449 && boost::filesystem::is_directory (lTravelDBFilePath))) {
450 std::ostringstream oStr;
451 oStr <<
"The file-path to the Xapian database/index ('"
452 << iTravelDBFilePath <<
"') does not exist or is not a directory. ";
453 oStr <<
"That usually means that the OpenTREP indexer (opentrep-indexer) "
454 <<
"has not been launched yet, or that it has operated "
455 <<
"on a different Xapian database/index file-path.";
457 throw FileNotFoundException (oStr.str());
461 Xapian::Database lXapianDatabase (iTravelDBFilePath);
465 <<
"=========================================");
469 QuerySlices lQuerySlices (lXapianDatabase, iTravelQuery, iTransliterator);
474 const TravelQuery_T& lNormalisedQueryString = lQuerySlices.getQueryString();
475 if (!(iTravelQuery == lNormalisedQueryString)) {
483 lQuerySlices.getStringPartitionList();
484 for (StringPartitionList_T::const_iterator itSlice =
485 lStringPartitionList.begin();
486 itSlice != lStringPartitionList.end(); ++itSlice) {
487 StringPartition lStringPartition = *itSlice;
488 const std::string& lTravelQuerySlice = lStringPartition.getInitialString();
495 ResultCombination& lResultCombination =
509 const bool areAllWordsCodes =
510 areAllCodeOrGeoID (lTravelQuerySlice, lCodeList);
513 if (areAllWordsCodes ==
true && !(iSQLDBType ==
DBType::NODB)) {
522 <<
") is made only of IATA/ICAO/UNLOCODE codes "
523 <<
"or Geonames ID. The " << iSQLDBType.describe()
524 <<
" SQL database (" << iSQLDBConnStr
525 <<
") will be used. "
526 <<
"The Xapian database/index will not be used");
529 ioLocationList, ioWordList);
532 if (lNbOfMatches == 0) {
546 <<
"The Xapian database will be used instead");
549 <<
") has got items/words, which are neither "
550 <<
"IATA/ICAO codes nor Geonames ID. "
551 <<
"The Xapian database/index will be used");
559 lResultCombination, ioWordList);
564 lResultCombination.calculateAllWeights();
582 <<
"========================================="
583 << std::endl <<
"Summary:" << std::endl
584 << lPlaceHolder.toShortString() << std::endl
585 <<
"========================================="
592 lPlaceHolder.createLocations (ioLocationList);
596 oNbOfMatches = ioLocationList.size();
#define OPENTREP_LOG_ERROR(iToBeLogged)
#define OPENTREP_LOG_DEBUG(iToBeLogged)
static NbOfDBEntries_T getPORByICAOCode(soci::session &, const ICAOCode_T &, LocationList_T &)
static soci::session * initSQLDBSession(const DBType &, const SQLDBConnectionString_T &)
static NbOfDBEntries_T getPORByUNLOCode(soci::session &, const UNLOCode_T &, LocationList_T &, const bool iUniqueEntry)
static NbOfDBEntries_T getPORByGeonameID(soci::session &, const GeonamesID_T &, LocationList_T &)
static NbOfDBEntries_T getPORByIATACode(soci::session &, const IATACode_T &, LocationList_T &, const bool iUniqueEntry)
static FacPlaceHolder & instance()
static void initLinkWithPlace(PlaceHolder &, Place &)
static FacPlace & instance()
static void initLinkWithResultHolder(ResultCombination &, ResultHolder &)
static FacResultCombination & instance()
ResultCombination & create(const TravelQuery_T &iQueryString)
static void initLinkWithResult(ResultHolder &, Result &)
static FacResultHolder & instance()
ResultHolder & create(const TravelQuery_T &iQueryString, const Xapian::Database &iDatabase)
Result & create(const TravelQuery_T &, const Xapian::Database &)
static FacResult & instance()
Class modelling a place/POR (point of reference).
std::string toString() const
Class wrapping functions on a list of ResultHolder objects.
const ResultHolder & getBestMatchingResultHolder() const
bool chooseBestMatchingResultHolder()
StringSet getCorrectedStringSet() const
const Percentage_T & getBestMatchingWeight() const
std::string describeShortKey() const
Class wrapping functions on a list of Result objects.
std::string describeShortKey() const
const ResultList_T & getResultList() const
std::string toString() const
Class wrapping a set of Xapian documents having matched a given query string.
std::string fullTextMatch(const Xapian::Database &, const TravelQuery_T &)
bool hasFullTextMatched() const
const RawDataString_T & getBestDocData() const
void fillPlace(Place &) const
static Location retrieveLocation(const Xapian::Document &)
static void tokeniseStringIntoWordList(const TravelQuery_T &, WordList_T &)
std::list< Word_T > WordList_T
void addUnmatchedWord(const TravelQuery_T &iQueryString, WordList_T &ioWordList, WordSet_T &ioWordSet)
void chooseBestMatchingResultHolder(ResultCombination &ioResultCombination)
unsigned int NbOfDBEntries_T
std::string TravelQuery_T
void searchString(const StringPartition &iStringPartition, const Xapian::Database &iDatabase, ResultCombination &ioResultCombination, WordList_T &ioWordList)
std::list< Location > LocationList_T
void createPlaces(const ResultCombination &iResultCombination, PlaceHolder &ioPlaceHolder)
NbOfMatches_T getLocationList(const DBType &iSQLDBType, const SQLDBConnectionString_T &iSQLDBConnStr, const WordList_T &iCodeList, LocationList_T &ioLocationList, WordList_T &ioWordList)
Location getBestMatchingLocation(const LocationList_T &iLocationList)
std::set< std::string > WordSet_T
unsigned short NbOfMatches_T
unsigned int GeonamesID_T
std::list< Result * > ResultList_T
std::list< StringPartition > StringPartitionList_T
std::vector< std::string > WordList_T
Enumeration of database types.
const std::string describe() const
static bool shouldKeep(const std::string &iPhrase, const std::string &iWord)
Structure modelling a (geographical) location.
const PageRank_T & getPageRank() const
StringPartition_T _partition
Class holding a set of strings, e.g., {"rio", "de", "janeiro"}.
std::string describe() const