aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-09-28 21:55:36 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-09-28 21:55:36 +0200
commit62ec38b1821db48dd7250b2cd82a7203ed6ec889 (patch)
treed7fc7e7b01e4e05586894168e784c5b0124a2833
parent9a0c247a8e909e262c8b40ac05650c01307eec66 (diff)
Documentation fixes
-rw-r--r--doc/manual.xhtml270
1 files changed, 135 insertions, 135 deletions
diff --git a/doc/manual.xhtml b/doc/manual.xhtml
index e8ee426..f49bed2 100644
--- a/doc/manual.xhtml
+++ b/doc/manual.xhtml
@@ -424,17 +424,17 @@ for consistency.
data member. </li>
<li>Provide clean and easy to use object-oriented persistence
- model and database APIs that support development of realistic
+ model and database APIs that support the development of realistic
applications for a wide variety of domains.</li>
- <li>Provide portable and thread-safe implementation. ODB should be
+ <li>Provide a portable and thread-safe implementation. ODB should be
written in standard C++ and capable of persisting any standard
C++ classes.</li>
<li>Provide profiles that integrate ODB with type systems of
widely-used frameworks and libraries such as Qt and Boost.</li>
- <li>Provide high-performance and low overhead implementation. ODB
+ <li>Provide a high-performance and low overhead implementation. ODB
should make efficient use of database and application resources.</li>
</ul>
@@ -443,11 +443,11 @@ for consistency.
<h2><a name="0.1">About This Document</a></h2>
<p>The goal of this manual is to provide you with an understanding
- of the object persistence model and APIs as implemented by ODB.
+ of the object persistence model and APIs which are implemented by ODB.
As such, this document is intended for C++ application developers and
software architects who are looking for a C++ object persistence
solution. Prior experience with C++ is required to understand
- this document. Basic understanding of relational database systems
+ this document. A basic understanding of relational database systems
is advantageous but not expected or required.</p>
@@ -495,13 +495,13 @@ for consistency.
database schema, and run native SQL <code>SELECT</code> queries.</p>
<p>ODB is not a framework. It does not dictate how you should write
- your application. Rather it is designed to fit into your
+ your application. Rather, it is designed to fit into your
style and architecture by only handling object persistence
and not interfering with any other functionality. There is
no common base type that all persistent classes should derive
- from nor there are any restrictions on the data member types
+ from nor are there any restrictions on the data member types
in persistent classes. Existing classes can be made persistent
- with little or nor modifications.</p>
+ with a few or no modifications.</p>
<p>ODB has been designed for high performance and low memory
overhead. Prepared statements are used to send and receive
@@ -514,26 +514,26 @@ for consistency.
APIs to reduce overhead and provide the most efficient implementation
for each database operation. Finally, persistent classes have
zero memory overhead. There are no hidden "database" members
- that each class must have nor there are per-object data structures
+ that each class must have nor are there per-object data structures
allocated by ODB.</p>
<p>In this chapter we present a high-level overview of ODB.
We will start with the ODB architecture and then outline the
workflow of building an application that uses ODB. We will
- conclude this chapter by contrasting the drawbacks of
+ conclude the chapter by contrasting the drawbacks of
the traditional way of saving C++ objects to relational
databases with the benefits of using ODB for object
- persistence. The next chapter takes the more hands-on approach
+ persistence. The next chapter takes a more hands-on approach
and shows the concrete steps necessary to implement object
persistence in a simple "Hello World" application.</p>
<h2><a name="1.1">1.1 Architecture and Workflow</a></h2>
<p>From the application developer's perspective, ODB
- consist of three main components: the ODB compiler, the common
+ consists of three main components: the ODB compiler, the common
runtime library, called <code>libodb</code>, and the
database-specific runtime libraries, called
- <code>libodb-&lt;database></code> where &lt;database> is
+ <code>libodb-&lt;database></code>, where &lt;database> is
the name of the database system this runtime
is for, for example, <code>libodb-mysql</code>. For instance,
if the application is going to use the MySQL database for
@@ -574,9 +574,9 @@ for consistency.
the ODB Pragma Language and ODB Query Language. The ODB Pragma
Language is used to communicate various properties of persistent
classes to the ODB compiler by means of special <code>#pragma</code>
- directives embedded in the C++ header files. It controls such aspects
- of the object-relational mapping as names of tables and columns that
- are used for persistent classes and their members or mapping between
+ directives embedded in the C++ header files. It controls aspects
+ of the object-relational mapping such as names of tables and columns
+ that are used for persistent classes and their members or mapping between
C++ types and database types.</p>
<p>The ODB Query Language is an object-oriented database query
@@ -596,7 +596,7 @@ for consistency.
<h2><a name="1.2">1.2 Benefits</a></h2>
<p>The traditional way of saving C++ objects to relational databases
- requires manually writing code that converts between the database
+ requires that you manually write code which converts between the database
and C++ representations of each persistent class. The actions that
such code usually performs include conversion between C++ values and
strings or database types, preparation and execution of SQL queries,
@@ -607,16 +607,16 @@ for consistency.
<li><b>Difficult and time consuming.</b> Writing database conversion
code for any non-trivial application requires extensive
knowledge of the specific database system and its APIs.
- It can also take considerable amount of time to write
+ It can also take a considerable amount of time to write
and maintain. Supporting multi-threaded applications can
complicate this task even further.</li>
<li><b>Suboptimal performance.</b> Optimal conversion often
requires writing large amounts of extra code, such as
parameter binding for prepared statements and caching
- of connections, statements, and buffers. Writing such
- code in an ad-hoc manner is often too difficult and time
- consuming.</li>
+ of connections, statements, and buffers. Writing code
+ like this in an ad-hoc manner is often too difficult
+ and time consuming.</li>
<li><b>Database vendor lock-in.</b> The conversion code is written for
a specific database which makes it hard to switch to another
@@ -637,7 +637,7 @@ for consistency.
<ul class="list">
<li><b>Ease of use.</b> ODB automatically generates database conversion
code from your C++ class declarations and allows you to manipulate
- persistent objects using a simple and thread-safe object-oriented
+ persistent objects using simple and thread-safe object-oriented
database APIs.</li>
<li><b>Concise code.</b> With ODB hiding the details of the underlying
@@ -648,7 +648,7 @@ for consistency.
<li><b>Optimal performance.</b> ODB has been designed for high performance
and low memory overhead. All the available optimization techniques,
such as prepared statements and extensive connection, statement,
- and buffer caching are used to provide the most efficient
+ and buffer caching, are used to provide the most efficient
implementation for each database operation.</li>
<li><b>Database portability.</b> Because the database conversion code
@@ -671,7 +671,7 @@ for consistency.
<p>Overall, ODB provides an easy to use yet flexible and powerful
object-relational mapping (ORM) system for C++. Unlike other
- ORM implementation for C++ that still require you to write
+ ORM implementations for C++ that still require you to write
database conversion or member registration code for each
persistent class, ODB keeps persistent classes purely
declarative. The functional part, the database conversion
@@ -810,10 +810,10 @@ private:
by the database and assigned to the object when it is made
persistent.</p>
- <p>In this example we choose to add an identifier because none of
+ <p>In this example we chose to add an identifier because none of
the existing members could serve the same purpose. However, if
a class already has a member with suitable properties, then it
- is natural to use that member for an identifier. For example,
+ is natural to use that member as an identifier. For example,
if our <code>person</code> class contained some form of personal
identification (SSN in the United States or ID/passport number
in other countries), then we could use that as an id. Or, if
@@ -851,15 +851,15 @@ class person
<p>To compile the <code>person.hxx</code> header we created in the
previous section and generate the support code for the MySQL
- database we invoke the ODB compiler from a terminal (UNIX) or
+ database, we invoke the ODB compiler from a terminal (UNIX) or
a command prompt (Windows):</p>
<pre class="terminal">
odb -d mysql --generate-query person.hxx
</pre>
- <p>We will use MySQL as the database of choice in the reminder of
- this chapter though other supported database systems can be used
+ <p>We will use MySQL as the database of choice in the remainder of
+ this chapter, though other supported database systems can be used
instead.</p>
<p>If you haven't installed the common ODB runtime library
@@ -871,7 +871,7 @@ odb -d mysql --generate-query person.hxx
person.hxx:10:24: fatal error: odb/core.hxx: No such file or directory
</pre>
- <p>To resolve this you will need to specify <code>libodb</code> headers
+ <p>To resolve this you will need to specify the <code>libodb</code> headers
location with the <code>-I</code> preprocessor option, for example:</p>
<pre class="terminal">
@@ -891,8 +891,8 @@ odb -I.../libodb -d mysql --generate-query person.hxx
<code>person-odb.cxx</code> and link the resulting object
file to your application.</p>
- <p>You may be wondering what is the <code>--generate-query</code>
- option for. It instructs the ODB compiler to generate
+ <p>You may be wondering what the <code>--generate-query</code>
+ option is for. It instructs the ODB compiler to generate
optional query support code that we will use later in our
"Hello World" example. Another option that we will find
useful is <code>--generate-schema</code>. This option
@@ -904,18 +904,18 @@ odb -I.../libodb -d mysql --generate-query person.hxx
odb -d mysql --generate-query --generate-schema person.hxx
</pre>
- <p>The database schema file contains SQL statement that creates
+ <p>The database schema file contains SQL statements that creates
tables necessary to store the persistent classes. We will learn
how to use it in the next section.</p>
- <p>If you would like to see the list of all the available ODB compiler
+ <p>If you would like to see a list of all the available ODB compiler
options, refer to the
<a href="http://www.codesynthesis.com/products/odb/doc/odb.xhtml">ODB
Compiler Command Line Manual</a>.</p>
<p>Now that we have the persistent class and the database support
code, the only part that is left is the application code that
- does something useful with all this. But before we move on to
+ does something useful with all of this. But before we move on to
the fun part, let's first learn how to build and run an application
that uses ODB. This way when we have some application code
to try, there are no more delays before we can run it.</p>
@@ -938,8 +938,8 @@ c++ -c person-odb.cxx
</pre>
<p>Similar to the ODB compilation, if you get an error stating that
- a headers in <code>odb/</code> or <code>odb/mysql</code> directory
- in not found, you will need to use the <code>-I</code>
+ a header in <code>odb/</code> or <code>odb/mysql</code> directory
+ is not found, you will need to use the <code>-I</code>
preprocessor option to specify the location of the common ODB runtime
library (<code>libodb</code>) and MySQL ODB runtime library
(<code>libodb-mysql</code>).</p>
@@ -967,10 +967,10 @@ c++ -o driver driver.o person-odb.o -lodb-mysql -lodb
mysql --user=odb_test --database=odb_test &lt; person.sql
</pre>
- <p>The above command will login to a local MySQL server as user
- <code>odb_test</code> without a password and use database
+ <p>The above command will log in to a local MySQL server as user
+ <code>odb_test</code> without a password and use the database
named <code>odb_test</code>. Note that after executing this
- command all data stored in the <code>odb_test</code> database
+ command, all the data stored in the <code>odb_test</code> database
will be deleted.</p>
<p>Once the database schema is ready, we run our application
@@ -1059,7 +1059,7 @@ main (int argc, char* argv[])
<p>Once we are in <code>main()</code>, the first thing we do is create
the MySQL database object. Notice that this is the last line in
<code>driver.cxx</code> that mentions MySQL explicitly; the rest
- of the code works though the common interfaces and is database
+ of the code works through the common interfaces and is database
system-independent. We use the <code>argc</code>/<code>argv</code>
<code>mysql::database</code> constructor which automatically
extract the database parameters, such as login name, password,
@@ -1068,11 +1068,11 @@ main (int argc, char* argv[])
constructors which allow you to pass this information directly
(see <a href="#6.1.2">Section 6.1.2, "MySQL Database Class"</a>).</p>
- <p>Next we create three <code>person</code> objects. Right now they are
+ <p>Next, we create three <code>person</code> objects. Right now they are
transient objects, which means that if we terminate the application
at this point, they will be gone without any evidence of them ever
existing. The next line starts a database transaction. We discuss
- transactions in detail later in this manual. For now all we need
+ transactions in detail later in this manual. For now, all we need
to know is that all ODB database operations must be performed within
a transaction and that a transaction is an atomic unit of work; all
database operations performed within a transaction either succeed
@@ -1086,7 +1086,7 @@ main (int argc, char* argv[])
crashes at this point, there will still be no evidence of our
objects ever existing.</p>
- <p>In our case one more thing happens when we call <code>persist()</code>.
+ <p>In our case, one more thing happens when we call <code>persist()</code>.
Remember that we decided to use database-assigned identifiers for our
<code>person</code> objects. The call to <code>persist()</code> is
where this assignment happens. Once this function returns, the
@@ -1094,8 +1094,8 @@ main (int argc, char* argv[])
<p>After we have persisted our objects, it is time to commit the
transaction and make the changes permanent. Only after the
- <code>commit()</code> function returns successfully are we
- guaranteed that the objects are made persistent. Continuing with
+ <code>commit()</code> function returns successfully, are we
+ guaranteed that the objects are made persistent. Continuing
with the crash example, if our application terminates after
the commit for whatever reason, the objects' state in the
database will remain intact. In fact, as we will discover
@@ -1104,15 +1104,15 @@ main (int argc, char* argv[])
transaction must be committed explicitly with the
<code>commit()</code> call. If the <code>transaction</code>
object leaves scope without the transaction being
- explicitly committed or rolled back, it will be automatically
+ explicitly committed or rolled back, it will automatically be
rolled back. This behavior allows you not to worry about
exceptions being thrown within a transaction; if they
cross the transaction boundary, the transaction will
- be automatically rolled back and all the changes made
+ automatically be rolled back and all the changes made
to the database undone.</p>
<p>After the transaction has been committed, we save the
- objects ids in local variables. We will use them later in this
+ objects' identifiers in local variables. We will use them later in this
chapter to perform other database operations on our persistent
objects. You might have noticed that our <code>person</code>
class doesn't have the <code>id()</code> function that we use
@@ -1138,7 +1138,7 @@ mysql --user=odb_test --database=odb_test &lt; person.sql
objects' state in the database. While we will make our application
more entertaining shortly, for now we can use the <code>mysql</code>
client to examine the database content. It will also give us a feel
- for how the object are stored:</p>
+ for how the objects are stored:</p>
<pre class="terminal">
mysql --user=odb_test --database=odb_test
@@ -1227,7 +1227,7 @@ main (int argc, char* argv[])
<p>Then we begin a new transaction and call the <code>query()</code>
database function. We pass a query expression
(<code>query::age > 30</code>) which limits the returned objects
- only to those with age greater than 30. We also save the result
+ only to those with the age greater than 30. We also save the result
of the query in a local variable.</p>
<p>The next few lines perform a standard for-loop iteration
@@ -1244,7 +1244,7 @@ Hello, Jane!
</pre>
- <p>That looks about right but how do we know that the query actually
+ <p>That looks about right, but how do we know that the query actually
used the database instead of just using some in-memory artifacts of
the earlier <code>persist()</code> calls? One way to test this
would be to comment out the first transaction in our application
@@ -1288,8 +1288,8 @@ Hello, John (7)!
Hello, Jane (8)!
</pre>
- <p>The identifiers 3, 6, and 9 that miss from the above list belong to
- the "Joe Dirt" objects which are not selected by this query.</p>
+ <p>The identifiers 3, 6, and 9 that are missing from the above list belong
+ to the "Joe Dirt" objects which are not selected by this query.</p>
<h2><a name="2.6">2.6 Updating Persistent Objects</a></h2>
@@ -1376,8 +1376,8 @@ Hello, Joe!
</pre>
<p>What if we didn't have an identifier for Joe? Maybe this object
- was made persisted in another run of our application or by another
- application altogether. Provided that we have only one Joe Dirt
+ was made persistent in another run of our application or by another
+ application altogether. Provided that we only have one Joe Dirt
in the database, we can use the query facility to come up with
an alternative implementation of the above transaction:</p>
@@ -1422,7 +1422,7 @@ Hello, Joe!
<p>To delete John from the database we start a transaction, call
the <code>erase()</code> database function with John's object
- id, and commit the transaction. After the transaction is committed
+ id, and commit the transaction. After the transaction is committed,
the erased object is no longer persistent.</p>
<p>If we don't have an object id handy, we can use queries to find
@@ -1485,7 +1485,7 @@ Hello, Joe!
start with basic concepts and terminology in <a href="#3.1">Section 3.1</a>
and continue with the discussion of the <code>odb::database</code>
class in <a href="#3.2">Section 3.2</a> and transactions in
- <a href="#3.3">Section 3.3</a>. The reminder of this chapter
+ <a href="#3.3">Section 3.3</a>. The remainder of this chapter
deals with the core database operations and concludes with
the discussion of ODB exceptions.</p>
@@ -1500,9 +1500,9 @@ Hello, Joe!
a software implementation for managing this data (for example
MySQL), and, finally, some database software implementations
may manage several data stores which are usually distinguished
- by name. This name is also commonly referred to as database.</p>
+ by name. This name is also commonly referred to as a database.</p>
- <p>In this manual, when we use just the word <em>database</em>, we
+ <p>In this manual, when we use the word <em>database</em>, we
refer to the first meaning above, for example,
"The <code>update()</code> function saves the object's state to
the database." The term Database Management System (DBMS) is
@@ -1538,22 +1538,22 @@ Hello, Joe!
and <em>object class</em> interchangeably. In contrast,
a value type can be a fundamental C++ type, such as
<code>int</code> or a class type, such as <code>std::string</code>.
- If a value consists of other values then is is called a
+ If a value consists of other values, then it is called a
<em>composite value</em> and its type &mdash; a
- <em>composite value type</em>. Otherwise the the value is
+ <em>composite value type</em>. Otherwise, the value is
called <em>simple value</em> and its type &mdash; a
<em>simple value type</em>. Note that the distinction between
simple and composite values is conceptual rather than
representational. For example, <code>std::string</code>
is a simple value type because conceptually string is a
single value even though the representation of the string
- class may contain several data member each of which could be
+ class may contain several data members each of which could be
considered a value. In fact, the same value type can be
viewed (and mapped) as both simple and composite by different
applications.</p>
<p>Seeing how all these concepts map to the relational model
- will hopefully make these distinctions more clear. In a relational
+ will hopefully make these distinctions clearer. In a relational
database an object type is mapped to a table and a value type is
mapped to one or more columns. A simple value type is mapped
to a single column while a composite value type is mapped to
@@ -1567,8 +1567,8 @@ Hello, Joe!
members: year, month, and day. In one application it can be
considered a composite value and each member will get its
own column in a relational database. In another application
- it can considered a simple value and stored in a single
- column as a number of day from some predefined date.</p>
+ it can be considered a simple value and stored in a single
+ column as a number of days from some predefined date.</p>
<p>Until now, we have been using the term <em>persistent class</em>
to refer to object classes. We will continue to do so even though
@@ -1613,7 +1613,7 @@ Hello, Joe!
the database-related properties of a class and its
members (see <a href="#5">Chapter 5, "ODB Pragma Language"</a>).</p>
- <p>You may be wondering whether we also have to do declare value types
+ <p>You may be wondering whether we also have to declare value types
as persistent. We don't need to do anything special for simple value
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
@@ -1631,10 +1631,10 @@ Hello, Joe!
a person, which is a real-world entity. Name and age, which we
used as data members in our <code>person</code> class are clearly
values. It is hard to think of age 31 or name "Joe" as having their
- own identity.</p>
+ own identities.</p>
<p>A good test to determine whether something is an object or
- a value is to consider if other objects might reference
+ a value, is to consider if other objects might reference
it. A person is clearly an object because it can be referred
to by other objects such as a spouse, an employer, or a
bank. On the other hand, a person's age or name is not
@@ -1644,7 +1644,7 @@ Hello, Joe!
choose a suitable object id. For example, for a
person there is an established notion of an identifier
(SSN, student id, passport number, etc). Another alternative
- is to use person's email address as an identifier.</p>
+ is to use a person's email address as an identifier.</p>
<p>Note, however, that these are only guidelines. There could
be good reasons to make something that would normally be
@@ -1652,14 +1652,14 @@ Hello, Joe!
stores a vast number of people. Many of the <code>person</code>
objects in this database have the same names and surnames and
the overhead of storing them in every object may negatively
- affect the performance. In this case we could make first name
+ affect the performance. In this case, we could make the first name
and last name each an object and only store references to
these objects in the <code>person</code> class.</p>
<p>An instance of a persistent class can be in one of two states:
<em>transient</em> and <em>persistent</em>. A transient
instance only has a representation in the application's
- memory and will cease to exist when the application terminates
+ memory and will cease to exist when the application terminates,
unless it is explicitly made persistent. In other words, a
transient instance of a persistent class behaves just like an
instance of any ordinary C++ class. A persistent instance
@@ -1706,7 +1706,7 @@ Hello, Joe!
<p>The <code>odb::database</code> interface defines functions for
starting transactions and manipulating persistent objects.
- These are discussed in detail in the reminder of this chapter
+ These are discussed in detail in the remainder of this chapter
as well as the next chapter which is dedicated to the topic of
querying the database for persistent objects. For details on the
system-specific <code>database</code> classes, refer to
@@ -1740,7 +1740,7 @@ Hello, Joe!
<p>By isolation we mean that the changes made to the database
state during a transaction are only visible inside this
transaction until and unless it is committed. Using the
- above example with bank transfer, the results of the
+ above example with the bank transfer, the results of the
debit operation performed on the first object is not
visible to other transactions until the credit operation
is successfully completed and the transaction is committed.</p>
@@ -1792,7 +1792,7 @@ namespace odb
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
- transactions, the <code>odb::transaction_already_finalized</code>
+ transaction, the <code>odb::transaction_already_finalized</code>
exception is thrown.</p>
<p>The <code>database()</code> function returns the database this
@@ -1803,7 +1803,7 @@ namespace odb
You 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 transaction access or modify more than one object
+ <p>If two or more transactions access or modify more than one object
and are executed concurrently by different applications or by
different threads within the same application, then it is possible
that these transactions will try to access objects in an incompatible
@@ -1814,7 +1814,7 @@ namespace odb
At the same time the second transaction has modified <code>object2</code>
and is waiting for the first transaction to commit its changes to
<code>object1</code> because it also needs to modify <code>object1</code>.
- As a result none of the two transactions can complete.</p>
+ As a result, none of the two transactions can be completed.</p>
<p>The database system detects such situations and automatically
aborts the waiting operation in one of the deadlocked transactions.
@@ -1842,14 +1842,14 @@ for (;;)
</pre>
<p>Note that in the above discussion of atomicity, consistency,
- isolation, and durability, all of these guarantees only apply
+ isolation, and durability, all of those guarantees only apply
to the object's state in the database as opposed to the object's
state in the application's memory. It is possible to roll
a transaction back but still have changes from this
transaction in the application's memory. An easy way to
avoid this potential inconsistency is to instantiate
persistent objects only within the transaction scope. Consider,
- for example, this two implementations of the same transaction:</p>
+ for example, these two implementations of the same transaction:</p>
<pre class="c++">
void
@@ -1887,7 +1887,7 @@ update_age (database&amp; db, unsigned long id)
<p>Of course, it may not always be possible to write the
application in this style. Oftentimes we need to access and
- modify application's state of persistent objects out of
+ modify the application's state of persistent objects out of
transactions. In this case it may make sense to try to
roll back the changes made to the application state if
the transaction was rolled back and the database state
@@ -1952,7 +1952,7 @@ update_age (database&amp; db, person&amp; p)
number of objects persisted does not exceed the value space of
the id type.</p>
- <p>When calling the <code>persist()</code> functions we don't need to
+ <p>When calling the <code>persist()</code> functions, we don't need to
explicitly specify the template type since it will be automatically
deduced from the argument being passed. The <code>odb::object_traits</code>
template used in the signature above is part of the database support
@@ -2049,7 +2049,7 @@ t.commit ();
find the object (or objects) matching some criteria (see
<a href="#4">Chapter 4, "Querying the Database"</a>). Note,
however, that loading an object's state using its
- identifier can be significantly faster that executing a query.</p>
+ identifier can be significantly faster than executing a query.</p>
<h2><a name="3.6">3.6 Updating Persistent Objects</a></h2>
@@ -2167,7 +2167,7 @@ namespace odb
}
</pre>
- <p>Catching this exception guarantees that you will catch all
+ <p>Catching this exception guarantees that you 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>
@@ -2226,7 +2226,7 @@ namespace odb
}
</pre>
- <p>The first four exception (<code>already_in_transaction</code>,
+ <p>The first four exceptions (<code>already_in_transaction</code>,
<code>not_in_transaction</code>,
<code>transaction_already_finalized</code>, and
<code>deadlock</code>) are thrown by the
@@ -2277,7 +2277,7 @@ namespace odb
explicitly request the generation of the necessary database support
code with the <code>--generate-query</code> ODB compiler option.</p>
- <p>ODB provides flexible query API that offers two distinct levels of
+ <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
object-oriented query language, called ODB Query Language. This
@@ -2313,7 +2313,7 @@ namespace odb
query q ("first = 'John' AND age = " + query::_ref (age));
</pre>
- <p>Note that at this level you loose the static typing of
+ <p>Note that at this level you lose the static typing of
query expressions. For example, if we wrote something like this:</p>
<pre class="c++">
@@ -2331,7 +2331,7 @@ namespace odb
</pre>
<p>It would compile fine and would trigger an error only when executed
- by the the database system.</p>
+ by the database system.</p>
<p>You can also combine the two query languages in a single query, for
example:</p>
@@ -2343,10 +2343,10 @@ namespace odb
<h2><a name="4.1">4.1 ODB Query Language</a></h2>
- <p>An ODB query is an expression that tell the database system whether
- any given object matches the desired criteria. As such a query expression
- always evaluates to <code>true</code> or <code>false</code>. At
- the higher lever, an expression consist of other expressions
+ <p>An ODB query is an expression that tells the database system whether
+ any given object matches the desired criteria. As such, a query expression
+ always evaluates as <code>true</code> or <code>false</code>. At
+ the higher level, an expression consists of other expressions
combined with logical operators such as <code>&amp;&amp;</code> (AND),
<code>||</code> (OR), and <code>!</code> (NOT). For example:</p>
@@ -2439,10 +2439,10 @@ namespace odb
</tr>
</table>
- <p>The <code>in()</code> function accepts maximum of five arguments.
+ <p>The <code>in()</code> function accepts a maximum of five arguments.
Use the <code>in_range()</code> function if you need to compare
to more than five values. This function accepts a pair of
- standard C++ iterators and compares to all the value from
+ standard C++ iterators and compares to all the values from
the <code>begin</code> position inclusive and until and
excluding the <code>end</code> position. The following
code fragment shows how we can use these functions:</p>
@@ -2483,7 +2483,7 @@ namespace odb
is copied from the C++ variable to the query instance at the query
construction time. On the other hand, if a parameter is bound by
reference, then the query instance stores a reference to the
- bound variable. The actual value for the parameter is only extracted
+ bound variable. The actual value of the parameter is only extracted
at the query execution time. Consider, for example, the following
two queries:</p>
@@ -2503,7 +2503,7 @@ namespace odb
<code>_val()</code> and <code>_ref()</code>, that allow you 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 semantics is used by default. In the
+ explicitly, the value semantic is used by default. In the
native query language, binding must always be specified
explicitly. For example:</p>
@@ -2519,7 +2519,7 @@ namespace odb
<p>A query that only has by-value parameters does not depend on any
other variables and is self-sufficient once constructed. A query
- that has one or more by-reference parameter depends on the
+ 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
undefined.</p>
@@ -2541,16 +2541,16 @@ namespace odb
query (const odb::query&lt;T>&amp;, bool cache = true);
</pre>
- <p>The first <code>query()</code> function is used to return all
+ <p>The first <code>query()</code> function is used to return all the
persistent objects of a given type stored in the database.
- The second functions uses the passed query instance to only return
+ The second function uses the passed query instance to only return
objects matching the query criteria. The <code>cache</code> argument
- determines whether the object states should be cached in the
+ determines whether the objects' states should be cached in the
application's memory or if they should be returned by the database
system one by one as the iteration over the result progresses. The
result caching is discussed in detail in the next section.</p>
- <p>When calling the <code>query()</code> function we have to
+ <p>When calling the <code>query()</code> function, we have to
explicitly specify the object type we are querying. For example:</p>
<pre class="c++">
@@ -2607,9 +2607,9 @@ result r (find_underage (db, query::first == "John"));
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
- another. The result instance is only usable within a transaction
+ another. The result instance is only usable within the transaction
it was created in. Trying to manipulate the result after the
- transaction has terminates leads to undefined behavior.</p>
+ transaction has terminated leads to undefined behavior.</p>
<p>The <code>odb::result</code> class template conforms to the
standard C++ sequence requirements and has the following
@@ -2665,7 +2665,7 @@ namespace odb
cache the result at a later stage if it wasn't already
cached during query execution.</p>
- <p>If result is cached, the entire state of the returned
+ <p>If the result is cached, the database state of all the returned
objects is stored in the application's memory. Note that
the actual objects are still only instantiated on demand
during result iteration. It is the raw database state that
@@ -2673,7 +2673,7 @@ namespace odb
the object's state is sent by the database system one object
at a time as the iteration progresses.</p>
- <p>Uncached results can improve performance of both the application
+ <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
a small portion of the returned objects. However, uncached
@@ -2681,7 +2681,7 @@ namespace odb
uncached result in a transaction. Creating another result
(cached or uncached) by calling <code>database::query()</code>
will invalidate the existing uncached result. Furthermore,
- executing any other database function, such as <code>update()</code>
+ calling any other database functions, such as <code>update()</code>
or <code>erase()</code> will also invalidate the uncached result.</p>
<p>The <code>empty()</code> function returns <code>true</code> if
@@ -2766,8 +2766,8 @@ namespace odb
<p>The overloaded <code>result_iterator::load()</code> functions are
similar to <code>database::load()</code>. The first function
returns a dynamically allocated instance of the current
- object which you are responsible for deleting. As an optimization,
- if the iterator already owns an object as a result of an earlier
+ object. As an optimization, if the iterator already owns an object
+ 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
@@ -2816,7 +2816,7 @@ namespace odb
language to capture database-specific information about C++ types.
This chapter describes the ODB pragma language in more detail. It
can be read together with other chapters in the manual to get a
- sense of what kind configurations and mapping fine-tuning are
+ sense of what kind of configurations and mapping fine-tuning are
possible. You can also use this chapter as a reference at a later
stage.</p>
@@ -2824,11 +2824,11 @@ namespace odb
<p><code>#pragma db <i>qualifier</i> [<i>specifier</i> <i>specifier</i> ...]</code></p>
- <p>The <em>qualifier</em> tell the ODB compiler what kind of C++ construct
+ <p>The <em>qualifier</em> tells the ODB compiler what kind of C++ construct
this pragma describes. Valid qualifiers are <code>object</code>,
<code>value</code>, and <code>member</code>. Pragmas with the
<code>object</code> qualifier describe persistent object types.
- It tells the ODB compiler that a C++ class it describe is a
+ It tells the ODB compiler that the C++ class it describes is a
persistent class. Similarly, pragmas with the <code>value</code>
qualifier describes value types and the <code>member</code>
qualifier is used to describe data members of persistent object
@@ -2836,7 +2836,7 @@ namespace odb
<p>The <em>specifier</em> informs the ODB compiler about a particular
database-related property of the C++ declaration. For example, the
- <code>id</code> member specifier tell the ODB compiler that this
+ <code>id</code> member specifier tells the ODB compiler that this
member contains this object's identifier. Below is the declaration
of the <code>person</code> class that shows how we can use ODB
pragmas:</p>
@@ -2857,7 +2857,7 @@ private:
data member the pragma belongs to. Rather, the pragma applies to
a C++ declaration that immediately follows the pragma. Such pragmas
are called <em>positioned pragmas</em>. In positioned pragmas that
- apply to data members the <code>member</code> qualifier can be
+ apply to data members, the <code>member</code> qualifier can be
omitted for brevity, for example:</p>
<pre class="c++">
@@ -2947,7 +2947,7 @@ private:
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 most popular C++ compiler.</p>
+ in the following sub-section for popular C++ compilers.</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,
@@ -2971,7 +2971,7 @@ private:
};
</pre>
- <p>The alternative to using the <code>PRAGMA_DB</code> macro is to
+ <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>
@@ -2998,7 +2998,7 @@ private:
<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
+ To disable only the unknown pragma warning, you can add the
<code>-Wno-unknown-pragmas</code> option after <code>-Wall</code>,
for example:</p>
@@ -3010,7 +3010,7 @@ g++ -Wall -Wno-unknown-pragmas ...
<p>Microsoft Visual C++ issues an unknown pragma warning (C4068) at
warning level 1 or higher. This means that unless you have disabled
- warnings altogether (level 0), you will see this warning.</p>
+ 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
@@ -3018,7 +3018,7 @@ g++ -Wall -Wno-unknown-pragmas ...
where you can enter warning numbers that should be disabled. Simply
enter 4068 into this field.</p>
- <p>You can also disable this warning only for a specific header or
+ <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>
@@ -3119,7 +3119,7 @@ private:
<p>In the above example we changed the mapping for the <code>bool</code>
type which is now mapped to the <code>INT</code> database type. In
- this case the <code>value</code> pragma is all that is necessary
+ this case, the <code>value</code> pragma is all that is necessary
since the ODB compiler will be able to figure out how to store
a boolean value as an integer in the database. However, there
could be situations where the ODB compiler will not know how to
@@ -3131,7 +3131,7 @@ private:
#pragma db value(bool) type("VARCHAR(5) NOT NULL")
</pre>
- <p>The possible database value for the C++ <code>true</code> value could
+ <p>The possible database values for the C++ <code>true</code> value could
be <code>"true"</code>, or <code>"TRUE"</code>, or <code>"True"</code>.
Or, maybe, all of the above are valid. The ODB compiler has no way
of knowing how your application wants to convert <code>bool</code>
@@ -3139,7 +3139,7 @@ private:
ODB allows you to provide your own database conversion functions
by specializing the <code>value_traits</code> class template. The
<code>mapping</code> example in the <code>odb-examples</code>
- package shows how to do this for all supported database systems.</p>
+ package shows how to do this for all the supported database systems.</p>
<p>It is also possible to change the database type mapping for individual
members, as described in <a href="#5.4">Section 5.4, "Data Member
@@ -3234,7 +3234,7 @@ private:
<p>Note that automatically-assigned object ids are not reused.
If you have a high object turnover (that is, objects are routinely
made persistent and then erased), then care must be taken not to
- run out of object ids. In such situations using
+ run out of object ids. In such situations, using
<code>unsigned long long</code> as the identifier type is a safe
choice.</p>
@@ -3261,9 +3261,9 @@ private:
<p>The behavior of this specifier for members is similar to that
for value types. The only difference is the scope. The value
type pragma applies to all members with this value type that
- don't have their own <code>type</code> specifiers. While the
+ don't have their own <code>type</code> specifiers, while the
member pragma applies only to a single member. For more
- information on the semantics of this specifier refer to
+ information on the semantics of this specifier, refer to
<a href="#5.3">Section 5.3, "Value Type Pragmas"</a>.</p>
<h3><a name="5.4.4">5.4.4 <code>column</code></a></h3>
@@ -3428,7 +3428,7 @@ private:
differently depending on whether the member of this type
is an object id or not. If the member is an object id,
then for this member <code>std::string</code> is mapped
- to <code>VARCHAR(255) NOT NULL</code> MySQL type. Otherwise
+ to <code>VARCHAR(255) NOT NULL</code> MySQL type. Otherwise,
it is mapped to <code>TEXT NOT NULL</code>.</p>
<h3><a name="6.1.2">6.1.2 MySQL Database Class</a></h3>
@@ -3534,7 +3534,7 @@ namespace odb
<p>The overloaded <code>database</code> constructors allow you
to specify MySQL database parameters that should be used when
- connecting to the database. In MySQL <code>NULL</code> and
+ 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
@@ -3583,13 +3583,13 @@ namespace odb
interface as well as the available implementations are described
in the next section.</p>
- <p>The set of accessor function following the constructors allows you
+ <p>The set of accessor functions following the constructors allow you
to query the parameters of the <code>database</code> instance.</p>
<p>The <code>connection()</code> function returns the MySQL database
connection encapsulated by the <code>odb::mysql::connection</code>
class. Normally, you wouldn't call this function directly and
- instead let the ODB runtime manage database connections. However,
+ instead let the ODB runtime manage the database connections. However,
if for some reason you need to access the underlying MySQL connection
handle, refer to the MySQL ODB runtime source code for the interface
of the <code>connection</code> class.</p>
@@ -3634,7 +3634,7 @@ namespace odb
<p>The <code>new_connection_factory</code> class creates a new
connection whenever one is requested. When a connection is no
- longer needed it is released and closed. The
+ longer needed, it is released and closed. The
<code>connection_pool_factory</code> class implements a
connection pool. It has the following interface:</p>
@@ -3652,7 +3652,7 @@ namespace odb
</pre>
<p>The <code>max_connections</code> argument specifies the maximum
- number of concurrent connections this pool factory will
+ number of concurrent connections that this pool factory will
maintain. Similarly, the <code>min_connections</code> argument
specifies the minimum number of available connections that
should be kept open.</p>
@@ -3663,7 +3663,7 @@ namespace odb
<code>max_connections</code> value to see if a new connection
can be created. If the total number of connections maintained
by the pool is less than this value, then a new connection is
- created and returned. Otherwise the calling thread is blocked
+ created and returned. Otherwise, the calling thread is blocked
until a connection becomes available.</p>
<p>When a connection is released, the pool factory first checks
@@ -3671,16 +3671,16 @@ namespace odb
one of them is unblocked and is given the connection. Otherwise,
the pool factory checks whether the total number of connections
maintained by the pool is greater than the <code>min_connections</code>
- value. If that's the case, the connection is closed. Otherwise the
+ value. If that's the case, the connection is closed. Otherwise, the
connection is added to the pool of available connections to be
returned on the next request. In other words, if the number of
connections maintained by the pool exceeds the <code>min_connections</code>
number and there are no threads waiting for a new connection,
then the pool will close the excess connections.</p>
- <p>If <code>max_connections</code> value is 0 then the pool will
+ <p>If the <code>max_connections</code> value is 0, then the pool will
create a new connection whenever all of the existing connections
- are in use. If the <code>min_connections</code> value is 0 then
+ are in use. If the <code>min_connections</code> value is 0, then
the pool will never close a connection and instead maintain all
the connections that were ever created.</p>
@@ -3751,13 +3751,13 @@ namespace odb
a MySQL database operation fails. The MySQL-specific error
information is accessible via the <code>error()</code>,
<code>sqlstate()</code>, and <code>message()</code> functions.
- All this information is also combined and returned in
+ All this information is also combined and returned in a
human-readable form by the <code>what()</code> function.</p>
<p>The <code>odb::mysql::cli_exception</code> is thrown by the
command line parsing constructor of the <code>odb::mysql::database</code>
class if the MySQL option values are missing or invalid. The
- <code>what()</code> function provides human-readable description
+ <code>what()</code> function returns a human-readable description
of an error.</p>
</div>