diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2013-01-09 14:50:26 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2013-01-16 07:42:56 +0200 |
commit | 5cf30ccfe764701f549e4152ad312187221f5285 (patch) | |
tree | f3e558a08ab9d2d8fb00855ab1c0ef42d4d9af91 /common/session/custom/driver.cxx | |
parent | 9bd664e4cb39f6654e8754c8cfd4c28295ee2d90 (diff) |
Implement two-phase session insertion
On the first step an uninitialized object is inserted into the cache
as before (this is necessary to handle recursive loading). The second
step is to notify the session that the object has been initialized.
On this second step the session can perform change tracking preparations,
such as make a copy of the object or reset the modification flag.
New test: common/session/custom (implements a custom session that uses
copies to track changes).
Diffstat (limited to 'common/session/custom/driver.cxx')
-rw-r--r-- | common/session/custom/driver.cxx | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/common/session/custom/driver.cxx b/common/session/custom/driver.cxx new file mode 100644 index 0000000..1ec7cbb --- /dev/null +++ b/common/session/custom/driver.cxx @@ -0,0 +1,168 @@ +// file : common/session/custom/driver.cxx +// copyright : Copyright (c) 2009-2012 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 <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; + +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"); + ste = db->load<employee> (st->employees ()[0].object_id ()); + + // 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"); + cse = db->load<employee> (cs->employees ()[0].object_id ()); + 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); // Flush all the changes. + assert (tracer.count == 3); + t.commit (); + s.mark (); // Mark all the changed objects as unchanged. + } + + { + 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); // Flush all the changes. + assert (tracer.count == 2); + t.commit (); + s.mark (); // Mark all the changed objects as unchanged. + } + + { + transaction t (db->begin ()); + tracer.count = 0; + t.tracer (tracer); + s.flush (*db); + assert (tracer.count == 0); + t.commit (); + } + } + catch (const odb::exception& e) + { + cerr << e.what () << endl; + return 1; + } +} |