aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-01-17 15:15:59 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-01-17 15:15:59 +0200
commit9825b7b79eb73c5cfdd1bb1daa66dc6a699de7e5 (patch)
tree232e0400744c20061cc93b906037d337557c5e66 /doc
parentf45761ef4c29fbedcc841281175f6ce36e7e15ef (diff)
Cosmetic manual changes
Diffstat (limited to 'doc')
-rw-r--r--doc/manual.xhtml628
1 files changed, 319 insertions, 309 deletions
diff --git a/doc/manual.xhtml b/doc/manual.xhtml
index d2c65c6..8fe19f0 100644
--- a/doc/manual.xhtml
+++ b/doc/manual.xhtml
@@ -328,63 +328,62 @@ for consistency.
<th>5</th><td><a href="#5">ODB Pragma Language</a>
<table class="toc">
<tr>
- <th>5.1</th><td><a href="#5.1">C++ Compiler Warnings</a>
+ <th>5.1</th><td><a href="#5.1">Object Type Pragmas</a>
<table class="toc">
- <tr><th>5.1.1</th><td><a href="#5.1.1">GNU C++</a></td></tr>
- <tr><th>5.1.2</th><td><a href="#5.1.2">Visual C++</a></td></tr>
- <tr><th>5.1.3</th><td><a href="#5.1.3">Sun C++</a></td></tr>
- <tr><th>5.1.4</th><td><a href="#5.1.4">IBM XL C++</a></td></tr>
- <tr><th>5.1.5</th><td><a href="#5.1.5">HP aC++</a></td></tr>
+ <tr><th>5.1.1</th><td><a href="#5.1.1"><code>table</code></a></td></tr>
+ <tr><th>5.1.2</th><td><a href="#5.1.2"><code>pointer</code></a></td></tr>
</table>
</td>
</tr>
<tr>
- <th>5.2</th><td><a href="#5.2">Object Type Pragmas</a>
+ <th>5.2</th><td><a href="#5.2">Value Type Pragmas</a>
<table class="toc">
- <tr><th>5.2.1</th><td><a href="#5.2.1"><code>table</code></a></td></tr>
- <tr><th>5.2.2</th><td><a href="#5.2.2"><code>pointer</code></a></td></tr>
+ <tr><th>5.2.1</th><td><a href="#5.2.1"><code>type</code></a></td></tr>
+ <tr><th>5.2.2</th><td><a href="#5.2.2"><code>not_null</code></a></td></tr>
+ <tr><th>5.2.3</th><td><a href="#5.2.3"><code>unordered</code></a></td></tr>
+ <tr><th>5.2.4</th><td><a href="#5.2.4"><code>index_type</code></a></td></tr>
+ <tr><th>5.2.5</th><td><a href="#5.2.5"><code>key_type</code></a></td></tr>
+ <tr><th>5.2.6</th><td><a href="#5.2.6"><code>value_type</code></a></td></tr>
+ <tr><th>5.2.7</th><td><a href="#5.2.7"><code>id_column</code></a></td></tr>
+ <tr><th>5.2.8</th><td><a href="#5.2.8"><code>index_column</code></a></td></tr>
+ <tr><th>5.2.9</th><td><a href="#5.2.9"><code>key_column</code></a></td></tr>
+ <tr><th>5.2.10</th><td><a href="#5.2.10"><code>value_column</code></a></td></tr>
</table>
</td>
</tr>
<tr>
- <th>5.3</th><td><a href="#5.3">Value Type Pragmas</a>
+ <th>5.3</th><td><a href="#5.3">Data Member Pragmas</a>
<table class="toc">
- <tr><th>5.3.1</th><td><a href="#5.3.1"><code>type</code></a></td></tr>
- <tr><th>5.3.2</th><td><a href="#5.3.2"><code>not_null</code></a></td></tr>
- <tr><th>5.3.3</th><td><a href="#5.3.3"><code>unordered</code></a></td></tr>
- <tr><th>5.3.4</th><td><a href="#5.3.4"><code>index_type</code></a></td></tr>
- <tr><th>5.3.5</th><td><a href="#5.3.5"><code>key_type</code></a></td></tr>
- <tr><th>5.3.6</th><td><a href="#5.3.6"><code>value_type</code></a></td></tr>
- <tr><th>5.3.7</th><td><a href="#5.3.7"><code>id_column</code></a></td></tr>
- <tr><th>5.3.8</th><td><a href="#5.3.8"><code>index_column</code></a></td></tr>
- <tr><th>5.3.9</th><td><a href="#5.3.9"><code>key_column</code></a></td></tr>
- <tr><th>5.3.10</th><td><a href="#5.3.10"><code>value_column</code></a></td></tr>
+ <tr><th>5.3.1</th><td><a href="#5.3.1"><code>id</code></a></td></tr>
+ <tr><th>5.3.2</th><td><a href="#5.3.2"><code>auto</code></a></td></tr>
+ <tr><th>5.3.3</th><td><a href="#5.3.3"><code>type</code></a></td></tr>
+ <tr><th>5.3.4</th><td><a href="#5.3.4"><code>column</code></a></td></tr>
+ <tr><th>5.3.5</th><td><a href="#5.3.5"><code>transient</code></a></td></tr>
+ <tr><th>5.3.6</th><td><a href="#5.3.6"><code>not_null</code></a></td></tr>
+ <tr><th>5.3.7</th><td><a href="#5.3.7"><code>inverse</code></a></td></tr>
+ <tr><th>5.3.8</th><td><a href="#5.3.8"><code>unordered</code></a></td></tr>
+ <tr><th>5.3.9</th><td><a href="#5.3.9"><code>table</code></a></td></tr>
+ <tr><th>5.3.10</th><td><a href="#5.3.10"><code>index_type</code></a></td></tr>
+ <tr><th>5.3.11</th><td><a href="#5.3.11"><code>key_type</code></a></td></tr>
+ <tr><th>5.3.12</th><td><a href="#5.3.12"><code>value_type</code></a></td></tr>
+ <tr><th>5.3.13</th><td><a href="#5.3.13"><code>id_column</code></a></td></tr>
+ <tr><th>5.3.14</th><td><a href="#5.3.14"><code>index_column</code></a></td></tr>
+ <tr><th>5.3.15</th><td><a href="#5.3.15"><code>key_column</code></a></td></tr>
+ <tr><th>5.3.16</th><td><a href="#5.3.16"><code>value_column</code></a></td></tr>
</table>
</td>
</tr>
<tr>
- <th>5.4</th><td><a href="#5.4">Data Member Pragmas</a>
+ <th>5.4</th><td><a href="#5.4">C++ Compiler Warnings</a>
<table class="toc">
- <tr><th>5.4.1</th><td><a href="#5.4.1"><code>id</code></a></td></tr>
- <tr><th>5.4.2</th><td><a href="#5.4.2"><code>auto</code></a></td></tr>
- <tr><th>5.4.3</th><td><a href="#5.4.3"><code>type</code></a></td></tr>
- <tr><th>5.4.4</th><td><a href="#5.4.4"><code>column</code></a></td></tr>
- <tr><th>5.4.5</th><td><a href="#5.4.5"><code>transient</code></a></td></tr>
- <tr><th>5.4.6</th><td><a href="#5.4.6"><code>not_null</code></a></td></tr>
- <tr><th>5.4.7</th><td><a href="#5.4.7"><code>inverse</code></a></td></tr>
- <tr><th>5.4.8</th><td><a href="#5.4.8"><code>unordered</code></a></td></tr>
- <tr><th>5.4.9</th><td><a href="#5.4.9"><code>table</code></a></td></tr>
- <tr><th>5.4.10</th><td><a href="#5.4.10"><code>index_type</code></a></td></tr>
- <tr><th>5.4.11</th><td><a href="#5.4.11"><code>key_type</code></a></td></tr>
- <tr><th>5.4.12</th><td><a href="#5.4.12"><code>value_type</code></a></td></tr>
- <tr><th>5.4.13</th><td><a href="#5.4.13"><code>id_column</code></a></td></tr>
- <tr><th>5.4.14</th><td><a href="#5.4.14"><code>index_column</code></a></td></tr>
- <tr><th>5.4.15</th><td><a href="#5.4.15"><code>key_column</code></a></td></tr>
- <tr><th>5.4.16</th><td><a href="#5.4.16"><code>value_column</code></a></td></tr>
+ <tr><th>5.4.1</th><td><a href="#5.4.1">GNU C++</a></td></tr>
+ <tr><th>5.4.2</th><td><a href="#5.4.2">Visual C++</a></td></tr>
+ <tr><th>5.4.3</th><td><a href="#5.4.3">Sun C++</a></td></tr>
+ <tr><th>5.4.4</th><td><a href="#5.4.4">IBM XL C++</a></td></tr>
+ <tr><th>5.4.5</th><td><a href="#5.4.5">HP aC++</a></td></tr>
</table>
</td>
</tr>
-
</table>
</td>
</tr>
@@ -797,7 +796,7 @@ private:
of core ODB declarations, such as <code>odb::access</code>, that
are used to define persistent classes.</p>
- <p>The second change is the addition of <code>db object</code>
+ <p>The second change is the addition of <code>db&nbsp;object</code>
pragma just before the class definition. This pragma tells the
ODB compiler that the class that follows is persistent. Note
that making a class persistent does not mean that all objects
@@ -826,7 +825,7 @@ private:
have a unique, within its class, identifier. Or, in other words,
no two persistent instances of the same type have equal
identifiers. For our class we use an integer id. The
- <code>db id auto</code> pragma that precedes the <code>id_</code>
+ <code>db&nbsp;id auto</code> pragma that precedes the <code>id_</code>
member tells the ODB compiler that the following member is the
object's identifier. The <code>auto</code> specifier indicates that it
is a database-assigned id. A unique id will be automatically generated
@@ -1641,8 +1640,8 @@ class person
<p>Normally, an object class should define the default constructor. The
generated database support code uses this constructor when
- instantiating an object from the persistent state. If you add the
- default constructor only for the database support code, then you
+ instantiating an object from the persistent state. If we add the
+ default constructor only for the database support code, then we
can make it private. It is also possible to have an object type
without the default constructor. However, in this case, the database
operations can only load the persistent state into an existing instance
@@ -1680,11 +1679,11 @@ private:
types such as <code>int</code> or <code>std::string</code> since the
ODB compiler knows how to map them to suitable database system types and
how to convert between the two. On the other hand, if a simple value
- is unknown to the ODB compiler then you will need to provide the
+ is unknown to the ODB compiler then we will need to provide the
mapping to the database system type and, possibly, the code to
convert between the two. For more information on how to achieve
- this refer to the <code>db&nbsp;type</code> pragma (<a href="#5.3.1">Section
- 5.3.1, "<code>type</code>"</a>). Similar to object types, composite
+ this refer to the <code>db&nbsp;type</code> pragma (<a href="#5.2.1">Section
+ 5.2.1, "<code>type</code>"</a>). Similar to object types, composite
value types have to be explicitly declared as persistent using the
<code>db&nbsp;value</code> pragma, for example:</p>
@@ -1770,11 +1769,11 @@ class name
with the sharing semantics, such as <code>shared_ptr</code> mentioned
previously, as object pointers.</p>
- <p>ODB provides two mechanisms for changing the object pointer type. You
+ <p>ODB provides two mechanisms for changing the object pointer type. We
can use the <code>--default-pointer</code> option to specify the
alternate default object pointer type. All objects that don't
have the object pointer explicitly specified with the
- <code>db pointer</code> pragma (see below) will use the default
+ <code>db&nbsp;pointer</code> pragma (see below) will use the default
pointer type. Refer to the
<a href="http://www.codesynthesis.com/products/odb/doc/odb.xhtml">ODB
Compiler Command Line Manual</a> for details on this option's argument.
@@ -1784,8 +1783,8 @@ class name
--default-pointer std::tr1::shared_ptr
</pre>
- <p>The second mechanism allows you to specify the object pointer on
- an object by object basis using the <code>db pointer</code>
+ <p>The second mechanism allows us to specify the object pointer on
+ an object by object basis using the <code>db&nbsp;pointer</code>
pragma, for example:</p>
<pre class="c++">
@@ -1796,7 +1795,7 @@ class person
};
</pre>
- <p>Refer to <a href="#5.2.2">Section 5.2.2, "<code>pointer</code>"</a>
+ <p>Refer to <a href="#5.1.2">Section 5.1.2, "<code>pointer</code>"</a>
for more information on this pragma.</p>
<p>Built-in support, provided by the ODB runtime, library allows us to use
@@ -1813,10 +1812,10 @@ class person
<p>Before an application can make use of persistence services
offered by ODB, it has to create a database class instance. A
database instance is the representation of the place where
- the application stores its persistent objects. You create
+ the application stores its persistent objects. We create
a database instance by instantiating one of the database
system-specific classes. For example, <code>odb::mysql::database</code>
- would be such a class for the MySQL database system. You will
+ would be such a class for the MySQL database system. We will
also normally pass a database name as an argument to the
class' constructor. The following code fragment
shows how we can create a database instance for the MySQL
@@ -1930,7 +1929,7 @@ namespace odb
has been <em>finalized</em>, that is, explicitly committed or rolled
back, the destructor of the <code>odb::transaction</code> class will
automatically roll it back when the transaction instance goes
- out of scope. If you try to commit or roll back a finalized
+ out of scope. If we try to commit or roll back a finalized
transaction, the <code>odb::transaction_already_finalized</code>
exception is thrown.</p>
@@ -1939,7 +1938,7 @@ namespace odb
function returns the currently active transaction for this
thread. If there is no active transaction, this function
throws the <code>odb::not_in_transaction</code> exception.
- You can check whether there is a transaction in effect in
+ We can check whether there is a transaction in effect in
this thread using the <code>has_current()</code> static function.</p>
<p>If two or more transactions access or modify more than one object
@@ -2095,7 +2094,7 @@ update_age (database&amp; db, person&amp; p)
<p>The first <code>persist()</code> function expects a constant reference
to an instance being persisted. The second function expects a constant
object pointer. Both of these functions can only be used on objects with
- application-assigned object ids (<a href="#5.4.2">Section 5.4.2,
+ application-assigned object ids (<a href="#5.3.2">Section 5.3.2,
"<code>auto</code>"</a>).</p>
<p>The second and third <code>persist()</code> versions are similar to the
@@ -2369,7 +2368,7 @@ namespace odb
}
</pre>
- <p>Catching this exception guarantees that you will catch all the
+ <p>Catching this exception guarantees that we will catch all the
exceptions thrown by ODB. The <code>what()</code> function
returns a human-readable description of the condition that
triggered the exception.</p>
@@ -2460,7 +2459,7 @@ namespace odb
<p>The <code>null_pointer</code> exception is thrown when a
pointer to a persistent object declared non-<code>NULL</code>
- with the <code>db not_null</code> pragma has the <code>NULL</code>
+ with the <code>db&nbsp;not_null</code> pragma has the <code>NULL</code>
value. See <a href="#Y">Chapter Y, "Relationships"</a> for details.</p>
<p>The next three exceptions (<code>already_in_transaction</code>,
@@ -2528,7 +2527,7 @@ namespace odb
container types as discussed later in <a href="#X.4">Section X.4,
"Using Custom Containers"</a>.</p>
- <p>You don't need to do anything special to declare a member of a
+ <p>We don't need to do anything special to declare a member of a
container type in a persistent class. For example:</p>
<pre class="c++">
@@ -2637,7 +2636,7 @@ private:
(called <code>index</code>), and the value column of type
<code>std::string</code> (called <code>value</code>).</p>
- <p>A number of ODB pragmas allow you to customize the table name,
+ <p>A number of ODB pragmas allow us to customize the table name,
column names, and native database types for the container both on
the per-container and per-member basis. For more information on
these pragmas, refer to <a href="#5">Chapter 5, "ODB Pragma
@@ -2730,7 +2729,7 @@ private:
(called <code>object_id</code>) and the value column of type
<code>std::string</code> (called <code>value</code>).</p>
- <p>A number of ODB pragmas allow you to customize the table name,
+ <p>A number of ODB pragmas allow us to customize the table name,
column names, and native database types for the container both on
the per-container and per-member basis. For more information on
these pragmas, refer to <a href="#5">Chapter 5, "ODB Pragma
@@ -2795,7 +2794,7 @@ private:
<code>unsigned short</code> (called <code>key</code>), and the value
column of type <code>std::string</code> (called <code>value</code>).</p>
- <p>A number of ODB pragmas allow you to customize the table name,
+ <p>A number of ODB pragmas allow us to customize the table name,
column names, and native database types for the container both on
the per-container and per-member basis. For more information on
these pragmas, refer to <a href="#5">Chapter 5, "ODB Pragma
@@ -2878,7 +2877,7 @@ private:
Section Y.4, "Using Custom Smart Pointers"</a>. Any supported
smart pointer can be used in a data member as long as it can be
explicitly constructed from the canonical object pointer (@@ ref).
- For example, you can use <code>weak_ptr</code> if the object pointer
+ For example, we can use <code>weak_ptr</code> if the object pointer
is <code>shared_ptr</code>.</p>
<p>When an object containing a pointer to another object is loaded,
@@ -3277,7 +3276,7 @@ CREATE TABLE employee (
of these references.</p>
<p>To eliminate redundant database schema references we can use the
- <code>inverse</code> pragma (<a href="#5.4.7">Section 5.4.7,
+ <code>inverse</code> pragma (<a href="#5.3.7">Section 5.3.7,
"<code>inverse</code>"</a>) which tells the ODB compiler that
a pointer is the inverse side of a bidirectional relationship.
Either side of a relationship can be made inverse. For example:</p>
@@ -3321,7 +3320,7 @@ CREATE TABLE employee (
pointer. Also note that an ordered container (<a href="#X.1">Section
X.1, "Ordered Containers"</a>) of pointers that is an inverse side
of a bidirectional relationship is always treated as unordered
- (<a href="#5.4.8">Section 5.4.8, "<code>unordered</code>"</a>)
+ (<a href="#5.3.8">Section 5.3.8, "<code>unordered</code>"</a>)
because the contents of such a container are implicitly built from
the direct side of the relationship which does not contain the
element order (index).</p>
@@ -3863,7 +3862,7 @@ t.commit ();
<p>Composite value type is a <code>class</code> or <code>struct</code>
type that is mapped to more than one database column. To declare
- a composite value type we use the <code>db value</code> pragma,
+ a composite value type we use the <code>db&nbsp;value</code> pragma,
for example:</p>
<pre class="c++">
@@ -3993,7 +3992,7 @@ t.commit ();
<p>Customizing a column name for a data member of a simple value
type is straightforward: we simply specify the desired name with
- the <code>db column</code> pragma (@@ ref). For composite value
+ the <code>db&nbsp;column</code> pragma (@@ ref). For composite value
types things are slightly more complicated since it is mapped to
multiple columns. Consider the following example:</p>
@@ -4034,7 +4033,7 @@ CREATE TABLE person (
</pre>
<p>We can customize both the prefix and the suffix using the
- <code>db column</code> pragma as shown in the following
+ <code>db&nbsp;column</code> pragma as shown in the following
example:</p>
<pre class="c++">
@@ -4093,8 +4092,8 @@ CREATE TABLE person (
<p>The same principal applies when a composite value type is used
as an element of a container, except that instead of
- <code>db column</code> either the <code>db value_column</code>
- (@@ ref) or <code>db key_column</code> (@@ ref) pragmas are used to
+ <code>db&nbsp;column</code> either the <code>db&nbsp;value_column</code>
+ (@@ ref) or <code>db&nbsp;key_column</code> (@@ ref) pragmas are used to
specify the column prefix.</p>
<p>When a composite value type contains a container, an extra table
@@ -4138,7 +4137,7 @@ CREATE TABLE person (
</pre>
<p>To customize the container table name we can use the
- <code>db table</code> (@@ ref) pragma, for example:</p>
+ <code>db&nbsp;table</code> (@@ ref) pragma, for example:</p>
<pre class="c++">
#pragma db value
@@ -4275,7 +4274,7 @@ namespace odb
</pre>
<p>The session constructor creates a new session and sets it as a
- current session for this thread. If you try to create a session
+ current session for this thread. If we try to create a session
while there is already a current session in effect, this constructor
throws the <code>odb::already_in_session</code> exception. The
destructor clears the current session for this thread if this
@@ -4283,11 +4282,11 @@ namespace odb
<p>The static <code>current()</code> accessor returns the currently active
session for this thread. If there is no active session, this function
- throws the <code>odb::not_in_session</code> exception. You can check
+ throws the <code>odb::not_in_session</code> exception. We can check
whether there is a session in effect in this thread using the
<code>has_current()</code> static function.</p>
- <p>The static <code>current()</code> modifier allows you to set the
+ <p>The static <code>current()</code> modifier allows us to set the
current session for this thread. The <code>reset_current</code>
static function clears the current session. These two functions
allow for more advanced use cases, such as multiplexing
@@ -4361,18 +4360,18 @@ t.commit ();
<h1><a name="4">4 Querying the Database</a></h1>
- <p>If you don't know the identifiers of the objects that you are looking
- for, you can use queries to search the database for objects matching
- certain criteria. The ODB query facility is optional and you need to
+ <p>If we don't know the identifiers of the objects that we are looking
+ for, we can use queries to search the database for objects matching
+ certain criteria. The ODB query facility is optional and we need to
explicitly request the generation of the necessary database support
code with the <code>--generate-query</code> ODB compiler option.</p>
<p>ODB provides a flexible query API that offers two distinct levels of
abstraction from the database system query language such as SQL.
- At the high level you are presented with an easy to use yet powerful
+ At the high level we are presented with an easy to use yet powerful
object-oriented query language, called ODB Query Language. This
query language is modeled after and is integrated into C++ allowing
- you to write expressive and safe queries that look and feel like
+ us to write expressive and safe queries that look and feel like
ordinary C++. We have already seen examples of these queries in the
introductory chapters. Below is another, more interesting, example:</p>
@@ -4403,7 +4402,7 @@ t.commit ();
query q ("first = 'John' AND age = " + query::_ref (age));
</pre>
- <p>Note that at this level you lose the static typing of
+ <p>Note that at this level we lose the static typing of
query expressions. For example, if we wrote something like this:</p>
<pre class="c++">
@@ -4423,7 +4422,7 @@ t.commit ();
<p>It would compile fine and would trigger an error only when executed
by the database system.</p>
- <p>You can also combine the two query languages in a single query, for
+ <p>We can also combine the two query languages in a single query, for
example:</p>
<pre class="c++">
@@ -4447,7 +4446,7 @@ t.commit ();
<p>At the core of every query expression lie simple expressions which
involve one or more object members, values, or parameters. To
- refer to an object member you use an expression such as
+ refer to an object member we use an expression such as
<code>query::first</code> above. The names of members in the
<code>query</code> class are derived from the names of data members
in the object class by removing the common member name decorations,
@@ -4550,7 +4549,7 @@ t.commit ();
<p>The operator precedence in the query expressions are the same
- as for equivalent C++ operators. You can use parentheses to
+ as for equivalent C++ operators. We can use parentheses to
make sure the expression is evaluated in the desired order.
For example:</p>
@@ -4589,7 +4588,7 @@ t.commit ();
</pre>
<p>The <code>odb::query</code> class provides two special functions,
- <code>_val()</code> and <code>_ref()</code>, that allow you to
+ <code>_val()</code> and <code>_ref()</code>, that allow us to
bind the parameter either by value or by reference, respectively.
In the ODB query language, if the binding is not specified
explicitly, the value semantic is used by default. In the
@@ -4610,7 +4609,7 @@ t.commit ();
other variables and is self-sufficient once constructed. A query
that has one or more by-reference parameters depends on the
bound variables until the query is executed. If one such variable
- goes out of scope and you execute the query, the behavior is
+ goes out of scope and we execute the query, the behavior is
undefined.</p>
<h2><a name="4.3">4.3 Executing a Query</a></h2>
@@ -4661,7 +4660,7 @@ t.commit ();
result r1 (db.query&lt;person> (query::first == "John"));
</pre>
- <p>Normally you would create a named query instance if you are
+ <p>Normally we would create a named query instance if we are
planning to run the same query multiple times and would use the
in-line version for those that are executed only once.</p>
@@ -4692,7 +4691,7 @@ result r (find_underage (db, query::first == "John"));
</pre>
<p>It is best to view an instance of <code>odb::result</code>
- as a handle to a stream, such as a file stream. While you can
+ as a handle to a stream, such as a file stream. While we can
make a copy of a result or assign one result to another, the
two instances will refer to the same result stream. Advancing
the current position in one instance will also advance it in
@@ -4750,7 +4749,7 @@ namespace odb
result caching when we talked about query execution. As you
may remember the <code>database::query()</code> function
caches the result unless instructed not to by the caller.
- The <code>cache()</code> function allows you to
+ The <code>cache()</code> function allows us to
cache the result at a later stage if it wasn't already
cached during query execution.</p>
@@ -4763,8 +4762,8 @@ namespace odb
at a time as the iteration progresses.</p>
<p>Uncached results can improve the performance of both the application
- and the database system in situations where you have a large
- number of objects in the result or if you will only examine
+ and the database system in situations where we have a large
+ number of objects in the result or if we will only examine
a small portion of the returned objects. However, uncached
results have a number of limitations. There can only be one
uncached result in a transaction. Creating another result
@@ -4776,7 +4775,7 @@ namespace odb
<p>The <code>empty()</code> function returns <code>true</code> if
there are no objects in the result and <code>false</code> otherwise.
The <code>size()</code> function can only be called for cached results.
- It returns the number of objects in the result. If you call this
+ It returns the number of objects in the result. If we call this
function on an uncached result, the <code>odb::result_not_cached</code>
exception is thrown.</p>
@@ -4798,13 +4797,13 @@ namespace odb
only two position operations that it supports are to move to the
next object and to determine whether the end of the result stream
has been reached. In fact, the result iterator can only be in two
- states: the current position and the end position. If you have
- two iterators pointing to the current position and then you
+ states: the current position and the end position. If we have
+ two iterators pointing to the current position and then we
advance one of them, the other will advance as well. This,
for example, means that it doesn't make sense to store an
iterator that points to some object of interest in the result
stream with the intent of dereferencing it after the iteration
- is over. Instead, you would need to store the object itself.</p>
+ is over. Instead, we would need to store the object itself.</p>
<p>The result iterator has the following dereference functions
that can be used to access the pointed-to object:</p>
@@ -4831,13 +4830,13 @@ namespace odb
}
</pre>
- <p>When you call the <code>*</code> or <code>-></code> operator,
+ <p>When we call the <code>*</code> or <code>-></code> operator,
the iterator will allocate a new instance of the object class
in the dynamic memory, load its state from the database
state, and return a reference or pointer to the new instance. The
iterator maintains the ownership of the returned object and will
return the same pointer for subsequent calls to either of these
- operators until it is advanced to the next object or you call
+ operators until it is advanced to the next object or we call
the first <code>load()</code> function (see below). For example:</p>
<pre class="c++">
@@ -4859,7 +4858,7 @@ namespace odb
as a result of an earlier
call to the <code>*</code> or <code>-></code> operator, then it
relinquishes the ownership of this object and returns it instead.
- This allows you to write code like this without worrying about
+ This allows us to write code like this without worrying about
a double allocation:</p>
<pre class="c++">
@@ -4880,7 +4879,7 @@ namespace odb
operator results in the allocation of a new object.</p>
<p>The second <code>load()</code> function allows
- you to load the current object's state into an existing instance.
+ us to load the current object's state into an existing instance.
For example:</p>
<pre class="c++">
@@ -4963,9 +4962,8 @@ private:
unsigned long id_;
</pre>
-
<p>While keeping the C++ declarations and database declarations close
- together eases maintenance and increases readability, you can also
+ together eases maintenance and increases readability, we can also
place them in different parts of the same header file or even
factor them to a separate file. To achieve this we use the so called
<em>named pragmas</em>. Unlike positioned pragmas, named pragmas
@@ -5026,143 +5024,20 @@ private:
};
</pre>
- <h2><a name="5.1">5.1 C++ Compiler Warnings</a></h2>
+ <p>The following three sections cover the specifiers applicable
+ to the <code>object</code>, <code>value</code>, and <code>member</code>
+ qualifiers.</p>
- <p>The C++ header file that defines your persistent classes and
+ <p>The C++ header file that defines our persistent classes and
normally contains one or more ODB pragmas is compiled by both
the ODB compiler to generate the database support code and
- the C++ compiler to build your application. Some C++ compilers
+ the C++ compiler to build our application. Some C++ compilers
issue warnings about pragmas that they do not recognize. There
- are several ways to deal with this problem. The easiest is to
- disable such warnings using one of the compiler-specific command
- line options or warning control pragmas. This method is described
- in the following sub-section for popular C++ compilers.</p>
+ are several ways to deal with this problem which are covered
+ at the end of this chapter in <a href="#5.4">Section 5.4,
+ "C++ Compiler Warnings"</a>.</p>
- <p>There are also several C++ compiler-independent methods that you
- can employ. The first is to use the <code>PRAGMA_DB</code> macro,
- defined in <code>&lt;odb/core.hxx></code>, instead of using
- <code>#pragma&nbsp;db</code> directly. This macro expands to the
- ODB pragma when compiled with the ODB compiler and to an empty
- declaration when compiled with other compilers. The following example
- shows how we can use this macro:</p>
-
- <pre class="c++">
-#include &lt;odb/core.hxx>
-
-PRAGMA_DB(object)
-class person
-{
- ...
-private:
- PRAGMA_DB(id)
- unsigned long id_;
- ...
-};
- </pre>
-
- <p>An alternative to using the <code>PRAGMA_DB</code> macro is to
- group the <code>#pragma&nbsp;db</code> directives in blocks that are
- conditionally included into compilation only when compiled with the
- ODB compiler. For example:</p>
-
- <pre class="c++">
-class person
-{
- ...
-private:
- unsigned long id_;
- ...
-};
-
-#ifdef ODB_COMPILER
-# pragma db object(person)
-# pragma db member(person::id_) id
-#endif
- </pre>
-
- <p>The disadvantage of this approach is that it can quickly become
- overly verbose when positioned pragmas are used.</p>
-
- <h3><a name="5.1.1">5.1.1 GNU C++</a></h3>
-
- <p>GNU g++ does not issue warnings about unknown pragmas
- unless requested with the <code>-Wall</code> command line option.
- To disable only the unknown pragma warning, you can add the
- <code>-Wno-unknown-pragmas</code> option after <code>-Wall</code>,
- for example:</p>
-
- <pre class="terminal">
-g++ -Wall -Wno-unknown-pragmas ...
- </pre>
-
- <h3><a name="5.1.2">5.1.2 Visual C++</a></h3>
-
- <p>Microsoft Visual C++ issues an unknown pragma warning (C4068) at
- warning level 1 or higher. This means that unless you have disabled
- the warnings altogether (level 0), you will see this warning.</p>
-
- <p>To disable this warning via the compiler command line, you can add
- the <code>/wd4068</code> C++ compiler option in Visual Studio 2008
- and earlier. In Visual Studio 2010 there is now a special GUI field
- where you can enter warning numbers that should be disabled. Simply
- enter 4068 into this field.</p>
-
- <p>You can also disable this warning for only a specific header or
- a fragment of a header using the warning control pragma. For
- example:</p>
-
- <pre class="c++">
-#include &lt;odb/core.hxx>
-
-#pragma warning (push)
-#pragma warning (disable:4068)
-
-#pragma db object
-class person
-{
- ...
-private:
- #pragma db id
- unsigned long id_;
- ...
-};
-
-#pragma warning (pop)
- </pre>
-
- <h3><a name="5.1.3">5.1.3 Sun C++</a></h3>
-
- <p>The Sun C++ compiler does not issue warnings about unknown pragmas
- unless the <code>+w</code> or <code>+w2</code> option is specified.
- To disable only the unknown pragma warning you can add the
- <code>-erroff=unknownpragma</code> option anywhere on the
- command line, for example:</p>
-
- <pre class="terminal">
-CC +w -erroff=unknownpragma ...
- </pre>
-
- <h3><a name="5.1.4">5.1.4 IBM XL C++</a></h3>
-
- <p>IBM XL C++ issues an unknown pragma warning (1540-1401) by default.
- To disable this warning you can add the <code>-qsuppress=1540-1401</code>
- command line option, for example:</p>
-
- <pre class="terminal">
-xlC -qsuppress=1540-1401 ...
- </pre>
-
- <h3><a name="5.1.5">5.1.5 HP aC++</a></h3>
-
- <p>HP aC++ (aCC) issues an unknown pragma warning (2161) by default.
- To disable this warning you can add the <code>+W2161</code>
- command line option, for example:</p>
-
- <pre class="terminal">
-aCC +W2161 ...
- </pre>
-
- <h2><a name="5.2">5.2 Object Type Pragmas</a></h2>
+ <h2><a name="5.1">5.1 Object Type Pragmas</a></h2>
<p>A pragma with the <code>object</code> qualifier declares a C++ class
as a persistent object type. The qualifier can be optionally followed,
@@ -5179,19 +5054,19 @@ aCC +W2161 ...
<tr>
<td><code>table</code></td>
<td>the table name for the persistent class</td>
- <td><a href="#5.2.1">5.2.1</a></td>
+ <td><a href="#5.1.1">5.1.1</a></td>
</tr>
<tr>
<td><code>pointer</code></td>
<td>the pointer type for the persistent class</td>
- <td><a href="#5.2.2">5.2.2</a></td>
+ <td><a href="#5.1.2">5.1.2</a></td>
</tr>
</table>
- <h3><a name="5.2.1">5.2.1 <code>table</code></a></h3>
+ <h3><a name="5.1.1">5.1.1 <code>table</code></a></h3>
<p>The <code>table</code> specifier specifies the table name that should
be used to store objects of the class in a relational database. For
@@ -5208,7 +5083,7 @@ class person
<p>If the table name is not specified, the class name is used as the
table name.</p>
- <h3><a name="5.2.2">5.2.2 <code>pointer</code></a></h3>
+ <h3><a name="5.1.2">5.1.2 <code>pointer</code></a></h3>
<p>The <code>pointer</code> specifier specifies the object pointer type
for the persistent class. The object pointer type is used to return,
@@ -5224,8 +5099,8 @@ class person
</pre>
<p>There are several ways to specify an object pointer with the
- <code>pointer</code> specifier. You can use a complete pointer
- type as shown in the example above. Alternatively, you can
+ <code>pointer</code> specifier. We can use a complete pointer
+ type as shown in the example above. Alternatively, we can
specify only the template name of a smart pointer in which
case the ODB compiler will automatically append the class
name as a template argument. The following example is
@@ -5258,7 +5133,7 @@ class person
<p>For additional information on object pointers, refer to
<a href="#@@">Section @@, ""</a>.</p>
- <h2><a name="5.3">5.3 Value Type Pragmas</a></h2>
+ <h2><a name="5.2">5.2 Value Type Pragmas</a></h2>
<p>A pragma with the <code>value</code> qualifier describes a value
type. It can be optionally followed, in any order, by one or more
@@ -5275,67 +5150,67 @@ class person
<tr>
<td><code>type</code></td>
<td>the database type for the value type</td>
- <td><a href="#5.3.1">5.3.1</a></td>
+ <td><a href="#5.2.1">5.2.1</a></td>
</tr>
<tr>
<td><code>not_null</code></td>
<td>object pointer cannot be <code>NULL</code></td>
- <td><a href="#5.3.2">5.3.2</a></td>
+ <td><a href="#5.2.2">5.2.2</a></td>
</tr>
<tr>
<td><code>unordered</code></td>
<td>ordered container should be stored unordered</td>
- <td><a href="#5.3.3">5.3.3</a></td>
+ <td><a href="#5.2.3">5.2.3</a></td>
</tr>
<tr>
<td><code>index_type</code></td>
<td>the database type for the container's index type</td>
- <td><a href="#5.3.4">5.3.4</a></td>
+ <td><a href="#5.2.4">5.2.4</a></td>
</tr>
<tr>
<td><code>key_type</code></td>
<td>the database type for the container's key type</td>
- <td><a href="#5.3.5">5.3.5</a></td>
+ <td><a href="#5.2.5">5.2.5</a></td>
</tr>
<tr>
<td><code>value_type</code></td>
<td>the database type for the container's value type</td>
- <td><a href="#5.3.6">5.3.6</a></td>
+ <td><a href="#5.2.6">5.2.6</a></td>
</tr>
<tr>
<td><code>id_column</code></td>
<td>the column name for the container's table object id</td>
- <td><a href="#5.3.7">5.3.7</a></td>
+ <td><a href="#5.2.7">5.2.7</a></td>
</tr>
<tr>
<td><code>index_column</code></td>
<td>the column name for the container's table index</td>
- <td><a href="#5.3.8">5.3.8</a></td>
+ <td><a href="#5.2.8">5.2.8</a></td>
</tr>
<tr>
<td><code>key_column</code></td>
<td>the column name for the container's table key</td>
- <td><a href="#5.3.9">5.3.9</a></td>
+ <td><a href="#5.2.9">5.2.9</a></td>
</tr>
<tr>
<td><code>value_column</code></td>
<td>the column name for the container's table value</td>
- <td><a href="#5.3.10">5.3.10</a></td>
+ <td><a href="#5.2.10">5.2.10</a></td>
</tr>
</table>
<p>Many of the value type specifiers have corresponding member type
- specifiers with the same names (see <a href="#5.4">Section 5.4,
+ specifiers with the same names (see <a href="#5.3">Section 5.3,
"Data Member Pragmas"</a>). The behavior of such specifiers
for members is similar to that for value types. The only difference
is the scope. A particular value type specifier applies to all
@@ -5344,7 +5219,7 @@ class person
to a single member. In other words, member specifiers take precedence
over values specified with value specifiers.</p>
- <h3><a name="5.3.1">5.3.1 <code>type</code></a></h3>
+ <h3><a name="5.2.1">5.2.1 <code>type</code></a></h3>
<p>The <code>type</code> specifier specifies the native database type
that should be used for data members of this type. For example:</p>
@@ -5392,7 +5267,7 @@ private:
<code>mapping</code> example in the <code>odb-examples</code>
package shows how to do this for all the supported database systems.</p>
- <h3><a name="5.3.2">5.3.2 <code>not_null</code></a></h3>
+ <h3><a name="5.2.2">5.2.2 <code>not_null</code></a></h3>
<p>The <code>not_null</code> specifier specifies that an object pointer
or a container of object pointers type cannot have or contain the
@@ -5420,7 +5295,7 @@ typedef std::vector&lt;shared_ptr&lt;account> > accounts;
#pragma db value(accounts) not_null
</pre>
- <h3><a name="5.3.3">5.3.3 <code>unordered</code></a></h3>
+ <h3><a name="5.2.3">5.2.3 <code>unordered</code></a></h3>
<p>The <code>unordered</code> specifier specifies that the ordered
container should be stored in the database unordered. The database
@@ -5433,13 +5308,13 @@ typedef std::vector&lt;std::string> names;
#pragma db value(names) unordered
</pre>
- <h3><a name="5.3.4">5.3.4 <code>index_type</code></a></h3>
+ <h3><a name="5.2.4">5.2.4 <code>index_type</code></a></h3>
<p>The <code>index_type</code> specifier specifies the native
database type that should be used for the ordered container's
index column. The semantics of <code>index_type</code>
are similar to that of the <code>type</code> specifier (see
- <a href="#5.3.1">Section 5.3.1, "<code>type</code>"</a>). The native
+ <a href="#5.2.1">Section 5.2.1, "<code>type</code>"</a>). The native
database type is expected to be an integer type. For example:</p>
<pre class="c++">
@@ -5447,13 +5322,13 @@ typedef std::vector&lt;std::string> names;
#pragma db value(names) index_type("SMALLINT UNSIGNED NOT NULL")
</pre>
- <h3><a name="5.3.5">5.3.5 <code>key_type</code></a></h3>
+ <h3><a name="5.2.5">5.2.5 <code>key_type</code></a></h3>
<p>The <code>key_type</code> specifier specifies the native
database type that should be used for the map container's
key column. The semantics of <code>key_type</code>
are similar to that of the <code>type</code> specifier (see
- <a href="#5.3.1">Section 5.3.1, "<code>type</code>"</a>). For
+ <a href="#5.2.1">Section 5.2.1, "<code>type</code>"</a>). For
example:</p>
<pre class="c++">
@@ -5461,13 +5336,13 @@ typedef std::map&lt;unsigned short, float> age_weight_map;
#pragma db value(age_weight_map) key_type("INT UNSIGNED NOT NULL")
</pre>
- <h3><a name="5.3.6">5.3.6 <code>value_type</code></a></h3>
+ <h3><a name="5.2.6">5.2.6 <code>value_type</code></a></h3>
<p>The <code>value_type</code> specifier specifies the native
database type that should be used for the container's
value column. The semantics of <code>value_type</code>
are similar to that of the <code>type</code> specifier (see
- <a href="#5.3.1">Section 5.3.1, "<code>type</code>"</a>). For
+ <a href="#5.2.1">Section 5.2.1, "<code>type</code>"</a>). For
example:</p>
<pre class="c++">
@@ -5475,7 +5350,7 @@ typedef std::vector&lt;std::string> names;
#pragma db value(names) value_type("VARCHAR(255) NOT NULL")
</pre>
- <h3><a name="5.3.7">5.3.7 <code>id_column</code></a></h3>
+ <h3><a name="5.2.7">5.2.7 <code>id_column</code></a></h3>
<p>The <code>id_column</code> specifier specifies the column
name that should be used to store the object id in the
@@ -5489,7 +5364,7 @@ typedef std::vector&lt;std::string> names;
<p>If the column name is not specified, then <code>object_id</code>
is used by default.</p>
- <h3><a name="5.3.8">5.3.8 <code>index_column</code></a></h3>
+ <h3><a name="5.2.8">5.2.8 <code>index_column</code></a></h3>
<p>The <code>index_column</code> specifier specifies the column
name that should be used to store the element index in the
@@ -5503,7 +5378,7 @@ typedef std::vector&lt;std::string> names;
<p>If the column name is not specified, then <code>index</code>
is used by default.</p>
- <h3><a name="5.3.9">5.3.9 <code>key_column</code></a></h3>
+ <h3><a name="5.2.9">5.2.9 <code>key_column</code></a></h3>
<p>The <code>key_column</code> specifier specifies the column
name that should be used to store the key in the map
@@ -5517,7 +5392,7 @@ typedef std::map&lt;unsigned short, float> age_weight_map;
<p>If the column name is not specified, then <code>key</code>
is used by default.</p>
- <h3><a name="5.3.10">5.3.10 <code>value_column</code></a></h3>
+ <h3><a name="5.2.10">5.2.10 <code>value_column</code></a></h3>
<p>The <code>value_column</code> specifier specifies the column
name that should be used to store the element value in the
@@ -5534,7 +5409,7 @@ typedef std::map&lt;unsigned short, float> age_weight_map;
<!-- Data Member Pragmas -->
- <h2><a name="5.4">5.4 Data Member Pragmas</a></h2>
+ <h2><a name="5.3">5.3 Data Member Pragmas</a></h2>
<p>A pragma with the <code>member</code> qualifier or a positioned
pragma without a qualifier describes a data member. It can
@@ -5552,104 +5427,104 @@ typedef std::map&lt;unsigned short, float> age_weight_map;
<tr>
<td><code>id</code></td>
<td>the member is an object id</td>
- <td><a href="#5.4.1">5.4.1</a></td>
+ <td><a href="#5.3.1">5.3.1</a></td>
</tr>
<tr>
<td><code>auto</code></td>
<td>id is assigned by the database</td>
- <td><a href="#5.4.2">5.4.2</a></td>
+ <td><a href="#5.3.2">5.3.2</a></td>
</tr>
<tr>
<td><code>type</code></td>
<td>the database type for the member</td>
- <td><a href="#5.4.3">5.4.3</a></td>
+ <td><a href="#5.3.3">5.3.3</a></td>
</tr>
<tr>
<td><code>column</code></td>
<td>the column name for the member</td>
- <td><a href="#5.4.4">5.4.4</a></td>
+ <td><a href="#5.3.4">5.3.4</a></td>
</tr>
<tr>
<td><code>transient</code></td>
<td>the member is not stored in the database</td>
- <td><a href="#5.4.5">5.4.5</a></td>
+ <td><a href="#5.3.5">5.3.5</a></td>
</tr>
<tr>
<td><code>not_null</code></td>
<td>object pointer cannot be NULL</td>
- <td><a href="#5.4.6">5.4.6</a></td>
+ <td><a href="#5.3.6">5.3.6</a></td>
</tr>
<tr>
<td><code>inverse</code></td>
<td>the member is an inverse side of a bidirectional relationship</td>
- <td><a href="#5.4.7">5.4.7</a></td>
+ <td><a href="#5.3.7">5.3.7</a></td>
</tr>
<tr>
<td><code>unordered</code></td>
<td>ordered container should be stored unordered</td>
- <td><a href="#5.4.8">5.4.8</a></td>
+ <td><a href="#5.3.8">5.3.8</a></td>
</tr>
<tr>
<td><code>table</code></td>
<td>the table name for the container</td>
- <td><a href="#5.4.9">5.4.9</a></td>
+ <td><a href="#5.3.9">5.3.9</a></td>
</tr>
<tr>
<td><code>index_type</code></td>
<td>the database type for the container's index type</td>
- <td><a href="#5.4.10">5.4.10</a></td>
+ <td><a href="#5.3.10">5.3.10</a></td>
</tr>
<tr>
<td><code>key_type</code></td>
<td>the database type for the container's key type</td>
- <td><a href="#5.4.11">5.4.11</a></td>
+ <td><a href="#5.3.11">5.3.11</a></td>
</tr>
<tr>
<td><code>value_type</code></td>
<td>the database type for the container's value type</td>
- <td><a href="#5.4.12">5.4.12</a></td>
+ <td><a href="#5.3.12">5.3.12</a></td>
</tr>
<tr>
<td><code>id_column</code></td>
<td>the column name for the container's table object id</td>
- <td><a href="#5.4.13">5.4.13</a></td>
+ <td><a href="#5.3.13">5.3.13</a></td>
</tr>
<tr>
<td><code>index_column</code></td>
<td>the column name for the container's table index</td>
- <td><a href="#5.4.14">5.4.14</a></td>
+ <td><a href="#5.3.14">5.3.14</a></td>
</tr>
<tr>
<td><code>key_column</code></td>
<td>the column name for the container's table key</td>
- <td><a href="#5.4.15">5.4.15</a></td>
+ <td><a href="#5.3.15">5.3.15</a></td>
</tr>
<tr>
<td><code>value_column</code></td>
<td>the column name for the container's table value</td>
- <td><a href="#5.4.16">5.4.16</a></td>
+ <td><a href="#5.3.16">5.3.16</a></td>
</tr>
</table>
<p>Many of the member specifiers have corresponding value type
- specifiers with the same names (see <a href="#5.3">Section 5.3,
+ specifiers with the same names (see <a href="#5.2">Section 5.2,
"Value Type Pragmas"</a>). The behavior of such specifiers
for members is similar to that for value types. The only difference
is the scope. A particular value type specifier applies to all
@@ -5658,7 +5533,7 @@ typedef std::map&lt;unsigned short, float> age_weight_map;
to a single member. In other words, member specifiers take precedence
over values specified with value specifiers.</p>
- <h3><a name="5.4.1">5.4.1 <code>id</code></a></h3>
+ <h3><a name="5.3.1">5.3.1 <code>id</code></a></h3>
<p>The <code>id</code> specifier specifies that the data member contains
the object id. Every persistent class must have a member designated
@@ -5679,7 +5554,7 @@ private:
<p>In a relational database, an identifier member is mapped to a
primary key.</p>
- <h3><a name="5.4.2">5.4.2 <code>auto</code></a></h3>
+ <h3><a name="5.3.2">5.3.2 <code>auto</code></a></h3>
<p>The <code>auto</code> specifier specifies that the object's identifier
is automatically assigned by the database. Only a member that was
@@ -5707,7 +5582,7 @@ private:
<p>For additional information on the automatic identifier assignment,
refer to <a href="#3.5">Section 3.5, "Making Objects Persistent"</a>.</p>
- <h3><a name="5.4.3">5.4.3 <code>type</code></a></h3>
+ <h3><a name="5.3.3">5.3.3 <code>type</code></a></h3>
<p>The <code>type</code> specifier specifies the native database type
that should be used for the data member. For example:</p>
@@ -5724,7 +5599,7 @@ private:
};
</pre>
- <h3><a name="5.4.4">5.4.4 <code>column</code></a></h3>
+ <h3><a name="5.3.4">5.3.4 <code>column</code></a></h3>
<p>The <code>column</code> specifier specifies the column name
that should be used to store the member in a relational database.
@@ -5750,7 +5625,7 @@ private:
name by removing the common member name decorations, such as leading
and trailing underscores, the <code>m_</code> prefix, etc.</p>
- <h3><a name="5.4.5">5.4.5 <code>transient</code></a></h3>
+ <h3><a name="5.3.5">5.3.5 <code>transient</code></a></h3>
<p>The <code>transient</code> specifier instructs the ODB compiler
not to store the data member in the database. For example:</p>
@@ -5773,7 +5648,7 @@ private:
references that are only meaningful in the application's
memory, as well as utility members such as mutexes, etc.</p>
- <h3><a name="5.4.6">5.4.6 <code>not_null</code></a></h3>
+ <h3><a name="5.3.6">5.3.6 <code>not_null</code></a></h3>
<p>The <code>not_null</code> specifier specifies that the member of
an object pointer or a container of object pointers type cannot
@@ -5802,7 +5677,7 @@ private:
};
</pre>
- <h3><a name="5.4.7">5.4.7 <code>inverse</code></a></h3>
+ <h3><a name="5.3.7">5.3.7 <code>inverse</code></a></h3>
<p>The <code>inverse</code> specifier specifies that the member of
an object pointer or a container of object pointers type is an
@@ -5842,9 +5717,9 @@ private:
information. Only ordered and set containers can be used for
inverse members. If an inverse member is of an ordered container
type, it is automatically marked as unordered (see
- <a href="#5.4.8">Section 5.4.8, "<code>unordered</code>"</a>).</p>
+ <a href="#5.3.8">Section 5.3.8, "<code>unordered</code>"</a>).</p>
- <h3><a name="5.4.8">5.4.8 <code>unordered</code></a></h3>
+ <h3><a name="5.3.8">5.3.8 <code>unordered</code></a></h3>
<p>The <code>unordered</code> specifier specifies that the member of
an ordered container type should be stored in the database unordered.
@@ -5864,7 +5739,7 @@ private:
};
</pre>
- <h3><a name="5.4.9">5.4.9 <code>table</code></a></h3>
+ <h3><a name="5.3.9">5.3.9 <code>table</code></a></h3>
<p>The <code>table</code> specifier specifies the table name that should
be used to store the contents of the container member. For example:</p>
@@ -5895,13 +5770,13 @@ private:
to <a href="#Z.1">Section Z.1, "Composite Value Column and Table
Names"</a> for details.</p>
- <h3><a name="5.4.10">5.4.10 <code>index_type</code></a></h3>
+ <h3><a name="5.3.10">5.3.10 <code>index_type</code></a></h3>
<p>The <code>index_type</code> specifier specifies the native
database type that should be used for the ordered container's
index column of the data member. The semantics of <code>index_type</code>
are similar to that of the <code>type</code> specifier (see
- <a href="#5.4.3">Section 5.4.3, "<code>type</code>"</a>). The native
+ <a href="#5.3.3">Section 5.3.3, "<code>type</code>"</a>). The native
database type is expected to be an integer type. For example:</p>
<pre class="c++">
@@ -5916,13 +5791,13 @@ private:
};
</pre>
- <h3><a name="5.4.11">5.4.11 <code>key_type</code></a></h3>
+ <h3><a name="5.3.11">5.3.11 <code>key_type</code></a></h3>
<p>The <code>key_type</code> specifier specifies the native
database type that should be used for the map container's
key column of the data member. The semantics of <code>key_type</code>
are similar to that of the <code>type</code> specifier (see
- <a href="#5.4.3">Section 5.4.3, "<code>type</code>"</a>). For
+ <a href="#5.3.3">Section 5.3.3, "<code>type</code>"</a>). For
example:</p>
<pre class="c++">
@@ -5937,13 +5812,13 @@ private:
};
</pre>
- <h3><a name="5.4.12">5.4.12 <code>value_type</code></a></h3>
+ <h3><a name="5.3.12">5.3.12 <code>value_type</code></a></h3>
<p>The <code>value_type</code> specifier specifies the native
database type that should be used for the container's
value column of the data member. The semantics of <code>value_type</code>
are similar to that of the <code>type</code> specifier (see
- <a href="#5.4.3">Section 5.4.3, "<code>type</code>"</a>). For
+ <a href="#5.3.3">Section 5.3.3, "<code>type</code>"</a>). For
example:</p>
<pre class="c++">
@@ -5958,14 +5833,14 @@ private:
};
</pre>
- <h3><a name="5.4.13">5.4.13 <code>id_column</code></a></h3>
+ <h3><a name="5.3.13">5.3.13 <code>id_column</code></a></h3>
<p>The <code>id_column</code> specifier specifies the column
name that should be used to store the object id in the
container's table for the member. The semantics of
<code>id_column</code> are similar to that of the
<code>column</code> specifier (see
- <a href="#5.4.4">Section 5.4.4, "<code>column</code>"</a>).
+ <a href="#5.3.4">Section 5.3.4, "<code>column</code>"</a>).
For example:</p>
<pre class="c++">
@@ -5983,14 +5858,14 @@ private:
<p>If the column name is not specified, then <code>object_id</code>
is used by default.</p>
- <h3><a name="5.4.14">5.4.14 <code>index_column</code></a></h3>
+ <h3><a name="5.3.14">5.3.14 <code>index_column</code></a></h3>
<p>The <code>index_column</code> specifier specifies the column
name that should be used to store the element index in the
ordered container's table for the member. The semantics of
<code>index_column</code> are similar to that of the
<code>column</code> specifier (see
- <a href="#5.4.4">Section 5.4.4, "<code>column</code>"</a>).
+ <a href="#5.3.4">Section 5.3.4, "<code>column</code>"</a>).
For example:</p>
<pre class="c++">
@@ -6008,14 +5883,14 @@ private:
<p>If the column name is not specified, then <code>index</code>
is used by default.</p>
- <h3><a name="5.4.15">5.4.15 <code>key_column</code></a></h3>
+ <h3><a name="5.3.15">5.3.15 <code>key_column</code></a></h3>
<p>The <code>key_column</code> specifier specifies the column
name that should be used to store the key in the map
container's table for the member. The semantics of
<code>key_column</code> are similar to that of the
<code>column</code> specifier (see
- <a href="#5.4.4">Section 5.4.4, "<code>column</code>"</a>).
+ <a href="#5.3.4">Section 5.3.4, "<code>column</code>"</a>).
For example:</p>
<pre class="c++">
@@ -6033,14 +5908,14 @@ private:
<p>If the column name is not specified, then <code>key</code>
is used by default.</p>
- <h3><a name="5.4.16">5.4.16 <code>value_column</code></a></h3>
+ <h3><a name="5.3.16">5.3.16 <code>value_column</code></a></h3>
<p>The <code>value_column</code> specifier specifies the column
name that should be used to store the element value in the
container's table for the member. The semantics of
<code>value_column</code> are similar to that of the
<code>column</code> specifier (see
- <a href="#5.4.4">Section 5.4.4, "<code>column</code>"</a>).
+ <a href="#5.3.4">Section 5.3.4, "<code>column</code>"</a>).
For example:</p>
<pre class="c++">
@@ -6058,6 +5933,141 @@ private:
<p>If the column name is not specified, then <code>value</code>
is used by default.</p>
+ <h2><a name="5.4">5.4 C++ Compiler Warnings</a></h2>
+
+ <p>When the C++ header file defining our persistent classes and
+ containing ODB pragmas is processed by a C++ compiler, it
+ may issue warnings about pragmas that it doesn't recognize. There
+ are several ways to deal with this problem. The easiest is to
+ disable such warnings using one of the compiler-specific command
+ line options or warning control pragmas. This method is described
+ in the following sub-section for popular C++ compilers.</p>
+
+ <p>There are also several C++ compiler-independent methods that we
+ can employ. The first is to use the <code>PRAGMA_DB</code> macro,
+ defined in <code>&lt;odb/core.hxx></code>, instead of using
+ <code>#pragma&nbsp;db</code> directly. This macro expands to the
+ ODB pragma when compiled with the ODB compiler and to an empty
+ declaration when compiled with other compilers. The following example
+ shows how we can use this macro:</p>
+
+ <pre class="c++">
+#include &lt;odb/core.hxx>
+
+PRAGMA_DB(object)
+class person
+{
+ ...
+private:
+ PRAGMA_DB(id)
+ unsigned long id_;
+ ...
+};
+ </pre>
+
+ <p>An alternative to using the <code>PRAGMA_DB</code> macro is to
+ group the <code>#pragma&nbsp;db</code> directives in blocks that are
+ conditionally included into compilation only when compiled with the
+ ODB compiler. For example:</p>
+
+ <pre class="c++">
+class person
+{
+ ...
+private:
+ unsigned long id_;
+ ...
+};
+
+#ifdef ODB_COMPILER
+# pragma db object(person)
+# pragma db member(person::id_) id
+#endif
+ </pre>
+
+ <p>The disadvantage of this approach is that it can quickly become
+ overly verbose when positioned pragmas are used.</p>
+
+ <h3><a name="5.4.1">5.4.1 GNU C++</a></h3>
+
+ <p>GNU g++ does not issue warnings about unknown pragmas
+ unless requested with the <code>-Wall</code> command line option.
+ To disable only the unknown pragma warning, we can add the
+ <code>-Wno-unknown-pragmas</code> option after <code>-Wall</code>,
+ for example:</p>
+
+ <pre class="terminal">
+g++ -Wall -Wno-unknown-pragmas ...
+ </pre>
+
+ <h3><a name="5.4.2">5.4.2 Visual C++</a></h3>
+
+ <p>Microsoft Visual C++ issues an unknown pragma warning (C4068) at
+ warning level 1 or higher. This means that unless we have disabled
+ the warnings altogether (level 0), we will see this warning.</p>
+
+ <p>To disable this warning via the compiler command line, we can add
+ the <code>/wd4068</code> C++ compiler option in Visual Studio 2008
+ and earlier. In Visual Studio 2010 there is now a special GUI field
+ where we can enter warning numbers that should be disabled. Simply
+ enter 4068 into this field.</p>
+
+ <p>We can also disable this warning for only a specific header or
+ a fragment of a header using the warning control pragma. For
+ example:</p>
+
+ <pre class="c++">
+#include &lt;odb/core.hxx>
+
+#pragma warning (push)
+#pragma warning (disable:4068)
+
+#pragma db object
+class person
+{
+ ...
+private:
+ #pragma db id
+ unsigned long id_;
+ ...
+};
+
+#pragma warning (pop)
+ </pre>
+
+ <h3><a name="5.4.3">5.4.3 Sun C++</a></h3>
+
+ <p>The Sun C++ compiler does not issue warnings about unknown pragmas
+ unless the <code>+w</code> or <code>+w2</code> option is specified.
+ To disable only the unknown pragma warning we can add the
+ <code>-erroff=unknownpragma</code> option anywhere on the
+ command line, for example:</p>
+
+ <pre class="terminal">
+CC +w -erroff=unknownpragma ...
+ </pre>
+
+ <h3><a name="5.4.4">5.4.4 IBM XL C++</a></h3>
+
+ <p>IBM XL C++ issues an unknown pragma warning (1540-1401) by default.
+ To disable this warning we can add the <code>-qsuppress=1540-1401</code>
+ command line option, for example:</p>
+
+ <pre class="terminal">
+xlC -qsuppress=1540-1401 ...
+ </pre>
+
+ <h3><a name="5.4.5">5.4.5 HP aC++</a></h3>
+
+ <p>HP aC++ (aCC) issues an unknown pragma warning (2161) by default.
+ To disable this warning we can add the <code>+W2161</code>
+ command line option, for example:</p>
+
+ <pre class="terminal">
+aCC +W2161 ...
+ </pre>
+
+
<!-- CHAPTER -->
@@ -6278,13 +6288,13 @@ namespace odb
<p>You will need to include the <code>&lt;odb/mysql/database.hxx></code>
header file to make this class available in your application.</p>
- <p>The overloaded <code>database</code> constructors allow you
+ <p>The overloaded <code>database</code> constructors allow us
to specify MySQL database parameters that should be used when
connecting to the database. In MySQL <code>NULL</code> and an
empty string are treated as the same values for all the
string parameters except <code>password</code> and
<code>socket</code>. The <code>client_flags</code> argument
- allows you to specify various MySQL client library flags. For more
+ allows us to specify various MySQL client library flags. For more
information on the possible values, refer to the MySQL C API
documentation. The <code>CLIENT_FOUND_ROWS</code> flag is always set
by the MySQL ODB runtime regardless of whether it was passed in the
@@ -6303,7 +6313,7 @@ namespace odb
--options-file &lt;file>
</pre>
- <p>The <code>--options-file</code> option allows you to specify some
+ <p>The <code>--options-file</code> option allows us to specify some
or all of the database options in a file with each option appearing
on a separate line followed by space and an option value.</p>
@@ -6323,13 +6333,13 @@ namespace odb
with short descriptions that are recognized by this constructor.</p>
<p>The last argument to all of the constructors is the
- pointer to the connection factory. If you pass a
+ pointer to the connection factory. If we pass a
non-<code>NULL</code> value, the database instance assumes
ownership of the factory instance. The connection factory
interface as well as the available implementations are described
in the next section.</p>
- <p>The set of accessor functions following the constructors allow you
+ <p>The set of accessor functions following the constructors allow us
to query the parameters of the <code>database</code> instance.</p>
<p>The <code>connection()</code> function returns the MySQL database