Author: wyoung
Date: Tue Jun 26 06:16:30 2007
New Revision: 1615

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1615&view=rev
Log:
- Fixed the SSQLS BLOB incompatibility!  Just had to give ColData a copy
  ctor, change the sql_blob typedefs to use ColData instead of
  std::string, and change the operator<<() for ColData.  Thus, if you use
  sql_blob in your SSQLS definition, the data conversion path goes from
  MYSQL_ROW data to ColData, and then is copied into the ColData field in
  the SSQLS directly.  The operator<<() change is needed because it used
  to use ColData::c_str() in the insertion process.
- Changed cgi_jpeg example to use the new mechanism
- Updated the new SSQLS chapter section on BLOBs to reflect all this
- A few other minor changes related to all this

Modified:
    trunk/Wishlist
    trunk/doc/userman/userman.dbx
    trunk/examples/cgi_jpeg.cpp
    trunk/lib/coldata.h
    trunk/lib/manip.cpp
    trunk/lib/sql_types.h

Modified: trunk/Wishlist
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/Wishlist?rev=1615&r1=1614&r2=1615&view=diff
==============================================================================
--- trunk/Wishlist (original)
+++ trunk/Wishlist Tue Jun 26 06:16:30 2007
@@ -18,11 +18,6 @@
 
       http://lists.mysql.com/plusplus/6631
     
-    o Create a type dedicated to holding BLOB data, then add that
-      type to ColData?  This would fix the SSQLS incompatibilty.
-      Only other way would be to redesign the convert-via-ColData
-      mechanism, which will have to wait for v3.
-
     o Define HAVE_MYSQL_SSL_SET by default on Windows?  Make similar
       decisions for other autoconf-only macros.
 
@@ -254,9 +249,7 @@
     some definite date, get coding and provide a patch!
 
     o SSQLS v2.  Not sure how it will look yet, but there are ideas
-      in play, and patches to study.  Consider removing ColData at
-         the same time, as it's the culprit in SSQLS BLOB
-         incompatibility.
+      in play, and patches to study.
 
     o Figure out some way to name debug DLL and library under VC++
       differently (trailing 'd'?) to prevent some problems due

Modified: trunk/doc/userman/userman.dbx
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/doc/userman/userman.dbx?rev=1615&r1=1614&r2=1615&view=diff
==============================================================================
--- trunk/doc/userman/userman.dbx (original)
+++ trunk/doc/userman/userman.dbx Tue Jun 26 06:16:30 2007
@@ -1643,36 +1643,39 @@
     <sect2>
         <title>SSQLS and BLOB Columns</title>
 
-        <para>You can't currently use SSQLS to store binary
-        data.</para>
-
-        <para>BLOB columns are truncated when they contain null
-        characters if you store them in an SSQLS. This happens because
-        to get from the raw data format returned by the MySQL database
-        to an SSQLS field, the data goes through a conversion step via
-        <ulink type="classref" url="ColData__Tmpl">ColData</ulink>. The
-        most correct target type for a BLOB column is
-        <classname>mysqlpp::sql_blob</classname>, which is
-        currently an alias for <classname>std::string</classname>.
-        <classname>ColData</classname> converts to that via
-        <methodname>ColData::operator cchar*()</methodname>,
-        which means the data is treated as a C string, so embedded
-        nulls are treated as end-of-data markers. We can't just
-        add an <methodname>operator std::string</methodname> to
-        <classname>ColData</classname>, because that creates a bunch
-        of type conversion ambiguities.</para>
-
-        <para>I'm documenting this here because I don't
-        see any easy fixes. The fix might require redesigning
-        <classname>ColData</classname>, which would have to wait until
-        v3.0. Alternately, we could possibly create a dedicated BLOB
-        data type, to make the correct conversion unambiguous to
-        the compiler.</para>
-
-        <para>In the meantime, you will have to use
-        lower-level mechanisms to deal with BLOB data. See
-        <filename>examples/cgi_jpeg.cpp</filename> for the recommended
-        method.</para>
+        <para>It takes special care to use SSQLS with BLOB
+        columns. It's safest to declare the column as a
+        <classname>mysqlpp::sql_blob</classname> variable. This
+        is currently a typedef alias for <ulink type="classref"
+        url="ColData__Tmpl">ColData</ulink>, which is the form the
+        data is in just before the SSQLS mechanism populates the
+        structure. Thus, you end up getting a simple copy of the
+        <classname>ColData</classname> object's contents, without
+        interference.</para>
+
+        <para>You might think you could use
+        <classname>std::string</classname> instead of
+        <classname>sql_blob</classname>, but the current
+        design of <classname>ColData</classname> converts to
+        <classname>std::string</classname> via a C string. There's
+        no way to fix that without completely redesigning either
+        <classname>ColData</classname> or the SSQLS mechanism.</para>
+
+        <para>The <classname>sql_blob</classname> typedef may be
+        changed to alias a different type in the future, so using it
+        instead of <classname>ColData</classname> ensures that your
+        code tracks these library changes automatically. Besides,
+        <classname>ColData</classname> is only intended to be an
+        internal mechanism within MySQL++. The only reason the
+        layering is so thin here is because it's the only way to
+        prevent BLOB data from being corrupted, short of redesigning
+        either SSQLS or <classname>ColData</classname>.</para>
+
+        <para>You can see this technique in action in the
+        <filename>cgi_jpeg</filename> example:</para>
+
+        <programlisting><xi:include href="cgi_jpeg.txt" parse="text"
+        xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
     </sect2>
 </sect1>
 

