// file : common/lazy-ptr/driver.cxx // author : Boris Kolpackov <boris@codesynthesis.com> // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file // Test lazy object pointers. // #include <memory> // std::auto_ptr #include <cassert> #include <iostream> #include <odb/database.hxx> #include <odb/transaction.hxx> #include <common/common.hxx> #include "test.hxx" #include "test-odb.hxx" using namespace std; using namespace odb::core; auto_ptr<obj2> create (unsigned int id) { auto_ptr<obj2> r (new obj2 (id)); return r; } lazy_auto_ptr<obj2> create (database& db, unsigned int id) { lazy_auto_ptr<obj2> r (db, id); return r; } int main (int argc, char* argv[]) { try { auto_ptr<database> db (create_database (argc, argv)); // Raw. // { typedef cont1 cont; typedef obj1 obj; // persist // obj* o1 (new obj (1)); { transaction t (db->begin ()); db->persist (o1); t.commit (); } auto_ptr<cont> c1 (new cont (1)); auto_ptr<cont> c2 (new cont (2)); lazy_ptr<obj> lo1 (*db, 1); obj* o2 (new obj (2)); obj* o3 (new obj (3)); obj* o4 (new obj (4)); c1->o.push_back (lo1); c1->o.push_back (o2); c2->o.push_back (o3); c2->o.push_back (o4); // Test pointer comparison. // assert (lazy_ptr<obj> () == lazy_ptr<obj> ()); assert (lazy_ptr<obj> (o1) != lazy_ptr<obj> ()); assert (lo1 != lazy_ptr<obj> ()); assert (lazy_ptr<obj> (o1) == lazy_ptr<obj> (o1)); assert (lo1 == lazy_ptr<obj> (*db, o1)); assert (lo1 != lazy_ptr<obj> (*db, o2)); delete o1; { transaction t (db->begin ()); db->persist (o2); db->persist (o3); db->persist (o4); db->persist (*c1); db->persist (*c2); t.commit (); } // load // { session s; transaction t (db->begin ()); auto_ptr<cont> c (db->load<cont> (1)); obj* o (db->load<obj> (1)); // Not loaded. // assert (c->o.size () == 2); assert (!c->o[0].loaded ()); assert (!c->o[1].loaded ()); assert (!o->c.loaded ()); // Correct object ids. // assert (c->o[0].object_id<obj> () == o->id); assert (o->c.object_id<cont> () == c->id); // Load. // cont* cl (o->c.load ()); obj* ol (c->o[0].load ()); assert (cl == c.get ()); assert (ol == o); // Test unload/reload. // o->c.unload (); assert (!o->c.loaded ()); o->c.load (); assert (o->c.loaded ()); t.commit (); } } // Auto pointer. // { typedef cont2 cont; typedef obj2 obj; // persist // { auto_ptr<obj> o1 (new obj (1)); transaction t (db->begin ()); db->persist (*o1); t.commit (); } auto_ptr<cont> c1 (new cont (1)); auto_ptr<cont> c2 (new cont (2)); lazy_auto_ptr<obj> lo1 = create (*db, 1); lo1 = create (*db, 1); c1->o = lo1; c2->o = create (2); { transaction t (db->begin ()); db->persist (*c2->o); db->persist (*c1); db->persist (*c2); t.commit (); } // load // { session s; transaction t (db->begin ()); auto_ptr<cont> c (db->load<cont> (1)); obj* o (db->load<obj> (1)); // Not loaded. // assert (!c->o.loaded ()); assert (!o->c.loaded ()); // Correct object ids. // assert (c->o.object_id<obj> () == o->id); assert (o->c.object_id<cont> () == c->id); // Load. // cont* cl (o->c.load ()); const auto_ptr<obj>& ol (c->o.load ()); assert (cl == c.get ()); assert (ol.get () == o); t.commit (); } // unload/reload // { // No session. transaction t (db->begin ()); auto_ptr<cont> c (db->load<cont> (1)); assert (!c->o.loaded ()); c->o.load (); assert (c->o.loaded ()); c->o.unload (); assert (!c->o.loaded ()); c->o.load (); assert (c->o.loaded ()); t.commit (); } } // TR1. // #ifdef HAVE_TR1_MEMORY { using namespace ::tr1; // persist // shared_ptr<cont> c1 (new cont (1)); { transaction t (db->begin ()); db->persist (c1); t.commit (); } lazy_shared_ptr<cont> lc1 (*db, 1); shared_ptr<cont> c2 (new cont (2)); shared_ptr<obj> o1 (new obj (1)); shared_ptr<obj> o2 (new obj (2)); shared_ptr<obj> o3 (new obj (3)); shared_ptr<obj> o4 (new obj (4)); o1->c = lc1; o2->c = lc1; o3->c = c2; o4->c = c2; // Test pointer comparison. // assert (lazy_shared_ptr<cont> () == lazy_shared_ptr<cont> ()); assert (lazy_shared_ptr<cont> (c1) != lazy_shared_ptr<cont> ()); assert (lc1 != lazy_shared_ptr<cont> ()); assert (lazy_shared_ptr<cont> (c1) == lazy_shared_ptr<cont> (c1)); assert (lc1 == lazy_shared_ptr<cont> (*db, c1)); assert (lc1 != lazy_shared_ptr<cont> (*db, c2)); { transaction t (db->begin ()); db->persist (o1); db->persist (o2); db->persist (o3); db->persist (o4); db->persist (c2); t.commit (); } // load // { session s; transaction t (db->begin ()); shared_ptr<cont> c (db->load<cont> (1)); shared_ptr<obj> o (db->load<obj> (1)); // Not loaded. // assert (c->o.size () == 2); assert (!c->o[0].loaded ()); assert (!c->o[1].loaded ()); assert (!o->c.loaded ()); // Correct object ids. // assert (c->o[0].object_id<obj> () == o->id); assert (o->c.object_id<cont> () == c->id); // Load. // shared_ptr<cont> cl (o->c.load ()); shared_ptr<obj> ol (c->o[0].load ()); assert (cl == c); assert (ol == o); t.commit (); } // Test lazy weak locking and reloading. // { // No session. transaction t (db->begin ()); shared_ptr<cont> c (db->load<cont> (1)); // Lock. // assert (!c->o[1].loaded ()); lazy_shared_ptr<obj> l (c->o[1].lock ()); assert (!l.loaded ()); assert (l.object_id<obj> () == c->o[1].object_id<obj> ()); // Reload. // assert (!c->o[1].loaded ()); shared_ptr<obj> ol (c->o[1].load ()); assert (c->o[1].loaded ()); ol.reset (); assert (!c->o[1].loaded ()); ol = c->o[1].load (); assert (c->o[1].loaded ()); t.commit (); } } #endif } catch (const odb::exception& e) { cerr << e.what () << endl; return 1; } }