~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle-2.0/libdrizzle/libdrizzle.hpp

  • Committer: Mark Atwood
  • Date: 2011-08-21 06:58:08 UTC
  • mfrom: (2407.1.6 client)
  • Revision ID: me@mark.atwood.name-20110821065808-l3xxgvbreily086c
mergeĀ lp:~olafvdspek/drizzle/client

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>
 
40
#include <fstream>
37
41
#include <libdrizzle/libdrizzle.h>
 
42
#include <map>
38
43
#include <sstream>
39
44
#include <stdexcept>
40
45
 
42
47
 
43
48
class bad_query : public std::runtime_error
44
49
{
 
50
public:
 
51
  bad_query(const std::string& v) : std::runtime_error(v)
 
52
  {
 
53
  }
45
54
};
46
55
 
47
56
class noncopyable
60
69
public:
61
70
  drizzle_c()
62
71
  {
63
 
    drizzle_create(&b_);
 
72
    drizzle_create(*this);
64
73
  }
65
74
 
66
75
  ~drizzle_c()
67
76
  {
68
 
    drizzle_free(&b_);
 
77
    drizzle_free(*this);
69
78
  }
70
79
 
 
80
  operator drizzle_st*()
 
81
  {
 
82
    return &b_;
 
83
  }
 
84
private:
71
85
  drizzle_st b_;
72
86
};
73
87
 
74
 
class result_c : noncopyable
 
88
class result_c
75
89
{
76
90
public:
77
 
  result_c()
78
 
  {
79
 
    memset(&b_, 0, sizeof(b_));
80
 
  }
81
 
 
82
 
  ~result_c()
83
 
  {
84
 
    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();
85
96
  }
86
97
 
87
98
  const char* error()
88
99
  {
89
 
    return drizzle_result_error(&b_);
 
100
    return drizzle_result_error(*this);
90
101
  }
91
102
 
92
103
  uint16_t error_code()
93
104
  {
94
 
    return drizzle_result_error_code(&b_);
 
105
    return drizzle_result_error_code(*this);
95
106
  }
96
107
 
97
108
  uint16_t column_count()
98
109
  {
99
 
    return drizzle_result_column_count(&b_);    
 
110
    return drizzle_result_column_count(*this);    
100
111
  }
101
112
 
102
113
  uint64_t row_count()
103
114
  {
104
 
    return drizzle_result_row_count(&b_);
 
115
    return drizzle_result_row_count(*this);
105
116
  }
106
117
 
107
118
  drizzle_column_st* column_next()
108
119
  {
109
 
    return drizzle_column_next(&b_);
 
120
    return drizzle_column_next(*this);
110
121
  }
111
122
 
112
123
  drizzle_row_t row_next()
113
124
  {
114
 
    return drizzle_row_next(&b_);
 
125
    return drizzle_row_next(*this);
115
126
  }
116
127
 
117
128
  void column_seek(uint16_t i)
118
129
  {
119
 
    drizzle_column_seek(&b_, i);
 
130
    drizzle_column_seek(*this, i);
120
131
  }
121
132
 
122
133
  void row_seek(uint64_t i)
123
134
  {
124
 
    drizzle_row_seek(&b_, i);
 
135
    drizzle_row_seek(*this, i);
125
136
  }
126
137
 
127
138
  size_t* row_field_sizes()
128
139
  {
129
 
    return drizzle_row_field_sizes(&b_);
 
140
    return drizzle_row_field_sizes(*this);
130
141
  }
131
 
 
132
 
  drizzle_result_st b_;
 
142
private:
 
143
  boost::shared_ptr<drizzle_result_st> b_;
133
144
};
134
145
 
135
146
class connection_c : noncopyable
137
148
public:
138
149
  explicit connection_c(drizzle_c& drizzle)
139
150
  {
140
 
    drizzle_con_create(&drizzle.b_, &b_);
 
151
    drizzle_con_create(drizzle, *this);
 
152
    read_conf_files();
141
153
  }
142
154
 
143
155
  ~connection_c()
144
156
  {
145
 
    drizzle_con_free(&b_);
 
157
    drizzle_con_free(*this);
 
158
  }
 
159
 
 
160
  operator drizzle_con_st*()
 
161
  {
 
162
    return &b_;
146
163
  }
147
164
 
148
165
  const char* error()
149
166
  {
150
 
    return drizzle_con_error(&b_);
 
167
    return drizzle_con_error(*this);
151
168
  }
152
169
 
153
170
  void set_tcp(const char* host, in_port_t port)
154
171
  {
155
 
    drizzle_con_set_tcp(&b_, host, port);
 
172
    drizzle_con_set_tcp(*this, host, port);
156
173
  }
157
174
 
158
175
  void set_auth(const char* user, const char* password)
159
176
  {
160
 
    drizzle_con_set_auth(&b_, user, password);
 
177
    drizzle_con_set_auth(*this, user, password);
161
178
  }
162
179
 
163
180
  void set_db(const char* db)
164
181
  {
165
 
    drizzle_con_set_db(&b_, db);
 
182
    drizzle_con_set_db(*this, db);
166
183
  }
167
184
 
168
185
  drizzle_return_t query(result_c& result, const char* str, size_t str_size)
169
186
  {
170
187
    drizzle_return_t ret;
171
 
    drizzle_query(&b_, &result.b_, str, str_size, &ret);
172
 
    if (ret == DRIZZLE_RETURN_OK)
173
 
      ret = drizzle_result_buffer(&result.b_);
 
188
    drizzle_query(*this, result, str, str_size, &ret);
 
189
    if (!ret)
 
190
      ret = drizzle_result_buffer(result);
174
191
    return ret;
175
192
  }
176
193
 
184
201
    return query(result, str, strlen(str));
185
202
  }
186
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
  }
 
221
private:
 
222
  void read_conf_files();
 
223
 
187
224
  drizzle_con_st b_;
188
225
};
189
226
 
257
294
    return con_.query(result, read());
258
295
  }
259
296
 
 
297
  result_c execute()
 
298
  {
 
299
    return con_.query(read());
 
300
  }
 
301
 
260
302
  std::string read() const
261
303
  {
262
304
    return out_ + in_;
267
309
  std::string out_;
268
310
};
269
311
 
 
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
  
 
343
  map<string, string> conf;
 
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('=');
 
362
      if (i != string::npos)
 
363
        conf[boost::trim_copy(s.substr(0, i))] = boost::trim_copy(s.substr(i + 1));
 
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
 
270
372
}