~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle-2.0/libdrizzle.hpp

  • Committer: Mark Atwood
  • Date: 2012-01-04 16:59:32 UTC
  • mfrom: (2478.2.3 real-key-use-catalog)
  • Revision ID: me@mark.atwood.name-20120104165932-cm0xqs4by0u3p4cy
mergeĀ lp:~stewart/drizzle/key-use-catalog

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 
34
34
#pragma once
35
35
 
 
36
#include <boost/algorithm/string.hpp>
 
37
#include <boost/foreach.hpp>
 
38
#include <boost/shared_ptr.hpp>
36
39
#include <cstring>
37
 
#include <libdrizzle/libdrizzle.h>
 
40
#include <fstream>
 
41
#include <libdrizzle-2.0/libdrizzle.h>
 
42
#include <map>
 
43
#include <sstream>
38
44
#include <stdexcept>
39
45
 
40
46
namespace drizzle {
41
47
 
42
48
class bad_query : public std::runtime_error
43
49
{
44
 
};
45
 
 
46
 
class drizzle_c
 
50
public:
 
51
  bad_query(const std::string& v) : std::runtime_error(v)
 
52
  {
 
53
  }
 
54
};
 
55
 
 
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
47
68
{
48
69
public:
49
70
  drizzle_c()
50
71
  {
51
 
    drizzle_create(&b_);
 
72
    b_= drizzle_create();
52
73
  }
53
74
 
54
75
  ~drizzle_c()
55
76
  {
56
 
    drizzle_free(&b_);
 
77
    drizzle_free(b_);
57
78
  }
58
79
 
59
 
  drizzle_st b_;
 
80
  operator drizzle_st*()
 
81
  {
 
82
    return b_;
 
83
  }
 
84
private:
 
85
  drizzle_st *b_;
60
86
};
61
87
 
