Author: wyoung
Date: Thu Oct 25 16:04:47 2007
New Revision: 1788

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1788&view=rev
Log:
Added error number parameters and accessor functions to BadQuery,
ConnectionFailed and DBSelectionFailed exceptions, to preserve the state
of Connection::errnum() at the point of the exception, so you don't have
to rely on this value remaining unchanged during the exception throw
process.  All places that use these exceptions now include this value
where possible.

Initial patch by Jim Wallace, greatly reworked by me.

Modified:
    trunk/lib/connection.cpp
    trunk/lib/exceptions.h
    trunk/lib/query.cpp

Modified: trunk/lib/connection.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/connection.cpp?rev=1788&r1=1787&r2=1788&view=diff
==============================================================================
--- trunk/lib/connection.cpp (original)
+++ trunk/lib/connection.cpp Thu Oct 25 16:04:47 2007
@@ -193,7 +193,7 @@
        else {
                copacetic_ = is_connected_ = false;
                if (throw_exceptions()) {
-                       throw ConnectionFailed(error());
+                       throw ConnectionFailed(error(), errnum());
                }
        }
 
@@ -232,7 +232,7 @@
        else {
                copacetic_ = is_connected_ = false;
                if (throw_exceptions()) {
-                       throw ConnectionFailed(error());
+                       throw ConnectionFailed(error(), errnum());
                }
        }
 
