dbTalk Databases Forums  

Patch: Nullable fields in SQLSS

mailing.database.mysql-plusplus mailing.database.mysql-plusplus


Discuss Patch: Nullable fields in SQLSS in the mailing.database.mysql-plusplus forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Waba
 
Posts: n/a

Default Patch: Nullable fields in SQLSS - 02-04-2006 , 02:18 AM






--CXFpZVxO6m2Ol4tQ
Content-Type: multipart/mixed; boundary="//IivP0gvsAy3Can"
Content-Disposition: inline


--//IivP0gvsAy3Can
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Here is my patch that enables one to use nullable fields in SQLSS. Since
it will break binary compatibility, I feel necessary to explain the
steps that I have followed. If you don't care, just skip to the summary
below.


WALKTHROUGH:

Let's try to compile a test program that contains a SQLSS with fields of
type mysqlpp::Null<something>. As expected we get compiler errors. It
complains that

Null<T>::Null (const ColData)

is ambiguous, because it matches either the ctor that takes a T, or the
ctor that takes another Null<T>. Indeed, both calls are resolved through
the implicit conversion operators of ColData (to T - int, let's say, and
to Null<T>). IMHO, making these ops was a mistake (even back in v0.6x),
and it's too late to change it. See section 11.4 of Stroustrup's TC++PL
(3rd ed.) for a full discussion.

We have to be more explicit here, and there are several paths awaiting
our exploration: we could make Null constructible from ColData directly,
but that would lead to an include loop as each class would need a
full definition of the other. We cannot kill the implicit conversion
operators of ColData to T as they are required for backwards source
compatibility. OTOH, the conversion to Null has got to stay in some
form inside the ColData class, as it is alone to know whether its
content is null or not. (2) We can however replace this conversion
by a real function, as it is useless in its current form (except for
Null<string>, as ColData inherits from Str, another early mistake, see
section 12.4.2).

Having removed this operator, implicitly constructing a Null<string>
=66rom a ColData is now impossible. However, it works for Null<int>, which
is very bad as the is-null information is lost on the way! We have to
resort to some trick to forbid both operations: we define the operator
(blocking all but string), and write an instruction inside that will
fail for string:

operator Null<T, B> () { T (1)/1; return get_null<T, B> (); }

This is the kind of tricks used in Boost.MPL. Now, constructing a Null
=66rom a ColData is homogeneously impossible for all types, which is a
Good Thing. The user can still however write:

Null<T, B> n (col_data.get_null<T, B> ());

(3) At this point the compiler will actually attempt to process the code
inside get_null(), and will scream about another ambiguous conversion
in the manual comparison to the string "NULL". This may not be the case
everywhere however, as g++-4.0 states that

ISO C++ says that these are ambiguous, even though the worst conversion
for the first is better than the worst conversion for the second.

Anyway, the problem is easily fixed: instead of calling these implicit
operators via "(*this)[0]", static_cast to the base Str type first.

(8) Ok, now we can compile calls to get_null<T, B> () for T numeric,
but it's still broken for strings and date types, as there is no
mysql_convert template code for them. Easily fixed too, not forgetting
to update the "end" parameter accordingly. However, that leads to
DateTime needing the full definition of ColData (since it's only a
typedef) and ColData needing DateTime to produce Null<DateTime>, so
we've got to break the circle one way or another. No choice here: we
have to remove the Date/Time-from-ColData ctors. We could attempt
to retain source compatibility by defining more implicit conversion
operators inside ColData, however that would break in some cases.

(1) Rather, we template the string ctors of DateTime, therefore
making them usable for ColData aswell, avoiding to include coldata.h
and solving all our problems. Now everything compiles again, except
SSQLSes that have Nulls inside ;-) (6) Human coders can manually call
get_null(), however the macros defined by custom.pl can't do that
without resorting to even more template tricks.

We can however modify custom.pl to call the general explicit conversion
method, conv(), instead of forcing an implicit conversion through
static_cast. Now the compiler reminds us that we forgot to specialize
(overload, actually) conv() to handle Nulls. This is easily done
through:

template <class T, class B> Null<T, B> conv (Null<T, B>) const

which in turn calls get_null(). We are 100% sure that the right function
gets called every time, as the wrong one wouldn't compile.

(4) Not totally related, but when making a Null<string>, the only
correct (as in "compiles") Behavior parameter is NullisBlank, which is
not the default. OTOH, the comma in Null<string, NullisBlank> breaks the
macro call, so the users will have to use a typedef anyway. Rather than
forcing everyone to do so, let's define it ourselves in null.h.

(7) Anticipating on what we're supposed to discover only by running our
sample code, we need to refine the quoting system to accommodate for
Null templates.

Et voil=E0! Now the last thing left to do is an improved custom7.cpp that
proves the correct behaviour of our patch. Thank you for reading so far.


SUMMARY: (The numbers below refer to those above)

