#include "selectcommand.h" #include "connection.h" #include "column.h" #include "error.h" #include MySQL::SelectCommand::SelectCommand(const Connection * conn, const std::string & sql) : DB::Command(sql), DB::SelectCommand(sql), MySQL::Command(conn, sql), executed(false) { } void MySQL::SelectCommand::execute() { if (!executed) { bindParams(); fields.resize(mysql_stmt_field_count(stmt)); for (Binds::iterator i = fields.begin(); i != fields.end(); ++i) { memset(&*i, 0, sizeof(MYSQL_BIND)); } MYSQL_RES * prepare_meta_result = mysql_stmt_result_metadata(stmt); MYSQL_FIELD * fieldDefs = mysql_fetch_fields(prepare_meta_result); for (unsigned int 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: columns.insert(boost::shared_ptr(new Column(fieldDefs[i].name, i, &fields[i]))); break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: columns.insert(boost::shared_ptr(new Column(fieldDefs[i].name, i, &fields[i]))); break; case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: columns.insert(boost::shared_ptr(new Column(fieldDefs[i].name, i, &fields[i]))); break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: columns.insert(boost::shared_ptr(new StringColumn(fieldDefs[i].name, i, &fields[i], fieldDefs[i].length))); break; case MYSQL_TYPE_NULL: columns.insert(boost::shared_ptr(new NullColumn(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: case MYSQL_TYPE_TIME: default: mysql_free_result(prepare_meta_result); throw Error("Unexpected type"); } } mysql_free_result(prepare_meta_result); if (mysql_stmt_bind_result(stmt, &fields.front())) { throw Error(mysql_stmt_error(stmt)); } if (mysql_stmt_execute(stmt)) { throw Error(mysql_stmt_error(stmt)); } if (mysql_stmt_store_result(stmt)) { throw Error(mysql_stmt_error(stmt)); } executed = true; } } bool MySQL::SelectCommand::fetch() { execute(); switch (mysql_stmt_fetch(stmt)) { case 0: return true; case MYSQL_NO_DATA: return false; default: throw Error(mysql_stmt_error(stmt)); } } const DB::Column& MySQL::SelectCommand::operator[](unsigned int n) const { if (n < columns.size()) { return **columns.get<0>().find(n); } throw Error(); } const DB::Column& MySQL::SelectCommand::operator[](const Glib::ustring & n) const { typedef Columns::nth_index<1>::type CbyName; CbyName::iterator i = columns.get<1>().find(n); if (i != columns.get<1>().end()) { return **i; } throw Error(); } unsigned int MySQL::SelectCommand::getOrdinal(const Glib::ustring & n) const { typedef Columns::nth_index<1>::type CbyName; CbyName::iterator i = columns.get<1>().find(n); if (i != columns.get<1>().end()) { return (*i)->colNo; } throw Error(); } unsigned int MySQL::SelectCommand::columnCount() const { return fields.size(); }