2318.5.17
by Olaf van der Spek
Fix copyright |
1 |
/* Drizzle Client Library
|
2318.5.16
by Olaf van der Spek
Fix copyright |
2 |
* Copyright (C) 2011 Olaf van der Spek
|
2318.5.17
by Olaf van der Spek
Fix copyright |
3 |
* All rights reserved.
|
4 |
*
|
|
5 |
* Redistribution and use in source and binary forms, with or without
|
|
6 |
* modification, are permitted provided that the following conditions are
|
|
7 |
* met:
|
|
8 |
*
|
|
9 |
* * Redistributions of source code must retain the above copyright
|
|
10 |
* notice, this list of conditions and the following disclaimer.
|
|
11 |
*
|
|
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
|
|
15 |
* distribution.
|
|
16 |
*
|
|
17 |
* * The names of its contributors may not be used to endorse or
|
|
18 |
* promote products derived from this software without specific prior
|
|
19 |
* written permission.
|
|
20 |
*
|
|
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.
|
|
2318.5.16
by Olaf van der Spek
Fix copyright |
32 |
*/
|
33 |
||
2318.5.40
by Olaf van der Spek
Oops |
34 |
#pragma once
|
35 |
||
2407.1.4
by Olaf van der Spek
Read conf files |
36 |
#include <boost/algorithm/string.hpp> |
37 |
#include <boost/foreach.hpp> |
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
38 |
#include <boost/shared_ptr.hpp> |
2318.5.40
by Olaf van der Spek
Oops |
39 |
#include <cstring> |
2407.1.4
by Olaf van der Spek
Read conf files |
40 |
#include <fstream> |
2449.1.2
by Brian Aker
Additional fixes for libdrizzle. |
41 |
#include <libdrizzle-2.0/libdrizzle.h> |
2407.1.4
by Olaf van der Spek
Read conf files |
42 |
#include <map> |
2385.3.5
by Olaf van der Spek
Fix PBMS |
43 |
#include <sstream> |
2318.5.40
by Olaf van der Spek
Oops |
44 |
#include <stdexcept> |
45 |
||
46 |
namespace drizzle { |
|
47 |
||
48 |
class bad_query : public std::runtime_error |
|
49 |
{
|
|
2407.1.3
by Olaf van der Spek
Add throwing variants of query() |
50 |
public: |
51 |
bad_query(const std::string& v) : std::runtime_error(v) |
|
52 |
{
|
|
53 |
}
|
|
2318.5.40
by Olaf van der Spek
Oops |
54 |
};
|
55 |
||
2385.3.4
by Olaf van der Spek
drizzle::noncopyable |
56 |
class noncopyable |
57 |
{
|
|
58 |
protected: |
|
59 |
noncopyable() |
|
60 |
{
|
|
61 |
}
|
|
62 |
private: |
|
63 |
noncopyable(const noncopyable&); |
|
64 |
void operator=(const noncopyable&); |
|
65 |
};
|
|
66 |
||
67 |
class drizzle_c : noncopyable |
|
2318.5.40
by Olaf van der Spek
Oops |
68 |
{
|
69 |
public: |
|
70 |
drizzle_c() |
|
71 |
{
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
72 |
drizzle_create(*this); |
2318.5.40
by Olaf van der Spek
Oops |
73 |
}
|
74 |
||
75 |
~drizzle_c() |
|
76 |
{
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
77 |
drizzle_free(*this); |
2318.5.40
by Olaf van der Spek
Oops |
78 |
}
|
79 |
||
2407.1.2
by Olaf van der Spek
Make base members private |
80 |
operator drizzle_st*() |
81 |
{
|
|
82 |
return &b_; |
|
83 |
}
|
|
84 |
private: |
|
2318.5.40
by Olaf van der Spek
Oops |
85 |
drizzle_st b_; |
86 |
};
|
|
87 |
||
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
88 |
class result_c |
2318.5.40
by Olaf van der Spek
Oops |
89 |
{
|
90 |
public: |
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
91 |
operator drizzle_result_st*() |
92 |
{
|
|
93 |
if (!b_) |
|
94 |
b_.reset(new drizzle_result_st, drizzle_result_free); |
|
95 |
return b_.get(); |
|
2318.5.40
by Olaf van der Spek
Oops |
96 |
}
|
97 |
||
2318.5.6
by Olaf van der Spek
Refactor |
98 |
const char* error() |
99 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
100 |
return drizzle_result_error(*this); |
2318.5.6
by Olaf van der Spek
Refactor |
101 |
}
|
102 |
||
103 |
uint16_t error_code() |
|
104 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
105 |
return drizzle_result_error_code(*this); |
2318.5.6
by Olaf van der Spek
Refactor |
106 |
}
|
107 |
||
2318.5.5
by Olaf van der Spek
C++ client lib wrapper |
108 |
uint16_t column_count() |
109 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
110 |
return drizzle_result_column_count(*this); |
2318.5.5
by Olaf van der Spek
C++ client lib wrapper |
111 |
}
|
112 |
||
113 |
uint64_t row_count() |
|
114 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
115 |
return drizzle_result_row_count(*this); |
2318.5.5
by Olaf van der Spek
C++ client lib wrapper |
116 |
}
|
117 |
||
2318.5.12
by Olaf van der Spek
Refactor |
118 |
drizzle_column_st* column_next() |
119 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
120 |
return drizzle_column_next(*this); |
2318.5.12
by Olaf van der Spek
Refactor |
121 |
}
|
122 |
||
2318.5.5
by Olaf van der Spek
C++ client lib wrapper |
123 |
drizzle_row_t row_next() |
124 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
125 |
return drizzle_row_next(*this); |
2318.5.5
by Olaf van der Spek
C++ client lib wrapper |
126 |
}
|
2318.5.12
by Olaf van der Spek
Refactor |
127 |
|
128 |
void column_seek(uint16_t i) |
|
129 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
130 |
drizzle_column_seek(*this, i); |
2318.5.12
by Olaf van der Spek
Refactor |
131 |
}
|
132 |
||
133 |
void row_seek(uint64_t i) |
|
134 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
135 |
drizzle_row_seek(*this, i); |
2318.5.12
by Olaf van der Spek
Refactor |
136 |
}
|
137 |
||
138 |
size_t* row_field_sizes() |
|
139 |
{
|
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
140 |
return drizzle_row_field_sizes(*this); |
2318.5.12
by Olaf van der Spek
Refactor |
141 |
}
|
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
142 |
private: |
143 |
boost::shared_ptr<drizzle_result_st> b_; |
|
2318.5.40
by Olaf van der Spek
Oops |
144 |
};
|
145 |
||
2385.3.4
by Olaf van der Spek
drizzle::noncopyable |
146 |
class connection_c : noncopyable |
2318.5.40
by Olaf van der Spek
Oops |
147 |
{
|
148 |
public: |
|
149 |
explicit connection_c(drizzle_c& drizzle) |
|
150 |
{
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
151 |
drizzle_con_create(drizzle, *this); |
2407.1.4
by Olaf van der Spek
Read conf files |
152 |
read_conf_files(); |
2318.5.40
by Olaf van der Spek
Oops |
153 |
}
|
154 |
||
155 |
~connection_c() |
|
156 |
{
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
157 |
drizzle_con_free(*this); |
158 |
}
|
|
159 |
||
160 |
operator drizzle_con_st*() |
|
161 |
{
|
|
162 |
return &b_; |
|
2318.5.40
by Olaf van der Spek
Oops |
163 |
}
|
164 |
||
165 |
const char* error() |
|
166 |
{
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
167 |
return drizzle_con_error(*this); |
2318.5.40
by Olaf van der Spek
Oops |
168 |
}
|
169 |
||
2367.2.3
by Olaf van der Spek
Use C++ API |
170 |
void set_tcp(const char* host, in_port_t port) |
171 |
{
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
172 |
drizzle_con_set_tcp(*this, host, port); |
2367.2.3
by Olaf van der Spek
Use C++ API |
173 |
}
|
174 |
||
175 |
void set_auth(const char* user, const char* password) |
|
176 |
{
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
177 |
drizzle_con_set_auth(*this, user, password); |
2367.2.3
by Olaf van der Spek
Use C++ API |
178 |
}
|
179 |
||
180 |
void set_db(const char* db) |
|
181 |
{
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
182 |
drizzle_con_set_db(*this, db); |
2367.2.3
by Olaf van der Spek
Use C++ API |
183 |
}
|
184 |
||
2318.5.32
by Olaf van der Spek
Refactor |
185 |
drizzle_return_t query(result_c& result, const char* str, size_t str_size) |
2318.5.5
by Olaf van der Spek
C++ client lib wrapper |
186 |
{
|
187 |
drizzle_return_t ret; |
|
2407.1.2
by Olaf van der Spek
Make base members private |
188 |
drizzle_query(*this, result, str, str_size, &ret); |
2407.1.3
by Olaf van der Spek
Add throwing variants of query() |
189 |
if (!ret) |
2407.1.1
by Olaf van der Spek
Make drizzle::result_c copyable |
190 |
ret = drizzle_result_buffer(result); |
2318.5.5
by Olaf van der Spek
C++ client lib wrapper |
191 |
return ret; |
2318.5.40
by Olaf van der Spek
Oops |
192 |
}
|
193 |
||
194 |
drizzle_return_t query(result_c& result, const std::string& str) |
|
195 |
{
|
|
196 |
return query(result, str.data(), str.size()); |
|
197 |
}
|
|
198 |
||
199 |
drizzle_return_t query(result_c& result, const char* str) |
|
200 |
{
|
|
201 |
return query(result, str, strlen(str)); |
|
202 |
}
|
|
2407.1.3
by Olaf van der Spek
Add throwing variants of query() |
203 |
|
204 |
result_c query(const char* str, size_t str_size) |
|
205 |
{
|
|
206 |
result_c result; |
|
207 |
if (query(result, str, str_size)) |
|
208 |
throw bad_query(error()); |
|
209 |
return result; |
|
210 |
}
|
|
211 |
||
212 |
result_c query(const std::string& str) |
|
213 |
{
|
|
214 |
return query(str.data(), str.size()); |
|
215 |
}
|
|
216 |
||
217 |
result_c query(const char* str) |
|
218 |
{
|
|
219 |
return query(str, strlen(str)); |
|
220 |
}
|
|
2407.1.2
by Olaf van der Spek
Make base members private |
221 |
private: |
2407.1.4
by Olaf van der Spek
Read conf files |
222 |
void read_conf_files(); |
223 |
||
2318.5.40
by Olaf van der Spek
Oops |
224 |
drizzle_con_st b_; |
225 |
};
|
|
226 |
||
2385.3.2
by Olaf van der Spek
Add drizzle::query_c |
227 |
class query_c |
228 |
{
|
|
229 |
public: |
|
230 |
query_c(connection_c& con, const std::string& in = "") : |
|
231 |
con_(con), |
|
232 |
in_(in) |
|
233 |
{
|
|
234 |
}
|
|
235 |
||
236 |
void operator=(const std::string& v) |
|
237 |
{
|
|
238 |
in_ = v; |
|
239 |
out_.clear(); |
|
240 |
}
|
|
241 |
||
242 |
void operator+=(const std::string& v) |
|
243 |
{
|
|
244 |
in_ += v; |
|
245 |
}
|
|
246 |
||
247 |
query_c& p_name(const std::string& v) |
|
248 |
{
|
|
249 |
std::vector<char> r(2 * v.size() + 2); |
|
250 |
r.resize(drizzle_escape_string(&r.front() + 1, v.data(), v.size()) + 2); |
|
251 |
r.front() = '`'; |
|
252 |
r.back() = '`'; |
|
253 |
p_raw(&r.front(), r.size()); |
|
254 |
return *this; |
|
255 |
}
|
|
256 |
||
257 |
query_c& p_raw(const char* v, size_t sz) |
|
258 |
{
|
|
259 |
size_t i = in_.find('?'); |
|
260 |
assert(i != std::string::npos); |
|
261 |
if (i == std::string::npos) |
|
262 |
return *this; |
|
263 |
out_.append(in_.substr(0, i)); |
|
264 |
in_.erase(0, i + 1); |
|
265 |
out_.append(v, sz); |
|
266 |
return *this; |
|
267 |
}
|
|
268 |
||
269 |
query_c& p_raw(const std::string& v) |
|
270 |
{
|
|
271 |
return p_raw(v.data(), v.size()); |
|
272 |
}
|
|
273 |
||
274 |
query_c& p(const std::string& v) |
|
275 |
{
|
|
276 |
std::vector<char> r(2 * v.size() + 2); |
|
277 |
r.resize(drizzle_escape_string(&r.front() + 1, v.data(), v.size()) + 2); |
|
278 |
r.front() = '\''; |
|
279 |
r.back() = '\''; |
|
280 |
p_raw(&r.front(), r.size()); |
|
281 |
return *this; |
|
282 |
}
|
|
283 |
||
2385.3.5
by Olaf van der Spek
Fix PBMS |
284 |
query_c& p(long long v) |
2385.3.2
by Olaf van der Spek
Add drizzle::query_c |
285 |
{
|
2385.3.5
by Olaf van der Spek
Fix PBMS |
286 |
std::stringstream ss; |
287 |
ss << v; |
|
288 |
p_raw(ss.str()); |
|
2385.3.2
by Olaf van der Spek
Add drizzle::query_c |
289 |
return *this; |
290 |
}
|
|
291 |
||
292 |
drizzle_return_t execute(result_c& result) |
|
293 |
{
|
|
294 |
return con_.query(result, read()); |
|
295 |
}
|
|
296 |
||
2407.1.3
by Olaf van der Spek
Add throwing variants of query() |
297 |
result_c execute() |
298 |
{
|
|
299 |
return con_.query(read()); |
|
300 |
}
|
|
301 |
||
2385.3.2
by Olaf van der Spek
Add drizzle::query_c |
302 |
std::string read() const |
303 |
{
|
|
304 |
return out_ + in_; |
|
305 |
}
|
|
306 |
private: |
|
307 |
connection_c& con_; |
|
308 |
std::string in_; |
|
309 |
std::string out_; |
|
310 |
};
|
|
311 |
||
2407.1.4
by Olaf van der Spek
Read conf files |
312 |
template<class T> |
313 |
const char* get_conf(const T& c, const std::string& v) |
|
314 |
{
|
|
315 |
typename T::const_iterator i = c.find(v); |
|
316 |
return i == c.end() ? NULL : i->second.c_str(); |
|
317 |
}
|
|
318 |
||
319 |
void connection_c::read_conf_files() |
|
320 |
{
|
|
321 |
using namespace std; |
|
322 |
||
323 |
vector<string> conf_files; |
|
324 |
#ifdef WIN32
|
|
325 |
{
|
|
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"); |
|
331 |
}
|
|
332 |
#else
|
|
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"); |
|
336 |
#endif
|
|
337 |
if (const char* d = getenv("HOME")) |
|
338 |
{
|
|
339 |
conf_files.push_back(string(d) + "/.my.cnf"); |
|
340 |
conf_files.push_back(string(d) + "/.drizzle.conf"); |
|
341 |
}
|
|
342 |
||
2407.1.6
by Olaf van der Spek
Refactor |
343 |
map<string, string> conf; |
2407.1.4
by Olaf van der Spek
Read conf files |
344 |
BOOST_FOREACH(string& it, conf_files) |
345 |
{
|
|
346 |
ifstream is(it.c_str()); |
|
347 |
bool client_section = false; |
|
348 |
for (string s; getline(is, s); ) |
|
349 |
{
|
|
350 |
size_t i = s.find('#'); |
|
351 |
if (i != string::npos) |
|
352 |
s.erase(i); |
|
353 |
boost::trim(s); |
|
354 |
if (boost::starts_with(s, "[")) |
|
355 |
{
|
|
356 |
client_section = s == "[client]"; |
|
357 |
continue; |
|
358 |
}
|
|
359 |
else if (!client_section) |
|
360 |
continue; |
|
361 |
i = s.find('='); |
|
2407.1.6
by Olaf van der Spek
Refactor |
362 |
if (i != string::npos) |
363 |
conf[boost::trim_copy(s.substr(0, i))] = boost::trim_copy(s.substr(i + 1)); |
|
2407.1.4
by Olaf van der Spek
Read conf files |
364 |
}
|
365 |
}
|
|
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")); |
|
370 |
}
|
|
371 |
||
2318.5.40
by Olaf van der Spek
Oops |
372 |
}
|