61 typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
64 const boost::char_separator<char> lSepatorList(
" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
67 Tokeniser_T lTokens (iPhrase, lSepatorList);
68 for (Tokeniser_T::const_iterator tok_iter = lTokens.begin();
69 tok_iter != lTokens.end(); ++tok_iter) {
70 const std::string& lTerm = *tok_iter;
71 ioWordList.push_back (lTerm);
106 unsigned short& ioSpellingErrorDistance,
107 std::string& ioQueryString,
108 std::string& ioXapianDBFilepath,
109 std::string& ioSQLDBTypeString,
110 std::string& ioSQLDBConnectionString,
111 unsigned short& ioDeploymentNumber,
112 std::string& ioLogFilename,
113 unsigned short& ioSearchType,
114 std::ostringstream& oStr) {
117 if (ioQueryString.empty() ==
true) {
126 boost::program_options::options_description generic (
"Generic options");
127 generic.add_options()
128 (
"prefix",
"print installation prefix")
129 (
"version,v",
"print version string")
130 (
"help,h",
"produce help message");
134 boost::program_options::options_description config (
"Configuration");
138 "Spelling error distance (e.g., 3)")
141 "Xapian database filepath (e.g., /tmp/opentrep/xapian_traveldb)")
144 "SQL database type (e.g., nodb for no SQL database, sqlite for SQLite, mysql for MariaDB/MySQL)")
146 boost::program_options::value< std::string >(&ioSQLDBConnectionString),
147 "SQL database connection string (e.g., ~/tmp/opentrep/sqlite_travel.db for SQLite, "
148 "\"db=trep_trep user=trep password=trep\" for MariaDB/MySQL)")
151 "Deployment number (from to N, where N=1 normally)")
154 "Filepath for the logs")
157 "Type of search request (0 = full text, 1 = coordinates)")
159 boost::program_options::value< WordList_T >(&lWordList)->multitoken(),
160 "Travel query word list (e.g. sna francisco rio de janero los angeles reykyavki), "
161 "which sould be located at the end of the command line (otherwise, "
162 "the other options would be interpreted as part of that travel query word list)")
167 boost::program_options::options_description hidden (
"Hidden options");
170 boost::program_options::value< std::vector<std::string> >(),
171 "Show the copyright (license)");
173 boost::program_options::options_description cmdline_options;
174 cmdline_options.add(generic).add(config).add(hidden);
176 boost::program_options::options_description config_file_options;
177 config_file_options.add(config).add(hidden);
179 boost::program_options::options_description visible (
"Allowed options");
180 visible.add(generic).add(config);
182 boost::program_options::positional_options_description p;
183 p.add (
"copyright", -1);
185 boost::program_options::variables_map vm;
186 boost::program_options::
187 store (boost::program_options::command_line_parser (argc, argv).
188 options (cmdline_options).positional(p).run(), vm);
190 std::ifstream ifs (
"opentrep-searcher.cfg");
191 boost::program_options::store (parse_config_file (ifs, config_file_options),
193 boost::program_options::notify (vm);
195 if (vm.count (
"help")) {
196 std::cout << visible << std::endl;
200 if (vm.count (
"version")) {
201 std::cout << PACKAGE_NAME <<
", version " << PACKAGE_VERSION << std::endl;
205 if (vm.count (
"prefix")) {
206 std::cout <<
"Installation prefix: " << PREFIXDIR << std::endl;
210 if (vm.count (
"deploymentnb")) {
211 ioDeploymentNumber = vm[
"deploymentnb"].as<
unsigned short >();
212 oStr <<
"Deployment number: " << ioDeploymentNumber << std::endl;
215 if (vm.count (
"xapiandb")) {
216 ioXapianDBFilepath = vm[
"xapiandb"].as< std::string >();
217 oStr <<
"Xapian database filepath is: " << ioXapianDBFilepath
218 << ioDeploymentNumber << std::endl;
221 if (vm.count (
"sqldbtype")) {
222 ioSQLDBTypeString = vm[
"sqldbtype"].as< std::string >();
223 oStr <<
"SQL database type is: " << ioSQLDBTypeString << std::endl;
229 ioSQLDBConnectionString =
"";
239 if (vm.count (
"sqldbconx")) {
240 ioSQLDBConnectionString = vm[
"sqldbconx"].as< std::string >();
246 const std::string& lSQLDBConnString =
248 ioSQLDBConnectionString,
251 oStr <<
"SQL database connection string is: " << lSQLDBConnString
255 if (vm.count (
"log")) {
256 ioLogFilename = vm[
"log"].as< std::string >();
257 oStr <<
"Log filename is: " << ioLogFilename << std::endl;
260 oStr <<
"The type of search is: " << ioSearchType << std::endl;
262 oStr <<
"The spelling error distance is: " << ioSpellingErrorDistance
266 oStr <<
"The travel query string is: " << ioQueryString << std::endl;
276 std::ostringstream oStr;
283 lNonMatchedWordList);
285 oStr << nbOfMatches <<
" (geographical) location(s) have been found "
286 <<
"matching your query (`" << iTravelQuery <<
"'). "
287 << lNonMatchedWordList.size() <<
" word(s) was/were left unmatched."
290 if (nbOfMatches != 0) {
292 for (OPENTREP::LocationList_T::const_iterator itLocation =
293 lLocationList.begin();
294 itLocation != lLocationList.end(); ++itLocation, ++idx) {
296 oStr <<
" [" << idx <<
"]: " << lLocation << std::endl;
300 if (lNonMatchedWordList.empty() ==
false) {
301 oStr <<
"List of unmatched words:" << std::endl;
304 for (OPENTREP::WordList_T::const_iterator itWord =
305 lNonMatchedWordList.begin();
306 itWord != lNonMatchedWordList.end(); ++itWord, ++idx) {
308 oStr <<
" [" << idx <<
"]: " << lWord << std::endl;
316int main (
int argc,
char* argv[]) {
322 std::string lLogFilename;
325 std::string lXapianDBNameStr;
328 unsigned short lSearchType;
331 unsigned short lSpellingErrorDistance;
334 std::string lSQLDBTypeStr;
337 std::string lSQLDBConnectionStr;
343 std::ostringstream oIntroStr;
346 const int lOptionParserStatus =
348 lXapianDBNameStr, lSQLDBTypeStr, lSQLDBConnectionStr,
349 lDeploymentNumber, lLogFilename, lSearchType, oIntroStr);
356 std::ofstream logOutputFile;
358 logOutputFile.open (lLogFilename.c_str());
359 logOutputFile.clear();
362 std::cout << oIntroStr.str();
366 boost::posix_time::ptime lTimeUTC =
367 boost::posix_time::second_clock::universal_time();
368 logOutputFile <<
"[" << lTimeUTC <<
"][" << __FILE__ <<
"#"
369 << __LINE__ <<
"]:Parameters:" << std::endl
370 << oIntroStr.str() << std::endl;
373 std::ostringstream oStr;
374 if (lSearchType == 0) {
380 lDBType, lSQLDBConnStr,
387 const bool lExistXapianDBDir =
389 if (lExistXapianDBDir ==
false) {
390 std::ostringstream errorStr;
391 errorStr <<
"Error - The file-path to the Xapian database/index ('"
392 << lActualXapianDBDir
393 <<
"') does not exist or is not a directory." << std::endl;
394 errorStr <<
"\tThat usually means that the OpenTREP indexer "
395 <<
"(opentrep-indexer) has not been launched yet, "
396 <<
"or that it has operated on a different Xapian "
397 <<
"database/index file-path." << std::endl;
398 errorStr <<
"\tFor instance the Xapian database/index may have been "
399 <<
"created with a different deployment number ("
400 << lDeploymentNumber <<
" being the current deployment number)";
401 std::cerr << errorStr.str() << std::endl;
406 const std::string& lOutput =
parseQuery (opentrepService, lTravelQuery);
410 oStr <<
"Finding the airports closest to: " << lTravelQuery << std::endl;
414 std::cout << oStr.str();
417 lTimeUTC = boost::posix_time::second_clock::universal_time();
418 logOutputFile <<
"[" << lTimeUTC <<
"][" << __FILE__ <<
"#"
419 << __LINE__ <<
"]:Results:" << std::endl
420 << oStr.str() << std::endl;
423 logOutputFile.close();
int readConfiguration(int argc, char *argv[], unsigned short &ioSpellingErrorDistance, std::string &ioQueryString, std::string &ioXapianDBFilepath, std::string &ioSQLDBTypeString, std::string &ioSQLDBConnectionString, unsigned short &ioDeploymentNumber, std::string &ioLogFilename, unsigned short &ioSearchType, std::ostringstream &oStr)