summaryrefslogtreecommitdiff
path: root/odb-tests/common/section/polymorphism/test.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb-tests/common/section/polymorphism/test.hxx')
-rw-r--r--odb-tests/common/section/polymorphism/test.hxx542
1 files changed, 542 insertions, 0 deletions
diff --git a/odb-tests/common/section/polymorphism/test.hxx b/odb-tests/common/section/polymorphism/test.hxx
new file mode 100644
index 0000000..6d524bd
--- /dev/null
+++ b/odb-tests/common/section/polymorphism/test.hxx
@@ -0,0 +1,542 @@
+// file : common/section/polymorphism/test.hxx
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef TEST_HXX
+#define TEST_HXX
+
+#include <string>
+#include <vector>
+#include <memory>
+
+#include <odb/core.hxx>
+#include <odb/section.hxx>
+
+// Test basic polymorphic section functionality.
+//
+#pragma db namespace table("t1_")
+namespace test1
+{
+ #pragma db object polymorphic abstract
+ struct root
+ {
+ root (int n): rs1n (n), rs2n (n), rs4n (n) {rs2v.push_back (n);}
+ virtual ~root () {}
+
+ #pragma db id auto
+ unsigned long id;
+
+ // rs1: override in base and derived
+ //
+ #pragma db load(lazy) update(change)
+ odb::section rs1;
+
+ #pragma db section(rs1)
+ int rs1n;
+
+ // rs2: no override
+ //
+ #pragma db load(lazy)
+ odb::section rs2;
+
+ #pragma db section(rs2)
+ int rs2n;
+
+ #pragma db section(rs2)
+ std::vector<int> rs2v;
+
+ // rs3: empty
+ //
+ #pragma db load(lazy)
+ odb::section rs3;
+
+ // rs4: override "gap"
+ //
+ #pragma db load(lazy)
+ odb::section rs4;
+
+ #pragma db section(rs4)
+ int rs4n;
+ };
+
+ #pragma db object
+ struct base: root
+ {
+ base (int n = 999, const std::string& s = "xxx")
+ : root (n), rs1s (s), bs1n (n) {rs3v.push_back (n);}
+
+ // rs1
+ //
+ #pragma db section(rs1)
+ std::string rs1s;
+
+ // rs3
+ //
+ #pragma db section(rs3)
+ std::vector<int> rs3v;
+
+ // bs1: override in derived
+ //
+ #pragma db load(lazy)
+ odb::section bs1;
+
+ #pragma db section(bs1)
+ int bs1n;
+ };
+
+ #pragma db object
+ struct derived: base
+ {
+ derived (int n = 999, const std::string& s = "xxx", bool b = false)
+ : base (n, s), rs1b (b), rs3n (n), rs4s (s), bs1s (s), ds1n (n)
+ {rs1v.push_back (n);}
+
+ // rs1
+ //
+ #pragma db section(rs1)
+ bool rs1b;
+
+ #pragma db section(rs1)
+ std::vector<int> rs1v;
+
+ // rs3
+ //
+ #pragma db section(rs3)
+ int rs3n;
+
+ // rs4
+ //
+ #pragma db section(rs4)
+ std::string rs4s;
+
+ // bs1
+ //
+ #pragma db section(bs1)
+ std::string bs1s;
+
+ // ds1: no override
+ //
+ #pragma db load(lazy)
+ odb::section ds1;
+
+ #pragma db section(ds1)
+ int ds1n;
+ };
+}
+
+// Test empty section and override "gap".
+//
+#pragma db namespace table("t2_")
+namespace test2
+{
+ #pragma db object polymorphic abstract
+ struct root
+ {
+ virtual ~root () {}
+
+ #pragma db id auto
+ unsigned long id;
+
+ #pragma db load(lazy)
+ odb::section s;
+ };
+
+ #pragma db object abstract
+ struct base: root
+ {
+ // The "gap".
+ };
+
+ #pragma db object
+ struct derived: base
+ {
+ derived (int n = 999): sn (n) {sv.push_back (n);}
+
+ #pragma db section(s)
+ int sn;
+
+ #pragma db section(s)
+ std::vector<int> sv;
+ };
+}
+
+// Test value-only/container-only base/override combinations.
+//
+#pragma db namespace table("t3_")
+namespace test3
+{
+ #pragma db object polymorphic
+ struct root
+ {
+ root (int n = 999)
+ : s1n (n), s2n (n) {s3v.push_back (n); s4nv.push_back (n);}
+ virtual ~root () {}
+
+ #pragma db id auto
+ unsigned long id;
+
+ // value/value
+ //
+ #pragma db load(lazy)
+ odb::section s1;
+
+ #pragma db section(s1)
+ int s1n;
+
+ // value/container
+ //
+ #pragma db load(lazy)
+ odb::section s2;
+
+ #pragma db section(s2)
+ int s2n;
+
+ // container/value
+ //
+ #pragma db load(lazy)
+ odb::section s3;
+
+ #pragma db section(s3)
+ std::vector<int> s3v;
+
+ // container/container
+ //
+ #pragma db load(lazy)
+ odb::section s4;
+
+ #pragma db section(s4)
+ std::vector<int> s4nv;
+ };
+
+ #pragma db object
+ struct base: root
+ {
+ base (int n = 999): root (n) {}
+
+ // The "gap".
+ };
+
+ #pragma db object
+ struct derived: base
+ {
+ derived (int n = 999, const std::string& s = "xxx")
+ : base (n), s1s (s), s3n (n) {s2v.push_back (n); s4sv.push_back (s);}
+
+ #pragma db section(s1)
+ std::string s1s;
+
+ #pragma db section(s2)
+ std::vector<int> s2v;
+
+ #pragma db section(s3)
+ int s3n;
+
+ #pragma db section(s4)
+ std::vector<std::string> s4sv;
+ };
+}
+
+// Test basic polymorphic optimistic section functionality.
+//
+#pragma db namespace table("t4_")
+namespace test4
+{
+ #pragma db object polymorphic optimistic abstract sectionable
+ struct root
+ {
+ root (int n): rs1n (n), rs2n (n), rs3n (n), rs4n (n) {}
+ virtual ~root () {}
+
+ #pragma db id auto
+ unsigned long id;
+
+ #pragma db version
+ unsigned long long v;
+
+ // rs1: readwrite, override
+ //
+ #pragma db load(lazy) update(change)
+ odb::section rs1;
+
+ #pragma db section(rs1)
+ int rs1n;
+
+ // rs2: readonly, no override
+ //
+ #pragma db load(lazy)
+ odb::section rs2;
+
+ #pragma db section(rs2)
+ const int rs2n;
+
+ // rs3: readonly, readonly override
+ //
+ #pragma db load(lazy)
+ odb::section rs3;
+
+ #pragma db section(rs3)
+ const int rs3n;
+
+ // rs4: readonly, readwrite override
+ //
+ #pragma db load(lazy)
+ odb::section rs4;
+
+ #pragma db section(rs4)
+ const int rs4n;
+ };
+
+ #pragma db object
+ struct base: root
+ {
+ base (int n = 999, const std::string& s = "xxx")
+ : root (n), rs1s (s), rs4s (s) {}
+
+ // rs1
+ //
+ #pragma db section(rs1)
+ std::string rs1s;
+
+ // rs4
+ //
+ #pragma db section(rs4)
+ std::string rs4s;
+
+ // bs2: empty, readwrite override
+ //
+ #pragma db load(lazy)
+ odb::section bs1;
+ };
+
+ #pragma db object
+ struct derived: base
+ {
+ derived (int n = 999, const std::string& s = "xxx", bool b = false)
+ : base (n, s), rs1b (b), rs3s (s), bs1n (n)
+ {
+ rs1v.push_back (n);
+ rs4v.push_back (n);
+ ds1v.push_back (n);
+ }
+
+ // rs1
+ //
+ #pragma db section(rs1)
+ bool rs1b;
+
+ #pragma db section(rs1)
+ std::vector<int> rs1v;
+
+ // rs3
+ //
+ #pragma db section(rs3)
+ const std::string rs3s;
+
+ // rs4
+ //
+ #pragma db section(rs4)
+ std::vector<int> rs4v;
+
+ // bs1
+ //
+ #pragma db section(bs1)
+ int bs1n;
+
+ // ds1: readwrite
+ //
+ #pragma db load(lazy)
+ odb::section ds1;
+
+ #pragma db section(ds1)
+ std::vector<int> ds1v;
+ };
+}
+
+// Test polymorphic optimistic readonly/empty to readwrite section override.
+//
+#pragma db namespace table("t5_")
+namespace test5
+{
+ #pragma db object polymorphic optimistic abstract
+ struct root
+ {
+ virtual ~root () {}
+
+ #pragma db id auto
+ unsigned long id;
+
+ #pragma db version
+ unsigned long long v;
+
+ #pragma db load(lazy) update(change)
+ odb::section s;
+ };
+
+ #pragma db object
+ struct base: root
+ {
+ // The "gap".
+ };
+
+ #pragma db object
+ struct derived: base
+ {
+ derived (int n = 999): sn (n) {}
+
+ #pragma db section(s)
+ int sn;
+ };
+}
+
+// Test polymorphic optimistic readonly/empty to readwrite section override,
+// eager-loaded case.
+//
+#pragma db namespace table("t6_")
+namespace test6
+{
+ #pragma db object polymorphic optimistic abstract
+ struct root
+ {
+ virtual ~root () {}
+
+ #pragma db id auto
+ unsigned long id;
+
+ #pragma db version
+ unsigned long long v;
+
+ #pragma db update(change)
+ odb::section s;
+ };
+
+ #pragma db object abstract
+ struct base: root
+ {
+ // The "gap".
+ };
+
+ #pragma db object
+ struct derived: base
+ {
+ derived (int n = 999): sn (n) {}
+
+ #pragma db section(s)
+ int sn;
+ };
+}
+
+// Test polymorphic optimistic section added in derived.
+//
+#pragma db namespace table("t7_")
+namespace test7
+{
+ #pragma db object polymorphic optimistic sectionable
+ struct root
+ {
+ virtual ~root () {}
+
+ #pragma db id auto
+ unsigned long id;
+
+ #pragma db version
+ unsigned long long v;
+ };
+
+ #pragma db object
+ struct base: root
+ {
+ #pragma db load(lazy) update(change)
+ odb::section s;
+ };
+
+ #pragma db object
+ struct derived: base
+ {
+ derived (int n = 999): sn (n) {}
+
+ #pragma db section(s)
+ int sn;
+ };
+}
+
+// Test reuse/polymorphic inheritance and optimistic mix.
+//
+#pragma db namespace table("t8_")
+namespace test8
+{
+ #pragma db object optimistic sectionable abstract
+ struct root
+ {
+ #pragma db id auto
+ unsigned long id;
+
+ #pragma db version
+ unsigned long long v;
+ };
+
+ #pragma db object polymorphic sectionable
+ struct base: root
+ {
+ virtual ~base () {}
+ };
+
+ #pragma db object
+ struct derived: base
+ {
+ derived (int n = 999): sn (n) {}
+
+ #pragma db load(lazy) update(change)
+ odb::section s;
+
+ #pragma db section(s)
+ int sn;
+ };
+}
+
+// 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).
+//
+#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<std::shared_ptr<element>> 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 // TEST_HXX