#pragma once #include #include #include using namespace std::string_literals; template struct Index; template struct Index> { static const std::size_t value = 0; }; template struct Index> { static const std::size_t value = Index>::value + 1; }; struct UpdateQuery: public Query { template UpdateQuery(const std::string& name, const std::tuple& columns): Query("UPDATE ") { this->body += name; this->insert_col_names_and_values(columns); } template void insert_col_names_and_values(const std::tuple& columns) { this->body += " SET "; this->insert_col_name_and_value(columns); this->body += " WHERE "s + Id::name + "=$" + std::to_string(this->current_param); } template typename std::enable_if::type insert_col_name_and_value(const std::tuple& columns) { using ColumnType = std::decay_t(columns))>; if (!std::is_same::value) { this->body += ColumnType::name + "=$"s + std::to_string(this->current_param); this->current_param++; if (N < (sizeof...(T) - 1)) this->body += ", "; } this->insert_col_name_and_value(columns); } template typename std::enable_if::type insert_col_name_and_value(const std::tuple&) {} template void execute(DatabaseEngine& db, const std::tuple& columns) { #ifdef DEBUG_SQL_QUERIES const auto timer = this->log_and_time(); #endif auto statement = db.prepare(this->body); this->bind_param(columns, *statement); this->bind_id(columns, *statement); statement->step(); } template typename std::enable_if::type bind_param(const std::tuple& columns, Statement& statement, int index=1) { auto&& column = std::get(columns); using ColumnType = std::decay_t; if (!std::is_same::value) actual_bind(statement, column.value, index++); this->bind_param(columns, statement, index); } template typename std::enable_if::type bind_param(const std::tuple&, Statement&, int) {} template void bind_id(const std::tuple& columns, Statement& statement) { static constexpr auto index = Index>::value; auto&& value = std::get(columns); actual_bind(statement, value.value, sizeof...(T)); } }; template void update(Row& row, DatabaseEngine& db) { UpdateQuery query(row.table_name, row.columns); query.execute(db, row.columns); }