summaryrefslogtreecommitdiff
path: root/libmysqlpp/selectcommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libmysqlpp/selectcommand.cpp')
-rw-r--r--libmysqlpp/selectcommand.cpp129
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();
+}
+