From 9825b7b79eb73c5cfdd1bb1daa66dc6a699de7e5 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 17 Jan 2011 15:15:59 +0200 Subject: Cosmetic manual changes --- doc/manual.xhtml | 628 ++++++++++++++++++++++++++++--------------------------- 1 file 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. 5ODB Pragma Language - - - - -
5.1C++ Compiler Warnings + 5.1Object Type Pragmas - - - - - + +
5.1.1GNU C++
5.1.2Visual C++
5.1.3Sun C++
5.1.4IBM XL C++
5.1.5HP aC++
5.1.1table
5.1.2pointer
5.2Object Type Pragmas + 5.2Value Type Pragmas - - + + + + + + + + + +
5.2.1table
5.2.2pointer
5.2.1type
5.2.2not_null
5.2.3unordered
5.2.4index_type
5.2.5key_type
5.2.6value_type
5.2.7id_column
5.2.8index_column
5.2.9key_column
5.2.10value_column
5.3Value Type Pragmas + 5.3Data Member Pragmas - - - - - - - - - - + + + + + + + + + + + + + + + +
5.3.1type
5.3.2not_null
5.3.3unordered
5.3.4index_type
5.3.5key_type
5.3.6value_type
5.3.7id_column
5.3.8index_column
5.3.9key_column
5.3.10value_column
5.3.1id
5.3.2auto
5.3.3type
5.3.4column
5.3.5transient
5.3.6not_null
5.3.7inverse
5.3.8unordered
5.3.9table
5.3.10index_type
5.3.11key_type
5.3.12value_type
5.3.13id_column
5.3.14index_column
5.3.15key_column
5.3.16value_column
5.4Data Member Pragmas + 5.4C++ Compiler Warnings - - - - - - - - - - - - - - - - + + + + +
5.4.1id
5.4.2auto
5.4.3type
5.4.4column
5.4.5transient
5.4.6not_null
5.4.7inverse
5.4.8unordered
5.4.9table
5.4.10index_type
5.4.11key_type
5.4.12value_type
5.4.13id_column
5.4.14index_column
5.4.15key_column
5.4.16value_column
5.4.1GNU C++
5.4.2Visual C++
5.4.3Sun C++
5.4.4IBM XL C++
5.4.5HP aC++
@@ -797,7 +796,7 @@ private: of core ODB declarations, such as odb::access, that are used to define persistent classes.

-

The second change is the addition of db object +

The second change is the addition of db object 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 - db id auto pragma that precedes the id_ + db id auto pragma that precedes the id_ member tells the ODB compiler that the following member is the object's identifier. The auto specifier indicates that it is a database-assigned id. A unique id will be automatically generated @@ -1641,8 +1640,8 @@ class person

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 int or std::string 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 db type pragma (Section - 5.3.1, "type"). Similar to object types, composite + this refer to the db type pragma (Section + 5.2.1, "type"). Similar to object types, composite value types have to be explicitly declared as persistent using the db value pragma, for example:

@@ -1770,11 +1769,11 @@ class name with the sharing semantics, such as shared_ptr mentioned previously, as object pointers.

-

ODB provides two mechanisms for changing the object pointer type. You +

ODB provides two mechanisms for changing the object pointer type. We can use the --default-pointer option to specify the alternate default object pointer type. All objects that don't have the object pointer explicitly specified with the - db pointer pragma (see below) will use the default + db pointer pragma (see below) will use the default pointer type. Refer to the ODB Compiler Command Line Manual for details on this option's argument. @@ -1784,8 +1783,8 @@ class name --default-pointer std::tr1::shared_ptr -

The second mechanism allows you to specify the object pointer on - an object by object basis using the db pointer +

The second mechanism allows us to specify the object pointer on + an object by object basis using the db pointer pragma, for example:

@@ -1796,7 +1795,7 @@ class person
 };
   
-

Refer to Section 5.2.2, "pointer" +

Refer to Section 5.1.2, "pointer" for more information on this pragma.

