aboutsummaryrefslogtreecommitdiff
path: root/common/inheritance/polymorphism/test3.hxx
blob: a6c27fa30c7393602bb2199ba1afa6a24bd90e81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// file      : common/inheritance/polymorphism/test3.hxx
// copyright : Copyright (c) 2009-2015 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