Author: wyoung
Date: Fri Feb 15 10:44:00 2008
New Revision: 2205

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=2205&view=rev
Log:
- It's now a compile-time error to try to convert a SQL null to any
  other data type if you use the default NullIsNull behavior.
- Removed BadNullConversion exception as a result, and updated the
  manual to change code that used to discuss this to say that the code
  doesn't compile.
- Added test/null_uniqueness.cpp to test this.  Can't add it to dtest
  routine or normal build process since it's doesn't compile.

Added:
    trunk/test/null_uniqueness.cpp
Modified:
    trunk/doc/userman/tutorial.dbx
    trunk/lib/exceptions.h
    trunk/lib/null.h

Modified: trunk/doc/userman/tutorial.dbx
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/doc/userman/tutorial.dbx?rev=2205&r1=2204&r2=2205&view=diff
==============================================================================
--- trunk/doc/userman/tutorial.dbx (original)
+++ trunk/doc/userman/tutorial.dbx Fri Feb 15 10:44:00 2008
@@ -678,35 +678,33 @@
     <programlisting>
 myfield = mysqlpp::null;</programlisting>
 
-    <para>The final aspect of MySQL++&rsquo;s null handling is that, by
-    default, it will enforce the uniqueness of the SQL null value. If
-    you try to convert a SQL null to a plain C++ data type, MySQL++ will
-    throw a <ulink type="classref" url="BadNullConversion"/> exception.
-    If you insert a SQL null into a C++ stream, you get
-    &ldquo;(NULL)&rdquo;. If you don&rsquo;t like this behavior, you can
-    change it, by passing a different value for the second parameter to
-    template <classname>Null</classname>. By default, this parameter is
-    <ulink type="structref" url="NullIsNull"/>, meaning that we should
-    enforce the uniqueness of the null type. To relax this distinction,
+    <para>By default, MySQL++ enforces the uniqueness of SQL null at
+    compile time. If you try to convert a SQL null to any other data
+    type, the compiler will emit an error message saying something
+    about <type>CannotConvertNullToAnyOtherDataType</type>. It&rsquo;s
+    safe to insert a SQL null into a C++ stream, though: you get
+    &ldquo;(NULL)&rdquo;.</para>
+
+    <para>If you don&rsquo;t like this behavior, you can change it
+    by passing a different value for the second parameter to template
+    <classname>Null</classname>. By default, this parameter is <ulink
+    type="structref" url="NullIsNull"/>, meaning that we should
+    enforce the uniqueness of SQL null. To relax this distinction,
     you can instantiate the <classname>Null</classname> template with a
     different behavior type: <ulink type="structref" url="NullIsZero"/>
     or <ulink type="structref" url="NullIsBlank"/>. Consider this
     code:</para>
 
     <programlisting>
-mysqlpp::Null&lt;unsigned char, mysqlpp::NullIsZero&gt; myfield;
-
-myfield = mysqlpp::null;
+mysqlpp::Null&lt;unsigned char, mysqlpp::NullIsZero&gt; myfield(mysqlpp::null);
 cout &lt;&lt; myfield &lt;&lt; endl;
-
-int x = myfield;
-cout &lt;&lt; x &lt;&lt; endl;</programlisting>
+cout &lt;&lt; int(myfield) &lt;&lt; endl;</programlisting>
 
     <para>This will print &ldquo;0&rdquo; twice. If you had used the
     default for the second <classname>Null</classname> template
     parameter, the first output statement would have printed
-    &ldquo;(NULL)&rdquo;, and the second would have thrown a
-    <classname>BadNullConversion</classname> exception.</para>
+    &ldquo;(NULL)&rdquo;, and the second wouldn&rsquo;t even
+    compile.</para>
   </sect2>
 
 

Modified: trunk/lib/exceptions.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/exceptions.h?rev=2205&r1=2204&r2=2205&view=diff
==============================================================================
--- trunk/lib/exceptions.h (original)
+++ trunk/lib/exceptions.h Fri Feb 15 10:44:00 2008
@@ -172,20 +172,6 @@
 };
 
 