Built-in support, provided by the ODB runtime, library allows us to use @@ -1813,10 +1812,10 @@ class person

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, odb::mysql::database - 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 finalized, that is, explicitly committed or rolled back, the destructor of the odb::transaction 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 odb::transaction_already_finalized exception is thrown.

@@ -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 odb::not_in_transaction 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 has_current() static function.

If two or more transactions access or modify more than one object @@ -2095,7 +2094,7 @@ update_age (database& db, person& p)

The first persist() 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 (Section 5.4.2, + application-assigned object ids (Section 5.3.2, "auto").

The second and third persist() versions are similar to the @@ -2369,7 +2368,7 @@ namespace odb } -

Catching this exception guarantees that you will catch all the +

Catching this exception guarantees that we will catch all the exceptions thrown by ODB. The what() function returns a human-readable description of the condition that triggered the exception.

@@ -2460,7 +2459,7 @@ namespace odb

The null_pointer exception is thrown when a pointer to a persistent object declared non-NULL - with the db not_null pragma has the NULL + with the db not_null pragma has the NULL value. See Chapter Y, "Relationships" for details.

The next three exceptions (already_in_transaction, @@ -2528,7 +2527,7 @@ namespace odb container types as discussed later in Section X.4, "Using Custom Containers".

-

You don't need to do anything special to declare a member of a +

We don't need to do anything special to declare a member of a container type in a persistent class. For example:

@@ -2637,7 +2636,7 @@ private:
      (called index), and the value column of type
      std::string (called value).

-

A number of ODB pragmas allow you to customize the table name, +

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 Chapter 5, "ODB Pragma @@ -2730,7 +2729,7 @@ private: (called object_id) and the value column of type std::string (called value).

-

A number of ODB pragmas allow you to customize the table name, +

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 Chapter 5, "ODB Pragma @@ -2795,7 +2794,7 @@ private: unsigned short (called key), and the value column of type std::string (called value).

-

A number of ODB pragmas allow you to customize the table name, +

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 Chapter 5, "ODB Pragma @@ -2878,7 +2877,7 @@ private: Section Y.4, "Using Custom Smart Pointers". 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 weak_ptr if the object pointer + For example, we can use weak_ptr if the object pointer is shared_ptr.

When an object containing a pointer to another object is loaded, @@ -3277,7 +3276,7 @@ CREATE TABLE employee ( of these references.

To eliminate redundant database schema references we can use the - inverse pragma (Section 5.4.7, + inverse pragma (Section 5.3.7, "inverse") 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:

@@ -3321,7 +3320,7 @@ CREATE TABLE employee ( pointer. Also note that an ordered container (Section X.1, "Ordered Containers") of pointers that is an inverse side of a bidirectional relationship is always treated as unordered - (Section 5.4.8, "unordered") + (Section 5.3.8, "unordered") 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).

@@ -3863,7 +3862,7 @@ t.commit ();

Composite value type is a class or struct type that is mapped to more than one database column. To declare - a composite value type we use the db value pragma, + a composite value type we use the db value pragma, for example:

@@ -3993,7 +3992,7 @@ t.commit ();
 
   

Customizing a column name for a data member of a simple value type is straightforward: we simply specify the desired name with - the db column pragma (@@ ref). For composite value + the db column pragma (@@ ref). For composite value types things are slightly more complicated since it is mapped to multiple columns. Consider the following example:

@@ -4034,7 +4033,7 @@ CREATE TABLE person (

We can customize both the prefix and the suffix using the - db column pragma as shown in the following + db column pragma as shown in the following example:

@@ -4093,8 +4092,8 @@ CREATE TABLE person (
 
   

The same principal applies when a composite value type is used as an element of a container, except that instead of - db column either the db value_column - (@@ ref) or db key_column (@@ ref) pragmas are used to + db column either the db value_column + (@@ ref) or db key_column (@@ ref) pragmas are used to specify the column prefix.

When a composite value type contains a container, an extra table @@ -4138,7 +4137,7 @@ CREATE TABLE person (

To customize the container table name we can use the - db table (@@ ref) pragma, for example:

+ db table (@@ ref) pragma, for example:

 #pragma db value
@@ -4275,7 +4274,7 @@ namespace odb
   

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 odb::already_in_session exception. The destructor clears the current session for this thread if this @@ -4283,11 +4282,11 @@ namespace odb

The static current() accessor returns the currently active session for this thread. If there is no active session, this function - throws the odb::not_in_session exception. You can check + throws the odb::not_in_session exception. We can check whether there is a session in effect in this thread using the has_current() static function.

-

The static current() modifier allows you to set the +

The static current() modifier allows us to set the current session for this thread. The reset_current static function clears the current session. These two functions allow for more advanced use cases, such as multiplexing @@ -4361,18 +4360,18 @@ t.commit ();

4 Querying the Database

-

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 +

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 --generate-query ODB compiler option.

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:

@@ -4403,7 +4402,7 @@ t.commit (); query q ("first = 'John' AND age = " + query::_ref (age));
-

Note that at this level you lose the static typing of +

Note that at this level we lose the static typing of query expressions. For example, if we wrote something like this:

@@ -4423,7 +4422,7 @@ t.commit ();
   

It would compile fine and would trigger an error only when executed by the database system.

-

You can also combine the two query languages in a single query, for +

We can also combine the two query languages in a single query, for example:

@@ -4447,7 +4446,7 @@ t.commit ();
 
   

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 query::first above. The names of members in the query 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 ();

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:

@@ -4589,7 +4588,7 @@ t.commit ();

The odb::query class provides two special functions, - _val() and _ref(), that allow you to + _val() and _ref(), 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.

4.3 Executing a Query

@@ -4661,7 +4660,7 @@ t.commit (); result r1 (db.query<person> (query::first == "John"));
-

Normally you would create a named query instance if you are +

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.

@@ -4692,7 +4691,7 @@ result r (find_underage (db, query::first == "John"));

It is best to view an instance of odb::result - 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 database::query() function caches the result unless instructed not to by the caller. - The cache() function allows you to + The cache() function allows us to cache the result at a later stage if it wasn't already cached during query execution.

@@ -4763,8 +4762,8 @@ namespace odb at a time as the iteration progresses.

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

The empty() function returns true if there are no objects in the result and false otherwise. The size() 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 odb::result_not_cached exception is thrown.

@@ -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.

+ is over. Instead, we would need to store the object itself.

The result iterator has the following dereference functions that can be used to access the pointed-to object:

@@ -4831,13 +4830,13 @@ namespace odb } -

When you call the * or -> operator, +

When we call the * or -> 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 load() function (see below). For example:

@@ -4859,7 +4858,7 @@ namespace odb
      as a result of an earlier
      call to the * or -> 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:

@@ -4880,7 +4879,7 @@ namespace odb
      operator results in the allocation of a new object.

The second load() 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:

@@ -4963,9 +4962,8 @@ private:
   unsigned long id_;
   
-

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 named pragmas. Unlike positioned pragmas, named pragmas @@ -5026,143 +5024,20 @@ private: };

-

5.1 C++ Compiler Warnings

+

The following three sections cover the specifiers applicable + to the object, value, and member + qualifiers.

-

The C++ header file that defines your persistent classes and +

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.

+ are several ways to deal with this problem which are covered + at the end of this chapter in Section 5.4, + "C++ Compiler Warnings".

-

There are also several C++ compiler-independent methods that you - can employ. The first is to use the PRAGMA_DB macro, - defined in <odb/core.hxx>, instead of using - #pragma db 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:

- -
-#include <odb/core.hxx>
-
-PRAGMA_DB(object)
-class person
-{
-  ...
-private:
-  PRAGMA_DB(id)
-  unsigned long id_;
-  ...
-};
-  
- -

An alternative to using the PRAGMA_DB macro is to - group the #pragma db directives in blocks that are - conditionally included into compilation only when compiled with the - ODB compiler. For example:

- -
-class person
-{
-  ...
-private:
-  unsigned long id_;
-  ...
-};
-
-#ifdef ODB_COMPILER
-#  pragma db object(person)
-#  pragma db member(person::id_) id
-#endif
-  
- -

The disadvantage of this approach is that it can quickly become - overly verbose when positioned pragmas are used.

- -

5.1.1 GNU C++

- -

GNU g++ does not issue warnings about unknown pragmas - unless requested with the -Wall command line option. - To disable only the unknown pragma warning, you can add the - -Wno-unknown-pragmas option after -Wall, - for example:

- -
-g++ -Wall -Wno-unknown-pragmas ...
-  
- -

5.1.2 Visual C++

- -

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.

- -

To disable this warning via the compiler command line, you can add - the /wd4068 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.

- -

You can also disable this warning for only a specific header or - a fragment of a header using the warning control pragma. For - example:

- -
-#include <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)
-  
- -

5.1.3 Sun C++

- -

The Sun C++ compiler does not issue warnings about unknown pragmas - unless the +w or +w2 option is specified. - To disable only the unknown pragma warning you can add the - -erroff=unknownpragma option anywhere on the - command line, for example:

- -
-CC +w -erroff=unknownpragma ...
-  
- -

5.1.4 IBM XL C++

- -

IBM XL C++ issues an unknown pragma warning (1540-1401) by default. - To disable this warning you can add the -qsuppress=1540-1401 - command line option, for example:

- -
-xlC -qsuppress=1540-1401 ...
-  
- -

5.1.5 HP aC++

- -

HP aC++ (aCC) issues an unknown pragma warning (2161) by default. - To disable this warning you can add the +W2161 - command line option, for example:

- -
-aCC +W2161 ...
-  
- -

5.2 Object Type Pragmas

+

5.1 Object Type Pragmas

A pragma with the object qualifier declares a C++ class as a persistent object type. The qualifier can be optionally followed, @@ -5179,19 +5054,19 @@ aCC +W2161 ... table the table name for the persistent class - 5.2.1 + 5.1.1 pointer the pointer type for the persistent class - 5.2.2 + 5.1.2 -

5.2.1 table

+

5.1.1 table

The table 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

If the table name is not specified, the class name is used as the table name.

-

5.2.2 pointer

+

5.1.2 pointer

The pointer specifier specifies the object pointer type for the persistent class. The object pointer type is used to return, @@ -5224,8 +5099,8 @@ class person

There are several ways to specify an object pointer with the - pointer specifier. You can use a complete pointer - type as shown in the example above. Alternatively, you can + pointer 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

For additional information on object pointers, refer to Section @@, "".

-

5.3 Value Type Pragmas

+

5.2 Value Type Pragmas

A pragma with the value qualifier describes a value type. It can be optionally followed, in any order, by one or more @@ -5275,67 +5150,67 @@ class person type the database type for the value type - 5.3.1 + 5.2.1 not_null object pointer cannot be NULL - 5.3.2 + 5.2.2 unordered ordered container should be stored unordered - 5.3.3 + 5.2.3 index_type the database type for the container's index type - 5.3.4 + 5.2.4 key_type the database type for the container's key type - 5.3.5 + 5.2.5 value_type the database type for the container's value type - 5.3.6 + 5.2.6 id_column the column name for the container's table object id - 5.3.7 + 5.2.7 index_column the column name for the container's table index - 5.3.8 + 5.2.8 key_column the column name for the container's table key - 5.3.9 + 5.2.9 value_column the column name for the container's table value - 5.3.10 + 5.2.10

Many of the value type specifiers have corresponding member type - specifiers with the same names (see Section 5.4, + specifiers with the same names (see Section 5.3, "Data Member Pragmas"). 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.

-

5.3.1 type

+

5.2.1 type

The type specifier specifies the native database type that should be used for data members of this type. For example:

@@ -5392,7 +5267,7 @@ private: mapping example in the odb-examples package shows how to do this for all the supported database systems.

-

5.3.2 not_null

+

5.2.2 not_null

The not_null 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<shared_ptr<account> > accounts; #pragma db value(accounts) not_null -

5.3.3 unordered

+

5.2.3 unordered

The unordered specifier specifies that the ordered container should be stored in the database unordered. The database @@ -5433,13 +5308,13 @@ typedef std::vector<std::string> names; #pragma db value(names) unordered -

5.3.4 index_type

+

5.2.4 index_type

The index_type specifier specifies the native database type that should be used for the ordered container's index column. The semantics of index_type are similar to that of the type specifier (see - Section 5.3.1, "type"). The native + Section 5.2.1, "type"). The native database type is expected to be an integer type. For example:

@@ -5447,13 +5322,13 @@ typedef std::vector<std::string> names;
 #pragma db value(names) index_type("SMALLINT UNSIGNED NOT NULL")
   
-

5.3.5 key_type

+

5.2.5 key_type

The key_type specifier specifies the native database type that should be used for the map container's key column. The semantics of key_type are similar to that of the type specifier (see - Section 5.3.1, "type"). For + Section 5.2.1, "type"). For example:

@@ -5461,13 +5336,13 @@ typedef std::map<unsigned short, float> age_weight_map;
 #pragma db value(age_weight_map) key_type("INT UNSIGNED NOT NULL")
   
-

5.3.6 value_type

+

5.2.6 value_type

The value_type specifier specifies the native database type that should be used for the container's value column. The semantics of value_type are similar to that of the type specifier (see - Section 5.3.1, "type"). For + Section 5.2.1, "type"). For example:

@@ -5475,7 +5350,7 @@ typedef std::vector<std::string> names;
 #pragma db value(names) value_type("VARCHAR(255) NOT NULL")
   
-

5.3.7 id_column

+

5.2.7 id_column

The id_column specifier specifies the column name that should be used to store the object id in the @@ -5489,7 +5364,7 @@ typedef std::vector<std::string> names;

If the column name is not specified, then object_id is used by default.

-

5.3.8 index_column

+

5.2.8 index_column

The index_column specifier specifies the column name that should be used to store the element index in the @@ -5503,7 +5378,7 @@ typedef std::vector<std::string> names;

If the column name is not specified, then index is used by default.

-

5.3.9 key_column

+

5.2.9 key_column

The key_column specifier specifies the column name that should be used to store the key in the map @@ -5517,7 +5392,7 @@ typedef std::map<unsigned short, float> age_weight_map;

If the column name is not specified, then key is used by default.

-

5.3.10 value_column

+

5.2.10 value_column

The value_column specifier specifies the column name that should be used to store the element value in the @@ -5534,7 +5409,7 @@ typedef std::map<unsigned short, float> age_weight_map; -

5.4 Data Member Pragmas

+

5.3 Data Member Pragmas

A pragma with the member qualifier or a positioned pragma without a qualifier describes a data member. It can @@ -5552,104 +5427,104 @@ typedef std::map<unsigned short, float> age_weight_map; id the member is an object id - 5.4.1 + 5.3.1 auto id is assigned by the database - 5.4.2 + 5.3.2 type the database type for the member - 5.4.3 + 5.3.3 column the column name for the member - 5.4.4 + 5.3.4 transient the member is not stored in the database - 5.4.5 + 5.3.5 not_null object pointer cannot be NULL - 5.4.6 + 5.3.6 inverse the member is an inverse side of a bidirectional relationship - 5.4.7 + 5.3.7 unordered ordered container should be stored unordered - 5.4.8 + 5.3.8 table the table name for the container - 5.4.9 + 5.3.9 index_type the database type for the container's index type - 5.4.10 + 5.3.10 key_type the database type for the container's key type - 5.4.11 + 5.3.11 value_type the database type for the container's value type - 5.4.12 + 5.3.12 id_column the column name for the container's table object id - 5.4.13 + 5.3.13 index_column the column name for the container's table index - 5.4.14 + 5.3.14 key_column the column name for the container's table key - 5.4.15 + 5.3.15 value_column the column name for the container's table value - 5.4.16 + 5.3.16

Many of the member specifiers have corresponding value type - specifiers with the same names (see Section 5.3, + specifiers with the same names (see Section 5.2, "Value Type Pragmas"). 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<unsigned short, float> age_weight_map; to a single member. In other words, member specifiers take precedence over values specified with value specifiers.

-

5.4.1 id

+

5.3.1 id

The id specifier specifies that the data member contains the object id. Every persistent class must have a member designated @@ -5679,7 +5554,7 @@ private:

In a relational database, an identifier member is mapped to a primary key.

-

5.4.2 auto

+

5.3.2 auto

The auto specifier specifies that the object's identifier is automatically assigned by the database. Only a member that was @@ -5707,7 +5582,7 @@ private:

For additional information on the automatic identifier assignment, refer to Section 3.5, "Making Objects Persistent".

-

5.4.3 type

+

5.3.3 type

The type specifier specifies the native database type that should be used for the data member. For example:

@@ -5724,7 +5599,7 @@ private: }; -

5.4.4 column

+

5.3.4 column

The column 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 m_ prefix, etc.

-

5.4.5 transient

+

5.3.5 transient

The transient specifier instructs the ODB compiler not to store the data member in the database. For example:

@@ -5773,7 +5648,7 @@ private: references that are only meaningful in the application's memory, as well as utility members such as mutexes, etc.

-

5.4.6 not_null

+

5.3.6 not_null

The not_null specifier specifies that the member of an object pointer or a container of object pointers type cannot @@ -5802,7 +5677,7 @@ private: }; -

5.4.7 inverse

+

5.3.7 inverse

The inverse 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 - Section 5.4.8, "unordered").

+ Section 5.3.8, "unordered").

-

5.4.8 unordered

+

5.3.8 unordered

The unordered specifier specifies that the member of an ordered container type should be stored in the database unordered. @@ -5864,7 +5739,7 @@ private: }; -

5.4.9 table

+

5.3.9 table

The table specifier specifies the table name that should be used to store the contents of the container member. For example:

@@ -5895,13 +5770,13 @@ private: to Section Z.1, "Composite Value Column and Table Names" for details.

-

5.4.10 index_type

+

5.3.10 index_type

The index_type specifier specifies the native database type that should be used for the ordered container's index column of the data member. The semantics of index_type are similar to that of the type specifier (see - Section 5.4.3, "type"). The native + Section 5.3.3, "type"). The native database type is expected to be an integer type. For example:

@@ -5916,13 +5791,13 @@ private:
 };
   
