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++’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
- “(NULL)”. If you don’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’s
+ safe to insert a SQL null into a C++ stream, though: you get
+ “(NULL)”.</para>
+
+ <para>If you don’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<unsigned char, mysqlpp::NullIsZero> myfield;
-
-myfield = mysqlpp::null;
+mysqlpp::Null<unsigned char, mysqlpp::NullIsZero> myfield(mysqlpp::null);
cout << myfield << endl;
-
-int x = myfield;
-cout << x << endl;</programlisting>
+cout << int(myfield) << endl;</programlisting>
<para>This will print “0” twice. If you had used the
default for the second <classname>Null</classname> template
parameter, the first output statement would have printed
- “(NULL)”, and the second would have thrown a
- <classname>BadNullConversion</classname> exception.</para>
+ “(NULL)”, and the second wouldn’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