Here is a summary of the changes. For a discussion on the reasons behind
them, please read the above.
1) DateTime loses its ColData constructor, which is replaced by a
template ctor that works for all strings and ColData variants.
2) The non-functional conversion operator to Null in ColData is made
unusable for all types. It is replaced by an explicit get_null()
function and an overload of conv().
3) Modification in the get_null() function so that it compiles on the
strict g++-4.0
4) Added a NullString typedef for user convenience, as it must exist to
use null strings in SSQLSs.
5) Made the desired ostream format explicit in datetime.cpp. Unsure why
change 1 (I think) made this necessary.
6) In the populate code of the SSQLSs, use explicit conversion through
conv() rather than relying on implicit conversion operators.
7) Handle Null templates correctly in the quoting manipulators.
8) Added mysql_convert template instantiations for strings and time
types.

This patch has been tested under g++ 3.3, 3.4 and 4.0. Please test it
under VC++ as I have no access this platform. Please also test that=20
real-world applications still compile with it (I don't see how run-time
behaviour could be affected).


Best regards,
-Waba.

--//IivP0gvsAy3Can
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="null-in-ssqls.patch"
Content-Transfer-Encoding: quoted-printable

Index: lib/datetime.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/datetime.h (revision 1163)
+++ lib/datetime.h (working copy)
@@ -31,7 +31,6 @@
=20
#include "defs.h"
=20
-#include "coldata.h"
#include "stream2string.h"
#include "tiny_int.h"
=20
@@ -164,19 +163,12 @@
/// \brief Initialize object from a MySQL date-and-time string
///
/// \sa DateTime(cchar*)
- DateTime(const ColData& str)
+ template<class Str>
+ DateTime(const Str &str)
{
convert(str.c_str());
}
=20
- /// \brief Initialize object from a MySQL date-and-time string
- ///
- /// \sa DateTime(cchar*)
- DateTime(const std::string& str)
- {
- convert(str.c_str());
- }
-
/// \brief Compare this datetime to another.
///
/// Returns < 0 if this datetime is before the other, 0 of they are
@@ -259,16 +251,9 @@
/// \brief Initialize object from a MySQL date string
///
/// \sa Date(cchar*)
- Date(const ColData& str) { convert(str.c_str()); }
-
- /// \brief Initialize object from a MySQL date string
- ///
- /// \sa Date(cchar*)
- Date(const std::string& str)
- {
- convert(str.c_str());
- }
-
+ template<class Str>
+ Date(const Str& str) { convert(str.c_str()); }
+=09
/// \brief Compare this date to another.
///
/// Returns < 0 if this date is before the other, 0 of they are
@@ -342,16 +327,9 @@
/// \brief Initialize object from a MySQL time string
///
/// \sa Time(cchar*)
- Time(const ColData& str) { convert(str.c_str()); }
+ template<class Str>
+ Time(const Str& str) { convert(str.c_str()); }
=20
- /// \brief Initialize object from a MySQL time string
- ///
- /// \sa Time(cchar*)
- Time(const std::string& str)
- {
- convert(str.c_str());
- }
-
/// \brief Parse a MySQL time string into this object.
MYSQLPP_EXPORT cchar* convert(cchar*);
=20
Index: lib/coldata.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/coldata.h (revision 1163)
+++ lib/coldata.h (working copy)
@@ -149,6 +149,9 @@
/// \brief Template for converting data from one type to another.
template <class Type> Type conv(Type dummy) const;
=20
+ template <class T, class B> Null<T, B> conv (Null<T, B>) const
+ { return get_null<T, B> (); }
+=09
/// \brief Set a flag indicating that this object is a SQL null.
void it_is_null() { null_ =3D true; }
=20
@@ -161,6 +164,19 @@
return buf_;
}
=09
+ /** \brief Convert to a nullable type.
+ *
+ * You have to explicitely provide the template types to the function,
+ * like this:
+ * <code>
+ * Null<T, B> n (col_data.get_null<T, B> ());
+ * </code>
+ *
+ * Or use conv(), to which you can give a sample of the desired
+ * return type.
+ */
+ template <class T, class B> Null<T, B> get_null () const;
+
/// \brief Returns a const char pointer to the string form of
/// this object's data.
operator cchar*() const { return buf_.c_str(); }
@@ -222,8 +238,19 @@
/// \brief Converts this object's string data to a bool
operator bool() const { return conv(0); }
=20
- template <class T, class B> operator Null<T, B>() const;
-
+ /** \brief Dummy conversion to Null.
+ *
+ * This is meant to be ambiguous to the compiler. Without this trick,
+ * Null would be constructible from the other implicit conversion=20
+ * operators, and would in the end be counter-intuitive to the user
+ * who would lose the is-null information. This way, constructing a=20
+ * Null from a ColData implicitely is impossible.
+ *
+ * Use get_null() or conv() explicitely instead.
+ */
+ template<class T, class B> operator Null<T, B> () const=20
+ { T (1)/1; return get_null<T, B> (); }
+=09
private:
mysql_type_info type_;
std::string buf_;
@@ -295,13 +322,13 @@
/// the object is exactly equal to "NULL". Else, it constructs an empty
/// object of type T and tries to convert it to Null<T, B>.
template <class Str> template<class T, class B>
-ColData_Tmpl<Str>:perator Null<T, B>() const
+Null<T, B> ColData_Tmpl<Str>::get_null () const
{
if ((Str::size() =3D=3D 4) &&
- (*this)[0] =3D=3D 'N' &&
- (*this)[1] =3D=3D 'U' &&
- (*this)[2] =3D=3D 'L' &&
- (*this)[3] =3D=3D 'L') {
+ static_cast<Str>(*this)[0] =3D=3D 'N' &&
+ static_cast<Str>(*this)[1] =3D=3D 'U' &&
+ static_cast<Str>(*this)[2] =3D=3D 'L' &&
+ static_cast<Str>(*this)[3] =3D=3D 'L') {
return Null<T, B>(null);
}
else {
Index: lib/null.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/null.h (revision 1163)
+++ lib/null.h (working copy)
@@ -35,6 +35,7 @@
#include "exceptions.h"
=20
#include <iostream>
+#include <string>
=20
namespace mysqlpp {
=20
@@ -273,6 +274,9 @@
return o << n.data;
}
=20
+/// \brief The correct Null template types for nullable STL strings
+typedef Null<std::string, NullisBlank> NullString;
+
} // end namespace mysqlpp
=20
#endif
Index: lib/datetime.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/datetime.cpp (revision 1163)
+++ lib/datetime.cpp (working copy)
@@ -40,9 +40,9 @@
{
char fill =3D os.fill('0');
ios::fmtflags flags =3D os.setf(ios::right);
- os << setw(4) << d.year << '-'=20
- << setw(2) << d.month << '-'
- << setw(2) << d.day;
+ os << setw(4) << static_cast<int>(d.year) << '-'
+ << setw(2) << static_cast<int>(d.month) << '-'
+ << setw(2) << static_cast<int>(d.day);
os.flags(flags);
os.fill(fill);
return os;
@@ -53,9 +53,9 @@
{
char fill =3D os.fill('0');
ios::fmtflags flags =3D os.setf(ios::right);
- os << setw(2) << t.hour << ':'=20
- << setw(2) << t.minute << ':'
- << setw(2) << t.second;
+ os << setw(2) << static_cast<int>(t.hour) << ':'=20
+ << setw(2) << static_cast<int>(t.minute) << ':'
+ << setw(2) << static_cast<int>(t.second);
os.flags(flags);
os.fill(fill);
return os;
Index: lib/custom.pl
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/custom.pl (revision 1163)
+++ lib/custom.pl (working copy)
@@ -262,7 +262,7 @@
$parm_simple2c_b .=3D ", " unless $j =3D=3D $i;
$defs .=3D " T$j I$j;";
$defs .=3D "\n" unless $j =3D=3D $i;
- $popul .=3D " s->I$j =3D static_cast<T$j>(row.at(O$j));";
+ $popul .=3D " s->I$j =3D row.at(O$j).conv (T$j ());";
$popul .=3D "\n" unless $j =3D=3D $i;
$names .=3D " N$j ";
$names .=3D ",\n" unless $j =3D=3D $i;
Index: lib/manip.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/manip.h (revision 1163)
+++ lib/manip.h (working copy)
@@ -201,6 +201,18 @@
return *o.ostr << '\'' << in << '\'';
}
=20
+
+template <class T, class B>
+MYSQLPP_EXPORT inline std:stream& operator <<(quote_type1 o,
+ const Null<T, B>& in)
+{
+ if (in.is_null)
+ return *o.ostr << "NULL";
+ else
+ return o << in.data; // quote again
+}
+
+
#endif // !defined(DOXYGEN_IGNORE)
=20
=20
@@ -313,6 +325,18 @@
return *o.ostr << '\'' << in << '\'';
}
=20
+
+template <class T, class B>
+MYSQLPP_EXPORT inline std:stream& operator <<(quote_only_type1 o,
+ const Null<T, B>& in)
+{
+ if (in.is_null)
+ return *o.ostr << "NULL";
+ else
+ return o << in.data; // quote again
+}
+
+
#endif // !defined(DOXYGEN_IGNORE)
=20
=20
@@ -427,6 +451,18 @@
return *o.ostr << '"' << in << '"';
}
=20
+
+template <class T, class B>
+MYSQLPP_EXPORT inline std:stream& operator <<(quote_double_only_type1 o,
+ const Null<T, B>& in)
+{
+ if (in.is_null)
+ return *o.ostr << "NULL";
+ else
+ return o << in.data; // quote again
+}
+
+
#endif // !defined(DOXYGEN_IGNORE)
=20
=20
Index: lib/convert.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/convert.h (revision 1163)
+++ lib/convert.h (working copy)
@@ -34,8 +34,10 @@
#include "platform.h"
=20
#include "defs.h"
+#include "datetime.h"
=20
#include <stdlib.h>
+#include <string>
=20
namespace mysqlpp {
=20
@@ -113,6 +115,63 @@
=20
#endif // !defined(DOXYGEN_IGNORE)
=20
+template <>
+class mysql_convert<std::string>
+{
+ std::string m_str;
+=09
+public:
+ mysql_convert (const char* str, const char *& end) :
+ m_str (str)
+ {
+ end =3D str + m_str.size ();
+ }
+=09
+ operator std::string () { return m_str; }
+};
+
+template <>
+class mysql_convert<Date>
+{
+ Date m_data;
+=09
+public:
+ mysql_convert (const char* str, const char *& end)
+ {
+ end =3D m_data.convert (str);
+ }
+=09
+ operator Date () { return m_data; }
+};
+
+template <>
+class mysql_convert<DateTime>
+{
+ DateTime m_data;
+=09
+public:
+ mysql_convert (const char* str, const char *& end)
+ {
+ end =3D m_data.convert (str);
+ }
+=09
+ operator DateTime () { return m_data; }
+};
+
+template <>
+class mysql_convert<Time>
+{
+ Time m_data;
+=09
+public:
+ mysql_convert (const char* str, const char *& end)
+ {
+ end =3D m_data.convert (str);
+ }
+=09
+ operator Time () { return m_data; }
+};
+
} // end namespace mysqlpp
=20
#endif
Index: examples/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- examples/Makefile.am (revision 1163)
+++ examples/Makefile.am (working copy)
@@ -27,7 +27,7 @@
=20
noinst_PROGRAMS =3D resetdb simple1 simple2 simple3 usequery multiquery \
custom1 custom2 custom3 custom4 custom5 custom6 fieldinf1 \
- dbinfo updel load_file cgi_image
+ dbinfo updel load_file cgi_image custom7
=20
noinst_HEADERS =3D util.h
=20
@@ -70,6 +70,9 @@
custom6_SOURCES =3D custom6.cpp util.cpp
custom6_DEPENDENCIES =3D $(MYSQLPP_LIB)
=20
+custom7_SOURCES =3D custom7.cpp util.cpp
+custom7_DEPENDENCIES =3D $(MYSQLPP_LIB)
+
fieldinf1_SOURCES =3D fieldinf1.cpp util.cpp
fieldinf1_DEPENDENCIES =3D $(MYSQLPP_LIB)
=20
Index: examples/resetdb.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- examples/resetdb.cpp (revision 1163)
+++ examples/resetdb.cpp (working copy)
@@ -60,6 +60,7 @@
// really care, as it'll get created next.
cout << "Dropping existing stock table..." << endl;
query.execute("drop table stock");
+ query.execute("drop table stock2");
}
else {
// Database doesn't exist yet, so create and select it.
@@ -105,6 +106,12 @@
=20
cout << (new_db ? "Created" : "Reinitialized") <<
" sample database successfully." << endl;
+=09
+ // The stock2 table introduces a null string, needed to test
+ // custom7.
+ cout << "Creating new stock2 table..." << endl;
+ query.execute ("create table stock2 (id int primary key, "
+ " name varchar(20), qtty int, eta date)");
}
catch (const mysqlpp::BadQuery& er) {
// Handle any query errors

--//IivP0gvsAy3Can--

--CXFpZVxO6m2Ol4tQ
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFD5GNIUQHbkgA+2bIRArg2AJ9jxi1oljhaQ9g5QWK6VA 5QkVWZFwCeJW/F
7pqg7Uq6J/G/jScu+ECihsI=
=LERN
-----END PGP SIGNATURE-----

--CXFpZVxO6m2Ol4tQ--

Reply With Quote
  #2  
Old   
Chris Frey
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 02-04-2006 , 02:40 AM






On Sat, Feb 04, 2006 at 09:18:16AM +0100, Waba wrote:
Quote:
Here is my patch that enables one to use nullable fields in SQLSS. Since
it will break binary compatibility, I feel necessary to explain the
steps that I have followed. If you don't care, just skip to the summary
below.
Thanks. Excellent documentation for your patch. I've only skimmed it
so far; I hope to have time to look at it closer soon.

Side note: looks like svn didn't pick up your new custom7.cpp in its diff
output. It's missing in the patch, but I see traces of it in Makefile.am :-)

- Chris


--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #3  
Old   
Waba
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 02-04-2006 , 03:16 AM



--i9LlY+UWpKt15+FH
Content-Type: multipart/mixed; boundary="sdtB3X0nJg68CQEu"
Content-Disposition: inline


--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sat, Feb 04, 2006 at 03:40:29AM -0500, Chris Frey wrote:
Quote:
Side note: looks like svn didn't pick up your new custom7.cpp in its diff
output. It's missing in the patch, but I see traces of it in Makefile.am :-)
Ooops! I forgot to svn-add it, sorry. Here is an updated version of the
patch, that includes custom7.cpp.

-Waba.

--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="null-in-ssqls2.patch"
Content-Transfer-Encoding: quoted-printable

Index: lib/datetime.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/datetime.h (revision 1163)
+++ lib/datetime.h (working copy)
@@ -31,7 +31,6 @@
=20
#include "defs.h"
=20
-#include "coldata.h"
#include "stream2string.h"
#include "tiny_int.h"
=20
@@ -164,19 +163,12 @@
/// \brief Initialize object from a MySQL date-and-time string
///
/// \sa DateTime(cchar*)
- DateTime(const ColData& str)
+ template<class Str>
+ DateTime(const Str &str)
{
convert(str.c_str());
}
=20
- /// \brief Initialize object from a MySQL date-and-time string
- ///
- /// \sa DateTime(cchar*)
- DateTime(const std::string& str)
- {
- convert(str.c_str());
- }
-
/// \brief Compare this datetime to another.
///
/// Returns < 0 if this datetime is before the other, 0 of they are
@@ -259,16 +251,9 @@
/// \brief Initialize object from a MySQL date string
///
/// \sa Date(cchar*)
- Date(const ColData& str) { convert(str.c_str()); }
-
- /// \brief Initialize object from a MySQL date string
- ///
- /// \sa Date(cchar*)
- Date(const std::string& str)
- {
- convert(str.c_str());
- }
-
+ template<class Str>
+ Date(const Str& str) { convert(str.c_str()); }
+=09
/// \brief Compare this date to another.
///
/// Returns < 0 if this date is before the other, 0 of they are
@@ -342,16 +327,9 @@
/// \brief Initialize object from a MySQL time string
///
/// \sa Time(cchar*)
- Time(const ColData& str) { convert(str.c_str()); }
+ template<class Str>
+ Time(const Str& str) { convert(str.c_str()); }
=20
- /// \brief Initialize object from a MySQL time string
- ///
- /// \sa Time(cchar*)
- Time(const std::string& str)
- {
- convert(str.c_str());
- }
-
/// \brief Parse a MySQL time string into this object.
MYSQLPP_EXPORT cchar* convert(cchar*);
=20
Index: lib/coldata.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/coldata.h (revision 1163)
+++ lib/coldata.h (working copy)
@@ -149,6 +149,9 @@
/// \brief Template for converting data from one type to another.
template <class Type> Type conv(Type dummy) const;
=20
+ template <class T, class B> Null<T, B> conv (Null<T, B>) const
+ { return get_null<T, B> (); }
+=09
/// \brief Set a flag indicating that this object is a SQL null.
void it_is_null() { null_ =3D true; }
=20
@@ -161,6 +164,19 @@
return buf_;
}
=09
+ /** \brief Convert to a nullable type.
+ *
+ * You have to explicitely provide the template types to the function,
+ * like this:
+ * <code>
+ * Null<T, B> n (col_data.get_null<T, B> ());
+ * </code>
+ *
+ * Or use conv(), to which you can give a sample of the desired
+ * return type.
+ */
+ template <class T, class B> Null<T, B> get_null () const;
+
/// \brief Returns a const char pointer to the string form of
/// this object's data.
operator cchar*() const { return buf_.c_str(); }
@@ -222,8 +238,19 @@
/// \brief Converts this object's string data to a bool
operator bool() const { return conv(0); }
=20
- template <class T, class B> operator Null<T, B>() const;
-
+ /** \brief Dummy conversion to Null.
+ *
+ * This is meant to be ambiguous to the compiler. Without this trick,
+ * Null would be constructible from the other implicit conversion=20
+ * operators, and would in the end be counter-intuitive to the user
+ * who would lose the is-null information. This way, constructing a=20
+ * Null from a ColData implicitely is impossible.
+ *
+ * Use get_null() or conv() explicitely instead.
+ */
+ template<class T, class B> operator Null<T, B> () const=20
+ { T (1)/1; return get_null<T, B> (); }
+=09
private:
mysql_type_info type_;
std::string buf_;
@@ -295,13 +322,13 @@
/// the object is exactly equal to "NULL". Else, it constructs an empty
/// object of type T and tries to convert it to Null<T, B>.
template <class Str> template<class T, class B>
-ColData_Tmpl<Str>:perator Null<T, B>() const
+Null<T, B> ColData_Tmpl<Str>::get_null () const
{
if ((Str::size() =3D=3D 4) &&
- (*this)[0] =3D=3D 'N' &&
- (*this)[1] =3D=3D 'U' &&
- (*this)[2] =3D=3D 'L' &&
- (*this)[3] =3D=3D 'L') {
+ static_cast<Str>(*this)[0] =3D=3D 'N' &&
+ static_cast<Str>(*this)[1] =3D=3D 'U' &&
+ static_cast<Str>(*this)[2] =3D=3D 'L' &&
+ static_cast<Str>(*this)[3] =3D=3D 'L') {
return Null<T, B>(null);
}
else {
Index: lib/null.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/null.h (revision 1163)
+++ lib/null.h (working copy)
@@ -35,6 +35,7 @@
#include "exceptions.h"
=20
#include <iostream>
+#include <string>
=20
namespace mysqlpp {
=20
@@ -273,6 +274,9 @@
return o << n.data;
}
=20
+/// \brief The correct Null template types for nullable STL strings
+typedef Null<std::string, NullisBlank> NullString;
+
} // end namespace mysqlpp
=20
#endif
Index: lib/datetime.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/datetime.cpp (revision 1163)
+++ lib/datetime.cpp (working copy)
@@ -40,9 +40,9 @@
{
char fill =3D os.fill('0');
ios::fmtflags flags =3D os.setf(ios::right);
- os << setw(4) << d.year << '-'=20
- << setw(2) << d.month << '-'
- << setw(2) << d.day;
+ os << setw(4) << static_cast<int>(d.year) << '-'
+ << setw(2) << static_cast<int>(d.month) << '-'
+ << setw(2) << static_cast<int>(d.day);
os.flags(flags);
os.fill(fill);
return os;
@@ -53,9 +53,9 @@
{
char fill =3D os.fill('0');
ios::fmtflags flags =3D os.setf(ios::right);
- os << setw(2) << t.hour << ':'=20
- << setw(2) << t.minute << ':'
- << setw(2) << t.second;
+ os << setw(2) << static_cast<int>(t.hour) << ':'=20
+ << setw(2) << static_cast<int>(t.minute) << ':'
+ << setw(2) << static_cast<int>(t.second);
os.flags(flags);
os.fill(fill);
return os;
Index: lib/custom.pl
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/custom.pl (revision 1163)
+++ lib/custom.pl (working copy)
@@ -262,7 +262,7 @@
$parm_simple2c_b .=3D ", " unless $j =3D=3D $i;
$defs .=3D " T$j I$j;";
$defs .=3D "\n" unless $j =3D=3D $i;
- $popul .=3D " s->I$j =3D static_cast<T$j>(row.at(O$j));";
+ $popul .=3D " s->I$j =3D row.at(O$j).conv (T$j ());";
$popul .=3D "\n" unless $j =3D=3D $i;
$names .=3D " N$j ";
$names .=3D ",\n" unless $j =3D=3D $i;
Index: lib/manip.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/manip.h (revision 1163)
+++ lib/manip.h (working copy)
@@ -201,6 +201,18 @@
return *o.ostr << '\'' << in << '\'';
}
=20
+
+template <class T, class B>
+MYSQLPP_EXPORT inline std:stream& operator <<(quote_type1 o,
+ const Null<T, B>& in)
+{
+ if (in.is_null)
+ return *o.ostr << "NULL";
+ else
+ return o << in.data; // quote again
+}
+
+
#endif // !defined(DOXYGEN_IGNORE)
=20
=20
@@ -313,6 +325,18 @@
return *o.ostr << '\'' << in << '\'';
}
=20
+
+template <class T, class B>
+MYSQLPP_EXPORT inline std:stream& operator <<(quote_only_type1 o,
+ const Null<T, B>& in)
+{
+ if (in.is_null)
+ return *o.ostr << "NULL";
+ else
+ return o << in.data; // quote again
+}
+
+
#endif // !defined(DOXYGEN_IGNORE)
=20
=20
@@ -427,6 +451,18 @@
return *o.ostr << '"' << in << '"';
}
=20
+
+template <class T, class B>
+MYSQLPP_EXPORT inline std:stream& operator <<(quote_double_only_type1 o,
+ const Null<T, B>& in)
+{
+ if (in.is_null)
+ return *o.ostr << "NULL";
+ else
+ return o << in.data; // quote again
+}
+
+
#endif // !defined(DOXYGEN_IGNORE)
=20
=20
Index: lib/convert.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- lib/convert.h (revision 1163)
+++ lib/convert.h (working copy)
@@ -34,8 +34,10 @@
#include "platform.h"
=20
#include "defs.h"
+#include "datetime.h"
=20
#include <stdlib.h>
+#include <string>
=20
namespace mysqlpp {
=20
@@ -113,6 +115,63 @@
=20
#endif // !defined(DOXYGEN_IGNORE)
=20
+template <>
+class mysql_convert<std::string>
+{
+ std::string m_str;
+=09
+public:
+ mysql_convert (const char* str, const char *& end) :
+ m_str (str)
+ {
+ end =3D str + m_str.size ();
+ }
+=09
+ operator std::string () { return m_str; }
+};
+
+template <>
+class mysql_convert<Date>
+{
+ Date m_data;
+=09
+public:
+ mysql_convert (const char* str, const char *& end)
+ {
+ end =3D m_data.convert (str);
+ }
+=09
+ operator Date () { return m_data; }
+};
+
+template <>
+class mysql_convert<DateTime>
+{
+ DateTime m_data;
+=09
+public:
+ mysql_convert (const char* str, const char *& end)
+ {
+ end =3D m_data.convert (str);
+ }
+=09
+ operator DateTime () { return m_data; }
+};
+
+template <>
+class mysql_convert<Time>
+{
+ Time m_data;
+=09
+public:
+ mysql_convert (const char* str, const char *& end)
+ {
+ end =3D m_data.convert (str);
+ }
+=09
+ operator Time () { return m_data; }
+};
+
} // end namespace mysqlpp
=20
#endif
Index: examples/custom7.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- examples/custom7.cpp (revision 0)
+++ examples/custom7.cpp (revision 0)
@@ -0,0 +1,155 @@
+/************************************************** *********************
+ custom7.cpp - This example demonstrates the use of the Null types
+ inside SSQLS structures. You should get a grasp of the
+ involved concepts through the previous examples first.
+=20
+ Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
+ MySQL AB, and (c) 2004, 2005 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 "util.h"
+
+#include <mysql++.h>
+#include <custom.h>
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <vector>
+
+using namespace std;
+
+// This is the same kind of structures than in the previous custom example=
s,
+// however this one deals with null strings, int and dates.
+sql_create_4(stock2,
+ 1, 4,
+ int, id,
+ mysqlpp::NullString, name,
+ mysqlpp::Null<int>, qtty,
+ mysqlpp::Null<mysqlpp:ate>, eta)
+
+// Simple exception class for reporting testing errors
+struct TestError : mysqlpp::Exception
+{ TestError (const std::string &w) : mysqlpp::Exception (w) {} };
+
+int
+main(int argc, char *argv[])
+{
+ // Wrap all MySQL++ interactions in one big try block, so any
+ // errors are handled gracefully.
+ try { =09
+ // Establish the connection to the database server.
+ mysqlpp::Connection con(mysqlpp::use_exceptions);
+ if (!connect_to_db(argc, argv, con)) {
+ return 1;
+ }
+ mysqlpp::Query q =3D con.query ();
+
+ // Let's start by inserting some rows with null items in our
+ // stock2 table.
+ cout << "Populating stock2..." << endl;
+ q << "delete from stock2";
+ q.execute ();
+ // Notice that we have to give a string to the stock2 ctor
+ // here, not a char* as C++ does not allow for more than
+ // one explicit construction (char* -> string -> Null<string>)
+ q.insert (stock2 (0, string ("Pickle Relish"), 5,=20
+ mysqlpp::null));
+ q.execute ();
+ q.insert (stock2 (1, mysqlpp::null, mysqlpp::null,=20
+ mysqlpp:ate (2006, 2, 3)));
+ q.execute ();
+ q.insert (stock2 (2, mysqlpp::null, mysqlpp::null,=20
+ mysqlpp::null));
+ q.execute ();
+
+ // Display its contents to the user, in a manner independant of
+ // the new code (null-in-SSQLS)
+ q << "select * from stock2";
+ mysqlpp::Result res =3D q.store ();
+ cout << "stock2 now contains:" << endl;
+ cout << " ID | Name | Qtty | ETA " << endl;
+ cout << "----+---------------+------+------------" << endl;
+ for (size_t i =3D 0; i < res.size (); i++)
+ {
+ mysqlpp::Row row =3D res.at (i);
+ cout << setw(3) << row["id"] << " | "
+ << setw(13) << row["name"] << " | "
+ << setw(4) << row["qtty"] << " | "
+ << row["eta"] << endl;
+ }
+ cout << endl;
+
+ // Now read back the values in SSQLS mode and compare them.
+ cout << "Reading again the values in SSQLS mode:" << endl;
+ vector<stock2> res2;
+ q << "select * from stock2";
+ q.storein (res2);
+ if (res.size () !=3D res2.size ())
+ throw TestError ("The size of the results differ!");
+ for (size_t i =3D 0; i < res.size (); i++)
+ {
+ mysqlpp::Row row =3D res.at (i);
+ stock2 st =3D res2.at (i);
+ if (row["name"].is_null () !=3D st.name.is_null
+ || row["qtty"].is_null () !=3D st.qtty.is_null
+ || row["eta"].is_null () !=3D st.eta.is_null)
+ throw TestError ("At least one null status differs!");
+
+ stringstream ss1, ss2;
+ mysqlpp::Null<int> sample_null_int;
+ mysqlpp::Null<mysqlpp:ate> sample_null_date;
+ // In order to get the same quoting mode, we have to=20
+ // convert the ColData to Nulls. We'll use the conv()
+ // member function for that. It takes a sample of the
+ // type we request.
+ ss1 << row["name"].conv (mysqlpp::NullString ()) << ","=20
+ << row["qtty"].conv (sample_null_int) << ","=20
+ << row["eta"].conv (sample_null_date);
+ ss2 << st.name << "," << st.qtty << "," << st.eta;
+ if (ss1.str () !=3D ss2.str ())
+ throw TestError ("At least one row differs:\n"+
+ ss1.str ()+"\n"+ss2.str ()+"\n");
+ }
+
+ cout << "They are exactly identical!" << endl;
+ }
+ catch (const mysqlpp::BadQuery& er) {
+ // Handle any query errors
+ cerr << "Query error: " << er.what() << endl;
+ return -1;
+ }
+ catch (const mysqlpp::BadConversion& er) {
+ // Handle bad conversions; e.g. type mismatch populating 'stock'
+ cerr << "Conversion error: " << er.what() << endl <<
+ "\tretrieved data size: " << er.retrieved <<
+ ", actual size: " << er.actual_size << endl;
+ return -1;
+ }
+ catch (const mysqlpp::Exception& er) {
+ // Catch-all for any other MySQL++ exceptions
+ cerr << "Error: " << er.what() << endl;
+ return -1;
+ }
+
+ return 0;
+}

Property changes on: examples/custom7.cpp
__________________________________________________ _________________
Name: svn:keywords
+ Id LastChangedRevision

Index: examples/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- examples/Makefile.am (revision 1163)
+++ examples/Makefile.am (working copy)
@@ -27,7 +27,7 @@
=20
noinst_PROGRAMS =3D resetdb simple1 simple2 simple3 usequery multiquery \
custom1 custom2 custom3 custom4 custom5 custom6 fieldinf1 \
- dbinfo updel load_file cgi_image
+ dbinfo updel load_file cgi_image custom7
=20
noinst_HEADERS =3D util.h
=20
@@ -70,6 +70,9 @@
custom6_SOURCES =3D custom6.cpp util.cpp
custom6_DEPENDENCIES =3D $(MYSQLPP_LIB)
=20
+custom7_SOURCES =3D custom7.cpp util.cpp
+custom7_DEPENDENCIES =3D $(MYSQLPP_LIB)
+
fieldinf1_SOURCES =3D fieldinf1.cpp util.cpp
fieldinf1_DEPENDENCIES =3D $(MYSQLPP_LIB)
=20
Index: examples/resetdb.cpp
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D
--- examples/resetdb.cpp (revision 1163)
+++ examples/resetdb.cpp (working copy)
@@ -60,6 +60,7 @@
// really care, as it'll get created next.
cout << "Dropping existing stock table..." << endl;
query.execute("drop table stock");
+ query.execute("drop table stock2");
}
else {
// Database doesn't exist yet, so create and select it.
@@ -105,6 +106,12 @@
=20
cout << (new_db ? "Created" : "Reinitialized") <<
" sample database successfully." << endl;
+=09
+ // The stock2 table introduces a null string, needed to test
+ // custom7.
+ cout << "Creating new stock2 table..." << endl;
+ query.execute ("create table stock2 (id int primary key, "
+ " name varchar(20), qtty int, eta date)");
}
catch (const mysqlpp::BadQuery& er) {
// Handle any query errors

--sdtB3X0nJg68CQEu--

--i9LlY+UWpKt15+FH
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFD5HEKUQHbkgA+2bIRAn2CAKCELXhn4JWiVAS71N7Hck 8CwonExACeIEmb
k0gFq9dDG58PAGlMcJrrWnY=
=bSO2
-----END PGP SIGNATURE-----

--i9LlY+UWpKt15+FH--


Reply With Quote
  #4  
Old   
Warren Young
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 02-06-2006 , 12:38 PM



Waba wrote:
Quote:
Here is my patch that enables one to use nullable fields in SQLSS. Since
it will break binary compatibility...
Anything that breaks binary compatibility will have to wait for v3.0.
There will at least be a v2.1 release before that point.

Thanks for doing the work, but I'm going to have to put this on a shelf
for now.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #5  
Old   
AT
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 06-11-2006 , 03:52 AM



I guess it is worth mentioning that the patch is based on V2.0.7 of mysqlpp.
Right? I guess it will not work on 2.1.1, since the make environment was
changed. (Automake to bakefile)

Rgds and thx for the patch,
Jens

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw


Reply With Quote
  #6  
Old   
AT
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 06-12-2006 , 12:22 PM



Jens Lindenmeier wrote:
Quote:
I guess it is worth mentioning that the patch is based on V2.0.7 of
mysqlpp.
Right? I guess it will not work on 2.1.1, since the make environment was
changed. (Automake to bakefile)
If you actually _try_ the patch, you'll find that you get only one
failure, which adds a new example to examples/Makefile.am, which is
completely peripheral to the patch proper. It's trivial to add that
example manually.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #7  
Old   
AT
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 07-08-2006 , 04:03 PM



Hi

Does anybody have an updated and tested version of this patch of Waba's
for the latest release of mysql++

thanks
Mike

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw


Reply With Quote
  #8  
Old   
AT
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 07-10-2006 , 10:47 AM



Mike Arnold wrote:
Quote:
Does anybody have an updated and tested version of this patch of Waba's
for the latest release of mysql++
It applies to the current version just fine, if you tell patch to skip
examples/Makefile.am. That change just adds one example program to the
build system, which you can do by hand if you're really interested.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #9  
Old   
AT
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 07-10-2006 , 10:54 AM



Warren Young wrote:
Quote:
Mike Arnold wrote:

Does anybody have an updated and tested version of this patch of
Waba's for the latest release of mysql++

It applies to the current version just fine, if you tell patch to skip
examples/Makefile.am. That change just adds one example program to the
build system, which you can do by hand if you're really interested.
Looking at it deeper, the custom7 example isn't even included in the
original patch, so the example/Makefile.am change shouldn't be applied
anyway. In other words, it's 100% fine as it is, if you tell it to
ignore the hunk that's going to fail anyway.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #10  
Old   
Warren Young
 
Posts: n/a

Default Re: Patch: Nullable fields in SQLSS - 11-05-2007 , 01:20 PM



Waba wrote:
Quote:
Here is my patch that enables one to use nullable fields in SQLSS.
So it's only 21 months since you posted this, but it's applied now.

Not even close to applied as-is, but I hope I've kept the purpose and
spirit of the patch intact. Some of the differences are because of
changes in the library infrastructure since the v2.0 days when you
created this patch. You took MySQL++ to task for ColData deriving from
std::string, for example, which is no longer true in v3.

Another reason for differences is because I thought I had a better way
to get some things done. The biggest example here is the dancing around
you had to do to make it compile after changing DateTime's ctors to be
templatized for anything that looks like a std::string instead of having
explicit ctors for std::string and ColData. I took the ctor change
idea, which was sound, but made the new templatized ctor explicit. This
avoided the dancing around at the expense of implicit conversions of
string to DateTime. Like many implicit conversion ideas, it sounds good
on paper until you see all the demented ways the compiler has for making
use of this freedom.

Anyone reading this who wants to use Null<T> types in SSQLSes: please
try this and report to the list if it doesn't work. This is a very
invasive patch, and I'm not convinced it's completely kosher. You can
check out the svn version of MySQL++ like so:

svn co svn://svn.gna.org/svn/mysqlpp/trunk mysqlp

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.