-

5.4.11 key_type

+

5.3.11 key_type

The key_type specifier specifies the native database type that should be used for the map container's key column of the data member. The semantics of key_type are similar to that of the type specifier (see - Section 5.4.3, "type"). For + Section 5.3.3, "type"). For example:

@@ -5937,13 +5812,13 @@ private:
 };
   
-

5.4.12 value_type

+

5.3.12 value_type

The value_type specifier specifies the native database type that should be used for the container's value column of the data member. The semantics of value_type are similar to that of the type specifier (see - Section 5.4.3, "type"). For + Section 5.3.3, "type"). For example:

@@ -5958,14 +5833,14 @@ private:
 };
   
-

5.4.13 id_column

+

5.3.13 id_column

The id_column 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 id_column are similar to that of the column specifier (see - Section 5.4.4, "column"). + Section 5.3.4, "column"). For example:

@@ -5983,14 +5858,14 @@ private:
   

If the column name is not specified, then object_id is used by default.

-

5.4.14 index_column

+

5.3.14 index_column

The index_column 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 index_column are similar to that of the column specifier (see - Section 5.4.4, "column"). + Section 5.3.4, "column"). For example:

@@ -6008,14 +5883,14 @@ private:
   

If the column name is not specified, then index is used by default.

-

5.4.15 key_column

