Commit 4bb34515 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Request execution simplifications

parent b15b8969
......@@ -63,5 +63,5 @@ bool Album::createTable( sqlite3* dbConnection )
"artwork_url TEXT,"
"UNSIGNED INTEGER last_sync_date"
")";
return SqliteTools::createTable( dbConnection, req );
return SqliteTools::executeRequest( dbConnection, req );
}
......@@ -26,7 +26,7 @@ bool AlbumTrack::createTable(sqlite3* dbConnection)
"album_id UNSIGNED INTEGER NOT NULL,"
"FOREIGN KEY (album_id) REFERENCES Album(id_album) ON DELETE CASCADE"
")";
return SqliteTools::createTable( dbConnection, req );
return SqliteTools::executeRequest( dbConnection, req );
}
const std::string& AlbumTrack::genre()
......
......@@ -23,7 +23,6 @@ include_directories("${CMAKE_SOURCE_DIR}/include")
list(APPEND SRC_LIST ${HEADERS_LIST}
MediaLibrary.cpp
SqliteTools.cpp
File.cpp
Album.cpp
Show.cpp
......
......@@ -112,7 +112,7 @@ class Cache
Store.erase( it );
static const std::string req = "DELETE FROM " + TABLEPOLICY::Name + " WHERE " +
TABLEPOLICY::CacheColumn + " = ?";
return SqliteTools::destroy( dbConnection, req.c_str(), key );
return SqliteTools::executeDelete( dbConnection, req.c_str(), key );
}
private:
......
......@@ -40,22 +40,10 @@ bool File::insert( sqlite3* dbConnection )
{
assert( m_dbConnection == NULL );
assert( m_id == 0 );
sqlite3_stmt* stmt;
static const std::string req = "INSERT INTO " + policy::FileTable::Name +
" VALUES(NULL, ?, ?, ?, ?, ?, ?)";
if ( sqlite3_prepare_v2( dbConnection, req.c_str(), -1, &stmt, NULL ) != SQLITE_OK )
{
std::cerr << "Failed to insert record: " << sqlite3_errmsg( dbConnection ) << std::endl;
return false;
}
const char* tmpMrl = strdup( m_mrl.c_str() );
sqlite3_bind_int( stmt, 1, m_type );
sqlite3_bind_int( stmt, 2, m_duration );
sqlite3_bind_int( stmt, 3, m_albumTrackId );
sqlite3_bind_int( stmt, 4, m_playCount );
sqlite3_bind_int( stmt, 5, m_showEpisodeId );
sqlite3_bind_text( stmt, 6, tmpMrl, -1, &free );
if ( sqlite3_step( stmt ) != SQLITE_DONE )
if ( SqliteTools::executeRequest( dbConnection, req.c_str(), (int)m_type, m_duration,
m_albumTrackId, m_playCount, m_showEpisodeId, m_mrl ) == false )
return false;
m_id = sqlite3_last_insert_rowid( dbConnection );
m_dbConnection = dbConnection;
......@@ -121,11 +109,10 @@ bool File::createTable(sqlite3* connection)
"show_episode_id UNSIGNED INTEGER,"
"mrl TEXT UNIQUE ON CONFLICT FAIL"
")";
if ( SqliteTools::createTable( connection, req.c_str() ) == false )
if ( SqliteTools::executeRequest( connection, req.c_str() ) == false )
return false;
req = "CREATE INDEX file_index ON " + policy::FileTable::Name + " (mrl)";
auto stmt = SqliteTools::executeRequest( connection, req.c_str() );
return sqlite3_step( stmt.get() ) == SQLITE_DONE;
return SqliteTools::executeRequest( connection, req.c_str() );
}
bool File::addLabel( LabelPtr label )
......@@ -136,17 +123,7 @@ bool File::addLabel( LabelPtr label )
return false;
}
const char* req = "INSERT INTO LabelFileRelation VALUES(?, ?)";
sqlite3_stmt* stmt;
if ( sqlite3_prepare_v2( m_dbConnection, req, -1, &stmt, NULL ) != SQLITE_OK )
{
std::cerr << "Failed to insert record: " << sqlite3_errmsg( m_dbConnection ) << std::endl;
return false;
}
sqlite3_bind_int( stmt, 1, label->id() );
sqlite3_bind_int( stmt, 2, m_id );
bool res = sqlite3_step( stmt ) == SQLITE_DONE;
sqlite3_finalize( stmt );
return res;
return SqliteTools::executeRequest( m_dbConnection, req, label->id(), m_id );
}
bool File::removeLabel( LabelPtr label )
......@@ -157,17 +134,7 @@ bool File::removeLabel( LabelPtr label )
return false;
}
const char* req = "DELETE FROM LabelFileRelation WHERE id_label = ? AND id_file = ?";
sqlite3_stmt* stmt;
if ( sqlite3_prepare_v2( m_dbConnection, req, -1, &stmt, NULL ) != SQLITE_OK )
{
std::cerr << "Failed to remove record: " << sqlite3_errmsg( m_dbConnection ) << std::endl;
return false;
}
sqlite3_bind_int( stmt, 1, label->id() );
sqlite3_bind_int( stmt, 2, m_id );
sqlite3_step( stmt );
sqlite3_finalize( stmt );
return sqlite3_changes( m_dbConnection ) > 0;
return SqliteTools::executeDelete( m_dbConnection, req, label->id(), m_id );
}
const std::string& policy::FileCache::key(const std::shared_ptr<File> self )
......
......@@ -53,16 +53,8 @@ bool Label::insert( sqlite3* dbConnection )
{
assert( m_dbConnection == nullptr );
assert( m_id == 0 );
sqlite3_stmt* stmt;
const char* req = "INSERT INTO Label VALUES(NULL, ?)";
if ( sqlite3_prepare_v2( dbConnection, req, -1, &stmt, NULL ) != SQLITE_OK )
{
std::cerr << "Failed to insert record: " << sqlite3_errmsg( dbConnection ) << std::endl;
return false;
}
char* tmpName = strdup( m_name.c_str() );
sqlite3_bind_text( stmt, 1, tmpName, -1, &free );
if ( sqlite3_step( stmt ) != SQLITE_DONE )
if ( SqliteTools::executeRequest( dbConnection, req, m_name ) == false )
return false;
m_dbConnection = dbConnection;
m_id = sqlite3_last_insert_rowid( dbConnection );
......@@ -75,24 +67,19 @@ bool Label::createTable(sqlite3* dbConnection)
"id_label INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT UNIQUE ON CONFLICT FAIL"
")";
if ( SqliteTools::createTable( dbConnection, req.c_str() ) == false )
if ( SqliteTools::executeRequest( dbConnection, req.c_str() ) == false )
return false;
//FIXME: Check for a better way when addressing transactions
req = "CREATE INDEX label_index ON " + policy::LabelTable::Name + " (name)";
{
auto stmt = SqliteTools::executeRequest( dbConnection, req.c_str() );
if ( stmt == nullptr )
return false;
if ( sqlite3_step( stmt.get() ) != SQLITE_DONE )
return false;
}
if ( SqliteTools::executeRequest( dbConnection, req.c_str() ) == false )
return false;
req = "CREATE TABLE IF NOT EXISTS LabelFileRelation("
"id_label INTEGER,"
"id_file INTEGER,"
"PRIMARY KEY (id_label, id_file)"
"FOREIGN KEY(id_label) REFERENCES Label(id_label) ON DELETE CASCADE,"
"FOREIGN KEY(id_file) REFERENCES File(id_file) ON DELETE CASCADE);";
return SqliteTools::createTable( dbConnection, req.c_str() );
return SqliteTools::executeRequest( dbConnection, req.c_str() );
}
......
......@@ -18,9 +18,7 @@ bool MediaLibrary::initialize(const std::string& dbPath)
// PRAGMA foreign_keys = ON;
if ( res != SQLITE_OK )
return false;
sqlite3_stmt* stmt;
sqlite3_prepare_v2( m_dbConnection, "PRAGMA foreign_keys = ON", -1, &stmt, NULL );
if ( sqlite3_step( stmt ) != SQLITE_DONE )
if ( SqliteTools::executeRequest( m_dbConnection, "PRAGMA foreign_keys = ON" ) == false )
return false;
return ( File::createTable( m_dbConnection ) &&
Label::createTable( m_dbConnection ) &&
......
......@@ -62,5 +62,5 @@ bool Show::createTable(sqlite3* dbConnection)
"last_sync_date UNSIGNED INTEGER,"
"tvdb_id TEXT"
")";
return SqliteTools::createTable( dbConnection, req );
return SqliteTools::executeRequest( dbConnection, req );
}
......@@ -78,5 +78,5 @@ bool ShowEpisode::createTable(sqlite3* dbConnection)
"show_id UNSIGNED INT,"
"FOREIGN KEY(show_id) REFERENCES Show(id_show)"
")";
return SqliteTools::createTable( dbConnection, req );
return SqliteTools::executeRequest( dbConnection, req );
}
#include <iostream>
#include "SqliteTools.h"
bool SqliteTools::createTable( sqlite3 *db, const char* request )
{
auto stmt = executeRequest( db, request );
int res = sqlite3_step( stmt.get() );
while ( res != SQLITE_DONE && res != SQLITE_ERROR )
res = sqlite3_step( stmt.get() );
if ( res == SQLITE_ERROR )
{
std::cerr << "Failed to execute request: " << request << std::endl;
std::cerr << sqlite3_errmsg( db ) << std::endl;
}
return res == SQLITE_DONE;
}
......@@ -42,8 +42,6 @@ class SqliteTools
private:
typedef std::unique_ptr<sqlite3_stmt, int (*)(sqlite3_stmt*)> StmtPtr;
public:
static bool createTable(sqlite3* db, const char* request );
/**
* Will fetch all records of type IMPL and return them as a shared_ptr to INTF
* This WILL add all fetched records to the cache
......@@ -55,7 +53,7 @@ class SqliteTools
static bool fetchAll( sqlite3* dbConnection, const char* req, std::vector<std::shared_ptr<INTF> >& results, const Args&... args )
{
results.clear();
auto stmt = executeRequest( dbConnection, req, args...);
auto stmt = prepareRequest( dbConnection, req, args...);
if ( stmt == nullptr )
return false;
int res = sqlite3_step( stmt.get() );
......@@ -72,7 +70,7 @@ class SqliteTools
static std::shared_ptr<T> fetchOne( sqlite3* dbConnection, const char* req, const Args&... args )
{
std::shared_ptr<T> result;
auto stmt = executeRequest( dbConnection, req, args... );
auto stmt = prepareRequest( dbConnection, req, args... );
if ( stmt == nullptr )
return nullptr;
if ( sqlite3_step( stmt.get() ) != SQLITE_ROW )
......@@ -82,24 +80,40 @@ class SqliteTools
}
template <typename... Args>
static bool destroy( sqlite3* dbConnection, const char* req, const Args&... args )
static bool executeDelete( sqlite3* dbConnection, const char* req, const Args&... args )
{
auto stmt = executeRequest( dbConnection, req, args... );
if ( stmt == nullptr )
if ( executeRequest( dbConnection, req, args... ) == false )
return false;
sqlite3_step( stmt.get() );
return sqlite3_changes( dbConnection ) > 0;
}
/**
* This is meant to be used for "write only" requests, as the statement is not
* exposed to the caller.
*/
template <typename... Args>
static StmtPtr executeRequest( sqlite3* dbConnection, const char* req, const Args&... args )
static bool executeRequest( sqlite3* dbConnection, const char* req, const Args&... args )
{
return _executeRequest<1>( dbConnection, req, args... );
auto stmt = prepareRequest( dbConnection, req, args... );
if ( stmt == nullptr )
return false;
int res;
do
{
res = sqlite3_step( stmt.get() );
} while ( res != SQLITE_DONE && res != SQLITE_ERROR );
return res == SQLITE_DONE;
}
private:
template <typename... Args>
static StmtPtr prepareRequest( sqlite3* dbConnection, const char* req, const Args&... args )
{
return _prepareRequest<1>( dbConnection, req, args... );
}
template <unsigned int>
static StmtPtr _executeRequest( sqlite3* dbConnection, const char* req )
static StmtPtr _prepareRequest( sqlite3* dbConnection, const char* req )
{
sqlite3_stmt* stmt = nullptr;
int res = sqlite3_prepare_v2( dbConnection, req, -1, &stmt, NULL );
......@@ -112,9 +126,9 @@ class SqliteTools
}
template <unsigned int COLIDX, typename T, typename... Args>
static StmtPtr _executeRequest( sqlite3* dbConnection, const char* req, const T& arg, const Args&... args )
static StmtPtr _prepareRequest( sqlite3* dbConnection, const char* req, const T& arg, const Args&... args )
{
auto stmt = _executeRequest<COLIDX + 1>( dbConnection, req, args... );
auto stmt = _prepareRequest<COLIDX + 1>( dbConnection, req, args... );
Traits<T>::Bind( stmt.get(), COLIDX, arg );
return stmt;
}
......
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