62
88
class result_c
63
89
{
64
90
public:
65
 
  result_c()
66
 
  {
67
 
    memset(&b_, 0, sizeof(b_));
68
 
  }
69
 
 
70
 
  ~result_c()
71
 
  {
72
 
    drizzle_result_free(&b_);
 
91
  operator drizzle_result_st*()
 
92
  {
 
93
    if (!b_)
 
94
      b_.reset(new drizzle_result_st, drizzle_result_free);
 
95
    return b_.get();
73
96
  }
74
97
 
75
98
  const char* error()
76
99
  {
77
 
    return drizzle_result_error(&b_);
 
100
    return drizzle_result_error(*this);
78
101
  }
79
102
 
80
103
  uint16_t error_code()
81
104
  {
82
 
    return drizzle_result_error_code(&b_);
 
105
    return drizzle_result_error_code(*this);
83
106
  }
84
107
 
85
108
  uint16_t column_count()
86
109
  {
87
 
    return drizzle_result_column_count(&b_);    
 
110
    return drizzle_result_column_count(*this);    
88
111
  }
89
112
 
90
113
  uint64_t row_count()
91
114
  {
92
 
    return drizzle_result_row_count(&b_);
 
115
    return drizzle_result_row_count(*this);
93
116
  }
94
117
 
95
118
  drizzle_column_st* column_next()
96
119
  {
97
 
    return drizzle_column_next(&b_);
 
120
    return drizzle_column_next(*this);
98
121
  }
99
122
 
100
123
  drizzle_row_t row_next()
101
124
  {
102
 
    return drizzle_row_next(&b_);
 
125
    return drizzle_row_next(*this);
103
126
  }
104
127
 
105
128
  void column_seek(uint16_t i)
106
129
  {
107
 
    drizzle_column_seek(&b_, i);
 
130
    drizzle_column_seek(*this, i);
108
131
  }
109
132
 
110
133
  void row_seek(uint64_t i)
111
134
  {
112
 
    drizzle_row_seek(&b_, i);
 
135
    drizzle_row_seek(*this, i);
113
136
  }
114
137
 
115
138
  size_t* row_field_sizes()
116
139
  {
117
 
    return drizzle_row_field_sizes(&b_);
 
140
    return drizzle_row_field_sizes(*this);
118
141
  }
119
 
 
120
 
  drizzle_result_st b_;
 
142
private:
 
143
  boost::shared_ptr<drizzle_result_st> b_;
121
144
};
122
145
 
123
 
class connection_c
 
146
class connection_c : noncopyable
124
147
{
125
148
public:
126
149
  explicit connection_c(drizzle_c& drizzle)
127
150
  {
128
 
    drizzle_con_create(&drizzle.b_, &b_);
 
151
    b_= drizzle_con_create(drizzle);
 
152
 
 
153
    if (b_ == NULL)
 
154
    {
 
155
      throw "drizzle_con_create() failed";
 
156
    }
 
157
    read_conf_files();
129
158
  }
130
159
 
131
160
  ~connection_c()
132
161
  {
133
 
    drizzle_con_free(&b_);
 
162
    drizzle_con_free(b_);
 
163
  }
 
164
 
 
165
  operator drizzle_con_st*()
 
166
  {
 
167
    return b_;
134
168
  }
135
169
 
136
170
  const char* error()
137
171
  {
138
 
    return drizzle_con_error(&b_);
 
172
    return drizzle_con_error(b_);
139
173
  }
140
174
 
141
175
  void set_tcp(const char* host, in_port_t port)
142
176
  {
143
 
    drizzle_con_set_tcp(&b_, host, port);
 
177
    drizzle_con_set_tcp(b_, host, port);
144
178
  }
145
179
 
146
180
  void set_auth(const char* user, const char* password)
147
181
  {
148
 
    drizzle_con_set_auth(&b_, user, password);
 
182
    drizzle_con_set_auth(b_, user, password);
149
183
  }
150
184
 
151
185
  void set_db(const char* db)
152
186
  {
153
 
    drizzle_con_set_db(&b_, db);
 
187
    drizzle_con_set_db(b_, db);
154
188
  }
155
189
 
156
190
  drizzle_return_t query(result_c& result, const char* str, size_t str_size)
157
191
  {
158
192
    drizzle_return_t ret;
159
 
    drizzle_query(&b_, &result.b_, str, str_size, &ret);
160
 
    if (ret == DRIZZLE_RETURN_OK)
161
 
      ret = drizzle_result_buffer(&result.b_);
 
193
 
 
194
    drizzle_query(*this, result, str, str_size, &ret);
 
195
 
 
196
    if (!ret)
 
197
    {
 
198
      ret = drizzle_result_buffer(result);
 
199
    }
 
200
 
162
201
    return ret;
163
202
  }
164
203
 
172
211
    return query(result, str, strlen(str));
173
212
  }
174
213
 
175
 
  drizzle_con_st b_;
176
 
};
177
 
 
178
 
/*
179
 
inline drizzle_return_t query(drizzle_con_st* con, result_c& result, const char* str, size_t str_size)
180
 
{
181
 
  drizzle_return_t ret;
182
 
  drizzle_query(con, &result.b_, str, str_size, &ret);
183
 
  if (ret == DRIZZLE_RETURN_OK)
184
 
    ret = drizzle_result_buffer(&result.b_);
185
 
  return ret;
186
 
}
187
 
 
188
 
inline drizzle_return_t query(drizzle_con_st* con, result_c& result, const std::string& str)
189
 
{
190
 
  return query(con, result, str.data(), str.size());
191
 
}
192
 
 
193
 
inline drizzle_return_t query(drizzle_con_st* con, result_c& result, const char* str)
194
 
{
195
 
  return query(con, result, str, strlen(str));
196
 
}
197
 
*/
 
214
  result_c query(const char* str, size_t str_size)
 
215
  {
 
216
    result_c result;
 
217
    if (query(result, str, str_size))
 
218
    {
 
219
      throw bad_query(error());
 
220
    }
 
221
 
 
222
    return result;
 
223
  }
 
224
 
 
225
  result_c query(const std::string& str)
 
226
  {
 
227
    return query(str.data(), str.size());
 
228
  }
 
229
 
 
230
  result_c query(const char* str)
 
231
  {
 
232
    return query(str, strlen(str));
 
233
  }
 
234
private:
 
235
  void read_conf_files();
 
236
 
 
237
  drizzle_con_st *b_;
 
