Author: wyoung
Date: Tue Nov 20 06:24:49 2007
New Revision: 1873

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1873&view=rev
Log:
Added a section to userman's tutorial chapter explaining String and
SQLTypeAdapter.

Modified:
    trunk/Wishlist
    trunk/doc/userman/userman.dbx

Modified: trunk/Wishlist
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/Wishlist?rev=1873&r1=1872&r2=1873&view=diff
==============================================================================
--- trunk/Wishlist (original)
+++ trunk/Wishlist Tue Nov 20 06:24:49 2007
@@ -12,8 +12,6 @@
     The items in this section are those things we definitely want to
     get done in v3.0.  Most of them break the ABI, so they can't wait
     for a future version, because v4 could be years out.
-
-    o Add a userman section on String and SQLTypeAdapter.
 
     o field_list should use backticks to quote its items to handle
       spaces and other special characters.  Probably also remove all
@@ -102,6 +100,10 @@
     This is stuff that would be nice to have, but it wouldn't be a
     good idea to bet on seeing it in v3.0.  If you really want some
     of this, best to just get coding and provide a patch!
+
+    o Can String replace RefCountedPointer?  More broadly, can it be
+      the generic "hold big chunks of data efficiently even in the
+      face of copying" class?
 
     o Either add quote_force and similar manipulators, or remove the
       'r' and 'R' modifiers in template queries.  As it stands, you

Modified: trunk/doc/userman/userman.dbx
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/doc/userman/userman.dbx?rev=1873&r1=1872&r2=1873&view=diff
==============================================================================
--- trunk/doc/userman/userman.dbx (original)
+++ trunk/doc/userman/userman.dbx Tue Nov 20 06:24:49 2007
@@ -572,7 +572,7 @@
     </sect2>
 
 
-    <sect2>
+    <sect2 id="qescape" xreflabel="quoting and escaping">
         <title>Quoting and Escaping</title>
 
         <para>SQL syntax often requires certain data to be
@@ -1117,6 +1117,177 @@
 
         <programlisting><xi:include href="fieldinf.txt" parse="text"
         xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
