36
#include <boost/algorithm/string.hpp>
37
#include <boost/foreach.hpp>
38
#include <boost/shared_ptr.hpp>
37
41
#include <libdrizzle/libdrizzle.h>
38
44
#include <stdexcept>
40
46
namespace drizzle {
42
48
class bad_query : public std::runtime_error
51
bad_query(const std::string& v) : std::runtime_error(v)
63
noncopyable(const noncopyable&);
64
void operator=(const noncopyable&);
67
class drizzle_c : noncopyable
72
drizzle_create(*this);
80
operator drizzle_st*()
67
memset(&b_, 0, sizeof(b_));
72
drizzle_result_free(&b_);
91
operator drizzle_result_st*()
94
b_.reset(new drizzle_result_st, drizzle_result_free);
75
98
const char* error()
77
return drizzle_result_error(&b_);
100
return drizzle_result_error(*this);
80
103
uint16_t error_code()
82
return drizzle_result_error_code(&b_);
105
return drizzle_result_error_code(*this);
85
108
uint16_t column_count()
87
return drizzle_result_column_count(&b_);
110
return drizzle_result_column_count(*this);
90
113
uint64_t row_count()
92
return drizzle_result_row_count(&b_);
115
return drizzle_result_row_count(*this);
95
118
drizzle_column_st* column_next()
97
return drizzle_column_next(&b_);
120
return drizzle_column_next(*this);
100
123
drizzle_row_t row_next()
102
return drizzle_row_next(&b_);
125
return drizzle_row_next(*this);
105
128
void column_seek(uint16_t i)
107
drizzle_column_seek(&b_, i);
130
drizzle_column_seek(*this, i);
110
133
void row_seek(uint64_t i)
112
drizzle_row_seek(&b_, i);
135
drizzle_row_seek(*this, i);
115
138
size_t* row_field_sizes()
117
return drizzle_row_field_sizes(&b_);
140
return drizzle_row_field_sizes(*this);
120
drizzle_result_st b_;
143
boost::shared_ptr<drizzle_result_st> b_;
146
class connection_c : noncopyable
126
149
explicit connection_c(drizzle_c& drizzle)
128
drizzle_con_create(&drizzle.b_, &b_);
151
drizzle_con_create(drizzle, *this);
133
drizzle_con_free(&b_);
157
drizzle_con_free(*this);
160
operator drizzle_con_st*()
136
165
const char* error()
138
return drizzle_con_error(&b_);
167
return drizzle_con_error(*this);
170
void set_tcp(const char* host, in_port_t port)
172
drizzle_con_set_tcp(*this, host, port);
175
void set_auth(const char* user, const char* password)
177
drizzle_con_set_auth(*this, user, password);
180
void set_db(const char* db)
182
drizzle_con_set_db(*this, db);
141
185
drizzle_return_t query(result_c& result, const char* str, size_t str_size)
143
187
drizzle_return_t ret;
144
drizzle_query(&b_, &result.b_, str, str_size, &ret);
145
if (ret == DRIZZLE_RETURN_OK)
146
ret = drizzle_result_buffer(&result.b_);
188
drizzle_query(*this, result, str, str_size, &ret);
190
ret = drizzle_result_buffer(result);
157
201
return query(result, str, strlen(str));
204
result_c query(const char* str, size_t str_size)
207
if (query(result, str, str_size))
208
throw bad_query(error());
212
result_c query(const std::string& str)
214
return query(str.data(), str.size());
217
result_c query(const char* str)
219
return query(str, strlen(str));
222
void read_conf_files();
160
224
drizzle_con_st b_;
164
inline drizzle_return_t query(drizzle_con_st* con, result_c& result, const char* str, size_t str_size)
166
drizzle_return_t ret;
167
drizzle_query(con, &result.b_, str, str_size, &ret);
168
if (ret == DRIZZLE_RETURN_OK)
169
ret = drizzle_result_buffer(&result.b_);
173
inline drizzle_return_t query(drizzle_con_st* con, result_c& result, const std::string& str)
175
return query(con, result, str.data(), str.size());
178
inline drizzle_return_t query(drizzle_con_st* con, result_c& result, const char* str)
180
return query(con, result, str, strlen(str));
230
query_c(connection_c& con, const std::string& in = "") :
236
void operator=(const std::string& v)
242
void operator+=(const std::string& v)
247
query_c& p_name(const std::string& v)
249
std::vector<char> r(2 * v.size() + 2);
250
r.resize(drizzle_escape_string(&r.front() + 1, v.data(), v.size()) + 2);
253
p_raw(&r.front(), r.size());
257
query_c& p_raw(const char* v, size_t sz)
259
size_t i = in_.find('?');
260
assert(i != std::string::npos);
261
if (i == std::string::npos)
263
out_.append(in_.substr(0, i));
269
query_c& p_raw(const std::string& v)
271
return p_raw(v.data(), v.size());
274
query_c& p(const std::string& v)
276
std::vector<char> r(2 * v.size() + 2);
277
r.resize(drizzle_escape_string(&r.front() + 1, v.data(), v.size()) + 2);
280
p_raw(&r.front(), r.size());
284
query_c& p(long long v)
286
std::stringstream ss;
292
drizzle_return_t execute(result_c& result)
294
return con_.query(result, read());
299
return con_.query(read());
302
std::string read() const
313
const char* get_conf(const T& c, const std::string& v)
315
typename T::const_iterator i = c.find(v);
316
return i == c.end() ? NULL : i->second.c_str();
319
void connection_c::read_conf_files()
323
vector<string> conf_files;
326
boost::array<char, MAX_PATH> d;
327
GetWindowsDirectoryA(d.data(), d.size());
328
conf_files.push_back(string(d.data()) + "/my.cnf");
329
conf_files.push_back(string(d.data()) + "/drizzle.cnf");
330
conf_files.push_back(string(d.data()) + "/drizzle.conf");
333
conf_files.push_back("/etc/mysql/my.cnf");
334
conf_files.push_back("/etc/drizzle/drizzle.cnf");
335
conf_files.push_back("/etc/drizzle/drizzle.conf");
337
if (const char* d = getenv("HOME"))
339
conf_files.push_back(string(d) + "/.my.cnf");
340
conf_files.push_back(string(d) + "/.drizzle.conf");
343
map<string, string> conf;
344
BOOST_FOREACH(string& it, conf_files)
346
ifstream is(it.c_str());
347
bool client_section = false;
348
for (string s; getline(is, s); )
350
size_t i = s.find('#');
351
if (i != string::npos)
354
if (boost::starts_with(s, "["))
356
client_section = s == "[client]";
359
else if (!client_section)
362
if (i != string::npos)
363
conf[boost::trim_copy(s.substr(0, i))] = boost::trim_copy(s.substr(i + 1));
366
if (conf.count("host") || conf.count("port"))
367
set_tcp(get_conf(conf, "host"), atoi(get_conf(conf, "port")));
368
if (conf.count("user") || conf.count("password"))
369
set_auth(get_conf(conf, "user"), get_conf(conf, "password"));