summaryrefslogtreecommitdiff
path: root/src/database
diff options
context:
space:
mode:
Diffstat (limited to 'src/database')
-rw-r--r--src/database/index.hpp21
-rw-r--r--src/database/insert_query.hpp91
-rw-r--r--src/database/query.hpp41
-rw-r--r--src/database/row.hpp52
-rw-r--r--src/database/select_query.hpp77
-rw-r--r--src/database/table.hpp44
-rw-r--r--src/database/update_query.hpp51
7 files changed, 164 insertions, 213 deletions
diff --git a/src/database/index.hpp b/src/database/index.hpp
index 30766ab..094a36a 100644
--- a/src/database/index.hpp
+++ b/src/database/index.hpp
@@ -8,19 +8,16 @@
namespace
{
template <std::size_t N=0, typename... T>
-typename std::enable_if<N == sizeof...(T), void>::type
-add_column_name(std::string&)
-{ }
-
-template <std::size_t N=0, typename... T>
-typename std::enable_if<N < sizeof...(T), void>::type
-add_column_name(std::string& out)
+void add_column_name(std::string& out)
{
- using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<std::tuple<T...>>()))>::type;
- out += ColumnType::name;
- if (N != sizeof...(T) - 1)
- out += ",";
- add_column_name<N+1, T...>(out);
+ if constexpr(N < sizeof...(T))
+ {
+ using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<std::tuple<T...>>()))>::type;
+ out += ColumnType::name;
+ if (N != sizeof...(T) - 1)
+ out += ",";
+ add_column_name<N + 1, T...>(out);
+ }
}
}
diff --git a/src/database/insert_query.hpp b/src/database/insert_query.hpp
index 04c098c..ed1944f 100644
--- a/src/database/insert_query.hpp
+++ b/src/database/insert_query.hpp
@@ -11,20 +11,17 @@
#include <tuple>
template <std::size_t N=0, typename... T>
-typename std::enable_if<N < sizeof...(T), void>::type
-update_autoincrement_id(std::tuple<T...>& columns, Statement& statement)
+void update_autoincrement_id(std::tuple<T...>& columns, Statement& statement)
{
- using ColumnType = typename std::decay<decltype(std::get<N>(columns))>::type;
- if (std::is_same<ColumnType, Id>::value)
- auto&& column = std::get<Id>(columns);
- update_autoincrement_id<N+1>(columns, statement);
+ if constexpr(N < sizeof...(T))
+ {
+ using ColumnType = typename std::decay<decltype(std::get<N>(columns))>::type;
+ if (std::is_same<ColumnType, Id>::value)
+ auto&& column = std::get<Id>(columns);
+ update_autoincrement_id<N + 1>(columns, statement);
+ }
}
-template <std::size_t N=0, typename... T>
-typename std::enable_if<N == sizeof...(T), void>::type
-update_autoincrement_id(std::tuple<T...>&, Statement&)
-{}
-
struct InsertQuery: public Query
{
template <typename... T>
@@ -53,23 +50,20 @@ struct InsertQuery: public Query
}
template <int N=0, typename... T>
- typename std::enable_if<N < sizeof...(T), void>::type
- bind_param(const std::tuple<T...>& columns, Statement& statement, int index=1)
+ void bind_param(const std::tuple<T...>& columns, Statement& statement, int index=1)
{
- auto&& column = std::get<N>(columns);
- using ColumnType = std::decay_t<decltype(column)>;
+ if constexpr(N < sizeof...(T))
+ {
+ auto&& column = std::get<N>(columns);
+ using ColumnType = std::decay_t<decltype(column)>;
- if (!std::is_same<ColumnType, Id>::value)
- actual_bind(statement, column.value, index++);
+ if constexpr(!std::is_same<ColumnType, Id>::value)
+ actual_bind(statement, column.value, index++);
- this->bind_param<N+1>(columns, statement, index);
+ this->bind_param<N + 1>(columns, statement, index);
+ }
}
- template <int N=0, typename... T>
- typename std::enable_if<N == sizeof...(T), void>::type
- bind_param(const std::tuple<T...>&, Statement&, int)
- {}
-
template <typename... T>
void insert_values(const std::tuple<T...>& columns)
{
@@ -79,23 +73,21 @@ struct InsertQuery: public Query
}
template <int N=0, typename... T>
- typename std::enable_if<N < sizeof...(T), void>::type
- insert_value(const std::tuple<T...>& columns, int index=1)
+ void insert_value(const std::tuple<T...>& columns, int index=1)
{
- using ColumnType = std::decay_t<decltype(std::get<N>(columns))>;
-
- if (!std::is_same<ColumnType, Id>::value)
+ if constexpr(N < sizeof...(T))
{
- this->body += "$" + std::to_string(index++);
- if (N != sizeof...(T) - 1)
- this->body += ", ";
+ using ColumnType = std::decay_t<decltype(std::get<N>(columns))>;
+
+ if (!std::is_same<ColumnType, Id>::value)
+ {
+ this->body += "$" + std::to_string(index++);
+ if (N != sizeof...(T) - 1)
+ this->body += ", ";
+ }
+ this->insert_value<N + 1>(columns, index);
}
- this->insert_value<N+1>(columns, index);
}
- template <int N=0, typename... T>
- typename std::enable_if<N == sizeof...(T), void>::type
- insert_value(const std::tuple<T...>&, const int)
- { }
template <typename... T>
void insert_col_names(const std::tuple<T...>& columns)
@@ -106,24 +98,21 @@ struct InsertQuery: public Query
}
template <int N=0, typename... T>
- typename std::enable_if<N < sizeof...(T), void>::type
- insert_col_name(const std::tuple<T...>& columns)
+ void insert_col_name(const std::tuple<T...>& columns)
{
- using ColumnType = std::decay_t<decltype(std::get<N>(columns))>;
-
- if (!std::is_same<ColumnType, Id>::value)
+ if constexpr(N < sizeof...(T))
{
- this->body += ColumnType::name;
+ using ColumnType = std::decay_t<decltype(std::get<N>(columns))>;
- if (N < (sizeof...(T) - 1))
- this->body += ", ";
- }
+ if (!std::is_same<ColumnType, Id>::value)
+ {
+ this->body += ColumnType::name;
- this->insert_col_name<N+1>(columns);
- }
+ if (N < (sizeof...(T) - 1))
+ this->body += ", ";
+ }
- template <int N=0, typename... T>
- typename std::enable_if<N == sizeof...(T), void>::type
- insert_col_name(const std::tuple<T...>&)
- {}
+ this->insert_col_name<N + 1>(columns);
+ }
+ }
};
diff --git a/src/database/query.hpp b/src/database/query.hpp
index 1c4a5ff..2a2d2d4 100644
--- a/src/database/query.hpp
+++ b/src/database/query.hpp
@@ -13,12 +13,12 @@
void actual_bind(Statement& statement, const std::string& value, int index);
void actual_bind(Statement& statement, const std::int64_t& value, int index);
-template <typename T, typename std::enable_if_t<std::is_integral<T>::value>* = 0>
+void actual_bind(Statement& statement, const std::optional<bool>& value, int index);
+template <typename T>
void actual_bind(Statement& statement, const T& value, int index)
{
actual_bind(statement, static_cast<std::int64_t>(value), index);
}
-void actual_bind(Statement& statement, const std::optional<bool>& value, int index);
#ifdef DEBUG_SQL_QUERIES
#include <utils/scopetimer.hpp>
@@ -57,38 +57,27 @@ struct Query
#endif
};
-template <typename ColumnType>
-void add_param(Query& query, const ColumnType& column)
-{
- std::cout << "add_param<ColumnType>" << std::endl;
- actual_add_param(query, column.value);
-}
-
+void actual_add_param(Query& query, const std::string& val);
+void actual_add_param(Query& query, const std::optional<bool>& val);
template <typename T>
void actual_add_param(Query& query, const T& val)
{
query.params.push_back(std::to_string(val));
}
-void actual_add_param(Query& query, const std::string& val);
-
-template <typename T>
-typename std::enable_if<!std::is_integral<T>::value, Query&>::type
-operator<<(Query& query, const T&)
-{
- query.body += T::name;
- return query;
-}
-void actual_add_param(Query& query, const std::optional<bool>& val);
-
Query& operator<<(Query& query, const char* str);
Query& operator<<(Query& query, const std::string& str);
-template <typename Integer>
-typename std::enable_if<std::is_integral<Integer>::value, Query&>::type
-operator<<(Query& query, const Integer& i)
+template <typename T>
+Query& operator<<(Query& query, const T& i)
{
- query.body += "$" + std::to_string(query.current_param++);
- actual_add_param(query, i);
+ if constexpr(std::is_integral<T>::value)
+ {
+ query.body += "$" + std::to_string(query.current_param++);
+ actual_add_param(query, i);
+ }
+ else
+ {
+ query.body += T::name;
+ }
return query;
}
-
diff --git a/src/database/row.hpp b/src/database/row.hpp
index 3703ff7..194a9c5 100644
--- a/src/database/row.hpp
+++ b/src/database/row.hpp
@@ -29,41 +29,39 @@ struct Row
return col.value;
}
- template <bool Coucou=true>
- void save(std::unique_ptr<DatabaseEngine>& db, typename std::enable_if<!is_one_of<Id, T...> && Coucou>::type* = nullptr)
+ void save(std::unique_ptr<DatabaseEngine>& db)
{
- this->insert(*db);
- }
-
- template <bool Coucou=true>
- void save(std::unique_ptr<DatabaseEngine>& db, typename std::enable_if<is_one_of<Id, T...> && Coucou>::type* = nullptr)
- {
- const Id& id = std::get<Id>(this->columns);
- if (id.value == Id::unset_value)
+ if constexpr(is_one_of<Id, T...>)
{
- this->insert(*db);
- if (db->last_inserted_rowid >= 0)
- std::get<Id>(this->columns).value = static_cast<Id::real_type>(db->last_inserted_rowid);
+ const Id& id = std::get<Id>(this->columns);
+ if (id.value == Id::unset_value)
+ {
+ this->insert(*db);
+ if (db->last_inserted_rowid >= 0)
+ std::get<Id>(this->columns).value = static_cast<Id::real_type>(db->last_inserted_rowid);
+ }
+ else
+ this->update(*db);
}
else
- this->update(*db);
+ this->insert(*db);
}
private:
- template <bool Coucou=true>
- void insert(DatabaseEngine& db, typename std::enable_if<is_one_of<Id, T...> && Coucou>::type* = nullptr)
- {
- InsertQuery query(this->table_name, this->columns);
- // Ugly workaround for non portable stuff
- query.body += db.get_returning_id_sql_string(Id::name);
- query.execute(db, this->columns);
- }
-
- template <bool Coucou=true>
- void insert(DatabaseEngine& db, typename std::enable_if<!is_one_of<Id, T...> && Coucou>::type* = nullptr)
+ void insert(DatabaseEngine& db)
{
- InsertQuery query(this->table_name, this->columns);
- query.execute(db, this->columns);
+ if constexpr(is_one_of<Id, T...>)
+ {
+ InsertQuery query(this->table_name, this->columns);
+ // Ugly workaround for non portable stuff
+ query.body += db.get_returning_id_sql_string(Id::name);
+ query.execute(db, this->columns);
+ }
+ else
+ {
+ InsertQuery query(this->table_name, this->columns);
+ query.execute(db, this->columns);
+ }
}
void update(DatabaseEngine& db)
diff --git a/src/database/select_query.hpp b/src/database/select_query.hpp
index cd9943c..f7496a4 100644
--- a/src/database/select_query.hpp
+++ b/src/database/select_query.hpp
@@ -15,48 +15,37 @@
using namespace std::string_literals;
template <typename T>
-typename std::enable_if<std::is_integral<T>::value, std::int64_t>::type
-extract_row_value(Statement& statement, const int i)
+auto extract_row_value(Statement& statement, const int i)
{
- return statement.get_column_int64(i);
-}
-
-template <typename T>
-typename std::enable_if<std::is_same<std::string, T>::value, T>::type
-extract_row_value(Statement& statement, const int i)
-{
- return statement.get_column_text(i);
-}
-
-template <typename T>
-typename std::enable_if<std::is_same<std::optional<bool>, T>::value, T>::type
-extract_row_value(Statement& statement, const int i)
-{
- const auto integer = statement.get_column_int(i);
- if (integer > 0)
- return true;
- else if (integer < 0)
- return false;
- return std::nullopt;
+ if constexpr(std::is_integral<T>::value)
+ return statement.get_column_int64(i);
+ else if constexpr (std::is_same<std::string, T>::value)
+ return statement.get_column_text(i);
+ else if (std::is_same<std::optional<bool>, T>::value)
+ {
+ const auto integer = statement.get_column_int(i);
+ if (integer > 0)
+ return std::optional<bool>{true};
+ else if (integer < 0)
+ return std::optional<bool>{false};
+ return std::optional<bool>{};
+ }
}
template <std::size_t N=0, typename... T>
-typename std::enable_if<N < sizeof...(T), void>::type
-extract_row_values(Row<T...>& row, Statement& statement)
+void extract_row_values(Row<T...>& row, Statement& statement)
{
- using ColumnType = typename std::remove_reference<decltype(std::get<N>(row.columns))>::type;
+ if constexpr(N < sizeof...(T))
+ {
+ using ColumnType = typename std::remove_reference<decltype(std::get<N>(row.columns))>::type;
- auto&& column = std::get<N>(row.columns);
- column.value = static_cast<decltype(column.value)>(extract_row_value<typename ColumnType::real_type>(statement, N));
+ auto&& column = std::get<N>(row.columns);
+ column.value = static_cast<decltype(column.value)>(extract_row_value<typename ColumnType::real_type>(statement, N));
- extract_row_values<N+1>(row, statement);
+ extract_row_values<N + 1>(row, statement);
+ }
}
-template <std::size_t N=0, typename... T>
-typename std::enable_if<N == sizeof...(T), void>::type
-extract_row_values(Row<T...>&, Statement&)
-{}
-
template <typename... T>
struct SelectQuery: public Query
{
@@ -69,23 +58,21 @@ struct SelectQuery: public Query
}
template <std::size_t N=0>
- typename std::enable_if<N < sizeof...(T), void>::type
- insert_col_name()
+ void insert_col_name()
{
- using ColumnsType = std::tuple<T...>;
- using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnsType>()))>::type;
+ if constexpr(N < sizeof...(T))
+ {
+ using ColumnsType = std::tuple<T...>;
+ using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnsType>()))>::type;
- this->body += " " + std::string{ColumnType::name};
+ this->body += " " + std::string{ColumnType::name};
- if (N < (sizeof...(T) - 1))
- this->body += ", ";
+ if (N < (sizeof...(T) - 1))
+ this->body += ", ";
- this->insert_col_name<N+1>();
+ this->insert_col_name<N + 1>();
+ }
}
- template <std::size_t N=0>
- typename std::enable_if<N == sizeof...(T), void>::type
- insert_col_name()
- {}
SelectQuery& where()
{
diff --git a/src/database/table.hpp b/src/database/table.hpp
index 680e7cc..eb68418 100644
--- a/src/database/table.hpp
+++ b/src/database/table.hpp
@@ -93,36 +93,32 @@ class Table
private:
template <std::size_t N=0>
- typename std::enable_if<N < sizeof...(T), void>::type
- add_column_if_not_exists(DatabaseEngine& db, const std::set<std::string>& existing_columns)
+ void add_column_if_not_exists(DatabaseEngine& db, const std::set<std::string>& existing_columns)
{
- using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnTypes>()))>::type;
- if (existing_columns.count(ColumnType::name) == 0)
- add_column_to_table<ColumnType>(db, this->name);
- add_column_if_not_exists<N+1>(db, existing_columns);
+ if constexpr(N < sizeof...(T))
+ {
+ using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnTypes>()))>::type;
+ if (existing_columns.count(ColumnType::name) == 0)
+ add_column_to_table<ColumnType>(db, this->name);
+ add_column_if_not_exists<N + 1>(db, existing_columns);
+ }
}
- template <std::size_t N=0>
- typename std::enable_if<N == sizeof...(T), void>::type
- add_column_if_not_exists(DatabaseEngine&, const std::set<std::string>&)
- {}
template <std::size_t N=0>
- typename std::enable_if<N < sizeof...(T), void>::type
- add_column_create(DatabaseEngine& db, std::string& str)
+ void add_column_create(DatabaseEngine& db, std::string& str)
{
- using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnTypes>()))>::type;
- str += ColumnType::name;
- str += " ";
- str += ToSQLType<ColumnType>(db);
- if (N != sizeof...(T) - 1)
- str += ",";
-
- add_column_create<N+1>(db, str);
+ if constexpr(N < sizeof...(T))
+ {
+ using ColumnType = typename std::remove_reference<decltype(std::get<N>(std::declval<ColumnTypes>()))>::type;
+ str += ColumnType::name;
+ str += " ";
+ str += ToSQLType<ColumnType>(db);
+ if (N != sizeof...(T) - 1)
+ str += ",";
+
+ add_column_create<N + 1>(db, str);
+ }
}
- template <std::size_t N=0>
- typename std::enable_if<N == sizeof...(T), void>::type
- add_column_create(DatabaseEngine&, std::string&)
- { }
const std::string name;
};
diff --git a/src/database/update_query.hpp b/src/database/update_query.hpp
index a29ac3f..0ee2bd9 100644
--- a/src/database/update_query.hpp
+++ b/src/database/update_query.hpp
@@ -39,27 +39,25 @@ struct UpdateQuery: public Query
}
template <int N=0, typename... T>
- typename std::enable_if<N < sizeof...(T), void>::type
- insert_col_name_and_value(const std::tuple<T...>& columns)
+ void insert_col_name_and_value(const std::tuple<T...>& columns)
{
- using ColumnType = std::decay_t<decltype(std::get<N>(columns))>;
-
- if (!std::is_same<ColumnType, Id>::value)
+ if constexpr(N < sizeof...(T))
{
- this->body += ColumnType::name + "=$"s + std::to_string(this->current_param);
- this->current_param++;
+ using ColumnType = std::decay_t<decltype(std::get<N>(columns))>;
- if (N < (sizeof...(T) - 1))
- this->body += ", ";
- }
+ if (!std::is_same<ColumnType, Id>::value)
+ {
+ this->body += ColumnType::name + "=$"s
+ + std::to_string(this->current_param);
+ this->current_param++;
- this->insert_col_name_and_value<N+1>(columns);
- }
- template <int N=0, typename... T>
- typename std::enable_if<N == sizeof...(T), void>::type
- insert_col_name_and_value(const std::tuple<T...>&)
- {}
+ if (N < (sizeof...(T) - 1))
+ this->body += ", ";
+ }
+ this->insert_col_name_and_value<N + 1>(columns);
+ }
+ }
template <typename... T>
void execute(DatabaseEngine& db, const std::tuple<T...>& columns)
@@ -76,23 +74,20 @@ struct UpdateQuery: public Query
}
template <int N=0, typename... T>
- typename std::enable_if<N < sizeof...(T), void>::type
- bind_param(const std::tuple<T...>& columns, Statement& statement, int index=1)
+ void bind_param(const std::tuple<T...>& columns, Statement& statement, int index=1)
{
- auto&& column = std::get<N>(columns);
- using ColumnType = std::decay_t<decltype(column)>;
+ if constexpr(N < sizeof...(T))
+ {
+ auto&& column = std::get<N>(columns);
+ using ColumnType = std::decay_t<decltype(column)>;
- if (!std::is_same<ColumnType, Id>::value)
- actual_bind(statement, column.value, index++);
+ if (!std::is_same<ColumnType, Id>::value)
+ actual_bind(statement, column.value, index++);
- this->bind_param<N+1>(columns, statement, index);
+ this->bind_param<N + 1>(columns, statement, index);
+ }
}
- template <int N=0, typename... T>
- typename std::enable_if<N == sizeof...(T), void>::type
- bind_param(const std::tuple<T...>&, Statement&, int)
- {}
-
template <typename... T>
void bind_id(const std::tuple<T...>& columns, Statement& statement)
{