Discussion:
[soci-users] Weird behaviour of indicators when using soci::values
Brian Ravnsgaard Riis
2013-05-27 21:26:50 UTC
Permalink
Hi,

I've been experimenting with SOCI for a couple of days now, trying to use
it to do ORM agains a SQLite3 backend. Found a weird issue that I really
do not understand, and seems to make SOCI useless for ORM. I'm guessing I
miss something obvious.

Given:

class Category
{
public:
Category(std::string const & name) :
name_(name)
{ }

std::string Name() const
{ return name_; }

void Name(std::string const & name)
{ name_ = name; }

private:
std::string name_;
};

I would expect type_conversion to be specialized as follows:

namespace soci {
template <> struct type_conversion<Category>
{
typedef values base_type;

static void to_base(Category const & c,
base_type & v,
indicator & ind)
{
v.set("CategoryName", c.Name(),
c.Name().empty() ? i_null : i_ok);
ind = i_ok;
}

static void from_base(base_type const & v,
indicator ind,
Category & c)
{
if(ind == i_ok)
c.Name(v.get<std::string>("CategoryName"));
}
};

And called as:

sql << "INSERT INTO Categories (CategoryName) VALUES(:CategoryName)",
soci::use(c_instance1);

sql << "SELECT Categoryname FROM Categories", soci::into(c_instance2);

However in from_base ind is always some random value, probably outside the
indicator enum range and never yet i_ok. I tried making a local indicator
variable and passing it to soci::into but the same thing happens. If I
initialize it to i_ok before passing it, it works.

The same thing happens with the regression tests, if I modify
common-tests.h to make a check of the indicator value (where the source
says "// here we ignore the possibility the whole object might be NULL").

What am I missing? Did I fully misunderstand the recommended approach? Or
am I just daft? Currently, I find both quite possible... :-o

/Brian
Mateusz Loskot
2013-05-30 11:37:13 UTC
Permalink
Post by Brian Ravnsgaard Riis
Hi,
I've been experimenting with SOCI for a couple of days now, trying to use
it to do ORM agains a SQLite3 backend. Found a weird issue that I really
do not understand, and seems to make SOCI useless for ORM. I'm guessing I
miss something obvious.
class Category
{
name_(name)
{ }
std::string Name() const
{ return name_; }
void Name(std::string const & name)
{ name_ = name; }
std::string name_;
};
namespace soci {
template <> struct type_conversion<Category>
{
typedef values base_type;
static void to_base(Category const & c,
base_type & v,
indicator & ind)
{
v.set("CategoryName", c.Name(),
c.Name().empty() ? i_null : i_ok);
ind = i_ok;
}
static void from_base(base_type const & v,
indicator ind,
Category & c)
{
if(ind == i_ok)
c.Name(v.get<std::string>("CategoryName"));
}
};
sql << "INSERT INTO Categories (CategoryName) VALUES(:CategoryName)",
soci::use(c_instance1);
sql << "SELECT Categoryname FROM Categories", soci::into(c_instance2);
However in from_base ind is always some random value, probably outside the
indicator enum range and never yet i_ok. I tried making a local indicator
variable and passing it to soci::into but the same thing happens. If I
initialize it to i_ok before passing it, it works.
Brian,

Thanks for reporting this.

No, you are not missing anything, your use case looks fine.

It seems there is a bug in SOCI caused by uninitialised indicator members
of conversion_into_type and conversion_use_type specialisations.

I have opened issue:

https://github.com/SOCI/soci/issues/152

and I have proposed fix in this pull request

https://github.com/SOCI/soci/pull/153

It hasn't been merged, as it is to be decided if we want to
postpone release of this fix until SOCI 4.0.0.

Meanwhile, if you could check if this fix solves your problem,
that would be very helpful. You can grab it from my fork of the repo
and checkout bugfix/152-indicators branch:

git clone git://github.com/mloskot/soci.git
git checkout bugfix/152-indicators

then build SOCI and test your program with it.

Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net
Brian Ravnsgaard Riis
2013-05-30 12:24:56 UTC
Permalink
Den Thu, 30 May 2013 13:37:13 +0200 skrev Mateusz Loskot
Post by Mateusz Loskot
Brian,
Thanks for reporting this.
No, you are not missing anything, your use case looks fine.
It seems there is a bug in SOCI caused by uninitialised indicator members
of conversion_into_type and conversion_use_type specialisations.
https://github.com/SOCI/soci/issues/152
and I have proposed fix in this pull request
https://github.com/SOCI/soci/pull/153
It hasn't been merged, as it is to be decided if we want to
postpone release of this fix until SOCI 4.0.0.
Meanwhile, if you could check if this fix solves your problem,
that would be very helpful. You can grab it from my fork of the repo
git clone git://github.com/mloskot/soci.git
git checkout bugfix/152-indicators
then build SOCI and test your program with it.
Best regards,
Yep, that seems to work nicely! Thanks a lot! :-)

/Brian
Mateusz Loskot
2013-05-30 13:29:40 UTC
Permalink
Post by Brian Ravnsgaard Riis
Den Thu, 30 May 2013 13:37:13 +0200 skrev Mateusz Loskot
Post by Mateusz Loskot
Brian,
Thanks for reporting this.
No, you are not missing anything, your use case looks fine.
It seems there is a bug in SOCI caused by uninitialised indicator members
of conversion_into_type and conversion_use_type specialisations.
https://github.com/SOCI/soci/issues/152
and I have proposed fix in this pull request
https://github.com/SOCI/soci/pull/153
It hasn't been merged, as it is to be decided if we want to
postpone release of this fix until SOCI 4.0.0.
Meanwhile, if you could check if this fix solves your problem,
that would be very helpful. You can grab it from my fork of the repo
git clone git://github.com/mloskot/soci.git
git checkout bugfix/152-indicators
then build SOCI and test your program with it.
Best regards,
Yep, that seems to work nicely! Thanks a lot! :-)
Great, thanks!
I presume SOCI 3.2.2 is likely to be.

Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net

Loading...