aboutsummaryrefslogtreecommitdiff
path: root/common/polymorphism/driver.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-10-08 14:47:57 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-10-08 14:47:57 +0200
commit6b76715e63d2c265a4c51c73f9019bc578f874cb (patch)
treec0b5f6a944abf6fe015742bbc08e5a393249cf6d /common/polymorphism/driver.cxx
parentdcee8530bb5c58710a22f50bb92ac7c3b19ddf84 (diff)
Fix bug in transient inheritance handling
Also test that we can handle it for objects, composite values, and views.
Diffstat (limited to 'common/polymorphism/driver.cxx')
-rw-r--r--common/polymorphism/driver.cxx1880
1 files changed, 0 insertions, 1880 deletions
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 <memory> // std::auto_ptr
-#include <cassert>
-#include <iostream>
-
-#include <odb/database.hxx>
-#include <odb/session.hxx>
-#include <odb/transaction.hxx>
-
-#include <common/common.hxx>
-
-#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<database> 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<root> pr (db->load<root> (r.id));
- auto_ptr<base> pb (db->load<base> (b.id));
- auto_ptr<derived> pd (db->load<derived> (d.id));
- t.commit ();
-
- assert (*pr == r);
- assert (*pb == b);
- assert (*pd == d);
- }
-
- // Dynamic load.
- //
- {
- transaction t (db->begin ());
- auto_ptr<root> pb (db->load<root> (b.id));
- auto_ptr<root> pd1 (db->load<root> (d.id));
- auto_ptr<base> pd2 (db->load<base> (d.id));
- t.commit ();
-
- assert (*pb == b);
- assert (*pd1 == d);
- assert (*pd2 == d);
- }
-
- // Invalid load.
- //
- {
- transaction t (db->begin ());
-
- try
- {
- auto_ptr<base> p (db->load<base> (r.id));
- assert (false);
- }
- catch (const object_not_persistent&) {}
-
- try
- {
- auto_ptr<derived> p (db->load<derived> (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<root&> (b1));
- derived d1;
- db->load (d.id, static_cast<base&> (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<root&> (b));
- assert (false);
- }
- catch (const object_not_persistent&) {}
-
- try
- {
- derived d;
- db->load (b.id, static_cast<base&> (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<root> (b));
- assert (d1 == static_cast<base> (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<root&> (b1));
- derived d1;
- d1.id = d.id;
- db->reload (static_cast<base&> (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<root&> (b));
- assert (false);
- }
- catch (const object_not_persistent&) {}
-
- try
- {
- derived d;
- d.id = b.id;
- db->reload (static_cast<base&> (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<root> (b));
- assert (d1 == static_cast<base> (d));
- }
-
- // Query.
- //
- {
- typedef odb::query<root> root_query;
- typedef odb::result<root> root_result;
-
- typedef odb::query<base> base_query;
- typedef odb::result<base> base_result;
-
- typedef odb::result<derived> derived_result;
-
- transaction t (db->begin ());
-
- // Test loading via root.
- //
- {
- root_result qr (db->query<root> ("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<base> ("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> ());
- 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<root> ());
-
- 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> (
- 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> (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<base> ());
-
- 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<derived> d1 (db->load<derived> (d.id));
- assert (*d1 == d);
- assert (*i == b);
- mask |= 1;
- }
- else if (ds == "test1::derived")
- {
- auto_ptr<base> b1 (db->load<base> (b.id));
- assert (*b1 == b);
- assert (*i == d);
- mask |= 2;
- }
- }
-
- assert (mask == 3);
- }
-
- t.commit ();
- }
-
- // Views.
- //
- {
- typedef odb::query<root_view> root_query;
- typedef odb::result<root_view> root_result;
-
- typedef odb::query<base_view> base_query;
- typedef odb::result<base_view> base_result;
-
- typedef odb::result<derived_view> derived_result;
-
- transaction t (db->begin ());
-
- // root
- //
- {
- root_result qr (db->query<root_view> ("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<base_view> ("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_view> ());
- 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<root> pr (db->load<root> (r.id));
- auto_ptr<base> pb (db->load<base> (b.id));
- auto_ptr<derived> pd (db->load<derived> (d.id));
- t.commit ();
-
- assert (*pr == r);
- assert (*pb == b);
- assert (*pd == d);
- }
-
- // Invalid erase via id.
- //
- {
- transaction t (db->begin ());
-
- try
- {
- db->erase<base> (r.id);
- assert (false);
- }
- catch (const object_not_persistent&) {}
-
- try
- {
- db->erase<derived> (b.id);
- assert (false);
- }
- catch (const object_not_persistent&) {}
-
- t.commit ();
- }
-
- // Static erase via id.
- //
- {
- transaction t (db->begin ());
- db->erase<root> (r.id);
- db->erase<base> (b.id);
- t.commit ();
- }
-
- // Dynamic erase via id.
- //
- {
- transaction t (db->begin ());
- db->erase<root> (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<derived> pd (db->load<derived> (d.id));
- auto_ptr<base> pb (db->load<base> (d.id));
- auto_ptr<root> pr (db->load<root> (d.id));
- t.commit ();
-
- assert (pd->rp.object_id<root_pointer> () == rp.id &&
- pd->bp.object_id<base_pointer> () == bp.id);
-
- derived* p (dynamic_cast<derived*> (pb.get ()));
- assert (p != 0 &&
- p->rp.object_id<root_pointer> () == rp.id &&
- p->bp.object_id<base_pointer> () == bp.id);
-
- p = dynamic_cast<derived*> (pr.get ());
- assert (p != 0 &&
- p->rp.object_id<root_pointer> () == rp.id &&
- p->bp.object_id<base_pointer> () == bp.id);
- }
-
- // Query.
- //
- {
- typedef odb::query<base> base_query;
- typedef odb::result<base> base_result;
-
- transaction t (db->begin ());
-
- // Test query conditions with columns in pointed-to objects from
- // multiple tables.
- //
- {
- base_result qr (
- db->query<base> (
- 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_view> root_result;
- typedef odb::result<base_view> base_result;
-
- transaction t (db->begin ());
-
- // root
- //
- {
- root_result qr (db->query<root_view> ());
- 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_view> ());
- 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<base> p1 (db->load<base> (b1.id));
- auto_ptr<base> p2 (db->load<base> (b2.id));
- auto_ptr<root> p3 (db->load<root> (b3.id));
- assert (*p1 == b1);
- assert (*p2 == b2);
- assert (*p3 == b3);
- }
-
- {
- auto_ptr<derived> p1 (db->load<derived> (d1.id));
- auto_ptr<base> p2 (db->load<base> (d2.id));
- auto_ptr<root> p3 (db->load<root> (d3.id));
- assert (*p1 == d1);
- assert (*p2 == d2);
- assert (*p3 == d3);
- }
-
- t.commit ();
- }
-
- // Query.
- //
- {
- typedef odb::query<derived> derived_query;
- typedef odb::result<derived> derived_result;
-
- transaction t (db->begin ());
-
- // Test query conditions with columns in pointed-to objects from
- // multiple tables.
- //
- {
- derived_result qr (
- db->query<derived> (
- 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_view> base_query;
- typedef odb::result<base_view> base_result;
-
- typedef odb::query<derived_view> derived_query;
- typedef odb::result<derived_view> derived_result;
-
- typedef odb::query<root_view> root_query;
- typedef odb::result<root_view> root_result;
-
- transaction t (db->begin ());
-
- // base
- //
- {
- base_result qr (
- db->query<base_view> (
- 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_view> (
- 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_view> (
- 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<view1> query;
- typedef odb::result<view1> result;
-
- transaction t (db->begin ());
-
- {
- result qr (
- db->query<view1> (
- 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<view2> result;
-
- transaction t (db->begin ());
-
- {
- result qr (db->query<view2> ());
- 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<root> p (db->load<root> (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<base> p (db->load<base> (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<root> p (db->load<root> (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<derived&> (*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<root> p (db->load<root> (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<base> p (db->load<base> (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<root> p (db->load<root> (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<base> 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<base> pb (db->load<base> (b.id));
- auto_ptr<root> pd (db->load<root> (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<base> query;
- typedef odb::result<base> result;
-
- transaction t (db->begin ());
-
- result r (db->query<base> ("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<root> p (db->load<root> (d.id));
- t.commit ();
- }
- }
- }
-
- // Test 7: polymorphism and object cache (session).
- //
-#if defined(HAVE_CXX11) || defined(HAVE_TR1_MEMORY)
- {
- using namespace test7;
-
- shared_ptr<root> r (new root (1, 1));
- shared_ptr<base> b (new base (2, 2, "b"));
- shared_ptr<root> 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<root> (r->id) == r);
- assert (db->load<base> (b->id) == b);
- assert (db->load<root> (d->id) == d);
- }
-
- // Load.
- //
- {
- session s;
-
- transaction t (db->begin ());
- shared_ptr<root> r1 (db->load<root> (r->id));
- shared_ptr<base> b1 (db->load<base> (b->id));
- shared_ptr<derived> d1 (db->load<derived> (d->id));
- t.commit ();
-
- assert (db->load<root> (r->id) == r1);
- assert (db->load<base> (b->id) == b1);
- assert (db->load<root> (d->id) == d1);
-
- assert (!db->find<derived> (b->id));
- }
-
- // Query.
- //
- {
- typedef odb::query<root> query;
- typedef odb::result<root> result;
-
- session s;
-
- transaction t (db->begin ());
- shared_ptr<root> r1 (db->load<root> (r->id));
- shared_ptr<base> b1 (db->load<base> (b->id));
- shared_ptr<derived> d1 (db->load<derived> (d->id));
- t.commit ();
-
- {
- transaction t (db->begin ());
-
- result r (db->query<root> ("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<root> (r->id);
- db->load<root> (b->id);
- db->load<root> (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<root> (r->id));
- assert (!db->find<base> (b->id));
- assert (!db->find<root> (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<root&> (d1));
- db->persist (static_cast<interm&> (d2));
-
- try
- {
- db->persist (i);
- assert (false);
- }
- catch (const odb::abstract_class&) {}
-
- try
- {
- db->persist (static_cast<base&> (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<root> pb (db->load<root> (b.id));
- auto_ptr<interm> pd1 (db->load<interm> (d1.id));
- auto_ptr<derived2> pd2 (db->load<derived2> (d2.id));
-
- assert (*pb == b);
- assert (*pd1 == d1);
- assert (*pd2 == d2);
-
- // load (id, obj)
- //
- db->load (b.id, static_cast<root&> (vb));
- db->load (d1.id, static_cast<base&> (vd1));
- db->load (d2.id, static_cast<interm&> (vd2));
-
- assert (vb == b);
- assert (vd1 == d1);
- assert (vd2 == d2);
-
- try
- {
- db->load (i.id, static_cast<root&> (vi));
- assert (false);
- }
- catch (const odb::no_type_info&) {}
-
- // reload (obj)
- //
- vb.num = 0;
- vd1.num = 0;
- vd2.num = 0;
-
- db->reload (static_cast<root&> (vb));
- db->reload (static_cast<base&> (vd1));
- db->reload (static_cast<interm&> (vd2));
-
- assert (vb == b);
- assert (vd1 == d1);
- assert (vd2 == d2);
-
- try
- {
- db->reload (static_cast<root&> (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<root&> (b));
- db->update (d1);
- db->update (static_cast<interm&> (d2));
-
- try
- {
- db->update (i);
- assert (false);
- }
- catch (const odb::abstract_class&) {}
-
- try
- {
- db->update (static_cast<base&> (i));
- assert (false);
- }
- catch (const odb::no_type_info&) {}
-
- t.commit ();
- }
-
- {
- transaction t (db->begin ());
- auto_ptr<base> pb (db->load<base> (b.id));
- auto_ptr<root> pd1 (db->load<root> (d1.id));
- auto_ptr<base> pd2 (db->load<base> (d2.id));
- t.commit ();
-
- assert (*pb == b);
- assert (*pd1 == d1);
- assert (*pd2 == d2);
- }
- }
-
- // Erase.
- //
- {
- transaction t (db->begin ());
- db->erase (b);
- db->erase<interm> (d1.id);
- db->erase (static_cast<root&> (d2));
-
- try
- {
- db->erase (i);
- assert (false);
- }
- catch (const odb::abstract_class&) {}
-
- try
- {
- db->erase (static_cast<base&> (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_root&> (ro_d1));
- db->update (ro_b1);
-
- transaction t (db->begin ());
- db->update (static_cast<ro_root&> (rw_b1));
- db->update (rw_r);
- db->update (static_cast<ro_base&> (rw_d1));
- t.commit ();
- }
- }
-
- // Load.
- //
- {
- transaction t (db->begin ());
- auto_ptr<ro_root> p_ro_r (db->load<ro_root> (ro_r.id));
- auto_ptr<ro_root> p_rw_b (db->load<ro_root> (rw_b.id));
- auto_ptr<ro_root> p_ro_d (db->load<ro_root> (ro_d.id));
-
- auto_ptr<rw_root> p_rw_r (db->load<rw_root> (rw_r.id));
- auto_ptr<rw_root> p_ro_b (db->load<rw_root> (ro_b.id));
- auto_ptr<rw_root> p_rw_d (db->load<rw_root> (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<root&> (d));
- t.commit ();
- }
-
- // Load.
- //
- {
- transaction t (db->begin ());
- auto_ptr<root> pb (db->load<root> (b.id));
- auto_ptr<root> pd (db->load<root> (d.id));
- t.commit ();
-
- assert (*pb == b);
- assert (*pd == d);
- }
-
- // Update.
- //
- {
- b.num++;
- d.num++;
-
- transaction t (db->begin ());
- db->update (static_cast<root&> (b));
- db->update (d);
- t.commit ();
- }
-
- // Load.
- //
- {
- transaction t (db->begin ());
- auto_ptr<root> pb (db->load<root> (b.id));
- auto_ptr<root> pd (db->load<root> (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<base&> (d));
- t.commit ();
- }
-
- // Load.
- //
- {
- transaction t (db->begin ());
- auto_ptr<base> pb (db->load<base> (b.id));
- auto_ptr<base> pd (db->load<base> (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<base> pb (db->load<base> (b.id));
- auto_ptr<base> pd (db->load<base> (d.id));
- t.commit ();
-
- assert (*pb == b);
- assert (*pd == d);
- }
-
- // Query.
- //
- {
- typedef odb::query<base> base_query;
- typedef odb::result<base> base_result;
-
- typedef odb::query<derived> derived_query;
- typedef odb::result<derived> derived_result;
-
- transaction t (db->begin ());
-
- {
- base_result qr (db->query<base> (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> (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<root&> (d));
- t.commit ();
- }
-
- // Load.
- //
- {
- transaction t (db->begin ());
- auto_ptr<root> pb (db->load<root> (id1));
- auto_ptr<root> pd (db->load<root> (id2));
- t.commit ();
-
- assert (*pb == b);
- assert (*pd == d);
- }
- }
- }
- catch (const odb::exception& e)
- {
- cerr << e.what () << endl;
- return 1;
- }
-}