0.08.02
C++ Open Travel Request Parsing Library
Toggle main menu visibility
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
11
#include <
opentrep/OPENTREP_exceptions.hpp
>
12
#include <
opentrep/DBType.hpp
>
13
#include <
opentrep/basic/Utilities.hpp
>
14
#include <
opentrep/service/Logger.hpp
>
15
16
namespace
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
// //////////////////////////////////////////////////////////////////////
106
StringMap_T
107
parseMySQLConnectionString
(
const
SQLDBConnectionString_T
& iSQLDBConnStr) {
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());
144
throw
SQLDatabaseConnectionStringParsingException
(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());
154
throw
SQLDatabaseConnectionStringParsingException
(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());
164
throw
SQLDatabaseConnectionStringParsingException
(errStr.str());
165
}
166
167
return
oStrMap;
168
}
169
170
// //////////////////////////////////////////////////////////////////////
171
SQLDBConnectionString_T
172
buildMySQLConnectionString
(
const
StringMap_T
& iStringMap,
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
222
displayMySQLConnectionString
(
const
StringMap_T
& iStringMap,
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
// //////////////////////////////////////////////////////////////////////
243
StringMap_T
244
parsePGConnectionString
(
const
SQLDBConnectionString_T
& iSQLDBConnStr) {
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());
273
throw
SQLDatabaseConnectionStringParsingException
(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());
281
throw
SQLDatabaseConnectionStringParsingException
(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());
289
throw
SQLDatabaseConnectionStringParsingException
(errStr.str());
290
}
291
292
return
oStrMap;
293
}
294
295
// //////////////////////////////////////////////////////////////////////
296
SQLDBConnectionString_T
297
buildPGConnectionString
(
const
StringMap_T
& iStringMap,
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
329
displayPGConnectionString
(
const
StringMap_T
& iStringMap,
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
351
parseAndDisplayConnectionString
(
const
DBType
& iDBType,
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
}
DBType.hpp
Logger.hpp
OPENTREP_LOG_ERROR
#define OPENTREP_LOG_ERROR(iToBeLogged)
Definition
Logger.hpp:24
OPENTREP_exceptions.hpp
Utilities.hpp
OPENTREP::SQLDatabaseConnectionStringParsingException
Definition
OPENTREP_exceptions.hpp:333
OPENTREP
Definition
BasChronometer.cpp:10
OPENTREP::WordList_T
std::list< Word_T > WordList_T
Definition
OPENTREP_Types.hpp:690
OPENTREP::tokeniseStringIntoWordList
void tokeniseStringIntoWordList(const std::string &iPhrase, WordList_T &ioWordList)
Definition
Utilities.cpp:19
OPENTREP::buildMySQLConnectionString
SQLDBConnectionString_T buildMySQLConnectionString(const StringMap_T &iStringMap, const DeploymentNumber_T &iDeploymentNumber)
Definition
Utilities.cpp:172
OPENTREP::createStringFromWordList
std::string createStringFromWordList(const WordList_T &iWordList, const NbOfWords_T iSplitIdx, const bool iFromBeginningFlag)
Definition
Utilities.cpp:43
OPENTREP::displayMySQLConnectionString
std::string displayMySQLConnectionString(const StringMap_T &iStringMap, const DeploymentNumber_T &iDeploymentNumber)
Definition
Utilities.cpp:222
OPENTREP::DEFAULT_OPENTREP_DEPLOYMENT_NUMBER_SIZE
const unsigned short DEFAULT_OPENTREP_DEPLOYMENT_NUMBER_SIZE
OPENTREP::buildPGConnectionString
SQLDBConnectionString_T buildPGConnectionString(const StringMap_T &iStringMap, const DeploymentNumber_T &iDeploymentNumber)
Definition
Utilities.cpp:297
OPENTREP::displayPGConnectionString
std::string displayPGConnectionString(const StringMap_T &iStringMap, const DeploymentNumber_T &iDeploymentNumber)
Definition
Utilities.cpp:329
OPENTREP::parseAndDisplayConnectionString
std::string parseAndDisplayConnectionString(const DBType &iDBType, const std::string &iSQLDBConnStr, const DeploymentNumber_T &iDeploymentNumber)
Definition
Utilities.cpp:351
OPENTREP::parseMySQLConnectionString
StringMap_T parseMySQLConnectionString(const SQLDBConnectionString_T &iSQLDBConnStr)
Definition
Utilities.cpp:107
OPENTREP::DeploymentNumber_T
unsigned short DeploymentNumber_T
Definition
OPENTREP_Types.hpp:108
OPENTREP::parsePGConnectionString
StringMap_T parsePGConnectionString(const SQLDBConnectionString_T &iSQLDBConnStr)
Definition
Utilities.cpp:244
OPENTREP::StringMap_T
std::map< const std::string, std::string > StringMap_T
Definition
Utilities.hpp:43
OPENTREP::NbOfWords_T
unsigned short NbOfWords_T
Definition
OPENTREP_Types.hpp:710
OPENTREP::DBType
Enumeration of database types.
Definition
DBType.hpp:17
OPENTREP::DBType::MYSQL
@ MYSQL
Definition
DBType.hpp:23
OPENTREP::DBType::PG
@ PG
Definition
DBType.hpp:22
OPENTREP::DBType::SQLITE3
@ SQLITE3
Definition
DBType.hpp:21
OPENTREP::DBType::NODB
@ NODB
Definition
DBType.hpp:20
OPENTREP::SQLDBConnectionString_T
Definition
OPENTREP_Types.hpp:56
Generated on
for OpenTREP by
1.17.0