-/// \brief Exception thrown when you attempt to convert a SQL null
-/// to an incompatible type.
-
-class MYSQLPP_EXPORT BadNullConversion : public Exception
-{
-public:
-       /// \brief Create exception object
-       explicit BadNullConversion(const char* w = "") :
-       Exception(w)
-       {
-       }
-};
-
-
 /// \brief Exception thrown when you pass an unrecognized option to
 /// Connection::set_option().
 

Modified: trunk/lib/null.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/null.h?rev=2205&r1=2204&r2=2205&view=diff
==============================================================================
--- trunk/lib/null.h (original)
+++ trunk/lib/null.h Fri Feb 15 10:44:00 2008
@@ -44,23 +44,43 @@
 
 /// \brief The type of the global mysqlpp::null object.
 ///
-/// This class is for internal use only.  Normal code should use
-/// Null instead.
+/// User code shouldn't declare variables of this type.  Use the
+/// Null template instead.
 class MYSQLPP_EXPORT null_type
 {
-public:
-#if !defined(DOXYGEN_IGNORE)
-// Doxygen will not generate documentation for this section.
-       template <class Type> operator Type() const
-       {
-               throw BadNullConversion();
-               return Type();
+private:
+#if !defined(DOXYGEN_IGNORE)
+// Doxygen will not generate documentation for this section.
+       template <typename CannotConvertNullToAnyOtherDataType>
+       operator CannotConvertNullToAnyOtherDataType() const
+       {
+               return CannotConvertNullToAnyOtherDataType();
        }
 #endif // !defined(DOXYGEN_IGNORE)
 };
 
 /// \brief Global 'null' instance.  Use wherever you need a SQL null.
-/// (As opposed to a C++ language null pointer or null character.)
+///
+/// SQL null is equal to nothing else.  It is not the same as C++'s
+/// NULL value, it is not a Boolean false....it is unique.  As such, if
+/// you use this in some other type context, you will get a compiler
+/// error saying something about \c CannotConvertNullToAnyOtherDataType.
+/// The only thing you can assign this object instance to is a variable
+/// of type Null<T>, and then only directly.  Code like this does not
+/// work:
+///
+/// \code
+/// int foo = return_some_value_for_foo();
+/// mysqlpp::Null<int> bar = foo ? foo : mysqlpp::null;
+/// \endcode
+/// 
+/// The compiler will try to convert mysqlpp::null to \c int to make
+/// all values in the conditional operation consistent, but this is
+/// not legal.  Anyway, it's questionable code because it means you're
+/// using SQL null to mean the same thing as zero here.  If zero is a
+/// special value, there's no reason to use SQL null.  SQL null exists
+/// when every value for a particular column is legal and you need
+/// something that means "no legal value".
 const null_type null = null_type();
 
 
@@ -75,7 +95,7 @@
 {
 #if !defined(DOXYGEN_IGNORE)
 // Doxygen will not generate documentation for this section.
-       static null_type null_is() { return null_type(); }
+       static null_type null_is() { return null; }
 
        static std::ostream& null_ostr(std::ostream& o)
        {

Added: trunk/test/null_uniqueness.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/test/null_uniqueness.cpp?rev=2205&view=auto
==============================================================================
--- trunk/test/null_uniqueness.cpp (added)
+++ trunk/test/null_uniqueness.cpp Fri Feb 15 10:44:00 2008
@@ -1,0 +1,39 @@
+/***********************************************************************
+ test/null_uniqueness.cpp - Code for checking that null_type cannot be
+    converted to anything else.  Because it triggers a compile-time
+       check, it can't be included in the test suite.  You have to just
+       try building it.  Comment out the assignment to int to check that
+       the return statement also triggers the compile-time check.
+
+ Copyright (c) 2008 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++.
+
+ MySQL++ is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ MySQL++ is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with MySQL++; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ USA
+***********************************************************************/
+
+#include <mysql++.h>
+
+int
+main()
+{
+       mysqlpp::Null<int> ni = mysqlpp::null;
+       int this_should_not_even_compile = mysqlpp::null;
+       return ni;              // neither should this
+}
+


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

Reply via email to