+

5.3.15 key_column

The key_column 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 key_column are similar to that of the column specifier (see - Section 5.4.4, "column"). + Section 5.3.4, "column"). For example:

@@ -6033,14 +5908,14 @@ private:
   

If the column name is not specified, then key is used by default.

-

5.4.16 value_column

+

5.3.16 value_column

The value_column 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 value_column are similar to that of the column specifier (see - Section 5.4.4, "column"). + Section 5.3.4, "column"). For example:

@@ -6058,6 +5933,141 @@ private:
   

If the column name is not specified, then value is used by default.

+

5.4 C++ Compiler Warnings

+ +

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.

+ +

There are also several C++ compiler-independent methods that we + can employ. The first is to use the PRAGMA_DB macro, + defined in <odb/core.hxx>, instead of using + #pragma db 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:

+ +
+#include <odb/core.hxx>
+
+PRAGMA_DB(object)
+class person
+{
+  ...
+private:
+  PRAGMA_DB(id)
+  unsigned long id_;
+  ...
+};
+  
+ +

An alternative to using the PRAGMA_DB macro is to + group the #pragma db directives in blocks that are + conditionally included into compilation only when compiled with the + ODB compiler. For example:

+ +
+class person
+{
+  ...
+private:
+  unsigned long id_;
+  ...
+};
+
+#ifdef ODB_COMPILER
+#  pragma db object(person)
+#  pragma db member(person::id_) id
+#endif
+  
+ +

