TraDemGen Logo  1.00.0
C++ Simulated Travel Demand Generation Library
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
trademgen_with_db.cpp
Go to the documentation of this file.
1 // STL
2 #include <cassert>
3 #include <iostream>
4 #include <sstream>
5 #include <fstream>
6 #include <vector>
7 #include <string>
8 // Boost (Extended STL)
9 #include <boost/date_time/posix_time/posix_time.hpp>
10 #include <boost/date_time/gregorian/gregorian.hpp>
11 #include <boost/tokenizer.hpp>
12 #include <boost/program_options.hpp>
13 // StdAir
14 #include <stdair/stdair_basic_types.hpp>
15 #include <stdair/basic/BasConst_General.hpp>
16 #include <stdair/basic/BasDBParams.hpp>
17 #include <stdair/basic/BasLogParams.hpp>
18 // TraDemGen
20 #include <trademgen/config/trademgen-paths.hpp>
21 
22 
23 // //////// Type definitions ///////
24 typedef std::vector<std::string> WordList_T;
25 
26 
27 // //////// Constants //////
31 const std::string K_TRADEMGEN_DEFAULT_LOG_FILENAME ("trademgen_with_db.log");
32 
36 const std::string K_TRADEMGEN_DEFAULT_INPUT_FILENAME (STDAIR_SAMPLE_DIR
37  "/demand01.csv");
38 
44 
48 const stdair::RandomSeed_T K_TRADEMGEN_DEFAULT_RANDOM_SEED =
49  stdair::DEFAULT_RANDOM_SEED;
50 
54 const std::string K_TRADEMGEN_DEFAULT_QUERY_STRING ("my good old query");
55 
59 const std::string K_TRADEMGEN_DEFAULT_DB_USER ("dsim");
60 const std::string K_TRADEMGEN_DEFAULT_DB_PASSWD ("dsim");
61 const std::string K_TRADEMGEN_DEFAULT_DB_DBNAME ("sim_dsim");
62 const std::string K_TRADEMGEN_DEFAULT_DB_HOST ("localhost");
63 const std::string K_TRADEMGEN_DEFAULT_DB_PORT ("3306");
64 
65 
66 // //////////////////////////////////////////////////////////////////////
67 void tokeniseStringIntoWordList (const std::string& iPhrase,
68  WordList_T& ioWordList) {
69  // Empty the word list
70  ioWordList.clear();
71 
72  // Boost Tokeniser
73  typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
74 
75  // Define the separators
76  const boost::char_separator<char> lSepatorList(" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
77 
78  // Initialise the phrase to be tokenised
79  Tokeniser_T lTokens (iPhrase, lSepatorList);
80  for (Tokeniser_T::const_iterator tok_iter = lTokens.begin();
81  tok_iter != lTokens.end(); ++tok_iter) {
82  const std::string& lTerm = *tok_iter;
83  ioWordList.push_back (lTerm);
84  }
85 
86 }
87 
88 // //////////////////////////////////////////////////////////////////////
89 std::string createStringFromWordList (const WordList_T& iWordList) {
90  std::ostringstream oStr;
91 
92  unsigned short idx = iWordList.size();
93  for (WordList_T::const_iterator itWord = iWordList.begin();
94  itWord != iWordList.end(); ++itWord, --idx) {
95  const std::string& lWord = *itWord;
96  oStr << lWord;
97  if (idx > 1) {
98  oStr << " ";
99  }
100  }
101 
102  return oStr.str();
103 }
104 
105 
106 // ///////// Parsing of Options & Configuration /////////
107 // A helper function to simplify the main part.
108 template<class T> std::ostream& operator<< (std::ostream& os,
109  const std::vector<T>& v) {
110  std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " "));
111  return os;
112 }
113 
116 
118 int readConfiguration (int argc, char* argv[], bool& ioIsBuiltin,
119  stdair::RandomSeed_T& ioRandomSeed,
120  std::string& ioQueryString,
121  stdair::Filename_T& ioInputFilename,
122  std::string& ioLogFilename,
123  std::string& ioDBUser, std::string& ioDBPasswd,
124  std::string& ioDBHost, std::string& ioDBPort,
125  std::string& ioDBDBName) {
126 
127  // Default for the built-in input
129 
130  // Initialise the travel query string, if that one is empty
131  if (ioQueryString.empty() == true) {
132  ioQueryString = K_TRADEMGEN_DEFAULT_QUERY_STRING;
133  }
134 
135  // Transform the query string into a list of words (STL strings)
136  WordList_T lWordList;
137  tokeniseStringIntoWordList (ioQueryString, lWordList);
138 
139  // Declare a group of options that will be allowed only on command line
140  boost::program_options::options_description generic ("Generic options");
141  generic.add_options()
142  ("prefix", "print installation prefix")
143  ("version,v", "print version string")
144  ("help,h", "produce help message");
145 
146  // Declare a group of options that will be allowed both on command
147  // line and in config file
148  boost::program_options::options_description config ("Configuration");
149  config.add_options()
150  ("builtin,b",
151  "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")
152  ("seed,s",
153  boost::program_options::value<stdair::RandomSeed_T>(&ioRandomSeed)->default_value(K_TRADEMGEN_DEFAULT_RANDOM_SEED),
154  "Seed for the random generation")
155  ("input,i",
156  boost::program_options::value< std::string >(&ioInputFilename)->default_value(K_TRADEMGEN_DEFAULT_INPUT_FILENAME),
157  "(CVS) input file for the demand distributions")
158  ("log,l",
159  boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_TRADEMGEN_DEFAULT_LOG_FILENAME),
160  "Filepath for the logs")
161  ("user,u",
162  boost::program_options::value< std::string >(&ioDBUser)->default_value(K_TRADEMGEN_DEFAULT_DB_USER),
163  "SQL database user (e.g., dsim)")
164  ("passwd,p",
165  boost::program_options::value< std::string >(&ioDBPasswd)->default_value(K_TRADEMGEN_DEFAULT_DB_PASSWD),
166  "SQL database password (e.g., dsim)")
167  ("host,H",
168  boost::program_options::value< std::string >(&ioDBHost)->default_value(K_TRADEMGEN_DEFAULT_DB_HOST),
169  "SQL database hostname (e.g., localhost)")
170  ("port,P",
171  boost::program_options::value< std::string >(&ioDBPort)->default_value(K_TRADEMGEN_DEFAULT_DB_PORT),
172  "SQL database port (e.g., 3306)")
173  ("dbname,m",
174  boost::program_options::value< std::string >(&ioDBDBName)->default_value(K_TRADEMGEN_DEFAULT_DB_DBNAME),
175  "SQL database name (e.g., sim_dsim)")
176  ("query,q",
177  boost::program_options::value< WordList_T >(&lWordList)->multitoken(),
178  "Query word list")
179  ;
180 
181  // Hidden options, will be allowed both on command line and
182  // in config file, but will not be shown to the user.
183  boost::program_options::options_description hidden ("Hidden options");
184  hidden.add_options()
185  ("copyright",
186  boost::program_options::value< std::vector<std::string> >(),
187  "Show the copyright (license)");
188 
189  boost::program_options::options_description cmdline_options;
190  cmdline_options.add(generic).add(config).add(hidden);
191 
192  boost::program_options::options_description config_file_options;
193  config_file_options.add(config).add(hidden);
194 
195  boost::program_options::options_description visible ("Allowed options");
196  visible.add(generic).add(config);
197 
198  boost::program_options::positional_options_description p;
199  p.add ("copyright", -1);
200 
201  boost::program_options::variables_map vm;
202  boost::program_options::
203  store (boost::program_options::command_line_parser (argc, argv).
204  options (cmdline_options).positional(p).run(), vm);
205 
206  std::ifstream ifs ("trademgen_with_db.cfg");
207  boost::program_options::store (parse_config_file (ifs, config_file_options),
208  vm);
209  boost::program_options::notify (vm);
210 
211  if (vm.count ("help")) {
212  std::cout << visible << std::endl;
214  }
215 
216  if (vm.count ("version")) {
217  std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
219  }
220 
221  if (vm.count ("prefix")) {
222  std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
224  }
225 
226  if (vm.count ("builtin")) {
227  ioIsBuiltin = true;
228  }
229  const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no";
230  std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl;
231 
232  if (ioIsBuiltin == false) {
233 
234  // The BOM tree should be built from parsing a demand input file
235  if (vm.count ("input")) {
236  ioInputFilename = vm["input"].as< std::string >();
237  std::cout << "Input filename is: " << ioInputFilename << std::endl;
238 
239  } else {
240  // The built-in option is not selected. However, no demand input file
241  // is specified
242  std::cerr << "Either one among the -b/--builtin and -i/--input "
243  << "options must be specified" << std::endl;
244  }
245  }
246 
247  if (vm.count ("log")) {
248  ioLogFilename = vm["log"].as< std::string >();
249  std::cout << "Log filename is: " << ioLogFilename << std::endl;
250  }
251 
252  if (vm.count ("user")) {
253  ioDBUser = vm["user"].as< std::string >();
254  std::cout << "SQL database user name is: " << ioDBUser << std::endl;
255  }
256 
257  if (vm.count ("passwd")) {
258  ioDBPasswd = vm["passwd"].as< std::string >();
259  // std::cout << "SQL database user password is: " << ioDBPasswd << std::endl;
260  }
261 
262  if (vm.count ("host")) {
263  ioDBHost = vm["host"].as< std::string >();
264  std::cout << "SQL database host name is: " << ioDBHost << std::endl;
265  }
266 
267  if (vm.count ("port")) {
268  ioDBPort = vm["port"].as< std::string >();
269  std::cout << "SQL database port number is: " << ioDBPort << std::endl;
270  }
271 
272  if (vm.count ("dbname")) {
273  ioDBDBName = vm["dbname"].as< std::string >();
274  std::cout << "SQL database name is: " << ioDBDBName << std::endl;
275  }
276 
277  //
278  std::cout << "The random generation seed is: " << ioRandomSeed << std::endl;
279 
280  ioQueryString = createStringFromWordList (lWordList);
281  std::cout << "The query string is: " << ioQueryString << std::endl;
282 
283  return 0;
284 }
285 
286 
287 // /////////////// M A I N /////////////////
288 int main (int argc, char* argv[]) {
289 
290  // State whether the BOM tree should be built-in or parsed from an input file
291  bool isBuiltin;
292 
293  // Random generation seed
294  stdair::RandomSeed_T lRandomSeed;
295 
296  // Query
297  std::string lQuery;
298 
299  // Input file name
300  stdair::Filename_T lInputFilename;
301 
302  // Output log File
303  std::string lLogFilename;
304 
305  // SQL database parameters
306  std::string lDBUser;
307  std::string lDBPasswd;
308  std::string lDBHost;
309  std::string lDBPort;
310  std::string lDBDBName;
311 
312  // Airline code
313  const stdair::AirlineCode_T lAirlineCode ("BA");
314 
315  // Call the command-line option parser
316  const int lOptionParserStatus =
317  readConfiguration (argc, argv, isBuiltin, lRandomSeed, lQuery,
318  lInputFilename, lLogFilename,
319  lDBUser, lDBPasswd, lDBHost, lDBPort, lDBDBName);
320 
321  if (lOptionParserStatus == K_TRADEMGEN_EARLY_RETURN_STATUS) {
322  return 0;
323  }
324 
325  // Set the database parameters
326  stdair::BasDBParams lDBParams (lDBUser, lDBPasswd, lDBHost, lDBPort,
327  lDBDBName);
328 
329  // Set the log parameters
330  std::ofstream logOutputFile;
331  // open and clean the log outputfile
332  logOutputFile.open (lLogFilename.c_str());
333  logOutputFile.clear();
334 
335  // Set up the log parameters
336  const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
337 
338  // Initialise the TraDemGen service object
339  TRADEMGEN::TRADEMGEN_Service trademgenService (lLogParams, lDBParams,
340  lRandomSeed);
341 
342  // Check wether or not a (CSV) input file should be read
343  if (isBuiltin == true) {
344  // Create a sample DemandStream object, and insert it within the BOM tree
345  trademgenService.buildSampleBom();
346 
347  } else {
348  // Create the DemandStream objects, and insert them within the BOM tree
349  const TRADEMGEN::DemandFilePath lDemandFilePath (lInputFilename);
350  trademgenService.parseAndLoad (lDemandFilePath);
351  }
352 
353  // Query the database
354  trademgenService.displayAirlineListFromDB();
355 
356  // Close the Log outputFile
357  logOutputFile.close();
358 
359  return 0;
360 }