// file : qt/common/smart-ptr/driver.cxx // author : Constantin Michael <constantin@codesynthesis.com> // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file // Test Qt smart pointers. // #include <memory> // std::auto_ptr #include <cassert> #include <iostream> #include <QtCore/QSharedPointer> #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; // Force instantiation of all QLazySharedPointer and QLazyWeakPointer // class template members. // template class QLazySharedPointer<cont>; template class QLazyWeakPointer<cont>; int main (int argc, char* argv[]) { try { auto_ptr<database> db (create_database (argc, argv)); QSharedPointer<cont> c1 (new cont (1)); QSharedPointer<cont> c2 (new cont (2)); // Test boolean conversion operator. // { assert (!QLazySharedPointer<cont> ()); assert (!QLazyWeakPointer<cont> ()); assert (QLazySharedPointer<cont> (c1)); assert (QLazySharedPointer<cont> (*db, 1)); assert (QLazyWeakPointer<cont> (c1)); assert (QLazyWeakPointer<cont> (*db, 1)); } // Test loaded () implementation. // { assert (QLazySharedPointer<cont> ().loaded ()); assert (!QLazySharedPointer<cont> (c1).loaded ()); assert (!QLazySharedPointer<cont> (*db, 1).loaded ()); assert (QLazySharedPointer<cont> (*db, c1).loaded ()); assert (QLazyWeakPointer<cont> ().loaded ()); assert (!QLazyWeakPointer<cont> (c1).loaded ()); assert (!QLazyWeakPointer<cont> (*db, 1).loaded ()); assert (QLazyWeakPointer<cont> (*db, c1).loaded ()); } // Test comparison operators. // { // Transient QLazySharedPointer. // assert (QLazySharedPointer<cont> () == QLazySharedPointer<cont> ()); assert (QLazySharedPointer<cont> () != QLazySharedPointer<cont> (c1)); assert (QLazySharedPointer<cont> (c1) != QLazySharedPointer<cont> (c2)); assert (QLazySharedPointer<cont> (c2) == QLazySharedPointer<cont> (c2)); // Persistent QLazySharedPointer. // QLazySharedPointer<cont> ls1 (*db, 1), ls2 (*db, c2); assert (ls1 != QLazySharedPointer<cont> ()); assert (ls1 != QLazySharedPointer<cont> (c1)); assert (ls1 == QLazySharedPointer<cont> (*db, c1)); assert (ls1 != ls2); assert (ls2 == QLazySharedPointer<cont> (c2)); // Transient QLazyWeakPointer. // assert (QLazyWeakPointer<cont> () == QLazyWeakPointer<cont> ()); assert (QLazyWeakPointer<cont> () != QLazyWeakPointer<cont> (c1)); assert (QLazyWeakPointer<cont> (c1) != QLazyWeakPointer<cont> (c2)); assert (QLazyWeakPointer<cont> (c2) == QLazyWeakPointer<cont> (c2)); assert (QLazyWeakPointer<cont> () == QLazySharedPointer<cont> ()); assert (QLazyWeakPointer<cont> () != QLazySharedPointer<cont> (c1)); assert (QLazyWeakPointer<cont> (c1) != QLazySharedPointer<cont> (c2)); assert (QLazyWeakPointer<cont> (c2) == QLazySharedPointer<cont> (c2)); // Persistent QLazyWeakPointer. // QLazyWeakPointer<cont> lw1 (*db, 1), lw2 (*db, c2); assert (lw1 != QLazyWeakPointer<cont> ()); assert (lw1 != QLazyWeakPointer<cont> (c1)); assert (lw1 == QLazyWeakPointer<cont> (*db, c1)); assert (lw1 != lw2); assert (lw2 == QLazyWeakPointer<cont> (c2)); assert (ls1 == lw1); assert (ls1 != QLazyWeakPointer<cont> (c1)); assert (ls1 == QLazyWeakPointer<cont> (*db, c1)); assert (ls1 != lw2); assert (ls2 == QLazyWeakPointer<cont> (c2)); } // Test swap. // { QLazySharedPointer<cont> lx (*db, 1), ly; swap (lx, ly); assert (lx.isNull ()); assert (ly == QLazySharedPointer<cont> (*db, c1)); } // Persist. // QSharedPointer<obj> o1 (new obj (1)); QSharedPointer<obj> o2 (new obj (2)); QSharedPointer<obj> o3 (new obj (3)); QSharedPointer<obj> o4 (new obj (4)); o1->c = c1; o2->c = c1; o3->c = c2; o4->c = c2; { transaction t (db->begin ()); db->persist (c1); db->persist (o1); db->persist (o2); db->persist (o3); db->persist (o4); db->persist (c2); t.commit (); } // Load. // { session s; transaction t (db->begin ()); QSharedPointer<cont> c (db->load<cont> (1)); QSharedPointer<obj> o (db->load<obj> (1)); // Ensure that lazy pointers are present but not loaded. // assert (c->o.size () == 2); assert (!c->o[0].loaded ()); assert (!c->o[1].loaded ()); assert (!o->c.loaded ()); // Ensure that the correct object IDs were loaded. // assert (c->o[0].objectId<obj> () == 1); assert (c->o[1].objectId<obj> () == 2); assert (o->c.objectId<obj> () == 1); // Load the lazy pointer targets ensuring that the loaded // targets correspond to the cached session objects. // QSharedPointer<cont> cl (o->c.load ()); QSharedPointer<obj> ol (c->o[0].load ()); assert (c->o[0].loaded ()); assert (o->c.loaded ()); assert (cl == c); assert (ol == o); t.commit (); } // Test lazy weak locking and reloading. // { // No session. // transaction t (db->begin ()); QSharedPointer<cont> c (db->load<cont> (1)); // Lock. // assert (!c->o[1].loaded ()); QLazySharedPointer<obj> l (c->o[1].toStrongRef ()); assert (!l.loaded ()); assert (l.objectId<obj> () == c->o[1].objectId<obj> ()); // Reload. // assert (!c->o[1].loaded ()); QSharedPointer<obj> ol (c->o[1].load ()); assert (c->o[1].loaded ()); ol.clear (); assert (!c->o[1].loaded ()); ol = c->o[1].load (); assert (c->o[1].loaded ()); t.commit (); } // // Test QSharedPointer as a value wrapper. // { obj2 o1 (1); obj2 o2 (2); o2.num = QSharedPointer<unsigned long> (new unsigned long (123)); transaction t (db->begin ()); db->persist (o1); db->persist (o2); t.commit (); } { transaction t (db->begin ()); QSharedPointer<obj2> o1 (db->load<obj2> (1)); QSharedPointer<obj2> o2 (db->load<obj2> (2)); t.commit (); assert (!o1->num); assert (o2->num && *o2->num == 123); } } catch (const odb::exception& e) { cerr << e.what () << endl; return 1; } }