From d59e3c27450747e5a04585ee9e943376b5bcfa41 Mon Sep 17 00:00:00 2001
From: Michael Shepanski To get the result of a view we use the same Normally, to get the result of a view we use the same
+ Do not be concerned if, at this point, much appears unclear. The intent
of this chapter is to give you only a general idea of how to persist C++
objects with ODB. We will cover all the details throughout the remainder
@@ -4920,11 +4921,104 @@ find_minors (database& db, const query& name_query)
result r (find_minors (db, query::first == "John"));
+ The result of executing a query is zero, one, or more objects
+ matching the query criteria. The In situations where we know that a query produces at most one
+ element, we can instead use the The shortcut query functions have the following signatures: Similar to Similar to the The If the query executed using Common situations where we can use the shortcut functions are a
+ query condition that uses a data member with the
+ The result of executing a query is zero, one, or more objects
- matching the query criteria. The result is returned as an instance
- of the The Most modern relational database systems have the notion of a prepared
@@ -5195,12 +5288,12 @@ namespace odb
In ODB all the non-query database operations such as
query()
- function as when querying the database for an object. Here is
+ query()
function as when querying the database for
+ an object. Here, however, we are executing an aggregate query
+ which always returns exactly one element. Therefore, instead
+ of getting the result instance and then iterating over it, we
+ can use the shortcut query_value()
function. Here is
how we can load and print our statistics using the view we have
just created:query()
function
+ returns this result as an instance of the odb::result
+ class template, which provides a stream-like interface and is
+ discussed in detail in the next section.database::query_one()
and
+ database::query_value()
shortcut functions, for example:
+ typedef odb::query<person> query;
+
+ auto_ptr<person> p (
+ db.query_one<person> (
+ query::email == "jon@example.com"));
+
+
+
+ template <typename T>
+ typename object_traits<T>::pointer_type
+ query_one ();
+
+ template <typename T>
+ bool
+ query_one (T&);
+
+ template <typename T>
+ T
+ query_value ();
+
+ template <typename T>
+ typename object_traits<T>::pointer_type
+ query_one (const odb::query<T>&);
+
+ template <typename T>
+ bool
+ query_one (const odb::query<T>&, T&);
+
+ template <typename T>
+ T
+ query_value (const odb::query<T>&);
+
+
+ query()
, the first three functions are used
+ to return the only persistent object of a given type stored in the
+ database. The second three versions use the passed query instance
+ to only return the object matching the query criteria.database::find()
functions
+ (Section 3.9, "Loading Persistent Objects"),
+ query_one()
can either allocate a new instance of the
+ object class in the dynamic memory or it can load the object's state
+ into an existing instance. The query_value()
function
+ allocates and returns the object by value.query_one()
function allows us to determine
+ if the query result contains zero or one element. If no objects
+ matching the query criteria were found in the database, the
+ first version of query_one()
returns the NULL
+ pointer while the second — false
. If the second
+ version returns false
, then the passed object
+ remains unchanged. For example:
+ if (unique_ptr<person> p = db.query_one<person> (
+ query::email == "jon@example.com"))
+ {
+ ...
+ }
+
+ person p;
+ if (db.query_one<person> (query::email == "jon@example.com", p))
+ {
+ ...
+ }
+
+
+ query_one()
or
+ query_value()
returns more than one element,
+ then these functions fail with an assertion. Additionally,
+ query_value()
also fails with an assertion if
+ the query returned no elements.unique
constraint (at most one element returned;
+ see Section 14.7, "Index Definition Pragmas")
+ as well as aggregate queries (exactly one element returned; see
+ Chapter 10, "Views").4.4 Query Result
- odb::result
class template, for example:database::query()
function returns the result of
+ executing a query as an instance of the odb::result
+ class template, for example:
typedef odb::query<person> query;
@@ -5183,7 +5277,6 @@ namespace odb
}
-
4.5 Prepared Queries
persist()
, load()
, update()
,
- etc., are implemented in terms of prepared statements that are
- cached and reused. While the query()
database
- operation also uses the prepared statement, this statement
- is not cached or reused by default since ODB has no knowledge
- of whether a query will be executed multiple times or only
- once. Instead, ODB provides a mechanism, called prepared queries,
+ etc., are implemented in terms of prepared statements that are cached
+ and reused. While the query()
, query_one()
,
+ and query_one()
database operations also use prepared
+ statements, these statements are not cached or reused by default since
+ ODB has no knowledge of whether a query will be executed multiple times
+ or only once. Instead, ODB provides a mechanism, called prepared queries,
that allows us to prepare a query once and execute it multiple
times. In other words, ODB prepared queries are a thin wrapper
around the underlying database's prepared statement functionality.
The execute_one()
and execute_value()
+ functions can be used as shortcuts to execute a query that is
+ known to return at most one or exactly one object, respectively.
+ The arguments and return values in these functions have the same
+ semantics as in query_one()
and query_value()
.
+ And similar to execute()
above, prepare_query()
+ and execute_one/value()
can be seen as the
+ query_one/value()
function split into two:
+ prepare_query()
takes the first
+ query_one/value()
argument (the query condition) while
+ execute_one/value()
takes the second argument (if any)
+ and returns the result. Note also that execute_one/value()
+ never caches its result but invalidates the result of any previous
+ execute()
call on the same prepared query.
The name()
function returns the prepared query name.
This is the same name as was passed as the first argument in the
prepare_query()
call. The statement()
@@ -9746,11 +9863,12 @@ struct employee_name
to compile any header that defines a view with the
--generate-query
ODB compiler option.
To query the database for a view we use the database::query()
- function in exactly the same way as we would use it to query the
- database for an object. For example, the following code fragment
- shows how we can find the names of all the employees that are
- younger than 31:
To query the database for a view we use the
+ database::query()
, database::query_one()
, or
+ database::query_value()
functions in exactly the same way
+ as we would use them to query the database for an object. For example,
+ the following code fragment shows how we can find the names of all the
+ employees that are younger than 31:
typedef odb::query<employee_name> query; @@ -10028,18 +10146,18 @@ struct employee_count querying the database for an object. For example:-typedef odb::result<employee_count> result; typedef odb::query<employee_count> query; transaction t (db.begin ()); -// Find the number of employees with the Doe last name. +// Find the number of employees with the Doe last name. Result of this +// aggregate query contains only one element so use the query_value() +// shortcut function. // -result r (db.query<employee_count> (query::last == "Doe")); +employee_count ec ( + db.query_value<employee_count> (query::last == "Doe")); -// Result of this aggregate query contains only one element. -// -cout << r.begin ()->count << endl; +cout << ec.count << endl; t.commit ();@@ -19660,20 +19778,16 @@ struct person_min_max_agetypedef odb::query<person_min_max_age> query; -typedef odb::result<person_min_max_age> result; transaction t (db.begin ()); +// We know this query always returns a single row, so use query_value(). // We have to pass dummy values for OUT parameters. // -result r ( - db.query<person_min_max_age> ( +person_min_max_age mma ( + db.query_value<person_min_max_age> ( query::_val (0) + "," + query::_val (0))); -// We know this query always returns a single row. -// -person_min_max_age mma (*r.begin ()); - cerr << mma.min_age << " " << mma.max_age << endl; t.commit (); -- cgit v1.1