/*
* Copyright (C) 2019 Emeric Poupon
*
* This file is part of LMS.
*
* LMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LMS. If not, see .
*/
#include
#include
#include
#include "database/Artist.hpp"
#include "database/Cluster.hpp"
#include "database/Db.hpp"
#include "database/TrackList.hpp"
#include "database/Release.hpp"
#include "database/Track.hpp"
#include "database/User.hpp"
using namespace Database;
#define CHECK(PRED) \
do \
{ \
try \
{ \
if (!(PRED)) \
{ \
std::string error {"Predicate FAILED '" + std::string {#PRED} + "' at " + __FUNCTION__ + "@l." + std::to_string(__LINE__)}; \
std::cerr << error << std::endl; \
throw std::runtime_error {error}; \
} \
} \
catch (std::exception& e) \
{ \
std::cerr << "Exception caught: " << e.what() << std::endl; \
throw; \
} \
} while (0)
class ScopedFileDeleter final
{
public:
ScopedFileDeleter(const std::filesystem::path& path) : _path {path} {}
~ScopedFileDeleter() { std::filesystem::remove(_path); }
ScopedFileDeleter(const ScopedFileDeleter&) = delete;
ScopedFileDeleter(ScopedFileDeleter&&) = delete;
ScopedFileDeleter operator=(const ScopedFileDeleter&) = delete;
ScopedFileDeleter operator=(ScopedFileDeleter&&) = delete;
private:
const std::filesystem::path _path;
};
template
class ScopedEntity
{
public:
template
ScopedEntity(Session& session, Args&& ...args)
: _session {session}
{
auto transaction {_session.createUniqueTransaction()};
auto entity {T::create(_session, std::forward(args)...)};
CHECK(entity);
_id = entity.id();
}
~ScopedEntity()
{
auto transaction {_session.createUniqueTransaction()};
auto entity {T::getById(_session, _id)};
entity.remove();
}
ScopedEntity(const ScopedEntity&) = delete;
ScopedEntity(ScopedEntity&&) = delete;
ScopedEntity& operator=(const ScopedEntity&) = delete;
ScopedEntity& operator=(ScopedEntity&&) = delete;
typename T::pointer lockAndGet()
{
auto transaction {_session.createSharedTransaction()};
return get();
}
typename T::pointer get()
{
_session.checkSharedLocked();
auto entity {T::getById(_session, _id)};
CHECK(entity);
return entity;
}
typename T::pointer operator->()
{
return get();
}
IdType getId() const { return _id; }
private:
Session& _session;
IdType _id {};
};
using ScopedArtist = ScopedEntity;
using ScopedCluster = ScopedEntity;
using ScopedClusterType = ScopedEntity;
using ScopedRelease = ScopedEntity;
using ScopedTrack = ScopedEntity