Rework DB session + transactions. Now can handle multiple read only transactions in parallel

This commit is contained in:
emeric
2019-07-16 13:17:23 +02:00
parent 2a1fb0182b
commit 38ce2600d2
79 changed files with 1840 additions and 1369 deletions
+8 -8
View File
@@ -85,10 +85,10 @@ class DatabaseSettingsModel : public Wt::WFormModel
void loadData()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto scanSettings {ScanSettings::get(LmsApp->getDboSession())};
auto similaritySettings {SimilaritySettings::get(LmsApp->getDboSession())};
const ScanSettings::pointer scanSettings {ScanSettings::get(LmsApp->getDbSession())};
const SimilaritySettings::pointer similaritySettings {SimilaritySettings::get(LmsApp->getDbSession())};
setValue(MediaDirectoryField, scanSettings->getMediaDirectory().string());
@@ -108,17 +108,17 @@ class DatabaseSettingsModel : public Wt::WFormModel
if (!clusterTypes.empty())
{
std::vector<std::string> names;
std::transform(clusterTypes.begin(), clusterTypes.end(),std::back_inserter(names), [](auto clusterType) { return clusterType->getName(); });
std::transform(clusterTypes.begin(), clusterTypes.end(), std::back_inserter(names), [](auto clusterType) { return clusterType->getName(); });
setValue(TagsField, joinStrings(names, " "));
}
}
void saveData()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
auto scanSettings {ScanSettings::get(LmsApp->getDboSession())};
auto similaritySettings {SimilaritySettings::get(LmsApp->getDboSession())};
ScanSettings::pointer scanSettings {ScanSettings::get(LmsApp->getDbSession())};
SimilaritySettings::pointer similaritySettings {SimilaritySettings::get(LmsApp->getDbSession())};
scanSettings.modify()->setMediaDirectory(valueText(MediaDirectoryField).toUTF8());
@@ -135,7 +135,7 @@ class DatabaseSettingsModel : public Wt::WFormModel
similaritySettings.modify()->setEngineType(_similarityEngineTypeModel->getValue(*similarityEngineTypeRow));
auto clusterTypes {splitString(valueText(TagsField).toUTF8(), " ")};
scanSettings.modify()->setClusterTypes(std::set<std::string>(clusterTypes.begin(), clusterTypes.end()));
scanSettings.modify()->setClusterTypes(LmsApp->getDbSession(), std::set<std::string>(clusterTypes.begin(), clusterTypes.end()));
}
private:
+4 -11
View File
@@ -54,21 +54,14 @@ class InitWizardModel : public Wt::WFormModel
void saveData()
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction(LmsApp->getDbSession().createUniqueTransaction());
// Check if a user already exist
// If it's the case, just do nothing
if (!Database::User::getAll(LmsApp->getDboSession()).empty())
if (!Database::User::getAll(LmsApp->getDbSession()).empty())
throw LmsException("Admin user already created");
// Create user
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().registerNew();
Database::User::pointer user = LmsApp->getDb().createUser(authUser);
// Account
authUser.setIdentity(Wt::Auth::Identity::LoginName, valueText(AdminLoginField));
Database::Handler::getPasswordService().updatePassword(authUser, valueText(PasswordField));
Database::User::pointer user {LmsApp->getDbSession().createUser(valueText(AdminLoginField).toUTF8(), valueText(PasswordField).toUTF8())};
user.modify()->setType(Database::User::Type::ADMIN);
}
@@ -81,7 +74,7 @@ class InitWizardModel : public Wt::WFormModel
if (!valueText(PasswordField).empty())
{
// Evaluate the strength of the password
auto res = Database::Handler::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField),
auto res = Database::Session::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField),
valueText(AdminLoginField), "");
if (!res.isValid())
+26 -32
View File
@@ -78,17 +78,16 @@ class UserModel : public Wt::WFormModel
void saveData()
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
if (_userId)
{
// Update user
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().findWithId( std::to_string(*_userId) );
Database::User::pointer user = LmsApp->getDb().getUser( authUser );
Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *_userId)};
// Account
if (!valueText(PasswordField).empty())
Database::Handler::getPasswordService().updatePassword(authUser, valueText(PasswordField));
LmsApp->getDbSession().updateUserPassword(user, valueText(PasswordField).toUTF8());
auto transcodeBitrateLimitRow {_bitrateModel->getRowFromString(valueText(AudioTranscodeBitrateLimitField))};
if (transcodeBitrateLimitRow)
@@ -97,12 +96,7 @@ class UserModel : public Wt::WFormModel
else
{
// Create user
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().registerNew();
Database::User::pointer user = LmsApp->getDb().createUser(authUser);
// Account
authUser.setIdentity(Wt::Auth::Identity::LoginName, valueText(LoginField));
Database::Handler::getPasswordService().updatePassword(authUser, valueText(PasswordField));
Database::User::pointer user = LmsApp->getDbSession().createUser(valueText(LoginField).toUTF8(), valueText(PasswordField).toUTF8());
auto transcodeBitrateLimitRow {_bitrateModel->getRowFromString(valueText(AudioTranscodeBitrateLimitField))};
if (transcodeBitrateLimitRow )
@@ -120,11 +114,9 @@ class UserModel : public Wt::WFormModel
if (!_userId)
return;
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto authUser {LmsApp->getDb().getUserDatabase().findWithId( std::to_string(*_userId) )};
auto user {LmsApp->getDb().getUser(authUser)};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *_userId)};
if (user == LmsApp->getUser())
throw LmsException("Cannot edit ourselves");
@@ -133,12 +125,14 @@ class UserModel : public Wt::WFormModel
setValue(AudioTranscodeBitrateLimitField, _bitrateModel->getString(*transcodeBitrateLimitRow));
}
Wt::WString getLogin() const
Wt::WString getLoginName() const
{
if (_userId)
{
auto authUser = LmsApp->getDb().getUserDatabase().findWithId( std::to_string(*_userId) );
return authUser.identity(Wt::Auth::Identity::LoginName);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *_userId)};
return LmsApp->getDbSession().getUserLoginName(user);
}
else
return valueText(LoginField);
@@ -150,8 +144,8 @@ class UserModel : public Wt::WFormModel
if (field == LoginField)
{
auto user = LmsApp->getDb().getUserDatabase().findWithIdentity(Wt::Auth::Identity::LoginName, valueText(LoginField));
if (user.isValid())
const Database::User::pointer user {LmsApp->getDbSession().getUser(valueText(LoginField).toUTF8())};
if (user)
error = Wt::WString::tr("Lms.Admin.User.user-already-exists");
}
else if (field == PasswordField)
@@ -161,13 +155,13 @@ class UserModel : public Wt::WFormModel
if (Wt::asNumber(value(DemoField)))
{
//Demo account: password must be the same as the login name
if (valueText(PasswordField) != getLogin())
if (valueText(PasswordField) != getLoginName())
error = Wt::WString::tr("Lms.Admin.User.demo-password-invalid");
}
else
{
// Evaluate the strength of the password for non demo accounts
auto res = Database::Handler::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField), getLogin(), "");
auto res = Database::Session::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField), getLoginName(), "");
if (!res.isValid())
error = res.message();
@@ -176,9 +170,9 @@ class UserModel : public Wt::WFormModel
}
else if (field == DemoField)
{
Wt::Dbo::Transaction transaction {LmsApp->getDboSession()};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
if (Wt::asNumber(value(DemoField)) && Database::User::getDemo(LmsApp->getDboSession()))
if (Wt::asNumber(value(DemoField)) && Database::User::getDemo(LmsApp->getDbSession()))
error = Wt::WString::tr("Lms.Admin.User.demo-account-already-exists");
}
@@ -226,23 +220,23 @@ UserView::refreshView()
auto userId = readAs<Database::IdType>(wApp->internalPathNextPart("/admin/user/"));
LMS_LOG(UI, DEBUG) << "userId = " << (userId ? std::to_string(*userId) : "none");
clear();
Wt::WTemplateFormView* t = addNew<Wt::WTemplateFormView>(Wt::WString::tr("Lms.Admin.User.template"));
Wt::WTemplateFormView* t {addNew<Wt::WTemplateFormView>(Wt::WString::tr("Lms.Admin.User.template"))};
auto model = std::make_shared<UserModel>(userId);
auto model {std::make_shared<UserModel>(userId)};
if (userId)
{
auto authUser = LmsApp->getDb().getUserDatabase().findWithId( std::to_string(*userId) );
auto name = authUser.identity(Wt::Auth::Identity::LoginName);
t->bindString("title", Wt::WString::tr("Lms.Admin.User.user-edit").arg(name), Wt::TextFormat::Plain);
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *userId)};
const std::string loginName {LmsApp->getDbSession().getUserLoginName(user)};
t->bindString("title", Wt::WString::tr("Lms.Admin.User.user-edit").arg(loginName), Wt::TextFormat::Plain);
t->setCondition("if-has-last-login-attempt", true);
Wt::WLineEdit *lastLoginAttempt = t->bindNew<Wt::WLineEdit>("last-login-attempt");
lastLoginAttempt->setText(authUser.lastLoginAttempt().toString());
Wt::WLineEdit *lastLoginAttempt {t->bindNew<Wt::WLineEdit>("last-login-attempt")};
lastLoginAttempt->setText(LmsApp->getDbSession().getUserLastLoginAttempt(user).toString());
lastLoginAttempt->setEnabled(false);
}
else
+13 -17
View File
@@ -59,22 +59,16 @@ UsersView::refreshView()
_container->clear();
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
auto users = Database::User::getAll(LmsApp->getDboSession());
for (auto user : users)
auto users = Database::User::getAll(LmsApp->getDbSession());
for (const auto& user : users)
{
auto userId = std::to_string(user.id());
Wt::WTemplate* entry = _container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Admin.Users.template.entry"));
const Database::IdType userId {user.id()};
Wt::Auth::User authUser = LmsApp->getDb().getUserDatabase().findWithId(userId);
if (!authUser.isValid()) {
LMS_LOG(UI, ERROR) << "Skipping invalid userId = " << user.id();
continue;
}
Wt::WTemplate* entry {_container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Admin.Users.template.entry"))};
auto login = authUser.identity(Wt::Auth::Identity::LoginName);
entry->bindString("name", login, Wt::TextFormat::Plain);
entry->bindString("name", LmsApp->getDbSession().getUserLoginName(user), Wt::TextFormat::Plain);
// Create tag
if (user->isAdmin() || user->isDemo())
@@ -106,16 +100,18 @@ UsersView::refreshView()
{
if (btn == Wt::StandardButton::Yes)
{
Wt::Dbo::Transaction transaction(LmsApp->getDboSession());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), userId)};
if (user)
LmsApp->getDbSession().removeUser(user);
auto authUser = LmsApp->getDb().getUserDatabase().findWithId(userId);
auto user = LmsApp->getDb().getUser(authUser);
LmsApp->getDb().getUserDatabase().deleteUser( authUser );
user.remove();
_container->removeWidget(entry);
}
else
{
delBtn->removeChild(msgBox);
}
});
msgBox->show();