Modified: trunk/examples/cgi_jpeg.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/examples/cgi_jpeg.cpp?rev=1615&r1=1614&r2=1615&view=diff
==============================================================================
--- trunk/examples/cgi_jpeg.cpp (original)
+++ trunk/examples/cgi_jpeg.cpp Tue Jun 26 06:16:30 2007
@@ -28,6 +28,7 @@
 ***********************************************************************/
 
 #include <mysql++.h>
+#include <custom.h>
 
 using namespace std;
 using namespace mysqlpp;
@@ -36,6 +37,11 @@
 #define IMG_HOST               "localhost"
 #define IMG_USER               "root"
 #define IMG_PASSWORD   "nunyabinness"
+
+sql_create_2(images,
+       1, 2,
+       mysqlpp::sql_int_unsigned, id,
+       mysqlpp::sql_blob, data)
 
 int
 main()
@@ -57,14 +63,14 @@
                                "directory, then" << endl;
                cerr << "invoke it with a URL like this:" << endl;
                cerr << endl;
-               cerr << "    http://server.name.com/cgi-bin/cgi_image?id=2"; <<
+               cerr << "    http://server.name.com/cgi-bin/cgi_jpeg?id=2"; <<
                                endl;
                cerr << endl;
                cerr << "This will retrieve the image with ID 2." << endl;
                cerr << endl;
                cerr << "You will probably have to change some of the #defines "
                                "at the top of" << endl;
-               cerr << "examples/cgi_image.cpp to allow the lookup to work." <<
+               cerr << "examples/cgi_jpeg.cpp to allow the lookup to work." <<
                                endl;
                return 1;
        }
@@ -73,14 +79,13 @@
        try {
                con.connect(IMG_DATABASE, IMG_HOST, IMG_USER, IMG_PASSWORD);
                Query query = con.query();
-               query << "SELECT data FROM images WHERE id = " << img_id;
+               query << "SELECT * FROM images WHERE id = " << img_id;
                ResUse res = query.use();
                if (res) {
-                       Row row = res.fetch_row();
-                       unsigned long length = row.raw_size(0);
+                       images img = res.fetch_row();
                        cout << "Content-type: image/jpeg" << endl;
-                       cout << "Content-length: " << length << endl << endl;
-                       fwrite(row.raw_data(0), 1, length, stdout);
+                       cout << "Content-length: " << img.data.length() << 
"\n\n";
+                       cout << img.data;
                }
                else {
                        cout << "Content-type: text/plain" << endl << endl;

Modified: trunk/lib/coldata.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/coldata.h?rev=1615&r1=1614&r2=1615&view=diff
==============================================================================
--- trunk/lib/coldata.h (original)
+++ trunk/lib/coldata.h Tue Jun 26 06:16:30 2007
@@ -95,6 +95,16 @@
        /// way to set the type data once the object's constructed.
        ColData_Tmpl() :
        null_(false)
+       {
+       }
+
+       /// \brief Copy ctor
+       ///
+       /// \param cd the other ColData_Tmpl object
+       ColData_Tmpl(const ColData_Tmpl<Str>& cd) :
+       Str(cd.data(), cd.length()),
+       type_(cd.type_),
+       null_(cd.null_)
        {
        }
 

Modified: trunk/lib/manip.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/manip.cpp?rev=1615&r1=1614&r2=1615&view=diff
==============================================================================
--- trunk/lib/manip.cpp (original)
+++ trunk/lib/manip.cpp Tue Jun 26 06:16:30 2007
@@ -211,7 +211,9 @@
 {
        if (dont_quote_auto || (o.rdbuf() == cout.rdbuf()) ||
                        (o.rdbuf() == cerr.rdbuf())) {
-               return o << in.c_str();
+               // Write out the raw data.  Have to do it this way in case
+               // it's a BLOB field.
+               return o.write(in.data(), in.length());
        }
 
        if (in.escape_q()) {

Modified: trunk/lib/sql_types.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/sql_types.h?rev=1615&r1=1614&r2=1615&view=diff
==============================================================================
--- trunk/lib/sql_types.h (original)
+++ trunk/lib/sql_types.h Tue Jun 26 06:16:30 2007
@@ -56,10 +56,10 @@
 
 typedef std::string            sql_enum;
 
-typedef std::string            sql_blob;
-typedef std::string            sql_tinyblob;
-typedef std::string            sql_mediumblob;
-typedef std::string            sql_longblob;
+typedef ColData                        sql_blob;
+typedef ColData                        sql_tinyblob;
+typedef ColData                        sql_mediumblob;
+typedef ColData                        sql_longblob;
 
 typedef std::string            sql_char;
 typedef std::string            sql_varchar;


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

Reply via email to