[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