13#include <mysql/errmsg.h>
32#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO
80 mDBPassword(password),
86 InfoLog( <<
"Using MySQL DB with server=" << server <<
", user=" << user <<
", dbName=" <<
databaseName <<
", port=" << port);
88 for (
int i=0;
i<MaxTable;
i++)
96 ErrLog( <<
"Repro uses MySQL from multiple threads - you MUST link with a thread safe version of the mySQL client library!");
107 disconnectFromDatabase();
111MySqlDb::initialize()
const
121MySqlDb::disconnectFromDatabase()
const
125 for (
int i=0;
i<MaxTable;
i++)
141MySqlDb::connectToDatabase()
const
144 disconnectFromDatabase();
153 ErrLog( <<
"MySQL init failed: insufficient memory.");
192 if(mConn == 0 || !isConnected())
194 rc = connectToDatabase();
208 rc = connectToDatabase();
270 for(
unsigned int i = 0;
i <
result->field_count;
i++)
284 DebugLog(<<
"singleResultQuery: no rows returned by query");
305 ds <<
"INSERT INTO " << tableName(UserTable) <<
" (user, domain, realm, passwordHash, passwordHashAlt, name, email, forwardAddress)"
307 << rec.
user <<
"', '"
309 << rec.
realm <<
"', '"
312 << rec.
name <<
"', '"
313 << rec.
email <<
"', '"
315 <<
" ON DUPLICATE KEY UPDATE"
316 <<
" user='" << rec.
user
317 <<
"', domain='" << rec.
domain
318 <<
"', realm='" << rec.
realm
321 <<
"', name='" << rec.
name
322 <<
"', email='" << rec.
email
326 return query(command, 0) == 0;
338 ds <<
"SELECT user, domain, realm, passwordHash, passwordHashAlt, name, email, forwardAddress FROM " << tableName(UserTable) <<
" ";
339 userWhereClauseToDataStream(key,
ds);
377 std::vector<Data>
ret;
384 UserStore::getUserAndDomainFromKey(key, user, domain);
385 ds <<
"SELECT passwordHash FROM " << tableName(UserTable) <<
" WHERE user = '" << user <<
"' AND domain = '" << domain <<
"' ";
389 if(!mCustomUserAuthQuery.empty() && !domain.
empty())
391 ds <<
" UNION " << mCustomUserAuthQuery;
393 command.
replace(
"$user", user);
394 command.
replace(
"$domain", domain);
398 if(singleResultQuery(command,
ret) != 0 ||
ret.size() == 0)
410MySqlDb::firstUserKey()
413 if (mResult[UserTable])
416 mResult[UserTable] = 0;
422 ds <<
"SELECT user, domain FROM " << tableName(UserTable);
425 if(
query(command, &mResult[UserTable]) != 0)
430 if(mResult[UserTable] == 0)
436 return nextUserKey();
441MySqlDb::nextUserKey()
443 if(mResult[UserTable] == 0)
452 mResult[UserTable] = 0;
458 return UserStore::buildKey(user, domain);
468 ds <<
"INSERT INTO " << tableName(TlsPeerIdentityTable) <<
" (peerName, tlsPeerIdentity)"
472 <<
" ON DUPLICATE KEY UPDATE"
477 return query(command, 0) == 0;
489 ds <<
"SELECT peerName, authorizedIdentity FROM " << tableName(TlsPeerIdentityTable) <<
" ";
490 tlsPeerIdentityWhereClauseToDataStream(key,
ds);
520MySqlDb::firstTlsPeerIdentityKey()
523 if (mResult[TlsPeerIdentityTable])
526 mResult[TlsPeerIdentityTable] = 0;
532 ds <<
"SELECT peerName, authorizedIdentity FROM " << tableName(TlsPeerIdentityTable);
535 if(
query(command, &mResult[TlsPeerIdentityTable]) != 0)
540 if(mResult[TlsPeerIdentityTable] == 0)
546 return nextTlsPeerIdentityKey();
551MySqlDb::nextTlsPeerIdentityKey()
553 if(mResult[TlsPeerIdentityTable] == 0)
562 mResult[TlsPeerIdentityTable] = 0;
566 Data authorizedIdentity(
row[1]);
568 return TlsPeerIdentityStore::buildKey(peerName, authorizedIdentity);
573MySqlDb::dbWriteRecord(
const Table
table,
588 ds <<
"REPLACE INTO " << tableName(
table)
591 <<
"', value='" <<
pData.base64encode()
597 ds <<
"REPLACE INTO " << tableName(
table)
599 <<
"', value='" <<
pData.base64encode()
603 return query(command, 0) == 0;
607MySqlDb::dbReadRecord(
const Table
table,
615 ds <<
"SELECT value FROM " << tableName(
table)
633 bool success =
false;
647MySqlDb::dbNextKey(
const Table
table,
bool first)
661 ds <<
"SELECT attr FROM " << tableName(
table);
669 if (mResult[
table] == 0)
677 if (mResult[
table] == 0)
696MySqlDb::dbNextRecord(
const Table
table,
714 ds <<
"SELECT value FROM " << tableName(
table);
720 ds <<
" WHERE attr2='" << escapeString(key,
escapedKey) <<
"'";
733 if (mResult[
table] == 0)
740 if (mResult[
table] == 0)
759MySqlDb::dbBeginTransaction(
const Table
table)
761 Data command(
"SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
762 if(
query(command, 0) == 0)
764 command =
"START TRANSACTION";
765 return query(command, 0) == 0;
771MySqlDb::userWhereClauseToDataStream(
const Key& key,
DataStream&
ds)
const
775 UserStore::getUserAndDomainFromKey(key, user, domain);
776 ds <<
" WHERE user='" << user
777 <<
"' AND domain='" << domain
782MySqlDb::tlsPeerIdentityWhereClauseToDataStream(
const Key& key,
DataStream&
ds)
const
785 Data authorizedIdentity;
786 TlsPeerIdentityStore::getTlsPeerIdentityFromKey(key, peerName, authorizedIdentity);
787 ds <<
" WHERE peerName='" << peerName
788 <<
"' 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...