// file : query/driver.cxx // copyright : not copyrighted - public domain #include #include // std::auto_ptr #include #include #include #include "database.hxx" // create_database #include "person.hxx" #include "person-odb.hxx" using namespace std; using odb::database; using odb::transaction; typedef odb::query query; typedef odb::result result; static void print (person& p) { cout << p.first () << " "; if (!p.middle ().null ()) cout << p.middle ().get () << " "; cout << p.last () << " " << p.age () << endl; } static void print (result& r) { for (result::iterator i (r.begin ()); i != r.end (); ++i) print (*i); cout << endl; } int main (int argc, char* argv[]) { try { auto_ptr db (create_database (argc, argv)); { typedef vector people; people p; p.push_back (person ("John", "Doe", 21)); p.push_back (person ("John", "Smith", 22)); p.push_back (person ("Jack", "Johnson", 31)); p.push_back (person ("John", "JJ", "Jackson", 32)); p.push_back (person ("Jane", "JD", "Doe", 23)); p.push_back (person ("Jane", "JS", "Smith", 24)); transaction t (db->begin ()); for (people::iterator i (p.begin ()); i != p.end (); ++i) db->persist (*i); t.commit (); } // A simple query and result handling. // { transaction t (db->begin ()); result r (db->query (query::age < 30)); for (result::iterator i (r.begin ()); i != r.end (); ++i) { cout << i->first () << " " << i->last () << " " << i->age () << endl; } // Alternatively we can get a dynamically-allocated object. // /* for (result::iterator i (r.begin ()); i != r.end (); ++i) { auto_ptr p (i.load ()); cout << p->first () << " " << p->last () << " " << p->age () << endl; } */ // Or we can load the state into an existing object. // /* person p ("", "", 0); for (result::iterator i (r.begin ()); i != r.end (); ++i) { i.load (p); cout << p.first () << " " << p.last () << " " << p.age () << endl; } */ cout << endl; t.commit (); } // Use query_one() as a shortcut when there's no more than one element // in the result. // { transaction t (db->begin ()); auto_ptr p (db->query_one (query::age == 21)); if (p.get () != 0) { print (*p); cout << endl; } // Or we can load the state into an existing object. // /* person p ("", "", 0); if (db->query_one (query::age == 21, p)) { print (p); cout << endl; } */ t.commit (); } // Query that shows how to combine expressions with &&, ||, and ! // as well as use paranthesis to control evaluation order. // { transaction t (db->begin ()); result r ( db->query ( (query::first == "John" || query::first == "Jane") && !(query::last != "Doe" || query::age > 30))); print (r); t.commit (); } // Query that shows how to use by-reference parameter binding. // { transaction t (db->begin ()); unsigned short lower, upper; query q (query::age >= query::_ref (lower) && query::age < query::_ref (upper)); for (unsigned short band (0); band < 10; ++band) { lower = band * 10; upper = lower + 10; result r (db->query (q)); if (!r.empty ()) { cout << lower << '-' << (upper - 1) << ':' << endl; print (r); } } t.commit (); } // Query that shows how to use the in() function. // { transaction t (db->begin ()); result r ( db->query ( query::last.in ("Smith", "Johnson", "Jockson"))); print (r); t.commit (); } // The same query but using the in_range() function. // { vector names; names.push_back ("Smith"); names.push_back ("Johnson"); names.push_back ("Jockson"); transaction t (db->begin ()); result r ( db->query ( query::last.in_range (names.begin (), names.end ()))); print (r); t.commit (); } // Query that shows how to test for NULL values using the // is_null()/is_not_null() functions. // { transaction t (db->begin ()); result r (db->query (query::middle.is_not_null ())); print (r); t.commit (); } } catch (const odb::exception& e) { cerr << e.what () << endl; return 1; } }