11 #include <boost/filesystem.hpp>
12 #include <boost/regex.hpp>
14 #include <soci/soci.h>
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);
274 const boost::regex lGeoIDCodeExp (
"^[[:digit:]]{1,11}$");
275 const bool lMatchesWithGeoID = regex_match (lWord, lGeoIDCodeExp);
281 if (lMatchesWithIATACode ==
false && lMatchesWithICAOCode ==
false
282 && lMatchesWithGeoID ==
false) {
283 areAllWordsCodes =
false;
288 return areAllWordsCodes;
313 soci::session* lSociSession_ptr =
315 if (lSociSession_ptr == NULL) {
316 std::ostringstream oStr;
317 oStr <<
"The " << iSQLDBType.
describe()
318 <<
" database is not accessible. Connection string: "
319 << iSQLDBConnStr << std::endl
320 <<
"Hint: launch the 'opentrep-dbmgr' program and "
321 <<
"see the 'tutorial' command.";
325 assert (lSociSession_ptr != NULL);
328 for (WordList_T::const_iterator itWord = iCodeList.begin();
329 itWord != iCodeList.end(); ++itWord) {
330 const std::string& lWord = *itWord;
333 const boost::regex lIATACodeExp (
"^[[:alpha:]]{3}$");
334 const bool lMatchesWithIATACode = regex_match (lWord, lIATACodeExp);
335 if (lMatchesWithIATACode ==
true) {
338 const bool lUniqueEntry =
true;
341 ioLocationList, lUniqueEntry);
342 oNbOfMatches += lNbOfEntries;
347 const boost::regex lICAOCodeExp (
"^([[:alpha:]]|[[:digit:]]){4}$");
348 const bool lMatchesWithICAOCode = regex_match (lWord, lICAOCodeExp);
349 if (lMatchesWithICAOCode ==
true) {
355 oNbOfMatches += lNbOfEntries;
360 const boost::regex lGeoIDCodeExp (
"^[[:digit:]]{1,11}$");
361 const bool lMatchesWithGeoID = regex_match (lWord, lGeoIDCodeExp);
362 if (lMatchesWithGeoID ==
true) {
372 oNbOfMatches += lNbOfEntries;
374 }
catch (boost::bad_lexical_cast& eCast) {
376 <<
"') cannot be understood.");
386 interpretTravelRequest (
const TravelDBFilePath_T& iTravelDBFilePath,
387 const DBType& iSQLDBType,
388 const SQLDBConnectionString_T& iSQLDBConnStr,
392 const OTransliterator& iTransliterator) {
396 assert (iTravelQuery.empty() ==
false);
400 boost::filesystem::path lTravelDBFilePath (iTravelDBFilePath.begin(),
401 iTravelDBFilePath.end());
402 if (!(boost::filesystem::exists (lTravelDBFilePath)
403 && boost::filesystem::is_directory (lTravelDBFilePath))) {
404 std::ostringstream oStr;
405 oStr <<
"The file-path to the Xapian database/index ('"
406 << iTravelDBFilePath <<
"') does not exist or is not a directory.";
408 throw FileNotFoundException (oStr.str());
412 Xapian::Database lXapianDatabase (iTravelDBFilePath);
416 <<
"=========================================");
420 QuerySlices lQuerySlices (lXapianDatabase, iTravelQuery, iTransliterator);
425 const TravelQuery_T& lNormalisedQueryString = lQuerySlices.getQueryString();
426 if (!(iTravelQuery == lNormalisedQueryString)) {
434 lQuerySlices.getStringPartitionList();
435 for (StringPartitionList_T::const_iterator itSlice =
436 lStringPartitionList.begin();
437 itSlice != lStringPartitionList.end(); ++itSlice) {
438 StringPartition lStringPartition = *itSlice;
439 const std::string& lTravelQuerySlice = lStringPartition.getInitialString();
446 ResultCombination& lResultCombination =
461 const bool areAllWordsCodes =
462 areAllCodeOrGeoID (lTravelQuerySlice, lCodeList);
465 if (areAllWordsCodes ==
true && !(iSQLDBType ==
DBType::NODB)) {
474 <<
") is made only of IATA/ICAO codes "
475 <<
"or Geonames ID. The " << iSQLDBType.describe()
476 <<
" SQL database (" << iSQLDBConnStr
477 <<
") will be used. "
478 <<
"The Xapian database will not be used");
482 ioLocationList, ioWordList);
485 if (lNbOfMatches == 0) {
499 <<
"The Xapian database will be used instead");
502 <<
") has got items/words, which are neither "
503 <<
"IATA/ICAO codes nor Geonames ID. "
504 <<
"The Xapian database/index will be used");
512 lResultCombination, ioWordList);
517 lResultCombination.calculateAllWeights();
535 <<
"========================================="
536 << std::endl <<
"Summary:" << std::endl
537 << lPlaceHolder.toShortString() << std::endl
538 <<
"========================================="
545 lPlaceHolder.createLocations (ioLocationList);
549 oNbOfMatches = ioLocationList.size();
const ResultList_T & getResultList() const
ResultHolder & create(const TravelQuery_T &iQueryString, const Xapian::Database &iDatabase)
bool chooseBestMatchingResultHolder()
#define OPENTREP_LOG_ERROR(iToBeLogged)
#define OPENTREP_LOG_DEBUG(iToBeLogged)
static void initLinkWithResult(ResultHolder &, Result &)
void addUnmatchedWord(const TravelQuery_T &iQueryString, WordList_T &ioWordList, WordSet_T &ioWordSet)
unsigned int GeonamesID_T
unsigned short NbOfMatches_T
static FacPlace & instance()
const ResultHolder & getBestMatchingResultHolder() const
NbOfMatches_T getLocationList(const DBType &iSQLDBType, const SQLDBConnectionString_T &iSQLDBConnStr, const WordList_T &iCodeList, LocationList_T &ioLocationList, WordList_T &ioWordList)
StringSet getCorrectedStringSet() const
Structure modelling a (geographical) location.
static FacResultCombination & instance()
const std::string describe() const
static Location retrieveLocation(const Xapian::Document &)
std::string fullTextMatch(const Xapian::Database &, const TravelQuery_T &)
static void initLinkWithResultHolder(ResultCombination &, ResultHolder &)
std::string describeShortKey() const
unsigned int NbOfDBEntries_T
std::list< StringPartition > StringPartitionList_T
Result & create(const TravelQuery_T &, const Xapian::Database &)
std::vector< std::string > WordList_T
std::list< Word_T > WordList_T
std::string describeShortKey() const
bool hasFullTextMatched() const
const Percentage_T & getBestMatchingWeight() const
static FacResult & instance()
Enumeration of database types.
static void tokeniseStringIntoWordList(const TravelQuery_T &, WordList_T &)
static NbOfDBEntries_T getPORByIATACode(soci::session &, const IATACode_T &, LocationList_T &, const bool iUniqueEntry)
std::set< std::string > WordSet_T
std::string describe() const
Class wrapping functions on a list of Result objects.
std::list< Result * > ResultList_T
Class modelling a place/POR (point of reference).
static bool shouldKeep(const std::string &iPhrase, const std::string &iWord)
std::list< Location > LocationList_T
void searchString(const StringPartition &iStringPartition, const Xapian::Database &iDatabase, ResultCombination &ioResultCombination, WordList_T &ioWordList)
ResultCombination & create(const TravelQuery_T &iQueryString)
Class wrapping functions on a list of ResultHolder objects.
std::string toString() const
static FacResultHolder & instance()
void fillPlace(Place &) const
static FacPlaceHolder & instance()
StringPartition_T _partition
static NbOfDBEntries_T getPORByGeonameID(soci::session &, const GeonamesID_T &, LocationList_T &)
static void initLinkWithPlace(PlaceHolder &, Place &)
std::string toString() const
Class holding a set of strings, e.g., {"rio", "de", "janeiro"}.
std::string TravelQuery_T
void createPlaces(const ResultCombination &iResultCombination, PlaceHolder &ioPlaceHolder)
void chooseBestMatchingResultHolder(ResultCombination &ioResultCombination)
static NbOfDBEntries_T getPORByICAOCode(soci::session &, const ICAOCode_T &, LocationList_T &)
static soci::session * initSQLDBSession(const DBType &, const SQLDBConnectionString_T &)
Class wrapping a set of Xapian documents having matched a given query string.
const RawDataString_T & getBestDocData() const