libdballe  7.19
mysql.h
Go to the documentation of this file.
1 
4 #ifndef DBALLE_SQL_MYSQL_H
5 #define DBALLE_SQL_MYSQL_H
6 
7 #include <dballe/sql/sql.h>
8 #include <mysql.h>
9 #include <cstdlib>
10 #include <vector>
11 
12 namespace dballe {
13 namespace sql {
14 struct MySQLStatement;
15 
19 struct error_mysql : public error_db
20 {
21  std::string msg;
22 
23  error_mysql(MYSQL* db, const std::string& msg);
24  error_mysql(const std::string& dbmsg, const std::string& msg);
25  ~error_mysql() throw () {}
26 
27  const char* what() const noexcept override { return msg.c_str(); }
28 
29  static void throwf(MYSQL* db, const char* fmt, ...) WREPORT_THROWF_ATTRS(2, 3);
30 };
31 
32 namespace mysql {
33 
35 {
36  std::string host;
37  std::string user;
38  bool has_passwd = false;
39  std::string passwd;
40  bool has_dbname = false;
41  std::string dbname;
42  unsigned port = 0;
43  std::string unix_socket;
44 
45  // Reset everything to defaults
46  void reset();
47  void parse_url(const std::string& url);
48  // Modeled after http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
49  std::string to_url() const;
50 };
51 
52 struct Row
53 {
54  MYSQL_RES* res = nullptr;
55  MYSQL_ROW row = nullptr;
56 
57  Row(MYSQL_RES* res, MYSQL_ROW row) : res(res), row(row) {}
58 
59  operator bool() const { return row != nullptr; }
60  operator MYSQL_ROW() { return row; }
61  operator const MYSQL_ROW() const { return row; }
62 
63  int as_int(unsigned col) const { return strtol(row[col], 0, 10); }
64  unsigned as_unsigned(unsigned col) const { return strtoul(row[col], 0, 10); }
65  const char* as_cstring(unsigned col) const { return row[col]; }
66  std::string as_string(unsigned col) const { return std::string(row[col], mysql_fetch_lengths(res)[col]); }
67  std::vector<uint8_t> as_blob(unsigned col) const
68  {
69  return std::vector<uint8_t>(row[col], row[col] + mysql_fetch_lengths(res)[col]);
70  }
71  Datetime as_datetime(int col) const;
72  bool isnull(unsigned col) const { return row[col] == nullptr; }
73 };
74 
75 struct Result
76 {
77  MYSQL_RES* res = nullptr;
78 
79  Result() : res(nullptr) {}
80  Result(MYSQL_RES* res) : res(res) {}
81  ~Result() { if (res) mysql_free_result(res); }
82 
84  Result(Result&& o) : res(o.res) { o.res = nullptr; }
85  Result& operator=(Result&& o)
86  {
87  if (this == &o) return *this;
88  if (res) mysql_free_result(res);
89  res = o.res;
90  o.res = nullptr;
91  return *this;
92  }
93 
94  operator bool() const { return res != nullptr; }
95 
96  operator MYSQL_RES*() { return res; }
97  operator const MYSQL_RES*() const { return res; }
98 
99  unsigned rowcount() const { return mysql_num_rows(res); }
100  unsigned colcount() const { return mysql_num_fields(res); }
101 
103  Row expect_one_result();
104 
114  Row fetch() { return Row(res, mysql_fetch_row(res)); }
115 
116  // Prevent copy
117  Result(const Result&) = delete;
118  Result& operator=(const Result&) = delete;
119 };
120 
121 }
122 
123 
126 {
127 protected:
129  MYSQL* db = nullptr;
130 
131  void send_result(mysql::Result&& res, std::function<void(const mysql::Row&)> dest);
132 
133 protected:
134  void init_after_connect();
135 
136  // See https://dev.mysql.com/doc/refman/5.0/en/mysql-real-connect.html
137  void open(const mysql::ConnectInfo& info);
138 
139 public:
140  MySQLConnection();
141  MySQLConnection(const MySQLConnection&) = delete;
142  MySQLConnection(const MySQLConnection&&) = delete;
143  ~MySQLConnection();
144  MySQLConnection& operator=(const MySQLConnection&) = delete;
145  MySQLConnection& operator=(const MySQLConnection&&) = delete;
146 
147  operator MYSQL*() { return db; }
148 
149  // See http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
150  void open_url(const std::string& url);
151  void open_test();
152 
154  std::string escape(const char* str);
156  std::string escape(const std::string& str);
158  std::string escape(const std::vector<uint8_t>& str);
159 
164  void exec_no_data_nothrow(const char* query) noexcept;
165  // Run a query, checking that it is successful and it gives no results
166  void exec_no_data(const char* query);
167  // Run a query, checking that it is successful and it gives no results
168  void exec_no_data(const std::string& query);
169  // Run a query, with a locally stored result
170  mysql::Result exec_store(const char* query);
171  // Run a query, with a locally stored result
172  mysql::Result exec_store(const std::string& query);
173  // Run a query, with a remotely fetched result
174  void exec_use(const char* query, std::function<void(const mysql::Row&)> dest);
175  // Run a query, with a remotely fetched result
176  void exec_use(const std::string& query, std::function<void(const mysql::Row&)> dest);
177 
178  std::unique_ptr<Transaction> transaction() override;
179  bool has_table(const std::string& name) override;
180  std::string get_setting(const std::string& key) override;
181  void set_setting(const std::string& key, const std::string& value) override;
182  void drop_settings() override;
183  void execute(const std::string& query) override;
184  void explain(const std::string& query, FILE* out) override;
185 
189  void drop_table_if_exists(const char* name);
190 
197  int get_last_insert_id();
198 };
199 
200 }
201 }
202 #endif
203 
Row fetch()
Fetch one row.
Definition: mysql.h:114
Report a MySQL error.
Definition: mysql.h:19
Result(Result &&o)
Implement move.
Definition: mysql.h:84
Copyright (C) 2008–2010 ARPA-SIM urpsim@smr.arpa.emr.it
Definition: cmdline.h:17
MySQL DB connector.
Definition: mysql.h:75
Definition: sql.h:59
Common infrastructure for talking with SQL databases.
Error in case of failed database operations.
Definition: error.h:21
Definition: mysql.h:34
Date and time.
Definition: types.h:158
#define WREPORT_THROWF_ATTRS(a, b)
Definition: mysql.h:52
Database connection.
Definition: mysql.h:125