Commit 401d7926 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Allow multiple types to be used as the key in fetch helpers

parent 47e31d2e
......@@ -37,7 +37,7 @@ const std::vector<IFile*>& MediaLibrary::files()
if ( m_files == NULL )
{
const char* req = "SELECT * FROM File";
SqliteTools::fetchAll<File>( m_dbConnection, req, 0, m_files );
SqliteTools::fetchAll<File>( m_dbConnection, req, m_files );
}
return *m_files;
}
......
#ifndef SQLITETOOLS_H
#define SQLITETOOLS_H
#include <cstring>
#include <sqlite3.h>
#include <string>
#include <vector>
#include <iostream>
template <typename T>
struct TypeHelper
{
static const T Default = {};
};
// Have a base case for integral type only
// Use specialization to define other cases, and fail for the rest.
template <typename T>
struct Traits
{
static constexpr
typename std::enable_if<std::is_integral<T>::value, int>::type
(*Bind)(sqlite3_stmt *, int, int) = &sqlite3_bind_int;
};
template <>
struct Traits<std::string>
{
static int Bind(sqlite3_stmt* stmt, int pos, const std::string& value )
{
char* tmp = strdup( value.c_str() );
sqlite3_bind_text( stmt, pos, tmp, -1, free );
}
};
class SqliteTools
{
public:
static bool createTable(sqlite3* db, const char* request );
template <typename T, typename U>
static bool fetchAll( sqlite3* dbConnection, const char* req, unsigned int foreignKey, std::vector<U*>*& results)
template <typename T, typename U, typename KEYTYPE>
static bool fetchAll( sqlite3* dbConnection, const char* req, const KEYTYPE& foreignKey, std::vector<U*>*& results)
{
results = new std::vector<U*>;
sqlite3_stmt* stmt;
......@@ -23,8 +50,8 @@ class SqliteTools
std::cerr << sqlite3_errmsg( dbConnection ) << std::endl;
return false;
}
if ( foreignKey != 0 )
sqlite3_bind_int( stmt, 1, foreignKey );
if ( foreignKey != TypeHelper<KEYTYPE>::Default )
Traits<KEYTYPE>::Bind( stmt, 1, foreignKey );
res = sqlite3_step( stmt );
while ( res == SQLITE_ROW )
{
......@@ -36,8 +63,14 @@ class SqliteTools
return true;
}
template <typename T>
static T* fetchOne( sqlite3* dbConnection, const char* req, unsigned int primaryKey )
template <typename T, typename U>
static bool fetchAll( sqlite3* dbConnection, const char* req, std::vector<U*>*& results)
{
return fetchAll<T, U>( dbConnection, req, 0, results );
}
template <typename T, typename KEYTYPE>
static T* fetchOne( sqlite3* dbConnection, const char* req, const KEYTYPE& primaryKey )
{
T* result = NULL;
sqlite3_stmt *stmt;
......@@ -48,7 +81,7 @@ class SqliteTools
std::cerr << sqlite3_errmsg( dbConnection ) << std::endl;
return result;
}
sqlite3_bind_int( stmt, 1, primaryKey );
Traits<KEYTYPE>::Bind( stmt, 1, primaryKey );
if ( sqlite3_step( stmt ) != SQLITE_ROW )
return result;
result = new T( dbConnection, 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