From 7b7a7b9a2a557535837c8d4b0b2af3e44b14594d Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <boris@codesynthesis.com>
Date: Mon, 1 Apr 2013 17:16:49 +0200
Subject: Handle inverse member in base class of polymorphic hierarchy

---
 common/inheritance/polymorphism/driver.cxx |  81 +++++++++++++++++++++++
 common/inheritance/polymorphism/makefile   |   3 +-
 common/inheritance/polymorphism/test14.hxx | 100 +++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+), 1 deletion(-)
 create mode 100644 common/inheritance/polymorphism/test14.hxx

(limited to 'common')

diff --git a/common/inheritance/polymorphism/driver.cxx b/common/inheritance/polymorphism/driver.cxx
index cd0c02e..7ab6346 100644
--- a/common/inheritance/polymorphism/driver.cxx
+++ b/common/inheritance/polymorphism/driver.cxx
@@ -28,6 +28,7 @@
 #include "test11.hxx"
 #include "test12.hxx"
 #include "test13.hxx"
+#include "test14.hxx"
 
 #include "test1-odb.hxx"
 #include "test2-odb.hxx"
@@ -42,6 +43,7 @@
 #include "test11-odb.hxx"
 #include "test12-odb.hxx"
 #include "test13-odb.hxx"
+#include "test14-odb.hxx"
 
 using namespace std;
 using namespace odb::core;
@@ -1921,6 +1923,85 @@ main (int argc, char* argv[])
         assert (rb1.id == b1.id);
       }
     }
+
+    // Test 14: inverse pointer in polymorphic base.
+    //
+    {
+      using namespace test14;
+
+      derived d;
+      d.num = 123;
+
+      d.o1 = new object1;
+      d.o2 = new object2;
+      d.o3.push_back (new object3);
+      d.o4.push_back (new object4);
+
+      // Persist.
+      //
+      {
+        transaction t (db->begin ());
+        db->persist (d.o1);
+        db->persist (d.o2);
+        db->persist (d.o3[0]);
+        db->persist (d.o4[0]);
+        db->persist (d);
+        t.commit ();
+      }
+
+      // Load.
+      //
+      {
+        session s;
+
+        transaction t (db->begin ());
+        object1* p1 (db->load<object1> (d.o1->id));
+        object2* p2 (db->load<object2> (d.o2->id));
+        object3* p3 (db->load<object3> (d.o3[0]->id));
+        object4* p4 (db->load<object4> (d.o4[0]->id));
+        t.commit ();
+
+        assert (p1->d->num = d.num);
+        assert (p2->d[0]->num = d.num);
+        assert (p3->d[0]->num = d.num);
+        assert (p4->d->num = d.num);
+        delete p1->d;
+      }
+
+      // Query.
+      //
+      {
+        typedef odb::query<object1> query;
+        typedef odb::result<object1> result;
+
+        session s;
+        transaction t (db->begin ());
+
+        result r (db->query<object1> (query::d->num == d.num));
+        result::iterator i (r.begin ()), e (r.end ());
+
+        assert (i != e && i->d->num == d.num);
+        delete i.load ()->d;
+        assert (++i == e);
+        t.commit ();
+      }
+
+      {
+        typedef odb::query<object4> query;
+        typedef odb::result<object4> result;
+
+        session s;
+        transaction t (db->begin ());
+
+        result r (db->query<object4> (query::d->num == d.num));
+        result::iterator i (r.begin ()), e (r.end ());
+
+        assert (i != e && i->d->num == d.num);
+        delete i.load ()->d;
+        assert (++i == e);
+        t.commit ();
+      }
+    }
   }
   catch (const odb::exception& e)
   {
diff --git a/common/inheritance/polymorphism/makefile b/common/inheritance/polymorphism/makefile
index f2131f4..d250541 100644
--- a/common/inheritance/polymorphism/makefile
+++ b/common/inheritance/polymorphism/makefile
@@ -6,7 +6,8 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make
 
 cxx_tun := driver.cxx
 odb_hdr := test1.hxx test2.hxx test3.hxx test4.hxx test5.hxx test6.hxx \
-test7.hxx test8.hxx test9.hxx test10.hxx test11.hxx test12.hxx test13.hxx
+test7.hxx test8.hxx test9.hxx test10.hxx test11.hxx test12.hxx test13.hxx \
+test14.hxx
 cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o) $(odb_hdr:.hxx=-odb.o))
 cxx_od  := $(cxx_obj:.o=.o.d)
 
diff --git a/common/inheritance/polymorphism/test14.hxx b/common/inheritance/polymorphism/test14.hxx
new file mode 100644
index 0000000..95baf61
--- /dev/null
+++ b/common/inheritance/polymorphism/test14.hxx
@@ -0,0 +1,100 @@
+// file      : common/inheritance/polymorphism/test14.hxx
+// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
+// license   : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef TEST14_HXX
+#define TEST14_HXX
+
+#include <vector>
+
+#include <odb/core.hxx>
+
+// Test inverse pointer in polymorphic base.
+//
+#pragma db namespace table("t14_")
+namespace test14
+{
+  struct object1;
+  struct object2;
+  struct object3;
+  struct object4;
+
+  #pragma db object polymorphic session
+  struct base
+  {
+    virtual ~base ();
+
+    #pragma db id auto
+    unsigned long id;
+
+    object1* o1;
+    object2* o2;
+    std::vector<object3*> o3;
+    std::vector<object4*> o4;
+  };
+
+  #pragma db object
+  struct derived: base
+  {
+    unsigned long num;
+  };
+
+  // one-to-one(i)
+  //
+  #pragma db object session
+  struct object1
+  {
+    #pragma db id auto
+    unsigned long id;
+
+    #pragma db inverse(o1)
+    derived* d;
+  };
+
+  // one-to-many(i)
+  //
+  #pragma db object session
+  struct object2
+  {
+    #pragma db id auto
+    unsigned long id;
+
+    #pragma db inverse(o2)
+    std::vector<derived*> d;
+  };
+
+  // many-to-many(i)
+  //
+  #pragma db object session
+  struct object3
+  {
+    #pragma db id auto
+    unsigned long id;
+
+    #pragma db inverse(o3)
+    std::vector<derived*> d;
+  };
+
+  // many-to-one(i)
+  //
+  #pragma db object session
+  struct object4
+  {
+    #pragma db id auto
+    unsigned long id;
+
+    #pragma db inverse(o4)
+    derived* d;
+  };
+
+  inline base::
+  ~base ()
+  {
+    delete o1;
+    delete o2;
+    delete o3[0];
+    delete o4[0];
+  }
+}
+
+#endif // TEST14_HXX
-- 
cgit v1.1