+    </sect2>
+
+
+    <sect2>
+        <title>MySQL++'s Special String Types</title>
+
+        <para>MySQL++ has two classes that work like
+        <classname>std::string</classname> to some degree: <ulink
+        type="classref" url="String"/> and <ulink type="classref"
+        url="SQLTypeAdapter"/>. These classes exist to provide
+        functionality that <classname>std::string</classname>
+        doesn't provide, but they are neither derivatives of nor
+        complete supersets of <classname>std::string</classname>.
+        As a result, end-user code generally doesn't deal with these
+        classes directly, because <classname>std::string</classname>
+        is a better general-purpose string type. In fact, MySQL++
+        itself uses <classname>std::string</classname> most of the
+        time, too. But, the places these specialized stringish types
+        do get used are so important to the way MySQL++ works that
+        it's well worth taking the time to understand them.</para>
+
+
+        <sect3>
+            <title>SQLTypeAdapter</title>
+
+            <para>The simpler of the two is
+            <classname>SQLTypeAdapter</classname>,
+            or <classname>STA</classname> for
+            short.<footnote><para>In version 2 of MySQL++ and
+            earlier, <classname>SQLTypeAdapter</classname> was
+            called <classname>SQLString</classname>, but it was
+            confusing because its name and the fact that it derived
+            from <classname>std::string</classname> suggested that
+            it was a general-purpose string type. MySQL++ even used
+            it this way in a few places internally. In v3, we made it
+            a simple base class and renamed it to reflect its proper
+            limited function.</para></footnote></para>
+
+            <para>As its name suggests, its only purpose is to
+            adapt other data types to be used with SQL. It has a
+            whole bunch of conversion constructors, one for all data
+            types we expect to be used with MySQL++ for values in
+            queries. SQL queries are strings, so constructors that take
+            stringish types just make a copy of that string, and all
+            the others "stringize" the value in the format needed by
+            SQL.<footnote><para><classname>SQLTypeAdapter</classname>
+            doesn't do <xref linkend="qescape"/> itself. That
+            happens elsewhere, right at the point that the
+            <classname>STA</classname> gets used to build a
+            query.</para></footnote> The conversion constructors
+            preserve type information, so this stringization process
+            doesn't throw away any essential information.</para>
+
+            <para><classname>STA</classname> is used anywhere
+            MySQL++ needs to be able to accept any of several
+            data types for use in a SQL query. Major users
+            are <classname>Query</classname>'s template query
+            mechanism and the <classname>Query</classname>
+            stream quoting and escaping mechanism. You
+            care about <classname>STA</classname> because
+            any time you pass a data value to MySQL++ to
+            be used in building a SQL query, it goes through
+            <classname>STA</classname>. <classname>STA</classname>
+            is one of the key pieces in MySQL++ that makes it easy
+            to generate syntactically-correct SQL queries.</para>
+        </sect3>
+
+
+        <sect3>
+            <title>String</title>
+
+            <para>If MySQL++ can be said to have its own generic
+            string type, it's <classname>String</classname>,
+            but it's not really functional enough for general
+            use. It's possible that in future versions of MySQL++
+            we'll expand its interface to include everything
+            <classname>std::string</classname> does, so that's why
+            it's called that.<footnote><para>If you used MySQL++
+            before v3, <classname>String</classname> used to be
+            called <classname>ColData</classname>. It was renamed
+            because starting in v2.3, we began using it for holding
+            more than just column data. I considered renaming it
+            <classname>SQLString</classname> instead, but that would
+            have confused old MySQL++ users to no end. Instead,
+            I followed the example of <classname>Set</classname>,
+            MySQL++'s specialized <classname>std::set</classname>
+            variant.</para></footnote></para>
+
+            <para>The key thing <classname>String</classname>
+            provides over <classname>std::string</classname>
+            is conversion of strings in SQL value formats to
+            their native C++ data types. For example, if you
+            initialize it with the string "2007-11-19", you can
+            assign the <classname>String</classname> to a <ulink
+            type="structref" url="Date">Date</ulink>, not because
+            <classname>Date</classname> knows how to initialize
+            itself from <classname>String</classname>, but the
+            reverse: <classname>String</classname> has a bunch of
+            implicit conversion operators defined for it, so you
+            can use it in any type context that makes sense in your
+            application.</para>
+
+            <para>Because <methodname>Row::operator[]</methodname>
+            returns <classname>String</classname>, you can say things
+            like this:</para>
+
+            <programlisting>int x = row["x"];</programlisting>
+
+            <para>In a very real sense, <classname>String</classname>
+            is the inverse of <classname>STA</classname>:
+            <classname>String</classname> converts SQL value strings
+            to C++ data types, and <classname>STA</classname> converts
+            C++ data types to SQL value strings.<footnote><para>For a
+            time during the development of MySQL++ v3.0, I considered
+            merging <classname>SQLTypeAdapter</classname> and
+            <classname>String</classname> to take advantage of the fact
+            that they're two sides of the same coin. Unfortunately,
+            C++'s type conversion rules got in the way, because
+            such a combined class lets you convert almost anything
+            to anything, which gives the C++ compiler plenty of rope
+            to hang itself.</para></footnote></para>
+
+            <para><classname>String</classname> has two main
+            uses.</para>
+
+            <para>By far the most common use is as the
+            field value type of <classname>Row</classname>,
+            as exemplified above. It's not just the return
+            type of <methodname>Row::operator[]</methodname>,
+            though: it's actually the value type used within
+            <classname>Row</classname>'s internal array. As a result,
+            any time MySQL++ pulls data from the database, it goes
+            through <classname>String</classname> when converting
+            it from the string form used in SQL result sets to the
+            C++ data type you actually want the data in. It's the
+            core of the structure population mechanism in <xref
+            linkend="ssqls"/>, for example.</para>
+
+            <para>Because <classname>String</classname> is the
+            last pristine form of data in a result set before
+            it gets out of MySQL++'s internals where end-user
+            code can see it, MySQL++'s <type>sql_blob</type>
+            and related <type>typedef</type>s are aliases for
+            <classname>String</classname>. Using anything else would
+            require copies; while the whole "networked database server"
+            thing means most of MySQL++ can be quite inefficient and
+            still not affect benchmark results meaningfully, BLOBs
+            tend to be big, so making unnecessary copies can really
+            make a difference. Which brings us to...</para>
+        </sect3>
+
+
+        <sect3>
+            <title>Reference Counting</title>
+
+            <para>To avoid unnecessary buffer
+            copies, both <classname>STA</classname> and
+            <classname>String</classname> are implemented in terms
+            of a reference-counted copy-on-write buffer scheme. Both
+            classes share the same underlying mechanism, and so are
+            interoperable. This means that if you construct one of
+            these objects from another, it doesn't actually copy the
+            string data, it only copies a pointer to the data buffer,
+            and increments its reference count. If the object has
+            new data assigned to it or it's otherwise modified, it
+            decrements its reference count and creates its own copy
+            of the buffer. This has a lot of practical import, such
+            as the fact that <methodname>Row::operator[]</methodname>
+            can return <classname>String</classname> by value, and
+            it's still efficient.</para>
+        </sect3>
     </sect2>
 
 


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

Reply via email to