The Battle for Wesnoth  1.15.3+dev
connection.cpp
Go to the documentation of this file.
1 //
2 // M A R I A D B + +
3 //
4 // Copyright Sylvain Rochette Langlois 2013,
5 // Frantisek Boranek 2015,
6 // The ViaDuck Project 2016 - 2018.
7 // Distributed under the Boost Software License, Version 1.0.
8 // (See accompanying file LICENSE or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 #include <mysql.h>
12 #include <mariadb++/connection.hpp>
13 #include "private.hpp"
14 
15 using namespace mariadb;
16 
17 #define MYSQL_ERROR_DISCONNECT(mysql) \
18  { \
19  m_last_error_no = mysql_errno(mysql); \
20  m_last_error = mysql_error(mysql); \
21  disconnect(); \
22  MARIADB_ERROR(m_last_error_no, m_last_error); \
23  }
24 
26  : m_mysql(NULL), m_auto_commit(true), m_account(account) {}
27 
29  return connection_ref(new connection(account));
30 }
31 
33 
34 const std::string& connection::schema() const { return m_schema; }
35 
37  if (!connect()) return false;
38 
39  if (mysql_select_db(m_mysql, schema.c_str())) MYSQL_ERROR(m_mysql);
40 
41  m_schema = schema;
42  return true;
43 }
44 
45 const std::string& connection::charset() const { return m_charset; }
46 
48  if (!connect()) return false;
49 
50  if (mysql_set_character_set(m_mysql, value.c_str())) MYSQL_ERROR(m_mysql);
51 
52  m_charset = value;
53  return true;
54 }
55 
56 bool connection::connected() const {
57  if (m_mysql == nullptr)
58  return false;
59  else
60  return !mysql_ping(m_mysql);
61 }
62 
64 
65 bool connection::auto_commit() const { return m_auto_commit; }
66 
68  if (m_auto_commit == auto_commit) return true;
69 
70  if (!connect()) return false;
71 
72  if (mysql_autocommit(m_mysql, auto_commit)) MYSQL_ERROR(m_mysql);
73 
75  return true;
76 }
77 
79  if (connected()) return true;
80 
81  if (m_mysql == nullptr) {
82  m_mysql = mysql_init(nullptr);
83 
84  if (!m_mysql) {
85  MARIADB_ERROR(0, "Cannot create MYSQL object.");
86  }
87  }
88 
89  if (!m_account->ssl_key().empty()) {
90  if (mysql_ssl_set(m_mysql, m_account->ssl_key().c_str(),
91  m_account->ssl_certificate().c_str(), m_account->ssl_ca().c_str(),
92  m_account->ssl_ca_path().c_str(), m_account->ssl_cipher().c_str()))
94  }
95 
96  //
97  // set connect options
98  //
99  for (auto& pair : m_account->connect_options()) {
100  if (0 != mysql_options(m_mysql, pair.first, pair.second->value()))
102  }
103 
104  if (!mysql_real_connect(
105  m_mysql, m_account->host_name().c_str(), m_account->user_name().c_str(),
106  m_account->password().c_str(), nullptr, m_account->port(),
107  m_account->unix_socket().empty() ? nullptr : m_account->unix_socket().c_str(),
108  CLIENT_MULTI_STATEMENTS))
110 
112 
113  if (!m_account->schema().empty()) {
114  if (!set_schema(m_account->schema().c_str())) MYSQL_ERROR_DISCONNECT(m_mysql);
115  }
116 
117  //
118  // Set options
119  //
120  for (auto& pair : m_account->options()) {
121  if (1 != execute("SET OPTION " + pair.first + "=" + pair.second))
123  }
124 
125  return true;
126 }
127 
129  if (!m_mysql) return;
130 
131  mysql_close(m_mysql);
132  mysql_thread_end(); // mysql_init() call mysql_thread_init therefor it needed to clear memory
133  // when closed msql handle
134  m_mysql = nullptr;
135 }
136 
138  result_set_ref rs;
139 
140  if (!connect()) return rs;
141 
142  if (mysql_real_query(m_mysql, query.c_str(), query.size())) {
144  }
145 
146  rs.reset(new result_set(this));
147  return rs;
148 }
149 
151  if (!connect()) return 0;
152 
153  u64 affected_rows = 0;
154 
155  if (mysql_real_query(m_mysql, query.c_str(), query.size())) {
157  }
158 
159  int status;
160  do {
161  MYSQL_RES* result = mysql_store_result(m_mysql);
162 
163  if (result)
164  mysql_free_result(result);
165  else if (mysql_field_count(m_mysql) == 0)
166  affected_rows += mysql_affected_rows(m_mysql);
167  else {
169  }
170 
171  status = mysql_next_result(m_mysql);
172  if (status > 0) {
174  }
175  } while (status == 0);
176 
177  return affected_rows;
178 }
179 
181  if (!connect()) return 0;
182 
183  if (mysql_real_query(m_mysql, query.c_str(), query.size())) {
185  }
186 
187  return mysql_insert_id(m_mysql);
188 }
189 
191  if (!connect()) return statement_ref();
192 
193  return statement_ref(new statement(this, query));
194 }
195 
197  if (!connect()) return transaction_ref();
198 
199  return transaction_ref(new transaction(this, level, consistent_snapshot));
200 }
transaction_ref create_transaction(isolation::level level=isolation::repeatable_read, bool consistent_snapshot=true)
Create a transaction.
Definition: connection.cpp:196
bool set_schema(const std::string &schema)
Sets the schema (database name).
Definition: connection.cpp:36
std::shared_ptr< transaction > transaction_ref
Definition: transaction.hpp:78
std::shared_ptr< result_set > result_set_ref
Definition: result_set.hpp:219
std::shared_ptr< account > account_ref
Definition: account.hpp:19
void disconnect()
Disconnects from the database.
Definition: connection.cpp:128
result_set_ref query(const std::string &query)
Execute a query with an result (if no result is returned, the result_set will be empty).
Definition: connection.cpp:137
#define MARIADB_ERROR(error_id, error)
Definition: private.hpp:51
#define MYSQL_ERROR_DISCONNECT(mysql)
Definition: connection.cpp:17
account_ref m_account
Definition: connection.hpp:200
#define MYSQL_ERROR_NO_BRAKET(mysql)
Definition: private.hpp:57
Class used to store account and connection information used by mariadb::connection when connecting...
Definition: account.hpp:46
u64 insert(const std::string &query)
Execute a query (usually, but not limited to INSERT) with interest for the last row id...
Definition: connection.cpp:180
friend class transaction
Definition: connection.hpp:30
std::string m_charset
Definition: connection.hpp:198
virtual ~connection()
Destroys connection and automatically disconnects.
Definition: connection.cpp:32
bool connected() const
Indicates whether the connection is active.
Definition: connection.cpp:56
friend class result_set
Definition: connection.hpp:28
#define MYSQL_ERROR(mysql)
Definition: private.hpp:62
account_ref account() const
Gets the account associated with this connection.
Definition: connection.cpp:63
bool connect()
Actually connects to the database using given account, sets SSL and additional options as well as aut...
Definition: connection.cpp:78
static connection_ref create(const account_ref &account)
Creates a new connection using the given account.
Definition: connection.cpp:28
bool set_auto_commit(bool auto_commit)
Sets the auto_commit setting.
Definition: connection.cpp:67
std::string m_schema
Definition: connection.hpp:196
u64 execute(const std::string &query)
Execute a query without interest in a result.
Definition: connection.cpp:150
bool set_charset(const std::string &value)
Sets the charset.
Definition: connection.cpp:47
bool auto_commit() const
Gets the status of the auto_commit setting.
Definition: connection.cpp:65
unsigned long long u64
Definition: types.hpp:34
std::shared_ptr< connection > connection_ref
Definition: statement.hpp:33
connection(const account_ref &account)
Private constructor used to create a connection with the given account.
Definition: connection.cpp:25
const std::string & charset() const
Gets the charset associated with this connection.
Definition: connection.cpp:45
std::shared_ptr< statement > statement_ref
Definition: statement.hpp:109
const std::string & schema() const
Gets the schema (database name)
Definition: connection.cpp:34
statement_ref create_statement(const std::string &query)
Create a prepared statement.
Definition: connection.cpp:190
friend class statement
Definition: connection.hpp:29