22 #include <boost/thread/mutex.hpp>
23 #include <boost/thread/locks.hpp>
28 const std::string& dbPort,
29 const std::string& dbUsr,
30 const std::string& dbPwd,
31 const std::string& dbName):
38 fConnectAttemptTimeoutSec(0),
39 fMinConnectDelaySec(-1),
40 fMaxConnectDelaySec(-1),
41 fDisconnectTimeoutSec(-1),
46 fMutex =
new boost::mutex();
78 int maxNumAttempts = 0;
79 double sleepTimeSec = 1;
97 if(attempt++ < maxNumAttempts)
120 const char* pgoptions = NULL;
121 const char* pgtty = NULL;
133 std::string msg =
"Cannot connect to DB. Srv="
153 boost::lock_guard<boost::mutex> guard(*
fMutex);
192 return table.begin()->second.front().GetDouble();
208 return table.begin()->second.front().GetInt();
224 return table.begin()->second.front().GetBool();
240 return table.begin()->second.front().GetString();
256 return table.begin()->second[0].GetVectorInt();
271 return table.begin()->second[0].GetVectorDouble();
287 return table.begin()->second[0].GetVectorString();
294 PGresult* result = NULL;
307 PGresult* result = NULL;
313 sscanf(PQcmdTuples(result),
"%d", &affected);
322 if(fields.size() != values.size()) {
324 std::string errMsg =
"QDb::Insert: size of fields differs from size of values";
325 err.SetDescription(__FILE__,__LINE__,errMsg);
329 std::string fieldlist;
330 std::string valuelist;
331 for(
size_t i = 0; i < fields.size(); i++) {
332 std::string valuestr = values[i].GetString();
333 if(valuestr ==
"NULL" || valuestr ==
"Null" || valuestr ==
"null") {
continue; }
338 valuelist += valuestr;
339 fieldlist += fields[i].GetString();
342 std::stringstream query;
343 query<<
"INSERT into "<<tableName<<
" ("<<fieldlist<<
")"
344 <<
" SELECT "<<valuelist<<
" WHERE NOT EXISTS ("
345 <<
" SELECT * from "<<tableName<<
" WHERE "
346 <<
"("<<fieldlist<<
") IN (("<<valuelist<<
")))";
347 return DoExec(query.str());
354 boost::lock_guard<boost::mutex> guard(*
fMutex);
379 ExecStatusType status = PQresultStatus(*result);
382 case PGRES_TUPLES_OK:
383 case PGRES_COMMAND_OK:
386 case PGRES_BAD_RESPONSE:
387 case PGRES_NONFATAL_ERROR:
388 case PGRES_FATAL_ERROR:
389 case PGRES_EMPTY_QUERY:
392 case PGRES_COPY_BOTH:
395 std::string msg =
"DoQuery: Error while executing query \""
398 + PQresStatus(status)
400 + PQresultErrorMessage(*result);
413 PGresult *result = NULL;
418 if (PQresultStatus (result) != PGRES_TUPLES_OK)
420 std::string errMsg =
"DoQuery: Error while executing query \"";
423 errMsg += PQresultErrorMessage(result);
429 int nRows = PQntuples(result);
438 int numFields = PQnfields(result);
439 for (
int field = 0; field < numFields; field++)
441 const char *fieldName = PQfname(result, field);
442 table[fieldName].reserve(nRows);
443 for (
int row = 0; row < nRows; row++)
445 const char *value = PQgetvalue(result, row, field);
446 table[fieldName].push_back(
QVdt(value, fieldName));
457 const std::string& query,
458 const std::string& funcName,
459 const std::string& file,
467 "No fields returned in "
473 "Multiple fields returned in "
479 const column& col = table.begin()->second;
482 "No rows returned in "
488 "Multiple rows returned in "
509 int randGranularity = 5000;
511 = intervalSec * (rand() % randGranularity) / randGranularity;
514 int numSecs = (int)sleepTimeSec;
515 int numMicroSecs = 1e6*(sleepTimeSec - numSecs);
517 usleep(numMicroSecs);
561 bool isRunning =
false;
568 "Watchdog timer thread died unexpectedly");
@ QERR_DB_MAXLINES_EXCEEDED
QError Check(bool &isRunning)
void SetDatabase(QDb *db)
void SetWatchdogTimer(QWatchdogTimer *timer)
std::vector< std::string > DoQueryVectorString(const std::string &query)
double fMinConnectDelaySec
QWatchdogTimer * fWatchdogTimer
std::vector< QVdt > column
std::vector< double > DoQueryVectorDouble(const std::string &query)
double fMaxConnectDelaySec
double fDisconnectTimeoutSec
QDbWatchdogThreadHandler * fThreadHandler
QError UpdateWatchdogTimer()
std::vector< int > DoQueryVectorInt(const std::string &query)
const std::string fDbPort
bool DoQueryBool(const std::string &query)
QError DoQuery(const std::string &query, QDbTable &table)
QError CheckSingleResult(const QDbTable &table, const std::string &query, const std::string &funcName, const std::string &file, int line) const
const std::string fDbHost
std::map< std::string, column > QDbTable
int DoQueryInt(const std::string &query)
double DoQueryDouble(const std::string &query)
int DoExec(const std::string &Query)
Execute an INSERT, UPDATE, DELETE, FETCH, or MOVE statement.
std::string DoQueryString(const std::string &query)
QDb(const std::string &dbHost, const std::string &dbPort, const std::string &dbUsr, const std::string &dbPwd, const std::string &dbName)
void RandomWaitBeforeConnect() const
QError BasicQuery(const std::string &query, PGresult **result) const
QError DoSQLNoReturn(const std::string &query)
int fConnectAttemptTimeoutSec
const std::string fDbUser
QError Query(const std::string &query, PGresult **result)
int Insert(const std::string &tableName, const column &fields, const column &values)
bool UnlockedDisconnect()
QError InitWatchdogThread()
const std::string fDbName
error class with error type and description
QError SetTimeoutSec(double timeout)