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, pg for PostgreSQL)")
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 or PostgreSQL)")
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 =
"";
237 if (vm.count (
"sqldbconx")) {
238 ioSQLDBConnectionString = vm[
"sqldbconx"].as< std::string >();
245 const std::string& lSQLDBConnString =
247 ioSQLDBConnectionString,
250 std::cout <<
"SQL database connection string is: " << lSQLDBConnString
254 std::cout <<
"Are non-IATA-referenced POR included? "
255 << ioIncludeNonIATAPOR << std::endl;
257 std::cout <<
"Index the POR in Xapian? "
258 << ioIndexPORInXapian << std::endl;
260 std::cout <<
"Add and re-index the POR in the SQL-based database? "
261 << ioAddPORInDB << std::endl;
263 if (vm.count (
"log")) {
264 ioLogFilename = vm[
"log"].as< std::string >();
268 std::cout <<
"Type the 'info' command to get a few details (e.g., file-path)"
564int main (
int argc,
char* argv[]) {
567 const unsigned int lHistorySize (100);
568 const std::string lHistoryFilename (
"opentrep-dbmgr.hist");
569 const std::string lHistoryBackupFilename (
"opentrep-dbmgr.hist.bak");
572 std::string lLogFilename;
575 std::string lPORFilepathStr;
578 std::string lXapianDBNameStr;
581 std::string lSQLDBTypeStr;
584 std::string lSQLDBConnectionStr;
599 const int lOptionParserStatus =
601 lSQLDBTypeStr, lSQLDBConnectionStr, lDeploymentNumber,
602 lIncludeNonIATAPOR, lShouldIndexPORInXapian,
603 lShouldAddPORInSQLDB, lLogFilename);
610 std::ofstream logOutputFile;
612 logOutputFile.open (lLogFilename.c_str());
613 logOutputFile.clear();
622 lDBType, lSQLDBConnStr,
625 lShouldIndexPORInXapian,
626 lShouldAddPORInSQLDB);
638 std::string lUserInput;
639 bool EndOfInput (
false);
644 std::ostringstream oPromptStr;
645 oPromptStr <<
"opentrep> ";
649 lUserInput = lReader.
GetLine (oPromptStr.str(), lTokenListByReadline,
657 std::cout << std::endl;
664 switch (lCommandType) {
668 std::cout << std::endl;
669 std::cout <<
"Commands: " << std::endl;
670 std::cout <<
" CTRL-L (Control and L keys)" <<
"\t" <<
"Clean the screen"
672 std::cout <<
" help" <<
"\t\t\t\t" <<
"Display this help" << std::endl;
673 std::cout <<
" info" <<
"\t\t\t\t"
674 <<
"Display details for the current session "
675 <<
"(e.g., file-paths for the log file, SQL database)"
677 std::cout <<
" tutorial" <<
"\t\t\t" <<
"Display examples" << std::endl;
678 std::cout <<
" quit" <<
"\t\t\t\t" <<
"Quit the application" << std::endl;
679 std::cout <<
" create_user" <<
"\t\t\t"
680 <<
"On SQL database, create the 'trep' user and the 'trep_trep' "
681 <<
"database. SQL database administrative rights are required."
683 std::cout <<
" reset_connection_string" <<
"\t"
684 <<
"Reset/update the connection string to a MySQL or PostgreSQL database."
685 <<
" The connection string must be given"
687 std::cout <<
" create_tables" <<
"\t\t\t"
688 <<
"Create/reset the SQL database (eg, SQLite3, PostgreSQL, MySQL) tables"
690 std::cout <<
" create_indexes" <<
"\t\t\t"
691 <<
"Create/reset the SQL database (eg, SQLite3, PostgreSQL, MySQL) indices"
693 std::cout <<
" toggle_deployment_number" <<
"\t"
694 <<
"Toggle the deployment number/version. "
695 <<
"To see the deployment version/number, type 'info'"
697 std::cout <<
" toggle_noniata_indexing_flag" <<
"\t"
698 <<
"Toggle the flag for the indexing (or not) of the non-IATA referenced POR."
699 <<
" To see the flag, type 'info'"
701 std::cout <<
" toggle_xapian_idexing_flag" <<
"\t"
702 <<
"Toggle the flag for the Xapian indexing (or not) of the POR."
703 <<
" To see the flag, type 'info'"
705 std::cout <<
" toggle_sqldb_inserting_flag" <<
"\t"
706 <<
"Toggle the flag for inserting (or not) the POR into the SQL database."
707 <<
" To see the flag, type 'info'"
709 std::cout <<
" fill_from_por_file" <<
"\t\t"
710 <<
"Parse the file of POR and fill-in the SQL database optd_por table."
711 << std::endl <<
"\t\t\t\t"
712 <<
"That command (re-)creates both the Xapian index and the SQL tables (as well as the indices), if needed."
713 << std::endl <<
"\t\t\t\t"
714 <<
"Note that, as that command takes minutes, the connection to the SQL database may be lost and the program will exit abnormally."
715 << std::endl <<
"\t\t\t\t"
716 <<
"In that latter case, just re-execute the program and check how far the indexation went by executing the following command."
718 std::cout <<
" list_nb" <<
"\t\t\t"
719 <<
"Display the number of the entries of the database."
721 std::cout <<
" list_all" <<
"\t\t\t"
722 <<
"List all the entries of the database, page by page."
723 <<
"Type the 'list_cont' command for a page down" << std::endl;
724 std::cout <<
" list_by_iata" <<
"\t\t\t"
725 <<
"List all the entries for a given IATA code"
727 std::cout <<
" list_by_icao" <<
"\t\t\t"
728 <<
"List all the entries for a given ICAO code"
730 std::cout <<
" list_by_faa" <<
"\t\t\t"
731 <<
"List all the entries for a given FAA code"
733 std::cout <<
" list_by_unlocode" <<
"\t\t\t"
734 <<
"List all the entries for a given UN/LOCODE code"
736 std::cout <<
" list_by_uiccode" <<
"\t\t\t"
737 <<
"List all the entries for a given UIC code"
739 std::cout <<
" list_by_geonameid" <<
"\t\t"
740 <<
"List all the entries for a given Geoname ID"
742 std::cout << std::endl;
754 std::cout << std::endl;
755 std::cout <<
"Log file-path: " <<
"\t\t\t\t\t" << lLogFilename
757 std::cout <<
"POR file-path: " <<
"\t\t\t\t\t" << lPORFilepathStr
759 std::cout <<
"Xapian index/database file-path: " <<
"\t\t"
760 << lXapianDBFP << std::endl;
761 std::cout <<
"SQL database type: " <<
"\t\t\t\t" << lDBType.
describe()
763 std::cout <<
"SQL database connection string: " <<
"\t\t" << lSQLConnStr
765 std::cout <<
"Deployment number/version: " <<
"\t\t\t"
766 << lDeploymentNumber <<
"/"
769 std::cout <<
"Whether to index NON-IATA-referenced POR: " <<
"\t"
770 << lIncludeNonIATAPOR << std::endl;
771 std::cout <<
"Whether to index the POR in Xapian: " <<
"\t\t"
772 << lShouldIndexPORInXapian << std::endl;
773 std::cout <<
"Whether to insert the POR in the SQL DB: " <<
"\t"
774 << lShouldAddPORInSQLDB << std::endl;
775 std::cout << std::endl;
781 std::cout << std::endl;
782 std::cout <<
"Typical succession of commands" << std::endl;
783 std::cout <<
" -------- " << std::endl;
784 std::cout <<
"Check with the 'info' command and adjust the various flags:"
786 std::cout <<
" toggle_deployment_number" << std::endl;
787 std::cout <<
" toggle_noniata_indexing_flag" << std::endl;
788 std::cout <<
" toggle_xapian_idexing_flag" << std::endl;
789 std::cout <<
" toggle_sqldb_inserting_flag" << std::endl;
790 std::cout << std::endl;
791 std::cout <<
" -------- " << std::endl;
792 std::cout <<
"Re-indexing of the POR data file:" << std::endl;
793 std::cout <<
" fill_from_por_file" << std::endl;
794 std::cout << std::endl;
795 std::cout <<
" -------- " << std::endl;
796 std::cout <<
"Check the content of the SQL database:" << std::endl;
797 std::cout <<
" list_nb" << std::endl;
798 std::cout <<
" list_by_iata nce" << std::endl;
799 std::cout <<
" list_by_icao lfmn" << std::endl;
800 std::cout <<
" list_by_faa jfk" << std::endl;
801 std::cout <<
" list_by_unlocode deham" << std::endl;
802 std::cout <<
" list_by_uiccode 87775007" << std::endl;
803 std::cout <<
" list_by_geonameid 6299418" << std::endl;
804 std::cout << std::endl;
805 std::cout <<
" -------- " << std::endl;
806 std::cout <<
"Management of the database user and database:" << std::endl;
807 std::cout <<
"* For PostgreSQL:" << std::endl;
808 std::cout <<
" reset_connection_string db=postgres user=$USER password=<passwd>"
810 std::cout <<
"* For MySQL:" << std::endl;
811 std::cout <<
" reset_connection_string db=mysql user=root password=<passwd>"
813 std::cout <<
" create_user" << std::endl;
814 std::cout <<
" reset_connection_string db=trep_trep user=trep password=trep"
816 std::cout <<
" create_tables" << std::endl;
817 std::cout <<
" create_indexes" << std::endl;
818 std::cout << std::endl;
835 std::cout << nbOfEntries
836 <<
" POR (points of reference) have been found in the Xapian "
837 <<
"index. Type 'info' to know where that Xapian index is "
838 "located." << std::endl;
845 std::cout << nbOfEntries
846 <<
" POR (points of reference) have been found in the "
847 << lDBType.
describe() <<
" database" << std::endl;
858 const std::string lIataCodeStr (
"NCE");
867 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
868 <<
"matching the IATA code ('" << lIataCodeStr <<
"')."
871 if (nbOfMatches != 0) {
873 for (OPENTREP::LocationList_T::const_iterator itLocation =
874 lLocationList.begin();
875 itLocation != lLocationList.end(); ++itLocation, ++idx) {
877 std::cout <<
" [" << idx <<
"]: " << lLocation.
toString() << std::endl;
881 std::cout <<
"List of unmatched words:" << std::endl;
882 std::cout <<
" [" << 1 <<
"]: " << lIataCodeStr << std::endl;
895 std::string lIataCodeStr (
"nce");
905 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
906 <<
"matching the IATA code ('" << lIataCodeStr <<
"')."
909 if (nbOfMatches != 0) {
911 for (OPENTREP::LocationList_T::const_iterator itLocation =
912 lLocationList.begin();
913 itLocation != lLocationList.end(); ++itLocation, ++idx) {
915 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
919 std::cout <<
"List of unmatched words:" << std::endl;
920 std::cout <<
" [" << 1 <<
"]: " << lIataCodeStr << std::endl;
933 std::string lIcaoCodeStr (
"lfmn");
943 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
944 <<
"matching the ICAO code ('" << lIcaoCodeStr <<
"')."
947 if (nbOfMatches != 0) {
949 for (OPENTREP::LocationList_T::const_iterator itLocation =
950 lLocationList.begin();
951 itLocation != lLocationList.end(); ++itLocation, ++idx) {
953 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
957 std::cout <<
"List of unmatched words:" << std::endl;
958 std::cout <<
" [" << 1 <<
"]: " << lIcaoCodeStr << std::endl;
971 std::string lFaaCodeStr (
"jfk");
981 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
982 <<
"matching the FAA code ('" << lFaaCodeStr <<
"')."
985 if (nbOfMatches != 0) {
987 for (OPENTREP::LocationList_T::const_iterator itLocation =
988 lLocationList.begin();
989 itLocation != lLocationList.end(); ++itLocation, ++idx) {
991 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
995 std::cout <<
"List of unmatched words:" << std::endl;
996 std::cout <<
" [" << 1 <<
"]: " << lFaaCodeStr << std::endl;
1009 std::string lUNLOCodeStr (
"deham");
1019 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
1020 <<
"matching the UN/LOCODE code ('" << lUNLOCodeStr <<
"')."
1023 if (nbOfMatches != 0) {
1025 for (OPENTREP::LocationList_T::const_iterator itLocation =
1026 lLocationList.begin();
1027 itLocation != lLocationList.end(); ++itLocation, ++idx) {
1029 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
1033 std::cout <<
"List of unmatched words:" << std::endl;
1034 std::cout <<
" [" << 1 <<
"]: " << lUNLOCodeStr << std::endl;
1047 std::string lUICCodeStr (
"87775007");
1055 lUICCode = boost::lexical_cast<OPENTREP::UICCode_T> (lUICCodeStr);
1057 }
catch (boost::bad_lexical_cast& eCast) {
1058 lUICCode = 87775007;
1059 std::cerr <<
"The UIC code ('" << lUICCodeStr
1060 <<
"') cannot be understood. The default value ("
1061 << lUICCode <<
") is kept." << std::endl;
1070 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
1071 <<
"matching the UIC code ('" << lUICCodeStr <<
"')."
1074 if (nbOfMatches != 0) {
1076 for (OPENTREP::LocationList_T::const_iterator itLocation =
1077 lLocationList.begin();
1078 itLocation != lLocationList.end(); ++itLocation, ++idx) {
1080 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
1084 std::cout <<
"List of unmatched words:" << std::endl;
1085 std::cout <<
" [" << 1 <<
"]: " << lUICCodeStr << std::endl;
1099 std::string lGeonameIDStr (
"6299418");
1107 lGeonameID = boost::lexical_cast<OPENTREP::GeonamesID_T> (lGeonameIDStr);
1109 }
catch (boost::bad_lexical_cast& eCast) {
1110 lGeonameID = 6299418;
1111 std::cerr <<
"The Geoname ID ('" << lGeonameIDStr
1112 <<
"') cannot be understood. The default value ("
1113 << lGeonameID <<
") is kept." << std::endl;
1122 std::cout << nbOfMatches <<
" (geographical) location(s) have been found "
1123 <<
"matching the Geoname ID ('" << lGeonameIDStr <<
"')."
1126 if (nbOfMatches != 0) {
1128 for (OPENTREP::LocationList_T::const_iterator itLocation =
1129 lLocationList.begin();
1130 itLocation != lLocationList.end(); ++itLocation, ++idx) {
1132 std::cout <<
" [" << idx <<
"]: " << lLocation << std::endl;
1136 std::cout <<
"List of unmatched items:" << std::endl;
1137 std::cout <<
" [" << 1 <<
"]: " << lGeonameIDStr << std::endl;
1146 std::cout <<
"Creating the 'trep' user and 'trep_trep' database"
1156 if (lCreationSuccessful ==
true) {
1157 std::cout <<
"The 'trep' user and 'trep_trep' database have been created"
1168 const std::string lConnectionStringStr =
toString (lTokenListByReadline);
1171 std::cout <<
"Reset the connection string" << std::endl;
1175 lConnectionString (lConnectionStringStr);
1179 std::cout <<
"The connection string has been reset" << std::endl;
1190 std::cout <<
"The new deployment number/version is: " << lDeploymentNumber
1203 std::cout <<
"The new flag is: " << lIncludeNonIATAPOR << std::endl;
1211 lShouldIndexPORInXapian =
1215 std::cout <<
"The new flag is: " << lShouldIndexPORInXapian << std::endl;
1226 std::cout <<
"The new flag is: " << lShouldAddPORInSQLDB << std::endl;
1234 std::cout <<
"Creating/resetting the " << lDBType.
describe()
1235 <<
" database tables" << std::endl;
1241 std::cout <<
"The " << lDBType.
describe()
1242 <<
" tables has been created/resetted" << std::endl;
1250 std::cout <<
"Creating/resetting the " << lDBType.
describe()
1251 <<
" database indices" << std::endl;
1257 std::cout <<
"The " << lDBType.
describe()
1258 <<
" indices has been created/resetted" << std::endl;
1266 std::cout <<
"Indexing the POR file and filling in the SQL database may "
1267 <<
"take a few minutes on some architectures "
1268 <<
"(and a few seconds on fastest ones)..."
1276 std::cout << lNbOfEntries <<
" entries have been processed" << std::endl;
1289 std::ostringstream oStr;
1290 oStr <<
"That command is not yet understood: '" << lUserInput
1291 <<
"' => " << lTokenListByReadline;
1293 std::cout << oStr.str() << std::endl;
1300 std::cout <<
"End of the session. Exiting." << std::endl;
1303 logOutputFile.close();