#pragma once #include #include #include #include #include #include #include #include template typename std::enable_if::type update_autoincrement_id(std::tuple& columns, Statement& statement) { using ColumnType = typename std::decay(columns))>::type; if (std::is_same::value) auto&& column = std::get(columns); update_autoincrement_id(columns, statement); } template typename std::enable_if::type update_autoincrement_id(std::tuple&, Statement&) {} struct InsertQuery: public Query { template InsertQuery(const std::string& name, const std::tuple& columns): Query("INSERT INTO ") { this->body += name; this->insert_col_names(columns); this->insert_values(columns); } template void execute(DatabaseEngine& db, 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); if (statement->step() != StepResult::Error) db.extract_last_insert_rowid(*statement); else log_error("Failed to extract the rowid from the last INSERT"); } 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 insert_values(const std::tuple& columns) { this->body += "VALUES ("; this->insert_value(columns); this->body += ")"; } template typename std::enable_if::type insert_value(const std::tuple& columns, int index=1) { using ColumnType = std::decay_t(columns))>; if (!std::is_same::value) { this->body += "$" + std::to_string(index++); if (N != sizeof...(T) - 1) this->body += ", "; } this->insert_value(columns, index); } template typename std::enable_if::type insert_value(const std::tuple&, const int) { } template void insert_col_names(const std::tuple& columns) { this->body += " ("; this->insert_col_name(columns); this->body += ")"; } template typename std::enable_if::type insert_col_name(const std::tuple& columns) { using ColumnType = std::decay_t(columns))>; if (!std::is_same::value) { this->body += ColumnType::name; if (N < (sizeof...(T) - 1)) this->body += ", "; } this->insert_col_name(columns); } template typename std::enable_if::type insert_col_name(const std::tuple&) {} };