diff options
Diffstat (limited to 'libmysqlpp/selectcommand.cpp')
-rw-r--r-- | libmysqlpp/selectcommand.cpp | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/libmysqlpp/selectcommand.cpp b/libmysqlpp/selectcommand.cpp new file mode 100644 index 0000000..e6bf789 --- /dev/null +++ b/libmysqlpp/selectcommand.cpp @@ -0,0 +1,129 @@ +#include "selectcommand.h" +#include "connection.h" +#include "column.h" +#include "error.h" +#include <string.h> + +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<ColumnBase>(new Column<int64_t, MYSQL_TYPE_LONGLONG>(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<ColumnBase>(new Column<double, MYSQL_TYPE_DOUBLE>(fieldDefs[i].name, i, &fields[i]))); + break; + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_DATETIME: + columns.insert(boost::shared_ptr<ColumnBase>(new Column<MYSQL_TIME, MYSQL_TYPE_DATETIME>(fieldDefs[i].name, i, &fields[i]))); + break; + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VAR_STRING: + columns.insert(boost::shared_ptr<ColumnBase>(new StringColumn(fieldDefs[i].name, i, &fields[i], fieldDefs[i].length))); + break; + case MYSQL_TYPE_NULL: + columns.insert(boost::shared_ptr<ColumnBase>(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(); +} + |