// file : common/section/basics/test.hxx // copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef TEST_HXX #define TEST_HXX #include #include #include #include #include #ifdef ODB_COMPILER # if defined(ODB_DATABASE_PGSQL) # define BLOB_TYPE "BYTEA" # elif defined(ODB_DATABASE_MSSQL) # define BLOB_TYPE "VARBINARY(max)" # else # define BLOB_TYPE "BLOB" # endif #endif // Test lazy-loaded, always-updated section. // #pragma db namespace table("t1_") namespace test1 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : sn (n_), n (n_), ss (s_) {sv.push_back (n_);} #pragma db id auto unsigned long id; #pragma db load(lazy) odb::section s; #pragma db section(s) int sn; int n; #pragma db section(s) std::string ss; #pragma db section(s) std::vector sv; }; } // Test lazy-loaded, change-updated section. // #pragma db namespace table("t2_") namespace test2 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : sn (n_), n (n_), ss (s_) {sv.push_back (n_);} #pragma db id auto unsigned long id; #pragma db load(lazy) update(change) odb::section s; #pragma db section(s) int sn; int n; #pragma db section(s) std::string ss; #pragma db section(s) std::vector sv; }; } // Test lazy-loaded, manually-updated section. // #pragma db namespace table("t3_") namespace test3 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : sn (n_), n (n_), ss (s_) {sv.push_back (n_);} #pragma db id auto unsigned long id; #pragma db load(lazy) update(manual) odb::section s; #pragma db section(s) int sn; int n; #pragma db section(s) std::string ss; #pragma db section(s) std::vector sv; }; } // Test eager-loaded, change-updated section. // #pragma db namespace table("t4_") namespace test4 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : sn (n_), n (n_), ss (s_) {sv.push_back (n_);} #pragma db id auto unsigned long id; #pragma db section(s) int sn; #pragma db update(change) odb::section s; int n; #pragma db section(s) std::string ss; #pragma db section(s) std::vector sv; }; } // Test eager-loaded, manually-updated section. // #pragma db namespace table("t5_") namespace test5 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : sn (n_), n (n_), ss (s_) {sv.push_back (n_);} #pragma db id auto unsigned long id; #pragma db section(s) int sn; #pragma db update(manual) odb::section s; int n; #pragma db section(s) std::string ss; #pragma db section(s) std::vector sv; }; } // Test value-only and container-only section. Also multiple sections // in an object. // #pragma db namespace table("t6_") namespace test6 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : n (n_), sn (n_), ss (s_) {sv.push_back (n_);} #pragma db id auto unsigned long id; int n; #pragma db load(lazy) odb::section s1; #pragma db load(lazy) odb::section s2; #pragma db section(s1) int sn; #pragma db section(s1) std::string ss; #pragma db section(s2) std::vector sv; }; } // Test sections and reuse inheritance. // #pragma db namespace table("t7_") namespace test7 { #pragma db object abstract struct base { #pragma db id auto unsigned long id; #pragma db load(lazy) odb::section s1; // Empty section. #pragma db load(lazy) odb::section s2; #pragma db section(s2) int sn2; }; #pragma db object abstract struct interm: base { // Section s1 is still empty. #pragma db section(s2) std::string ss2; }; #pragma db object struct derived: interm { #pragma db section(s1) int sn1; }; #pragma db object struct object: derived { object (int n = 999, const std::string& s = "xxx", bool b = false) { sn1 = sn2 = n; ss1 = ss2 = s; sb2 = b; } #pragma db section(s1) std::string ss1; #pragma db section(s2) bool sb2; }; } // Test readonly and inverse section members. // #pragma db namespace table("t8_") namespace test8 { struct object1; #pragma db object session struct object { object (int n_ = 999, const std::string& s_ = "xxx", object1* p_ = 0) : n (n_), sn (n_), ss (s_), sp (p_) {} #pragma db id auto unsigned long id; int n; #pragma db load(lazy) odb::section s; #pragma db section(s) readonly int sn; #pragma db section(s) std::string ss; #pragma db inverse(p) section(s) object1* sp; }; #pragma db object session struct object1 { object1 (object* p_ = 0): p (p_) {} ~object1 () {delete p;} #pragma db id auto unsigned long id; object* p; }; } // Test object without any columns to load or update. // #pragma db namespace table("t9_") namespace test9 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx"): sn (n_), ss (s_) {} #pragma db id auto unsigned long id; #pragma db load(lazy) update(manual) odb::section s; #pragma db section(s) int sn; #pragma db section(s) std::string ss; }; } // Test section without any columns or containers to update. // #pragma db namespace table("t10_") namespace test10 { #pragma db object struct object { object (int n_ = 999): n (n_), sn (n_) {} #pragma db id auto unsigned long id; int n; #pragma db load(lazy) odb::section s; #pragma db section(s) readonly int sn; }; } // Test section with composite member. // #pragma db namespace table("t11_") namespace test11 { #pragma db value struct comp { comp (int n_, const std::string& s_): s (s_) {v.push_back (n_);} std::string s; std::vector v; }; #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : n (n_), sn (n_), sc (n_, s_) {} #pragma db id auto unsigned long id; int n; #pragma db load(lazy) odb::section s; #pragma db section(s) int sn; #pragma db section(s) comp sc; }; } // Test change state restoration on transaction rollback. // #pragma db namespace table("t12_") namespace test12 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : sn (n_), n (n_), ss (s_) {} #pragma db id auto unsigned long id; #pragma db load(lazy) update(change) odb::section s; #pragma db section(s) int sn; int n; #pragma db section(s) std::string ss; }; } // Test section accessor/modifier. // #pragma db namespace table("t13_") namespace test13 { #pragma db object struct object { object (int n_ = 999, const std::string& s_ = "xxx") : n (n_), sn (n_), ss (s_) {} #pragma db id auto unsigned long id; int n; #pragma db section(s_) int sn; #pragma db section(s_) std::string ss; public: const odb::section& s () const {return s_;} odb::section& rw_s () {return s_;} private: #pragma db load(lazy) update(manual) odb::section s_; }; } // Test LOB in section streaming, column re-ordering. // #pragma db namespace table("t14_") namespace test14 { #pragma db object struct object { object (unsigned long id_ = 0, int n_ = 999, const std::string& s_ = "xxx") : id (id_), sb (s_.begin (), s_.end ()), sn (n_), n (n_) {} #pragma db id unsigned long id; #pragma db load(lazy) odb::section s; #pragma db section(s) type(BLOB_TYPE) std::vector sb; // Comes before sn. #pragma db section(s) int sn; int n; }; } // Test sections and optimistic concurrency. // #pragma db namespace table("t15_") namespace test15 { #pragma db object optimistic struct object { object (int n_ = 999, const std::string& s_ = "xxx") : sn (n_), n (n_), ss (s_) {sv.push_back (n_);} #pragma db id auto unsigned long id; #pragma db version mssql:type("ROWVERSION") unsigned long long v; #pragma db load(lazy) odb::section s; #pragma db section(s) int sn; int n; #pragma db section(s) std::string ss; #pragma db section(s) std::vector sv; }; } // Test container-only sections and optimistic concurrency. // #pragma db namespace table("t16_") namespace test16 { #pragma db object optimistic struct object { object (int n = 999) {sv.push_back (n);} #pragma db id auto unsigned long id; #pragma db version // mssql:type("ROWVERSION") unsigned long long v; #pragma db load(lazy) odb::section s; #pragma db section(s) std::vector sv; }; } // Test reuse-inheritance, sections, and optimistic concurrency. // #pragma db namespace table("t17_") namespace test17 { #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 struct base: root { }; #pragma db object struct object: base { object (int n = 999): s1n (n) {s2v.push_back (n);} #pragma db load(lazy) odb::section s1; #pragma db section(s1) int s1n; #pragma db load(lazy) odb::section s2; #pragma db section(s2) std::vector s2v; }; } // Test change-updated section and change-tracking container. // #pragma db namespace table("t18_") namespace test18 { #pragma db object struct object { object (int n = 999): sn (n) {sv.push_back (n);} #pragma db id auto unsigned long id; #pragma db load(lazy) update(change) odb::section s; #pragma db section(s) int sn; #pragma db section(s) odb::vector sv; }; } // Regression: BLOB in a value type used as a map value that is in a section. // #include #include #pragma db namespace table("t19_") namespace test19 { #pragma db value struct value { #pragma db type(BLOB_TYPE) std::vector b; }; #pragma db object struct object { #pragma db id auto unsigned long id; #pragma db load(lazy) update(always) odb::section s; #pragma db section(s) std::map m; }; } #endif // TEST_HXX