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);
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();