The disadvantage of this approach is that it can quickly become + overly verbose when positioned pragmas are used.

+ +

5.4.1 GNU C++

+ +

GNU g++ does not issue warnings about unknown pragmas + unless requested with the -Wall command line option. + To disable only the unknown pragma warning, we can add the + -Wno-unknown-pragmas option after -Wall, + for example:

+ +
+g++ -Wall -Wno-unknown-pragmas ...
+  
+ +

5.4.2 Visual C++

+ +

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.

+ +

To disable this warning via the compiler command line, we can add + the /wd4068 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.

+ +

We can also disable this warning for only a specific header or + a fragment of a header using the warning control pragma. For + example:

+ +
+#include <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)
+  
+ +

5.4.3 Sun C++

+ +

The Sun C++ compiler does not issue warnings about unknown pragmas + unless the +w or +w2 option is specified. + To disable only the unknown pragma warning we can add the + -erroff=unknownpragma option anywhere on the + command line, for example:

+ +
+CC +w -erroff=unknownpragma ...
+  
+ +

5.4.4 IBM XL C++

+ +

IBM XL C++ issues an unknown pragma warning (1540-1401) by default. + To disable this warning we can add the -qsuppress=1540-1401 + command line option, for example:

+ +
+xlC -qsuppress=1540-1401 ...
+  
+ +

5.4.5 HP aC++

+ +

HP aC++ (aCC) issues an unknown pragma warning (2161) by default. + To disable this warning we can add the +W2161 + command line option, for example:

+ +
+aCC +W2161 ...
+  
+ + @@ -6278,13 +6288,13 @@ namespace odb

You will need to include the <odb/mysql/database.hxx> header file to make this class available in your application.

-

The overloaded database constructors allow you +

The overloaded database constructors allow us to specify MySQL database parameters that should be used when connecting to the database. In MySQL NULL and an empty string are treated as the same values for all the string parameters except password and socket. The client_flags 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 CLIENT_FOUND_ROWS 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 <file>

-

The --options-file option allows you to specify some +

The --options-file 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.

@@ -6323,13 +6333,13 @@ namespace odb with short descriptions that are recognized by this constructor.

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-NULL 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.

-

The set of accessor functions following the constructors allow you +

The set of accessor functions following the constructors allow us to query the parameters of the database instance.

The connection() function returns the MySQL database -- cgit v1.1