Reworked the database session creation
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/Track.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
#include "database/User.hpp"
|
||||
@@ -128,7 +129,7 @@ struct RequestContext
|
||||
std::string userName;
|
||||
};
|
||||
|
||||
using SessionMap = std::map<Db*, std::unique_ptr<Session>>;
|
||||
using SessionMap = std::map<Db*, Session>;
|
||||
static std::map<std::thread::id, SessionMap> dbSessions;
|
||||
|
||||
static
|
||||
@@ -146,14 +147,14 @@ getOrCreateDbSession(Db& db)
|
||||
|
||||
auto it {sessionMap->find(&db)};
|
||||
if (it != std::end(*sessionMap))
|
||||
return *it->second;
|
||||
return it->second;
|
||||
|
||||
auto res { sessionMap->try_emplace(&db, db.createSession())};
|
||||
auto res { sessionMap->try_emplace(&db, db)};
|
||||
assert(res.second);
|
||||
|
||||
LMS_LOG(API_SUBSONIC, DEBUG) << "Created db session";
|
||||
|
||||
return *res.first->second;
|
||||
return res.first->second;
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
@@ -40,18 +40,6 @@ Db::Db(const std::filesystem::path& dbPath)
|
||||
connectionPool->setTimeout(std::chrono::seconds(10));
|
||||
|
||||
_connectionPool = std::move(connectionPool);
|
||||
|
||||
{
|
||||
auto session {createSession()};
|
||||
session->prepareTables();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<Session>
|
||||
Db::createSession()
|
||||
{
|
||||
return std::unique_ptr<Session>(new Session {_sharedMutex, *_connectionPool.get()});
|
||||
}
|
||||
|
||||
} // namespace Database
|
||||
|
||||
+5
-4
@@ -24,8 +24,6 @@
|
||||
|
||||
#include <Wt/Dbo/SqlConnectionPool.h>
|
||||
|
||||
#include "Session.hpp"
|
||||
|
||||
namespace Database {
|
||||
|
||||
// Session living class handling the database and the login
|
||||
@@ -35,9 +33,12 @@ class Db
|
||||
|
||||
Db(const std::filesystem::path& dbPath);
|
||||
|
||||
std::unique_ptr<Session> createSession();
|
||||
|
||||
private:
|
||||
friend class Session;
|
||||
|
||||
std::shared_mutex& getMutex() { return _sharedMutex; }
|
||||
Wt::Dbo::SqlConnectionPool& getConnectionPool() { return *_connectionPool; }
|
||||
|
||||
std::shared_mutex _sharedMutex;
|
||||
std::unique_ptr<Wt::Dbo::SqlConnectionPool> _connectionPool;
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "Artist.hpp"
|
||||
#include "Cluster.hpp"
|
||||
#include "Db.hpp"
|
||||
#include "Release.hpp"
|
||||
#include "ScanSettings.hpp"
|
||||
#include "SimilaritySettings.hpp"
|
||||
@@ -116,10 +117,10 @@ Session::doDatabaseMigrationIfNeeded()
|
||||
VersionInfo::get(*this).modify()->setVersion(LMS_DATABASE_VERSION);
|
||||
}
|
||||
|
||||
Session::Session(std::shared_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool)
|
||||
: _mutex {mutex}
|
||||
Session::Session(Db& db)
|
||||
: _db {db}
|
||||
{
|
||||
_session.setConnectionPool(connectionPool);
|
||||
_session.setConnectionPool(_db.getConnectionPool());
|
||||
|
||||
_session.mapClass<VersionInfo>("version_info");
|
||||
_session.mapClass<Artist>("artist");
|
||||
@@ -179,25 +180,25 @@ SharedTransaction::~SharedTransaction()
|
||||
void
|
||||
Session::checkUniqueLocked()
|
||||
{
|
||||
assert(lockDebug[&_mutex] == OwnedLock::Unique);
|
||||
assert(lockDebug[&_db.getMutex()] == OwnedLock::Unique);
|
||||
}
|
||||
|
||||
void
|
||||
Session::checkSharedLocked()
|
||||
{
|
||||
assert(lockDebug[&_mutex] != OwnedLock::None);
|
||||
assert(lockDebug[&_db.getMutex()] != OwnedLock::None);
|
||||
}
|
||||
|
||||
UniqueTransaction
|
||||
Session::createUniqueTransaction()
|
||||
{
|
||||
return UniqueTransaction{_mutex, _session};
|
||||
return UniqueTransaction{_db.getMutex(), _session};
|
||||
}
|
||||
|
||||
SharedTransaction
|
||||
Session::createSharedTransaction()
|
||||
{
|
||||
return SharedTransaction{_mutex, _session};
|
||||
return SharedTransaction{_db.getMutex(), _session};
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -54,9 +54,12 @@ class SharedTransaction
|
||||
Wt::Dbo::Transaction _transaction;
|
||||
};
|
||||
|
||||
class Db;
|
||||
class Session
|
||||
{
|
||||
public:
|
||||
Session (Db& database);
|
||||
|
||||
Session(const Session&) = delete;
|
||||
Session(Session&&) = delete;
|
||||
Session& operator=(const Session&) = delete;
|
||||
@@ -70,17 +73,16 @@ class Session
|
||||
|
||||
void optimize();
|
||||
|
||||
void prepareTables(); // need to run only once at startup
|
||||
|
||||
Wt::Dbo::Session& getDboSession() { return _session; }
|
||||
|
||||
private:
|
||||
friend class Db;
|
||||
|
||||
Session(std::shared_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool);
|
||||
|
||||
void doDatabaseMigrationIfNeeded();
|
||||
void prepareTables(); // need to run only once at startup
|
||||
|
||||
std::shared_mutex& _mutex;
|
||||
Db& _db;
|
||||
Wt::Dbo::Session _session;
|
||||
};
|
||||
|
||||
|
||||
+6
-2
@@ -134,15 +134,19 @@ int main(int argc, char* argv[])
|
||||
|
||||
// Initializing a connection pool to the database that will be shared along services
|
||||
Database::Db database {ServiceProvider<Config>::get()->getPath("working-dir") / "lms.db"};
|
||||
{
|
||||
Database::Session session {database};
|
||||
session.prepareTables();
|
||||
}
|
||||
|
||||
UserInterface::LmsApplicationGroupContainer appGroups;
|
||||
|
||||
// Service initialization order is important
|
||||
ServiceProvider<Auth::AuthTokenService>::create(ServiceProvider<Config>::get()->getULong("login-throttler-max-entriees", 10000));
|
||||
ServiceProvider<Auth::PasswordService>::create(ServiceProvider<Config>::get()->getULong("login-throttler-max-entriees", 10000));
|
||||
Scanner::MediaScanner& mediaScanner {ServiceProvider<Scanner::MediaScanner>::create(database.createSession())};
|
||||
Scanner::MediaScanner& mediaScanner {ServiceProvider<Scanner::MediaScanner>::create(database)};
|
||||
|
||||
Similarity::FeaturesScannerAddon similarityFeaturesScannerAddon {database.createSession()};
|
||||
Similarity::FeaturesScannerAddon similarityFeaturesScannerAddon {database};
|
||||
|
||||
mediaScanner.setAddon(similarityFeaturesScannerAddon);
|
||||
|
||||
|
||||
@@ -191,8 +191,8 @@ getOrCreateClusters(Session& session, const MetaData::Clusters& clustersNames)
|
||||
|
||||
namespace Scanner {
|
||||
|
||||
MediaScanner::MediaScanner(std::unique_ptr<Database::Session> dbSession)
|
||||
: _dbSession {std::move(dbSession)}
|
||||
MediaScanner::MediaScanner(Database::Db& db)
|
||||
: _dbSession {db}
|
||||
{
|
||||
_ioService.setThreadCount(1);
|
||||
|
||||
@@ -444,7 +444,7 @@ MediaScanner::scan(boost::system::error_code err)
|
||||
}
|
||||
|
||||
LMS_LOG(DBUPDATER, INFO) << "Optimizing db...";
|
||||
_dbSession->optimize();
|
||||
_dbSession.optimize();
|
||||
LMS_LOG(DBUPDATER, INFO) << "Optimize db done!";
|
||||
}
|
||||
|
||||
@@ -452,9 +452,9 @@ void
|
||||
MediaScanner::refreshScanSettings()
|
||||
{
|
||||
{
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
|
||||
ScanSettings::pointer scanSettings {ScanSettings::get(*_dbSession)};
|
||||
ScanSettings::pointer scanSettings {ScanSettings::get(_dbSession)};
|
||||
|
||||
LMS_LOG(DBUPDATER, INFO) << "Using scan settings version " << scanSettings->getScanVersion();
|
||||
|
||||
@@ -521,9 +521,9 @@ MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, S
|
||||
if (!forceScan)
|
||||
{
|
||||
// Skip file if last write is the same
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
|
||||
const Track::pointer track {Track::getByPath(*_dbSession, file)};
|
||||
const Track::pointer track {Track::getByPath(_dbSession, file)};
|
||||
|
||||
if (track && track->getLastWriteTime().toTime_t() == lastWriteTime.toTime_t()
|
||||
&& track->getScanVersion() == _scanVersion)
|
||||
@@ -542,9 +542,9 @@ MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, S
|
||||
|
||||
stats.scans++;
|
||||
|
||||
auto uniqueTransaction {_dbSession->createUniqueTransaction()};
|
||||
auto uniqueTransaction {_dbSession.createUniqueTransaction()};
|
||||
|
||||
Track::pointer track {Track::getByPath(*_dbSession, file) };
|
||||
Track::pointer track {Track::getByPath(_dbSession, file) };
|
||||
|
||||
// We estimate this is an audio file if:
|
||||
// - we found a least one audio stream
|
||||
@@ -588,25 +588,25 @@ MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, S
|
||||
}
|
||||
|
||||
// ***** Clusters
|
||||
std::vector<Cluster::pointer> clusters {getOrCreateClusters(*_dbSession, trackInfo->clusters)};
|
||||
std::vector<Cluster::pointer> clusters {getOrCreateClusters(_dbSession, trackInfo->clusters)};
|
||||
|
||||
// ***** Artists
|
||||
std::vector<Artist::pointer> artists {getOrCreateArtists(*_dbSession, trackInfo->artists)};
|
||||
std::vector<Artist::pointer> artists {getOrCreateArtists(_dbSession, trackInfo->artists)};
|
||||
|
||||
// ***** Release artists
|
||||
std::vector<Artist::pointer> releaseArtists {getOrCreateArtists(*_dbSession, trackInfo->albumArtists)};
|
||||
std::vector<Artist::pointer> releaseArtists {getOrCreateArtists(_dbSession, trackInfo->albumArtists)};
|
||||
|
||||
// ***** Release
|
||||
Release::pointer release;
|
||||
if (trackInfo->album)
|
||||
release = getOrCreateRelease(*_dbSession, *trackInfo->album);
|
||||
release = getOrCreateRelease(_dbSession, *trackInfo->album);
|
||||
|
||||
// If file already exist, update data
|
||||
// Otherwise, create it
|
||||
if (!track)
|
||||
{
|
||||
// Create a new song
|
||||
track = Track::create(*_dbSession, file);
|
||||
track = Track::create(_dbSession, file);
|
||||
LMS_LOG(DBUPDATER, INFO) << "Adding '" << file.string() << "'";
|
||||
stats.additions++;
|
||||
}
|
||||
@@ -629,10 +629,10 @@ MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, S
|
||||
|
||||
track.modify()->clearArtistLinks();
|
||||
for (const auto& artist : artists)
|
||||
track.modify()->addArtistLink(Database::TrackArtistLink::create(*_dbSession, track, artist, Database::TrackArtistLink::Type::Artist));
|
||||
track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, artist, Database::TrackArtistLink::Type::Artist));
|
||||
|
||||
for (const auto& releaseArtist : releaseArtists)
|
||||
track.modify()->addArtistLink(Database::TrackArtistLink::create(*_dbSession, track, releaseArtist, Database::TrackArtistLink::Type::ReleaseArtist));
|
||||
track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, releaseArtist, Database::TrackArtistLink::Type::ReleaseArtist));
|
||||
|
||||
track.modify()->setScanVersion(_scanVersion);
|
||||
track.modify()->setRelease(release);
|
||||
@@ -733,8 +733,8 @@ MediaScanner::removeMissingTracks(ScanStats& stats)
|
||||
{
|
||||
std::vector<std::filesystem::path> trackPaths;
|
||||
{
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
trackPaths = Track::getAllPaths(*_dbSession);;
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
trackPaths = Track::getAllPaths(_dbSession);;
|
||||
}
|
||||
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Checking tracks...";
|
||||
@@ -745,9 +745,9 @@ MediaScanner::removeMissingTracks(ScanStats& stats)
|
||||
|
||||
if (!checkFile(trackPath, _mediaDirectory, _fileExtensions))
|
||||
{
|
||||
auto transaction {_dbSession->createUniqueTransaction()};
|
||||
auto transaction {_dbSession.createUniqueTransaction()};
|
||||
|
||||
Track::pointer track {Track::getByPath(*_dbSession, trackPath)};
|
||||
Track::pointer track {Track::getByPath(_dbSession, trackPath)};
|
||||
if (track)
|
||||
{
|
||||
track.remove();
|
||||
@@ -762,10 +762,10 @@ MediaScanner::removeOrphanEntries()
|
||||
{
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Checking orphan clusters...";
|
||||
{
|
||||
auto transaction {_dbSession->createUniqueTransaction()};
|
||||
auto transaction {_dbSession.createUniqueTransaction()};
|
||||
|
||||
// Now process orphan Cluster (no track)
|
||||
auto clusters {Cluster::getAllOrphans(*_dbSession)};
|
||||
auto clusters {Cluster::getAllOrphans(_dbSession)};
|
||||
for (auto& cluster : clusters)
|
||||
{
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Removing orphan cluster '" << cluster->getName() << "'";
|
||||
@@ -775,9 +775,9 @@ MediaScanner::removeOrphanEntries()
|
||||
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Checking orphan artists...";
|
||||
{
|
||||
auto transaction {_dbSession->createUniqueTransaction()};
|
||||
auto transaction {_dbSession.createUniqueTransaction()};
|
||||
|
||||
auto artists {Artist::getAllOrphans(*_dbSession)};
|
||||
auto artists {Artist::getAllOrphans(_dbSession)};
|
||||
for (auto& artist : artists)
|
||||
{
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Removing orphan artist '" << artist->getName() << "'";
|
||||
@@ -787,9 +787,9 @@ MediaScanner::removeOrphanEntries()
|
||||
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Checking orphan releases...";
|
||||
{
|
||||
auto transaction {_dbSession->createUniqueTransaction()};
|
||||
auto transaction {_dbSession.createUniqueTransaction()};
|
||||
|
||||
auto releases {Release::getAllOrphans(*_dbSession)};
|
||||
auto releases {Release::getAllOrphans(_dbSession)};
|
||||
for (auto& release : releases)
|
||||
{
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Removing orphan release '" << release->getName() << "'";
|
||||
@@ -805,9 +805,9 @@ MediaScanner::checkDuplicatedAudioFiles(ScanStats& stats)
|
||||
{
|
||||
LMS_LOG(DBUPDATER, INFO) << "Checking duplicated audio files";
|
||||
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
|
||||
const std::vector<Track::pointer> tracks = Database::Track::getMBIDDuplicates(*_dbSession);
|
||||
const std::vector<Track::pointer> tracks = Database::Track::getMBIDDuplicates(_dbSession);
|
||||
for (const Track::pointer& track : tracks)
|
||||
{
|
||||
LMS_LOG(DBUPDATER, INFO) << "Found duplicated MBID [" << track->getMBID() << "], file: " << track->getPath().string() << " - " << track->getName();
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Scanner {
|
||||
class MediaScanner
|
||||
{
|
||||
public:
|
||||
MediaScanner(std::unique_ptr<Database::Session> dbSession);
|
||||
MediaScanner(Database::Db& db);
|
||||
|
||||
void setAddon(MediaScannerAddon& addon);
|
||||
|
||||
@@ -110,7 +110,7 @@ class MediaScanner
|
||||
Wt::Signal<ScanProgressStats> _sigScanInProgress;
|
||||
std::chrono::system_clock::time_point _lastScanInProgressEmit {};
|
||||
Wt::Signal<Wt::WDateTime> _sigScheduled;
|
||||
std::unique_ptr<Database::Session> _dbSession;
|
||||
Database::Session _dbSession;
|
||||
MetaData::TagLibParser _metadataParser;
|
||||
std::vector<MediaScannerAddon*> _addons;
|
||||
|
||||
|
||||
@@ -72,13 +72,13 @@ getTracksWithMBIDAndMissingFeatures(Database::Session& dbSession)
|
||||
return res;
|
||||
}
|
||||
|
||||
FeaturesScannerAddon::FeaturesScannerAddon(std::unique_ptr<Database::Session> dbSession)
|
||||
: _dbSession {std::move(dbSession)}
|
||||
FeaturesScannerAddon::FeaturesScannerAddon(Database::Db& db)
|
||||
: _dbSession {db}
|
||||
{
|
||||
std::optional<Similarity::FeaturesCache> cache {Similarity::FeaturesCache::read()};
|
||||
if (cache)
|
||||
{
|
||||
auto searcher {std::make_shared<Similarity::FeaturesSearcher>(*_dbSession.get(), *cache, [&]() { return _stopRequested; })};
|
||||
auto searcher {std::make_shared<Similarity::FeaturesSearcher>(_dbSession, *cache, [&]() { return _stopRequested; })};
|
||||
if (searcher->isValid())
|
||||
std::atomic_store(&_searcher, searcher);
|
||||
}
|
||||
@@ -99,9 +99,9 @@ FeaturesScannerAddon::requestStop()
|
||||
void
|
||||
FeaturesScannerAddon::trackUpdated(Database::IdType trackId)
|
||||
{
|
||||
auto uniqueTransaction {_dbSession->createUniqueTransaction()};
|
||||
auto uniqueTransaction {_dbSession.createUniqueTransaction()};
|
||||
|
||||
auto track {Database::Track::getById(*_dbSession, trackId)};
|
||||
auto track {Database::Track::getById(_dbSession, trackId)};
|
||||
if (!track)
|
||||
return;
|
||||
|
||||
@@ -112,9 +112,9 @@ void
|
||||
FeaturesScannerAddon::preScanComplete()
|
||||
{
|
||||
{
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
|
||||
if (Database::SimilaritySettings::get(*_dbSession)->getEngineType() != Database::SimilaritySettings::EngineType::Features)
|
||||
if (Database::SimilaritySettings::get(_dbSession)->getEngineType() != Database::SimilaritySettings::EngineType::Features)
|
||||
{
|
||||
LMS_LOG(DBUPDATER, INFO) << "Do not fetch features since the engine type does not make use of them";
|
||||
return;
|
||||
@@ -122,7 +122,7 @@ FeaturesScannerAddon::preScanComplete()
|
||||
}
|
||||
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Getting tracks with missing Features...";
|
||||
const std::vector<TrackInfo> tracksInfo {getTracksWithMBIDAndMissingFeatures(*_dbSession)};
|
||||
const std::vector<TrackInfo> tracksInfo {getTracksWithMBIDAndMissingFeatures(_dbSession)};
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Getting tracks with missing Features DONE (found " << tracksInfo.size() << ")";
|
||||
|
||||
if (!tracksInfo.empty())
|
||||
@@ -144,16 +144,16 @@ FeaturesScannerAddon::updateSearcher()
|
||||
{
|
||||
LMS_LOG(SIMILARITY, INFO) << "Updating searcher...";
|
||||
|
||||
if (hasAtLeastOneTrackWithFeatures(*_dbSession))
|
||||
if (hasAtLeastOneTrackWithFeatures(_dbSession))
|
||||
{
|
||||
LMS_LOG(DBUPDATER, INFO) << "No track suitable for features similarity clustering";
|
||||
std::atomic_store(&_searcher, std::shared_ptr<FeaturesSearcher>{});
|
||||
return;
|
||||
}
|
||||
|
||||
const auto features {getFeatureSettings(*_dbSession)};
|
||||
const auto features {getFeatureSettings(_dbSession)};
|
||||
|
||||
auto searcher {std::make_shared<Similarity::FeaturesSearcher>(*_dbSession, features, [&]() { return _stopRequested; })};
|
||||
auto searcher {std::make_shared<Similarity::FeaturesSearcher>(_dbSession, features, [&]() { return _stopRequested; })};
|
||||
if (searcher->isValid())
|
||||
{
|
||||
std::atomic_store(&_searcher, searcher);
|
||||
@@ -183,13 +183,13 @@ FeaturesScannerAddon::fetchFeatures(Database::IdType trackId, const std::string&
|
||||
}
|
||||
|
||||
{
|
||||
auto uniqueTransaction {_dbSession->createUniqueTransaction()};
|
||||
auto uniqueTransaction {_dbSession.createUniqueTransaction()};
|
||||
|
||||
Wt::Dbo::ptr<Database::Track> track {Database::Track::getById(*_dbSession, trackId)};
|
||||
Wt::Dbo::ptr<Database::Track> track {Database::Track::getById(_dbSession, trackId)};
|
||||
if (!track)
|
||||
return false;
|
||||
|
||||
Database::TrackFeatures::create(*_dbSession, track, data);
|
||||
Database::TrackFeatures::create(_dbSession, track, data);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -24,13 +24,17 @@
|
||||
|
||||
#include "SimilarityFeaturesSearcher.hpp"
|
||||
|
||||
namespace Database {
|
||||
class Db;
|
||||
}
|
||||
|
||||
namespace Similarity {
|
||||
|
||||
class FeaturesScannerAddon final : public Scanner::MediaScannerAddon
|
||||
{
|
||||
public:
|
||||
|
||||
FeaturesScannerAddon(std::unique_ptr<Database::Session> dbSession);
|
||||
FeaturesScannerAddon(Database::Db& db);
|
||||
|
||||
std::shared_ptr<FeaturesSearcher> getSearcher();
|
||||
|
||||
@@ -48,7 +52,7 @@ class FeaturesScannerAddon final : public Scanner::MediaScannerAddon
|
||||
|
||||
void updateSearcher();
|
||||
|
||||
std::unique_ptr<Database::Session> _dbSession;
|
||||
Database::Session _dbSession;
|
||||
std::shared_ptr<FeaturesSearcher> _searcher;
|
||||
bool _stopRequested {};
|
||||
};
|
||||
|
||||
+14
-14
@@ -60,7 +60,7 @@ namespace UserInterface {
|
||||
std::unique_ptr<Wt::WApplication>
|
||||
LmsApplication::create(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups)
|
||||
{
|
||||
return std::make_unique<LmsApplication>(env, db.createSession(), appGroups);
|
||||
return std::make_unique<LmsApplication>(env, db, appGroups);
|
||||
}
|
||||
|
||||
LmsApplication*
|
||||
@@ -70,12 +70,12 @@ LmsApplication::instance()
|
||||
}
|
||||
|
||||
Wt::Dbo::ptr<Database::User>
|
||||
LmsApplication::getUser() const
|
||||
LmsApplication::getUser()
|
||||
{
|
||||
if (!_userId)
|
||||
return {};
|
||||
|
||||
return Database::User::getById(*_dbSession, *_userId);
|
||||
return Database::User::getById(_dbSession, *_userId);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -85,34 +85,34 @@ LmsApplication::isUserAuthStrong() const
|
||||
}
|
||||
|
||||
bool
|
||||
LmsApplication::isUserAdmin() const
|
||||
LmsApplication::isUserAdmin()
|
||||
{
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
|
||||
return getUser()->isAdmin();
|
||||
}
|
||||
|
||||
bool
|
||||
LmsApplication::isUserDemo() const
|
||||
LmsApplication::isUserDemo()
|
||||
{
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
|
||||
return getUser()->isDemo();
|
||||
}
|
||||
|
||||
std::string
|
||||
LmsApplication::getUserLoginName() const
|
||||
LmsApplication::getUserLoginName()
|
||||
{
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
|
||||
return getUser()->getLoginName();
|
||||
}
|
||||
|
||||
LmsApplication::LmsApplication(const Wt::WEnvironment& env,
|
||||
std::unique_ptr<Database::Session> dbSession,
|
||||
Database::Db& db,
|
||||
LmsApplicationGroupContainer& appGroups)
|
||||
: Wt::WApplication {env},
|
||||
_dbSession {std::move(dbSession)},
|
||||
_dbSession {db},
|
||||
_appGroups {appGroups}
|
||||
{
|
||||
auto bootstrapTheme = std::make_unique<Wt::WBootstrapTheme>();
|
||||
@@ -165,8 +165,8 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env,
|
||||
// If here is no account in the database, launch the first connection wizard
|
||||
bool firstConnection {};
|
||||
{
|
||||
auto transaction {_dbSession->createSharedTransaction()};
|
||||
firstConnection = Database::User::getAll(*_dbSession).empty();
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
firstConnection = Database::User::getAll(_dbSession).empty();
|
||||
}
|
||||
|
||||
LMS_LOG(UI, DEBUG) << "Creating root widget. First connection = " << firstConnection;
|
||||
@@ -368,7 +368,7 @@ LmsApplication::handleUserLoggedOut()
|
||||
LMS_LOG(UI, INFO) << "User '" << getUserLoginName() << " 'logged out";
|
||||
|
||||
{
|
||||
auto transaction {_dbSession->createUniqueTransaction()};
|
||||
auto transaction {_dbSession.createUniqueTransaction()};
|
||||
getUser().modify()->clearAuthTokens();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include <Wt/WApplication.h>
|
||||
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "scanner/MediaScanner.hpp"
|
||||
|
||||
#include "LmsApplicationGroup.hpp"
|
||||
@@ -73,7 +75,7 @@ enum class MsgType
|
||||
class LmsApplication : public Wt::WApplication
|
||||
{
|
||||
public:
|
||||
LmsApplication(const Wt::WEnvironment& env, std::unique_ptr<Database::Session> dbSession, LmsApplicationGroupContainer& appGroups);
|
||||
LmsApplication(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups);
|
||||
|
||||
static std::unique_ptr<Wt::WApplication> create(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups);
|
||||
static LmsApplication* instance();
|
||||
@@ -81,13 +83,13 @@ class LmsApplication : public Wt::WApplication
|
||||
// Session application data
|
||||
std::shared_ptr<ImageResource> getImageResource() { return _imageResource; }
|
||||
std::shared_ptr<AudioResource> getAudioResource() { return _audioResource; }
|
||||
Database::Session& getDbSession() { return *_dbSession.get();}
|
||||
Database::Session& getDbSession() { return _dbSession;}
|
||||
|
||||
Wt::Dbo::ptr<Database::User> getUser() const;
|
||||
Wt::Dbo::ptr<Database::User> getUser();
|
||||
bool isUserAuthStrong() const; // user must be logged in prior this call
|
||||
bool isUserAdmin() const; // user must be logged in prior this call
|
||||
bool isUserDemo() const; // user must be logged in prior this call
|
||||
std::string getUserLoginName() const; // user must be logged in prior this call
|
||||
bool isUserAdmin(); // user must be logged in prior this call
|
||||
bool isUserDemo(); // user must be logged in prior this call
|
||||
std::string getUserLoginName(); // user must be logged in prior this call
|
||||
|
||||
Events& getEvents() { return _events; }
|
||||
|
||||
@@ -121,7 +123,7 @@ class LmsApplication : public Wt::WApplication
|
||||
void createHome();
|
||||
|
||||
Wt::Signal<> _preQuit;
|
||||
std::unique_ptr<Database::Session> _dbSession;
|
||||
Database::Session _dbSession;
|
||||
LmsApplicationGroupContainer& _appGroups;
|
||||
Events _events;
|
||||
std::optional<Database::IdType> _userId;
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "database/Track.hpp"
|
||||
#include "database/TrackList.hpp"
|
||||
#include "database/User.hpp"
|
||||
|
||||
#include "utils/StreamLogger.hpp"
|
||||
@@ -1266,13 +1267,14 @@ int main()
|
||||
for (std::size_t i = 0; i < 2; ++i)
|
||||
{
|
||||
Database::Db db {tmpFile};
|
||||
std::unique_ptr<Session> session {db.createSession()};
|
||||
Database::Session session {db};
|
||||
session.prepareTables();
|
||||
|
||||
auto runTest = [&session](const std::string& name, std::function<void(Session&)> testFunc)
|
||||
{
|
||||
std::cout << "Running test '" << name << "'..." << std::endl;
|
||||
testFunc(*session);
|
||||
testDatabaseEmpty(*session);
|
||||
testFunc(session);
|
||||
testDatabaseEmpty(session);
|
||||
std::cout << "Running test '" << name << "': SUCCESS" << std::endl;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "utils/Config.hpp"
|
||||
#include "utils/Service.hpp"
|
||||
#include "utils/StreamLogger.hpp"
|
||||
@@ -23,7 +24,7 @@ int main(int argc, char *argv[])
|
||||
ServiceProvider<Config>::create(configFilePath);
|
||||
|
||||
Database::Db db {ServiceProvider<Config>::get()->getPath("working-dir") / "lms.db"};
|
||||
auto session {db.createSession()};
|
||||
Database::Session session {db};
|
||||
|
||||
/* const FeatureSettings
|
||||
{
|
||||
|
||||
@@ -39,13 +39,13 @@ int main(int argc, char *argv[])
|
||||
ServiceProvider<Config>::create(configFilePath);
|
||||
|
||||
Database::Db db {ServiceProvider<Config>::get()->getPath("working-dir") / "lms.db"};
|
||||
auto session {db.createSession()};
|
||||
Database::Session session {db};
|
||||
|
||||
std::cout << "Getting all features..." << std::endl;
|
||||
|
||||
std::cout << "Classifying tracks..." << std::endl;
|
||||
// may be long...
|
||||
FeaturesSearcher searcher {*session, featuresSettings};
|
||||
FeaturesSearcher searcher {session, featuresSettings};
|
||||
|
||||
std::cout << "Classifying tracks DONE" << std::endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user