90 std::string& ioPORFilepath,
91 std::string& ioXapianDBFilepath,
92 std::string& ioSQLDBTypeString,
93 std::string& ioSQLDBConnectionString,
94 unsigned short& ioDeploymentNumber,
95 bool& ioIncludeNonIATAPOR,
96 bool& ioIndexPORInXapian,
98 std::string& ioLogFilename) {
101 boost::program_options::options_description generic (
"Generic options");
102 generic.add_options()
103 (
"prefix",
"print installation prefix")
104 (
"version,v",
"print version string")
105 (
"help,h",
"produce help message");
109 boost::program_options::options_description config (
"Configuration");
113 "POR file-path (e.g., ori_por_public.csv)")
116 "Xapian database filepath (e.g., /tmp/opentrep/xapian_traveldb)")
119 "SQL database type (e.g., nodb for no SQL database, sqlite for SQLite, mysql for MariaDB/MySQL)")
121 boost::program_options::value< std::string >(&ioSQLDBConnectionString),
122 "SQL database connection string (e.g., ~/tmp/opentrep/sqlite_travel.db for SQLite, \"db=trep_trep user=trep password=trep\" for MariaDB/MySQL)")
125 "Deployment number (from to N, where N=1 normally)")
128 "Whether or not to include POR not referenced by IATA (0 = only IATA-referenced POR, 1 = all POR are included)")
131 "Whether or not to index the POR in Xapian (0 = do not touch the Xapian index, 1 = re-index all the POR in Xapian)")
134 "Whether or not to add and index the POR in the SQL-based database (0 = do not touch the SQL-based database, 1 = add and re-index all the POR in the SQL-based database)")
137 "Filepath for the logs")
142 boost::program_options::options_description hidden (
"Hidden options");
145 boost::program_options::value< std::vector<std::string> >(),
146 "Show the copyright (license)");
148 boost::program_options::options_description cmdline_options;
149 cmdline_options.add(generic).add(config).add(hidden);
151 boost::program_options::options_description config_file_options;
152 config_file_options.add(config).add(hidden);
154 boost::program_options::options_description visible (
"Allowed options");
155 visible.add(generic).add(config);
157 boost::program_options::positional_options_description p;
158 p.add (
"copyright", -1);
160 boost::program_options::variables_map vm;
161 boost::program_options::
162 store (boost::program_options::command_line_parser (argc, argv).
163 options (cmdline_options).positional(p).run(), vm);
165 std::ifstream ifs (
"opentrep-dbmgr.cfg");
166 boost::program_options::store (parse_config_file (ifs, config_file_options),
168 boost::program_options::notify (vm);
170 if (vm.count (
"help")) {
171 std::cout << visible << std::endl;
175 if (vm.count (
"version")) {
176 std::cout << PACKAGE_NAME <<
", version " << PACKAGE_VERSION << std::endl;
180 if (vm.count (
"prefix")) {
181 std::cout <<
"Installation prefix: " << PREFIXDIR << std::endl;
185 if (vm.count (
"porfile")) {
186 ioPORFilepath = vm[
"porfile"].as< std::string >();
189 if (vm.count (
"deploymentnb")) {
190 ioDeploymentNumber = vm[
"deploymentnb"].as<
unsigned short >();
191 std::cout <<
"Deployment number " << ioDeploymentNumber << std::endl;
194 if (vm.count (
"xapiandb")) {
195 ioXapianDBFilepath = vm[
"xapiandb"].as< std::string >();
196 std::cout <<
"Xapian index/database filepath is: " << ioXapianDBFilepath
197 << ioDeploymentNumber << std::endl;
201 if (vm.count (
"sqldbtype")) {
202 ioSQLDBTypeString = vm[
"sqldbtype"].as< std::string >();
203 std::cout <<
"SQL database type is: " << ioSQLDBTypeString
220 ioAddPORInDB =
false;
221 ioSQLDBConnectionString =
"";
233 if (vm.count (
"sqldbconx")) {
234 ioSQLDBConnectionString = vm[
"sqldbconx"].as< std::string >();
240 const std::string& lSQLDBConnString =
242 ioSQLDBConnectionString,
245 std::cout <<
"SQL database connection string is: " << lSQLDBConnString
249 std::cout <<
"Are non-IATA-referenced POR included? "
250 << ioIncludeNonIATAPOR << std::endl;
252 std::cout <<
"Index the POR in Xapian? "
253 << ioIndexPORInXapian << std::endl;
255 std::cout <<
"Add and re-index the POR in the SQL-based database? "
256 << ioAddPORInDB << std::endl;
258 if (vm.count (
"log")) {
259 ioLogFilename = vm[
"log"].as< std::string >();
263 std::cout <<
"Type the 'info' command to get a few details (e.g., file-path)"
559int main (
int argc,
char* argv[]) {
562 const unsigned int lHistorySize (100);
563 const std::string lHistoryFilename (
"opentrep-dbmgr.hist");
564 const std::string lHistoryBackupFilename (
"opentrep-dbmgr.hist.bak");
567 std::string lLogFilename;
570 std::string lPORFilepathStr;
573 std::string lXapianDBNameStr;
576 std::string lSQLDBTypeStr;
579 std::string lSQLDBConnectionStr;
594 const int lOptionParserStatus =
596 lSQLDBTypeStr, lSQLDBConnectionStr, lDeploymentNumber,
597 lIncludeNonIATAPOR, lShouldIndexPORInXapian,
598 lShouldAddPORInSQLDB, lLogFilename);
605 std::ofstream logOutputFile;
607 logOutputFile.open (lLogFilename.c_str());
608 logOutputFile.clear();
617 lDBType, lSQLDBConnStr,
620 lShouldIndexPORInXapian,
621 lShouldAddPORInSQLDB);
633 std::string lUserInput;
634 bool EndOfInput (
false);
639 std::ostringstream oPromptStr;
640 oPromptStr <<
"opentrep> ";
644 lUserInput = lReader.
GetLine (oPromptStr.str(), lTokenListByReadline,
652 std::cout << std::endl;
659 switch (lCommandType) {
663 std::cout << std::endl;
664 std::cout <<
"Commands: " << std::endl;
665 std::cout <<
" CTRL-L (Control and L keys)" <<
"\t" <<
"Clean the screen"
667 std::cout <<
" help" <<
"\t\t\t\t" <<
"Display this help" << std::endl;
668 std::cout <<
" info" <<
"\t\t\t\t"
669 <<
"Display details for the current session "
670 <<
"(e.g., file-paths for the log file, SQL database)"
672 std::cout <<
" tutorial" <<
"\t\t\t" <<
"Display examples" << std::endl;
673 std::cout <<
" quit" <<
"\t\t\t\t" <<
"Quit the application" << std::endl;
674 std::cout <<
" create_user" <<
"\t\t\t"
675 <<
"On SQL database, create the 'trep' user and the 'trep_trep' "
676 <<
"database. SQL database administrative rights are required."
678 std::cout <<
" reset_connection_string" <<
"\t"
679 <<
"Reset/update the connection string to a MySQL database."
680 <<
" The connection string must be given"
682 std::cout <<
" create_tables" <<
"\t\t\t"
683 <<
"Create/reset the SQL database (eg, SQLite3, MySQL) tables"
685 std::cout <<
" create_indexes" <<
"\t\t\t"
686 <<
"Create/reset the SQL database (eg, SQLite3, MySQL) indices"
688 std::cout <<
" toggle_deployment_number" <<
"\t"
689 <<
"Toggle the deployment number/version. "
690 <<
"To see the deployment version/number, type 'info'"
692 std::cout <<
" toggle_noniata_indexing_flag" <<
"\t"
693 <<
"Toggle the flag for the indexing (or not) of the non-IATA referenced POR."
694 <<
" To see the flag, type 'info'"
696 std::cout <<
" toggle_xapian_idexing_flag" <<
"\t"
697 <<
"Toggle the flag for the Xapian indexing (or not) of the POR."
698 <<
" To see the flag, type 'info'"
700 std::cout <<
" toggle_sqldb_inserting_flag" <<
"\t"
701 <<
"Toggle the flag for inserting (or not) the POR into the SQL database."
702 <<
" To see the flag, type 'info'"
704 std::cout <<
" fill_from_por_file" <<
"\t\t"
705 <<
"Parse the file of POR and fill-in the SQL database optd_por table."
706 << std::endl <<
"\t\t\t\t"
707 <<
"That command (re-)creates both the Xapian index and the SQL tables (as well as the indices), if needed."
708 << std::endl <<
"\t\t\t\t"
709 <<
"Note that, as that command takes minutes, the connection to the SQL database may be lost and the program will exit abnormally."
710 << std::endl <<
"\t\t\t\t"
711 <<
"In that latter case, just re-execute the program and check how far the indexation went by executing the following command."
713 std::cout <<
" list_nb" <<
"\t\t\t"
714 <<
"Display the number of the entries of the database."
716 std::cout <<
" list_all" <<
"\t\t\t"
717 <<
"List all the entries of the database, page by page."
718 <<
"Type the 'list_cont' command for a page down" << std::endl;
719 std::cout <<
" list_by_iata" <<
"\t\t\t"
720 <<
"List all the entries for a given IATA code"
722 std::cout <<
" list_by_icao" <<
"\t\t\t"
723 <<
"List all the entries for a given ICAO code"
725 std::cout <<
" list_by_faa" <<
"\t\t\t"
726 <<
"List all the entries for a given FAA code"
728 std::cout <<
" list_by_unlocode" <<
"\t\t\t"
729 <<
"List all the entries for a given UN/LOCODE code"
731 std::cout <<
" list_by_uiccode" <<
"\t\t\t"
732 <<
"List all the entries for a given UIC code"
734 std::cout <<
" list_by_geonameid" <<
"\t\t"
735 <<
"List all the entries for a given Geoname ID"
737 std::cout << std::endl;
749 std::cout << std::endl;
750 std::cout <<
"Log file-path: " <<
"\t\t\t\t\t" << lLogFilename
752 std::cout <<
"POR file-path: " <<
"\t\t\t\t\t" << lPORFilepathStr
754 std::cout <<
"Xapian index/database file-path: " <<
"\t\t"
755 << lXapianDBFP << std::endl;
756 std::cout <<
"SQL database type: " <<
"\t\t\t\t" << lDBType.
describe()
758 std::cout <<
"SQL database connection string: " <<
"\t\t" << lSQLConnStr
760 std::cout <<
"Deployment number/version: " <<
"\t\t\t"
761 << lDeploymentNumber <<
"/"
764 std::cout <<
"Whether to index NON-IATA-referenced POR: " <<
"\t"
765 << lIncludeNonIATAPOR << std::endl;
766 std::cout <<
"Whether to index the POR in Xapian: " <<
"\t\t"
767 << lShouldIndexPORInXapian << std::endl;
768 std::cout <<
"Whether to insert the POR in the SQL DB: " <<
"\t"
769 << lShouldAddPORInSQLDB << std::endl;
770 std::cout << std::endl;
776 std::cout << std::endl;
777 std::cout <<
"Typical succession of commands" << std::endl;
778 std::cout <<
" -------- " << std::endl;
779 std::cout <<
"Check with the 'info' command and adjust the various flags:"
781 std::cout <<
" toggle_deployment_number" << std::endl;
782 std::cout <<
" toggle_noniata_indexing_flag" << std::endl;
783 std::cout <<
" toggle_xapian_idexing_flag" << std::endl;
784 std::cout <<
" toggle_sqldb_inserting_flag" << std::endl;
785 std::cout << std::endl;
786 std::cout <<
" -------- " << std::endl;
787 std::cout <<
"Re-indexing of the POR data file:" << std::endl;
788 std::cout <<
" fill_from_por_file" << std::endl;
789 std::cout << std::endl;
790 std::cout <<
" -------- " << std::endl;
791 std::cout <<
"Check the content of the SQL database:" << std::endl;
792 std::cout <<
" list_nb" << std::endl;
793 std::cout <<
" list_by_iata nce" << std::endl;
794 std::cout <<
" list_by_icao lfmn" << std::endl;
795 std::cout <<
" list_by_faa jfk" << std::endl;
796 std::cout <<
" list_by_unlocode deham" << std::endl;
797 std::cout <<
" list_by_uiccode 87775007" << std::endl;
798 std::cout <<
" list_by_geonameid 6299418" << std::endl;
799 std::cout << std::endl;
800 std::cout <<
" -------- " << std::endl;
801 std::cout <<
"Management of the database user and database:" << std::endl;
802 std::cout <<
" reset_connection_string db=mysql user=root password=<passwd>"
804 std::cout <<
" create_user" << std::endl;
805 std::cout <<
" reset_connection_string db=trep_trep user=trep password=trep"
807 std::cout <<
" create_tables" << std::endl;
808 std::cout <<
" create_indexes" << std::endl;
809 std::cout << std::endl;
826 std::cout << nbOfEntries
827 <<
" POR (points of reference) have been found in the Xapian "
828 <<
"index. Type 'info' to know where that Xapian index is "
829 "located." << std::endl;
836 std::cout << nbOfEntries
837 <<
" POR (points of reference) have been found in the "
838 << lDBType.
describe() <<
" database" << std::endl;
849 const std::string lIataCodeStr (
"NCE");
858 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
859 <<
"matching the IATA code ('" << lIataCodeStr <<
"')."
862 if (nbOfMatches != 0) {
864 for (OPENTREP::LocationList_T::const_iterator itLocation =
865 lLocationList.begin();
866 itLocation != lLocationList.end(); ++itLocation, ++idx) {
868 std::cout <<
" [" << idx <<
"]: " << lLocation.
toString() << std::endl;
872 std::cout <<
"List of unmatched words:" << std::endl;
873 std::cout <<
" [" << 1 <<
"]: " << lIataCodeStr << std::endl;
886 std::string lIataCodeStr (
"nce");
896 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
897 <<
"matching the IATA code ('" << lIataCodeStr <<
"')."
900 if (nbOfMatches != 0) {
902 for (OPENTREP::LocationList_T::const_iterator itLocation =
903 lLocationList.begin();
904 itLocation != lLocationList.end(); ++itLocation, ++idx) {
906 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
910 std::cout <<
"List of unmatched words:" << std::endl;
911 std::cout <<
" [" << 1 <<
"]: " << lIataCodeStr << std::endl;
924 std::string lIcaoCodeStr (
"lfmn");
934 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
935 <<
"matching the ICAO code ('" << lIcaoCodeStr <<
"')."
938 if (nbOfMatches != 0) {
940 for (OPENTREP::LocationList_T::const_iterator itLocation =
941 lLocationList.begin();
942 itLocation != lLocationList.end(); ++itLocation, ++idx) {
944 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
948 std::cout <<
"List of unmatched words:" << std::endl;
949 std::cout <<
" [" << 1 <<
"]: " << lIcaoCodeStr << std::endl;
962 std::string lFaaCodeStr (
"jfk");
972 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
973 <<
"matching the FAA code ('" << lFaaCodeStr <<
"')."
976 if (nbOfMatches != 0) {
978 for (OPENTREP::LocationList_T::const_iterator itLocation =
979 lLocationList.begin();
980 itLocation != lLocationList.end(); ++itLocation, ++idx) {
982 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
986 std::cout <<
"List of unmatched words:" << std::endl;
987 std::cout <<
" [" << 1 <<
"]: " << lFaaCodeStr << std::endl;
1000 std::string lUNLOCodeStr (
"deham");
1010 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
1011 <<
"matching the UN/LOCODE code ('" << lUNLOCodeStr <<
"')."
1014 if (nbOfMatches != 0) {
1016 for (OPENTREP::LocationList_T::const_iterator itLocation =
1017 lLocationList.begin();
1018 itLocation != lLocationList.end(); ++itLocation, ++idx) {
1020 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
1024 std::cout <<
"List of unmatched words:" << std::endl;
1025 std::cout <<
" [" << 1 <<
"]: " << lUNLOCodeStr << std::endl;
1038 std::string lUICCodeStr (
"87775007");
1046 lUICCode = boost::lexical_cast<OPENTREP::UICCode_T> (lUICCodeStr);
1048 }
catch (boost::bad_lexical_cast& eCast) {
1049 lUICCode = 87775007;
1050 std::cerr <<
"The UIC code ('" << lUICCodeStr
1051 <<
"') cannot be understood. The default value ("
1052 << lUICCode <<
") is kept." << std::endl;
1061 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
1062 <<
"matching the UIC code ('" << lUICCodeStr <<
"')."
1065 if (nbOfMatches != 0) {
1067 for (OPENTREP::LocationList_T::const_iterator itLocation =
1068 lLocationList.begin();
1069 itLocation != lLocationList.end(); ++itLocation, ++idx) {
1071 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
1075 std::cout <<
"List of unmatched words:" << std::endl;
1076 std::cout <<
" [" << 1 <<
"]: " << lUICCodeStr << std::endl;
1090 std::string lGeonameIDStr (
"6299418");
1098 lGeonameID = boost::lexical_cast<OPENTREP::GeonamesID_T> (lGeonameIDStr);
1100 }
catch (boost::bad_lexical_cast& eCast) {
1101 lGeonameID = 6299418;
1102 std::cerr <<
"The Geoname ID ('" << lGeonameIDStr
1103 <<
"') cannot be understood. The default value ("
1104 << lGeonameID <<
") is kept." << std::endl;
1113 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
1114 <<
"matching the Geoname ID ('" << lGeonameIDStr <<
"')."
1117 if (nbOfMatches != 0) {
1119 for (OPENTREP::LocationList_T::const_iterator itLocation =
1120 lLocationList.begin();
1121 itLocation != lLocationList.end(); ++itLocation, ++idx) {
1123 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
1127 std::cout <<
"List of unmatched items:" << std::endl;
1128 std::cout <<
" [" << 1 <<
"]: " << lGeonameIDStr << std::endl;
1137 std::cout <<
"Creating the 'trep' user and 'trep_trep' database"
1146 if (lCreationSuccessful ==
true) {
1147 std::cout <<
"The 'trep' user and 'trep_trep' database have been created"
1158 const std::string lConnectionStringStr =
toString (lTokenListByReadline);
1161 std::cout <<
"Reset the connection string" << std::endl;
1165 lConnectionString (lConnectionStringStr);
1169 std::cout <<
"The connection string has been reset" << std::endl;
1180 std::cout <<
"The new deployment number/version is: " << lDeploymentNumber
1193 std::cout <<
"The new flag is: " << lIncludeNonIATAPOR << std::endl;
1201 lShouldIndexPORInXapian =
1205 std::cout <<
"The new flag is: " << lShouldIndexPORInXapian << std::endl;
1216 std::cout <<
"The new flag is: " << lShouldAddPORInSQLDB << std::endl;
1224 std::cout <<
"Creating/resetting the " << lDBType.
describe()
1225 <<
" database tables" << std::endl;
1231 std::cout <<
"The " << lDBType.
describe()
1232 <<
" tables has been created/resetted" << std::endl;
1240 std::cout <<
"Creating/resetting the " << lDBType.
describe()
1241 <<
" database indexes" << std::endl;
1247 std::cout <<
"The " << lDBType.
describe()
1248 <<
" indexes has been created/resetted" << std::endl;
1256 std::cout <<
"Indexing the POR file and filling in the SQL database may "
1257 <<
"take a few minutes on some architectures "
1258 <<
"(and a few seconds on fastest ones)..."
1266 std::cout << lNbOfEntries <<
" entries have been processed" << std::endl;
1279 std::ostringstream oStr;
1280 oStr <<
"That command is not yet understood: '" << lUserInput
1281 <<
"' => " << lTokenListByReadline;
1283 std::cout << oStr.str() << std::endl;
1290 std::cout <<
"End of the session. Exiting." << std::endl;
1293 logOutputFile.close();