diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-01-13 11:31:14 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-01-13 11:31:14 +0200 |
commit | ab51fa65f9e8cad4ef5a1db85029dfe6404e9a1f (patch) | |
tree | 36c78dd50d88e4797f2bbb886c41399006111fea /inverse/driver.cxx | |
parent | 5511613df7dce6142a84111488aaa25ff792d66b (diff) |
Add composite, relationship, and inverse examples
All add the TR1 <memory> test for the latter two examples.
Diffstat (limited to 'inverse/driver.cxx')
-rw-r--r-- | inverse/driver.cxx | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/inverse/driver.cxx b/inverse/driver.cxx new file mode 100644 index 0000000..bffbf65 --- /dev/null +++ b/inverse/driver.cxx @@ -0,0 +1,258 @@ +// file : inverse/driver.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#include <memory> // std::auto_ptr +#include <iostream> + +#include <odb/database.hxx> +#include <odb/transaction.hxx> + +#include "database.hxx" // create_database + +#include "employee.hxx" +#include "employee-odb.hxx" + +using namespace std; +using namespace odb; + +void +print (const employee& e) +{ + cout << e.first () << " " << e.last () << endl + << " employer: " << e.employer ().load ()->name () << endl + << " position: " << e.position ().load ()->title () << endl; + + const projects& ps (e.projects ()); + + for (projects::const_iterator i (ps.begin ()); i != ps.end (); ++i) + { + const lazy_shared_ptr<project>& p (*i); + p.load (); + + cout << " project: " << p->name () << endl; + } + + cout << endl; +} + +int +main (int argc, char* argv[]) +{ + try + { + auto_ptr<database> db (create_database (argc, argv)); + + // Create a few persistent objects. + // + { + // Simple Tech Ltd. + // + { + shared_ptr<employer> er (new employer ("Simple Tech Ltd")); + + shared_ptr<position> he (new position ("Hardware Engineer")); + shared_ptr<position> se (new position ("Software Engineer")); + + shared_ptr<project> sh (new project ("Simple Hardware")); + shared_ptr<project> ss (new project ("Simple Software")); + + shared_ptr<employee> john (new employee ("John", "Doe", er, he)); + shared_ptr<employee> jane (new employee ("Jane", "Doe", er, se)); + + // Set the inverse side of the employee-employer relationship. + // + er->employees ().push_back (john); + er->employees ().push_back (jane); + + // Set the inverse side of the employee-position relationship. + // + he->employee (john); + se->employee (jane); + + // Set the employee-project relationship (both directions). + // + john->projects ().push_back (sh); + john->projects ().push_back (ss); + jane->projects ().push_back (ss); + + sh->employees ().push_back (john); + ss->employees ().push_back (john); + ss->employees ().push_back (jane); + + transaction t (db->begin ()); + + db->persist (er); + + db->persist (he); + db->persist (se); + + db->persist (sh); + db->persist (ss); + + db->persist (john); + db->persist (jane); + + t.commit (); + } + + // Complex Systems Inc. + // + { + shared_ptr<employer> er (new employer ("Complex Systems Inc")); + + shared_ptr<position> he (new position ("Hardware Engineer")); + shared_ptr<position> se (new position ("Software Engineer")); + + shared_ptr<project> ch (new project ("Complex Hardware")); + shared_ptr<project> cs (new project ("Complex Software")); + + shared_ptr<employee> john (new employee ("John", "Smith", er, se)); + shared_ptr<employee> jane (new employee ("Jane", "Smith", er, he)); + + // Set the inverse side of the employee-employer relationship. + // + er->employees ().push_back (john); + er->employees ().push_back (jane); + + // Set the inverse side of the employee-position relationship. + // + he->employee (john); + se->employee (jane); + + // Set the employee-project relationship (both directions). + // + john->projects ().push_back (cs); + jane->projects ().push_back (ch); + jane->projects ().push_back (cs); + + ch->employees ().push_back (jane); + cs->employees ().push_back (john); + cs->employees ().push_back (jane); + + transaction t (db->begin ()); + + db->persist (er); + + db->persist (he); + db->persist (se); + + db->persist (ch); + db->persist (cs); + + db->persist (john); + db->persist (jane); + + t.commit (); + } + } + + // Load Simple Tech Ltd and print its employees. We use a session in this + // and subsequent transactions to make sure that a single instance of any + // particular object (e.g., employer) is shared among all objects (e.g., + // employee) that relate to it. + // + { + session s; + transaction t (db->begin ()); + + shared_ptr<employer> stl (db->load<employer> ("Simple Tech Ltd")); + + employees& es (stl->employees ()); + + for (employees::iterator i (es.begin ()); i != es.end (); ++i) + { + lazy_weak_ptr<employee>& lwp (*i); + shared_ptr<employee> p (lwp.load ()); // Load and lock. + print (*p); + } + + t.commit (); + } + + // Find all Software Engineers. + // + { + typedef odb::query<position> query; + typedef odb::result<position> result; + + session s; + transaction t (db->begin ()); + + result r (db->query<position> (query::title == "Software Engineer")); + + for (result::iterator i (r.begin ()); i != r.end (); ++i) + { + const lazy_weak_ptr<employee>& lwp (i->employee ()); + shared_ptr<employee> p (lwp.load ()); // Load and lock. + + // Employee can be NULL if the position is vacant. + // + if (p) + print (*p); + } + + t.commit (); + } + + // John Doe has moved to Complex Systems Inc and is now working as + // a Software Engineer on Complex Software. + // + { + typedef odb::query<employee> query; + typedef odb::result<employee> result; + + session s; + transaction t (db->begin ()); + + // Create "unloaded" pointers to the employer and project objects. + // + lazy_shared_ptr<employer> csi (*db, std::string ("Complex Systems Inc")); + lazy_shared_ptr<project> cs (*db, std::string ("Complex Software")); + + // Create a new Software Engineer position. + // + shared_ptr<position> se (new position ("Software Engineer")); + + result r (db->query<employee> (query::first == "John" && + query::last == "Doe")); + + shared_ptr<employee> john (r.begin ().load ()); + + john->employer (csi); + john->position (se); + john->projects ().clear (); + john->projects ().push_back (cs); + + db->persist (se); + db->update (john); + + t.commit (); + } + + // Print Complex Systems Inc's employees. This time, instead of loading + // the employer object, we use a query which shows how we can use members + // of the pointed-to objects in the queries. + // + { + typedef odb::query<employee> query; + typedef odb::result<employee> result; + + session s; + transaction t (db->begin ()); + + result r (db->query<employee> ( + query::employer::name == "Complex Systems Inc")); + + for (result::iterator i (r.begin ()); i != r.end (); ++i) + print (*i); + + t.commit (); + } + } + catch (const odb::exception& e) + { + cerr << e.what () << endl; + return 1; + } +} |