Brian Ravnsgaard Riis
2013-05-27 21:26:50 UTC
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
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