From b336e7a1671fdd504759f87bc5ed23fbc7bcf717 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 15 Aug 2016 18:27:56 +0200 Subject: Lock object statements when loading sections Since we use the id image and loading of object pointers can overwrite it. --- common/section/polymorphism/driver.cxx | 45 +++++++++++++++++++++++++++++ common/section/polymorphism/test.hxx | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/common/section/polymorphism/driver.cxx b/common/section/polymorphism/driver.cxx index c9cfee3..d58e850 100644 --- a/common/section/polymorphism/driver.cxx +++ b/common/section/polymorphism/driver.cxx @@ -1754,6 +1754,51 @@ main (int argc, char* argv[]) t.commit (); } } + +#ifdef HAVE_CXX11 + // Test reuse/polymorphic inheritance and optimistic mix. + // + { + using namespace test9; + using std::shared_ptr; + + unsigned long long id; + + { + container c (123); + + c.e1.push_back (shared_ptr (new element (11))); + c.e1.push_back (shared_ptr (new element (12))); + + c.e2.push_back (shared_ptr (new element (21))); + c.e2.push_back (shared_ptr (new element (22))); + + transaction t (db->begin ()); + + db->persist (c.e1[0]); + db->persist (c.e1[1]); + db->persist (c.e2[0]); + db->persist (c.e2[1]); + + id = db->persist (c); + + t.commit (); + } + + { + transaction t (db->begin ()); + + shared_ptr c (db->load (id)); + + assert (c->n == 123); + db->load (*c, c->s); + assert (c->e1.size () == 2 && c->e1[0]->n == 11 && c->e1[1]->n == 12); + assert (c->e2.size () == 2 && c->e2[0]->n == 21 && c->e2[1]->n == 22); + + t.commit (); + } + } +#endif } catch (const odb::exception& e) { diff --git a/common/section/polymorphism/test.hxx b/common/section/polymorphism/test.hxx index 1c8e8fb..fe4ca96 100644 --- a/common/section/polymorphism/test.hxx +++ b/common/section/polymorphism/test.hxx @@ -5,8 +5,11 @@ #ifndef TEST_HXX #define TEST_HXX +#include // HAVE_CXX11 + #include #include +#include #include #include @@ -492,4 +495,53 @@ namespace test8 }; } +// Test id overwrite regression. +// +// The key here is the setup: the object that contains the containers in a +// section and the pointers to objects stored in those containers. And these +// objects derive polymorphically from the same base (and thus shared the id +// bindind). +// +#ifdef HAVE_CXX11 +#pragma db namespace table("t9_") +namespace test9 +{ + #pragma db object polymorphic pointer(std::shared_ptr) + struct base + { + virtual ~base () {} + + #pragma db id auto + unsigned long id; + }; + + #pragma db object + struct element: base + { + element (int n_ = 0): n (n_) {} + + int n; + }; + + typedef std::vector> elements; + + #pragma db object + struct container: base + { + container (int n_ = 0): n (n_) {} + + int n; + + #pragma db load(lazy) update(always) + odb::section s; + + #pragma db section(s) + elements e1; + + #pragma db section(s) + elements e2; + }; +} +#endif + #endif // TEST_HXX -- cgit v1.1