89 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Error, no Database Host!\n");
96 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Error, no Database Name!\n");
102 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Error, no Database Username!\n");
108 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Error, no Database Password!\n");
114 sprintf(port,
"%i", tcp_port);
116 (
char*)host, port,
"",
"",
117 (
char*)dbName, (
char*)userName, (
char*)password
122 LOG_ERR,
"CAAccountingDBInterface: Could not connect to Database. Reason: %s\n",
141 if (PQstatus(
m_dbConn) != CONNECTION_OK)
143 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Connection to database lost! Reason: %s\n",
147 if (PQstatus(
m_dbConn) != CONNECTION_OK)
149 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Could not reset database connection! Reason: %s\n",
155 CAMsg::printMsg(LOG_INFO,
"CAAccountingDBInterface: Database connection has been reset successfully!");
229 const char* queryF =
"SELECT XMLCC, SETTLED FROM COSTCONFIRMATIONS WHERE ACCOUNTNUMBER=%s AND CASCADE='%s'";
236 query =
new UINT8[strlen(queryF) + 32 + strlen((
char*)cascadeId)];
237 sprintf( (
char *)query, queryF, tmp, cascadeId);
239 CAMsg::printMsg(LOG_DEBUG,
"CAAccountingDBInterface: executing query %s\n", query);
246 if(PQresultStatus(result)!=PGRES_TUPLES_OK)
248 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Could not read XMLCC. Reason: %s\n",
249 PQresultErrorMessage(result));
254 if(PQntuples(result)!=1)
257 CAMsg::printMsg(LOG_DEBUG,
"CAAccountingDBInterface: XMLCC not found.\n");
263 xmlCC = (
UINT8*) PQgetvalue(result, 0, 0);
264 if (atoi(PQgetvalue(result, 0, 1)) == 0)
273 *pCC = CAXMLCostConfirmation::getInstance(xmlCC,strlen((
char*)xmlCC));
313 if(PQresultStatus(pResult) != PGRES_TUPLES_OK)
316 "CAAccountingDBInterface: Database Error '%s' while processing query '%s'\n",
317 PQresultErrorMessage(pResult), a_query
323 if ( (PQntuples(pResult) != 1) || (PQgetisnull(pResult, 0, 0)))
325 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Wrong number of tuples or null value\n");
330 r_count = atoi(PQgetvalue(pResult, 0, 0));
354 #ifndef HAVE_NATIVE_UINT64
355 #warning Native UINT64 type not available - CostConfirmation Database might be non-functional
357 const char* previousCCQuery =
"SELECT COUNT(*) FROM COSTCONFIRMATIONS WHERE ACCOUNTNUMBER='%s' AND CASCADE='%s'";
358 const char* query2F =
"INSERT INTO COSTCONFIRMATIONS(BYTES, XMLCC, SETTLED, ACCOUNTNUMBER, CASCADE) VALUES ('%s', '%s', '%d', '%s', '%s')";
359 const char* query3F =
"UPDATE COSTCONFIRMATIONS SET BYTES='%s', XMLCC='%s', SETTLED='%d' WHERE ACCOUNTNUMBER='%s' AND CASCADE='%s'";
360 const char* tempQuery;
368 UINT8 strAccountNumber[32];
378 pStrCC =
new UINT8[8192];
380 if(cc.toXMLString(pStrCC, &size)!=
E_SUCCESS)
382 CAMsg::printMsg(LOG_DEBUG,
"CAAccountingInstanceDBInterface: Could not transform CC to XML string!\n");
393 len =
max(strlen(previousCCQuery), strlen(query2F));
395 query =
new UINT8[
len + 32 + 32 + 1 + size + strlen((
char*)ccCascade)];
396 print64(strAccountNumber,cc.getAccountNumber());
397 sprintf( (
char*)query, previousCCQuery, strAccountNumber, ccCascade);
410 print64(tmp,cc.getTransferredBytes());
419 sprintf((
char*)query, tempQuery, tmp, pStrCC, 0, strAccountNumber, ccCascade);
426 if(PQresultStatus(pResult) != PGRES_COMMAND_OK)
432 "Database message '%s' while processing query '%s'\n",
433 PQresultErrorMessage(pResult), query
446 CAMsg::printMsg(LOG_DEBUG,
"CAAccountingInstanceDBInterface: Finished storing CC in DB.\n");
473 const char* query=
"SELECT XMLCC FROM COSTCONFIRMATIONS WHERE SETTLED=0 AND CASCADE = '%s' LIMIT %u";
478 CAXMLCostConfirmation* pCC;
487 finalQuery =
new UINT8[strlen(query)+strlen((
char*)cascadeId)];
488 sprintf( (
char*)finalQuery, query, cascadeId, a_maxCCs);
491 CAMsg::printMsg(LOG_DEBUG,
"Getting Cost confirmations for cascade: ");
499 if(PQresultStatus(result) != PGRES_TUPLES_OK)
504 numTuples = PQntuples(result);
505 *nrOfCCs = numTuples;
510 *resultCCs =
new CAXMLCostConfirmation *[numTuples];
514 pTmpStr = (
UINT8*) PQgetvalue(result, i, 0);
515 if( (pTmpStr!=NULL)&&
516 ( (pCC = CAXMLCostConfirmation::getInstance(pTmpStr,strlen((
char*)pTmpStr)) )!=NULL))
518 (*resultCCs)[i] = pCC;
554 const char* queryF =
"UPDATE COSTCONFIRMATIONS SET SETTLED=1 WHERE ACCOUNTNUMBER=%s AND BYTES=%s AND CASCADE='%s'";
565 UINT8 tmp[32], tmp2[32];
567 print64(tmp2,a_transferredBytes);
568 query =
new UINT8[strlen(queryF) + 32 + 32 + strlen((
char*)cascadeId)];
569 sprintf((
char *)query, queryF, tmp, tmp2, cascadeId);
574 if(PQresultStatus(result) != PGRES_COMMAND_OK)
598 const char* deleteQuery =
"DELETE FROM COSTCONFIRMATIONS WHERE ACCOUNTNUMBER = %s AND CASCADE='%s'";
614 finalQuery =
new UINT8[strlen(deleteQuery)+ 32 + strlen((
char*)cascadeId)];
615 sprintf((
char *)finalQuery,deleteQuery,temp, cascadeId);
621 if (PQresultStatus(result) != PGRES_COMMAND_OK)
635 CAMsg::printMsg(LOG_INFO,
"CAAccountingDBInterface: Costconfirmation for account %s was deleted!\n", temp);
639 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Could not delete account %s!\n", temp);
661 const char* selectQuery =
"SELECT COUNT(*) FROM PREPAIDAMOUNTS WHERE ACCOUNTNUMBER=%s AND CASCADE='%s'";
662 const char* insertQuery =
"INSERT INTO PREPAIDAMOUNTS(PREPAIDBYTES, ACCOUNTNUMBER, CASCADE) VALUES (%d, %s, '%s')";
663 const char* updateQuery =
"UPDATE PREPAIDAMOUNTS SET PREPAIDBYTES=%d WHERE ACCOUNTNUMBER=%s AND CASCADE='%s'";
682 len =
max(strlen(selectQuery), strlen(insertQuery));
684 finalQuery =
new UINT8[
len + 32 + 32 + strlen((
char*)cascadeId)];
685 sprintf( (
char *)finalQuery, selectQuery, tmp, cascadeId);
708 sprintf((
char*)finalQuery, query, prepaidBytes, tmp, cascadeId);
711 if (PQresultStatus(result) != PGRES_COMMAND_OK)
713 CAMsg::printMsg(LOG_ERR,
"CAAccountungDBInterface: Saving to prepaidamounts failed!\n");
717 "Database message '%s' while processing query '%s'\n",
718 PQresultErrorMessage(result), finalQuery
732 CAMsg::printMsg(LOG_DEBUG,
"CAAccountingDBInterface: Stored %d prepaid bytes for account nr. %s \n",prepaidBytes, tmp);
756 const char* selectQuery =
"SELECT PREPAIDBYTES FROM PREPAIDAMOUNTS WHERE ACCOUNTNUMBER=%s AND CASCADE='%s'";
759 UINT8 accountNumberAsString[32];
760 print64(accountNumberAsString,accountNumber);
769 finalQuery =
new UINT8[strlen(selectQuery) + 32 + strlen((
char*)cascadeId)];
770 sprintf( (
char *)finalQuery, selectQuery, accountNumberAsString, cascadeId);
773 if(PQresultStatus(result)!=PGRES_TUPLES_OK)
775 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Database error while trying to read prepaid bytes, Reason: %s\n", PQresultErrorMessage(result));
782 if(PQntuples(result)!=1)
790 SINT32 nrOfBytes = atoi(PQgetvalue(result, 0, 0));
796 const char* deleteQuery =
"DELETE FROM PREPAIDAMOUNTS WHERE ACCOUNTNUMBER=%s AND CASCADE='%s' ";
798 print64(accountNumberAsString,accountNumber);
799 sprintf( (
char *)finalQuery, deleteQuery, accountNumberAsString, cascadeId);
803 if (PQresultStatus(result2) != PGRES_COMMAND_OK)
805 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Deleting read prepaidamount failed.");
832 const char* previousStatusQuery =
"SELECT COUNT(*) FROM ACCOUNTSTATUS WHERE ACCOUNTNUMBER='%s' ";
834 const char* insertQuery =
"INSERT INTO ACCOUNTSTATUS(STATUSCODE,ACCOUNTNUMBER) VALUES ('%u', '%s')";
835 const char* updateQuery =
"UPDATE ACCOUNTSTATUS SET STATUSCODE=%u WHERE ACCOUNTNUMBER=%s";
852 len =
max(strlen(previousStatusQuery), strlen(insertQuery));
854 finalQuery =
new UINT8[
len + 32 + 32 + 32];
855 sprintf( (
char *)finalQuery, previousStatusQuery, tmp);
873 sprintf((
char*)finalQuery, query, statuscode, tmp);
876 if (PQresultStatus(result) != PGRES_COMMAND_OK)
878 CAMsg::printMsg(LOG_ERR,
"CAAccountungDBInterface: Saving the account status failed!\n");
882 "Database Error '%s' while processing query '%s'\n",
883 PQresultErrorMessage(result), finalQuery
897 CAMsg::printMsg(LOG_DEBUG,
"Stored status code %u for account nr. %s \n",statuscode, tmp);
916 PGresult* result = NULL;
918 char* clearAccountStatusStmt=
new char[queryMaxLen+1];
919 memset(clearAccountStatusStmt, 0, queryMaxLen+1);
924 CAMsg::printMsg(LOG_DEBUG,
"Cannot clear account status: accountnumber &llu is invalid.\n",
926 delete[] clearAccountStatusStmt;
933 if (PQresultStatus(result) != PGRES_COMMAND_OK)
935 CAMsg::printMsg(LOG_DEBUG,
"Clearing accountstatus for account %llu failed.\n", a_accountNumber);
939 delete[] clearAccountStatusStmt;
942 delete[] clearAccountStatusStmt;
943 CAMsg::printMsg(LOG_DEBUG,
"Clearing accountstatus for account %llu failed.\n", a_accountNumber);
964 const char* selectQuery =
"SELECT STATUSCODE FROM ACCOUNTSTATUS WHERE ACCOUNTNUMBER = %s";
967 UINT8 accountNumberAsString[32];
968 print64(accountNumberAsString,accountNumber);
979 finalQuery =
new UINT8[strlen(selectQuery) + 32];
980 sprintf( (
char *)finalQuery, selectQuery, accountNumberAsString);
985 if(PQresultStatus(result)!=PGRES_TUPLES_OK)
987 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: Database error while trying to read account status, Reason: %s\n", PQresultErrorMessage(result));
992 if(PQntuples(result) == 1)
994 int statusCodeIndex = PQfnumber(result,
"STATUSCODE");
996 if(statusCodeIndex != -1 )
998 a_statusCode = atoi(PQgetvalue(result, 0, statusCodeIndex));
1002 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: no status code found while reading account status\n");
1028 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: No DBConnection available. This should NEVER happen!\n");
1033 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: DBConnections not initialized. This should NEVER happen!\n");
1053 CAMsg::printMsg(LOG_DEBUG,
"CAAccountingDBInterface: Thread %x waits for connection with waitNr %Lu and %Lu Threads waiting before\n",
1061 CAMsg::printMsg(LOG_DEBUG,
"CAAccountingDBInterface: Thread %x with waitNr %Lu continues\n",
1062 pthread_self(), myWaitNr);
1074 if(returnedConnection != NULL)
1081 CAMsg::printMsg(LOG_WARNING,
"CAAccountingDBInterface: Warning requested DB connection can not be established\n");
1095 return returnedConnection;
1114 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: DBConnection structure corrupt!\n");
1119 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: DBConnections not initialized. This should NEVER happen!\n");
1130 CAMsg::printMsg(LOG_DEBUG,
"CAAccountingDBInterface: There are %Lu Threads waiting. Waking up thread with waitNr. %Lu\n",
1148 bool success =
false;
1162 bool success =
false;
1198 CAMsg::printMsg(LOG_CRIT,
"CAAccountingDBInterface: DBConnection initialization: "
1199 "could not connect to Database.\n");
1206 CAMsg::printMsg(LOG_CRIT,
"CAAccountingDBInterface: DBConnection initialization failed.\n");
1232 CAMsg::printMsg(LOG_ERR,
"CAAccountingDBInterface: DBConnection cleanup: "
1233 "an error occured while closing DBConnection.\n");
1248 PGresult* result = NULL;
1249 result = PQexec(conn, query);
#define MAX_DB_CONNECTIONS
#define STMT_CLEAR_ACCOUNT_STATUS
#define MONITORING_FIRE_PAY_EVENT(e_type)
unsigned long long thread_id_t
Type of an ID for a thread which can be used to identify the current and other threads.
void print64(UINT8 *buff, UINT64 num)
#define ACCOUNT_NUMBER_SIZE
#define MIN_ACCOUNTNUMBER
#define MAX_ACCOUNTNUMBER
SINT32 storePrepaidAmount(UINT64 accountNumber, SINT32 prepaidBytes, UINT8 *cascadeId)
static CAAccountingDBInterface * getConnection()
static CAAccountingDBInterface * ms_pDBConnectionPool[]
SINT32 __clearAccountStatus(UINT64 a_accountNumber)
SINT32 __storePrepaidAmount(UINT64 accountNumber, SINT32 prepaidBytes, UINT8 *cascadeId)
SINT32 initDBConnection()
Initiates the database connection.
SINT32 checkCountAllQuery(UINT8 *a_query, UINT32 &r_count)
Takes and executes a query that counts databae records and tests if the result is valid.
SINT32 __markAsSettled(UINT64 accountNumber, UINT8 *cascadeId, UINT64 a_transferredBytes)
Marks this account as settled.
SINT32 storeCostConfirmation(CAXMLCostConfirmation &cc, UINT8 *ccCascade)
Creates the tables we need in the DB.
SINT32 clearAccountStatus(UINT64 a_accountNumber)
bool checkConnectionStatus()
Checks if the connection still exists and tries to reconnect if not.
~CAAccountingDBInterface()
Destructor.
SINT32 __getCostConfirmation(UINT64 accountNumber, UINT8 *cascadeId, CAXMLCostConfirmation **pCC, bool &a_bSettled)
Gets the latest cost confirmation stored for the given user account.
static volatile UINT64 ms_threadWaitNr
SINT32 __storeCostConfirmation(CAXMLCostConfirmation &cc, UINT8 *ccCascade)
stores a cost confirmation in the DB
CAAccountingDBInterface()
Constructor.
SINT32 __getAccountStatus(UINT64 a_accountNumber, UINT32 &a_statusCode)
SINT32 __checkCountAllQuery(UINT8 *a_query, UINT32 &r_count)
SINT32 __getPrepaidAmount(UINT64 accountNumber, UINT8 *cascadeId, bool a_bDelete)
static SINT32 releaseConnection(CAAccountingDBInterface *dbIf)
static CAConditionVariable * ms_pConnectionAvailable
SINT32 getCostConfirmation(UINT64 accountNumber, UINT8 *cascadeId, CAXMLCostConfirmation **pCC, bool &a_bSettled)
SINT32 getAccountStatus(UINT64 a_accountNumber, UINT32 &a_statusCode)
SINT32 __deleteCC(UINT64 accountNumber, UINT8 *cascadeId)
PGconn * m_dbConn
connection to postgreSQL database
SINT32 __getUnsettledCostConfirmations(CAXMLCostConfirmation ***resultCCs, UINT8 *cascadeId, UINT32 *nrOfCCs, UINT32 a_maxCCs)
Fills the CAQueue with pointer to all non-settled cost confirmations.
SINT32 __storeAccountStatus(UINT64 a_accountNumber, UINT32 a_statusCode)
SINT32 deleteCC(UINT64 accountNumber, UINT8 *cascadeId)
if the BI reports an error while trying to settle a CC, this will be called to delete it from the dat...
PGresult * monitored_PQexec(PGconn *conn, const char *query)
static volatile UINT64 ms_nextThreadNr
SINT32 getUnsettledCostConfirmations(CAXMLCostConfirmation ***resultCCs, UINT8 *cascadeId, UINT32 *nrOfCCs, UINT32 a_maxCCs)
Fills the CAQueue with all non-settled cost confirmations.
SINT32 storeAccountStatus(UINT64 a_accountNumber, UINT32 a_statusCode)
SINT32 markAsSettled(UINT64 accountNumber, UINT8 *cascadeId, UINT64 a_transferredBytes)
Marks this account as settled.
SINT32 getPrepaidAmount(UINT64 accountNumber, UINT8 *cascadeId, bool a_bDelete)
SINT32 terminateDBConnection()
Terminates the database connection.
volatile thread_id_t m_owner
CAMutex * m_pConnectionMutex
SINT32 broadcast()
Signals this object.
SINT32 wait()
Waits for a signal or for a timeout.
static CACmdLnOptions * getOptions()
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
static thread_id_t getSelfID()
static const UINT32 ERR_OK