Author: wyoung
Date: Sun Aug 30 06:29:04 2009
New Revision: 2569
URL: http://svn.gna.org/viewcvs/mysqlpp?rev=2569&view=rev
Log:
- Added a DBDriver-specific error message variable. The next checkin will
have the driver returning internal errors not coming from the C API, the
only source previously.
- Reworked DBDriver::set_option(Option*) to use this new mechanism. It
previously returned the error string directly. Now it returns bool,
storing any error message internally for retrieval by Connection if it
sees a false return. This step isn't required by the previous item,
just a nice use of the new mechansim. (By the way, this does break
the DBDriver ABI, but since end-user code shouldn't be creating
DBDrivers and the only MySQL++ use of the object, by Connection, is
through pointers, it doesn't matter.)
Modified:
trunk/lib/connection.cpp
trunk/lib/dbdriver.cpp
trunk/lib/dbdriver.h
Modified: trunk/lib/connection.cpp
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/connection.cpp?rev=2569&r1=2568&r2=2569&view=diff
==============================================================================
--- trunk/lib/connection.cpp (original)
+++ trunk/lib/connection.cpp Sun Aug 30 06:29:04 2009
@@ -315,11 +315,12 @@
Connection::set_option(Option* o)
{
const std::type_info& oti = typeid(*o);
- error_message_ = driver_->set_option(o);
- if (error_message_.empty()) {
+ if (driver_->set_option(o)) {
+ error_message_.clear();
return true;
}
else {
+ error_message_ = driver_->error();
if (throw_exceptions()) {
throw BadOption(error_message_, oti);
}
Modified: trunk/lib/dbdriver.cpp
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/dbdriver.cpp?rev=2569&r1=2568&r2=2569&view=diff
==============================================================================
--- trunk/lib/dbdriver.cpp (original)
+++ trunk/lib/dbdriver.cpp Sun Aug 30 06:29:04 2009
@@ -78,25 +78,25 @@
unsigned int port, const char* db, const char* user,
const char* password)
{
- connect_prepare();
return is_connected_ =
+ connect_prepare() &&
mysql_real_connect(&mysql_, host, user, password, db,
- port, socket_name, mysql_.client_flag);
+ port, socket_name, mysql_.client_flag);
}
bool
DBDriver::connect(const MYSQL& other)
{
- connect_prepare();
return is_connected_ =
+ connect_prepare() &&
mysql_real_connect(&mysql_, other.host, other.user,
- other.passwd, other.db, other.port, other.unix_socket,
- other.client_flag);
-}
-
-
-void
+ other.passwd, other.db, other.port,
other.unix_socket,
+ other.client_flag);
+}
+
+
+bool
DBDriver::connect_prepare()
{
// Drop previous connection, if any, then prepare underlying C API
@@ -104,7 +104,10 @@
if (connected()) {
disconnect();
}
+
+ // Set up to call MySQL C API
mysql_init(&mysql_);
+ return true;
}
@@ -127,6 +130,7 @@
mysql_close(&mysql_);
memset(&mysql_, 0, sizeof(mysql_));
is_connected_ = false;
+ error_message_.clear();
}
}
@@ -135,6 +139,7 @@
DBDriver::enable_ssl(const char* key, const char* cert,
const char* ca, const char* capath, const char* cipher)
{
+ error_message_.clear();
#if defined(HAVE_MYSQL_SSL_SET)
return mysql_ssl_set(&mysql_, key, cert, ca, capath, cipher) == 0;
#else
@@ -152,6 +157,8 @@
DBDriver::escape_string(std::string* ps, const char* original,
size_t length)
{
+ error_message_.clear();
+
if (ps == 0) {
// Can't do any real work!
return 0;
@@ -219,6 +226,7 @@
string
DBDriver::query_info()
{
+ error_message_.clear();
const char* i = mysql_info(&mysql_);
return i ? string(i) : string();
}
@@ -260,8 +268,21 @@
}
-std::string
+bool
DBDriver::set_option(Option* o)
+{
+ if (connected()) {
+ return set_option_impl(o);
+ }
+ else {
+ error_message_.clear();
+ return true; // we won't know if it fails until ::connect()
+ }
+}
+
+
+bool
+DBDriver::set_option_impl(Option* o)
{
std::ostringstream os;
std::auto_ptr<Option> cleanup(o);
@@ -290,13 +311,15 @@
break;
}
- return os.str();
+ error_message_ = os.str();
+ return error_message_.empty();
}
bool
DBDriver::shutdown()
{
+ error_message_.clear();
return mysql_shutdown(&mysql_ SHUTDOWN_ARG);
}
Modified: trunk/lib/dbdriver.h
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/dbdriver.h?rev=2569&r1=2568&r2=2569&view=diff
==============================================================================
--- trunk/lib/dbdriver.h (original)
+++ trunk/lib/dbdriver.h Sun Aug 30 06:29:04 2009
@@ -82,12 +82,20 @@
/// \brief Return the number of rows affected by the last query
///
/// Wraps \c mysql_affected_rows() in the MySQL C API.
- ulonglong affected_rows() { return mysql_affected_rows(&mysql_); }
+ ulonglong affected_rows()
+ {
+ error_message_.clear();
+ return mysql_affected_rows(&mysql_);
+ }
/// \brief Get database client library version
///
/// Wraps \c mysql_get_client_info() in the MySQL C API.
- std::string client_version() const { return mysql_get_client_info(); }
+ std::string client_version() const
+ {
+ error_message_.clear();
+ return mysql_get_client_info();
+ }
/// \brief Establish a new connection using the same parameters as
/// an existing connection.
@@ -129,7 +137,10 @@
///
/// Wraps mysql_data_seek() in MySQL C API.
void data_seek(MYSQL_RES* res, ulonglong offset) const
- { mysql_data_seek(res, offset); }
+ {
+ error_message_.clear();
+ mysql_data_seek(res, offset);
+ }
/// \brief Drop the connection to the database server
///
@@ -169,7 +180,10 @@
///
/// Can return a MySQL++ DBDriver-specific error message if there
/// is one. If not, it simply wraps \c mysql_error() in the MySQL C
API.
- const char* error() { return mysql_error(&mysql_); }
+ const char* error()
+ {
+ return error_message_.length() ? error_message_.c_str() :
mysql_error(&mysql_);
+ }
/// \brief Return last MySQL error number associated with this
/// connection
@@ -196,6 +210,7 @@
/// \sa escape_string_no_conn(char*, const char*, size_t)
size_t escape_string(char* to, const char* from, size_t length)
{
+ error_message_.clear();
return mysql_real_escape_string(&mysql_, to, from,
static_cast<unsigned long>(length));
}
@@ -268,6 +283,7 @@
/// Wraps \c mysql_real_query() in the MySQL C API.
bool execute(const char* qstr, size_t length)
{
+ error_message_.clear();
return !mysql_real_query(&mysql_, qstr,
static_cast<unsigned long>(length));
}
@@ -280,14 +296,20 @@
///
/// Wraps \c mysql_fetch_row() in MySQL C API.
MYSQL_ROW fetch_row(MYSQL_RES* res) const
- { return mysql_fetch_row(res); }
+ {
+ error_message_.clear();
+ return mysql_fetch_row(res);
+ }
/// \brief Returns the lengths of the fields in the current row
/// from a "use" query.
///
/// Wraps \c mysql_fetch_lengths() in MySQL C API.
const unsigned long* fetch_lengths(MYSQL_RES* res) const
- { return mysql_fetch_lengths(res); }
+ {
+ error_message_.clear();
+ return mysql_fetch_lengths(res);
+ }
/// \brief Returns information about a particular field in a result
/// set
@@ -304,6 +326,7 @@
/// MySQL C API. (Which one it uses depends on i parameter.)
MYSQL_FIELD* fetch_field(MYSQL_RES* res, size_t i = UINT_MAX) const
{
+ error_message_.clear();
return i == UINT_MAX ? mysql_fetch_field(res) :
mysql_fetch_field_direct(res,
static_cast<unsigned int>(i));
@@ -313,13 +336,19 @@
///
/// Wraps \c mysql_field_seek() in MySQL C API.
void field_seek(MYSQL_RES* res, size_t field) const
- { mysql_field_seek(res, MYSQL_FIELD_OFFSET(field)); }
+ {
+ error_message_.clear();
+ mysql_field_seek(res, MYSQL_FIELD_OFFSET(field));
+ }
/// \brief Releases memory used by a result set
///
/// Wraps \c mysql_free_result() in MySQL C API.
void free_result(MYSQL_RES* res) const
- { mysql_free_result(res); }
+ {
+ error_message_.clear();
+ mysql_free_result(res);
+ }
/// \brief Return the connection options object
st_mysql_options get_options() const { return mysql_.options; }
@@ -331,7 +360,11 @@
/// named pipe, Unix socket...) and the server hostname.
///
/// Wraps \c mysql_get_host_info() in the MySQL C API.
- std::string ipc_info() { return mysql_get_host_info(&mysql_); }
+ std::string ipc_info()
+ {
+ error_message_.clear();
+ return mysql_get_host_info(&mysql_);
+ }
/// \brief Get ID generated for an AUTO_INCREMENT column in the
/// previous INSERT query.
@@ -343,7 +376,11 @@
/// the ID generated by the last query, which was a CALL statement,
/// and CALL doesn't generate IDs. You need to use LAST_INSERT_ID()
/// to get the ID in this case.
- ulonglong insert_id() { return mysql_insert_id(&mysql_); }
+ ulonglong insert_id()
+ {
+ error_message_.clear();
+ return mysql_insert_id(&mysql_);
+ }
/// \brief Kill a MySQL server thread
///
@@ -352,7 +389,11 @@
/// Wraps \c mysql_kill() in the MySQL C API.
///
/// \see thread_id()
- bool kill(unsigned long tid) { return !mysql_kill(&mysql_, tid); }
+ bool kill(unsigned long tid)
+ {
+ error_message_.clear();
+ return !mysql_kill(&mysql_, tid);
+ }
/// \brief Returns true if there are unconsumed results from the
/// most recent query.
@@ -360,6 +401,7 @@
/// Wraps \c mysql_more_results() in the MySQL C API.
bool more_results()
{
+ error_message_.clear();
#if MYSQL_VERSION_ID > 41000 // only in MySQL v4.1 +
return mysql_more_results(&mysql_);
#else
@@ -378,6 +420,7 @@
/// enum values.
nr_code next_result()
{
+ error_message_.clear();
#if MYSQL_VERSION_ID > 41000 // only in MySQL v4.1 +
switch (mysql_next_result(&mysql_)) {
case 0: return nr_more_results;
@@ -393,13 +436,19 @@
///
/// Wraps \c mysql_num_fields() in MySQL C API.
int num_fields(MYSQL_RES* res) const
- { return mysql_num_fields(res); }
-
+ {
+ error_message_.clear();
+ return mysql_num_fields(res);
+ }
+
/// \brief Returns the number of rows in the given result set
///
/// Wraps \c mysql_num_rows() in MySQL C API.
ulonglong num_rows(MYSQL_RES* res) const
- { return mysql_num_rows(res); }
+ {
+ error_message_.clear();
+ return mysql_num_rows(res);
+ }
/// \brief "Pings" the MySQL database
///
@@ -411,13 +460,21 @@
/// \retval false if either we already know the connection is down
/// and cannot re-establish it, or if the server did not respond to
/// the ping and we could not re-establish the connection.
- bool ping() { return !mysql_ping(&mysql_); }
+ bool ping()
+ {
+ error_message_.clear();
+ return !mysql_ping(&mysql_);
+ }
/// \brief Returns version number of MySQL protocol this connection
/// is using
///
/// Wraps \c mysql_get_proto_info() in the MySQL C API.
- int protocol_version() { return mysql_get_proto_info(&mysql_); }
+ int protocol_version()
+ {
+ error_message_.clear();
+ return mysql_get_proto_info(&mysql_);
+ }
/// \brief Returns information about the last executed query
///
@@ -432,21 +489,37 @@
/// because it was undocumented until recently, and it's a pretty
/// low-level thing. It's designed for things like MySQL
/// Administrator.
- bool refresh(unsigned options) { return !mysql_refresh(&mysql_,
options); }
+ bool refresh(unsigned options)
+ {
+ error_message_.clear();
+ return !mysql_refresh(&mysql_, options);
+ }
/// \brief Returns true if the most recent result set was empty
///
/// Wraps \c mysql_field_count() in the MySQL C API, returning true
/// if it returns 0.
- bool result_empty() { return mysql_field_count(&mysql_) == 0; }
+ bool result_empty()
+ {
+ error_message_.clear();
+ return mysql_field_count(&mysql_) == 0;
+ }
/// \brief Asks the database server to switch to a different database
- bool select_db(const char* db) { return !mysql_select_db(&mysql_, db); }
+ bool select_db(const char* db)
+ {
+ error_message_.clear();
+ return !mysql_select_db(&mysql_, db);
+ }
/// \brief Get the database server's version number
///
/// Wraps \c mysql_get_server_info() in the MySQL C API.
- std::string server_version() { return mysql_get_server_info(&mysql_); }
+ std::string server_version()
+ {
+ error_message_.clear();
+ return mysql_get_server_info(&mysql_);
+ }
/// \brief Sets a connection option
///
@@ -456,13 +529,14 @@
/// setting.
///
/// \see Connection::set_option(Option*) for commentary
- std::string set_option(Option* o);
+ bool set_option(Option* o);
/// \brief Set MySQL C API connection option
///
/// \internal Wraps \c mysql_options() in C API.
bool set_option(mysql_option moption, const void* arg = 0)
{
+ error_message_.clear();
return !mysql_options(&mysql_, moption,
static_cast<const char*>(arg));
}
@@ -473,6 +547,7 @@
/// \internal Wraps \c mysql_set_server_option() in C API.
bool set_option(enum_mysql_set_option msoption)
{
+ error_message_.clear();
return !mysql_set_server_option(&mysql_, msoption);
}
#endif
@@ -486,7 +561,7 @@
/// \brief Same as set_option(), except that it won't override
/// a previously-set option.
- std::string set_option_default(Option* o)
+ bool set_option_default(Option* o)
{
const std::type_info& ti = typeid(o);
for (OptionList::const_iterator it = applied_options_.begin();
@@ -516,7 +591,11 @@
/// and open tables.
///
/// Wraps \c mysql_stat() in the MySQL C API.
- std::string server_status() { return mysql_stat(&mysql_); }
+ std::string server_status()
+ {
+ error_message_.clear();
+ return mysql_stat(&mysql_);
+ }
/// \brief Saves the results of the query just execute()d in memory
/// and returns a pointer to the MySQL C API data structure the
@@ -525,7 +604,11 @@
/// \sa use_result()
///
/// Wraps \c mysql_store_result() in the MySQL C API.
- MYSQL_RES* store_result() { return mysql_store_result(&mysql_); }
+ MYSQL_RES* store_result()
+ {
+ error_message_.clear();
+ return mysql_store_result(&mysql_);
+ }
/// \brief Returns true if MySQL++ and the underlying MySQL C API
/// library were both compiled with thread awareness.
@@ -555,7 +638,11 @@
///
/// This has nothing to do with threading on the client side. It's
/// a server-side thread ID, to be used with kill().
- unsigned long thread_id() { return mysql_thread_id(&mysql_); }
+ unsigned long thread_id()
+ {
+ error_message_.clear();
+ return mysql_thread_id(&mysql_);
+ }
/// \brief Tells the underlying C API library that the current
/// thread will be using the library's services.
@@ -591,12 +678,20 @@
/// \sa store_result
///
/// Wraps \c mysql_use_result() in the MySQL C API.
- MYSQL_RES* use_result() { return mysql_use_result(&mysql_); }
+ MYSQL_RES* use_result()
+ {
+ error_message_.clear();
+ return mysql_use_result(&mysql_);
+ }
protected:
/// \brief Does things common to both connect() overloads, before
/// each go and establish the connection in their different ways.
- void connect_prepare();
+ bool connect_prepare();
+
+ /// \brief Common implementation of set_option(Option*) and the
+ /// delayed option setting code in connect_prepare()
+ bool set_option_impl(Option* o);
private:
/// \brief Data type of the list of applied connection options
@@ -609,6 +704,7 @@
MYSQL mysql_;
bool is_connected_;
OptionList applied_options_;
+ mutable std::string error_message_;
};
_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits