Commit 03dc124a authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Use a pair of shared_ptr/weak_ptr to monitor the database connection

This will avoid random crash due to dangling pointer in case the DB was
released
parent e7b5de70
...@@ -11,6 +11,7 @@ class IMetadataService; ...@@ -11,6 +11,7 @@ class IMetadataService;
class IMovie; class IMovie;
class IShow; class IShow;
class IShowEpisode; class IShowEpisode;
class sqlite3;
typedef std::shared_ptr<IFile> FilePtr; typedef std::shared_ptr<IFile> FilePtr;
typedef std::shared_ptr<ILabel> LabelPtr; typedef std::shared_ptr<ILabel> LabelPtr;
...@@ -19,5 +20,6 @@ typedef std::shared_ptr<IAlbumTrack> AlbumTrackPtr; ...@@ -19,5 +20,6 @@ typedef std::shared_ptr<IAlbumTrack> AlbumTrackPtr;
typedef std::shared_ptr<IShow> ShowPtr; typedef std::shared_ptr<IShow> ShowPtr;
typedef std::shared_ptr<IShowEpisode> ShowEpisodePtr; typedef std::shared_ptr<IShowEpisode> ShowEpisodePtr;
typedef std::shared_ptr<IMovie> MoviePtr; typedef std::shared_ptr<IMovie> MoviePtr;
typedef std::weak_ptr<sqlite3> DBConnection;
#endif // TYPES_H #endif // TYPES_H
...@@ -7,7 +7,7 @@ const std::string policy::AlbumTable::Name = "Album"; ...@@ -7,7 +7,7 @@ const std::string policy::AlbumTable::Name = "Album";
const std::string policy::AlbumTable::CacheColumn = "id_album"; const std::string policy::AlbumTable::CacheColumn = "id_album";
unsigned int Album::* const policy::AlbumTable::PrimaryKey = &Album::m_id; unsigned int Album::* const policy::AlbumTable::PrimaryKey = &Album::m_id;
Album::Album(sqlite3* dbConnection, sqlite3_stmt* stmt) Album::Album(DBConnection dbConnection, sqlite3_stmt* stmt)
: m_dbConnection( dbConnection ) : m_dbConnection( dbConnection )
{ {
m_id = sqlite3_column_int( stmt, 0 ); m_id = sqlite3_column_int( stmt, 0 );
...@@ -20,8 +20,7 @@ Album::Album(sqlite3* dbConnection, sqlite3_stmt* stmt) ...@@ -20,8 +20,7 @@ Album::Album(sqlite3* dbConnection, sqlite3_stmt* stmt)
} }
Album::Album( const std::string& id3tag ) Album::Album( const std::string& id3tag )
: m_dbConnection( nullptr ) : m_id( 0 )
, m_id( 0 )
, m_releaseDate( 0 ) , m_releaseDate( 0 )
, m_lastSyncDate( 0 ) , m_lastSyncDate( 0 )
, m_id3tag( id3tag ) , m_id3tag( id3tag )
...@@ -123,7 +122,7 @@ bool Album::destroy() ...@@ -123,7 +122,7 @@ bool Album::destroy()
return _Cache::destroy( m_dbConnection, this ); return _Cache::destroy( m_dbConnection, this );
} }
bool Album::createTable( sqlite3* dbConnection ) bool Album::createTable(DBConnection dbConnection )
{ {
static const std::string req = "CREATE TABLE IF NOT EXISTS " + static const std::string req = "CREATE TABLE IF NOT EXISTS " +
policy::AlbumTable::Name + policy::AlbumTable::Name +
...@@ -139,7 +138,7 @@ bool Album::createTable( sqlite3* dbConnection ) ...@@ -139,7 +138,7 @@ bool Album::createTable( sqlite3* dbConnection )
return SqliteTools::executeRequest( dbConnection, req ); return SqliteTools::executeRequest( dbConnection, req );
} }
AlbumPtr Album::create( sqlite3* dbConnection, const std::string& id3Tag ) AlbumPtr Album::create(DBConnection dbConnection, const std::string& id3Tag )
{ {
auto album = std::make_shared<Album>( id3Tag ); auto album = std::make_shared<Album>( id3Tag );
static const std::string& req = "INSERT INTO " + policy::AlbumTable::Name + static const std::string& req = "INSERT INTO " + policy::AlbumTable::Name +
......
...@@ -26,7 +26,7 @@ class Album : public IAlbum, public Cache<Album, IAlbum, policy::AlbumTable> ...@@ -26,7 +26,7 @@ class Album : public IAlbum, public Cache<Album, IAlbum, policy::AlbumTable>
private: private:
typedef Cache<Album, IAlbum, policy::AlbumTable> _Cache; typedef Cache<Album, IAlbum, policy::AlbumTable> _Cache;
public: public:
Album( sqlite3* dbConnection, sqlite3_stmt* stmt ); Album( DBConnection dbConnection, sqlite3_stmt* stmt );
Album( const std::string& id3tag ); Album( const std::string& id3tag );
virtual unsigned int id() const; virtual unsigned int id() const;
...@@ -43,11 +43,11 @@ class Album : public IAlbum, public Cache<Album, IAlbum, policy::AlbumTable> ...@@ -43,11 +43,11 @@ class Album : public IAlbum, public Cache<Album, IAlbum, policy::AlbumTable>
virtual AlbumTrackPtr addTrack( const std::string& name, unsigned int trackNb ); virtual AlbumTrackPtr addTrack( const std::string& name, unsigned int trackNb );
virtual bool destroy(); virtual bool destroy();
static bool createTable( sqlite3* dbConnection ); static bool createTable( DBConnection dbConnection );
static AlbumPtr create( sqlite3* dbConnection, const std::string& id3Tag ); static AlbumPtr create( DBConnection dbConnection, const std::string& id3Tag );
protected: protected:
sqlite3* m_dbConnection; DBConnection m_dbConnection;
unsigned int m_id; unsigned int m_id;
std::string m_name; std::string m_name;
unsigned int m_releaseDate; unsigned int m_releaseDate;
......
...@@ -7,7 +7,7 @@ const std::string policy::AlbumTrackTable::Name = "AlbumTrack"; ...@@ -7,7 +7,7 @@ const std::string policy::AlbumTrackTable::Name = "AlbumTrack";
const std::string policy::AlbumTrackTable::CacheColumn = "id_track"; const std::string policy::AlbumTrackTable::CacheColumn = "id_track";
unsigned int AlbumTrack::* const policy::AlbumTrackTable::PrimaryKey = &AlbumTrack::m_id; unsigned int AlbumTrack::* const policy::AlbumTrackTable::PrimaryKey = &AlbumTrack::m_id;
AlbumTrack::AlbumTrack( sqlite3* dbConnection, sqlite3_stmt* stmt ) AlbumTrack::AlbumTrack( DBConnection dbConnection, sqlite3_stmt* stmt )
: m_dbConnection( dbConnection ) : m_dbConnection( dbConnection )
, m_album( nullptr ) , m_album( nullptr )
{ {
...@@ -19,8 +19,7 @@ AlbumTrack::AlbumTrack( sqlite3* dbConnection, sqlite3_stmt* stmt ) ...@@ -19,8 +19,7 @@ AlbumTrack::AlbumTrack( sqlite3* dbConnection, sqlite3_stmt* stmt )
} }
AlbumTrack::AlbumTrack( const std::string& title, unsigned int trackNumber, unsigned int albumId ) AlbumTrack::AlbumTrack( const std::string& title, unsigned int trackNumber, unsigned int albumId )
: m_dbConnection( nullptr ) : m_id( 0 )
, m_id( 0 )
, m_title( title ) , m_title( title )
, m_trackNumber( trackNumber ) , m_trackNumber( trackNumber )
, m_albumId( albumId ) , m_albumId( albumId )
...@@ -33,7 +32,7 @@ unsigned int AlbumTrack::id() const ...@@ -33,7 +32,7 @@ unsigned int AlbumTrack::id() const
return m_id; return m_id;
} }
bool AlbumTrack::createTable(sqlite3* dbConnection) bool AlbumTrack::createTable( DBConnection dbConnection )
{ {
const char* req = "CREATE TABLE IF NOT EXISTS AlbumTrack (" const char* req = "CREATE TABLE IF NOT EXISTS AlbumTrack ("
"id_track INTEGER PRIMARY KEY AUTOINCREMENT," "id_track INTEGER PRIMARY KEY AUTOINCREMENT,"
...@@ -46,7 +45,7 @@ bool AlbumTrack::createTable(sqlite3* dbConnection) ...@@ -46,7 +45,7 @@ bool AlbumTrack::createTable(sqlite3* dbConnection)
return SqliteTools::executeRequest( dbConnection, req ); return SqliteTools::executeRequest( dbConnection, req );
} }
AlbumTrackPtr AlbumTrack::create(sqlite3* dbConnection, unsigned int albumId, const std::string& name, unsigned int trackNb) AlbumTrackPtr AlbumTrack::create(DBConnection dbConnection, unsigned int albumId, const std::string& name, unsigned int trackNb)
{ {
auto self = std::make_shared<AlbumTrack>( name, trackNb, albumId ); auto self = std::make_shared<AlbumTrack>( name, trackNb, albumId );
static const std::string req = "INSERT INTO " + policy::AlbumTrackTable::Name static const std::string req = "INSERT INTO " + policy::AlbumTrackTable::Name
......
...@@ -26,7 +26,7 @@ class AlbumTrack : public IAlbumTrack, public Cache<AlbumTrack, IAlbumTrack, pol ...@@ -26,7 +26,7 @@ class AlbumTrack : public IAlbumTrack, public Cache<AlbumTrack, IAlbumTrack, pol
private: private:
typedef Cache<AlbumTrack, IAlbumTrack, policy::AlbumTrackTable> _Cache; typedef Cache<AlbumTrack, IAlbumTrack, policy::AlbumTrackTable> _Cache;
public: public:
AlbumTrack( sqlite3* dbConnection, sqlite3_stmt* stmt ); AlbumTrack( DBConnection dbConnection, sqlite3_stmt* stmt );
AlbumTrack( const std::string& title, unsigned int trackNumber, unsigned int albumId ); AlbumTrack( const std::string& title, unsigned int trackNumber, unsigned int albumId );
virtual unsigned int id() const; virtual unsigned int id() const;
...@@ -38,12 +38,12 @@ class AlbumTrack : public IAlbumTrack, public Cache<AlbumTrack, IAlbumTrack, pol ...@@ -38,12 +38,12 @@ class AlbumTrack : public IAlbumTrack, public Cache<AlbumTrack, IAlbumTrack, pol
virtual bool destroy(); virtual bool destroy();
virtual bool files( std::vector<FilePtr>& files ); virtual bool files( std::vector<FilePtr>& files );
static bool createTable( sqlite3* dbConnection ); static bool createTable( DBConnection dbConnection );
static AlbumTrackPtr create(sqlite3* dbConnection, unsigned int albumId, static AlbumTrackPtr create( DBConnection dbConnection, unsigned int albumId,
const std::string& name, unsigned int trackNb ); const std::string& name, unsigned int trackNb );
private: private:
sqlite3* m_dbConnection; DBConnection m_dbConnection;
unsigned int m_id; unsigned int m_id;
std::string m_title; std::string m_title;
std::string m_genre; std::string m_genre;
......
...@@ -53,7 +53,7 @@ template <typename IMPL, typename INTF, typename TABLEPOLICY, typename CACHEPOLI ...@@ -53,7 +53,7 @@ template <typename IMPL, typename INTF, typename TABLEPOLICY, typename CACHEPOLI
class Cache class Cache
{ {
public: public:
static std::shared_ptr<IMPL> fetch( sqlite3* dbConnection, const typename CACHEPOLICY::KeyType& key ) static std::shared_ptr<IMPL> fetch( DBConnection dbConnectionWeak, const typename CACHEPOLICY::KeyType& key )
{ {
Lock lock( Mutex ); Lock lock( Mutex );
auto it = Store.find( key ); auto it = Store.find( key );
...@@ -61,7 +61,7 @@ class Cache ...@@ -61,7 +61,7 @@ class Cache
return it->second; return it->second;
static const std::string req = "SELECT * FROM " + TABLEPOLICY::Name + static const std::string req = "SELECT * FROM " + TABLEPOLICY::Name +
" WHERE " + TABLEPOLICY::CacheColumn + " = ?"; " WHERE " + TABLEPOLICY::CacheColumn + " = ?";
auto res = SqliteTools::fetchOne<IMPL>( dbConnection, req.c_str(), key ); auto res = SqliteTools::fetchOne<IMPL>( dbConnectionWeak, req.c_str(), key );
Store[key] = res; Store[key] = res;
return res; return res;
} }
...@@ -72,13 +72,13 @@ class Cache ...@@ -72,13 +72,13 @@ class Cache
* @param res A reference to the result vector. All existing elements will * @param res A reference to the result vector. All existing elements will
* be discarded. * be discarded.
*/ */
static bool fetchAll( sqlite3* dbConnection, std::vector<std::shared_ptr<INTF> >& res ) static bool fetchAll( DBConnection dbConnectionWeak, std::vector<std::shared_ptr<INTF> >& res )
{ {
static const std::string req = "SELECT * FROM " + TABLEPOLICY::Name; static const std::string req = "SELECT * FROM " + TABLEPOLICY::Name;
return SqliteTools::fetchAll<IMPL, INTF>( dbConnection, req.c_str(), res ); return SqliteTools::fetchAll<IMPL, INTF>( dbConnectionWeak, req.c_str(), res );
} }
static std::shared_ptr<IMPL> load( sqlite3* dbConnection, sqlite3_stmt* stmt ) static std::shared_ptr<IMPL> load( std::shared_ptr<sqlite3> dbConnection, sqlite3_stmt* stmt )
{ {
auto cacheKey = CACHEPOLICY::key( stmt ); auto cacheKey = CACHEPOLICY::key( stmt );
...@@ -91,7 +91,7 @@ class Cache ...@@ -91,7 +91,7 @@ class Cache
return inst; return inst;
} }
static bool destroy( sqlite3* dbConnection, const typename CACHEPOLICY::KeyType& key ) static bool destroy( DBConnection dbConnectionWeak, const typename CACHEPOLICY::KeyType& key )
{ {
Lock lock( Mutex ); Lock lock( Mutex );
auto it = Store.find( key ); auto it = Store.find( key );
...@@ -99,19 +99,19 @@ class Cache ...@@ -99,19 +99,19 @@ class Cache
Store.erase( it ); Store.erase( it );
static const std::string req = "DELETE FROM " + TABLEPOLICY::Name + " WHERE " + static const std::string req = "DELETE FROM " + TABLEPOLICY::Name + " WHERE " +
TABLEPOLICY::CacheColumn + " = ?"; TABLEPOLICY::CacheColumn + " = ?";
return SqliteTools::executeDelete( dbConnection, req.c_str(), key ); return SqliteTools::executeDelete( dbConnectionWeak, req.c_str(), key );
} }
static bool destroy( sqlite3* dbConnection, const std::shared_ptr<IMPL>& self ) static bool destroy( DBConnection dbConnectionWeak, const std::shared_ptr<IMPL>& self )
{ {
const auto& key = CACHEPOLICY::key( self ); const auto& key = CACHEPOLICY::key( self );
return destroy( dbConnection, key ); return destroy( dbConnectionWeak, key );
} }
static bool destroy( sqlite3* dbConnection, const IMPL* self ) static bool destroy( DBConnection dbConnectionWeak, const IMPL* self )
{ {
const auto& key = CACHEPOLICY::key( self ); const auto& key = CACHEPOLICY::key( self );
return destroy( dbConnection, key ); return destroy( dbConnectionWeak, key );
} }
static void clear() static void clear()
...@@ -141,9 +141,9 @@ class Cache ...@@ -141,9 +141,9 @@ class Cache
* Create a new instance of the cache class. * Create a new instance of the cache class.
*/ */
template <typename... Args> template <typename... Args>
static bool insert( sqlite3* dbConnection, std::shared_ptr<IMPL> self, const std::string& req, const Args&... args ) static bool insert( DBConnection dbConnectionWeak, std::shared_ptr<IMPL> self, const std::string& req, const Args&... args )
{ {
unsigned int pKey = SqliteTools::insert( dbConnection, req, args... ); unsigned int pKey = SqliteTools::insert( dbConnectionWeak, req, args... );
if ( pKey == 0 ) if ( pKey == 0 )
return false; return false;
(self.get())->*TABLEPOLICY::PrimaryKey = pKey; (self.get())->*TABLEPOLICY::PrimaryKey = pKey;
......
...@@ -14,7 +14,7 @@ const std::string policy::FileTable::Name = "File"; ...@@ -14,7 +14,7 @@ const std::string policy::FileTable::Name = "File";
const std::string policy::FileTable::CacheColumn = "mrl"; const std::string policy::FileTable::CacheColumn = "mrl";
unsigned int File::* const policy::FileTable::PrimaryKey = &File::m_id; unsigned int File::* const policy::FileTable::PrimaryKey = &File::m_id;
File::File( sqlite3* dbConnection, sqlite3_stmt* stmt ) File::File( DBConnection dbConnection, sqlite3_stmt* stmt )
: m_dbConnection( dbConnection ) : m_dbConnection( dbConnection )
{ {
m_id = sqlite3_column_int( stmt, 0 ); m_id = sqlite3_column_int( stmt, 0 );
...@@ -28,8 +28,7 @@ File::File( sqlite3* dbConnection, sqlite3_stmt* stmt ) ...@@ -28,8 +28,7 @@ File::File( sqlite3* dbConnection, sqlite3_stmt* stmt )
} }
File::File( const std::string& mrl ) File::File( const std::string& mrl )
: m_dbConnection( nullptr ) : m_id( 0 )
, m_id( 0 )
, m_type( UnknownType ) , m_type( UnknownType )
, m_duration( 0 ) , m_duration( 0 )
, m_albumTrackId( 0 ) , m_albumTrackId( 0 )
...@@ -40,7 +39,7 @@ File::File( const std::string& mrl ) ...@@ -40,7 +39,7 @@ File::File( const std::string& mrl )
{ {
} }
FilePtr File::create( sqlite3* dbConnection, const std::string& mrl ) FilePtr File::create( DBConnection dbConnection, const std::string& mrl )
{ {
auto self = std::make_shared<File>( mrl ); auto self = std::make_shared<File>( mrl );
static const std::string req = "INSERT INTO " + policy::FileTable::Name + static const std::string req = "INSERT INTO " + policy::FileTable::Name +
...@@ -142,7 +141,7 @@ unsigned int File::id() const ...@@ -142,7 +141,7 @@ unsigned int File::id() const
return m_id; return m_id;
} }
bool File::createTable(sqlite3* connection) bool File::createTable( DBConnection connection )
{ {
std::string req = "CREATE TABLE IF NOT EXISTS " + policy::FileTable::Name + "(" std::string req = "CREATE TABLE IF NOT EXISTS " + policy::FileTable::Name + "("
"id_file INTEGER PRIMARY KEY AUTOINCREMENT," "id_file INTEGER PRIMARY KEY AUTOINCREMENT,"
...@@ -165,7 +164,7 @@ bool File::createTable(sqlite3* connection) ...@@ -165,7 +164,7 @@ bool File::createTable(sqlite3* connection)
bool File::addLabel( LabelPtr label ) bool File::addLabel( LabelPtr label )
{ {
if ( m_dbConnection == nullptr || m_id == 0 || label->id() == 0) if ( m_id == 0 || label->id() == 0 )
{ {
std::cerr << "Both file & label need to be inserted in database before being linked together" << std::endl; std::cerr << "Both file & label need to be inserted in database before being linked together" << std::endl;
return false; return false;
...@@ -176,7 +175,7 @@ bool File::addLabel( LabelPtr label ) ...@@ -176,7 +175,7 @@ bool File::addLabel( LabelPtr label )
bool File::removeLabel( LabelPtr label ) bool File::removeLabel( LabelPtr label )
{ {
if ( m_dbConnection == nullptr || m_id == 0 || label->id() == 0 ) if ( m_id == 0 || label->id() == 0 )
{ {
std::cerr << "Can't unlink a label/file not inserted in database" << std::endl; std::cerr << "Can't unlink a label/file not inserted in database" << std::endl;
return false; return false;
......
...@@ -39,11 +39,11 @@ class File : public IFile, public Cache<File, IFile, policy::FileTable, policy:: ...@@ -39,11 +39,11 @@ class File : public IFile, public Cache<File, IFile, policy::FileTable, policy::
// ::new (pv) T(std::forward(args)...) // ::new (pv) T(std::forward(args)...)
// shall be well-formed, and private constructor would prevent that. // shall be well-formed, and private constructor would prevent that.
// There might be a way with a user-defined allocator, but we'll see that later... // There might be a way with a user-defined allocator, but we'll see that later...
File(sqlite3* dbConnection , sqlite3_stmt* stmt); File(DBConnection dbConnection , sqlite3_stmt* stmt);
File( const std::string& mrl ); File( const std::string& mrl );
static FilePtr create(sqlite3* dbConnection, const std::string& mrl ); static FilePtr create( DBConnection dbConnection, const std::string& mrl );
static bool createTable(sqlite3* connection); static bool createTable( DBConnection connection );
virtual unsigned int id() const; virtual unsigned int id() const;
virtual AlbumTrackPtr albumTrack(); virtual AlbumTrackPtr albumTrack();
...@@ -60,7 +60,7 @@ class File : public IFile, public Cache<File, IFile, policy::FileTable, policy:: ...@@ -60,7 +60,7 @@ class File : public IFile, public Cache<File, IFile, policy::FileTable, policy::
virtual bool setMovie( MoviePtr movie ); virtual bool setMovie( MoviePtr movie );
private: private:
sqlite3* m_dbConnection; DBConnection m_dbConnection;
// DB fields: // DB fields:
unsigned int m_id; unsigned int m_id;
......
...@@ -10,7 +10,7 @@ const std::string policy::LabelTable::Name = "Label"; ...@@ -10,7 +10,7 @@ const std::string policy::LabelTable::Name = "Label";
const std::string policy::LabelTable::CacheColumn = "name"; const std::string policy::LabelTable::CacheColumn = "name";
unsigned int Label::* const policy::LabelTable::PrimaryKey = &Label::m_id; unsigned int Label::* const policy::LabelTable::PrimaryKey = &Label::m_id;
Label::Label( sqlite3* dbConnection, sqlite3_stmt* stmt ) Label::Label( DBConnection dbConnection, sqlite3_stmt* stmt )
: m_dbConnection( dbConnection ) : m_dbConnection( dbConnection )
{ {
m_id = sqlite3_column_int( stmt, 0 ); m_id = sqlite3_column_int( stmt, 0 );
...@@ -18,8 +18,7 @@ Label::Label( sqlite3* dbConnection, sqlite3_stmt* stmt ) ...@@ -18,8 +18,7 @@ Label::Label( sqlite3* dbConnection, sqlite3_stmt* stmt )
} }
Label::Label( const std::string& name ) Label::Label( const std::string& name )
: m_dbConnection( nullptr ) : m_id( 0 )
, m_id( 0 )
, m_name( name ) , m_name( name )
{ {
} }
...@@ -42,7 +41,7 @@ bool Label::files( std::vector<FilePtr>& files ) ...@@ -42,7 +41,7 @@ bool Label::files( std::vector<FilePtr>& files )
return SqliteTools::fetchAll<File>( m_dbConnection, req, files, m_id ); return SqliteTools::fetchAll<File>( m_dbConnection, req, files, m_id );
} }
LabelPtr Label::create( sqlite3* dbConnection, const std::string& name ) LabelPtr Label::create(DBConnection dbConnection, const std::string& name )
{ {
auto self = std::make_shared<Label>( name ); auto self = std::make_shared<Label>( name );
const char* req = "INSERT INTO Label VALUES(NULL, ?)"; const char* req = "INSERT INTO Label VALUES(NULL, ?)";
...@@ -52,7 +51,7 @@ LabelPtr Label::create( sqlite3* dbConnection, const std::string& name ) ...@@ -52,7 +51,7 @@ LabelPtr Label::create( sqlite3* dbConnection, const std::string& name )
return self; return self;
} }
bool Label::createTable(sqlite3* dbConnection) bool Label::createTable(DBConnection dbConnection)
{ {
std::string req = "CREATE TABLE IF NOT EXISTS " + policy::LabelTable::Name + "(" std::string req = "CREATE TABLE IF NOT EXISTS " + policy::LabelTable::Name + "("
"id_label INTEGER PRIMARY KEY AUTOINCREMENT, " "id_label INTEGER PRIMARY KEY AUTOINCREMENT, "
......
...@@ -33,7 +33,7 @@ class Label : public ILabel, public Cache<Label, ILabel, policy::LabelTable, pol ...@@ -33,7 +33,7 @@ class Label : public ILabel, public Cache<Label, ILabel, policy::LabelTable, pol
private: private:
typedef Cache<Label, ILabel, policy::LabelTable, policy::LabelCachePolicy> _Cache; typedef Cache<Label, ILabel, policy::LabelTable, policy::LabelCachePolicy> _Cache;
public: public:
Label(sqlite3* dbConnection, sqlite3_stmt* stmt); Label( DBConnection dbConnection, sqlite3_stmt* stmt);
Label( const std::string& name ); Label( const std::string& name );
public: public:
...@@ -41,10 +41,10 @@ class Label : public ILabel, public Cache<Label, ILabel, policy::LabelTable, pol ...@@ -41,10 +41,10 @@ class Label : public ILabel, public Cache<Label, ILabel, policy::LabelTable, pol
virtual const std::string& name(); virtual const std::string& name();
virtual bool files( std::vector<FilePtr>& files ); virtual bool files( std::vector<FilePtr>& files );
static LabelPtr create(sqlite3* dbConnection, const std::string& name ); static LabelPtr create( DBConnection dbConnection, const std::string& name );
static bool createTable( sqlite3* dbConnection ); static bool createTable( DBConnection dbConnection );
private: private:
sqlite3* m_dbConnection; DBConnection m_dbConnection;
unsigned int m_id; unsigned int m_id;
std::string m_name; std::string m_name;
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "ShowEpisode.h" #include "ShowEpisode.h"
MediaLibrary::MediaLibrary() MediaLibrary::MediaLibrary()
: m_dbConnection( nullptr )
{ {
} }
...@@ -26,15 +25,16 @@ MediaLibrary::~MediaLibrary() ...@@ -26,15 +25,16 @@ MediaLibrary::~MediaLibrary()
Show::clear(); Show::clear();
ShowEpisode::clear(); ShowEpisode::clear();
Movie::clear(); Movie::clear();
sqlite3_close( m_dbConnection );
} }
bool MediaLibrary::initialize(const std::string& dbPath) bool MediaLibrary::initialize(const std::string& dbPath)
{ {
int res = sqlite3_open( dbPath.c_str(), &m_dbConnection ); sqlite3* dbConnection;
int res = sqlite3_open( dbPath.c_str(), &dbConnection );
if ( res != SQLITE_OK ) if ( res != SQLITE_OK )
return false; return false;
if ( SqliteTools::executeRequest( m_dbConnection, "PRAGMA foreign_keys = ON" ) == false ) m_dbConnection.reset( dbConnection, &sqlite3_close );
if ( SqliteTools::executeRequest( DBConnection(m_dbConnection), "PRAGMA foreign_keys = ON" ) == false )
return false; return false;
return ( File::createTable( m_dbConnection ) && return ( File::createTable( m_dbConnection ) &&
Label::createTable( m_dbConnection ) && Label::createTable( m_dbConnection ) &&
...@@ -91,7 +91,7 @@ AlbumPtr MediaLibrary::album( const std::string& id3Tag ) ...@@ -91,7 +91,7 @@ AlbumPtr MediaLibrary::album( const std::string& id3Tag )
// We can't use Cache helper, since albums are cached by primary keys // We can't use Cache helper, since albums are cached by primary keys
static const std::string req = "SELECT * FROM " + policy::AlbumTable::Name + static const std::string req = "SELECT * FROM " + policy::AlbumTable::Name +
" WHERE id3tag = ?"; " WHERE id3tag = ?";
return SqliteTools::fetchOne<Album>( m_dbConnection, req, id3Tag ); return SqliteTools::fetchOne<Album>( DBConnection( m_dbConnection ), req, id3Tag );
} }
AlbumPtr MediaLibrary::createAlbum( const std::string& id3Tag ) AlbumPtr MediaLibrary::createAlbum( const std::string& id3Tag )
......
...@@ -33,7 +33,7 @@ class MediaLibrary : public IMediaLibrary ...@@ -33,7 +33,7 @@ class MediaLibrary : public IMediaLibrary
virtual void addMetadataService( IMetadataService* service ); virtual void addMetadataService( IMetadataService* service );
private: private:
sqlite3* m_dbConnection; std::shared_ptr<sqlite3> m_dbConnection;
std::vector<std::unique_ptr<IMetadataService>> m_mdServices; std::vector<std::unique_ptr<IMetadataService>> m_mdServices;
}; };
#endif // MEDIALIBRARY_H #endif // MEDIALIBRARY_H
...@@ -6,7 +6,7 @@ const std::string policy::MovieTable::Name = "Movie"; ...@@ -6,7 +6,7 @@ const std::string policy::MovieTable::Name = "Movie";
const std::string policy::MovieTable::CacheColumn = "id_movie"; const std::string policy::MovieTable::CacheColumn = "id_movie";
unsigned int Movie::* const policy::MovieTable::PrimaryKey = &Movie::m_id; unsigned int Movie::* const policy::MovieTable::PrimaryKey = &Movie::m_id;
Movie::Movie( sqlite3* dbConnection, sqlite3_stmt* stmt ) Movie::Movie( DBConnection dbConnection, sqlite3_stmt* stmt )
: m_dbConnection( dbConnection ) : m_dbConnection( dbConnection )
{ {
m_id = Traits<unsigned int>::Load( stmt, 0 ); m_id = Traits<unsigned int>::Load( stmt, 0 );
...@@ -18,8 +18,7 @@ Movie::Movie( sqlite3* dbConnection, sqlite3_stmt* stmt ) ...@@ -18,8 +18,7 @@ Movie::Movie( sqlite3* dbConnection, sqlite3_stmt* stmt )
} }
Movie::Movie( const std::string& title ) Movie::Movie( const std::string& title )
: m_dbConnection( nullptr ) : m_id( 0 )
, m_id( 0 )
, m_title( title ) , m_title( title )
, m_releaseDate( 0 ) , m_releaseDate( 0 )
{ {
...@@ -115,7 +114,7 @@ bool Movie::files( std::vector<FilePtr>& files ) ...@@ -115,7 +114,7 @@ bool Movie::files( std::vector<FilePtr>& files )
return SqliteTools::fetchAll<File>( m_dbConnection, req, files, m_id ); return SqliteTools::fetchAll<File>( m_dbConnection, req, files, m_id );
} }
bool Movie::createTable( sqlite3* dbConnection ) bool Movie::createTable( DBConnection dbConnection )
{ {
static const std::string req = "CREATE TABLE IF NOT EXISTS " + policy::MovieTable::Name static const std::string req = "CREATE TABLE IF NOT EXISTS " + policy