1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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();
}
|