mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Add resend_count in db Model and refactor mutex use in model/table/ModelBase until no I hadn't expected concurrency in running db functions
This commit is contained in:
parent
582aba5bcd
commit
5f9ec065af
@ -24,6 +24,7 @@
|
||||
|
||||
\brief Container Wrapper class for mutex protected container
|
||||
changed to poco mutex for gradido login server
|
||||
default mutex from poco is recursive so it is some heavy thing
|
||||
|
||||
\author Dario Rekowski
|
||||
|
||||
@ -50,8 +51,8 @@ namespace UniLib {
|
||||
|
||||
inline const std::string& getLastSucceededLock() { return mLastSucceededLock; }
|
||||
protected:
|
||||
mutable Poco::Mutex mWorkMutex;
|
||||
private:
|
||||
Poco::Mutex mWorkMutex;
|
||||
std::string mLastSucceededLock;
|
||||
};
|
||||
}
|
||||
|
||||
@ -7,25 +7,25 @@ using namespace Poco::Data::Keywords;
|
||||
namespace model {
|
||||
namespace table {
|
||||
EmailOptIn::EmailOptIn(const Poco::UInt64& code, int user_id, EmailOptInType type/* = EMAIL_OPT_IN_REGISTER*/)
|
||||
: mUserId(user_id), mEmailVerificationCode(code), mType(type)
|
||||
: mUserId(user_id), mEmailVerificationCode(code), mType(type), mResendCount(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EmailOptIn::EmailOptIn(const Poco::UInt64& code, EmailOptInType type/* = EMAIL_OPT_IN_REGISTER*/)
|
||||
: mUserId(0), mEmailVerificationCode(code), mType(type)
|
||||
: mUserId(0), mEmailVerificationCode(code), mType(type), mResendCount(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EmailOptIn::EmailOptIn()
|
||||
: mUserId(0), mEmailVerificationCode(0)
|
||||
: mUserId(0), mEmailVerificationCode(0), mResendCount(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EmailOptIn::EmailOptIn(const EmailOptInTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mEmailVerificationCode(tuple.get<2>()), mType(tuple.get<3>())
|
||||
: ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mEmailVerificationCode(tuple.get<2>()), mType(tuple.get<3>()), mResendCount(tuple.get<4>())
|
||||
{
|
||||
|
||||
}
|
||||
@ -42,8 +42,8 @@ namespace model {
|
||||
|
||||
lock();
|
||||
insert << "INSERT INTO " << getTableName()
|
||||
<< " (user_id, verification_code, email_opt_in_type_id) VALUES(?,?,?)"
|
||||
, use(mUserId), use(mEmailVerificationCode), bind(mType);
|
||||
<< " (user_id, verification_code, email_opt_in_type_id, resend_count) VALUES(?,?,?,?)"
|
||||
, use(mUserId), use(mEmailVerificationCode), bind(mType), bind(mResendCount);
|
||||
unlock();
|
||||
return insert;
|
||||
}
|
||||
@ -53,9 +53,9 @@ namespace model {
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, user_id, verification_code, email_opt_in_type_id FROM " << getTableName()
|
||||
select << "SELECT id, user_id, verification_code, email_opt_in_type_id, resend_count FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?"
|
||||
, into(mID), into(mUserId), into(mEmailVerificationCode), into(mType);
|
||||
, into(mID), into(mUserId), into(mEmailVerificationCode), into(mType), into(mResendCount);
|
||||
|
||||
|
||||
return select;
|
||||
@ -76,7 +76,7 @@ namespace model {
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, user_id, verification_code, email_opt_in_type_id FROM " << getTableName()
|
||||
select << "SELECT id, user_id, verification_code, email_opt_in_type_id, resend_count FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?";
|
||||
|
||||
|
||||
@ -90,7 +90,7 @@ namespace model {
|
||||
throw Poco::NullValueException("EmailOptIn::_loadFromDB fieldNames empty or contain only one field");
|
||||
}
|
||||
|
||||
select << "SELECT user_id, verification_code, email_opt_in_type_id FROM " << getTableName()
|
||||
select << "SELECT user_id, verification_code, email_opt_in_type_id, resend_count FROM " << getTableName()
|
||||
<< " where " << fieldNames[0] << " = ? ";
|
||||
if (conditionType == MYSQL_CONDITION_AND) {
|
||||
for (int i = 1; i < fieldNames.size(); i++) {
|
||||
@ -106,12 +106,19 @@ namespace model {
|
||||
addError(new ParamError("EmailOptIn::_loadFromDB", "condition type not implemented", conditionType));
|
||||
}
|
||||
//<< " where " << fieldName << " = ?"
|
||||
select , into(mUserId), into(mEmailVerificationCode), into(mType);
|
||||
select , into(mUserId), into(mEmailVerificationCode), into(mType), into(mResendCount);
|
||||
|
||||
|
||||
return select;
|
||||
}
|
||||
|
||||
size_t EmailOptIn::addResendCountAndUpdate()
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
mResendCount++;
|
||||
return updateIntoDB("resend_count", mResendCount);
|
||||
}
|
||||
|
||||
std::string EmailOptIn::toString()
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
@ -17,7 +17,7 @@ namespace model {
|
||||
EMAIL_OPT_IN_REGISTER_DIRECT = 3
|
||||
};
|
||||
|
||||
typedef Poco::Tuple<int, int, Poco::UInt64, int> EmailOptInTuple;
|
||||
typedef Poco::Tuple<int, int, Poco::UInt64, int, int> EmailOptInTuple;
|
||||
|
||||
class EmailOptIn : public ModelBase
|
||||
{
|
||||
@ -34,10 +34,13 @@ namespace model {
|
||||
|
||||
inline Poco::UInt64 getCode() const { return mEmailVerificationCode; }
|
||||
inline int getUserId() const { return mUserId; }
|
||||
inline int getResendCount() const { Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex); return mResendCount; }
|
||||
inline EmailOptInType getType() const { return static_cast<EmailOptInType>(mType);}
|
||||
inline void setCode(Poco::UInt64 code) { mEmailVerificationCode = code; }
|
||||
inline void setUserId(int user_Id) { mUserId = user_Id; }
|
||||
|
||||
size_t addResendCountAndUpdate();
|
||||
|
||||
static const char* typeToString(EmailOptInType type);
|
||||
protected:
|
||||
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
|
||||
@ -50,6 +53,7 @@ namespace model {
|
||||
// data type must be a multiple of 4
|
||||
Poco::UInt64 mEmailVerificationCode;
|
||||
int mType;
|
||||
int mResendCount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -42,6 +42,7 @@ namespace model {
|
||||
{
|
||||
//printf("ModelBase::insertIntoDB with table: %s\n", getTableName());
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
Poco::Data::Statement insert = _insertIntoDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER));
|
||||
|
||||
size_t resultCount = 0;
|
||||
@ -54,10 +55,8 @@ namespace model {
|
||||
return select.execute() == 1;
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
lock("ModelBase::insertIntoDB");
|
||||
addError(new ParamError(getTableName(), "mysql error by select id", ex.displayText().data()));
|
||||
addError(new ParamError(getTableName(), "data set: ", toString().data()));
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -66,10 +65,8 @@ namespace model {
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
lock("ModelBase::insertIntoDB2");
|
||||
addError(new ParamError(getTableName(), "mysql error by insert", ex.displayText().data()));
|
||||
addError(new ParamError(getTableName(), "data set: ", toString().data()));
|
||||
unlock();
|
||||
}
|
||||
//printf("data valid: %s\n", toString().data());
|
||||
return false;
|
||||
@ -77,10 +74,9 @@ namespace model {
|
||||
|
||||
bool ModelBase::deleteFromDB()
|
||||
{
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
if (mID == 0) {
|
||||
lock();
|
||||
addError(new Error(getTableName(), "id is zero, couldn't delete from db"));
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
@ -102,23 +98,21 @@ namespace model {
|
||||
|
||||
void ModelBase::duplicate()
|
||||
{
|
||||
lock();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
mReferenceCount++;
|
||||
//printf("[ModelBase::duplicate] new value: %d\n", mReferenceCount);
|
||||
unlock();
|
||||
}
|
||||
|
||||
void ModelBase::release()
|
||||
{
|
||||
lock();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
mReferenceCount--;
|
||||
//printf("[ModelBase::release] new value: %d\n", mReferenceCount);
|
||||
if (0 == mReferenceCount) {
|
||||
unlock();
|
||||
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
unlock();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
#include <shared_mutex>
|
||||
//using namespace Poco::Data::Keywords;
|
||||
|
||||
namespace model {
|
||||
@ -76,6 +77,7 @@ namespace model {
|
||||
size_t ModelBase::loadFromDB(const std::string& fieldName, const T& fieldValue)
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
Poco::Data::Statement select = _loadFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER), fieldName);
|
||||
select, Poco::Data::Keywords::useRef(fieldValue);
|
||||
|
||||
@ -84,10 +86,8 @@ namespace model {
|
||||
resultCount = select.execute();
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
lock();
|
||||
addError(new ParamError(getTableName(), "mysql error by selecting", ex.displayText().data()));
|
||||
addError(new ParamError(getTableName(), "field name for select: ", fieldName.data()));
|
||||
unlock();
|
||||
}
|
||||
return resultCount;
|
||||
}
|
||||
@ -96,6 +96,7 @@ namespace model {
|
||||
bool ModelBase::isExistInDB(const std::string& fieldName, const T& fieldValue)
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement select(session);
|
||||
int id;
|
||||
@ -122,6 +123,7 @@ namespace model {
|
||||
{
|
||||
//printf("ModelBase::loadFromDB multi\n");
|
||||
std::vector<Tuple> results;
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
//return results;
|
||||
if (expectedResults > 0) {
|
||||
results.reserve(expectedResults);
|
||||
@ -147,7 +149,7 @@ namespace model {
|
||||
std::vector<Tuple> ModelBase::loadFromDB(const std::vector<std::string>& fieldNames, const std::vector<WhereFieldType>& fieldValues, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/, int expectedResults/* = 0*/)
|
||||
{
|
||||
std::vector<Tuple> results;
|
||||
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
if (fieldNames.size() != fieldValues.size() || fieldNames.size() <= 1) {
|
||||
lock();
|
||||
addError(new Error(getTableName(), "fieldNames and fieldValues size don't match or smaller as 1"));
|
||||
@ -183,6 +185,7 @@ namespace model {
|
||||
size_t ModelBase::loadFromDB(const std::vector<std::string>& fieldNames, const T1& field1Value, const T2& field2Value, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/)
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
Poco::Data::Statement select = _loadFromDB(cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER), fieldNames, conditionType);
|
||||
select, Poco::Data::Keywords::useRef(field1Value), Poco::Data::Keywords::useRef(field2Value);
|
||||
|
||||
@ -207,6 +210,7 @@ namespace model {
|
||||
size_t ModelBase::updateIntoDB(const std::string& fieldName, const T& fieldValue)
|
||||
{
|
||||
auto cm = ConnectionManager::getInstance();
|
||||
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
|
||||
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||
Poco::Data::Statement update(session);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user