diff options
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | view/README | 20 | ||||
-rw-r--r-- | view/driver.cxx | 25 | ||||
-rw-r--r-- | view/employee.hxx | 59 |
4 files changed, 61 insertions, 46 deletions
@@ -41,6 +41,9 @@ inverse inheritance Shows how to use persistent class inheritance. +view + Shows how to define and use object, table, mixed, and native views. + boost Shows how to persist objects that use Boost smart pointers, containers, and value types with the help of the Boost profile library (libodb-boost). diff --git a/view/README b/view/README index 108d234..4c30ad2 100644 --- a/view/README +++ b/view/README @@ -1,7 +1,7 @@ -This example shows how to declare and use views in ODB. It includes views -that show how to load a subset of data member from objects and tables, -perform aggregate queries, and join multiple objects and tables using -object relationships and custom join conditions. +This example shows how to define and use views in ODB. It includes views +that show how to load a subset of data members from objects or columns +from tables, perform aggregate queries, and join multiple objects and +tables using object relationships and custom join conditions. The example uses the shared_ptr smart pointer from TR1 and requires a C++ compiler with TR1 support or an external TR1 implementation, such as the @@ -11,7 +11,7 @@ The example consists of the following files: employee.hxx Header file defining the 'country', 'employer', and 'employee' persistent - classes. The example also uses a "legacy" 'employee_extra' table that is + classes. The example also uses the "legacy" 'employee_extra' table that is not mapped to a persistent class. After the persistent classes, this header defines a number of views that @@ -42,14 +42,14 @@ database.hxx driver.cxx Driver for the example. It includes the employee.hxx and employee-odb.hxx - headers to gain access to the persistent classes and their database support - code. It also includes database.hxx for the create_database() function - declaration. + headers to gain access to the persistent classes and views as well as + their database support code. It also includes database.hxx for the + create_database() function declaration. In main() the driver first calls create_database() to obtain the database instance. It then creates the legacy 'employee_extra' table and proceeds - to populate the database with a number of 'employee', 'employer', and - 'project' objects. Once this is done, the driver uses views defined in + to populate the database with a number of 'country', 'employer', and + 'employee' objects. Once this is done, the driver uses views defined in employee.hxx to load and print various information about the object model. To run the example we may first need to create the database schema (for some diff --git a/view/driver.cxx b/view/driver.cxx index ccd8d2d..bc32513 100644 --- a/view/driver.cxx +++ b/view/driver.cxx @@ -143,7 +143,7 @@ main (int argc, char* argv[]) result<employee_count> r ( db->query<employee_count> (query<employee_count>::last == "Doe")); - // Results of this aggregate query contains only one element. + // Result of this aggregate query contains only one element. // cout << r.begin ()->count << " employees with the Doe last name" << endl << endl; @@ -151,7 +151,7 @@ main (int argc, char* argv[]) t.commit (); } - // Load the employee-employer information for all the employess with the + // Load the employee-employer information for all the employees with the // Doe last name using the employee_employer view. // { @@ -175,7 +175,7 @@ main (int argc, char* argv[]) t.commit (); } - // Calculate average ages of all employees for each employer. + // Calculate min/max employee ages for each employer. // { typedef odb::query<employer_age> query; @@ -198,7 +198,7 @@ main (int argc, char* argv[]) // query::employee::last == "Doe")); // - cout << "Man/max employee ages" << endl; + cout << "Min/max employee ages" << endl; for (result::iterator i (r.begin ()); i != r.end (); ++i) cout << " " << i->employer_name << " " @@ -209,8 +209,8 @@ main (int argc, char* argv[]) t.commit (); } - // Load the country information employees different residence and - // nationality. + // Load the country information for employees with different residence + // and nationality. // { typedef odb::query<employee_country> query; @@ -218,7 +218,8 @@ main (int argc, char* argv[]) transaction t (db->begin ()); - // Note that we use the alias given in the object pragma after query::. + // Note that we use the alias given in the db object pragma after + // query::. // result r (db->query<employee_country> ( query::res_country::name != query::nat_country::name)); @@ -241,9 +242,9 @@ main (int argc, char* argv[]) transaction t (db->begin ()); - // With native views we have to use the native query syntax. + // With native views we have to use the native SQL query syntax. // - result r (db->query<employee_vacation> ("vacation_days != 0")); + result r (db->query<employee_vacation> ("vacation_days <> 0")); cout << "Employees with accumulated vacation days" << endl; @@ -255,15 +256,15 @@ main (int argc, char* argv[]) t.commit (); } - // Get the list of employees that have accumulated vacation days, - // this time using the improved employee_vacation2 view. + // Get the list of employees that have accumulated vacation days, this + // time using the improved employee_vacation2 view. // { typedef odb::result<employee_vacation2> result; transaction t (db->begin ()); - result r (db->query<employee_vacation2> ("vacation_days != 0")); + result r (db->query<employee_vacation2> ("vacation_days <> 0")); cout << "Employees with accumulated vacation days (take 2)" << endl; diff --git a/view/employee.hxx b/view/employee.hxx index 4ff4f1b..110cb9e 100644 --- a/view/employee.hxx +++ b/view/employee.hxx @@ -143,8 +143,8 @@ private: shared_ptr<employer> employed_by_; }; -// We also have a "legacy" employee_extra table that is not mapped to any -// object. It has the following columns: +// We also have the "legacy" employee_extra table that is not mapped to any +// persistent class. It has the following columns: // // CREATE TABLE employee_extra( // employee_id INTEGER NOT NULL, @@ -153,10 +153,10 @@ private: // // A simple view with a single associated object. It allows us to get -// the name of an employee without loading any of the other data, such -// as the country and employer objects. The first and last data members -// in the view are automatically assumed to correspond to the first_ and -// last_ members in the employee object. +// the name of an employee without loading any of the other parts, such +// as the referenced country and employer objects. The first and last +// data members in the view are automatically associated to the first_ +// and last_ members in the employee object. // #pragma db view object(employee) struct employee_name @@ -177,14 +177,13 @@ struct employee_count }; // A simple view with two associated object. It allows us to get the -// name of an employee and its employer without loading any other data. -// Because there is a relationship between the employee and employer -// objects (employee::employed_by_), the ODB compiler automatically -// used this relationship as a join condition. Also, similar to the -// employee_name view, the first and last data members are automatically -// assumed to correspond to the first_ and last_ members in the employee -// object. For the employer_name member we provide an explicit member -// reference. +// name of an employee and its employer without loading any other parts. +// Because there is an unambiguous relationship between the employee and +// employer objects (employee::employed_by_), the ODB compiler is able to +// automatically use this relationship as a join condition. Also, similar +// to the employee_name view, the first and last data members are auto- +// associated to the first_ and last_ members in the employee object. +// For the employer_name member we provide an explicit member reference. // #pragma db view object(employee) object(employer) struct employee_employer @@ -196,10 +195,9 @@ struct employee_employer std::string employer_name; }; -// A more interesting aggregate view using GROUP BY. It allows us to -// calculate the min/max age of employees for each employer. Here we -// use the C++-integrated syntax for the query condition template with -// a placeholder (?). +// A more interesting aggregate view that uses the GROUP BY clause. It +// allows us to calculate the min/max ages of employees for each employer. +// Here we use the query condition with a placeholder (?). // #pragma db view object(employee) object(employer) \ query ((?) + "GROUP BY" + employer::name_) @@ -216,8 +214,8 @@ struct employer_age }; // A more complex view with three associated objects, two of which are -// of the same type, which requires us to use aliases and disambiguate -// the relationships used to join each object. +// of the same type. This requires us to use aliases and disambiguate +// the relationships used to associate each object. // #pragma db view object(employee) \ object(country = res_country: employee::residence_) \ @@ -234,9 +232,9 @@ struct employee_country std::string nat_country_name; }; -// A native view. A native view provides a complete query and is normally -// based on an ad-hoc table. This view allows us to load the employee -// vacation information from the legacy employee_extra table. +// An example of a native view that provides a complete query and is based +// on an ad-hoc table. This view allows us to load the employee vacation +// information from the legacy employee_extra table. // #pragma db view query("SELECT employee_id, vacation_days " \ "FROM view_employee_extra") @@ -249,6 +247,19 @@ struct employee_vacation unsigned short days; }; +// A more robust implementation of the above view as a table view instead +// of a native view. +// +#pragma db view table("view_employee_extra") +struct employee_vacation1 +{ + #pragma db column("employee_id") type("INTEGER") + unsigned long id; + + #pragma db column("vacation_days") type("INTEGER") + unsigned short days; +}; + // An improved version of the previous view that extracts the employee // first and last names instead of the id. To get the names we need to // add the employee object to this view and use a custom join condition @@ -265,7 +276,7 @@ struct employee_vacation2 unsigned short days; }; -// An advanced view that joins two objects via a legacy table. It returns +// A mixed view that associates two objects and a legacy table. It returns // the previous employer information for each employee. // #pragma db view object(employee) \ |