// file : query/driver.cxx // author : Boris Kolpackov <boris@codesynthesis.com> // copyright : not copyrighted - public domain #include <vector> #include <memory> // std::auto_ptr #include <iostream> #include <odb/database.hxx> #include <odb/transaction.hxx> #include "database.hxx" // create_database #include "person.hxx" #include "person-odb.hxx" using namespace std; using odb::database; using odb::transaction; typedef odb::query<person> query; typedef odb::result<person> result; static void print (result& r) { for (result::iterator i (r.begin ()); i != r.end (); ++i) { cout << i->first () << " "; if (!i->middle ().null ()) cout << i->middle ().get () << " "; cout << i->last () << " " << i->age () << endl; } cout << endl; } int main (int argc, char* argv[]) { try { auto_ptr<database> db (create_database (argc, argv)); { typedef vector<person> 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<person> (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<person> 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 (); } // 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<person> ( (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<person> (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<person> ( query::last.in ("Smith", "Johnson", "Jockson"))); print (r); t.commit (); } // The same query but using the in_range() function. // { vector<string> names; names.push_back ("Smith"); names.push_back ("Johnson"); names.push_back ("Jockson"); transaction t (db->begin ()); result r ( db->query<person> ( 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<person> (query::middle.is_not_null ())); print (r); t.commit (); } } catch (const odb::exception& e) { cerr << e.what () << endl; return 1; } }