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) {
366 boost::lexical_cast<GeonamesID_T> (lWord);
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();