[odb-users] sqlite, one to many relationship, std::map,
std::weak_ptr
Daniel James
danielpeterjames at gmail.com
Thu Jan 17 08:41:18 EST 2013
Hello
I hope my mistake here isn't too embarrassingly simple...
I have the following objects to persist:
class Child;
#pragma db object pointer(std::shared_ptr)
class Parent
{
public:
#pragma db inverse(parent)
std::map<std::string, std::weak_ptr<Child>> children;
private:
friend class odb::access;
#pragma db id auto
unsigned long id_;
};
#pragma db object pointer(std::shared_ptr)
class Child
{
public:
std::string name;
std::shared_ptr<Parent> parent;
private:
friend class odb::access;
#pragma db id auto
unsigned long id_;
};
They are persisted to the following tables:
sqlite> select * from Child;
name parent id
---------- ---------- ----------
c1 1 1
c2 1 2
sqlite> select * from Parent;
id
----------
1
sqlite>
But upon retrieval of the Child objects I'm getting the following error:
SELECT "Parent"."id" FROM "Parent" WHERE "Parent"."id"=?
SELECT "Child"."id" FROM "Child" WHERE "Child"."parent"=?
Assertion failed: (static_cast<size_t> (sqlite3_data_count (stmt_)) == n),
function bind_result, file statement.cxx, line 152.
Abort trap: 6
Here's a program that demonstrates the issue:
int main(int argc, char *argv[])
{
odb::sqlite::database db("test.db", SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE);
{
odb::connection_ptr c (db.connection ());
c->execute ("PRAGMA foreign_keys=OFF");
odb::transaction t (c->begin ());
odb::schema_catalog::create_schema (db);
t.commit ();
c->execute ("PRAGMA foreign_keys=ON");
}
std::shared_ptr<Parent> p(std::make_shared<Parent>());
std::shared_ptr<Child> c1(std::make_shared<Child>());
c1->name = "c1";
std::shared_ptr<Child> c2(std::make_shared<Child>());
c2->name = "c2";
p->children["c1"] = c1;
p->children["c2"] = c2;
c1->parent = p;
c2->parent = p;
try
{
odb::transaction t(db.begin());
t.tracer(odb::stderr_tracer);
db.persist(p);
db.persist(c1);
db.persist(c2);
t.commit();
}
catch (odb::exception& e)
{
std::cerr << e.what() << '\n';
}
odb::transaction t2(db.begin());
t2.tracer(odb::stderr_tracer);
auto results(db.query(odb::query<Child>()));
auto r(results.begin());
std::cout << r->name << '\n';
t2.commit();
return 0;
}
More information about the odb-users
mailing list