#include "my-selectcommand.h" #include "my-connection.h" #include "my-column.h" #include "my-error.h" #include MySQL::SelectCommand::SelectCommand(const Connection * conn, const std::string & sql) : DB::Command(sql), DB::SelectCommand(sql), MySQL::Command(conn, sql), prepared(false), executed(false) { } void MySQL::SelectCommand::execute() { if (!prepared) { bindParams(); fields.resize(mysql_stmt_field_count(stmt)); for (auto & b : fields) { memset(&b, 0, sizeof(MYSQL_BIND)); } MYSQL_RES * prepare_meta_result = mysql_stmt_result_metadata(stmt); MYSQL_FIELD * fieldDefs = mysql_fetch_fields(prepare_meta_result); for (std::size_t i = 0; i < fields.size(); i += 1) { switch (fieldDefs[i].type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_YEAR: insertColumn(std::make_unique>(fieldDefs[i].name, i, &fields[i])); break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: insertColumn(std::make_unique>(fieldDefs[i].name, i, &fields[i])); break; case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: insertColumn(std::make_unique>(fieldDefs[i].name, i, &fields[i])); break; case MYSQL_TYPE_TIME: insertColumn(std::make_unique>(fieldDefs[i].name, i, &fields[i])); break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: insertColumn(std::make_unique(fieldDefs[i].name, i, &fields[i], fieldDefs[i].length)); break; case MYSQL_TYPE_NULL: insertColumn(std::make_unique(fieldDefs[i].name, i, &fields[i])); break; case MYSQL_TYPE_BIT: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_SET: case MYSQL_TYPE_ENUM: case MYSQL_TYPE_GEOMETRY: default: mysql_free_result(prepare_meta_result); throw DB::ColumnTypeNotSupported(); } } mysql_free_result(prepare_meta_result); if (mysql_stmt_bind_result(stmt, &fields.front())) { throw Error(stmt); } prepared = true; } if (!executed) { if (mysql_stmt_execute(stmt)) { throw Error(stmt); } if (mysql_stmt_store_result(stmt)) { throw Error(stmt); } executed = true; } } bool MySQL::SelectCommand::fetch() { execute(); switch (mysql_stmt_fetch(stmt)) { case 0: return true; case MYSQL_NO_DATA: executed = false; return false; default: throw Error(stmt); } }