From 4bd152adf66b9cad1300df506f15d8bd5ee749e2 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov mysql::database
constructors which allow you to pass this information directly
- (see Section 10.1.2, "MySQL Database Class").
Next, we create three person
objects. Right now they are
transient objects, which means that if we terminate the application
@@ -1190,10 +1190,10 @@ main (int argc, char* argv[])
The final bit of code in our example is the catch
block that handles the database exceptions. We do this by catching
- the base ODB exception (see Section 3.10, "ODB
+ the base ODB exception (Section 3.10, "ODB
Exceptions") and printing the diagnostics.
Let's now compile (see Section 2.3, "Compiling and
+ Let's now compile (Section 2.3, "Compiling and
Running") and then run our first ODB application: These two pragmas are the minimum required to declare a
persistent class. Other pragmas can be used to fine-tune
the database-related properties of a class and its
- members (see Chapter 9, "ODB Pragma Language").
@@ -1690,7 +1690,7 @@ class person
Normally, an object class should define the default constructor. The generated database support code uses this constructor when @@ -1700,7 +1700,8 @@ class person without the default constructor. However, in this case, the database operations can only load the persistent state into an existing instance (Section 3.6, "Loading Persistent Objects", - Section 4.4, "Query Result").
+ Section 4.4, "Query Result").The object id type + should be default-constructible.
If an object class has private or protected non-transient data members or if its default constructor is not public, then the @@ -1726,8 +1727,6 @@ private: }; -
The object id type should be default-constructible.
-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 int
or std::string
since the
@@ -1736,10 +1735,10 @@ private:
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
- 9.2.1, "type
"). Similar to object types, composite
- value types have to be explicitly declared as persistent using the
- db value
pragma, for example:
db type
pragma description
+ in Section 9.2.1, "type
". Similar
+ to object types, composite value types have to be explicitly declared
+ as persistent using the db value
pragma, for example:
#pragma db value @@ -1752,8 +1751,8 @@ class name };-
Composite values are discussed in greater detail in Chapter - 7, "Composite Value Types".
+Composite value types are discussed in more detail in + Chapter 7, "Composite Value Types".
Normally, you would use object types to model real-world entities,
things that have their own identity. For example, in the
@@ -1783,7 +1782,7 @@ class name
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 the first name
- and last name each an object and only store references to
+ and last name each an object and only store pointers to
these objects in the person
class.
An instance of a persistent class can be in one of two states: @@ -1817,18 +1816,17 @@ class name Boost.
However, to avoid any possibility of a mistake, such as forgetting
- to use a smart pointer for a returned object, as well as to be able
- to use more advanced ODB functionality, such as sessions and bidirectional
+ to use a smart pointer for a returned object, as well as to simplify the
+ use of more advanced ODB functionality, such as sessions and bidirectional
object relationships, it is recommended that you use smart pointers
- with the sharing semantics, such as shared_ptr
mentioned
- previously, as object pointers.
shared_ptr
+ smart pointer from TR1 or Boost is a good default choice.
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
- pointer type. Refer to the
+ 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 pointer type. Refer to the
ODB
Compiler Command Line Manual for details on this option's argument.
The typical usage is shown below:
Refer to Section 9.1.2, "pointer
"
for more information on this pragma.
Built-in support, provided by the ODB runtime, library allows us to use
- the TR1 shared_ptr
and std::auto_ptr
as
+
Built-in support that is provided by the ODB runtime library allows us
+ to use the TR1 shared_ptr
and std::auto_ptr
as
object pointers. Plus, ODB profile libraries, that are available for
commonly used frameworks and libraries (such as Boost and Qt),
provide support for smart pointers found in these frameworks and
@@ -2151,7 +2149,7 @@ update_age (database& db, person& p)
application-assigned object ids (Section 9.3.2,
"auto
").
The second and third persist()
versions are similar to the
+
The second and third persist()
functions are similar to the
first two except that they operate on unrestricted references and object
pointers. If the identifier of the object being persisted is assigned
by the database, these functions update the id member of the passed
@@ -2256,8 +2254,8 @@ t.commit ();
returns false
.
If we don't know the object id, then we can use queries to - find the object (or objects) matching some criteria (see - Chapter 4, "Querying the Database"). Note, + find the object (or objects) matching some criteria + (Chapter 4, "Querying the Database"). Note, however, that loading an object's state using its identifier can be significantly faster than executing a query.
@@ -2285,8 +2283,9 @@ t.commit ();The first update()
function expects an object reference,
while the other two expect object pointers. If the object passed to
- these functions does not exist in the database, update()
- throws the odb::object_not_persistent
exception.
update()
throws the odb::object_not_persistent
+ exception.
Below is an example of the funds transfer that we talked about in the earlier section on transactions. It uses the hypothetical @@ -2321,7 +2320,7 @@ transfer (database& db,
The same can be accomplished using dynamically allocated objects
- and the object pointer version of the update()
function,
+ and the update()
function with object pointer argument,
for example:
@@ -2401,8 +2400,8 @@ t.commit ();-3.9 Executing Native SQL Statements
In some situations we may need to execute native SQL statements - instead of using the object-oriented API described above. For - example, we may want to tune the database schema generated + instead of using the object-oriented database API described above. + For example, we may want to tune the database schema generated by the ODB compiler or take advantage of a feature that is specific to the database system we are using. The
+ return the number of rows that were affected by the statement. For + example:database::execute()
function, which has three @@ -2424,7 +2423,8 @@ t.commit (); statement length as the second argument and the statement itself may contain'\0'
characters, for example to represent binary data, if the database system supports it. All three functions - return the number of rows affected by the statement. For example:transaction t (db.begin ()); @@ -3147,7 +3147,7 @@ namespace odb+5 Containers
The ODB runtime library provides built-in persistence support for - all commonly used standard C++ containers, namely, + all the commonly used standard C++ containers, namely,
std::vector
,std::list
,std::set
,std::multiset
,std::map
, andstd::multimap
. Plus, ODB profile libraries, that are @@ -3166,11 +3166,15 @@ class person { ... private: - std::vector<std::name> nicknames_; + std::vector<std::string> nicknames_; ... };The complete version of the above code fragment and the other code + samples presented in this chapter can found in the
+container
+ example in theodb-examples
package.A data member in a persistent class that is of a container type behaves like a value type. That is, when an object is made persistent, the elements of the container are store in the database. Similarly, @@ -3186,12 +3190,13 @@ private: in detail in the following sections.
Containers in ODB can contain simple value types, composite value - types (Chapter 5, "Containers"), and pointers to - objects (Chapter 6, "Relationships"). Containers of + types (Chapter 7, "Composite Value Types"), and pointers + to objects (Chapter 6, "Relationships"). Containers of containers, either directly or indirectly via a composite value - type, are not allowed. A key in map and multimap containers can + type, are not allowed. A key in a map or multimap container can be a simple or composite value type but not a pointer to an object. - An index in the ordered container should be a simple integer type.
+ An index in the ordered container should be a simple integer value + type.The value type in the ordered, set, and map containers as well as the key type in the map containers should be default-constructible. @@ -3217,9 +3222,6 @@ class person { ... private: - #pragma db id auto - unsigned long id_; - std::vector<name> aliases_; ... }; @@ -3267,8 +3269,8 @@ private: (called
-index
), and the value column of typestd::string
(calledvalue
).A number of ODB pragmas allow us to customize the table name, - column names, and native database types for the container both on +
A number of ODB pragmas allow us to customize the table name, column + names, and native database types of an ordered container both, on the per-container and per-member basis. For more information on these pragmas, refer to Chapter 9, "ODB Pragma Language". The following example shows some of the possible @@ -3280,9 +3282,6 @@ class person { ... private: - #pragma db id auto - unsigned long id_; - #pragma db table("nicknames") \ id_column ("person_id") \ index_type ("SMALLINT UNSIGNED NOT NULL") \ @@ -3294,13 +3293,14 @@ private: };
While the C++ container used in the persistent class may be ordered, +
While the C++ container used in a persistent class may be ordered,
sometimes we may wish to store such a container in the database without
the order information. In the example above, for instance, the order
of person's nicknames is probably not important. To instruct the ODB
compiler to ignore the order in ordered containers we can use the
- unordered
pragma (see Chapter 9, "ODB
- Pragma Language" for details). For example:
db unordered
pragma (Section 9.2.3,
+ "unordered
", Section 9.3.8,
+ "unordered
"). For example:
#pragma db object @@ -3308,17 +3308,14 @@ class person { ... private: - #pragma db id auto - unsigned long id_; - #pragma db unordered std::vector<std::string> nicknames_; ... };-
The table for the ordered container that is marked unordered will - miss the index column and the order in which elements are retrieved +
The table for an ordered container that is marked unordered won't + have the index column and the order in which elements are retrieved from the database may not be the same as the order in which they were stored.
@@ -3361,7 +3358,7 @@ private:std::string
(called value
).
A number of ODB pragmas allow us to customize the table name, - column names, and native database types for the container both on + column names, and native database types of a set container, both on the per-container and per-member basis. For more information on these pragmas, refer to Chapter 9, "ODB Pragma Language". The following example shows some of the possible @@ -3373,9 +3370,6 @@ class person { ... private: - #pragma db id auto - unsigned long id_; - #pragma db table("emails") \ id_column ("person_id") \ value_type ("VARCHAR(255) NOT NULL") \ @@ -3387,7 +3381,7 @@ private:
In ODB map and multimap containers (referred to as just set +
In ODB map and multimap containers (referred to as just map
containers) are associative containers that contain key-value
elements based on some relationship between keys. A map container
may or may not guarantee a particular order of the elements that
@@ -3426,7 +3420,7 @@ private:
column of type std::string
(called value
).
A number of ODB pragmas allow us to customize the table name, - column names, and native database types for the container both on + column names, and native database types of a map container, both on the per-container and per-member basis. For more information on these pragmas, refer to Chapter 9, "ODB Pragma Language". The following example shows some of the possible @@ -3438,9 +3432,6 @@ class person { ... private: - #pragma db id auto - unsigned long id_; - #pragma db table("weight_map") \ id_column ("person_id") \ key_type ("INT UNSIGNED NOT NULL") \ @@ -3469,7 +3460,7 @@ private:
Once the container traits specialization is ready for your container,
you will need to include it into the ODB compilation process using
the --odb-epilogue
option and into the generated header
- file with the --hxx-prologue
option. As an example,
+ files with the --hxx-prologue
option. As an example,
suppose we have a hash table container for which we have the traits
specialization implemented in the hashtable-traits.hxx
file. Then, we can create an ODB compiler options file for this
@@ -3631,7 +3622,7 @@ unsigned long john_id, jane_id;
session makes sure that for a given object id, a single instance
is shared among all other objects that relate to it.
We can also use the data members from the pointed-to +
We can also use data members from pointed-to objects in database queries (Chapter 4, "Querying the Database"). For each pointer in a persistent class, the query class defines a nested scope containing members corresponding @@ -4454,7 +4445,7 @@ t.commit ();
Once the pointer traits specialization is ready, you will need to
include it into the ODB compilation process using the
--odb-epilogue
option and into the generated header
- file with the --hxx-prologue
option. As an example,
+ files with the --hxx-prologue
option. As an example,
suppose we have the smart_ptr
smart pointer for which
we have the traits specialization implemented in the
smart-ptr-traits.hxx
file. Then, we can create an ODB
@@ -4509,12 +4500,16 @@ class basic_name
};
+
The complete version of the above code fragment and the other code
+ samples presented in this chapter can found in the composite
+ example in the odb-examples
package.
A composite value type does not have to define a default constructor,
unless it is used as an element of a container, in which case the
default constructor can be made private. If a composite value type
has private or protected non-transient data members or if its
default constructor is not public and the value type is used as
- an element in a container, then the odb::access
class
+ an element of a container, then the odb::access
class
should be declared a friend of this value type. For example:
@@ -4536,16 +4531,12 @@ private: };-
The complete versions of the above code fragment as well as other code
- samples presented in this chapter can found in the composite
- example in the odb-examples
package.
The members of a composite value can be other value types (either simple or composite), containers (Chapter 5, "Containers"), and pointers to objects (Chapter 6, "Relationships"). Similarly, a composite value type can be used in object members, - as an element in a container, and as a base for another composite + as an element of a container, and as a base for another composite value type. In particular, composite value types can be used as element types in set containers (Section 5.2, "Set and Multiset Containers") and as key types in map containers @@ -4590,14 +4581,11 @@ class person { ... - #pragma db id auto - unsigned long id_; - name name_; }; -
We can also use the data members from the composite value types +
We can also use data members from composite value types
in database queries (Chapter 4, "Querying the
Database"). For each composite value in a persistent class,
the query class defines a nested scope containing members corresponding
@@ -4606,7 +4594,7 @@ class person
contains the name
scope (derived from the name_
data member) which in turn contains the extras
member
(derived from the name::extras_
data member of the
- composite value type). The process continues recursively for nested
+ composite value type). This process continues recursively for nested
composite value types and, as a result, we can use the
query::name::extras::nickname
expression while querying
the database for the person
objects. For example:
db column
pragma (Section
9.3.4, "column
"). For composite value
- types things are slightly more complicated since it is mapped to
+ types things are slightly more complex since they are mapped to
multiple columns. Consider the following example:
@@ -4728,16 +4716,16 @@ CREATE TABLE person ( last_name TEXT NOT NULL);-
The same principal applies when a composite value type is used +
The same principle 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
+ db column
, either the db value_column
(Section 9.3.16, "value_column
") or
db key_column
(Section 9.3.15, "key_column
")
pragmas are used to specify the column prefix.
When a composite value type contains a container, an extra table - is used to store the elements (Chapter 5, "Containers"). + is used to store its elements (Chapter 5, "Containers"). The names of such tables are constructed in a way similar to the column names, except that by default both the object name and the member name are used as a prefix. For example:
@@ -4820,7 +4808,7 @@ CREATE TABLE `person_nickname` (A session is an application's unit of work that may encompass several database transactions. In this version of ODB a session is just an object cache. In the future versions it will provide additional - functionality, such as automatic object state change flushing + functionality, such as automatic object state change tracking and optimistic concurrency.
Each thread of execution in an application can have only one active @@ -4860,7 +4848,7 @@ using namespace odb; } -
The odb::session
class has the following interface:
The session
class has the following interface:
namespace odb @@ -4928,7 +4916,7 @@ namespace odbhas_current()
static function.The static
@@ -4984,7 +4972,7 @@ t.commit (); when loaded, objects are always created and cached as non-constant). If we try to load an object as non-constant that was previously persisted and cached as constant, thecurrent()
modifier allows us to set the - current session for this thread. Thereset_current
+ current session for this thread. Thereset_current()
static function clears the current session. These two functions allow for more advanced use cases, such as multiplexing between two or more sessions in the same thread.odb::const_object
- exception is thrown. The following transaction illustrates the + exception is thrown. The following transaction shows the situation where this would happen:@@ -5137,7 +5125,7 @@ private: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 our application. Some C++ compilers + the C++ compiler to build the application. Some C++ compilers issue warnings about pragmas that they do not recognize. There are several ways to deal with this problem which are covered at the end of this chapter in Section 9.4, @@ -5159,13 +5147,13 @@ private:
- table
the table name for the persistent class +table name for a persistent class 9.1.1 @@ -5175,7 +5163,7 @@ private: - pointer
the pointer type for the persistent class +pointer type for a persistent class 9.1.2 9.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 + be used to store objects of a class in a relational database. For example:@@ -5192,8 +5180,8 @@ class person9.1.2
pointer
The
pointer
specifier specifies the object pointer type - for the persistent class. The object pointer type is used to return, - pass, and cache dynamically allocated instances of the persistent + for a persistent class. The object pointer type is used to return, + pass, and cache dynamically allocated instances of a persistent class. For example:@@ -5209,7 +5197,7 @@ class person 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 + name as a template argument. The following example is therefore equivalent to the one above:@@ -5236,7 +5224,7 @@ class person ODB compiler option, is used. If this option is not specified either, then the raw pointer is used by default. -+For additional information on object pointers refer to +
For a more detailed discussion of object pointers, refer to Section 3.2, "Object Pointers".
9.2 Value Type Pragmas
@@ -5255,7 +5243,7 @@ class person@@ -5273,57 +5261,57 @@ class person - type
the database type for the value type +database type for a value type 9.2.1 - index_type
the database type for the container's index type +database type for a container's index type 9.2.4 - key_type
the database type for the container's key type +database type for a container's key type 9.2.5 - value_type
the database type for the container's value type +database type for a container's value type 9.2.6 - id_column
the column name for the container's table object id +column name for a container's table object id 9.2.7 - index_column
the column name for the container's table index +column name for a container's table index 9.2.8 - key_column
the column name for the container's table key +column name for a container's table key 9.2.9 - value_column
the column name for the container's table value +column name for a container's table value 9.2.10 Many of the value type specifiers have corresponding member type - specifiers with the same names (see Section 9.3, + specifiers with the same names (Section 9.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 members of this value type that don't have a pre-member version of the specifier. While the member specifier always applies only to a single member. In other words, member specifiers take precedence - over values specified with value specifiers.
+ over parameters specified with value specifiers.9.2.1
@@ -5376,7 +5364,7 @@ private:type
9.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 + or a container of object pointers cannot have or contain theNULL
value. For example:@@ -5401,6 +5389,9 @@ typedef std::vector<shared_ptr<account> > accounts; #pragma db value(accounts) not_null+For a more detailed discussion of the
+NULL
object pointer + semantics, refer to Chapter 6, "Relationships".9.2.3
unordered
The
unordered
specifier specifies that the ordered @@ -5414,13 +5405,17 @@ typedef std::vector<std::string> names; #pragma db value(names) unorderedFor a more detailed discussion of ordered containers and their + storage in the database, refer to Section 5.1, + "Ordered Containers".
+9.2.4
index_type
The
index_type
specifier specifies the native - database type that should be used for the ordered container's + database type that should be used for an ordered container's index column. The semantics ofindex_type
- are similar to that of thetype
specifier (see - Section 9.2.1, "type
"). The native + are similar to that of thetype
specifier + (Section 9.2.1, "type
"). The native database type is expected to be an integer type. For example:@@ -5431,10 +5426,10 @@ typedef std::vector<std::string> names;9.2.5
key_type
The
key_type
specifier specifies the native - database type that should be used for the map container's + database type that should be used for a map container's key column. The semantics ofkey_type
- are similar to that of thetype
specifier (see - Section 9.2.1, "type
"). For + are similar to that of thetype
specifier + (Section 9.2.1, "type
"). For example:@@ -5445,10 +5440,10 @@ typedef std::map<unsigned short, float> age_weight_map;9.2.6
value_type
The
value_type
specifier specifies the native - database type that should be used for the container's + database type that should be used for a container's value column. The semantics ofvalue_type
- are similar to that of thetype
specifier (see - Section 9.2.1, "type
"). For + are similar to that of thetype
specifier + (Section 9.2.1, "type
"). For example:@@ -5459,7 +5454,7 @@ typedef std::vector<std::string> names;9.2.7
id_column
The
id_column
specifier specifies the column - name that should be used to store the object id in the + name that should be used to store the object id in a container's table. For example:@@ -5473,7 +5468,7 @@ typedef std::vector<std::string> names;9.2.8
index_column
The
index_column
specifier specifies the column - name that should be used to store the element index in the + name that should be used to store the element index in an ordered container's table. For example:@@ -5487,7 +5482,7 @@ typedef std::vector<std::string> names;9.2.9
key_column
The
key_column
specifier specifies the column - name that should be used to store the key in the map + name that should be used to store the key in a map container's table. For example:@@ -5501,7 +5496,7 @@ typedef std::map<unsigned short, float> age_weight_map;9.2.10
value_column
The
value_column
specifier specifies the column - name that should be used to store the element value in the + name that should be used to store the element value in a container's table. For example:@@ -5532,7 +5527,7 @@ typedef std::map<unsigned short, float> age_weight_map;@@ -5544,19 +5539,19 @@ typedef std::map<unsigned short, float> age_weight_map; - id
the member is an object id +member is an object id 9.3.1 - type
the database type for the member +database type for member 9.3.3 - column
the column name for the member +column name for member 9.3.4 @@ -5568,7 +5563,7 @@ typedef std::map<unsigned short, float> age_weight_map; - transient
the member is not stored in the database +member is not stored in the database 9.3.5 @@ -5580,68 +5575,68 @@ typedef std::map<unsigned short, float> age_weight_map; - inverse
the member is an inverse side of a bidirectional relationship +member is an inverse side of a bidirectional relationship 9.3.7 - table
the table name for the container +table name for a container 9.3.9 - index_type
the database type for the container's index type +database type for a container's index type 9.3.10 - key_type
the database type for the container's key type +database type for a container's key type 9.3.11 - value_type
the database type for the container's value type +database type for a container's value type 9.3.12 - id_column
the column name for the container's table object id +column name for a container's object id 9.3.13 - index_column
the column name for the container's table index +column name for a container's index 9.3.14 - key_column
the column name for the container's table key +column name for a container's key 9.3.15 - value_column
the column name for the container's table value +column name for a container's value 9.3.16 Many of the member specifiers have corresponding value type - specifiers with the same names (see Section 9.2, + specifiers with the same names (Section 9.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 members of this value type that don't have a pre-member version of the specifier. While the member specifier always applies only to a single member. In other words, member specifiers take precedence - over values specified with value specifiers.
+ over parameters specified with value specifiers.9.3.1
-id
The
id
specifier specifies that the data member contains +The
@@ -5691,7 +5686,7 @@ private:id
specifier specifies that a data member contains the object id. Every persistent class must have a member designated as an object's identifier. For example:9.3.3
type
The
+ that should be used for a data member. For example:type
specifier specifies the native database type - that should be used for the data member. For example:#pragma db object @@ -5708,7 +5703,7 @@ private:9.3.4
column
The
column
specifier specifies the column name - that should be used to store the member in a relational database. + that should be used to store a data member in a relational database. For example:@@ -5728,13 +5723,13 @@ private: "Composite Value Column and Table Names" for details.+If the column name is not specified, it is derived from the member - name by removing the common member name decorations, such as leading + name by removing the common data member name decorations, such as leading and trailing underscores, the
m_
prefix, etc.9.3.5
transient
The
+ not to store a data member in the database. For example:transient
specifier instructs the ODB compiler - not to store the data member in the database. For example:#pragma db object @@ -5756,7 +5751,7 @@ private:+9.3.6
-not_null
The
not_null
specifier specifies that the member of +The
@@ -5783,13 +5778,16 @@ private: };not_null
specifier specifies that a data member of an object pointer or a container of object pointers type cannot have or contain theNULL
value. For example:For a more detailed discussion of the
+NULL
object pointer + semantics, refer to Chapter 6, "Relationships".9.3.7
-inverse
The
inverse
specifier specifies that the member of +The
+ required argument to this specifier is the corresponding data + member name in the referenced object. For example:inverse
specifier specifies that a data member of an object pointer or a container of object pointers type is an inverse side of a bidirectional object relationship. The single - required argument to this specifier is the data member name in - the referenced object. For example:using std::tr1::shared_ptr; @@ -5817,17 +5815,20 @@ private: };-An inverse member does not have a corresponding column or table in - the resulting database schema. Instead, the column or table from - the referenced object is used to retrieve the relationship - 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 9.3.8, "
+unordered
").An inverse member does not have a corresponding column or, in case + of a container, table in the resulting database schema. Instead, the + column or table from the referenced object is used to retrieve the + relationship 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 + (Section 9.3.8, "
+ +unordered
").For a more detailed discussion of inverse members, refer to + Section 6.2, "Bidirectional Relationships".
9.3.8
-unordered
The
unordered
specifier specifies that the member of +The
unordered
specifier specifies that a member of an ordered container type should be stored in the database unordered. The database table for such a member will not contain the index column and the order in which elements are retrieved from the database may @@ -5845,10 +5846,14 @@ private: };For a more detailed discussion of ordered containers and their + storage in the database, refer to Section 5.1, + "Ordered Containers".
+9.3.9
table
The
+ be used to store the contents of a container member. For example:table
specifier specifies the table name that should - be used to store the contents of the container member. For example:#pragma db object @@ -5879,10 +5884,10 @@ private:9.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 ofindex_type
- are similar to that of thetype
specifier (see - Section 9.3.3, "type
"). The native + database type that should be used for an ordered container's + index column of a data member. The semantics ofindex_type
+ are similar to that of thetype
specifier + (Section 9.3.3, "type
"). The native database type is expected to be an integer type. For example:@@ -5900,10 +5905,10 @@ private:9.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 ofkey_type
- are similar to that of thetype
specifier (see - Section 9.3.3, "type
"). For + database type that should be used for a map container's + key column of a data member. The semantics ofkey_type
+ are similar to that of thetype
specifier + (Section 9.3.3, "type
"). For example:@@ -5921,10 +5926,10 @@ private:9.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 ofvalue_type
- are similar to that of thetype
specifier (see - Section 9.3.3, "type
"). For + database type that should be used for a container's + value column of a data member. The semantics ofvalue_type
+ are similar to that of thetype
specifier + (Section 9.3.3, "type
"). For example:@@ -5942,11 +5947,11 @@ private:9.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 + name that should be used to store the object id in a + container's table for a data member. The semantics ofid_column
are similar to that of the -column
specifier (see - Section 9.3.4, "column
"). +column
specifier + (Section 9.3.4, "column
"). For example:@@ -5967,11 +5972,11 @@ private:9.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 + name that should be used to store the element index in an + ordered container's table for a data member. The semantics ofindex_column
are similar to that of the -column
specifier (see - Section 9.3.4, "column
"). +column
specifier + (Section 9.3.4, "column
"). For example:@@ -5992,11 +5997,11 @@ private:9.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 + name that should be used to store the key in a map + container's table for a data member. The semantics ofkey_column
are similar to that of the -column
specifier (see - Section 9.3.4, "column
"). +column
specifier + (Section 9.3.4, "column
"). For example:@@ -6017,11 +6022,11 @@ private:9.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 + name that should be used to store the element value in a + container's table for a data member. The semantics ofvalue_column
are similar to that of the -column
specifier (see - Section 9.3.4, "column
"). +column
specifier + (Section 9.3.4, "column
"). For example:@@ -6041,9 +6046,9 @@ private:9.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 +
When a C++ header file defining persistent classes and containing + ODB pragmas is used to build the application, the C++ compiler 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 @@ -6200,7 +6205,7 @@ aCC +W2161 ...
The following table summarizes the default mapping between basic C++ value types and MySQL database types. This mapping can be customized on the per-type and per-member basis using the ODB - Pragmas Language (see Chapter 9, "ODB Pragma + Pragmas Language (Chapter 9, "ODB Pragma Language").
-- cgit v1.1