OpenTREP Logo  0.08.02
C++ Open Travel Request Parsing Library
Loading...
Searching...
No Matches
Utilities.cpp
Go to the documentation of this file.
1// //////////////////////////////////////////////////////////////////////
2// Import section
3// //////////////////////////////////////////////////////////////////////
4// STL
5#include <cassert>
6#include <ostream>
7#include <sstream>
8// Boost (Extended STL)
9#include <boost/tokenizer.hpp>
10// OpenTrep
12#include <opentrep/DBType.hpp>
15
16namespace OPENTREP {
17
18 // //////////////////////////////////////////////////////////////////////
19 void tokeniseStringIntoWordList (const std::string& iPhrase,
20 WordList_T& ioWordList) {
21 // Empty the word list
22 ioWordList.clear();
23
24 // Boost Tokeniser
25 typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
26
27 // Define the single-character separators.
28 // Note that multi-byte Unicode characters (e.g., “, ”)
29 // should not be inserted here
30 const boost::char_separator<char>
31 lSepatorList(" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
32
33 // Initialise the phrase to be tokenised
34 Tokeniser_T lTokens (iPhrase, lSepatorList);
35 for (Tokeniser_T::const_iterator tok_iter = lTokens.begin();
36 tok_iter != lTokens.end(); ++tok_iter) {
37 const std::string& lTerm = *tok_iter;
38 ioWordList.push_back (lTerm);
39 }
40 }
41
42 // //////////////////////////////////////////////////////////////////////
43 std::string createStringFromWordList (const WordList_T& iWordList,
44 const NbOfWords_T iSplitIdx,
45 const bool iFromBeginningFlag) {
46 std::ostringstream oStr;
47
48 // Browse the left-hand side of the string
49 NbOfWords_T idx = 0;
50 WordList_T::const_iterator itWord = iWordList.begin();
51 for ( ; itWord != iWordList.end(); ++itWord, ++idx) {
52
53 if (iFromBeginningFlag == true) {
54 // The beginning of the word list is needed
55
56 // Check whether the sub-list has reached the expected split point,
57 // if any
58 if (iSplitIdx != 0 && idx >= iSplitIdx) {
59 break;
60 }
61
62 //
63 if (idx > 0) {
64 oStr << " ";
65 }
66 //
67 const std::string& lWord = *itWord;
68 oStr << lWord;
69
70 } else {
71 // The end of the word list is needed
72
73 // Check whether the sub-list has reached the expected split point,
74 // if any
75 if (iSplitIdx == 0 || idx >= iSplitIdx) {
76 break;
77 }
78 }
79 }
80
81 // The beginning of the word list is needed
82 if (iFromBeginningFlag == true) {
83 return oStr.str();
84 }
85
86 // The end of the word list is needed
87 assert (iFromBeginningFlag == false);
88
89 // Browse the right-hand side of the string
90 for ( ; itWord != iWordList.end(); ++itWord, ++idx) {
91 // The end of the word list is needed
92
93 //
94 if (idx > iSplitIdx) {
95 oStr << " ";
96 }
97 //
98 const std::string& lWord = *itWord;
99 oStr << lWord;
100 }
101
102 return oStr.str();
103 }
104
105 // //////////////////////////////////////////////////////////////////////
108 StringMap_T oStrMap;
109
110 // Split on spaces; each token is "key=value". Split each token on the
111 // first '=' only, so that passwords containing '=' are handled
112 // correctly. This also means that any key supported by the underlying
113 // MySQL/MariaDB client library (e.g., 'db', 'user', 'password', 'host',
114 // 'port', 'unix_socket', etc.) is accepted and preserved, instead of
115 // only a fixed, hard-coded subset.
116 std::stringstream lConnStream (iSQLDBConnStr);
117 std::string kvStr;
118
119 while (std::getline (lConnStream, kvStr, ' ')) {
120 if (kvStr.empty()) {
121 continue;
122 }
123
124 const size_t eqPos = kvStr.find ('=');
125 if (eqPos == std::string::npos) {
126 continue;
127 }
128
129 const std::string lKey = kvStr.substr (0, eqPos);
130 const std::string lVal = kvStr.substr (eqPos + 1);
131 oStrMap[lKey] = lVal;
132 }
133
137 // SQL database name
138 const StringMap_T::const_iterator itDBName = oStrMap.find ("db");
139 if (itDBName == oStrMap.end()) {
140 std::ostringstream errStr;
141 errStr << "Error when parsing the SQL database connection string ('"
142 << iSQLDBConnStr << "'), the 'db' value cannot be found";
143 OPENTREP_LOG_ERROR (errStr.str());
145 }
146
147 // SQL database user
148 const StringMap_T::const_iterator itDBUser = oStrMap.find ("user");
149 if (itDBUser == oStrMap.end()) {
150 std::ostringstream errStr;
151 errStr << "Error when parsing the SQL database connection string ('"
152 << iSQLDBConnStr << "'), the 'user' value cannot be found";
153 OPENTREP_LOG_ERROR (errStr.str());
155 }
156
157 // SQL database password
158 const StringMap_T::const_iterator itDBPasswd = oStrMap.find ("password");
159 if (itDBPasswd == oStrMap.end()) {
160 std::ostringstream errStr;
161 errStr << "Error when parsing the SQL database connection string ('"
162 << iSQLDBConnStr << "'), the 'password' value cannot be found";
163 OPENTREP_LOG_ERROR (errStr.str());
165 }
166
167 return oStrMap;
168 }
169
170 // //////////////////////////////////////////////////////////////////////
171 SQLDBConnectionString_T
173 const DeploymentNumber_T& iDeploymentNumber) {
174 std::ostringstream oStr;
175
176 // SQL database name
177 const StringMap_T::const_iterator itDBName = iStringMap.find ("db");
178 assert (itDBName != iStringMap.end());
179 const std::string& lDBName = itDBName->second;
180
181 // SQL database user
182 const StringMap_T::const_iterator itDBUser = iStringMap.find ("user");
183 assert (itDBUser != iStringMap.end());
184 const std::string& lDBUser = itDBUser->second;
185
186 // SQL database password
187 const StringMap_T::const_iterator itDBPasswd = iStringMap.find ("password");
188 assert (itDBPasswd != iStringMap.end());
189 const std::string& lDBPasswd = itDBPasswd->second;
190
191 //
192 oStr << "db=" << lDBName;
193 if (lDBName != "mysql") {
194 oStr << iDeploymentNumber;
195 }
196
197 //
198 oStr << " user=" << lDBUser;
199
200 //
201 oStr << " password=" << lDBPasswd;
202
203 // Optional host and port (and, more generally, any other extra key
204 // supported by the underlying MySQL/MariaDB client library) are passed
205 // through unchanged, since they do not need to be re-suffixed with the
206 // deployment number.
207 const StringMap_T::const_iterator itHost = iStringMap.find ("host");
208 if (itHost != iStringMap.end()) {
209 oStr << " host=" << itHost->second;
210 }
211
212 const StringMap_T::const_iterator itPort = iStringMap.find ("port");
213 if (itPort != iStringMap.end()) {
214 oStr << " port=" << itPort->second;
215 }
216
217 return SQLDBConnectionString_T (oStr.str());
218 }
219
220 // //////////////////////////////////////////////////////////////////////
221 std::string
223 const DeploymentNumber_T& iDeploymentNumber) {
224 std::ostringstream oStr;
225
226 for (StringMap_T::const_iterator itDBKV = iStringMap.begin();
227 itDBKV != iStringMap.end(); ++itDBKV) {
228 const std::string& lDBKey = itDBKV->first;
229 const std::string& lDBValue = itDBKV->second;
230 oStr << lDBKey << "=";
231 oStr << lDBValue;
232 if (lDBKey == "db" && lDBValue != "mysql"
233 && iDeploymentNumber != DEFAULT_OPENTREP_DEPLOYMENT_NUMBER_SIZE) {
234 oStr << iDeploymentNumber;
235 }
236 oStr << " ";
237 }
238
239 return oStr.str();
240 }
241
242 // //////////////////////////////////////////////////////////////////////
245 StringMap_T oStrMap;
246
247 // Split on spaces; each token is "key=value". Split each token on the
248 // first '=' only, so that passwords containing '=' are handled correctly.
249 std::stringstream lConnStream (iSQLDBConnStr);
250 std::string kvStr;
251
252 while (std::getline (lConnStream, kvStr, ' ')) {
253 if (kvStr.empty()) {
254 continue;
255 }
256
257 const size_t eqPos = kvStr.find ('=');
258 if (eqPos == std::string::npos) {
259 continue;
260 }
261
262 const std::string lKey = kvStr.substr (0, eqPos);
263 const std::string lVal = kvStr.substr (eqPos + 1);
264 oStrMap[lKey] = lVal;
265 }
266
267 // Validate required fields
268 if (oStrMap.find ("dbname") == oStrMap.end()) {
269 std::ostringstream errStr;
270 errStr << "Error when parsing the PG connection string ('"
271 << iSQLDBConnStr << "'), the 'dbname' value cannot be found";
272 OPENTREP_LOG_ERROR (errStr.str());
274 }
275
276 if (oStrMap.find ("user") == oStrMap.end()) {
277 std::ostringstream errStr;
278 errStr << "Error when parsing the PG connection string ('"
279 << iSQLDBConnStr << "'), the 'user' value cannot be found";
280 OPENTREP_LOG_ERROR (errStr.str());
282 }
283
284 if (oStrMap.find ("password") == oStrMap.end()) {
285 std::ostringstream errStr;
286 errStr << "Error when parsing the PG connection string ('"
287 << iSQLDBConnStr << "'), the 'password' value cannot be found";
288 OPENTREP_LOG_ERROR (errStr.str());
290 }
291
292 return oStrMap;
293 }
294
295 // //////////////////////////////////////////////////////////////////////
296 SQLDBConnectionString_T
298 const DeploymentNumber_T& iDeploymentNumber) {
299 std::ostringstream oStr;
300
301 const StringMap_T::const_iterator itDBName = iStringMap.find ("dbname");
302 assert (itDBName != iStringMap.end());
303 oStr << "dbname=" << itDBName->second << iDeploymentNumber;
304
305 const StringMap_T::const_iterator itDBUser = iStringMap.find ("user");
306 assert (itDBUser != iStringMap.end());
307 oStr << " user=" << itDBUser->second;
308
309 const StringMap_T::const_iterator itDBPasswd = iStringMap.find ("password");
310 assert (itDBPasswd != iStringMap.end());
311 oStr << " password=" << itDBPasswd->second;
312
313 // Preserve optional host and port
314 const StringMap_T::const_iterator itHost = iStringMap.find ("host");
315 if (itHost != iStringMap.end()) {
316 oStr << " host=" << itHost->second;
317 }
318
319 const StringMap_T::const_iterator itPort = iStringMap.find ("port");
320 if (itPort != iStringMap.end()) {
321 oStr << " port=" << itPort->second;
322 }
323
324 return SQLDBConnectionString_T (oStr.str());
325 }
326
327 // //////////////////////////////////////////////////////////////////////
328 std::string
330 const DeploymentNumber_T& iDeploymentNumber) {
331 std::ostringstream oStr;
332
333 for (StringMap_T::const_iterator itDBKV = iStringMap.begin();
334 itDBKV != iStringMap.end(); ++itDBKV) {
335 const std::string& lDBKey = itDBKV->first;
336 const std::string& lDBValue = itDBKV->second;
337 oStr << lDBKey << "=";
338 oStr << lDBValue;
339 if (lDBKey == "dbname"
340 && iDeploymentNumber != DEFAULT_OPENTREP_DEPLOYMENT_NUMBER_SIZE) {
341 oStr << iDeploymentNumber;
342 }
343 oStr << " ";
344 }
345
346 return oStr.str();
347 }
348
349 // //////////////////////////////////////////////////////////////////////
350 std::string
352 const std::string& iSQLDBConnStr,
353 const DeploymentNumber_T& iDeploymentNumber) {
354 std::ostringstream oStr;
355
356 if (iDBType == DBType::NODB) {
357 // Do nothing at this stage
358 oStr << "";
359
360 } else if (iDBType == DBType::SQLITE3) {
361 oStr << iSQLDBConnStr << iDeploymentNumber;
362
363 } else if (iDBType == DBType::MYSQL) {
364 // Parse the connection string
365 const SQLDBConnectionString_T lSQLDBConnStr (iSQLDBConnStr);
366 const StringMap_T& lStrMap = parseMySQLConnectionString (lSQLDBConnStr);
367
368 // Re-build the new connection string, taking into account the
369 // deployment number/version
370 const std::string& lNewSQLDBConnStr =
371 displayMySQLConnectionString (lStrMap, iDeploymentNumber);
372 oStr << lNewSQLDBConnStr;
373
374 } else if (iDBType == DBType::PG) {
375 // Parse the connection string
376 const SQLDBConnectionString_T lSQLDBConnStr (iSQLDBConnStr);
377 const StringMap_T& lStrMap = parsePGConnectionString (lSQLDBConnStr);
378
379 // Re-build the new connection string, taking into account the
380 // deployment number/version
381 const std::string& lNewSQLDBConnStr =
382 displayPGConnectionString (lStrMap, iDeploymentNumber);
383 oStr << lNewSQLDBConnStr;
384 }
385
386 //
387 return oStr.str();
388 }
389}
#define OPENTREP_LOG_ERROR(iToBeLogged)
Definition Logger.hpp:24
std::list< Word_T > WordList_T
void tokeniseStringIntoWordList(const std::string &iPhrase, WordList_T &ioWordList)
Definition Utilities.cpp:19
SQLDBConnectionString_T buildMySQLConnectionString(const StringMap_T &iStringMap, const DeploymentNumber_T &iDeploymentNumber)
std::string createStringFromWordList(const WordList_T &iWordList, const NbOfWords_T iSplitIdx, const bool iFromBeginningFlag)
Definition Utilities.cpp:43
std::string displayMySQLConnectionString(const StringMap_T &iStringMap, const DeploymentNumber_T &iDeploymentNumber)
const unsigned short DEFAULT_OPENTREP_DEPLOYMENT_NUMBER_SIZE
SQLDBConnectionString_T buildPGConnectionString(const StringMap_T &iStringMap, const DeploymentNumber_T &iDeploymentNumber)
std::string displayPGConnectionString(const StringMap_T &iStringMap, const DeploymentNumber_T &iDeploymentNumber)
std::string parseAndDisplayConnectionString(const DBType &iDBType, const std::string &iSQLDBConnStr, const DeploymentNumber_T &iDeploymentNumber)
StringMap_T parseMySQLConnectionString(const SQLDBConnectionString_T &iSQLDBConnStr)
unsigned short DeploymentNumber_T
StringMap_T parsePGConnectionString(const SQLDBConnectionString_T &iSQLDBConnStr)
std::map< const std::string, std::string > StringMap_T
Definition Utilities.hpp:43
unsigned short NbOfWords_T
Enumeration of database types.
Definition DBType.hpp:17