Commit 8992d9e6 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Handle AlbumTrack deletion

parent 62b99a5f
#ifndef IALBUMTRACK_H
#define IALBUMTRACK_H
#include <memory>
#include <string>
#include "IMediaLibrary.h"
class IAlbum;
......@@ -16,6 +15,11 @@ class IAlbumTrack
virtual const std::string& title() = 0;
virtual unsigned int trackNumber() = 0;
virtual std::shared_ptr<IAlbum> album() = 0;
virtual bool files( std::vector<FilePtr>& files ) = 0;
/**
* @brief destroy Deletes the album track and the file(s) associated
*/
virtual bool destroy() = 0;
};
#endif // IALBUMTRACK_H
#include "AlbumTrack.h"
#include "Album.h"
#include "File.h"
#include "SqliteTools.h"
const std::string policy::AlbumTrackTable::Name = "AlbumTrack";
......@@ -79,3 +80,29 @@ std::shared_ptr<IAlbum> AlbumTrack::album()
}
return m_album;
}
bool AlbumTrack::destroy()
{
// Manually remove Files from cache, and let foreign key handling delete them from the DB
std::vector<FilePtr> fs;
if ( files( fs ) == false )
return false;
if ( fs.size() == 0 )
std::cerr << "No files found for AlbumTrack " << m_id << std::endl;
for ( auto& f : fs )
{
if ( File::discard( std::static_pointer_cast<File>( f ) ) == false )
{
std::cerr << "Failed to discard a file from cache";
return false;
}
}
return _Cache::destroy( m_dbConnection, this );
}
bool AlbumTrack::files(std::vector<FilePtr>& files)
{
static const std::string req = "SELECT * FROM " + policy::FileTable::Name
+ " WHERE album_track_id = ? ";
return SqliteTools::fetchAll<File>( m_dbConnection, req, files, m_id );
}
......@@ -34,6 +34,8 @@ class AlbumTrack : public IAlbumTrack, public Cache<AlbumTrack, IAlbumTrack, pol
virtual const std::string& title();
virtual unsigned int trackNumber();
virtual std::shared_ptr<IAlbum> album();
virtual bool destroy();
virtual bool files( std::vector<FilePtr>& files );
static bool createTable( sqlite3* dbConnection );
static AlbumTrackPtr create(sqlite3* dbConnection, unsigned int albumId,
......
......@@ -17,6 +17,10 @@ class PrimaryKeyCacheKeyPolicy
{
return self->id();
}
static unsigned int key( const TYPE* self )
{
return self->id();
}
static unsigned int key( sqlite3_stmt* stmt )
{
return Traits<unsigned int>::Load( stmt, 0 );
......@@ -104,17 +108,29 @@ class Cache
return destroy( dbConnection, key );
}
static bool destroy( sqlite3* dbConnection, const IMPL* self )
{
const auto& key = CACHEPOLICY::key( self );
return destroy( dbConnection, key );
}
static void clear()
{
Lock lock( Mutex );
Store.clear();
}
static bool discard( const typename CACHEPOLICY::KeyType& key )
/**
* @brief discard Discard a record from the cache
* @param key The key used for cache
* @return
*/
static bool discard( const std::shared_ptr<IMPL>& record )
{
auto key = CACHEPOLICY::key( record );
Lock lock( Mutex );
auto it = Store.find( key );
if ( it != Store.end() )
if ( it == Store.end() )
return false;
Store.erase( it );
return true;
......
......@@ -41,9 +41,8 @@ FilePtr File::create( sqlite3* dbConnection, const std::string& mrl )
{
auto self = std::make_shared<File>( mrl );
static const std::string req = "INSERT INTO " + policy::FileTable::Name +
" VALUES(NULL, ?, ?, ?, ?, ?, ?)";
bool pKey = _Cache::insert( dbConnection, self, req, (int)self->m_type, self->m_duration,
self->m_albumTrackId, self->m_playCount, self->m_showEpisodeId, self->m_mrl );
"(mrl) VALUES(?)";
bool pKey = _Cache::insert( dbConnection, self, req, mrl );
if ( pKey == false )
return nullptr;
self->m_dbConnection = dbConnection;
......@@ -118,7 +117,9 @@ bool File::createTable(sqlite3* connection)
"album_track_id UNSIGNED INTEGER,"
"play_count UNSIGNED INTEGER,"
"show_episode_id UNSIGNED INTEGER,"
"mrl TEXT UNIQUE ON CONFLICT FAIL"
"mrl TEXT UNIQUE ON CONFLICT FAIL,"
"FOREIGN KEY (album_track_id) REFERENCES " + policy::AlbumTrackTable::Name
+ "(id_track) ON DELETE CASCADE"
")";
return SqliteTools::executeRequest( connection, req );
}
......
......@@ -110,7 +110,7 @@ class SqliteTools
} while ( res == SQLITE_ROW );
if ( res != SQLITE_DONE )
{
std::cerr << "Invalid result: " << res << ": " <<
std::cerr << "Invalid result: " << sqlite3_errstr( res ) << ": " <<
sqlite3_errmsg( dbConnection ) << std::endl;
return false;
}
......
......@@ -92,3 +92,17 @@ TEST_F( Albums, AssignTrack )
ASSERT_NE( t, nullptr );
ASSERT_EQ( t->title(), "track" );
}
TEST_F( Albums, DeleteTrack )
{
auto f = ml->addFile( "file" );
auto a = ml->createAlbum( "album" );
auto t = a->addTrack( "track", 1 );
f->setAlbumTrack( t );
bool res = t->destroy();
ASSERT_TRUE( res );
auto f2 = ml->file( "file" );
ASSERT_EQ( f2, nullptr );
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment