diff options
Diffstat (limited to 'src/database')
-rw-r--r-- | src/database/index.hpp | 21 | ||||
-rw-r--r-- | src/database/insert_query.hpp | 91 | ||||
-rw-r--r-- | src/database/query.hpp | 41 | ||||
-rw-r--r-- | src/database/row.hpp | 52 | ||||
-rw-r--r-- | src/database/select_query.hpp | 77 | ||||
-rw-r--r-- | src/database/table.hpp | 44 | ||||
-rw-r--r-- | src/database/update_query.hpp | 51 |
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) { |