// file : common/session/custom/driver.cxx // copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file // Test custom session (C++11 only). // #include <memory> #include <cstddef> // std::size_t #include <cassert> #include <iostream> #include <odb/tracer.hxx> #include <odb/database.hxx> #include <odb/session.hxx> #include <odb/transaction.hxx> #include <odb/details/config.hxx> // ODB_CXX11_* #include <common/common.hxx> #include "session.hxx" #include "test.hxx" #include "test-odb.hxx" using namespace std; using odb::database; using odb::transaction; struct counting_tracer: odb::tracer { virtual void execute (odb::connection&, const char*) {count++;} size_t count; }; static counting_tracer tracer; struct failed {}; int main (int argc, char* argv[]) { try { auto_ptr<database> db (create_database (argc, argv)); // Simple Tech Ltd. // { shared_ptr<employer> er (new employer ("Simple Tech Ltd", "ST")); shared_ptr<employee> john (new employee ("John", "Doe", er)); shared_ptr<employee> jane (new employee ("Jane", "Doe", er)); transaction t (db->begin ()); db->persist (er); db->persist (john); db->persist (jane); t.commit (); } // Complex Systems Inc. // { shared_ptr<employer> er (new employer ("Complex Systems Inc", "CS")); shared_ptr<employee> john (new employee ("John", "Smith", er)); shared_ptr<employee> jane (new employee ("Jane", "Smith", er)); transaction t (db->begin ()); db->persist (er); db->persist (john); db->persist (jane); t.commit (); } { session s; shared_ptr<employer> st, cs; shared_ptr<employee> ste, cse; { transaction t (db->begin ()); st = db->load<employer> ("Simple Tech Ltd"); #ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT ste = db->load<employee> (st->employees ()[0].object_id ()); #else ste = db->load<employee> (st->employees ()[0].object_id<employee> ()); #endif // Test object cache. // shared_ptr<employee> e (st->employees ()[0].load ()); assert (ste->employer () == st); assert (ste == e); t.commit (); } { transaction t (db->begin ()); cs = db->load<employer> ("Complex Systems Inc"); #ifdef ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT cse = db->load<employee> (cs->employees ()[0].object_id ()); #else cse = db->load<employee> (cs->employees ()[0].object_id<employee> ()); #endif cs->employees ()[0].load (); t.commit (); } cs->symbol ("CSI"); // Swap employees. // ste->employer (cs); cse->employer (st); st->employees ()[0] = cse; cs->employees ()[0] = ste; { transaction t (db->begin ()); tracer.count = 0; t.tracer (tracer); s.flush (*db); assert (tracer.count == 3); t.commit (); } { transaction t (db->begin ()); tracer.count = 0; t.tracer (tracer); s.flush (*db); assert (tracer.count == 0); t.commit (); } cs->symbol ("COMP"); st->symbol ("SMPL"); { transaction t (db->begin ()); tracer.count = 0; t.tracer (tracer); s.flush (*db); assert (tracer.count == 2); t.commit (); } { transaction t (db->begin ()); tracer.count = 0; t.tracer (tracer); s.flush (*db); assert (tracer.count == 0); t.commit (); } // Explicit update. // cs->symbol ("CS"); st->symbol ("ST"); { transaction t (db->begin ()); db->update (cs); tracer.count = 0; t.tracer (tracer); s.flush (*db); assert (tracer.count == 1); t.commit (); } // Rollback after update. // cs->symbol ("CSI"); try { transaction t (db->begin ()); tracer.count = 0; t.tracer (tracer); s.flush (*db); assert (tracer.count == 1); throw failed (); t.commit (); } catch (const failed&) { transaction t (db->begin ()); tracer.count = 0; t.tracer (tracer); s.flush (*db); assert (tracer.count == 1); t.commit (); } } // Test session destruction before transaction is commited. // { transaction t (db->begin ()); { session s; shared_ptr<employer> st (db->load<employer> ("Simple Tech Ltd")); st->symbol ("STL"); tracer.count = 0; t.tracer (tracer); s.flush (*db); assert (tracer.count == 1); } t.commit (); } } catch (const odb::exception& e) { cerr << e.what () << endl; return 1; } }