1
/* Drizzle Client Library
2
* Copyright (C) 2011 Olaf van der Spek
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are
9
* * Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
12
* * Redistributions in binary form must reproduce the above
13
* copyright notice, this list of conditions and the following disclaimer
14
* in the documentation and/or other materials provided with the
17
* * The names of its contributors may not be used to endorse or
18
* promote products derived from this software without specific prior
21
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
#include <boost/algorithm/string.hpp>
37
#include <boost/foreach.hpp>
38
#include <boost/shared_ptr.hpp>
41
#include <libdrizzle-2.0/libdrizzle.h>
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
80
operator drizzle_st*()
91
operator drizzle_result_st*()
94
b_.reset(new drizzle_result_st, drizzle_result_free);
100
return drizzle_result_error(*this);
103
uint16_t error_code()
105
return drizzle_result_error_code(*this);
108
uint16_t column_count()
110
return drizzle_result_column_count(*this);
115
return drizzle_result_row_count(*this);
118
drizzle_column_st* column_next()
120
return drizzle_column_next(*this);
123
drizzle_row_t row_next()
125
return drizzle_row_next(*this);
128
void column_seek(uint16_t i)
130
drizzle_column_seek(*this, i);
133
void row_seek(uint64_t i)
135
drizzle_row_seek(*this, i);
138
size_t* row_field_sizes()
140
return drizzle_row_field_sizes(*this);
143
boost::shared_ptr<drizzle_result_st> b_;
146
class connection_c : noncopyable
149
explicit connection_c(drizzle_c& drizzle)
151
b_= drizzle_con_create(drizzle);
155
throw "drizzle_con_create() failed";
162
drizzle_con_free(b_);
165
operator drizzle_con_st*()
172
return drizzle_con_error(b_);
175
void set_tcp(const char* host, in_port_t port)
177
drizzle_con_set_tcp(b_, host, port);
180
void set_auth(const char* user, const char* password)
182
drizzle_con_set_auth(b_, user, password);
185
void set_db(const char* db)
187
drizzle_con_set_db(b_, db);
190
drizzle_return_t query(result_c& result, const char* str, size_t str_size)
192
drizzle_return_t ret;
194
drizzle_query(*this, result, str, str_size, &ret);
198
ret = drizzle_result_buffer(result);
204
drizzle_return_t query(result_c& result, const std::string& str)
206
return query(result, str.data(), str.size());
209
drizzle_return_t query(result_c& result, const char* str)
211
return query(result, str, strlen(str));
214
result_c query(const char* str, size_t str_size)
217
if (query(result, str, str_size))
219
throw bad_query(error());
225
result_c query(const std::string& str)
227
return query(str.data(), str.size());
230
result_c query(const char* str)
232
return query(str, strlen(str));
235
void read_conf_files();
243
query_c(connection_c& con, const std::string& in = "") :
249
void operator=(const std::string& v)
255
void operator+=(const std::string& v)
260
query_c& p_name(const std::string& v)
262
std::vector<char> r(2 * v.size() + 2);
263
r.resize(drizzle_escape_string(&r.front() + 1, r.size(), v.data(), v.size()) + 2);
266
p_raw(&r.front(), r.size());
270
query_c& p_raw(const char* v, size_t sz)
272
size_t i = in_.find('?');
273
assert(i != std::string::npos);
274
if (i == std::string::npos)
276
out_.append(in_.substr(0, i));
282
query_c& p_raw(const std::string& v)
284
return p_raw(v.data(), v.size());
287
query_c& p(const std::string& v)
289
std::vector<char> r(2 * v.size() + 2);
290
r.resize(drizzle_escape_string(&r.front() + 1, r.size(), v.data(), v.size()) + 2);
293
p_raw(&r.front(), r.size());
297
query_c& p(long long v)
299
std::stringstream ss;
305
drizzle_return_t execute(result_c& result)
307
return con_.query(result, read());
312
return con_.query(read());
315
std::string read() const
326
const char* get_conf(const T& c, const std::string& v)
328
typename T::const_iterator i = c.find(v);
329
return i == c.end() ? NULL : i->second.c_str();
332
void connection_c::read_conf_files()
336
vector<string> conf_files;
339
boost::array<char, MAX_PATH> d;
340
GetWindowsDirectoryA(d.data(), d.size());
341
conf_files.push_back(string(d.data()) + "/my.cnf");
342
conf_files.push_back(string(d.data()) + "/drizzle.cnf");
343
conf_files.push_back(string(d.data()) + "/drizzle.conf");
346
conf_files.push_back("/etc/mysql/my.cnf");
347
conf_files.push_back("/etc/drizzle/drizzle.cnf");
348
conf_files.push_back("/etc/drizzle/drizzle.conf");
350
if (const char* d = getenv("HOME"))
352
conf_files.push_back(string(d) + "/.my.cnf");
353
conf_files.push_back(string(d) + "/.drizzle.conf");
356
map<string, string> conf;
357
BOOST_FOREACH(string& it, conf_files)
359
ifstream is(it.c_str());
360
bool client_section = false;
361
for (string s; getline(is, s); )
363
size_t i = s.find('#');
364
if (i != string::npos)
367
if (boost::starts_with(s, "["))
369
client_section = s == "[client]";
372
else if (!client_section)
375
if (i != string::npos)
376
conf[boost::trim_copy(s.substr(0, i))] = boost::trim_copy(s.substr(i + 1));
379
if (conf.count("host") || conf.count("port"))
380
set_tcp(get_conf(conf, "host"), atoi(get_conf(conf, "port")));
381
if (conf.count("user") || conf.count("password"))
382
set_auth(get_conf(conf, "user"), get_conf(conf, "password"));