Commit 3287620b authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Move SqliteTable in its own header

parent e9f2b4d8
......@@ -29,7 +29,7 @@
#include "IMediaLibrary.h"
#include "database/Cache.h"
#include "database/SqliteTable.h"
#include "IAlbum.h"
class Album;
......
......@@ -28,7 +28,7 @@
#include "IAlbumTrack.h"
#include "IMediaLibrary.h"
#include "database/Cache.h"
#include "database/SqliteTable.h"
class Album;
class AlbumTrack;
......
......@@ -22,7 +22,7 @@
#pragma once
#include "database/Cache.h"
#include "database/SqliteTable.h"
#include "IArtist.h"
#include "IMediaLibrary.h"
......
......@@ -25,7 +25,7 @@
#include "IAudioTrack.h"
#include "IMediaLibrary.h"
#include "database/Cache.h"
#include "database/SqliteTable.h"
class AudioTrack;
......
......@@ -22,7 +22,7 @@
#pragma once
#include "database/Cache.h"
#include "database/SqliteTable.h"
#include "IFolder.h"
#include <sqlite3.h>
......
......@@ -30,7 +30,7 @@ class Media;
class Label;
#include "ILabel.h"
#include "database/Cache.h"
#include "database/SqliteTable.h"
namespace policy
{
......
......@@ -27,7 +27,7 @@
#include <sqlite3.h>
#include "IMedia.h"
#include "database/Cache.h"
#include "database/SqliteTable.h"
class Album;
......
......@@ -25,7 +25,7 @@
#include "IMovie.h"
#include <sqlite3.h>
#include "database/Cache.h"
#include "database/SqliteTable.h"
class Movie;
......
......@@ -25,7 +25,7 @@
#include <sqlite3.h>
#include "database/Cache.h"
#include "database/SqliteTable.h"
#include "IMediaLibrary.h"
#include "IShow.h"
......
......@@ -31,7 +31,7 @@ class ShowEpisode;
#include "IMediaLibrary.h"
#include "IShowEpisode.h"
#include "database/Cache.h"
#include "database/SqliteTable.h"
namespace policy
{
......
......@@ -23,7 +23,7 @@
#ifndef VIDEOTRACK_H
#define VIDEOTRACK_H
#include "database/Cache.h"
#include "database/SqliteTable.h"
#include "IVideoTrack.h"
#include <sqlite3.h>
......
......@@ -108,126 +108,4 @@ template <typename IMPL, typename CACHEPOLICY>
std::recursive_mutex Cache<IMPL, CACHEPOLICY>::Mutex;
/**
* This utility class eases up the implementation of caching.
*
* It is driven by 2 policy classes:
* - TABLEPOLICY describes the basics required to fetch a record. It has 2 static fields:
* - Name: the table name
* - CacheColumn: The column used to cache records.
* - CACHEPOLICY describes which column to use for caching by providing two "key" methods.
* One that takes a sqlite::Row and one that takes an instance of the type being cached
*
* The default CACHEPOLICY implementation bases itself on an unsigned int column, assumed
* to be the primary key, at index 0 of a fetch statement.
*
* Other template parameter:
* - IMPL: The actual implementation. Typically the type that inherits this class
* - INTF: An interface that express the type. This is used when fetching containers, as they
* are not polymorphic.
*
* How to use it:
* - Inherit this class and specify the template parameter & policies accordingly
* - Make this class a friend class of the class you inherit from
*/
template <typename IMPL, typename TABLEPOLICY, typename CACHEPOLICY = PrimaryKeyCacheKeyPolicy >
class Table
{
using _Cache = Cache<IMPL, CACHEPOLICY>;
public:
static std::shared_ptr<IMPL> fetch( DBConnection dbConnection, const typename CACHEPOLICY::KeyType& key )
{
auto l = _Cache::lock();
auto res = _Cache::load( key );
if ( res != nullptr )
return res;
static const std::string req = "SELECT * FROM " + TABLEPOLICY::Name +
" WHERE " + TABLEPOLICY::CacheColumn + " = ?";
res = sqlite::Tools::fetchOne<IMPL>( dbConnection, req, key );
if ( res == nullptr )
return nullptr;
_Cache::store( res );
return res;
}
template <typename... Args>
static std::shared_ptr<IMPL> fetchOne( DBConnection dbConnection, const std::string& req, Args&&... args )
{
return sqlite::Tools::fetchOne<IMPL>( dbConnection, req, std::forward<Args>( args )... );
}
/*
* Will fetch all elements from the database & cache them.
*/
template <typename INTF = IMPL>
static std::vector<std::shared_ptr<INTF>> fetchAll( DBConnection dbConnection )
{
static const std::string req = "SELECT * FROM " + TABLEPOLICY::Name;
// Lock the cache mutex before attempting to acquire a context, otherwise
// we could have a thread locking cache then DB, and a thread locking DB then cache
auto l = _Cache::lock();
return sqlite::Tools::fetchAll<IMPL, INTF>( dbConnection, req );
}
template <typename INTF, typename... Args>
static std::vector<std::shared_ptr<INTF>> fetchAll( DBConnection dbConnection, const std::string &req, Args&&... args )
{
auto l = _Cache::lock();
return sqlite::Tools::fetchAll<IMPL, INTF>( dbConnection, req, std::forward<Args>( args )... );
}
static std::shared_ptr<IMPL> load( DBConnection dbConnection, sqlite::Row& row )
{
auto l = _Cache::lock();
auto res = _Cache::load( row );
if ( res != nullptr )
return res;
res = std::make_shared<IMPL>( dbConnection, row );
_Cache::store( res );
return res;
}
static bool destroy( DBConnection dbConnection, const typename CACHEPOLICY::KeyType& key )
{
auto l = _Cache::lock();
_Cache::discard( key );
static const std::string req = "DELETE FROM " + TABLEPOLICY::Name + " WHERE " +
TABLEPOLICY::CacheColumn + " = ?";
return sqlite::Tools::executeDelete( dbConnection, req, key );
}
template <typename T>
static bool destroy( DBConnection dbConnection, const T* self )
{
const auto& key = CACHEPOLICY::key( self );
return destroy( dbConnection, key );
}
static void clear()
{
auto l = _Cache::lock();
_Cache::clear();
}
protected:
/*
* Create a new instance of the cache class.
*/
template <typename... Args>
static bool insert( DBConnection dbConnection, std::shared_ptr<IMPL> self, const std::string& req, Args&&... args )
{
auto l = _Cache::lock();
unsigned int pKey = sqlite::Tools::insert( dbConnection, req, std::forward<Args>( args )... );
if ( pKey == 0 )
return false;
(self.get())->*TABLEPOLICY::PrimaryKey = pKey;
_Cache::store( self );
return true;
}
};
#endif // CACHE_H
/*****************************************************************************
* Media Library
*****************************************************************************
* Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
*
* Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#pragma once
#include "Cache.h"
template <typename IMPL, typename TABLEPOLICY, typename CACHEPOLICY = PrimaryKeyCacheKeyPolicy >
class Table
{
using _Cache = Cache<IMPL, CACHEPOLICY>;
public:
static std::shared_ptr<IMPL> fetch( DBConnection dbConnection, const typename CACHEPOLICY::KeyType& key )
{
auto l = _Cache::lock();
auto res = _Cache::load( key );
if ( res != nullptr )
return res;
static const std::string req = "SELECT * FROM " + TABLEPOLICY::Name +
" WHERE " + TABLEPOLICY::CacheColumn + " = ?";
res = sqlite::Tools::fetchOne<IMPL>( dbConnection, req, key );
if ( res == nullptr )
return nullptr;
_Cache::store( res );
return res;
}
template <typename... Args>
static std::shared_ptr<IMPL> fetchOne( DBConnection dbConnection, const std::string& req, Args&&... args )
{
return sqlite::Tools::fetchOne<IMPL>( dbConnection, req, std::forward<Args>( args )... );
}
/*
* Will fetch all elements from the database & cache them.
*/
template <typename INTF = IMPL>
static std::vector<std::shared_ptr<INTF>> fetchAll( DBConnection dbConnection )
{
static const std::string req = "SELECT * FROM " + TABLEPOLICY::Name;
// Lock the cache mutex before attempting to acquire a context, otherwise
// we could have a thread locking cache then DB, and a thread locking DB then cache
auto l = _Cache::lock();
return sqlite::Tools::fetchAll<IMPL, INTF>( dbConnection, req );
}
template <typename INTF, typename... Args>
static std::vector<std::shared_ptr<INTF>> fetchAll( DBConnection dbConnection, const std::string &req, Args&&... args )
{
auto l = _Cache::lock();
return sqlite::Tools::fetchAll<IMPL, INTF>( dbConnection, req, std::forward<Args>( args )... );
}
static std::shared_ptr<IMPL> load( DBConnection dbConnection, sqlite::Row& row )
{
auto l = _Cache::lock();
auto res = _Cache::load( row );
if ( res != nullptr )
return res;
res = std::make_shared<IMPL>( dbConnection, row );
_Cache::store( res );
return res;
}
static bool destroy( DBConnection dbConnection, const typename CACHEPOLICY::KeyType& key )
{
auto l = _Cache::lock();
_Cache::discard( key );
static const std::string req = "DELETE FROM " + TABLEPOLICY::Name + " WHERE " +
TABLEPOLICY::CacheColumn + " = ?";
return sqlite::Tools::executeDelete( dbConnection, req, key );
}
template <typename T>
static bool destroy( DBConnection dbConnection, const T* self )
{
const auto& key = CACHEPOLICY::key( self );
return destroy( dbConnection, key );
}
static void clear()
{
auto l = _Cache::lock();
_Cache::clear();
}
protected:
/*
* Create a new instance of the cache class.
*/
template <typename... Args>
static bool insert( DBConnection dbConnection, std::shared_ptr<IMPL> self, const std::string& req, Args&&... args )
{
auto l = _Cache::lock();
unsigned int pKey = sqlite::Tools::insert( dbConnection, req, std::forward<Args>( args )... );
if ( pKey == 0 )
return false;
(self.get())->*TABLEPOLICY::PrimaryKey = pKey;
_Cache::store( self );
return true;
}
};
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