26#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO
76 mDBPassword(password),
82 InfoLog( <<
"Using PostgreSQL DB with server=" << server <<
", user=" << user <<
", dbName=" <<
databaseName <<
", port=" << port);
84 for (
int i=0;
i<MaxTable;
i++)
92 ErrLog( <<
"Repro uses PostgreSQL from multiple threads - you MUST link with a thread safe version of the PostgreSQL client library (libpq)!");
101PostgreSqlDb::~PostgreSqlDb()
103 disconnectFromDatabase();
107PostgreSqlDb::initialize()
const
117PostgreSqlDb::disconnectFromDatabase()
const
121 for (
int i=0;
i<MaxTable;
i++)
138PostgreSqlDb::connectToDatabase()
const
141 disconnectFromDatabase();
148 if(!mDBServer.empty())
165 if(!mDBPassword.empty())
206 if(mConn == 0 || !isConnected())
208 rc = connectToDatabase();
222 rc = connectToDatabase();
271 ErrLog(<<
"singleResultQuery: query failed, rc = " <<
rc);
284 DebugLog(<<
"singleResultQuery: no rows returned by query");
313 ds <<
"UPDATE " << tableName(UserTable) <<
" SET"
314 <<
" realm='" << rec.
realm
317 <<
"', name='" << rec.
name
318 <<
"', email='" << rec.
email
320 <<
"' WHERE username = '" << rec.
user
321 <<
"' AND domain='" << rec.
domain
323 <<
"INSERT INTO " << tableName(UserTable) <<
" (username, domain, realm, passwordHash, passwordHashAlt, name, email, forwardAddress)"
325 << rec.
user <<
"', '"
327 << rec.
realm <<
"', '"
330 << rec.
name <<
"', '"
331 << rec.
email <<
"', '"
333 <<
" WHERE NOT EXISTS (SELECT 1 FROM " << tableName(UserTable) <<
" WHERE "
334 <<
"username = '" << rec.
user <<
"' AND domain = '" << rec.
domain <<
"')";
336 return query(command, 0) == 0;
348 ds <<
"SELECT username, domain, realm, passwordHash, passwordHashAlt, name, email, forwardAddress FROM " << tableName(UserTable) <<
" ";
349 userWhereClauseToDataStream(key,
ds);
386 std::vector<Data>
ret;
393 UserStore::getUserAndDomainFromKey(key, user, domain);
394 ds <<
"SELECT passwordHash FROM " << tableName(UserTable) <<
" WHERE username = '" << user <<
"' AND domain = '" << domain <<
"' ";
398 if(!mCustomUserAuthQuery.empty() && !domain.
empty())
400 ds <<
" UNION " << mCustomUserAuthQuery;
402 command.
replace(
"$user", user);
403 command.
replace(
"$domain", domain);
407 if(singleResultQuery(command,
ret) != 0 ||
ret.size() == 0)
419PostgreSqlDb::firstUserKey()
422 if (mResult[UserTable])
425 mResult[UserTable] = 0;
432 ds <<
"SELECT username, domain FROM " << tableName(UserTable);
435 if(
query(command, &mResult[UserTable]) != 0)
440 if(mResult[UserTable] == 0)
446 return nextUserKey();
451PostgreSqlDb::nextUserKey()
453 if(mResult[UserTable] == 0)
462 mResult[UserTable] = 0;
469 return UserStore::buildKey(user, domain);
486 <<
"INSERT INTO " << tableName(TlsPeerIdentityTable) <<
" (peerName, authorizedIdentity)"
490 <<
" WHERE NOT EXISTS (SELECT 1 FROM " << tableName(TlsPeerIdentityTable) <<
" WHERE "
493 return query(command, 0) == 0;
505 ds <<
"SELECT peerName, authorizedIdentity FROM " << tableName(TlsPeerIdentityTable);
506 tlsPeerIdentityWhereClauseToDataStream(key,
ds);
535PostgreSqlDb::firstTlsPeerIdentityKey()
538 if (mResult[TlsPeerIdentityTable])
540 PQclear(mResult[TlsPeerIdentityTable]);
541 mResult[TlsPeerIdentityTable] = 0;
542 mRow[TlsPeerIdentityTable] = 0;
548 ds <<
"SELECT peerName, authorizedIdentity FROM " << tableName(TlsPeerIdentityTable);
551 if(
query(command, &mResult[TlsPeerIdentityTable]) != 0)
556 if(mResult[TlsPeerIdentityTable] == 0)
562 return nextTlsPeerIdentityKey();
567PostgreSqlDb::nextTlsPeerIdentityKey()
569 if(mResult[TlsPeerIdentityTable] == 0)
578 mResult[TlsPeerIdentityTable] = 0;
579 mRow[TlsPeerIdentityTable] = 0;
585 return TlsPeerIdentityStore::buildKey(peerName, authorizedIdentity);
590PostgreSqlDb::dbWriteRecord(
const Table
table,
605 ds <<
"DELETE FROM " << tableName(
table)
609 <<
" INSERT INTO " << tableName(
table)
610 <<
" (attr, attr2, value) VALUES ("
613 <<
"', '" <<
pData.base64encode()
619 ds <<
"DELETE FROM " << tableName(
table)
622 <<
" INSERT INTO " << tableName(
table)
623 <<
" (attr, value) VALUES ("
625 <<
"', '" <<
pData.base64encode()
629 return query(command, 0) == 0;
633PostgreSqlDb::dbReadRecord(
const Table
table,
641 ds <<
"SELECT value FROM " << tableName(
table)
659 bool success =
false;
667 StackLog(<<
"query result: " << success);
674PostgreSqlDb::dbNextKey(
const Table
table,
bool first)
689 ds <<
"SELECT attr FROM " << tableName(
table);
697 if (mResult[
table] == 0)
705 if (mResult[
table] == 0)
724PostgreSqlDb::dbNextRecord(
const Table
table,
743 ds <<
"SELECT value FROM " << tableName(
table);
749 ds <<
" WHERE attr2='" << escapeString(key,
escapedKey) <<
"'";
762 if (mResult[
table] == 0)
769 if (mResult[
table] == 0)
789PostgreSqlDb::dbBeginTransaction(
const Table
table)
791 Data command(
"SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ");
792 if(
query(command, 0))
795 return query(command, 0);
801PostgreSqlDb::userWhereClauseToDataStream(
const Key& key,
DataStream&
ds)
const
805 UserStore::getUserAndDomainFromKey(key, user, domain);
806 ds <<
" WHERE username='" << user
807 <<
"' AND domain='" << domain
812PostgreSqlDb::tlsPeerIdentityWhereClauseToDataStream(
const Key& key,
DataStream&
ds)
const
815 Data authorizedIdentity;
816 TlsPeerIdentityStore::getTlsPeerIdentityFromKey(key, peerName, authorizedIdentity);
817 ds <<
" WHERE peerName='" << peerName
818 <<
"' AND authorizedIdentity='" << authorizedIdentity
#define resip_assert(x)
This file needs to work for both C and C++ code.
resip::Data authorizedIdentity
resip::Data forwardAddress
resip::Data passwordHashAlt
An iostream that operates on an existing Data.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Data base64decode() const
Performs RFC 3548 Base 64 decoding of the contents of this data.
int replace(const Data &match, const Data &target, int max=INT_MAX)
Replaces up to max occurrences of the bytes match with target.
bool empty() const noexcept
Checks whether the Data is empty.
Data & truncate2(size_type len)
Shortens the size of this Data so length is at most of {len}.
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...