diff options
Diffstat (limited to 'common/polymorphism/test3.hxx')
-rw-r--r-- | common/polymorphism/test3.hxx | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/common/polymorphism/test3.hxx b/common/polymorphism/test3.hxx new file mode 100644 index 0000000..9a9a269 --- /dev/null +++ b/common/polymorphism/test3.hxx @@ -0,0 +1,147 @@ +// file : common/polymorphism/test3.hxx +// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef TEST3_HXX +#define TEST3_HXX + +#include <string> +#include <typeinfo> + +#include <odb/core.hxx> + +// Test delayed loading. +// +#pragma db namespace table("t3_") +namespace test3 +{ + #pragma db object polymorphic + struct root + { + virtual ~root () {} + root () {} + root (unsigned long i): id (i) {} + + #pragma db id + unsigned long id; + + virtual bool + compare (const root& r, bool tc = true) const + { + if (tc && typeid (r) != typeid (root)) + return false; + + return id == r.id; + } + }; + + inline bool + operator== (const root& x, const root& y) {return x.compare (y);} + + #pragma db object + struct base: root + { + virtual ~base () {delete rptr;} + base (): rptr (0) {} + base (unsigned long i, unsigned long n): root (i), num (n), rptr (0) {} + + unsigned long num; + root* rptr; + + virtual bool + compare (const root& r, bool tc = true) const + { + if (tc && typeid (r) != typeid (base)) + return false; + + const base& b (static_cast<const base&> (r)); + return + root::compare (r, false) && + num == b.num && + ((rptr == 0 && b.rptr == 0) || rptr->compare (*b.rptr)); + } + }; + + #pragma db object + struct derived: base + { + virtual ~derived () {delete bptr;} + derived (): bptr (0) {} + derived (unsigned long i, unsigned long n, const std::string& s) + : base (i, n), str (s), bptr (0) {} + + std::string str; + base* bptr; + + virtual bool + compare (const root& r, bool tc = true) const + { + if (tc && typeid (r) != typeid (derived)) + return false; + + const derived& d (static_cast<const derived&> (r)); + return + base::compare (r, false) && + str == d.str && + ((bptr == 0 && d.bptr == 0) || bptr->compare (*d.bptr)); + } + }; + + // Views. + // + #pragma db view object(base) object(root = r) + struct base_view + { + #pragma db column(base::id) + unsigned long b_id; + + #pragma db column(r::id) + unsigned long r_id; + + unsigned long num; + }; + + #pragma db view \ + object(derived = d) \ + object(base = b) \ + object(root = r: d::rptr) + struct derived_view + { + #pragma db column(d::id) + unsigned long d_id; + + #pragma db column(b::id) + unsigned long b_id; + + #pragma db column(r::id) + unsigned long r_id; + + #pragma db column(d::num) + unsigned long d_num; + + #pragma db column(b::num) + unsigned long b_num; + + std::string str; + }; + + // This is an example of a pathological case, where the right-hand-side + // of the join condition comes from one of the bases. As a result, we + // join the base table first, which means we will get both bases and + // derived objects instead of just derived. + // + //#pragma db view object(root = r) object(derived = d) + #pragma db view object(derived = d) object(root = r) + struct root_view + { + #pragma db column(r::id) + unsigned long r_id; + + #pragma db column(d::id) + unsigned long d_id; + + std::string str; + }; +} + +#endif // TEST3_HXX |