List:MySQL++« Previous MessageNext Message »
From:Warren Young Date:December 4 2008 10:20pm
Subject:Re: Problem with Null string type
View as plain text  
Brad Hubbard wrote:
> 23 mysqlpp::sql_char &mob = it->mobileNumber;

Okay, I was on the right track, just for the wrong reason.

There's really a chain of problems here.

The start of the chain is that Null::operator Type() is defined rather 
too cleverly to be as widely useful as it needs to be.  You can fix it 
with this patch:

Index: lib/null.h
===================================================================
--- lib/null.h  (revision 2432)
+++ lib/null.h  (working copy)
@@ -224,10 +224,10 @@
         /// this template.  See NullIsNull, NullIsZero and NullIsBlank.
         ///
         /// Otherwise, just returns the 'data' member.
-       operator Type&()
+       operator Type() const
         {
                 if (is_null)
-                       return data = Behavior::null_is();
+                       return Behavior::null_is();
                 else
                         return data;
         }

This allows you to use nullable types in const contexts.  It in turn 
means you need to change your assignment from by-reference to by-value:

	mysqlpp::sql_char mob = it->mobileNumber;

As I said before, this is plenty efficient, because it uses reference 
counted copies, so there's really no reason to cry over the loss of 
reference semantics.

But, the next link in the chain is that this doesn't compile, now on 
purpose instead of by accident.  You can't blindly convert a nullable 
type to non-null, any more than you can convert const to non-const: 
you'd be throwing away type information, so MySQL++ prevents it.  The 
error message you now get is a little cryptic, but clear enough.

This brings me back to my initial advice: change this line to either:

     mysqlpp::Null<mysqlpp::sql_char> mob = it->mobileNumber;

or:

     mysqlpp::sql_char mob = it->mobileNumber.data;

The first is safe, because you can call mob.is_null() to check it before 
doing something with the data.  The second is not, because 
Null<T,B>::data is uninitialized when the object is SQL NULL!  It's safe 
to assign from Null<T,B>::data if you call it->mobileNumber.is_null() 
first to check that it's not SQL NULL, of course.

If you absolutely have to be able to cast away null implicitly like 
this, you can change the SSQLS field type to:

	typedef mysqlpp::Null<mysqlpp::sql_char, mysqlpp::NullIsBlank>
			MyNullString;

	...

	MyNullString, mobileNumber

The typedef is required due to the same comma operator madness that came 
up in Ryan Frenz' recent thread.

NullIsBlank means you get an empty string for SQL NULL when converting 
to a stringish type like sql_char.

One then questions why you need this column to be NULLable, though, if 
you're going to just cast away the attribute like this.  I assume SQL 
NULL has a meaning different from blank in your DB, so you should be 
doing the conversions as above, with calls to is_null() before using the 
data.
Thread
Problem with Null string typeBrad Hubbard3 Dec
  • Re: Problem with Null string typeWarren Young3 Dec
    • Re: Problem with Null string typeBrad Hubbard3 Dec
      • Re: Problem with Null string typeWarren Young3 Dec
        • Re: Problem with Null string typeBrad Hubbard4 Dec
          • Re: Problem with Null string typeBrad Hubbard4 Dec
          • Re: Problem with Null string typeWarren Young4 Dec
            • Re: Problem with Null string typeBrad Hubbard5 Dec
              • Re: Problem with Null string typeWarren Young5 Dec
                • Re: Problem with Null string typeBrad Hubbard6 Dec
Re: Problem with Null string typeWarren Young6 Dec
  • Re: Problem with Null string typeBrad Hubbard6 Dec
    • execute failedbsingh8 Dec
      • Re: execute failedWarren Young8 Dec