From 6b76715e63d2c265a4c51c73f9019bc578f874cb Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 8 Oct 2012 14:47:57 +0200 Subject: Fix bug in transient inheritance handling Also test that we can handle it for objects, composite values, and views. --- common/polymorphism/driver.cxx | 1880 ---------------------------------------- 1 file changed, 1880 deletions(-) delete mode 100644 common/polymorphism/driver.cxx (limited to 'common/polymorphism/driver.cxx') diff --git a/common/polymorphism/driver.cxx b/common/polymorphism/driver.cxx deleted file mode 100644 index 1bd8a2f..0000000 --- a/common/polymorphism/driver.cxx +++ /dev/null @@ -1,1880 +0,0 @@ -// file : common/polymorphism/driver.cxx -// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC -// license : GNU GPL v2; see accompanying LICENSE file - -// Test polymorphic object inheritance. -// - -#include // std::auto_ptr -#include -#include - -#include -#include -#include - -#include - -#include "test1.hxx" -#include "test2.hxx" -#include "test3.hxx" -#include "test4.hxx" -#include "test5.hxx" -#include "test6.hxx" -#include "test7.hxx" -#include "test8.hxx" -#include "test9.hxx" -#include "test10.hxx" -#include "test11.hxx" -#include "test12.hxx" - -#include "test1-odb.hxx" -#include "test2-odb.hxx" -#include "test3-odb.hxx" -#include "test4-odb.hxx" -#include "test5-odb.hxx" -#include "test6-odb.hxx" -#include "test7-odb.hxx" -#include "test8-odb.hxx" -#include "test9-odb.hxx" -#include "test10-odb.hxx" -#include "test11-odb.hxx" -#include "test12-odb.hxx" - -using namespace std; -using namespace odb::core; - -const char* events[] = -{ - "pre_persist", - "post_persist", - "pre_load", - "post_load", - "pre_update", - "post_update", - "pre_erase", - "post_erase" -}; - -namespace test6 -{ - void base:: - db_callback (callback_event e, database&) - { - cout << "base " << events[e] << " " << id << endl; - } - - void base:: - db_callback (callback_event e, database&) const - { - cout << "base " << events[e] << " " << id << " const" << endl; - } - - void derived:: - db_callback (callback_event e, database&) const - { - cout << "derived " << events[e] << " " << id << " const" << endl; - } -} - -int -main (int argc, char* argv[]) -{ - try - { - auto_ptr db (create_database (argc, argv)); - - // Test 1: basic polymorphism functionality. - // - { - using namespace test1; - - root r (1, 1); - base b (2, 2, "bbb"); - derived d (3, 3, "ddd"); - - r.strs.push_back ("a"); - r.strs.push_back ("aa"); - r.strs.push_back ("aaa"); - - b.nums.push_back (21); - b.nums.push_back (22); - b.nums.push_back (23); - b.strs.push_back ("b"); - b.strs.push_back ("bb"); - b.strs.push_back ("bbb"); - - d.nums.push_back (31); - d.nums.push_back (32); - d.nums.push_back (33); - d.strs.push_back ("d"); - d.strs.push_back ("dd"); - d.strs.push_back ("ddd"); - - { - transaction t (db->begin ()); - - // Static persist. - // - db->persist (r); - db->persist (b); - - // Dynamic persist. - // - root& r (d); - db->persist (r); - - t.commit (); - } - - // Static load. - // - { - transaction t (db->begin ()); - auto_ptr pr (db->load (r.id)); - auto_ptr pb (db->load (b.id)); - auto_ptr pd (db->load (d.id)); - t.commit (); - - assert (*pr == r); - assert (*pb == b); - assert (*pd == d); - } - - // Dynamic load. - // - { - transaction t (db->begin ()); - auto_ptr pb (db->load (b.id)); - auto_ptr pd1 (db->load (d.id)); - auto_ptr pd2 (db->load (d.id)); - t.commit (); - - assert (*pb == b); - assert (*pd1 == d); - assert (*pd2 == d); - } - - // Invalid load. - // - { - transaction t (db->begin ()); - - try - { - auto_ptr p (db->load (r.id)); - assert (false); - } - catch (const object_not_persistent&) {} - - try - { - auto_ptr p (db->load (b.id)); - assert (false); - } - catch (const object_not_persistent&) {} - - t.commit (); - } - - // Static load into existing instance. - // - { - transaction t (db->begin ()); - root r1; - db->load (r.id, r1); - base b1; - db->load (b.id, b1); - derived d1; - db->load (d.id, d1); - t.commit (); - - assert (r1 == r); - assert (b1 == b); - assert (d1 == d); - } - - // Dynamic load into existing instance. - // - { - transaction t (db->begin ()); - base b1; - db->load (b.id, static_cast (b1)); - derived d1; - db->load (d.id, static_cast (d1)); - t.commit (); - - assert (b1 == b); - assert (d1 == d); - } - - // Invalid load into existing instance. - // - { - transaction t (db->begin ()); - - try - { - base b; - db->load (r.id, static_cast (b)); - assert (false); - } - catch (const object_not_persistent&) {} - - try - { - derived d; - db->load (b.id, static_cast (d)); - assert (false); - } - catch (const object_not_persistent&) {} - - t.commit (); - } - - // Slicing load. - // - { - transaction t (db->begin ()); - root b1; - db->load (b.id, b1); - base d1; - db->load (d.id, d1); - t.commit (); - - assert (b1 == static_cast (b)); - assert (d1 == static_cast (d)); - } - - // Static reload. - // - { - transaction t (db->begin ()); - root r1; - r1.id = r.id; - db->reload (r1); - base b1; - b1.id = b.id; - db->reload (b1); - derived d1; - d1.id = d.id; - db->reload (d1); - t.commit (); - - assert (r1 == r); - assert (b1 == b); - assert (d1 == d); - } - - // Dynamic reload. - // - { - transaction t (db->begin ()); - base b1; - b1.id = b.id; - db->reload (static_cast (b1)); - derived d1; - d1.id = d.id; - db->reload (static_cast (d1)); - t.commit (); - - assert (b1 == b); - assert (d1 == d); - } - - // Invalid reload. - // - { - transaction t (db->begin ()); - - try - { - base b; - b.id = r.id; - db->reload (static_cast (b)); - assert (false); - } - catch (const object_not_persistent&) {} - - try - { - derived d; - d.id = b.id; - db->reload (static_cast (d)); - assert (false); - } - catch (const object_not_persistent&) {} - - t.commit (); - } - - // Slicing reload. - // - { - transaction t (db->begin ()); - root b1; - b1.id = b.id; - db->reload (b1); - base d1; - d1.id = d.id; - db->reload (d1); - t.commit (); - - assert (b1 == static_cast (b)); - assert (d1 == static_cast (d)); - } - - // Query. - // - { - typedef odb::query root_query; - typedef odb::result root_result; - - typedef odb::query base_query; - typedef odb::result base_result; - - typedef odb::result derived_result; - - transaction t (db->begin ()); - - // Test loading via root. - // - { - root_result qr (db->query ("ORDER BY" + root_query::id)); - root_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && *i == r); - assert (++i != e && *i == b); - assert (++i != e && *i == d); - assert (++i == e); - } - - // Test loading via base. - // - { - base_result qr (db->query ("ORDER BY" + base_query::id)); - base_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && *i == b); - assert (++i != e && *i == d); - assert (++i == e); - } - - // Test loading via derived. - // - { - derived_result qr (db->query ()); - derived_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && *i == d); - assert (++i == e); - } - - // Test loading into an existing instance. - // - { - root_result qr (db->query ()); - - unsigned short mask (0); - - for (root_result::iterator i (qr.begin ()); i != qr.end (); ++i) - { - string ds (i.discriminator ()); - - if (ds == "test1::root") - { - root r1; - i.load (r1); - assert (r1 == r); - mask |= 1; - } - else if (ds == "test1::base") - { - base b1; - i.load (b1); - assert (b1 == b); - mask |= 2; - } - else if (ds == "test1::derived") - { - derived d1; - i.load (d1); - assert (d1 == d); - mask |= 4; - } - else - assert (false); - } - - assert (mask == 7); - } - - // Test query conditions with columns from multiple tables. - // - { - base_result qr ( - db->query ( - base_query::num == 3 && base_query::str == "ddd")); - - base_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && *i == d); - assert (++i == e); - } - - // Test discriminator access. - // - { - base_result qr (db->query (base_query::id == 3)); - base_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && i.discriminator () == "test1::derived"); - assert (++i == e); - } - - // Test loading of an object from the same hierarchy during - // query result iteration (tests image copying via change - // callbacks in some databases). - // - { - base_result qr (db->query ()); - - unsigned short mask (0); - - for (base_result::iterator i (qr.begin ()); i != qr.end (); ++i) - { - string ds (i.discriminator ()); - - if (ds == "test1::base") - { - auto_ptr d1 (db->load (d.id)); - assert (*d1 == d); - assert (*i == b); - mask |= 1; - } - else if (ds == "test1::derived") - { - auto_ptr b1 (db->load (b.id)); - assert (*b1 == b); - assert (*i == d); - mask |= 2; - } - } - - assert (mask == 3); - } - - t.commit (); - } - - // Views. - // - { - typedef odb::query root_query; - typedef odb::result root_result; - - typedef odb::query base_query; - typedef odb::result base_result; - - typedef odb::result derived_result; - - transaction t (db->begin ()); - - // root - // - { - root_result qr (db->query ("ORDER BY" + root_query::id)); - root_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && i->typeid_ == "test1::root" && i->num == r.num); - assert (++i != e && i->typeid_ == "test1::base" && i->num == b.num); - assert (++i != e && i->typeid_ == "test1::derived" && i->num == d.num); - assert (++i == e); - } - - // base - // - { - base_result qr (db->query ("ORDER BY" + base_query::id)); - base_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && - i->id == b.id && i->num == b.num && i->str == b.str); - assert (++i != e && - i->id == d.id && i->num == d.num && i->str == d.str); - assert (++i == e); - } - - // derived - // - { - derived_result qr (db->query ()); - derived_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && - i->num == d.num && i->str == d.str && - i->dnum == d.dnum && i->dstr == d.dstr); - assert (++i == e); - } - - t.commit (); - } - - // Update. - // - r.num++; - r.strs.push_back ("aaaa"); - - b.num++; - b.str += "b"; - b.nums.push_back (24); - b.strs.push_back ("bbbb"); - - d.num++; - d.str += "d"; - d.dnum++; - d.dstr += "d"; - d.nums.push_back (34); - d.strs.push_back ("dddd"); - - { - transaction t (db->begin ()); - - // Static update. - // - db->update (r); - db->update (b); - - // Dynamic update. - // - root& r (d); - db->update (r); - - t.commit (); - } - - // Verify update. - // - { - transaction t (db->begin ()); - auto_ptr pr (db->load (r.id)); - auto_ptr pb (db->load (b.id)); - auto_ptr pd (db->load (d.id)); - t.commit (); - - assert (*pr == r); - assert (*pb == b); - assert (*pd == d); - } - - // Invalid erase via id. - // - { - transaction t (db->begin ()); - - try - { - db->erase (r.id); - assert (false); - } - catch (const object_not_persistent&) {} - - try - { - db->erase (b.id); - assert (false); - } - catch (const object_not_persistent&) {} - - t.commit (); - } - - // Static erase via id. - // - { - transaction t (db->begin ()); - db->erase (r.id); - db->erase (b.id); - t.commit (); - } - - // Dynamic erase via id. - // - { - transaction t (db->begin ()); - db->erase (d.id); - t.commit (); - } - - { - transaction t (db->begin ()); - db->persist (r); - db->persist (b); - db->persist (d); - t.commit (); - } - - // Static erase via object. - // - { - transaction t (db->begin ()); - db->erase (r); - db->erase (b); - t.commit (); - } - - // Dynamic erase via object. - // - { - const root& r (d); - transaction t (db->begin ()); - db->erase (r); - t.commit (); - } - } - - // Test 2: inverse object pointers in polymorhic bases. - // - { - using namespace test2; - - derived d (1, "d", 1); - root_pointer rp (&d); - base_pointer bp (&d); - - { - transaction t (db->begin ()); - db->persist (rp); - db->persist (bp); - - d.rp.reset (*db, &rp); - d.bp.reset (*db, &bp); - - db->persist (d); - t.commit (); - } - - { - transaction t (db->begin ()); - auto_ptr pd (db->load (d.id)); - auto_ptr pb (db->load (d.id)); - auto_ptr pr (db->load (d.id)); - t.commit (); - - assert (pd->rp.object_id () == rp.id && - pd->bp.object_id () == bp.id); - - derived* p (dynamic_cast (pb.get ())); - assert (p != 0 && - p->rp.object_id () == rp.id && - p->bp.object_id () == bp.id); - - p = dynamic_cast (pr.get ()); - assert (p != 0 && - p->rp.object_id () == rp.id && - p->bp.object_id () == bp.id); - } - - // Query. - // - { - typedef odb::query base_query; - typedef odb::result base_result; - - transaction t (db->begin ()); - - // Test query conditions with columns in pointed-to objects from - // multiple tables. - // - { - base_result qr ( - db->query ( - base_query::rp->id == rp.id && - base_query::bp->id == bp.id)); - - base_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && i.discriminator () == "test2::derived"); - assert (++i == e); - } - - t.commit (); - } - - // Views. - // - { - typedef odb::result root_result; - typedef odb::result base_result; - - transaction t (db->begin ()); - - // root - // - { - root_result qr (db->query ()); - root_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && i->rp_id == rp.id && i->r_id == d.id); - assert (++i == e); - } - - // base - // - { - base_result qr (db->query ()); - base_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && - i->bp_id == bp.id && i->b_id == d.id && i->str == d.str); - assert (++i == e); - } - - t.commit (); - } - } - - // Test 3: delayed loading. - // - { - using namespace test3; - - base b1 (21, 21); - base b2 (22, 22); - base b3 (23, 23); - - derived d1 (31, 31, "d"); - derived d2 (32, 32, "dd"); - derived d3 (33, 33, "ddd"); - - b1.rptr = new root (1); - b2.rptr = new base (2, 2); - b3.rptr = new derived (3, 3, "b3"); - - d1.rptr = new root (4); - d2.rptr = new base (5, 5); - d3.rptr = new derived (6, 6, "d3"); - - d2.bptr = new base (7, 7); - d3.bptr = new derived (8, 8, "d3b"); - - { - transaction t (db->begin ()); - db->persist (b1); - db->persist (b2); - db->persist (b3); - - db->persist (d1); - db->persist (d2); - db->persist (d3); - - db->persist (b1.rptr); - db->persist (b2.rptr); - db->persist (b3.rptr); - - db->persist (d1.rptr); - db->persist (d2.rptr); - db->persist (d3.rptr); - - db->persist (d2.bptr); - db->persist (d3.bptr); - - t.commit (); - } - - { - transaction t (db->begin ()); - - { - auto_ptr p1 (db->load (b1.id)); - auto_ptr p2 (db->load (b2.id)); - auto_ptr p3 (db->load (b3.id)); - assert (*p1 == b1); - assert (*p2 == b2); - assert (*p3 == b3); - } - - { - auto_ptr p1 (db->load (d1.id)); - auto_ptr p2 (db->load (d2.id)); - auto_ptr p3 (db->load (d3.id)); - assert (*p1 == d1); - assert (*p2 == d2); - assert (*p3 == d3); - } - - t.commit (); - } - - // Query. - // - { - typedef odb::query derived_query; - typedef odb::result derived_result; - - transaction t (db->begin ()); - - // Test query conditions with columns in pointed-to objects from - // multiple tables. - // - { - derived_result qr ( - db->query ( - derived_query::rptr->id == 6 && - derived_query::bptr->id == 8 && - derived_query::bptr->num == 8)); - - derived_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && *i == d3); - assert (++i == e); - } - - t.commit (); - } - - // Views. - // - { - typedef odb::query base_query; - typedef odb::result base_result; - - typedef odb::query derived_query; - typedef odb::result derived_result; - - typedef odb::query root_query; - typedef odb::result root_result; - - transaction t (db->begin ()); - - // base - // - { - base_result qr ( - db->query ( - base_query::base::num == b2.num && - base_query::base::id == b2.id && - base_query::r::id == b2.rptr->id)); - - base_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && - i->b_id == b2.id && - i->r_id == b2.rptr->id && - i->num == b2.num); - assert (++i == e); - } - - // derived - // - { - derived_result qr ( - db->query ( - derived_query::d::str == d3.str && - derived_query::d::num == d3.num && - derived_query::b::num == d3.bptr->num && - derived_query::d::id == d3.id && - derived_query::b::id == d3.bptr->id && - derived_query::r::id == d3.rptr->id)); - - derived_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && - i->d_id == d3.id && - i->b_id == d3.bptr->id && - i->r_id == d3.rptr->id && - i->d_num == d3.num && - i->b_num == d3.bptr->num && - i->str == d3.str); - assert (++i == e); - } - - // root - // - { - root_result qr ( - db->query ( - root_query::r::id.in (b2.rptr->id, d2.rptr->id))); - - root_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && - i->r_id == d2.rptr->id && - i->d_id == d2.id && - i->str == d2.str); - assert (++i == e); - } - - t.commit (); - } - } - - // Test 4: views. - // - { - using namespace test4; - - base1 b1 (21, 1); - - root2 r2 (11, 0); - base2 b2 (21, 1, "abc"); - - { - transaction t (db->begin ()); - db->persist (b1); - db->persist (r2); - db->persist (b2); - t.commit (); - } - - { - typedef odb::query query; - typedef odb::result result; - - transaction t (db->begin ()); - - { - result qr ( - db->query ( - query::base1::num == b1.num)); - - result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && i->str == "abc"); - assert (++i == e); - } - - t.commit (); - } - - { - typedef odb::result result; - - transaction t (db->begin ()); - - { - result qr (db->query ()); - result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && i->min_num == 1); - assert (++i == e); - } - - t.commit (); - } - } - - // Test 5: polymorphism and optimistic concurrency. - // - { - using namespace test5; - - root r (1, 1); - base b (2, 2, "bbb"); - derived d (3, 3, "ddd"); - - r.strs.push_back ("a"); - r.strs.push_back ("aa"); - r.strs.push_back ("aaa"); - - b.nums.push_back (21); - b.nums.push_back (22); - b.nums.push_back (23); - b.strs.push_back ("b"); - b.strs.push_back ("bb"); - b.strs.push_back ("bbb"); - - d.nums.push_back (31); - d.nums.push_back (32); - d.nums.push_back (33); - d.strs.push_back ("d"); - d.strs.push_back ("dd"); - d.strs.push_back ("ddd"); - - { - transaction t (db->begin ()); - db->persist (r); - db->persist (b); - db->persist (d); - t.commit (); - } - - // Update. - // - { - transaction t (db->begin ()); - - // Root. - // - { - auto_ptr p (db->load (r.id)); - - r.num++; - r.strs.push_back ("aaaa"); - db->update (r); - - p->num--; - p->strs.pop_back (); - try - { - db->update (p); - assert (false); - } - catch (const odb::object_changed&) {} - - // Make sure the object is intact. - // - db->reload (p); - assert (r == *p); - } - - // Base. - // - { - auto_ptr p (db->load (b.id)); - - b.num++; - b.str += "b"; - b.strs.push_back ("bbbb"); - b.nums.push_back (24); - db->update (b); - - p->num--; - p->str += "B"; - p->strs.pop_back (); - p->nums.pop_back (); - try - { - db->update (p); - assert (false); - } - catch (const odb::object_changed&) {} - - // Make sure the object is intact. - // - db->reload (p); - assert (b == *p); - } - - // Derived. - // - { - auto_ptr p (db->load (d.id)); // Via root. - - d.num++; - d.str += "d"; - d.strs.push_back ("dddd"); - d.nums.push_back (24); - d.dnum++; - d.dstr += "d"; - db->update (d); - - derived& d1 (static_cast (*p)); - d1.num--; - d1.str += "D"; - d1.strs.pop_back (); - d1.nums.pop_back (); - d1.dnum--; - d1.dstr += "D"; - try - { - db->update (p); - assert (false); - } - catch (const odb::object_changed&) {} - - // Make sure the object is intact. - // - db->reload (p); - assert (d == *p); - } - - t.commit (); - } - - // Reload. - // - { - transaction t (db->begin ()); - - // Make sure reload doesn't modify the object if the versions - // match. - // - derived d1 (d); - d1.num++; - d1.str += "d"; - d1.strs.push_back ("dddd"); - d1.nums.push_back (24); - d1.dnum++; - d1.dstr += "d"; - derived d2 (d1); - - db->reload (d1); - assert (d1 == d2); - - t.commit (); - } - - // Erase. - // - { - transaction t (db->begin ()); - - // Root. - // - { - auto_ptr p (db->load (r.id)); - - r.num++; - r.strs.push_back ("aaaaa"); - db->update (r); - - try - { - db->erase (p); - assert (false); - } - catch (const odb::object_changed&) {} - - db->reload (p); - db->erase (p); - } - - // Base. - // - { - auto_ptr p (db->load (b.id)); - - b.num++; - b.str += "b"; - b.strs.push_back ("bbbb"); - b.nums.push_back (24); - db->update (b); - - try - { - db->erase (p); - assert (false); - } - catch (const odb::object_changed&) {} - - db->reload (p); - db->erase (p); - } - - // Derived. - // - { - auto_ptr p (db->load (d.id)); // Via root. - - d.num++; - d.str += "d"; - d.strs.push_back ("dddd"); - d.nums.push_back (24); - d.dnum++; - d.dstr += "d"; - db->update (d); - - try - { - db->erase (p); - assert (false); - } - catch (const odb::object_changed&) {} - - db->reload (p); - db->erase (p); - } - - // Try to update non-existent object. - // - { - try - { - db->update (d); - assert (false); - } - catch (const odb::object_changed&) {} - } - - // Try to erase non-existent object. - // - { - try - { - db->erase (d); - assert (false); - } - catch (const odb::object_changed&) {} - } - - t.commit (); - } - } - - // Test 6: polymorphism and callbacks. - // - { - using namespace test6; - - base b (1, 1, "bbb"); - auto_ptr d (new derived (2, 2, "ddd")); - - // Persist. - // - { - transaction t (db->begin ()); - db->persist (b); - db->persist (d); - t.commit (); - } - - // Load. - // - { - transaction t (db->begin ()); - - auto_ptr pb (db->load (b.id)); - auto_ptr pd (db->load (d->id)); - - db->load (b.id, *pb); - db->load (d->id, *pd); - - db->reload (*pb); - db->reload (*pd); - - t.commit (); - } - - // Update. - // - { - b.num++; - d->num++; - - transaction t (db->begin ()); - db->update (b); - db->update (d); - t.commit (); - } - - // Query. - // - { - typedef odb::query query; - typedef odb::result result; - - transaction t (db->begin ()); - - result r (db->query ("ORDER BY" + query::id)); - for (result::iterator i (r.begin ()); i != r.end (); ++i) - *i; - - t.commit (); - } - - // Erase. - // - { - transaction t (db->begin ()); - db->erase (b); - db->erase (d); - t.commit (); - } - - // Recursive (delayed) loading. - // - { - derived d (3, 3, "dddd"); - d.ptr.reset (new derived (4, 4, "ddddd")); - - { - transaction t (db->begin ()); - db->persist (d); - db->persist (d.ptr); - t.commit (); - } - - { - transaction t (db->begin ()); - auto_ptr p (db->load (d.id)); - t.commit (); - } - } - } - - // Test 7: polymorphism and object cache (session). - // -#if defined(HAVE_CXX11) || defined(HAVE_TR1_MEMORY) - { - using namespace test7; - - shared_ptr r (new root (1, 1)); - shared_ptr b (new base (2, 2, "b")); - shared_ptr d (new derived (3, 3, "d")); - - // Persist. - // - { - session s; - - { - transaction t (db->begin ()); - db->persist (r); - db->persist (b); - db->persist (d); - t.commit (); - } - - assert (db->load (r->id) == r); - assert (db->load (b->id) == b); - assert (db->load (d->id) == d); - } - - // Load. - // - { - session s; - - transaction t (db->begin ()); - shared_ptr r1 (db->load (r->id)); - shared_ptr b1 (db->load (b->id)); - shared_ptr d1 (db->load (d->id)); - t.commit (); - - assert (db->load (r->id) == r1); - assert (db->load (b->id) == b1); - assert (db->load (d->id) == d1); - - assert (!db->find (b->id)); - } - - // Query. - // - { - typedef odb::query query; - typedef odb::result result; - - session s; - - transaction t (db->begin ()); - shared_ptr r1 (db->load (r->id)); - shared_ptr b1 (db->load (b->id)); - shared_ptr d1 (db->load (d->id)); - t.commit (); - - { - transaction t (db->begin ()); - - result r (db->query ("ORDER BY" + query::id)); - result::iterator i (r.begin ()), e (r.end ()); - - assert (i != e && i.load () == r1); - assert (++i != e && i.load () == b1); - assert (++i != e && i.load () == d1); - assert (++i == e); - - t.commit (); - } - } - - // Erase. - // - { - session s; - - { - transaction t (db->begin ()); - db->load (r->id); - db->load (b->id); - db->load (d->id); - t.commit (); - } - - { - transaction t (db->begin ()); - db->erase (r); - db->erase (b); - db->erase (d); - t.commit (); - } - - { - transaction t (db->begin ()); - assert (!db->find (r->id)); - assert (!db->find (b->id)); - assert (!db->find (d->id)); - t.commit (); - } - } - } -#endif - - // Test 8: polymorphism and abstract bases. - // - { - using namespace test8; - - base b (1, 1, "b"); - interm i (2, 2, "i", true); - derived1 d1 (3, 3, "d1", true); - derived2 d2 (4, 4, "d2", false); - - // Persist. - // - { - transaction t (db->begin ()); - db->persist (b); - db->persist (static_cast (d1)); - db->persist (static_cast (d2)); - - try - { - db->persist (i); - assert (false); - } - catch (const odb::abstract_class&) {} - - try - { - db->persist (static_cast (i)); - assert (false); - } - catch (const odb::no_type_info&) {} - - t.commit (); - } - - // Load. - // - { - base vb; - interm vi; - derived1 vd1; - derived2 vd2; - - transaction t (db->begin ()); - - // load (id) - // - auto_ptr pb (db->load (b.id)); - auto_ptr pd1 (db->load (d1.id)); - auto_ptr pd2 (db->load (d2.id)); - - assert (*pb == b); - assert (*pd1 == d1); - assert (*pd2 == d2); - - // load (id, obj) - // - db->load (b.id, static_cast (vb)); - db->load (d1.id, static_cast (vd1)); - db->load (d2.id, static_cast (vd2)); - - assert (vb == b); - assert (vd1 == d1); - assert (vd2 == d2); - - try - { - db->load (i.id, static_cast (vi)); - assert (false); - } - catch (const odb::no_type_info&) {} - - // reload (obj) - // - vb.num = 0; - vd1.num = 0; - vd2.num = 0; - - db->reload (static_cast (vb)); - db->reload (static_cast (vd1)); - db->reload (static_cast (vd2)); - - assert (vb == b); - assert (vd1 == d1); - assert (vd2 == d2); - - try - { - db->reload (static_cast (vi)); - assert (false); - } - catch (const odb::no_type_info&) {} - - t.commit (); - } - - // Update. - // - { - b.num++; - b.str += 'b'; - d1.num++; - d1.str += "d1"; - d2.num++; - d2.str += "d1"; - - { - transaction t (db->begin ()); - db->update (static_cast (b)); - db->update (d1); - db->update (static_cast (d2)); - - try - { - db->update (i); - assert (false); - } - catch (const odb::abstract_class&) {} - - try - { - db->update (static_cast (i)); - assert (false); - } - catch (const odb::no_type_info&) {} - - t.commit (); - } - - { - transaction t (db->begin ()); - auto_ptr pb (db->load (b.id)); - auto_ptr pd1 (db->load (d1.id)); - auto_ptr pd2 (db->load (d2.id)); - t.commit (); - - assert (*pb == b); - assert (*pd1 == d1); - assert (*pd2 == d2); - } - } - - // Erase. - // - { - transaction t (db->begin ()); - db->erase (b); - db->erase (d1.id); - db->erase (static_cast (d2)); - - try - { - db->erase (i); - assert (false); - } - catch (const odb::abstract_class&) {} - - try - { - db->erase (static_cast (i)); - assert (false); - } - catch (const odb::no_type_info&) {} - - t.commit (); - } - } - - // Test 9: polymorphism and readonly classes. - // - { - using namespace test9; - - ro_root ro_r (1, 1); - rw_base rw_b (2, 2, "b"); - ro_derived ro_d (3, 3, "d"); - - rw_root rw_r (1, 1); - ro_base ro_b (2, 2, "b"); - rw_derived rw_d (3, 3, "d"); - - // Persist. - // - { - transaction t (db->begin ()); - db->persist (ro_r); - db->persist (rw_b); - db->persist (ro_d); - - db->persist (rw_r); - db->persist (ro_b); - db->persist (rw_d); - t.commit (); - } - - // Update. - // - { - ro_root ro_r1 (ro_r); - rw_base rw_b1 (rw_b); - ro_derived ro_d1 (ro_d); - - ro_base ro_b1 (ro_b); - rw_derived rw_d1 (rw_d); - - ro_r1.num++; - ro_r1.strs.push_back ("b"); - - rw_b1.num++; - rw_b1.strs.push_back ("b"); - rw_b1.str += "b"; - rw_b1.nums.push_back (2); - rw_b.str += "b"; - rw_b.nums.push_back (2); - - ro_d1.num++; - ro_d1.strs.push_back ("d"); - ro_d1.str += "d"; - ro_d1.nums.push_back (3); - ro_d1.dnum++; - ro_d1.dstr += "d"; - - rw_r.num++; - rw_r.strs.push_back ("b"); - - ro_b1.num++; - ro_b1.strs.push_back ("b"); - ro_b1.str += "b"; - ro_b1.nums.push_back (2); - - rw_d1.num++; - rw_d1.strs.push_back ("d"); - rw_d1.str += "d"; - rw_d1.nums.push_back (3); - rw_d1.dnum++; - rw_d1.dstr += "d"; - rw_d.dnum++; - rw_d.dstr += "d"; - - { - // These should be no-ops. - // - db->update (ro_r1); - db->update (static_cast (ro_d1)); - db->update (ro_b1); - - transaction t (db->begin ()); - db->update (static_cast (rw_b1)); - db->update (rw_r); - db->update (static_cast (rw_d1)); - t.commit (); - } - } - - // Load. - // - { - transaction t (db->begin ()); - auto_ptr p_ro_r (db->load (ro_r.id)); - auto_ptr p_rw_b (db->load (rw_b.id)); - auto_ptr p_ro_d (db->load (ro_d.id)); - - auto_ptr p_rw_r (db->load (rw_r.id)); - auto_ptr p_ro_b (db->load (ro_b.id)); - auto_ptr p_rw_d (db->load (rw_d.id)); - t.commit (); - - assert (*p_ro_r == ro_r); - assert (*p_rw_b == rw_b); - assert (*p_ro_d == ro_d); - - assert (*p_rw_r == rw_r); - assert (*p_ro_b == ro_b); - assert (*p_rw_d == rw_d); - } - } - - // Test 10: empty polymorphic classes. - // - { - using namespace test10; - - base b (1, 1); - derived d (2, 2); - - // Persist. - // - { - transaction t (db->begin ()); - db->persist (b); - db->persist (static_cast (d)); - t.commit (); - } - - // Load. - // - { - transaction t (db->begin ()); - auto_ptr pb (db->load (b.id)); - auto_ptr pd (db->load (d.id)); - t.commit (); - - assert (*pb == b); - assert (*pd == d); - } - - // Update. - // - { - b.num++; - d.num++; - - transaction t (db->begin ()); - db->update (static_cast (b)); - db->update (d); - t.commit (); - } - - // Load. - // - { - transaction t (db->begin ()); - auto_ptr pb (db->load (b.id)); - auto_ptr pd (db->load (d.id)); - t.commit (); - - assert (*pb == b); - assert (*pd == d); - } - } - - // Test 11: reuse and polymorphic inheritance. - // - { - using namespace test11; - - base b (1, 1, "b"); - derived d (2, 2, "d"); - - b.strs.push_back ("b"); - b.nums.push_back (1); - - d.strs.push_back ("d"); - d.nums.push_back (1); - - // Persist. - // - { - transaction t (db->begin ()); - db->persist (b); - db->persist (static_cast (d)); - t.commit (); - } - - // Load. - // - { - transaction t (db->begin ()); - auto_ptr pb (db->load (b.id)); - auto_ptr pd (db->load (d.id)); - t.commit (); - - assert (*pb == b); - assert (*pd == d); - } - - // Update. - // - { - b.num++; - b.str += "b"; - b.strs.push_back ("bb"); - b.nums.push_back (2); - - d.num++; - d.str += "d"; - d.strs.push_back ("dd"); - d.nums.push_back (2); - d.dnum++; - d.dstr += "d"; - - transaction t (db->begin ()); - db->update (b); - db->update (d); - t.commit (); - } - - // Load. - // - { - transaction t (db->begin ()); - auto_ptr pb (db->load (b.id)); - auto_ptr pd (db->load (d.id)); - t.commit (); - - assert (*pb == b); - assert (*pd == d); - } - - // Query. - // - { - typedef odb::query base_query; - typedef odb::result base_result; - - typedef odb::query derived_query; - typedef odb::result derived_result; - - transaction t (db->begin ()); - - { - base_result qr (db->query (base_query::num == 2)); - base_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && *i == b); - assert (++i == e); - } - - { - derived_result qr (db->query (derived_query::num == 3)); - derived_result::iterator i (qr.begin ()), e (qr.end ()); - - assert (i != e && *i == d); - assert (++i == e); - } - - t.commit (); - } - } - - // Test 12: polymorphic objects with auto id. - // - { - using namespace test12; - - base b (1); - derived d (2); - - unsigned long id1, id2; - - // Persist. - // - { - transaction t (db->begin ()); - id1 = db->persist (b); - id2 = db->persist (static_cast (d)); - t.commit (); - } - - // Load. - // - { - transaction t (db->begin ()); - auto_ptr pb (db->load (id1)); - auto_ptr pd (db->load (id2)); - t.commit (); - - assert (*pb == b); - assert (*pd == d); - } - } - } - catch (const odb::exception& e) - { - cerr << e.what () << endl; - return 1; - } -} -- cgit v1.1