TraDemGen Logo  0.2.2
C++ Simulated Travel Demand Generation Library
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines
trademgen_with_db.cpp
Go to the documentation of this file.
00001 // STL
00002 #include <cassert>
00003 #include <iostream>
00004 #include <sstream>
00005 #include <fstream>
00006 #include <vector>
00007 #include <string>
00008 // Boost (Extended STL)
00009 #include <boost/date_time/posix_time/posix_time.hpp>
00010 #include <boost/date_time/gregorian/gregorian.hpp>
00011 #include <boost/tokenizer.hpp>
00012 #include <boost/program_options.hpp>
00013 // StdAir
00014 #include <stdair/stdair_basic_types.hpp>
00015 #include <stdair/basic/BasConst_General.hpp>
00016 #include <stdair/basic/BasDBParams.hpp>
00017 #include <stdair/basic/BasLogParams.hpp>
00018 // TraDemGen
00019 #include <trademgen/TRADEMGEN_Service.hpp>
00020 #include <trademgen/config/trademgen-paths.hpp>
00021 
00022 
00023 // //////// Type definitions ///////
00024 typedef std::vector<std::string> WordList_T;
00025 
00026 
00027 // //////// Constants //////
00031 const std::string K_TRADEMGEN_DEFAULT_LOG_FILENAME ("trademgen_with_db.log");
00032 
00036 const std::string K_TRADEMGEN_DEFAULT_INPUT_FILENAME (STDAIR_SAMPLE_DIR
00037                                                       "/demand01.csv");
00038 
00043 const bool K_TRADEMGEN_DEFAULT_BUILT_IN_INPUT = false;
00044 
00048 const stdair::RandomSeed_T K_TRADEMGEN_DEFAULT_RANDOM_SEED =
00049   stdair::DEFAULT_RANDOM_SEED;
00050 
00054 const std::string K_TRADEMGEN_DEFAULT_QUERY_STRING ("my good old query");
00055 
00059 const std::string K_TRADEMGEN_DEFAULT_DB_USER ("dsim");
00060 const std::string K_TRADEMGEN_DEFAULT_DB_PASSWD ("dsim");
00061 const std::string K_TRADEMGEN_DEFAULT_DB_DBNAME ("sim_dsim");
00062 const std::string K_TRADEMGEN_DEFAULT_DB_HOST ("localhost");
00063 const std::string K_TRADEMGEN_DEFAULT_DB_PORT ("3306");
00064 
00065 
00066 // //////////////////////////////////////////////////////////////////////
00067 void tokeniseStringIntoWordList (const std::string& iPhrase,
00068                                  WordList_T& ioWordList) {
00069   // Empty the word list
00070   ioWordList.clear();
00071   
00072   // Boost Tokeniser
00073   typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
00074   
00075   // Define the separators
00076   const boost::char_separator<char> lSepatorList(" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
00077   
00078   // Initialise the phrase to be tokenised
00079   Tokeniser_T lTokens (iPhrase, lSepatorList);
00080   for (Tokeniser_T::const_iterator tok_iter = lTokens.begin();
00081        tok_iter != lTokens.end(); ++tok_iter) {
00082     const std::string& lTerm = *tok_iter;
00083     ioWordList.push_back (lTerm);
00084   }
00085   
00086 }
00087 
00088 // //////////////////////////////////////////////////////////////////////
00089 std::string createStringFromWordList (const WordList_T& iWordList) {
00090   std::ostringstream oStr;
00091 
00092   unsigned short idx = iWordList.size();
00093   for (WordList_T::const_iterator itWord = iWordList.begin();
00094        itWord != iWordList.end(); ++itWord, --idx) {
00095     const std::string& lWord = *itWord;
00096     oStr << lWord;
00097     if (idx > 1) {
00098       oStr << " ";
00099     }
00100   }
00101   
00102   return oStr.str();
00103 }
00104 
00105 
00106 // ///////// Parsing of Options & Configuration /////////
00107 // A helper function to simplify the main part.
00108 template<class T> std::ostream& operator<< (std::ostream& os,
00109                                             const std::vector<T>& v) {
00110   std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " ")); 
00111   return os;
00112 }
00113 
00115 const int K_TRADEMGEN_EARLY_RETURN_STATUS = 99;
00116 
00118 int readConfiguration (int argc, char* argv[], bool& ioIsBuiltin,
00119                        stdair::RandomSeed_T& ioRandomSeed, 
00120                        std::string& ioQueryString,
00121                        stdair::Filename_T& ioInputFilename,
00122                        std::string& ioLogFilename,
00123                        std::string& ioDBUser, std::string& ioDBPasswd,
00124                        std::string& ioDBHost, std::string& ioDBPort,
00125                        std::string& ioDBDBName) {
00126 
00127   // Default for the built-in input
00128   ioIsBuiltin = K_TRADEMGEN_DEFAULT_BUILT_IN_INPUT;
00129 
00130   // Initialise the travel query string, if that one is empty
00131   if (ioQueryString.empty() == true) {
00132     ioQueryString = K_TRADEMGEN_DEFAULT_QUERY_STRING;
00133   }
00134   
00135   // Transform the query string into a list of words (STL strings)
00136   WordList_T lWordList;
00137   tokeniseStringIntoWordList (ioQueryString, lWordList);
00138 
00139   // Declare a group of options that will be allowed only on command line
00140   boost::program_options::options_description generic ("Generic options");
00141   generic.add_options()
00142     ("prefix", "print installation prefix")
00143     ("version,v", "print version string")
00144     ("help,h", "produce help message");
00145     
00146   // Declare a group of options that will be allowed both on command
00147   // line and in config file
00148   boost::program_options::options_description config ("Configuration");
00149   config.add_options()
00150     ("builtin,b",
00151      "The sample BOM tree can be either built-in or parsed from an input file. That latter must then be given with the -i/--input option")
00152     ("seed,s",
00153      boost::program_options::value<stdair::RandomSeed_T>(&ioRandomSeed)->default_value(K_TRADEMGEN_DEFAULT_RANDOM_SEED),
00154      "Seed for the random generation")
00155     ("input,i",
00156      boost::program_options::value< std::string >(&ioInputFilename)->default_value(K_TRADEMGEN_DEFAULT_INPUT_FILENAME),
00157      "(CVS) input file for the demand distributions")
00158     ("log,l",
00159      boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_TRADEMGEN_DEFAULT_LOG_FILENAME),
00160      "Filepath for the logs")
00161     ("user,u",
00162      boost::program_options::value< std::string >(&ioDBUser)->default_value(K_TRADEMGEN_DEFAULT_DB_USER),
00163      "SQL database user (e.g., dsim)")
00164     ("passwd,p",
00165      boost::program_options::value< std::string >(&ioDBPasswd)->default_value(K_TRADEMGEN_DEFAULT_DB_PASSWD),
00166      "SQL database password (e.g., dsim)")
00167     ("host,H",
00168      boost::program_options::value< std::string >(&ioDBHost)->default_value(K_TRADEMGEN_DEFAULT_DB_HOST),
00169      "SQL database hostname (e.g., localhost)")
00170     ("port,P",
00171      boost::program_options::value< std::string >(&ioDBPort)->default_value(K_TRADEMGEN_DEFAULT_DB_PORT),
00172      "SQL database port (e.g., 3306)")
00173     ("dbname,m",
00174      boost::program_options::value< std::string >(&ioDBDBName)->default_value(K_TRADEMGEN_DEFAULT_DB_DBNAME),
00175      "SQL database name (e.g., sim_dsim)")
00176     ("query,q",
00177      boost::program_options::value< WordList_T >(&lWordList)->multitoken(),
00178      "Query word list")
00179     ;
00180 
00181   // Hidden options, will be allowed both on command line and
00182   // in config file, but will not be shown to the user.
00183   boost::program_options::options_description hidden ("Hidden options");
00184   hidden.add_options()
00185     ("copyright",
00186      boost::program_options::value< std::vector<std::string> >(),
00187      "Show the copyright (license)");
00188         
00189   boost::program_options::options_description cmdline_options;
00190   cmdline_options.add(generic).add(config).add(hidden);
00191 
00192   boost::program_options::options_description config_file_options;
00193   config_file_options.add(config).add(hidden);
00194 
00195   boost::program_options::options_description visible ("Allowed options");
00196   visible.add(generic).add(config);
00197         
00198   boost::program_options::positional_options_description p;
00199   p.add ("copyright", -1);
00200         
00201   boost::program_options::variables_map vm;
00202   boost::program_options::
00203     store (boost::program_options::command_line_parser (argc, argv).
00204            options (cmdline_options).positional(p).run(), vm);
00205 
00206   std::ifstream ifs ("trademgen_with_db.cfg");
00207   boost::program_options::store (parse_config_file (ifs, config_file_options),
00208                                  vm);
00209   boost::program_options::notify (vm);
00210     
00211   if (vm.count ("help")) {
00212     std::cout << visible << std::endl;
00213     return K_TRADEMGEN_EARLY_RETURN_STATUS;
00214   }
00215 
00216   if (vm.count ("version")) {
00217     std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
00218     return K_TRADEMGEN_EARLY_RETURN_STATUS;
00219   }
00220 
00221   if (vm.count ("prefix")) {
00222     std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
00223     return K_TRADEMGEN_EARLY_RETURN_STATUS;
00224   }
00225 
00226   if (vm.count ("builtin")) {
00227     ioIsBuiltin = true;
00228   }
00229   const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
00230   std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
00231 
00232   if (ioIsBuiltin == false) {
00233 
00234     // The BOM tree should be built from parsing a demand input file
00235     if (vm.count ("input")) {
00236       ioInputFilename = vm["input"].as< std::string >();
00237       std::cout << "Input filename is: " << ioInputFilename << std::endl;
00238 
00239     } else {
00240       // The built-in option is not selected. However, no demand input file
00241       // is specified
00242       std::cerr << "Either one among the -b/--builtin and -i/--input "
00243                 << "options must be specified" << std::endl;
00244     }
00245   }
00246 
00247   if (vm.count ("log")) {
00248     ioLogFilename = vm["log"].as< std::string >();
00249     std::cout << "Log filename is: " << ioLogFilename << std::endl;
00250   }
00251 
00252   if (vm.count ("user")) {
00253     ioDBUser = vm["user"].as< std::string >();
00254     std::cout << "SQL database user name is: " << ioDBUser << std::endl;
00255   }
00256 
00257   if (vm.count ("passwd")) {
00258     ioDBPasswd = vm["passwd"].as< std::string >();
00259     // std::cout << "SQL database user password is: " << ioDBPasswd << std::endl;
00260   }
00261 
00262   if (vm.count ("host")) {
00263     ioDBHost = vm["host"].as< std::string >();
00264     std::cout << "SQL database host name is: " << ioDBHost << std::endl;
00265   }
00266 
00267   if (vm.count ("port")) {
00268     ioDBPort = vm["port"].as< std::string >();
00269     std::cout << "SQL database port number is: " << ioDBPort << std::endl;
00270   }
00271 
00272   if (vm.count ("dbname")) {
00273     ioDBDBName = vm["dbname"].as< std::string >();
00274     std::cout << "SQL database name is: " << ioDBDBName << std::endl;
00275   }
00276 
00277   //
00278   std::cout << "The random generation seed is: " << ioRandomSeed << std::endl;
00279 
00280   ioQueryString = createStringFromWordList (lWordList);
00281   std::cout << "The query string is: " << ioQueryString << std::endl;
00282   
00283   return 0;
00284 }
00285 
00286 
00287 // /////////////// M A I N /////////////////
00288 int main (int argc, char* argv[]) {
00289 
00290   // State whether the BOM tree should be built-in or parsed from an input file
00291   bool isBuiltin;
00292 
00293   // Random generation seed
00294   stdair::RandomSeed_T lRandomSeed;
00295 
00296   // Query
00297   std::string lQuery;
00298 
00299   // Input file name
00300   stdair::Filename_T lInputFilename;
00301 
00302   // Output log File
00303   std::string lLogFilename;
00304 
00305   // SQL database parameters
00306   std::string lDBUser;
00307   std::string lDBPasswd;
00308   std::string lDBHost;
00309   std::string lDBPort;
00310   std::string lDBDBName;
00311   
00312   // Airline code
00313   const stdair::AirlineCode_T lAirlineCode ("BA");
00314   
00315   // Call the command-line option parser
00316   const int lOptionParserStatus = 
00317     readConfiguration (argc, argv, isBuiltin, lRandomSeed, lQuery,
00318                        lInputFilename, lLogFilename,
00319                        lDBUser, lDBPasswd, lDBHost, lDBPort, lDBDBName);
00320 
00321   if (lOptionParserStatus == K_TRADEMGEN_EARLY_RETURN_STATUS) {
00322     return 0;
00323   }
00324   
00325   // Set the database parameters
00326   stdair::BasDBParams lDBParams (lDBUser, lDBPasswd, lDBHost, lDBPort,
00327                                  lDBDBName);
00328   
00329   // Set the log parameters
00330   std::ofstream logOutputFile;
00331   // open and clean the log outputfile
00332   logOutputFile.open (lLogFilename.c_str());
00333   logOutputFile.clear();
00334   
00335   // Set up the log parameters
00336   const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00337 
00338   // Initialise the TraDemGen service object
00339   TRADEMGEN::TRADEMGEN_Service trademgenService (lLogParams, lDBParams,
00340                                                  lRandomSeed);
00341 
00342   // Check wether or not a (CSV) input file should be read
00343   if (isBuiltin == true) {
00344     // Create a sample DemandStream object, and insert it within the BOM tree
00345     trademgenService.buildSampleBom();
00346 
00347   } else {
00348     // Create the DemandStream objects, and insert them within the BOM tree
00349     trademgenService.parseAndLoad (lInputFilename);
00350   }  
00351 
00352   // Query the database
00353   trademgenService.displayAirlineListFromDB();
00354 
00355   // Close the Log outputFile
00356   logOutputFile.close();
00357 
00358   return 0;
00359 }