@@ -295,7 +295,7 @@
        if (connected()) {
                bool suc = !(mysql_select_db(&mysql_, db));
                if (throw_exceptions() && !suc) {
-                       throw DBSelectionFailed(error());
+                       throw DBSelectionFailed(error(), errnum());
                }
                else {
                        return suc;
@@ -324,7 +324,7 @@
                        // query, but it's acceptable to signal errors with 
BadQuery
                        // because the new mechanism is the FLUSH PRIVILEGES 
query.
                        // A program won't have to change when doing it the new 
way.
-                       throw BadQuery(error());
+                       throw BadQuery(error(), errnum());
                }
                else {
                        return suc;
@@ -332,7 +332,7 @@
        }
        else {
                if (throw_exceptions()) {
-                       throw BadQuery("MySQL++ connection not established");
+                       throw ConnectionFailed("MySQL++ connection not 
established");
                }
                else {
                        build_error_message("reload grant tables");
@@ -349,7 +349,7 @@
        if (connected()) {
                bool suc = !(mysql_shutdown(&mysql_ SHUTDOWN_ARG));
                if (throw_exceptions() && !suc) {
-                       throw ConnectionFailed(error());
+                       throw ConnectionFailed(error(), errnum());
                }
                else {
                        return suc;

Modified: trunk/lib/exceptions.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/exceptions.h?rev=1788&r1=1787&r2=1788&view=diff
==============================================================================
--- trunk/lib/exceptions.h (original)
+++ trunk/lib/exceptions.h Thu Oct 25 16:04:47 2007
@@ -5,10 +5,10 @@
 /// derivative, any of these exceptions can be thrown on error.
 
 /***********************************************************************
- Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
- MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
- Others may also hold copyrights on code in this file.  See the CREDITS
- file in the top directory of the distribution for details.
+ Copyright (c) 1998 by Kevin Atkinson, (c) 1999-2001 by MySQL AB, and
+ (c) 2004-2007 by Educational Technology Resources, Inc.  Others may
+ also hold copyrights on code in this file.  See the CREDITS file in
+ the top directory of the distribution for details.
 
  This file is part of MySQL++.
 
@@ -28,7 +28,7 @@
  USA
 ***********************************************************************/
 
-#ifndef MYSQLPP_EXCEPTIONS_H
+#if !defined(MYSQLPP_EXCEPTIONS_H)
 #define MYSQLPP_EXCEPTIONS_H
 
 #include "connection.h"
@@ -251,6 +251,15 @@
 /// \brief Exception thrown when the database server encounters a problem
 /// while processing your query.
 ///
+/// Unlike most other MySQL++ exceptions, which carry just an error
+/// message, this type carries an error number to preserve
+/// Connection::errnum()'s return value at the point the exception is 
+/// thrown.  We do this because when using the Transaction class, the
+/// rollback process that occurs during stack unwinding issues a query
+/// to the database server, overwriting the error value.  This rollback
+/// should always succeed, so this effect can fool code that relies on
+/// Connection::errnum() into believing that there was no error.
+///
 /// Beware that in older versions of MySQL++, this was effectively the
 /// generic exception type.  (This is most especially true in v1.7.x,
 /// but it continued to a lesser extent through the v2.x series.)  When
@@ -262,46 +271,102 @@
 class MYSQLPP_EXPORT BadQuery : public Exception
 {
 public:
-       /// \brief Create exception object, taking C string
-       explicit BadQuery(const char* w = "") :
-       Exception(w)
-       {
-       }
-
-       /// \brief Create exception object, taking C++ string
-       explicit BadQuery(const std::string& w) :
-       Exception(w)
-       {
-       }
-};
-
-
-/// \brief Exception thrown when there is a problem establishing the
-/// database server connection.  It's also thrown if
-/// Connection::shutdown() fails.
+       /// \brief Create exception object
+       ///
+       /// \param w explanation for why the exception was thrown
+       /// \param e the error number from the underlying database API
+       explicit BadQuery(const char* w = "", int e = 0) :
+       Exception(w), 
+       errnum_(e)
+       {
+       }
+
+       /// \brief Create exception object
+       ///
+       /// \param w explanation for why the exception was thrown
+       /// \param e the error number from the underlying database API
+       explicit BadQuery(const std::string& w, int e = 0) :
+       Exception(w), 
+       errnum_(e)
+       {
+       }
+
+       /// \brief Return the error number corresponding to the error
+       /// message returned by what()
+       ///
+       /// This may return the same value as Connection::errnum(), but not
+       /// always.  See the overview documentation for this class for the
+       /// reason for the difference.
+       int errnum() const { return errnum_; }
+       
+private:       
+       int     errnum_;        ///< error number associated with execption
+};
+
+
+/// \brief Exception thrown when there is a problem related to the
+/// database server connection.
+///
+/// This is thrown not just on making the connection, but also on
+/// shutdown and when calling certain of Connection's methods that
+/// require a connection when there isn't one.
 
 class MYSQLPP_EXPORT ConnectionFailed : public Exception
 {
 public:
        /// \brief Create exception object
-       explicit ConnectionFailed(const char* w = "") :
-       Exception(w)
-       {
-       }
+       ///
+       /// \param w explanation for why the exception was thrown
+       /// \param err the error number from the underlying database API
+       explicit ConnectionFailed(const char* w = "", int e = 0) :
+       Exception(w),
+       errnum_(e)
+       {
+       }
+
+       /// \brief Return the error number corresponding to the error
+       /// message returned by what(), if any.
+       ///
+       /// If the error number is 0, it means that the error message
+       /// doesn't come from the underlying database API, but rather from
+       /// MySQL++ itself.  This happens when an error condition is
+       /// detected up at this higher level instead of letting the
+       /// underlying database API do it.
+       int errnum() const { return errnum_; }
+       
+private:       
+       int     errnum_;        ///< error number associated with execption
 };
 
 
 /// \brief Exception thrown when the program tries to select a new
-/// database and the server refuses for some reason.
+/// database and the database server refuses for some reason.
 
 class MYSQLPP_EXPORT DBSelectionFailed : public Exception
 {
 public:
        /// \brief Create exception object
-       explicit DBSelectionFailed(const char* w = "") :
-       Exception(w)
-       {
-       }
+       ///
+       /// \param w explanation for why the exception was thrown
+       /// \param err the error number from the underlying database API
+       explicit DBSelectionFailed(const char* w = "", int e = 0) :
+       Exception(w),
+       errnum_(e)
+       {
+       }
+
+       /// \brief Return the error number corresponding to the error
+       /// message returned by what(), if any.
+       ///
+       /// If the error number is 0, it means that the error message
+       /// doesn't come from the underlying database API, but rather from
+       /// MySQL++ itself.  This happens when an error condition is
+       /// detected up at this higher level instead of letting the
+       /// underlying database API do it.
+       int errnum() const { return errnum_; }
+       
+private:       
+       int     errnum_;        ///< error number associated with execption
 };
 
 
@@ -375,4 +440,4 @@
 
 } // end namespace mysqlpp
 
-#endif
+#endif // !defined(MYSQLPP_EXCEPTIONS_H)

Modified: trunk/lib/query.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/query.cpp?rev=1788&r1=1787&r2=1788&view=diff
==============================================================================
--- trunk/lib/query.cpp (original)
+++ trunk/lib/query.cpp Thu Oct 25 16:04:47 2007
@@ -90,7 +90,7 @@
        copacetic_ = !mysql_real_query(&conn_->mysql_, str.data(),
                        static_cast<unsigned long>(str.length()));
        if (!copacetic_ && throw_exceptions()) {
-               throw BadQuery(error());
+               throw BadQuery(error(), errnum());
        }
        else {
                return copacetic_;
@@ -131,7 +131,7 @@
                return ResNSel(conn_);
        }
        else if (throw_exceptions()) {
-               throw BadQuery(error());
+               throw BadQuery(error(), errnum());
        }
        else {
                return ResNSel();
@@ -414,7 +414,7 @@
                        return Result();
                }
                else {
-                       throw BadQuery(error());
+                       throw BadQuery(error(), errnum());
                }
        }
 }
@@ -437,7 +437,7 @@
                        // result set, which is harmless.  We return an empty 
result
                        // set if exceptions are disabled, as well.
                        if (conn_->errnum() && throw_exceptions()) {
-                               throw BadQuery(error());
+                               throw BadQuery(error(), errnum());
                        } 
                        else {
                                return Result();
@@ -446,7 +446,7 @@
        }
        else if (throw_exceptions()) {
         if (ret > 0) {
-            throw BadQuery(error());
+            throw BadQuery(error(), errnum());
         }
         else {
             throw EndOfResultSets();
@@ -520,7 +520,7 @@
                        return ResUse();
                }
                else {
-                       throw BadQuery(error());
+                       throw BadQuery(error(), errnum());
                }
        }
 }


_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits

Reply via email to