238
};
 
239
 
 
240
class query_c
 
241
{
 
242
public:
 
243
  query_c(connection_c& con, const std::string& in = "") :
 
244
    con_(con),
 
245
    in_(in)
 
246
  {
 
247
  }
 
248
 
 
249
  void operator=(const std::string& v)
 
250
  {
 
251
    in_ = v;
 
252
    out_.clear();
 
253
  }
 
254
 
 
255
  void operator+=(const std::string& v)
 
256
  {
 
257
    in_ += v;
 
258
  }
 
259
 
 
260
  query_c& p_name(const std::string& v)
 
261
  {
 
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);    
 
264
    r.front() = '`';
 
265
    r.back() = '`';
 
266
    p_raw(&r.front(), r.size());
 
267
    return *this;
 
268
  }
 
269
 
 
270
  query_c& p_raw(const char* v, size_t sz)
 
271
  {
 
272
    size_t i = in_.find('?');
 
273
    assert(i != std::string::npos);
 
274
    if (i == std::string::npos)
 
275
      return *this;
 
276
    out_.append(in_.substr(0, i));
 
277
    in_.erase(0, i + 1);
 
278
    out_.append(v, sz);
 
279
    return *this;
 
280
  }
 
281
 
 
282
  query_c& p_raw(const std::string& v)
 
283
  {
 
284
    return p_raw(v.data(), v.size());
 
285
  }
 
286
 
 
287
  query_c& p(const std::string& v)
 
288
  {
 
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);    
 
291
    r.front() = '\'';
 
292
    r.back() = '\'';
 
293
    p_raw(&r.front(), r.size());
 
294
    return *this;
 
295
  }
 
296
 
 
297
  query_c& p(long long v)
 
298
  {
 
299
    std::stringstream ss;
 
300
    ss << v;
 
301
    p_raw(ss.str());
 
302
    return *this;
 
303
  }
 
304
 
 
305
  drizzle_return_t execute(result_c& result)
 
306
  {
 
307
    return con_.query(result, read());
 
308
  }
 
309
 
 
310
  result_c execute()
 
311
  {
 
312
    return con_.query(read());
 
313
  }
 
314
 
 
315
  std::string read() const
 
316
  {
 
317
    return out_ + in_;
 
318
  }
 
319
private:
 
320
  connection_c& con_;
 
321
  std::string in_;
 
322
  std::string out_;
 
323
};
 
324
 
 
325
template<class T>
 
326
const char* get_conf(const T& c, const std::string& v)
 
327
{
 
328
  typename T::const_iterator i = c.find(v);
 
329
  return i == c.end() ? NULL : i->second.c_str();
 
330
}
 
331
 
 
332
void connection_c::read_conf_files()
 
333
{
 
334
  using namespace std;
 
335
 
 
336
  vector<string> conf_files;
 
337
#ifdef WIN32
 
338
  {
 
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");
 
344
  }
 
345
#else
 
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");
 
349
#endif
 
350
  if (const char* d = getenv("HOME"))
 
351
  {
 
352
    conf_files.push_back(string(d) + "/.my.cnf");  
 
353
    conf_files.push_back(string(d) + "/.drizzle.conf");
 
354
  }
 
355
  
 
356
  map<string, string> conf;
 
357
  BOOST_FOREACH(string& it, conf_files)
 
358
  {
 
359
    ifstream is(it.c_str());
 
360
    bool client_section = false;
 
361
    for (string s; getline(is, s); )
 
362
    {
 
363
      size_t i = s.find('#');
 
364
      if (i != string::npos)
 
365
        s.erase(i);
 
366
      boost::trim(s);
 
367
      if (boost::starts_with(s, "["))
 
368
      {
 
369
        client_section = s == "[client]";
 
370
        continue;
 
371
      }
 
372
      else if (!client_section)
 
373
        continue;
 
374
      i = s.find('=');
 
375
      if (i != string::npos)
 
376
        conf[boost::trim_copy(s.substr(0, i))] = boost::trim_copy(s.substr(i + 1));
 
377
    }
 
378
  }
 
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"));
 
383
}
198
384
 
199
385
}