[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