From a44bbf24decdaee9bd8c716dc6843b4b4c6c7ec5 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 6 Feb 2015 08:57:30 +0200 Subject: Implement join types support in views --- common/view/basics/driver.cxx | 144 ++++++++++++++++++++++++++++++++++++++++++ common/view/basics/test.hxx | 104 ++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+) (limited to 'common/view/basics') diff --git a/common/view/basics/driver.cxx b/common/view/basics/driver.cxx index 01ae0ab..557efda 100644 --- a/common/view/basics/driver.cxx +++ b/common/view/basics/driver.cxx @@ -682,6 +682,150 @@ main (int argc, char* argv[]) assert (size (db->query ()) == 2); t.commit (); } + + // Test join types. + // + { + using namespace test2; + + { + obj1 o11 (1, 1); + obj1 o12 (2, 2); + + obj2 o21 (1, 1); + obj2 o22 (2, 1); + obj2 o23 (3, 3); + + transaction t (db->begin ()); + db->persist (o11); + db->persist (o12); + db->persist (o21); + db->persist (o22); + db->persist (o23); + t.commit (); + } + + { + typedef odb::query query; + typedef odb::result result; + + transaction t (db->begin ()); + result r (db->query ( + "ORDER BY" + query::o1::id1 + "," + query::o2::id2)); + result::iterator i (r.begin ()); + assert ( i != r.end () && i->id1 == 1 && *i->id2 == 1); + assert (++i != r.end () && i->id1 == 1 && *i->id2 == 2); + assert (++i != r.end () && i->id1 == 2 && i->id2.null ()); + assert (++i == r.end ()); + t.commit (); + } + +#if !defined(DATABASE_SQLITE) + { + typedef odb::query query; + typedef odb::result result; + + transaction t (db->begin ()); + result r (db->query ( + "ORDER BY" + query::o1::id1 + "," + query::o2::id2)); + result::iterator i (r.begin ()); + assert ( i != r.end () && i->id1 == 1 && *i->id2 == 1); + assert (++i != r.end () && i->id1 == 1 && *i->id2 == 2); + assert (++i != r.end () && i->id1 == 2 && i->id2.null ()); + assert (++i == r.end ()); + t.commit (); + } +#endif + +#if !defined(DATABASE_MYSQL) && !defined(DATABASE_SQLITE) + { + typedef odb::query query; + typedef odb::result result; + + transaction t (db->begin ()); + result r (db->query ( + "ORDER BY" + query::o1::id1 + "," + query::o2::id2)); + result::iterator i (r.begin ()); + + // SQL Server orders NULL values first. Got to be different. + // +#ifdef DATABASE_MSSQL + assert ( i != r.end () && i->id1.null () && *i->id2 == 3); + assert (++i != r.end () && *i->id1 == 1 && *i->id2 == 1); + assert (++i != r.end () && *i->id1 == 1 && *i->id2 == 2); + assert (++i != r.end () && *i->id1 == 2 && i->id2.null ()); +#else + assert ( i != r.end () && *i->id1 == 1 && *i->id2 == 1); + assert (++i != r.end () && *i->id1 == 1 && *i->id2 == 2); + assert (++i != r.end () && *i->id1 == 2 && i->id2.null ()); + assert (++i != r.end () && i->id1.null () && *i->id2 == 3); +#endif + assert (++i == r.end ()); + t.commit (); + } +#endif + + { + typedef odb::query query; + typedef odb::result result; + + transaction t (db->begin ()); + result r (db->query ( + "ORDER BY" + query::o1::id1 + "," + query::o2::id2)); + result::iterator i (r.begin ()); + assert ( i != r.end () && i->id1 == 1 && i->id2 == 1); + assert (++i != r.end () && i->id1 == 1 && i->id2 == 2); + assert (++i == r.end ()); + t.commit (); + } + + { + typedef odb::query query; + typedef odb::result result; + + transaction t (db->begin ()); + result r (db->query ( + "ORDER BY" + query::o1::id1 + "," + query::o2::id2)); + result::iterator i (r.begin ()); + assert ( i != r.end () && i->id1 == 1 && i->id2 == 1); + assert (++i != r.end () && i->id1 == 1 && i->id2 == 2); + assert (++i != r.end () && i->id1 == 1 && i->id2 == 3); + assert (++i != r.end () && i->id1 == 2 && i->id2 == 1); + assert (++i != r.end () && i->id1 == 2 && i->id2 == 2); + assert (++i != r.end () && i->id1 == 2 && i->id2 == 3); + assert (++i == r.end ()); + t.commit (); + } + + // Inner JOIN via relationship/container. + // + { + obj3 o31 (1, 1); + obj3 o32 (2, 2); + + obj4 o41 (1, 1); + obj4 o42 (2, 2); + o42.o3.push_back (&o32); + + transaction t (db->begin ()); + db->persist (o31); + db->persist (o32); + db->persist (o41); + db->persist (o42); + t.commit (); + } + + { + typedef odb::result result; + + transaction t (db->begin ()); + result r (db->query ()); + result::iterator i (r.begin ()); + assert ( i != r.end () && i->id4 == 2); + assert (++i == r.end ()); + t.commit (); + } + } } catch (const odb::exception& e) { diff --git a/common/view/basics/test.hxx b/common/view/basics/test.hxx index e9d61a5..0a2243d 100644 --- a/common/view/basics/test.hxx +++ b/common/view/basics/test.hxx @@ -5,6 +5,8 @@ #ifndef TEST_HXX #define TEST_HXX +#include // DATABASE_* + #include #include #include // std::size_t @@ -510,4 +512,106 @@ struct view14 std::string name; }; +// Test join types. +// +#pragma db namespace table("t2_") +namespace test2 +{ + #pragma db object + struct obj1 + { + obj1 (int id = 0, int n_ = 0): id1 (id), n (n_) {} + + #pragma db id + int id1; + + int n; + }; + + #pragma db object no_id + struct obj2 + { + obj2 (int id = 0, int n_ = 0): id2 (id), n (n_) {} + + #pragma db id + int id2; + + int n; + }; + + #pragma db view object(obj1 = o1) object(obj2 = o2 left: o1::n == o2::n) + struct vleft + { + int id1; + odb::nullable id2; + }; + +#if !defined(DATABASE_SQLITE) + + #pragma db view object(obj2 = o2) object(obj1 = o1 right: o2::n == o1::n) + struct vright + { + int id1; + odb::nullable id2; + }; + +#endif + +#if !defined(DATABASE_MYSQL) && !defined(DATABASE_SQLITE) + + #pragma db view object(obj1 = o1) object(obj2 = o2 full: o1::n == o2::n) + struct vfull + { + odb::nullable id1; + odb::nullable id2; + }; + +#endif + + #pragma db view object(obj1 = o1) object(obj2 = o2 inner: o1::n == o2::n) + struct vinner + { + int id1; + int id2; + }; + + #pragma db view object(obj1 = o1) object(obj2 = o2 cross) + struct vcross + { + int id1; + int id2; + }; + + // Inner JOIN via relationship/container. + // + #pragma db object + struct obj3 + { + obj3 (int id = 0, int n_ = 0): id3 (id), n (n_) {} + + #pragma db id + int id3; + + int n; + }; + + #pragma db object no_id + struct obj4 + { + obj4 (int id = 0, int n_ = 0): id4 (id), n (n_) {} + + #pragma db id + int id4; + + int n; + std::vector o3; + }; + + #pragma db view object(obj4) object(obj3 inner) + struct vrel + { + int id4; + }; +} + #endif // TEST_HXX -- cgit v1.1