Author: wyoung
Date: Thu May 12 18:38:37 2011
New Revision: 2690

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=2690&view=rev
Log:
Query::storein() now correctly distinguishes two cases where the
underlying "use" query returns an empty result set from the expected
normal case where this always gives results.  It can happen when the
DBMS barfs, and when someone passes us something like an INSERT query
even though that makes no sense with storein().  These situations no
longer cause MySQL++ to crash or lie to the caller that all is well.

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

Modified: trunk/lib/query.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/query.cpp?rev=2690&r1=2689&r2=2690&view=diff
==============================================================================
--- trunk/lib/query.cpp (original)
+++ trunk/lib/query.cpp Thu May 12 18:38:37 2011
@@ -476,6 +476,13 @@
 }
 
 
+bool
+Query::result_empty()
+{
+       return conn_->driver()->result_empty();
+}
+
+
 StoreQueryResult 
 Query::store() 
 { 

Modified: trunk/lib/query.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/query.h?rev=2690&r1=2689&r2=2690&view=diff
==============================================================================
--- trunk/lib/query.h (original)
+++ trunk/lib/query.h Thu May 12 18:38:37 2011
@@ -274,6 +274,11 @@
        /// or the stream interface.)
        void reset();
 
+       /// \brief Returns true if the most recent result set was empty
+       ///
+       /// Wraps DBDriver::result_empty()
+       bool result_empty();
+
        /// \brief Get built query as a C++ string
        std::string str() { return str(template_defaults); }
 
@@ -748,17 +753,30 @@
        template <class Sequence>
        void storein_sequence(Sequence& con, const SQLTypeAdapter& s)
        {
-               UseQueryResult result = use(s);
-               while (1) {
-                       MYSQL_ROW d = result.fetch_raw_row();
-                       if (!d)
-                               break;
-                       Row row(d, &result, result.fetch_lengths(),
-                                       throw_exceptions());
-                       if (!row)
-                               break;
-                       con.push_back(typename Sequence::value_type(row));
-               }
+               if (UseQueryResult result = use(s)) {
+                       while (1) {
+                               MYSQL_ROW d = result.fetch_raw_row();
+                               if (!d) break;
+                               Row row(d, &result, result.fetch_lengths(),
+                                               throw_exceptions());
+                               if (!row) break;
+                               con.push_back(typename 
Sequence::value_type(row));
+                       }
+               }
+               else if (!result_empty()) {
+                       // Underlying MySQL C API returned an empty result for 
this
+                       // query, but it also says it should have returned
+                       // something.  Reasons it can do that are given here:
+                       // 
http://dev.mysql.com/doc/refman/5.5/en/null-mysql-store-result.html
+                       // Regardless, it means the C library barfed, so we 
can't
+                       // just return an empty result set.
+                       copacetic_ = false;
+                       if (throw_exceptions()) {
+                               throw UseQueryError("Bogus empty result");
+                       }
+               }
+               // else, it was *supposed* to return nothing, because query was
+               // an INSERT, CREATE, etc. sort.  So, leave con untouched.
        }
 
        /// \brief Execute template query using given parameters, storing
@@ -806,17 +824,30 @@
        template <class Set>
        void storein_set(Set& con, const SQLTypeAdapter& s)
        {
-               UseQueryResult result = use(s);
-               while (1) {
-                       MYSQL_ROW d = result.fetch_raw_row();
-                       if (!d)
-                               return;
-                       Row row(d, &result, result.fetch_lengths(),
-                                       throw_exceptions());
-                       if (!row)
-                               break;
-                       con.insert(typename Set::value_type(row));
-               }
+               if (UseQueryResult result = use(s)) {
+                       while (1) {
+                               MYSQL_ROW d = result.fetch_raw_row();
+                               if (!d) break;
+                               Row row(d, &result, result.fetch_lengths(),
+                                               throw_exceptions());
+                               if (!row) break;
+                               con.insert(typename Set::value_type(row));
+                       }
+               }
+               else if (!result_empty()) {
+                       // Underlying MySQL C API returned an empty result for 
this
+                       // query, but it also says it should have returned
+                       // something.  Reasons it can do that are given here:
+                       // 
http://dev.mysql.com/doc/refman/5.5/en/null-mysql-store-result.html
+                       // Regardless, it means the C library barfed, so we 
can't
+                       // just return an empty result set.
+                       copacetic_ = false;
+                       if (throw_exceptions()) {
+                               throw UseQueryError("Bogus empty result");
+                       }
+               }
+               // else, it was *supposed* to return nothing, because query was
+               // an INSERT, CREATE, etc. sort.  So, leave con untouched.
        }
 
        /// \brief Execute template query using given parameters, storing


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

Reply via email to