diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2013-05-06 12:05:39 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2013-08-14 15:19:49 +0200 |
commit | 09d7377f81aeb8fde4aa1698e946457f03380d45 (patch) | |
tree | eaedf7045fde8354a3693ce77edc7d5f86824e4e /doc | |
parent | 548f0b10aa3adfc722198bf31f773ba85047f344 (diff) |
Add support for object sections
Sections are an optimization mechanism that allows the partitioning of
data members of a persistent class into groups that can be separately
loaded and/or updated.
Diffstat (limited to 'doc')
-rw-r--r-- | doc/manual.xhtml | 2401 |
1 files changed, 1600 insertions, 801 deletions
diff --git a/doc/manual.xhtml b/doc/manual.xhtml index 2746a0c..f754e40 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -429,154 +429,168 @@ for consistency. </tr> <tr> - <th>9</th><td><a href="#9">Views</a> + <th>9</th><td><a href="#9">Sections</a> <table class="toc"> - <tr><th>9.1</th><td><a href="#9.1">Object Views</a></td></tr> - <tr><th>9.2</th><td><a href="#9.2">Table Views</a></td></tr> - <tr><th>9.3</th><td><a href="#9.3">Mixed Views</a></td></tr> - <tr><th>9.4</th><td><a href="#9.4">View Query Conditions</a></td></tr> - <tr><th>9.5</th><td><a href="#9.5">Native Views</a></td></tr> - <tr><th>9.6</th><td><a href="#9.6">Other View Features and Limitations</a></td></tr> + <tr><th>9.1</th><td><a href="#9.1">Sections and Inheritance</a></td></tr> + <tr><th>9.2</th><td><a href="#9.2">Sections and Optimistic Concurrency</a></td></tr> + <tr><th>9.3</th><td><a href="#9.3">Sections and Lazy Pointers</a></td></tr> + <tr><th>9.4</th><td><a href="#9.4">Sections and Change-Tracking Containers</a></td></tr> </table> </td> </tr> <tr> - <th>10</th><td><a href="#10">Session</a> + <th>10</th><td><a href="#10">Views</a> <table class="toc"> - <tr><th>10.1</th><td><a href="#10.1">Object Cache</a></td></tr> - <tr><th>10.2</th><td><a href="#10.2">Custom Sessions</a></td></tr> + <tr><th>10.1</th><td><a href="#10.1">Object Views</a></td></tr> + <tr><th>10.2</th><td><a href="#10.2">Table Views</a></td></tr> + <tr><th>10.3</th><td><a href="#10.3">Mixed Views</a></td></tr> + <tr><th>10.4</th><td><a href="#10.4">View Query Conditions</a></td></tr> + <tr><th>10.5</th><td><a href="#10.5">Native Views</a></td></tr> + <tr><th>10.6</th><td><a href="#10.6">Other View Features and Limitations</a></td></tr> </table> </td> </tr> <tr> - <th>11</th><td><a href="#11">Optimistic Concurrency</a></td> + <th>11</th><td><a href="#11">Session</a> + <table class="toc"> + <tr><th>11.1</th><td><a href="#11.1">Object Cache</a></td></tr> + <tr><th>11.2</th><td><a href="#11.2">Custom Sessions</a></td></tr> + </table> + </td> </tr> <tr> - <th>12</th><td><a href="#12">ODB Pragma Language</a> + <th>12</th><td><a href="#12">Optimistic Concurrency</a></td> + </tr> + + <tr> + <th>14</th><td><a href="#14">ODB Pragma Language</a> <table class="toc"> <tr> - <th>12.1</th><td><a href="#12.1">Object Type Pragmas</a> + <th>14.1</th><td><a href="#14.1">Object Type Pragmas</a> <table class="toc"> - <tr><th>12.1.1</th><td><a href="#12.1.1"><code>table</code></a></td></tr> - <tr><th>12.1.2</th><td><a href="#12.1.2"><code>pointer</code></a></td></tr> - <tr><th>12.1.3</th><td><a href="#12.1.3"><code>abstract</code></a></td></tr> - <tr><th>12.1.4</th><td><a href="#12.1.4"><code>readonly</code></a></td></tr> - <tr><th>12.1.5</th><td><a href="#12.1.5"><code>optimistic</code></a></td></tr> - <tr><th>12.1.6</th><td><a href="#12.1.6"><code>no_id</code></a></td></tr> - <tr><th>12.1.7</th><td><a href="#12.1.7"><code>callback</code></a></td></tr> - <tr><th>12.1.8</th><td><a href="#12.1.8"><code>schema</code></a></td></tr> - <tr><th>12.1.9</th><td><a href="#12.1.9"><code>polymorphic</code></a></td></tr> - <tr><th>12.1.10</th><td><a href="#12.1.10"><code>session</code></a></td></tr> - <tr><th>12.1.11</th><td><a href="#12.1.11"><code>definition</code></a></td></tr> - <tr><th>12.1.12</th><td><a href="#12.1.12"><code>transient</code></a></td></tr> + <tr><th>14.1.1</th><td><a href="#14.1.1"><code>table</code></a></td></tr> + <tr><th>14.1.2</th><td><a href="#14.1.2"><code>pointer</code></a></td></tr> + <tr><th>14.1.3</th><td><a href="#14.1.3"><code>abstract</code></a></td></tr> + <tr><th>14.1.4</th><td><a href="#14.1.4"><code>readonly</code></a></td></tr> + <tr><th>14.1.5</th><td><a href="#14.1.5"><code>optimistic</code></a></td></tr> + <tr><th>14.1.6</th><td><a href="#14.1.6"><code>no_id</code></a></td></tr> + <tr><th>14.1.7</th><td><a href="#14.1.7"><code>callback</code></a></td></tr> + <tr><th>14.1.8</th><td><a href="#14.1.8"><code>schema</code></a></td></tr> + <tr><th>14.1.9</th><td><a href="#14.1.9"><code>polymorphic</code></a></td></tr> + <tr><th>14.1.10</th><td><a href="#14.1.10"><code>session</code></a></td></tr> + <tr><th>14.1.11</th><td><a href="#14.1.11"><code>definition</code></a></td></tr> + <tr><th>14.1.12</th><td><a href="#14.1.12"><code>transient</code></a></td></tr> + <tr><th>14.1.13</th><td><a href="#14.1.13"><code>sectionable</code></a></td></tr> </table> </td> </tr> <tr> - <th>12.2</th><td><a href="#12.2">View Type Pragmas</a> + <th>14.2</th><td><a href="#14.2">View Type Pragmas</a> <table class="toc"> - <tr><th>12.2.1</th><td><a href="#12.2.1"><code>object</code></a></td></tr> - <tr><th>12.2.2</th><td><a href="#12.2.2"><code>table</code></a></td></tr> - <tr><th>12.2.3</th><td><a href="#12.2.3"><code>query</code></a></td></tr> - <tr><th>12.2.4</th><td><a href="#12.2.4"><code>pointer</code></a></td></tr> - <tr><th>12.2.5</th><td><a href="#12.2.5"><code>callback</code></a></td></tr> - <tr><th>12.2.6</th><td><a href="#12.2.6"><code>definition</code></a></td></tr> - <tr><th>12.2.7</th><td><a href="#12.2.7"><code>transient</code></a></td></tr> + <tr><th>14.2.1</th><td><a href="#14.2.1"><code>object</code></a></td></tr> + <tr><th>14.2.2</th><td><a href="#14.2.2"><code>table</code></a></td></tr> + <tr><th>14.2.3</th><td><a href="#14.2.3"><code>query</code></a></td></tr> + <tr><th>14.2.4</th><td><a href="#14.2.4"><code>pointer</code></a></td></tr> + <tr><th>14.2.5</th><td><a href="#14.2.5"><code>callback</code></a></td></tr> + <tr><th>14.2.6</th><td><a href="#14.2.6"><code>definition</code></a></td></tr> + <tr><th>14.2.7</th><td><a href="#14.2.7"><code>transient</code></a></td></tr> </table> </td> </tr> <tr> - <th>12.3</th><td><a href="#12.3">Value Type Pragmas</a> + <th>14.3</th><td><a href="#14.3">Value Type Pragmas</a> <table class="toc"> - <tr><th>12.3.1</th><td><a href="#12.3.1"><code>type</code></a></td></tr> - <tr><th>12.3.2</th><td><a href="#12.3.2"><code>id_type</code></a></td></tr> - <tr><th>12.3.3</th><td><a href="#12.3.3"><code>null</code>/<code>not_null</code></a></td></tr> - <tr><th>12.3.4</th><td><a href="#12.3.4"><code>default</code></a></td></tr> - <tr><th>12.3.5</th><td><a href="#12.3.5"><code>options</code></a></td></tr> - <tr><th>12.3.6</th><td><a href="#12.3.6"><code>readonly</code></a></td></tr> - <tr><th>12.3.7</th><td><a href="#12.3.7"><code>definition</code></a></td></tr> - <tr><th>12.3.8</th><td><a href="#12.3.8"><code>transient</code></a></td></tr> - <tr><th>12.3.9</th><td><a href="#12.3.9"><code>unordered</code></a></td></tr> - <tr><th>12.3.10</th><td><a href="#12.3.10"><code>index_type</code></a></td></tr> - <tr><th>12.3.11</th><td><a href="#12.3.11"><code>key_type</code></a></td></tr> - <tr><th>12.3.12</th><td><a href="#12.3.12"><code>value_type</code></a></td></tr> - <tr><th>12.3.13</th><td><a href="#12.3.13"><code>value_null</code>/<code>value_not_null</code></a></td></tr> - <tr><th>12.3.14</th><td><a href="#12.3.14"><code>id_options</code></a></td></tr> - <tr><th>12.3.15</th><td><a href="#12.3.15"><code>index_options</code></a></td></tr> - <tr><th>12.3.16</th><td><a href="#12.3.16"><code>key_options</code></a></td></tr> - <tr><th>12.3.17</th><td><a href="#12.3.17"><code>value_options</code></a></td></tr> - <tr><th>12.3.18</th><td><a href="#12.3.18"><code>id_column</code></a></td></tr> - <tr><th>12.3.19</th><td><a href="#12.3.19"><code>index_column</code></a></td></tr> - <tr><th>12.3.20</th><td><a href="#12.3.20"><code>key_column</code></a></td></tr> - <tr><th>12.3.21</th><td><a href="#12.3.21"><code>value_column</code></a></td></tr> + <tr><th>14.3.1</th><td><a href="#14.3.1"><code>type</code></a></td></tr> + <tr><th>14.3.2</th><td><a href="#14.3.2"><code>id_type</code></a></td></tr> + <tr><th>14.3.3</th><td><a href="#14.3.3"><code>null</code>/<code>not_null</code></a></td></tr> + <tr><th>14.3.4</th><td><a href="#14.3.4"><code>default</code></a></td></tr> + <tr><th>14.3.5</th><td><a href="#14.3.5"><code>options</code></a></td></tr> + <tr><th>14.3.6</th><td><a href="#14.3.6"><code>readonly</code></a></td></tr> + <tr><th>14.3.7</th><td><a href="#14.3.7"><code>definition</code></a></td></tr> + <tr><th>14.3.8</th><td><a href="#14.3.8"><code>transient</code></a></td></tr> + <tr><th>14.3.9</th><td><a href="#14.3.9"><code>unordered</code></a></td></tr> + <tr><th>14.3.10</th><td><a href="#14.3.10"><code>index_type</code></a></td></tr> + <tr><th>14.3.11</th><td><a href="#14.3.11"><code>key_type</code></a></td></tr> + <tr><th>14.3.12</th><td><a href="#14.3.12"><code>value_type</code></a></td></tr> + <tr><th>14.3.13</th><td><a href="#14.3.13"><code>value_null</code>/<code>value_not_null</code></a></td></tr> + <tr><th>14.3.14</th><td><a href="#14.3.14"><code>id_options</code></a></td></tr> + <tr><th>14.3.15</th><td><a href="#14.3.15"><code>index_options</code></a></td></tr> + <tr><th>14.3.16</th><td><a href="#14.3.16"><code>key_options</code></a></td></tr> + <tr><th>14.3.17</th><td><a href="#14.3.17"><code>value_options</code></a></td></tr> + <tr><th>14.3.18</th><td><a href="#14.3.18"><code>id_column</code></a></td></tr> + <tr><th>14.3.19</th><td><a href="#14.3.19"><code>index_column</code></a></td></tr> + <tr><th>14.3.20</th><td><a href="#14.3.20"><code>key_column</code></a></td></tr> + <tr><th>14.3.21</th><td><a href="#14.3.21"><code>value_column</code></a></td></tr> </table> </td> </tr> <tr> - <th>12.4</th><td><a href="#12.4">Data Member Pragmas</a> + <th>14.4</th><td><a href="#14.4">Data Member Pragmas</a> <table class="toc"> - <tr><th>12.4.1</th><td><a href="#12.4.1"><code>id</code></a></td></tr> - <tr><th>12.4.2</th><td><a href="#12.4.2"><code>auto</code></a></td></tr> - <tr><th>12.4.3</th><td><a href="#12.4.3"><code>type</code></a></td></tr> - <tr><th>12.4.4</th><td><a href="#12.4.4"><code>id_type</code></a></td></tr> - <tr><th>12.4.5</th><td><a href="#12.4.5"><code>get</code>/<code>set</code>/<code>access</code></a></td></tr> - <tr><th>12.4.6</th><td><a href="#12.4.6"><code>null</code>/<code>not_null</code></a></td></tr> - <tr><th>12.4.7</th><td><a href="#12.4.7"><code>default</code></a></td></tr> - <tr><th>12.4.8</th><td><a href="#12.4.8"><code>options</code></a></td></tr> - <tr><th>12.4.9</th><td><a href="#12.4.9"><code>column</code> (object, composite value)</a></td></tr> - <tr><th>12.4.10</th><td><a href="#12.4.10"><code>column</code> (view)</a></td></tr> - <tr><th>12.4.11</th><td><a href="#12.4.11"><code>transient</code></a></td></tr> - <tr><th>12.4.12</th><td><a href="#12.4.12"><code>readonly</code></a></td></tr> - <tr><th>12.4.13</th><td><a href="#12.4.13"><code>virtual</code></a></td></tr> - <tr><th>12.4.14</th><td><a href="#12.4.14"><code>inverse</code></a></td></tr> - <tr><th>12.4.15</th><td><a href="#12.4.15"><code>version</code></a></td></tr> - <tr><th>12.4.16</th><td><a href="#12.4.16"><code>index</code></a></td></tr> - <tr><th>12.4.17</th><td><a href="#12.4.17"><code>unique</code></a></td></tr> - <tr><th>12.4.18</th><td><a href="#12.4.18"><code>unordered</code></a></td></tr> - <tr><th>12.4.19</th><td><a href="#12.4.19"><code>table</code></a></td></tr> - <tr><th>12.4.20</th><td><a href="#12.4.20"><code>index_type</code></a></td></tr> - <tr><th>12.4.21</th><td><a href="#12.4.21"><code>key_type</code></a></td></tr> - <tr><th>12.4.22</th><td><a href="#12.4.22"><code>value_type</code></a></td></tr> - <tr><th>12.4.23</th><td><a href="#12.4.23"><code>value_null</code>/<code>value_not_null</code></a></td></tr> - <tr><th>12.4.24</th><td><a href="#12.4.24"><code>id_options</code></a></td></tr> - <tr><th>12.4.25</th><td><a href="#12.4.25"><code>index_options</code></a></td></tr> - <tr><th>12.4.26</th><td><a href="#12.4.26"><code>key_options</code></a></td></tr> - <tr><th>12.4.27</th><td><a href="#12.4.27"><code>value_options</code></a></td></tr> - <tr><th>12.4.28</th><td><a href="#12.4.28"><code>id_column</code></a></td></tr> - <tr><th>12.4.29</th><td><a href="#12.4.29"><code>index_column</code></a></td></tr> - <tr><th>12.4.30</th><td><a href="#12.4.30"><code>key_column</code></a></td></tr> - <tr><th>12.4.31</th><td><a href="#12.4.31"><code>value_column</code></a></td></tr> + <tr><th>14.4.1</th><td><a href="#14.4.1"><code>id</code></a></td></tr> + <tr><th>14.4.2</th><td><a href="#14.4.2"><code>auto</code></a></td></tr> + <tr><th>14.4.3</th><td><a href="#14.4.3"><code>type</code></a></td></tr> + <tr><th>14.4.4</th><td><a href="#14.4.4"><code>id_type</code></a></td></tr> + <tr><th>14.4.5</th><td><a href="#14.4.5"><code>get</code>/<code>set</code>/<code>access</code></a></td></tr> + <tr><th>14.4.6</th><td><a href="#14.4.6"><code>null</code>/<code>not_null</code></a></td></tr> + <tr><th>14.4.7</th><td><a href="#14.4.7"><code>default</code></a></td></tr> + <tr><th>14.4.8</th><td><a href="#14.4.8"><code>options</code></a></td></tr> + <tr><th>14.4.9</th><td><a href="#14.4.9"><code>column</code> (object, composite value)</a></td></tr> + <tr><th>14.4.10</th><td><a href="#14.4.10"><code>column</code> (view)</a></td></tr> + <tr><th>14.4.11</th><td><a href="#14.4.11"><code>transient</code></a></td></tr> + <tr><th>14.4.12</th><td><a href="#14.4.12"><code>readonly</code></a></td></tr> + <tr><th>14.4.13</th><td><a href="#14.4.13"><code>virtual</code></a></td></tr> + <tr><th>14.4.14</th><td><a href="#14.4.14"><code>inverse</code></a></td></tr> + <tr><th>14.4.15</th><td><a href="#14.4.15"><code>version</code></a></td></tr> + <tr><th>14.4.16</th><td><a href="#14.4.16"><code>index</code></a></td></tr> + <tr><th>14.4.17</th><td><a href="#14.4.17"><code>unique</code></a></td></tr> + <tr><th>14.4.18</th><td><a href="#14.4.18"><code>unordered</code></a></td></tr> + <tr><th>14.4.19</th><td><a href="#14.4.19"><code>table</code></a></td></tr> + <tr><th>14.4.20</th><td><a href="#14.4.20"><code>load</code>/<code>update</code></a></td></tr> + <tr><th>14.4.21</th><td><a href="#14.4.21"><code>section</code></a></td></tr> + <tr><th>14.4.22</th><td><a href="#14.4.22"><code>index_type</code></a></td></tr> + <tr><th>14.4.23</th><td><a href="#14.4.23"><code>key_type</code></a></td></tr> + <tr><th>14.4.24</th><td><a href="#14.4.24"><code>value_type</code></a></td></tr> + <tr><th>14.4.25</th><td><a href="#14.4.25"><code>value_null</code>/<code>value_not_null</code></a></td></tr> + <tr><th>14.4.26</th><td><a href="#14.4.26"><code>id_options</code></a></td></tr> + <tr><th>14.4.27</th><td><a href="#14.4.27"><code>index_options</code></a></td></tr> + <tr><th>14.4.28</th><td><a href="#14.4.28"><code>key_options</code></a></td></tr> + <tr><th>14.4.29</th><td><a href="#14.4.29"><code>value_options</code></a></td></tr> + <tr><th>14.4.30</th><td><a href="#14.4.30"><code>id_column</code></a></td></tr> + <tr><th>14.4.31</th><td><a href="#14.4.31"><code>index_column</code></a></td></tr> + <tr><th>14.4.32</th><td><a href="#14.4.32"><code>key_column</code></a></td></tr> + <tr><th>14.4.33</th><td><a href="#14.4.33"><code>value_column</code></a></td></tr> </table> </td> </tr> <tr> - <th>12.5</th><td><a href="#12.5">Namespace Pragmas</a> + <th>14.5</th><td><a href="#14.5">Namespace Pragmas</a> <table class="toc"> - <tr><th>12.5.1</th><td><a href="#12.5.1"><code>pointer</code></a></td></tr> - <tr><th>12.5.2</th><td><a href="#12.5.2"><code>table</code></a></td></tr> - <tr><th>12.5.3</th><td><a href="#12.5.3"><code>schema</code></a></td></tr> - <tr><th>12.5.4</th><td><a href="#12.5.4"><code>session</code></a></td></tr> + <tr><th>14.5.1</th><td><a href="#14.5.1"><code>pointer</code></a></td></tr> + <tr><th>14.5.2</th><td><a href="#14.5.2"><code>table</code></a></td></tr> + <tr><th>14.5.3</th><td><a href="#14.5.3"><code>schema</code></a></td></tr> + <tr><th>14.5.4</th><td><a href="#14.5.4"><code>session</code></a></td></tr> </table> </td> </tr> <tr> - <th>12.6</th><td><a href="#12.6">Index Definition Pragmas</a></td> + <th>14.6</th><td><a href="#14.6">Index Definition Pragmas</a></td> </tr> <tr> - <th>12.7</th><td><a href="#12.7">Database Type Mapping Pragmas</a></td> + <th>14.7</th><td><a href="#14.7">Database Type Mapping Pragmas</a></td> </tr> <tr> - <th>12.8</th><td><a href="#12.8">C++ Compiler Warnings</a> + <th>14.8</th><td><a href="#14.8">C++ Compiler Warnings</a> <table class="toc"> - <tr><th>12.8.1</th><td><a href="#12.8.1">GNU C++</a></td></tr> - <tr><th>12.8.2</th><td><a href="#12.8.2">Visual C++</a></td></tr> - <tr><th>12.8.3</th><td><a href="#12.8.3">Sun C++</a></td></tr> - <tr><th>12.8.4</th><td><a href="#12.8.4">IBM XL C++</a></td></tr> - <tr><th>12.8.5</th><td><a href="#12.8.5">HP aC++</a></td></tr> - <tr><th>12.8.6</th><td><a href="#12.8.6">Clang</a></td></tr> + <tr><th>14.8.1</th><td><a href="#14.8.1">GNU C++</a></td></tr> + <tr><th>14.8.2</th><td><a href="#14.8.2">Visual C++</a></td></tr> + <tr><th>14.8.3</th><td><a href="#14.8.3">Sun C++</a></td></tr> + <tr><th>14.8.4</th><td><a href="#14.8.4">IBM XL C++</a></td></tr> + <tr><th>14.8.5</th><td><a href="#14.8.5">HP aC++</a></td></tr> + <tr><th>14.8.6</th><td><a href="#14.8.6">Clang</a></td></tr> </table> </td> </tr> @@ -585,9 +599,9 @@ for consistency. </tr> <tr> - <th>13</th><td><a href="#13">Advanced Techniques and Mechanisms</a> + <th>15</th><td><a href="#15">Advanced Techniques and Mechanisms</a> <table class="toc"> - <tr><th>13.1</th><td><a href="#13.1">Transaction Callbacks</a></td></tr> + <tr><th>15.1</th><td><a href="#15.1">Transaction Callbacks</a></td></tr> </table> </td> </tr> @@ -597,13 +611,13 @@ for consistency. </tr> <tr> - <th>14</th><td><a href="#14">Multi-Database Support</a> + <th>16</th><td><a href="#16">Multi-Database Support</a> <table class="toc"> - <tr><th>14.1</th><td><a href="#14.1">Static Multi-Database Support</a></td></tr> + <tr><th>16.1</th><td><a href="#16.1">Static Multi-Database Support</a></td></tr> <tr> - <th>14.2</th><td><a href="#14.2">Dynamic Multi-Database Support</a> + <th>16.2</th><td><a href="#16.2">Dynamic Multi-Database Support</a> <table class="toc"> - <tr><th>14.2.2</th><td><a href="#14.2.2">14.2.2 Dynamic Loading of Database Support Code</a></td></tr> + <tr><th>16.2.2</th><td><a href="#16.2.2">16.2.2 Dynamic Loading of Database Support Code</a></td></tr> </table> </td> </tr> @@ -612,156 +626,156 @@ for consistency. </tr> <tr> - <th>15</th><td><a href="#15">MySQL Database</a> + <th>17</th><td><a href="#17">MySQL Database</a> <table class="toc"> <tr> - <th>15.1</th><td><a href="#15.1">MySQL Type Mapping</a> + <th>17.1</th><td><a href="#17.1">MySQL Type Mapping</a> <table class="toc"> - <tr><th>15.1.1</th><td><a href="#15.1.1">String Type Mapping</a></td></tr> - <tr><th>15.1.2</th><td><a href="#15.1.2">Binary Type Mapping</a></td></tr> + <tr><th>17.1.1</th><td><a href="#17.1.1">String Type Mapping</a></td></tr> + <tr><th>17.1.2</th><td><a href="#17.1.2">Binary Type Mapping</a></td></tr> </table> </td> </tr> - <tr><th>15.2</th><td><a href="#15.2">MySQL Database Class</a></td></tr> - <tr><th>15.3</th><td><a href="#15.3">MySQL Connection and Connection Factory</a></td></tr> - <tr><th>15.4</th><td><a href="#15.4">MySQL Exceptions</a></td></tr> + <tr><th>17.2</th><td><a href="#17.2">MySQL Database Class</a></td></tr> + <tr><th>17.3</th><td><a href="#17.3">MySQL Connection and Connection Factory</a></td></tr> + <tr><th>17.4</th><td><a href="#17.4">MySQL Exceptions</a></td></tr> <tr> - <th>15.5</th><td><a href="#15.5">MySQL Limitations</a> + <th>17.5</th><td><a href="#17.5">MySQL Limitations</a> <table class="toc"> - <tr><th>15.5.1</th><td><a href="#15.5.1">Foreign Key Constraints</a></td></tr> + <tr><th>17.5.1</th><td><a href="#17.5.1">Foreign Key Constraints</a></td></tr> </table> </td> </tr> - <tr><th>15.6</th><td><a href="#15.6">MySQL Index Definition</a></td></tr> + <tr><th>17.6</th><td><a href="#17.6">MySQL Index Definition</a></td></tr> </table> </td> </tr> <tr> - <th>16</th><td><a href="#16">SQLite Database</a> + <th>18</th><td><a href="#18">SQLite Database</a> <table class="toc"> <tr> - <th>16.1</th><td><a href="#16.1">SQLite Type Mapping</a> + <th>18.1</th><td><a href="#18.1">SQLite Type Mapping</a> <table class="toc"> - <tr><th>16.1.1</th><td><a href="#16.1.1">String Type Mapping</a></td></tr> - <tr><th>16.1.2</th><td><a href="#16.1.2">Binary Type Mapping</a></td></tr> + <tr><th>18.1.1</th><td><a href="#18.1.1">String Type Mapping</a></td></tr> + <tr><th>18.1.2</th><td><a href="#18.1.2">Binary Type Mapping</a></td></tr> </table> </td> </tr> - <tr><th>16.2</th><td><a href="#16.2">SQLite Database Class</a></td></tr> - <tr><th>16.3</th><td><a href="#16.3">SQLite Connection and Connection Factory</a></td></tr> - <tr><th>16.4</th><td><a href="#16.4">SQLite Exceptions</a></td></tr> + <tr><th>18.2</th><td><a href="#18.2">SQLite Database Class</a></td></tr> + <tr><th>18.3</th><td><a href="#18.3">SQLite Connection and Connection Factory</a></td></tr> + <tr><th>18.4</th><td><a href="#18.4">SQLite Exceptions</a></td></tr> <tr> - <th>16.5</th><td><a href="#16.5">SQLite Limitations</a> + <th>18.5</th><td><a href="#18.5">SQLite Limitations</a> <table class="toc"> - <tr><th>16.5.1</th><td><a href="#16.5.1">Query Result Caching</a></td></tr> - <tr><th>16.5.2</th><td><a href="#16.5.2">Automatic Assignment of Object Ids</a></td></tr> - <tr><th>16.5.3</th><td><a href="#16.5.3">Foreign Key Constraints</a></td></tr> - <tr><th>16.5.4</th><td><a href="#16.5.4">Constraint Violations</a></td></tr> - <tr><th>16.5.5</th><td><a href="#16.5.5">Sharing of Queries</a></td></tr> - <tr><th>16.5.6</th><td><a href="#16.5.6">Forced Rollback</a></td></tr> + <tr><th>18.5.1</th><td><a href="#18.5.1">Query Result Caching</a></td></tr> + <tr><th>18.5.2</th><td><a href="#18.5.2">Automatic Assignment of Object Ids</a></td></tr> + <tr><th>18.5.3</th><td><a href="#18.5.3">Foreign Key Constraints</a></td></tr> + <tr><th>18.5.4</th><td><a href="#18.5.4">Constraint Violations</a></td></tr> + <tr><th>18.5.5</th><td><a href="#18.5.5">Sharing of Queries</a></td></tr> + <tr><th>18.5.6</th><td><a href="#18.5.6">Forced Rollback</a></td></tr> </table> </td> </tr> - <tr><th>16.6</th><td><a href="#16.6">SQLite Index Definition</a></td></tr> + <tr><th>18.6</th><td><a href="#18.6">SQLite Index Definition</a></td></tr> </table> </td> </tr> <tr> - <th>17</th><td><a href="#17">PostgreSQL Database</a> + <th>19</th><td><a href="#19">PostgreSQL Database</a> <table class="toc"> <tr> - <th>17.1</th><td><a href="#17.1">PostgreSQL Type Mapping</a> + <th>19.1</th><td><a href="#19.1">PostgreSQL Type Mapping</a> <table class="toc"> - <tr><th>17.1.1</th><td><a href="#17.1.1">String Type Mapping</a></td></tr> - <tr><th>17.1.2</th><td><a href="#17.1.2">Binary Type and <code>UUID</code> Mapping</a></td></tr> + <tr><th>19.1.1</th><td><a href="#19.1.1">String Type Mapping</a></td></tr> + <tr><th>19.1.2</th><td><a href="#19.1.2">Binary Type and <code>UUID</code> Mapping</a></td></tr> </table> </td> </tr> - <tr><th>17.2</th><td><a href="#17.2">PostgreSQL Database Class</a></td></tr> - <tr><th>17.3</th><td><a href="#17.3">PostgreSQL Connection and Connection Factory</a></td></tr> - <tr><th>17.4</th><td><a href="#17.4">PostgreSQL Exceptions</a></td></tr> + <tr><th>19.2</th><td><a href="#19.2">PostgreSQL Database Class</a></td></tr> + <tr><th>19.3</th><td><a href="#19.3">PostgreSQL Connection and Connection Factory</a></td></tr> + <tr><th>19.4</th><td><a href="#19.4">PostgreSQL Exceptions</a></td></tr> <tr> - <th>17.5</th><td><a href="#17.5">PostgreSQL Limitations</a> + <th>19.5</th><td><a href="#19.5">PostgreSQL Limitations</a> <table class="toc"> - <tr><th>17.5.1</th><td><a href="#17.5.1">Query Result Caching</a></td></tr> - <tr><th>17.5.2</th><td><a href="#17.5.2">Foreign Key Constraints</a></td></tr> - <tr><th>17.5.3</th><td><a href="#17.5.3">Unique Constraint Violations</a></td></tr> - <tr><th>17.5.4</th><td><a href="#17.5.4">Date-Time Format</a></td></tr> - <tr><th>17.5.5</th><td><a href="#17.5.5">Timezones</a></td></tr> - <tr><th>17.5.6</th><td><a href="#17.5.6"><code>NUMERIC</code> Type Support</a></td></tr> + <tr><th>19.5.1</th><td><a href="#19.5.1">Query Result Caching</a></td></tr> + <tr><th>19.5.2</th><td><a href="#19.5.2">Foreign Key Constraints</a></td></tr> + <tr><th>19.5.3</th><td><a href="#19.5.3">Unique Constraint Violations</a></td></tr> + <tr><th>19.5.4</th><td><a href="#19.5.4">Date-Time Format</a></td></tr> + <tr><th>19.5.5</th><td><a href="#19.5.5">Timezones</a></td></tr> + <tr><th>19.5.6</th><td><a href="#19.5.6"><code>NUMERIC</code> Type Support</a></td></tr> </table> </td> </tr> - <tr><th>17.6</th><td><a href="#17.6">PostgreSQL Index Definition</a></td></tr> + <tr><th>19.6</th><td><a href="#19.6">PostgreSQL Index Definition</a></td></tr> </table> </td> </tr> <tr> - <th>18</th><td><a href="#18">Oracle Database</a> + <th>20</th><td><a href="#20">Oracle Database</a> <table class="toc"> <tr> - <th>18.1</th><td><a href="#18.1">Oracle Type Mapping</a> + <th>20.1</th><td><a href="#20.1">Oracle Type Mapping</a> <table class="toc"> - <tr><th>18.1.1</th><td><a href="#18.1.1">String Type Mapping</a></td></tr> - <tr><th>18.1.2</th><td><a href="#18.1.2">Binary Type Mapping</a></td></tr> + <tr><th>20.1.1</th><td><a href="#20.1.1">String Type Mapping</a></td></tr> + <tr><th>20.1.2</th><td><a href="#20.1.2">Binary Type Mapping</a></td></tr> </table> </td> </tr> - <tr><th>18.2</th><td><a href="#18.2">Oracle Database Class</a></td></tr> - <tr><th>18.3</th><td><a href="#18.3">Oracle Connection and Connection Factory</a></td></tr> - <tr><th>18.4</th><td><a href="#18.4">Oracle Exceptions</a></td></tr> + <tr><th>20.2</th><td><a href="#20.2">Oracle Database Class</a></td></tr> + <tr><th>20.3</th><td><a href="#20.3">Oracle Connection and Connection Factory</a></td></tr> + <tr><th>20.4</th><td><a href="#20.4">Oracle Exceptions</a></td></tr> <tr> - <th>18.5</th><td><a href="#18.5">Oracle Limitations</a> + <th>20.5</th><td><a href="#20.5">Oracle Limitations</a> <table class="toc"> - <tr><th>18.5.1</th><td><a href="#18.5.1">Identifier Truncation</a></td></tr> - <tr><th>18.5.2</th><td><a href="#18.5.2">Query Result Caching</a></td></tr> - <tr><th>18.5.3</th><td><a href="#18.5.3">Foreign Key Constraints</a></td></tr> - <tr><th>18.5.4</th><td><a href="#18.5.4">Unique Constraint Violations</a></td></tr> - <tr><th>18.5.5</th><td><a href="#18.5.5">Large <code>FLOAT</code> and <code>NUMBER</code> Types</a></td></tr> - <tr><th>18.5.6</th><td><a href="#18.5.6">Timezones</a></td></tr> - <tr><th>18.5.7</th><td><a href="#18.5.7"><code>LONG</code> Types</a></td></tr> - <tr><th>18.5.8</th><td><a href="#18.5.8">LOB Types and By-Value Accessors/Modifiers</a></td></tr> + <tr><th>20.5.1</th><td><a href="#20.5.1">Identifier Truncation</a></td></tr> + <tr><th>20.5.2</th><td><a href="#20.5.2">Query Result Caching</a></td></tr> + <tr><th>20.5.3</th><td><a href="#20.5.3">Foreign Key Constraints</a></td></tr> + <tr><th>20.5.4</th><td><a href="#20.5.4">Unique Constraint Violations</a></td></tr> + <tr><th>20.5.5</th><td><a href="#20.5.5">Large <code>FLOAT</code> and <code>NUMBER</code> Types</a></td></tr> + <tr><th>20.5.6</th><td><a href="#20.5.6">Timezones</a></td></tr> + <tr><th>20.5.7</th><td><a href="#20.5.7"><code>LONG</code> Types</a></td></tr> + <tr><th>20.5.8</th><td><a href="#20.5.8">LOB Types and By-Value Accessors/Modifiers</a></td></tr> </table> </td> </tr> - <tr><th>18.6</th><td><a href="#18.6">Oracle Index Definition</a></td></tr> + <tr><th>20.6</th><td><a href="#20.6">Oracle Index Definition</a></td></tr> </table> </td> </tr> <tr> - <th>19</th><td><a href="#19">Microsoft SQL Server Database</a> + <th>21</th><td><a href="#21">Microsoft SQL Server Database</a> <table class="toc"> <tr> - <th>19.1</th><td><a href="#19.1">SQL Server Type Mapping</a> + <th>21.1</th><td><a href="#21.1">SQL Server Type Mapping</a> <table class="toc"> - <tr><th>19.1.1</th><td><a href="#19.1.1">String Type Mapping</a></td></tr> - <tr><th>19.1.2</th><td><a href="#19.1.2">Binary Type and <code>UNIQUEIDENTIFIER</code> Mapping</a></td></tr> - <tr><th>19.1.3</th><td><a href="#19.1.3"><code>ROWVERSION</code> Mapping</a></td></tr> - <tr><th>19.1.4</th><td><a href="#19.1.4">Long String and Binary Types</a></td></tr> + <tr><th>21.1.1</th><td><a href="#21.1.1">String Type Mapping</a></td></tr> + <tr><th>21.1.2</th><td><a href="#21.1.2">Binary Type and <code>UNIQUEIDENTIFIER</code> Mapping</a></td></tr> + <tr><th>21.1.3</th><td><a href="#21.1.3"><code>ROWVERSION</code> Mapping</a></td></tr> + <tr><th>21.1.4</th><td><a href="#21.1.4">Long String and Binary Types</a></td></tr> </table> </td> </tr> - <tr><th>19.2</th><td><a href="#19.2">SQL Server Database Class</a></td></tr> - <tr><th>19.3</th><td><a href="#19.3">SQL Server Connection and Connection Factory</a></td></tr> - <tr><th>19.4</th><td><a href="#19.4">SQL Server Exceptions</a></td></tr> + <tr><th>21.2</th><td><a href="#21.2">SQL Server Database Class</a></td></tr> + <tr><th>21.3</th><td><a href="#21.3">SQL Server Connection and Connection Factory</a></td></tr> + <tr><th>21.4</th><td><a href="#21.4">SQL Server Exceptions</a></td></tr> <tr> - <th>19.5</th><td><a href="#19.5">SQL Server Limitations</a> + <th>21.5</th><td><a href="#21.5">SQL Server Limitations</a> <table class="toc"> - <tr><th>19.5.1</th><td><a href="#19.5.1">Query Result Caching</a></td></tr> - <tr><th>19.5.2</th><td><a href="#19.5.2">Foreign Key Constraints</a></td></tr> - <tr><th>19.5.3</th><td><a href="#19.5.3">Unique Constraint Violations</a></td></tr> - <tr><th>19.5.4</th><td><a href="#19.5.4">Multi-threaded Windows Applications</a></td></tr> - <tr><th>19.5.5</th><td><a href="#19.5.5">Affected Row Count and DDL Statements</a></td></tr> - <tr><th>19.5.6</th><td><a href="#19.5.6">Long Data and Auto Object Ids, <code>ROWVERSION</code></a></td></tr> - <tr><th>19.5.7</th><td><a href="#19.5.7">Long Data and By-Value Accessors/Modifiers</a></td></tr> + <tr><th>21.5.1</th><td><a href="#21.5.1">Query Result Caching</a></td></tr> + <tr><th>21.5.2</th><td><a href="#21.5.2">Foreign Key Constraints</a></td></tr> + <tr><th>21.5.3</th><td><a href="#21.5.3">Unique Constraint Violations</a></td></tr> + <tr><th>21.5.4</th><td><a href="#21.5.4">Multi-threaded Windows Applications</a></td></tr> + <tr><th>21.5.5</th><td><a href="#21.5.5">Affected Row Count and DDL Statements</a></td></tr> + <tr><th>21.5.6</th><td><a href="#21.5.6">Long Data and Auto Object Ids, <code>ROWVERSION</code></a></td></tr> + <tr><th>21.5.7</th><td><a href="#21.5.7">Long Data and By-Value Accessors/Modifiers</a></td></tr> </table> </td> </tr> - <tr><th>19.6</th><td><a href="#19.6">SQL Server Index Definition</a></td></tr> + <tr><th>21.6</th><td><a href="#21.6">SQL Server Index Definition</a></td></tr> </table> </td> </tr> @@ -771,35 +785,35 @@ for consistency. </tr> <tr> - <th>20</th><td><a href="#20">Profiles Introduction</a></td> + <th>22</th><td><a href="#22">Profiles Introduction</a></td> </tr> <tr> - <th>21</th><td><a href="#21">Boost Profile</a> + <th>23</th><td><a href="#23">Boost Profile</a> <table class="toc"> - <tr><th>21.1</th><td><a href="#21.1">Smart Pointers Library</a></td></tr> - <tr><th>21.2</th><td><a href="#21.2">Unordered Containers Library</a></td></tr> - <tr><th>21.3</th><td><a href="#21.3">Multi-Index Container Library</a></td></tr> - <tr><th>21.4</th><td><a href="#21.4">Optional Library</a></td></tr> + <tr><th>23.1</th><td><a href="#23.1">Smart Pointers Library</a></td></tr> + <tr><th>23.2</th><td><a href="#23.2">Unordered Containers Library</a></td></tr> + <tr><th>23.3</th><td><a href="#23.3">Multi-Index Container Library</a></td></tr> + <tr><th>23.4</th><td><a href="#23.4">Optional Library</a></td></tr> <tr> - <th>21.5</th><td><a href="#21.5">Date Time Library</a> + <th>23.5</th><td><a href="#23.5">Date Time Library</a> <table class="toc"> - <tr><th>21.5.1</th><td><a href="#21.5.1">MySQL Database Type Mapping</a></td></tr> - <tr><th>21.5.2</th><td><a href="#21.5.2">SQLite Database Type Mapping</a></td></tr> - <tr><th>21.5.3</th><td><a href="#21.5.3">PostgreSQL Database Type Mapping</a></td></tr> - <tr><th>21.5.4</th><td><a href="#21.5.4">Oracle Database Type Mapping</a></td></tr> - <tr><th>21.5.5</th><td><a href="#21.5.5">SQL Server Database Type Mapping</a></td></tr> + <tr><th>23.5.1</th><td><a href="#23.5.1">MySQL Database Type Mapping</a></td></tr> + <tr><th>23.5.2</th><td><a href="#23.5.2">SQLite Database Type Mapping</a></td></tr> + <tr><th>23.5.3</th><td><a href="#23.5.3">PostgreSQL Database Type Mapping</a></td></tr> + <tr><th>23.5.4</th><td><a href="#23.5.4">Oracle Database Type Mapping</a></td></tr> + <tr><th>23.5.5</th><td><a href="#23.5.5">SQL Server Database Type Mapping</a></td></tr> </table> </td> </tr> <tr> - <th>21.6</th><td><a href="#21.6">Uuid Library</a> + <th>23.6</th><td><a href="#23.6">Uuid Library</a> <table class="toc"> - <tr><th>21.6.1</th><td><a href="#21.6.1">MySQL Database Type Mapping</a></td></tr> - <tr><th>21.6.2</th><td><a href="#21.6.2">SQLite Database Type Mapping</a></td></tr> - <tr><th>21.6.3</th><td><a href="#21.6.3">PostgreSQL Database Type Mapping</a></td></tr> - <tr><th>21.6.4</th><td><a href="#21.6.4">Oracle Database Type Mapping</a></td></tr> - <tr><th>21.6.5</th><td><a href="#21.6.5">SQL Server Database Type Mapping</a></td></tr> + <tr><th>23.6.1</th><td><a href="#23.6.1">MySQL Database Type Mapping</a></td></tr> + <tr><th>23.6.2</th><td><a href="#23.6.2">SQLite Database Type Mapping</a></td></tr> + <tr><th>23.6.3</th><td><a href="#23.6.3">PostgreSQL Database Type Mapping</a></td></tr> + <tr><th>23.6.4</th><td><a href="#23.6.4">Oracle Database Type Mapping</a></td></tr> + <tr><th>23.6.5</th><td><a href="#23.6.5">SQL Server Database Type Mapping</a></td></tr> </table> </td> </tr> @@ -808,35 +822,35 @@ for consistency. </tr> <tr> - <th>22</th><td><a href="#22">Qt Profile</a> + <th>24</th><td><a href="#24">Qt Profile</a> <table class="toc"> <tr> - <th>22.1</th><td><a href="#22.1">Basic Types Library</a> + <th>24.1</th><td><a href="#24.1">Basic Types Library</a> <table class="toc"> - <tr><th>22.1.1</th><td><a href="#22.1.1">MySQL Database Type Mapping</a></td></tr> - <tr><th>22.1.2</th><td><a href="#22.1.2">SQLite Database Type Mapping</a></td></tr> - <tr><th>22.1.3</th><td><a href="#22.1.3">PostgreSQL Database Type Mapping</a></td></tr> - <tr><th>22.1.4</th><td><a href="#22.1.4">Oracle Database Type Mapping</a></td></tr> - <tr><th>22.1.5</th><td><a href="#22.1.5">SQL Server Database Type Mapping</a></td></tr> + <tr><th>24.1.1</th><td><a href="#24.1.1">MySQL Database Type Mapping</a></td></tr> + <tr><th>24.1.2</th><td><a href="#24.1.2">SQLite Database Type Mapping</a></td></tr> + <tr><th>24.1.3</th><td><a href="#24.1.3">PostgreSQL Database Type Mapping</a></td></tr> + <tr><th>24.1.4</th><td><a href="#24.1.4">Oracle Database Type Mapping</a></td></tr> + <tr><th>24.1.5</th><td><a href="#24.1.5">SQL Server Database Type Mapping</a></td></tr> </table> </td> </tr> - <tr><th>22.2</th><td><a href="#22.2">Smart Pointers Library</a></td></tr> + <tr><th>24.2</th><td><a href="#24.2">Smart Pointers Library</a></td></tr> <tr> - <th>22.3</th><td><a href="#22.3">Containers Library</a> + <th>24.3</th><td><a href="#24.3">Containers Library</a> <table class="toc"> - <tr><th>22.3.1</th><td><a href="#22.3.1">Change-Tracking <code>QList</code></a></td></tr> + <tr><th>24.3.1</th><td><a href="#24.3.1">Change-Tracking <code>QList</code></a></td></tr> </table> </td> </tr> <tr> - <th>22.4</th><td><a href="#22.4">Date Time Library</a> + <th>24.4</th><td><a href="#24.4">Date Time Library</a> <table class="toc"> - <tr><th>22.4.1</th><td><a href="#22.4.1">MySQL Database Type Mapping</a></td></tr> - <tr><th>22.4.2</th><td><a href="#22.4.2">SQLite Database Type Mapping</a></td></tr> - <tr><th>22.4.3</th><td><a href="#22.4.3">PostgreSQL Database Type Mapping</a></td></tr> - <tr><th>22.4.4</th><td><a href="#22.4.4">Oracle Database Type Mapping</a></td></tr> - <tr><th>22.4.5</th><td><a href="#22.4.5">SQL Server Database Type Mapping</a></td></tr> + <tr><th>24.4.1</th><td><a href="#24.4.1">MySQL Database Type Mapping</a></td></tr> + <tr><th>24.4.2</th><td><a href="#24.4.2">SQLite Database Type Mapping</a></td></tr> + <tr><th>24.4.3</th><td><a href="#24.4.3">PostgreSQL Database Type Mapping</a></td></tr> + <tr><th>24.4.4</th><td><a href="#24.4.4">Oracle Database Type Mapping</a></td></tr> + <tr><th>24.4.5</th><td><a href="#24.4.5">SQL Server Database Type Mapping</a></td></tr> </table> </td> </tr> @@ -957,10 +971,10 @@ for consistency. <tr><th>6</th><td><a href="#6">Relationships</a></td></tr> <tr><th>7</th><td><a href="#7">Value Types</a></td></tr> <tr><th>8</th><td><a href="#8">Inheritance</a></td></tr> - <tr><th>9</th><td><a href="#9">Views</a></td></tr> - <tr><th>10</th><td><a href="#10">Session</a></td></tr> - <tr><th>11</th><td><a href="#11">Optimistic Concurrency</a></td></tr> - <tr><th>12</th><td><a href="#12">ODB Pragma Language</a></td></tr> + <tr><th>10</th><td><a href="#10">Views</a></td></tr> + <tr><th>11</th><td><a href="#11">Session</a></td></tr> + <tr><th>12</th><td><a href="#12">Optimistic Concurrency</a></td></tr> + <tr><th>14</th><td><a href="#14">ODB Pragma Language</a></td></tr> </table> @@ -1333,7 +1347,7 @@ private: placed after the class definition. They could have also been moved into a separate header leaving the original class completely unchanged (for more information on such a non-intrusive conversion - refer to <a href="#12">Chapter 12, "ODB Pragma Language"</a>).</p> + refer to <a href="#14">Chapter 14, "ODB Pragma Language"</a>).</p> <pre class="cxx"> class person @@ -1606,7 +1620,7 @@ main (int argc, char* argv[]) database name, etc., from the command line. In your own applications you may prefer to use other <code>mysql::database</code> constructors which allow you to pass this information directly - (<a href="#15.2">Section 15.2, "MySQL Database Class"</a>).</p> + (<a href="#17.2">Section 17.2, "MySQL Database Class"</a>).</p> <p>Next, we create three <code>person</code> objects. Right now they are transient objects, which means that if we terminate the application @@ -2014,7 +2028,7 @@ Hello, Joe! tables using object relationships or custom join conditions.</p> <p>While you can find a much more detailed description of views in - <a href="#9">Chapter 9, "Views"</a>, here is how we can define + <a href="#10">Chapter 10, "Views"</a>, here is how we can define the <code>person_stat</code> view that returns the basic statistics about the <code>person</code> objects:</p> @@ -2138,7 +2152,7 @@ odb::mysql::database db2 ("john", "secret", "test_db2"); tight integration with specific database systems to being able to write database-agnostic code and loading individual database systems support dynamically. While all these aspects are covered in detail - in <a href="#14">Chapter 14, "Multi-Database Support"</a>, in this + in <a href="#16">Chapter 16, "Multi-Database Support"</a>, in this section we will get a taste of this functionality by extending our "Hello World" example to be able to store its data either in MySQL or PostgreSQL (other database systems supported by ODB can be added @@ -2156,7 +2170,7 @@ odb --multi-database dynamic -d common -d mysql -d pgsql \ <p>The <code>--multi-database</code> ODB compiler option turns on multi-database support. For now it is not important what the <code>dynamic</code> value that we passed to this option means, but - if you are curious, see <a href="#14">Chapter 14</a>. The result of this + if you are curious, see <a href="#16">Chapter 16</a>. The result of this command are three sets of generated files: <code>person-odb.?xx</code> (common interface; corresponds to the <code>common</code> database), <code>person-odb-mysql.?xx</code> (MySQL support code), and @@ -2384,7 +2398,7 @@ psql --user=odb_test --dbname=odb_test -f person-pgsql.sql computations to the relational database instead of performing them in the application's process. To support such requirements ODB distinguishes a third kind of C++ types, called <em>views</em> - (<a href="#9">Chapter 9, "Views"</a>). An ODB view is a C++ + (<a href="#10">Chapter 10, "Views"</a>). An ODB view is a C++ <code>class</code> that embodies a light-weight, read-only projection of one or more persistent objects or database tables or the result of a native SQL query execution.</p> @@ -2497,13 +2511,13 @@ class person 7.2.1, "Composite Object Ids"</a>) value type. This type should be default-constructible. It is also possible to declare a persistent class without an object id, however, such a class will have limited - functionality (<a href="#12.1.6">Section 12.1.6, + functionality (<a href="#14.1.6">Section 14.1.6, "<code>no_id</code>"</a>).</p> <p>The above two pragmas are the minimum required to declare a persistent class with an object id. Other pragmas can be used to fine-tune the database-related properties of a class and its - members (<a href="#12">Chapter 12, "ODB Pragma Language"</a>).</p> + members (<a href="#14">Chapter 14, "ODB Pragma Language"</a>).</p> <p>Normally, a persistent class should define the default constructor. The generated database support code uses this constructor when @@ -2534,7 +2548,7 @@ private: <a href="#4.4">Section 4.4, "Query Result"</a>).</p> <p>The ODB compiler also needs access to the non-transient - (<a href="#12.4.11">Section 12.4.11, "<code>transient</code>"</a>) + (<a href="#14.4.11">Section 14.4.11, "<code>transient</code>"</a>) data members of a persistent class. The ODB compiler can access such data members directly if they are public. It can also do so if they are private or protected and the <code>odb::access</code> @@ -2607,9 +2621,14 @@ private: and modifier expressions using the <code>db get</code> and <code>db set</code> pragmas. For more information on custom accessor and modifier expressions refer to - <a href="#12.4.5">Section 12.4.5, + <a href="#14.4.5">Section 14.4.5, "<code>get</code>/<code>set</code>/<code>access</code>"</a>.</p> + <p>Data members of a persistent class can also be split into + separately-loaded and/or separately-updated sections. + For more information on this functionality, refer to + <a href="#9">Chapter 9, "Sections"</a>.</p> + <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 @@ -2619,7 +2638,7 @@ private: mapping to the database type and, possibly, the code to convert between the two. For more information on how to achieve this refer to the <code>db type</code> pragma description - in <a href="#12.3.1">Section 12.3.1, "<code>type</code>"</a>.</p> + in <a href="#14.3.1">Section 14.3.1, "<code>type</code>"</a>.</p> <p>Similar to object classes, composite value types have to be explicitly declared as persistent using the <code>db value</code> @@ -2652,7 +2671,7 @@ class name return pointers to these instances. As we will see in later chapters, pointers are also used to establish relationships between objects (<a href="#6">Chapter 6, "Relationships"</a>) as well as to cache - persistent objects in a session (<a href="#10">Chapter 10, + persistent objects in a session (<a href="#11">Chapter 11, "Session"</a>). While in most cases you won't need to deal with pointers to views, it is possible to a obtain a dynamically allocated instance of a view using the <code>result_iterator::load()</code> @@ -2751,9 +2770,9 @@ namespace accounting } </pre> - <p>Refer to <a href="#12.1.2">Section 12.1.2, "<code>pointer</code> - (object)"</a>, <a href="#12.2.4">Section 12.2.4, "<code>pointer</code> - (view)"</a>, and <a href="#12.5.1">Section 12.5.1, "<code>pointer</code> + <p>Refer to <a href="#14.1.2">Section 14.1.2, "<code>pointer</code> + (object)"</a>, <a href="#14.2.4">Section 14.2.4, "<code>pointer</code> + (view)"</a>, and <a href="#14.5.1">Section 14.5.1, "<code>pointer</code> (namespace)"</a> for more information on these mechanisms.</p> <p>Built-in support that is provided by the ODB runtime library allows us @@ -2899,7 +2918,7 @@ namespace odb our application. To map persistent classes to custom database schemas, ODB provides a wide range of mapping customization pragmas, such as <code>db table</code>, <code>db column</code>, - and <code>db type</code> (<a href="#12">Chapter 12, "ODB Pragma + and <code>db type</code> (<a href="#14">Chapter 14, "ODB Pragma Language"</a>). For sample code that shows how to perform such mapping for various C++ constructs, refer to the <code>schema/custom</code> example in the <code>odb-examples</code> package.</p> @@ -3106,7 +3125,7 @@ t.commit (); </pre> <p>For more information on the transaction callback support, refer - to <a href="#13.1">Section 13.1, "Transaction Callbacks"</a>.</p> + to <a href="#15.1">Section 15.1, "Transaction Callbacks"</a>.</p> <p>Note that in the above discussion of atomicity, consistency, isolation, and durability, all of those guarantees only apply @@ -3185,7 +3204,7 @@ update_age (database& db, person& p) } </pre> - <p>See also <a href="#13.1">Section 13.1, "Transaction Callbacks"</a> + <p>See also <a href="#15.1">Section 15.1, "Transaction Callbacks"</a> for an alternative approach.</p> <h2><a name="3.6">3.6 Connections</a></h2> @@ -3403,7 +3422,7 @@ for (unsigned short retry_count (0); ; retry_count++) <p>The first <code>persist()</code> function expects a constant reference to an instance being persisted. The second function expects a constant object pointer. Both of these functions can only be used on objects with - application-assigned object ids (<a href="#12.4.2">Section 12.4.2, + application-assigned object ids (<a href="#14.4.2">Section 14.4.2, "<code>auto</code>"</a>).</p> <p>The second and third <code>persist()</code> functions are similar to the @@ -3518,7 +3537,7 @@ t.commit (); <p>The first special property of <code>reload()</code> compared to the <code>load()</code> function is that it does not interact with the session's object cache - (<a href="#10.1">Section 10.1, "Object Cache"</a>). That is, if + (<a href="#11.1">Section 11.1, "Object Cache"</a>). That is, if the object being reloaded is already in the cache, then it will remain there after <code>reload()</code> returns. Similarly, if the object is not in the cache, then <code>reload()</code> won't @@ -3529,7 +3548,7 @@ t.commit (); concurrency model. In this case, if the states of the object in the application memory and in the database are the same, then no reloading will occur. For more information on optimistic - concurrency, refer to <a href="#11">Chapter 11, "Optimistic + concurrency, refer to <a href="#12">Chapter 12, "Optimistic Concurrency"</a>.</p> <p>If we don't know for sure whether an object with a given id @@ -3649,14 +3668,14 @@ t.commit (); there is no such object in the database. Instead, this condition is treated as a change of object state and <code>object_changed</code> is thrown instead. For a more detailed discussion of optimistic - concurrency, refer to <a href="#11">Chapter 11, "Optimistic + concurrency, refer to <a href="#12">Chapter 12, "Optimistic Concurrency"</a>.</p> <p>In ODB, persistent classes, composite value types, as well as individual - data members can be declared read-only (see <a href="#12.1.4">Section - 12.1.4, "<code>readonly</code> (object)"</a>, <a href="#12.3.6">Section - 12.3.6, "<code>readonly</code> (composite value)"</a>, and - <a href="#12.4.12">Section 12.4.12, "<code>readonly</code> + data members can be declared read-only (see <a href="#14.1.4">Section + 14.1.4, "<code>readonly</code> (object)"</a>, <a href="#14.3.6">Section + 14.3.6, "<code>readonly</code> (composite value)"</a>, and + <a href="#14.4.12">Section 14.4.12, "<code>readonly</code> (data member)"</a>).</p> <p>If an individual data member is declared read-only, then @@ -3737,7 +3756,7 @@ t.commit (); object in the database. Instead, this condition is treated as a change of object state and <code>object_changed</code> is thrown instead. For a more detailed discussion of optimistic concurrency, - refer to <a href="#11">Chapter 11, "Optimistic Concurrency"</a>.</p> + refer to <a href="#12">Chapter 12, "Optimistic Concurrency"</a>.</p> <p>The <code>erase_query()</code> function allows us to delete the state of multiple objects matching certain criteria. It uses @@ -4195,6 +4214,20 @@ namespace odb virtual const char* what () const throw (); }; + + // Section exceptions. + // + struct section_not_loaded: exception + { + virtual const char* + what () const throw (); + }; + + struct section_not_in_object: exception + { + virtual const char* + what () const throw (); + }; } </pre> @@ -4212,7 +4245,7 @@ namespace odb <p>The next two exceptions (<code>already_in_session</code>, and <code>not_in_session</code>) are thrown by the <code>odb::session</code> - class and are discussed in <a href="#10">Chapter 10, "Session"</a>.</p> + class and are discussed in <a href="#11">Chapter 11, "Session"</a>.</p> <p>The <code>session_required</code> exception is thrown when ODB detects that correctly loading a bidirectional object relationship requires a @@ -4249,7 +4282,7 @@ namespace odb by the <code>update()</code> database function and certain <code>erase()</code> database functions when operating on objects with the optimistic concurrency model. See - <a href="#11">Chapter 11, "Optimistic Concurrency"</a> for details.</p> + <a href="#12">Chapter 12, "Optimistic Concurrency"</a> for details.</p> <p>The <code>result_not_cached</code> exception is thrown by the query result class. Refer to <a href="#4.4">Section 4.4, @@ -4263,7 +4296,7 @@ namespace odb <p>The <code>abstract_class</code> exception is thrown by the database functions when we attempt to persist, update, load, or erase an instance of a polymorphic abstract class. For more information - on abstract classes, refer to <a href="#12.1.3">Section 12.1.3, + on abstract classes, refer to <a href="#14.1.3">Section 14.1.3, "<code>abstract</code>"</a>.</p> <p>The <code>no_type_info</code> exception is thrown by the database @@ -4289,6 +4322,13 @@ namespace odb name is not found. Refer to <a href="#3.4">Section 3.4, "Database"</a> for details.</p> + <p>The <code>section_not_loaded</code> exception is thrown if we + attempt to update an object section that hasn't been loaded. + The <code>section_not_in_object</code> exception is thrown if + the section instance being loaded or updated does not belong + to the corresponding object. See <a href="#9">Chapter 9, + "Sections"</a> for more information on these exceptions.</p> + <p>The <code>odb::exception</code> class is defined in the <code><odb/exception.hxx></code> header file. All the concrete ODB exceptions are defined in @@ -4746,7 +4786,10 @@ namespace odb (cached or uncached) by calling <code>database::query()</code> will invalidate the existing uncached result. Furthermore, calling any other database functions, such as <code>update()</code> - or <code>erase()</code> will also invalidate the uncached result.</p> + or <code>erase()</code> will also invalidate the uncached result. + It also follows that uncached results cannot be used on objects + with containers (<a href="#5">Chapter 5, "Containers"</a>) since + loading a container would invalidate the uncached result.</p> <p>The <code>empty()</code> function returns <code>true</code> if there are no objects in the result and <code>false</code> otherwise. @@ -5470,7 +5513,7 @@ private: column, they can occupy multiple columns. For an ordered container table the ODB compiler also defines two indexes: one for the object id column(s) and the other for the index - column. Refer to <a href="#12.6">Section 12.6, "Index Definition + column. Refer to <a href="#14.6">Section 14.6, "Index Definition Pragmas"</a> for more information on how to customize these indexes.</p> @@ -5499,7 +5542,7 @@ private: <p>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 <a href="#12">Chapter 12, "ODB Pragma + these pragmas, refer to <a href="#14">Chapter 14, "ODB Pragma Language"</a>. The following example shows some of the possible customizations:</p> @@ -5525,8 +5568,8 @@ private: 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 - <code>db unordered</code> pragma (<a href="#12.3.9">Section 12.3.9, - "<code>unordered</code>"</a>, <a href="#12.4.18">Section 12.4.18, + <code>db unordered</code> pragma (<a href="#14.3.9">Section 14.3.9, + "<code>unordered</code>"</a>, <a href="#14.4.18">Section 14.4.18, "<code>unordered</code>"</a>). For example:</p> <pre class="cxx"> @@ -5565,7 +5608,7 @@ private: id or element value are composite, then, instead of a single column, they can occupy multiple columns. ODB compiler also defines an index on a set container table for the object id - column(s). Refer to <a href="#12.6">Section 12.6, "Index Definition + column(s). Refer to <a href="#14.6">Section 14.6, "Index Definition Pragmas"</a> for more information on how to customize this index.</p> @@ -5593,7 +5636,7 @@ private: <p>A number of ODB pragmas allow us to customize the table name, 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 <a href="#12">Chapter 12, "ODB Pragma + these pragmas, refer to <a href="#14">Chapter 14, "ODB Pragma Language"</a>. The following example shows some of the possible customizations:</p> @@ -5632,7 +5675,7 @@ private: element value are composite, then instead of a single column they can occupy multiple columns. ODB compiler also defines an index on a map container table for the object id - column(s). Refer to <a href="#12.6">Section 12.6, "Index Definition + column(s). Refer to <a href="#14.6">Section 14.6, "Index Definition Pragmas"</a> for more information on how to customize this index.</p> @@ -5661,7 +5704,7 @@ private: <p>A number of ODB pragmas allow us to customize the table name, 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 <a href="#12">Chapter 12, "ODB Pragma + these pragmas, refer to <a href="#14">Chapter 14, "ODB Pragma Language"</a>. The following example shows some of the possible customizations:</p> @@ -5812,6 +5855,10 @@ for (;;) } </pre> + <p>For the interaction of change-tracking containers with change-updated + object sections, refer to <a href="#9.4">Section 9.4, "Sections and + Change-Tracking Containers"</a>.</p> + <h3><a name="5.4.1">5.4.1 Change-Tracking <code>vector</code></a></h3> <p>Class template <code>odb::vector</code>, defined in @@ -5828,8 +5875,8 @@ for (;;) <p><code>odb::vector</code> incurs 2-bit per element overhead in order to store the change state. It cannot - be stored unordered in the database (<a href="#12.4.18">Section - 12.4.18 "<code>unordered</code>"</a>) but can be used as an inverse + be stored unordered in the database (<a href="#14.4.18">Section + 14.4.18 "<code>unordered</code>"</a>) but can be used as an inverse side of a relationship (<a href="#6.2">6.2 "Bidirectional Relationships"</a>). In this case, no change tracking is performed since no state for such a container is stored in the database.</p> @@ -6085,11 +6132,11 @@ class employee <p>By default, an object pointer can be <code>NULL</code>. To specify that a pointer always points to a valid object we can - use the <code>not_null</code> pragma (<a href="#12.4.6">Section - 12.4.6, "<code>null</code>/<code>not_null</code>"</a>) for + use the <code>not_null</code> pragma (<a href="#14.4.6">Section + 14.4.6, "<code>null</code>/<code>not_null</code>"</a>) for single object pointers and the <code>value_not_null</code> pragma - (<a href="#12.4.23">Section - 12.4.23, "<code>value_null</code>/<code>value_not_null</code>"</a>) + (<a href="#14.4.25">Section + 14.4.25, "<code>value_null</code>/<code>value_not_null</code>"</a>) for containers of object pointers. For example:</p> <pre class="cxx"> @@ -6156,7 +6203,7 @@ unsigned long john_id, jane_id; <p>The only notable line in the above code is the creation of a session before the second transaction starts. As discussed in - <a href="#10">Chapter 10, "Session"</a>, a session acts as a cache + <a href="#11">Chapter 11, "Session"</a>, a session acts as a cache of persistent objects. By creating a session before loading the <code>employee</code> objects we make sure that their <code>employer_</code> pointers @@ -6336,7 +6383,7 @@ CREATE TABLE employee_projects ( <p>To obtain a more canonical database schema, the names of tables and columns above can be customized using ODB pragmas - (<a href="#12">Chapter 12, "ODB Pragma Language"</a>). For example:</p> + (<a href="#14">Chapter 14, "ODB Pragma Language"</a>). For example:</p> <pre class="cxx"> #pragma db object @@ -6503,7 +6550,7 @@ CREATE TABLE employee ( of these references.</p> <p>To eliminate redundant database schema references we can use the - <code>inverse</code> pragma (<a href="#12.4.14">Section 12.4.14, + <code>inverse</code> pragma (<a href="#14.4.14">Section 14.4.14, "<code>inverse</code>"</a>) which tells the ODB compiler that a pointer is the inverse side of a bidirectional relationship. Either side of a relationship can be made inverse. For example:</p> @@ -6547,7 +6594,7 @@ CREATE TABLE employee ( pointer. Also note that an ordered container (<a href="#5.1">Section 5.1, "Ordered Containers"</a>) of pointers that is an inverse side of a bidirectional relationship is always treated as unordered - (<a href="#12.4.18">Section 12.4.18, "<code>unordered</code>"</a>) + (<a href="#14.4.18">Section 14.4.18, "<code>unordered</code>"</a>) because the contents of such a container are implicitly built from the direct side of the relationship which does not contain the element order (index).</p> @@ -7198,6 +7245,10 @@ db.persist (e); t.commit (); </pre> + <p>For the interaction of lazy pointers with lazy-loaded object + sections, refer to <a href="#9.3">Section 9.3, "Sections and + Lazy Pointers"</a>.</p> + <h2><a name="6.5">6.5 Using Custom Smart Pointers</a></h2> <p>While the ODB runtime and profile libraries provide support for @@ -7279,7 +7330,7 @@ t.commit (); mapping for each database system refer to <a href="#II">Part II, Database Systems</a>. We can also provide a custom mapping for these or our own value types using the <code>db type</code> - pragma (<a href="#12.3.1">Section 12.3.1, "<code>type</code>"</a>).</p> + pragma (<a href="#14.3.1">Section 14.3.1, "<code>type</code>"</a>).</p> <h2><a name="7.2">7.2 Composite Value Types</a></h2> @@ -7331,7 +7382,7 @@ private: </pre> <p>The ODB compiler also needs access to the non-transient - (<a href="#12.4.11">Section 12.4.11, "<code>transient</code>"</a>) + (<a href="#14.4.11">Section 14.4.11, "<code>transient</code>"</a>) data members of a composite value type. It uses the same mechanisms as for persistent classes which are discussed in <a href="#3.2">Section 3.2, "Declaring Persistent Objects and @@ -7497,15 +7548,15 @@ class person pointer, or read-only data members. It also must be default-constructible. Furthermore, if the persistent class in which this composite value type is used as object id has session support - enabled (<a href="#10">Chapter 10, "Session"</a>), then it must also + enabled (<a href="#11">Chapter 11, "Session"</a>), then it must also implement the less-than comparison operator (<code>operator<</code>).</p> <h3><a name="7.2.2">7.2.2 Composite Value Column and Table Names</a></h3> <p>Customizing a column name for a data member of a simple value type is straightforward: we simply specify the desired name with - the <code>db column</code> pragma (<a href="#12.4.9">Section - 12.4.9, "<code>column</code>"</a>). For composite value + the <code>db column</code> pragma (<a href="#14.4.9">Section + 14.4.9, "<code>column</code>"</a>). For composite value types things are slightly more complex since they are mapped to multiple columns. Consider the following example:</p> @@ -7606,9 +7657,9 @@ CREATE TABLE person ( <p>The same principle applies when a composite value type is used as an element of a container, except that instead of <code>db column</code>, either the <code>db value_column</code> - (<a href="#12.4.31">Section 12.4.31, "<code>value_column</code>"</a>) or + (<a href="#14.4.33">Section 14.4.33, "<code>value_column</code>"</a>) or <code>db key_column</code> - (<a href="#12.4.30">Section 12.4.30, "<code>key_column</code>"</a>) + (<a href="#14.4.32">Section 14.4.32, "<code>key_column</code>"</a>) pragmas are used to specify the column prefix.</p> <p>When a composite value type contains a container, an extra table @@ -7652,8 +7703,8 @@ CREATE TABLE person ( </pre> <p>To customize the container table name we can use the - <code>db table</code> pragma (<a href="#12.4.19">Section - 12.4.19, "<code>table</code>"</a>), for example:</p> + <code>db table</code> pragma (<a href="#14.4.19">Section + 14.4.19, "<code>table</code>"</a>), for example:</p> <pre class="cxx"> #pragma db value @@ -7694,7 +7745,7 @@ CREATE TABLE person_nickname ( of a valid value in a column. While by default ODB maps values to columns that do not allow <code>NULL</code> values, it is possible to change that with the <code>db null</code> - pragma (<a href="#12.4.6">Section 12.4.6, + pragma (<a href="#14.4.6">Section 14.4.6, "<code>null</code>/<code>not_null</code>"</a>).</p> <p>To properly support the <code>NULL</code> semantics, the @@ -7819,7 +7870,7 @@ namespace odb consider using a more efficient implementation of the <em>optional value</em> concept such as the <code>optional</code> class template from Boost - (<a href="#21.4">Section 21.4, "Optional Library"</a>).</p> + (<a href="#23.4">Section 23.4, "Optional Library"</a>).</p> <p>Another common C++ representation of a value that can be <code>NULL</code> is a pointer. ODB will automatically @@ -8020,7 +8071,7 @@ public: instances of a base class from being stored in the database. To achieve this a persistent class can be declared abstract using the <code>db abstract</code> - pragma (<a href="#12.1.3">Section 12.1.3, "<code>abstract</code>"</a>). + pragma (<a href="#14.1.3">Section 14.1.3, "<code>abstract</code>"</a>). Note that a <em>C++-abstract</em> class, or a class that has one or more pure virtual functions and therefore cannot be instantiated, is also <em>database-abstract</em>. However, a @@ -8267,7 +8318,7 @@ class contractor: public person </pre> <p>Similarly, if we enable or disable session support - (<a href="#10">Chapter 10, "Session"</a>) for the root class, then + (<a href="#11">Chapter 11, "Session"</a>) for the root class, then the ODB compiler will automatically enable or disable it for all the derived classes.</p> @@ -8500,9 +8551,9 @@ t.commit (); to ordinary objects. These include containers (<a href="#5">Chapter 5, "Containers"</a>), object relationships, including to polymorphic objects (<a href="#6">Chapter 6, "Relationships"</a>), views - (<a href="#9">Chapter 9, "Views"</a>), session (<a href="#10">Chapter - 10, "Session"</a>), and optimistic concurrency (<a href="#11">Chapter - 11, "Optimistic Concurrency"</a>). There are, however, a few + (<a href="#10">Chapter 10, "Views"</a>), session (<a href="#11">Chapter + 11, "Session"</a>), and optimistic concurrency (<a href="#12">Chapter + 12, "Optimistic Concurrency"</a>). There are, however, a few limitations, mainly due to the underlying use of SQL to access the data.</p> @@ -8622,11 +8673,713 @@ class permanent_employee: public employee // Polymorphism inheritance. }; </pre> + + <!-- CHAPTER --> + + + <hr class="page-break"/> + <h1><a name="9">9 Sections</a></h1> + + <p>ODB sections are an optimization mechanism that allows us to + partition data members of a persistent class into groups that + can be separately loaded and/or updated. This can be useful, + for example, if an object contains expensive to load or update + data members (such as <code>BLOB</code>s or containers) and + that are accessed or modified infrequently. For example:</p> + + <pre class="cxx"> +#include <odb/section.hxx> + +#pragma db object +class person +{ + ... + + #pragma db load(lazy) update(manual) + odb::section keys_; + + #pragma db section(keys_) type("BLOB") + char public_key_[1024]; + + #pragma db section(keys_) type("BLOB") + char private_key_[1024]; +}; + +transaction t (db.begin ()); + +auto_ptr<person> p (db.load<person> (...)); // Keys are not loaded. + +if (need_keys) +{ + db.load (*p, p->keys_); // Load keys. + ... +} + +db.update (*p); // Keys are not updated. + +if (update_keys) +{ + ... + db.update (*p, p->keys_); // Update keys. +} + +t.commit (); + </pre> + + <p>A complete example that shows how to use sections is available in + the <code>section</code> directory in the <code>odb-examples</code> + package.</p> + + <p>Why do we need to group data members into sections? Why can't + each data member be loaded and updated independently if and + when necessary? The reason for this requirement is that loading + or updating a group of data members with a single database + statement is significantly more efficient than loading or updating + each data member with a separate statement. Because ODB + prepares and caches statements used to load and update + persistent objects, generating a custom statement for + a specific set of data members that need to be loaded or + updated together is not a viable approach either. To resolve + this, ODB allows us to group data members that are + often updated and/or loaded together into sections. To + achieve the best performance, we should aim to find a balance + between having too many sections with too few data + members and too few sections with too many data + members. We can use the access and modification patterns + of our application as a base for this decision.</p> + + <p>To add a new section to a persistent class we declare a new + data member of the <code>odb::section</code> type. At this + point we also need to specify the loading and updating behavior + of this section with the <code>db load</code> and + <code>db update</code> pragmas, respectively.</p> + + <p>The loading behavior of a section can be either <code>eager</code> + or <code>lazy</code>. An eager-loaded section is always loaded as + part of the object load. A lazy-loaded section is not loaded + as part of the object load and has to be explicitly loaded with + the <code>database::load()</code> function (discussed below) if + and when necessary.</p> + + <p>The updating behavior of a section can be <code>always</code>, + <code>change</code>, or <code>manual</code>. An always-updated + section is always updated as part of the object update, + provided it has been loaded. A change-updated section + is only updated as part of the object update if it has been loaded + and marked as changed. A manually-updated section is never updated + as part of the object update and has to be explicitly updated with + the <code>database::update()</code> function (discussed below) if + and when necessary.</p> + + <p>If no loading behavior is specified explicitly, then an eager-loaded + section is assumed. Similarly, if no updating behavior is specified, + then an always-updated section is assumed. An eager-loaded, always-updated + section is pointless and therefore illegal. Only persistent classes + with an object id can have sections.</p> + + <p>To specify that a data member belongs to a section we use the + <code>db section</code> pragma with the section's member + name as its single argument. Except for special data members + such as the object id and optimistic concurrency version, any + direct, non-transient member of a persistent class can belong + to a section, including composite values, containers, and + pointers to objects. For example:</p> + + <pre class="cxx"> +#pragma db value +class text +{ + std::string data; + std::string lang; +}; + +#pragma db object +class person +{ + ... + + #pragma db load(lazy) + odb::section extras_; + + #pragma db section(extras_) + text bio_; + + #pragma db section(extras_) + std::vector<std::string> nicknames_; + + #pragma db section(extras_) + std::shared_ptr<person> emergency_contact_; +}; + </pre> + + <p>An empty section is pointless and therefore illegal, except + in abstract or polymorphic classes where data members can be + added to a section by derived classes (see <a href="#9.1">Section + 9.1, "Sections and Inheritance"</a>).</p> + + <p>The <code>odb::section</code> class is defined in the + <code><odb/section.hxx></code> header file and has the + following interface:</p> + + <pre class="cxx"> +namespace odb +{ + class section + { + public: + // Load state. + // + bool + loaded () const; + + void + unload (); + + // Change state. + // + bool + changed () const; + + void + change (); + + // User data. + // + unsigned char + user_data () const; + + void + user_data (unsigned char); + }; +} + </pre> + + <p>The <code>loaded()</code> accessor can be used to determine + whether a section is already loaded. The <code>unload()</code> + modifier marks a loaded section as not loaded. This, for example, + can be useful if you don't want the section to be reloaded during + the object reload.</p> + + <p>The <code>changed()</code> accessor can be used to query the + section's change state. The <code>change()</code> modifier + marks the section as changed. It is valid to call this modifier + for an unloaded (or transient) section, however, the state will + be reset back to unchanged once the section (or object) is loaded. + The change state is only relevant to sections with change-updated + behavior and is ignored for all other sections.</p> + + <p>The size of the section class is one byte with four bits available + to store a custom state via the <code>user_data()</code> accessor + and modifier.</p> + + <p>The <code>odb::database</code> class provides special + versions of the <code>load()</code> and <code>update()</code> + functions that allow us to load and update sections of a + persistent class. Their signatures are as follows:</p> + + <pre class="cxx"> + template <typename T> + void + load (T& object, section&); + + template <typename T> + void + update (const T& object, const section&); + </pre> + + <p>Before calling the section <code>load()</code> function, the + object itself must already be loaded. If the section is already + loaded, then the call to <code>load()</code> will reload its + data members. It is illegal to explicitly load an eager-loaded + section.</p> + + <p>Before calling the section <code>update()</code> function, the + section (and therefore the object) must be in the loaded state. + If the section is not loaded, the <code>odb::section_not_loaded</code> + exception is thrown. The section <code>update()</code> function + does not check but does clear the section's change state. In + other words, section <code>update()</code> will always update + section data members in the database and clear the change flag. + Note also that any section, that is, always-, change-, or + manually-updated, can be explicitly updated with this function.</p> + + <p>Both section <code>load()</code> and <code>update()</code>, just + like the rest of the database operations, must be performed within + a transaction. Notice also that both <code>load()</code> and + <code>update()</code> expect a reference to the section as + their second argument. This reference must refer to the data + member in the object passed as the first argument. If instead + it refers to some other instance of the <code>section</code> + class, for example, a local copy or a temporary, then the + <code>odb::section_not_in_object</code> exception is thrown. + For example:</p> + + <pre class="cxx"> +#pragma db object +class person +{ +public: + ... + + odb::section + keys () const {return keys_;} + +private: + odb::section keys_; + + ... +}; + +auto_ptr<person> p (db.load<person> (...)); + +section s (p->keys ()); +db.load (*p, s); // Throw section_not_in_object, copy. + +db.update (*p, p->keys ()); // Throw section_not_in_object, copy. + </pre> + + <p>At first glance it may seem more appropriate to make the + <code>section</code> class non-copyable in order to prevent + such errors from happening. However, it is perfectly reasonable + to expect to be able to copy (or assign) sections as part of + the object copying (or assignment). As a result, sections are + left copyable and copy-assignable, however, this functionality + should not be used in accessors or modifiers. Instead, section + accessors and modifiers should always be by-reference. Here is + how we can fix our previous example:</p> + +<pre class="cxx"> +#pragma db object +class person +{ +public: + ... + + const odb::section& + keys () const {return keys_;} + + odb::section& + keys () {return keys_;} + +private: + odb::section keys_; + + ... +}; + +auto_ptr<person> p (db.load<person> (...)); + +section& s (p->keys ()); +db.load (*p, s); // Ok, reference. + +db.update (*p, p->keys ()); // Ok, reference. + </pre> + + <p>Several other database operations affect sections. The state of + a section in a transient object is undefined. That is, before + the call to object <code>persist()</code> or <code>load()</code> + functions, or after the call to object <code>erase()</code> + function, the values returned by the <code>section::loaded()</code> and + <code>section::changed()</code> accessors are undefined.</p> + + <p>After the call to <code>persist()</code>, all sections, including + eager-loaded ones, are marked as loaded and unchanged. If instead we + are loading an object with the <code>load()</code> call or as + a result of a query, then eager-loaded sections are loaded + and marked as loaded and unchanged while lazy-loaded ones are marked + as unloaded. If a lazy-loaded section is later loaded with the + section <code>load()</code> call, then it is marked as loaded and + unchanged.</p> + + <p>When we update an object with the <code>update()</code> call, + manually-updated sections are ignored while always-updated + sections are updated if they are loaded. Change-updated + sections are only updated if they are both loaded and marked + as changed. After the update, such sections are reset to the + unchanged state. When we reload an object with the + <code>reload()</code> call, sections that were loaded are + automatically reloaded and reset to the unchanged state.</p> + + <p>To further illustrate the state transitions of a section, + consider this example:</p> + + <pre class="cxx"> +#pragma db object +class person +{ + ... + + #pragma db load(lazy) update(change) + odb::section keys_; + + ... +}; + +transaction t (db.begin ()); + +person p ("John", "Doe"); // Section state is undefined (transient). + +db.persist (p); // Section state: loaded, unchanged. + +auto_ptr<person> l ( + db.load<person> (...)); // Section state: unloaded, unchanged. + +db.update (*l); // Section not updated since not loaded. +db.update (p); // Section not updated since not changed. + +p.keys_.change (); // Section state: loaded, changed. +db.update (p); // Section updated, state: loaded, unchanged. + +db.update (*l, l->keys_); // Throw section_not_loaded. +db.update (p, p.keys_); // Section updated even though not changed. + +db.reload (*l); // Section not reloaded since not loaded. +db.reload (p); // Section reloaded, state: loaded, unchanged. + +db.load (*l, l->keys_); // Section loaded, state: loaded, unchanged. +db.load (p, p.keys_); // Section reloaded, state: loaded, unchanged. + +db.erase (p); // Section state is undefined (transient). + +t.commit (); + </pre> + + <p>When using change-updated behavior, it is our responsibility to + mark the section as changed when any of the data members belonging + to this section is modified. A natural place to mark the section + as changed is the modifiers for section data members, for example:</p> + + <pre class="cxx"> +#pragma db object +class person +{ + ... + + typedef std::array<char, 1024> key_type; + + const key_type& + public_key () const {return public_key_;} + + void + public_key (const key_type& k) + { + public_key_ = k; + keys_.change (); + } + + const key_type& + private_key () const {return private_key_;} + + void + private_key (const key_type& k) + { + private_key_ = k; + keys_.change (); + } + +private: + #pragma db load(lazy) update(change) + odb::section keys_; + + #pragma db section(keys_) type("BLOB") + key_type public_key_; + + #pragma db section(keys_) type("BLOB") + key_type private_key_; + + ... +}; + </pre> + + <p>One interesting aspect of change-updated sections is what happens + when a transaction that performed an object or section update is + later rolled back. In this case, while the change state of a + section has been reset (after update), actual changes were not + committed to the database. Change-updated sections handle this + case by automatically registering a rollback callback and then, + if it is called, restoring the original change state. The + following code illustrates this semantics (continuing with + the previous example):</p> + + <pre class="cxx"> +auto_ptr<person> p; + +try +{ + transaction t (db.begin ()); + p = db.load<person> (...); + db.load (*p, p->keys_); + + p->private_key (new_key); // The section is marked changed. + db.update (*p); // The section is reset to unchanged. + + throw failed (); // Triggers rollback. + t.commit (); +} +catch (const failed&) +{ + // The section is restored back to changed. +} + </pre> + + + <h2><a name="9.1">9.1 Sections and Inheritance</a></h2> + + <p>With both reuse and polymorphism inheritance (<a href="#8">Chapter 8, + "Inheritance"</a>) it is possible to add new sections to derived + classes. It is also possible to add data members from derived + classes to sections declared in the base. For example:</p> + + <pre class="cxx"> +#pragma db object polymorphic +class person +{ + ... + + virtual void + print (); + + #pragma db load(lazy) + odb::section print_; + + #pragma db section(print_) + std::string bio_; +}; + +#pragma db object +class employee: public person +{ + ... + + virtual void + print (); + + #pragma db section(print_) + std::vector<std::string> employment_history_; +}; + +transaction t (db.begin ()); + +auto_ptr<person> p (db.load<person> (...)); // Person or employee. +db.load (*p, p->print_); // Load data members needed for print. +p->print (); + +t.commit (); + </pre> + + <p>When data members of a section are spread over several classes in a + reuse inheritance hierarchy, both section load and update are + performed with a single database statement. In contrast, with + polymorphism inheritance, section load is performed with a + single statement while update requires a separate statement + for each class that adds to the section.</p> + + <p>Note also that in polymorphism inheritance the section-to-object + association is static. Or, in other words, you can load a section + via an object only if its static type actually contains this + section. The following example will help illustrate this + point further:</p> + + <pre class="cxx"> +#pragma db object polymorphic +class person +{ + ... +}; + +#pragma db object +class employee: public person +{ + ... + + #pragma db load(lazy) + odb::section extras_; + + ... +}; + +#pragma db object +class manager: public employee +{ + ... +}; + +auto_ptr<manager> m (db.load<manager> (...)); + +person& p (*m); +employee& e (*m); +section& s (m->extras_); + +db.load (p, s); // Error: extras_ is not in person. +db.load (e, s); // Ok: extras_ is in employee. + </pre> + + <h2><a name="9.2">9.2 Sections and Optimistic Concurrency</a></h2> + + <p>When sections are used in a class with the optimistic concurrency + model (<a href="#12">Chapter 12, "Optimistic Concurrency"</a>), + both section update and load operations compare the object version + to that in the database and throw the <code>odb::object_changed</code> + exception if they do not match. In addition, the section update + operation increments the version to indicate that the object state + has changed. For example:</p> + + <pre class="cxx"> +#pragma db object optimistic +class person +{ + ... + + #pragma db version + unsigned long long version_; + + #pragma db load(lazy) + odb::section extras_; + + #pragma db section(extras_) + std::string bio_; +}; + +auto_ptr<person> p; + +{ + transaction t (db.begin ()); + p = db.load<person> (...); + t.commit (); +} + +{ + transaction t (db.begin ()); + + try + { + db.load (*p, p->extras_); // Throws if object state has changed. + } + catch (const object_changed&) + { + db.reload (*p); + db.load (*p, p->extras_); // Cannot fail. + } + + t.commit (); +} + </pre> + + <p>Note also that if an object update triggers one or more + section updates, then each such update will increment the + object version. As a result, an update of an object that + contains sections may result in a version increment by + more than one.</p> + + <p>When sections are used together with optimistic concurrency and + inheritance, an extra step may be required to enable this + functionality. If you plan to add new sections to derived + classes, then the root class of the hierarchy + (the one that declares the version data member) must be + declared as sectionable with the <code>db sectionable</code> + pragma. For example:</p> + + <pre class="cxx"> +#pragma db object polymorphic sectionable +class person +{ + ... + + #pragma db version + unsigned long long version_; +}; + +#pragma db object +class employee: public person +{ + ... + + #pragma db load(lazy) + odb::section extras_; + + #pragma db section(extras_) + std::vector<std::string> employment_history_; +}; + </pre> + + <p>This requirement has to do with the need to generate extra + version increment code in the root class that will be used + by sections added in the derived classes. If you forget to + declare the root class as sectionable and later add a + section to one of the derived classes, the ODB compiler + will issue diagnostics.</p> + + <h2><a name="9.3">9.3 Sections and Lazy Pointers</a></h2> + + <p>If a lazy pointer (<a href="#6.4">Section 6.4, "Lazy Pointers"</a>) + belongs to a lazy-loaded section, then we end up with two levels of + lazy loading. Specifically, when the section is loaded, the lazy + pointer is initialized with the object id but the object itself + is not loaded. For example:</p> + + <pre class="cxx"> +#pragma db object +class employee +{ + ... + + #pragma db load(lazy) + odb::section extras_; + + #pragma db section(extras_) + odb::lazy_shared_ptr<employer> employer_; +}; + +transaction t (db.begin ()); + +auto_ptr<employee> e (db.load<employee> (...)); // employer_ is NULL. + +db.load (*e, e->extras_); // employer_ contains valid employer id. + +e->employer_.load (); // employer_ points to employer object. + +t.commit (); + </pre> + + <h2><a name="9.4">9.4 Sections and Change-Tracking Containers</a></h2> + + <p>If a change-tracking container (<a href="#5.4">Section 5.4, + "Change-Tracking Containers"</a>) belongs to a change-updated + section, then prior to an object update ODB will check if the + container has been changed and if so, automatically mark the + section as changed. For example:</p> + +<pre class="cxx"> +#pragma db object +class person +{ + ... + + #pragma db load(lazy) update(change) + odb::section extras_; + + #pragma db section(extras_) + odb::vector<std::string> nicknames_; +}; + +transaction t (db.begin ()); + +auto_ptr<person> p (db.load<person> (...)); +db.load (*p, p->extras_); + +p->nicknames_.push_back ("JD"); + +db.update (*p); // Section is automatically updated even + // though it was not marked as changed. +t.commit (); + </pre> + + <!-- CHAPTER --> <hr class="page-break"/> - <h1><a name="9">9 Views</a></h1> + <h1><a name="10">10 Views</a></h1> <p>An ODB view is a C++ <code>class</code> or <code>struct</code> type that embodies a light-weight, read-only projection of one or more @@ -8764,11 +9517,11 @@ t.commit (); the result of a custom SQL query. The following sections discuss each of these kinds of view in more detail.</p> - <h2><a name="9.1">9.1 Object Views</a></h2> + <h2><a name="10.1">10.1 Object Views</a></h2> <p>To associate one or more objects with a view we use the - <code>db object</code> pragma (<a href="#12.2.1">Section - 12.2.1, "<code>object</code>"</a>). We have already seen + <code>db object</code> pragma (<a href="#14.2.1">Section + 14.2.1, "<code>object</code>"</a>). We have already seen a simple, single-object view in the introduction to this chapter. To associate the second and subsequent objects we repeat the <code>db object</code> pragma for each additional object, @@ -8799,7 +9552,7 @@ struct employee_employer below. The optional <i>join-condition</i> part provides the criteria which should be used to associate this object with any of the previously associated objects or, as we will see in - <a href="#9.3">Section 9.3, "Mixed Views"</a>, tables. Note that + <a href="#10.3">Section 10.3, "Mixed Views"</a>, tables. Note that while the first associated object can have an alias, it cannot have a join condition.</p> @@ -8949,7 +9702,7 @@ struct employee_birth_code or the match is ambiguous, the ODB compiler will issue an error. To associate two differently-named members or to resolve an ambiguity, we can explicitly specify the member association using the - <code>db column</code> pragma (<a href="#12.4.9">Section 12.4.9, + <code>db column</code> pragma (<a href="#14.4.9">Section 14.4.9, "<code>column</code>"</a>). For example:</p> <pre class="cxx"> @@ -8965,8 +9718,8 @@ struct employee_employer </pre> <p>If an object data member specifies the SQL type with - the <code>db type</code> pragma (<a href="#12.4.3">Section - 12.4.3, "<code>type</code>"</a>), then this type is also used for + the <code>db type</code> pragma (<a href="#14.4.3">Section + 14.4.3, "<code>type</code>"</a>), then this type is also used for the associated view data members.</p> <p>Note also that similar to join conditions, if we assign an alias to @@ -9148,7 +9901,7 @@ t.commit (); query expression, and you need to qualify the column with the table, then you will need to use the table alias instead.</p> - <h2><a name="9.2">9.2 Table Views</a></h2> + <h2><a name="10.2">10.2 Table Views</a></h2> <p>A table view is similar to an object view except that it is based on one or more database tables instead of persistent @@ -9156,7 +9909,7 @@ t.commit (); ad-hoc tables that are not mapped to persistent classes.</p> <p>To associate one or more tables with a view we use the - <code>db table</code> pragma (<a href="#12.2.2">Section 12.2.2, + <code>db table</code> pragma (<a href="#14.2.2">Section 14.2.2, "<code>table</code>"</a>). To associate the second and subsequent tables we repeat the <code>db table</code> pragma for each additional table. For example, the following view is based on the @@ -9211,7 +9964,7 @@ struct employee_max_vacation </pre> <p>For more information on database schemas and the format of the - qualified names, refer to <a href="#12.1.8">Section 12.1.8, + qualified names, refer to <a href="#14.1.8">Section 14.1.8, "<code>schema</code>"</a>.</p> <p>Note also that in the above examples we specified the SQL type @@ -9237,7 +9990,7 @@ struct employee_max_vacation column names, and query expressions. The optional <i>join-condition</i> part provides the criteria which should be used to associate this table with any of the previously associated tables or, as we will see in - <a href="#9.3">Section 9.3, "Mixed Views"</a>, objects. Note that + <a href="#10.3">Section 10.3, "Mixed Views"</a>, objects. Note that while the first associated table can have an alias, it cannot have a join condition.</p> @@ -9305,7 +10058,7 @@ t.commit (); </pre> - <h2><a name="9.3">9.3 Mixed Views</a></h2> + <h2><a name="10.3">10.3 Mixed Views</a></h2> <p>A mixed view has both associated objects and tables. As a first example of a mixed view, let us improve <code>employee_vacation</code> @@ -9368,12 +10121,12 @@ struct employee_prev_employer }; </pre> - <h2><a name="9.4">9.4 View Query Conditions</a></h2> + <h2><a name="10.4">10.4 View Query Conditions</a></h2> <p>Object, table, and mixed views can also specify an optional query condition that should be used whenever the database is queried for this view. To specify a query condition we use the - <code>db query</code> pragma (<a href="#12.2.3">Section 12.2.3, + <code>db query</code> pragma (<a href="#14.2.3">Section 14.2.3, "<code>query</code>"</a>).</p> <p>As an example, consider a view that returns some information about @@ -9479,7 +10232,7 @@ struct employer_age }; </pre> - <h2><a name="9.5">9.5 Native Views</a></h2> + <h2><a name="10.5">10.5 Native Views</a></h2> <p>The last kind of view supported by ODB is a native view. Native views are a low-level mechanism for capturing results of native @@ -9488,7 +10241,7 @@ struct employer_age the native SQL query, which must at a minimum include the select-list and, if applicable, the from-list. For example, here is how we can re-implement the <code>employee_vacation</code> table - view from Section 9.2 above as a native view:</p> + view from Section 10.2 above as a native view:</p> <pre class="cxx"> #pragma db view query("SELECT employee_id, vacation_days " \ @@ -9606,7 +10359,7 @@ result n (db.query<sequence_value> ( </pre> - <h2><a name="9.6">9.6 Other View Features and Limitations</a></h2> + <h2><a name="10.6">10.6 Other View Features and Limitations</a></h2> <p>Views cannot be derived from other views. However, you can derive a view from a transient C++ class. View data members cannot be @@ -9674,14 +10427,14 @@ struct employee_name <hr class="page-break"/> - <h1><a name="10">10 Session</a></h1> + <h1><a name="11">11 Session</a></h1> <p>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 future versions it may provide additional functionality, such as delayed database operations and automatic object state change tracking. As discussed later in - <a href="#10.2">Section 10.2, "Custom Sessions"</a>, it is also + <a href="#11.2">Section 11.2, "Custom Sessions"</a>, it is also possible to provide a custom session implementation that provides these or other features.</p> @@ -9868,7 +10621,7 @@ namespace odb iterate over the objects store in the cache. Refer to the ODB runtime header files for more details on this direct access.</p> - <h2><a name="10.1">10.1 Object Cache</a></h2> + <h2><a name="11.1">11.1 Object Cache</a></h2> <p>A session is an object cache. Every time a session-enabled object is made persistent by calling the <code>database::persist()</code> function @@ -9950,7 +10703,7 @@ unsigned long id2 (save (db, p2)); // p2 is cached in s as non-const. } </pre> - <h2><a name="10.2">10.2 Custom Sessions</a></h2> + <h2><a name="11.2">11.2 Custom Sessions</a></h2> <p>ODB can use a custom session implementation instead of the default <code>odb::session</code>. There could be multiple @@ -10070,7 +10823,7 @@ public: <hr class="page-break"/> - <h1><a name="11">11 Optimistic Concurrency</a></h1> + <h1><a name="12">12 Optimistic Concurrency</a></h1> <p>The ODB transaction model (<a href="#3.5">Section 3.5, "Transactions"</a>) guarantees consistency as long as we perform all the @@ -10154,9 +10907,9 @@ p.age (age); methods, such as timestamps, may be supported in the future.</p> <p>To declare a persistent class with the optimistic concurrency model we - use the <code>optimistic</code> pragma (<a href="#12.1.5">Section 12.1.5, + use the <code>optimistic</code> pragma (<a href="#14.1.5">Section 14.1.5, "<code>optimistic</code>"</a>). We also use the <code>version</code> - pragma (<a href="#12.4.15">Section 12.4.15, "<code>version</code>"</a>) + pragma (<a href="#14.4.15">Section 14.4.15, "<code>version</code>"</a>) to specify which data member will store the object version. For example:</p> @@ -10365,7 +11118,7 @@ for (bool done (false); !done; ) <hr class="page-break"/> - <h1><a name="12">12 ODB Pragma Language</a></h1> + <h1><a name="14">14 ODB Pragma Language</a></h1> <p>As we have already seen in previous chapters, ODB uses a pragma-based language to capture database-specific information about C++ types. @@ -10534,10 +11287,10 @@ class person 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 <a href="#12.8">Section 12.8, + at the end of this chapter in <a href="#14.8">Section 14.8, "C++ Compiler Warnings"</a>.</p> - <h2><a name="12.1">12.1 Object Type Pragmas</a></h2> + <h2><a name="14.1">14.1 Object Type Pragmas</a></h2> <p>A pragma with the <code>object</code> qualifier declares a C++ class as a persistent object type. The qualifier can be optionally followed, @@ -10554,78 +11307,84 @@ class person <tr> <td><code>table</code></td> <td>table name for a persistent class</td> - <td><a href="#12.1.1">12.1.1</a></td> + <td><a href="#14.1.1">14.1.1</a></td> </tr> <tr> <td><code>pointer</code></td> <td>pointer type for a persistent class</td> - <td><a href="#12.1.2">12.1.2</a></td> + <td><a href="#14.1.2">14.1.2</a></td> </tr> <tr> <td><code>abstract</code></td> <td>persistent class is abstract</td> - <td><a href="#12.1.3">12.1.3</a></td> + <td><a href="#14.1.3">14.1.3</a></td> </tr> <tr> <td><code>readonly</code></td> <td>persistent class is read-only</td> - <td><a href="#12.1.4">12.1.4</a></td> + <td><a href="#14.1.4">14.1.4</a></td> </tr> <tr> <td><code>optimistic</code></td> <td>persistent class with the optimistic concurrency model</td> - <td><a href="#12.1.5">12.1.5</a></td> + <td><a href="#14.1.5">14.1.5</a></td> </tr> <tr> <td><code>no_id</code></td> <td>persistent class has no object id</td> - <td><a href="#12.1.6">12.1.6</a></td> + <td><a href="#14.1.6">14.1.6</a></td> </tr> <tr> <td><code>callback</code></td> <td>database operations callback</td> - <td><a href="#12.1.7">12.1.7</a></td> + <td><a href="#14.1.7">14.1.7</a></td> </tr> <tr> <td><code>schema</code></td> <td>database schema for a persistent class</td> - <td><a href="#12.1.8">12.1.8</a></td> + <td><a href="#14.1.8">14.1.8</a></td> </tr> <tr> <td><code>polymorphic</code></td> <td>persistent class is polymorphic</td> - <td><a href="#12.1.9">12.1.9</a></td> + <td><a href="#14.1.9">14.1.9</a></td> </tr> <tr> <td><code>session</code></td> <td>enable/disable session support for a persistent class</td> - <td><a href="#12.1.10">12.1.10</a></td> + <td><a href="#14.1.10">14.1.10</a></td> </tr> <tr> <td><code>definition</code></td> <td>definition location for a persistent class</td> - <td><a href="#12.1.11">12.1.11</a></td> + <td><a href="#14.1.11">14.1.11</a></td> </tr> <tr> <td><code>transient</code></td> <td>all non-virtual data members in a persistent class are transient</td> - <td><a href="#12.1.12">12.1.12</a></td> + <td><a href="#14.1.12">14.1.12</a></td> + </tr> + + <tr> + <td><code>sectionable</code></td> + <td>support addition of new sections in derived classes</td> + <td><a href="#14.1.13">14.1.13</a></td> </tr> </table> - <h3><a name="12.1.1">12.1.1 <code>table</code></a></h3> + <h3><a name="14.1.1">14.1.1 <code>table</code></a></h3> <p>The <code>table</code> specifier specifies the table name that should be used to store objects of the persistent class in a relational @@ -10652,10 +11411,10 @@ class person </pre> <p>For more information on database schemas and the format of the - qualified names, refer to <a href="#12.1.8">Section 12.1.8, + qualified names, refer to <a href="#14.1.8">Section 14.1.8, "<code>schema</code>"</a>.</p> - <h3><a name="12.1.2">12.1.2 <code>pointer</code></a></h3> + <h3><a name="14.1.2">14.1.2 <code>pointer</code></a></h3> <p>The <code>pointer</code> specifier specifies the object pointer type for the persistent class. The object pointer type is used to return, @@ -10698,7 +11457,7 @@ class person </pre> <p>If a pointer type is not explicitly specified, the default pointer, - specified at the namespace level (<a href="#12.5.1">Section 12.5.1, + specified at the namespace level (<a href="#14.5.1">Section 14.5.1, "<code>pointer</code>"</a>) or with the <code>--default-pointer</code> ODB compiler option, is used. If neither of these two mechanisms is used to specify the pointer, then the raw pointer is used by default.</p> @@ -10706,7 +11465,7 @@ class person <p>For a more detailed discussion of object pointers, refer to <a href="#3.3">Section 3.3, "Object and View Pointers"</a>.</p> - <h3><a name="12.1.3">12.1.3 <code>abstract</code></a></h3> + <h3><a name="14.1.3">14.1.3 <code>abstract</code></a></h3> <p>The <code>abstract</code> specifier specifies that the persistent class is abstract. An instance of an abstract class cannot be stored in @@ -10738,7 +11497,7 @@ class contractor: public person discussion of persistent class inheritance, refer to <a href="#8">Chapter 8, "Inheritance"</a>.</p> - <h3><a name="12.1.4">12.1.4 <code>readonly</code></a></h3> + <h3><a name="14.1.4">14.1.4 <code>readonly</code></a></h3> <p>The <code>readonly</code> specifier specifies that the persistent class is read-only. The database state of read-only objects cannot be @@ -10763,17 +11522,17 @@ class person read-only while the rest is treated as read-write.</p> <p>Note that it is also possible to declare individual data members - (<a href="#12.4.12">Section 12.4.12, "<code>readonly</code>"</a>) - as well as composite value types (<a href="#12.3.6">Section 12.3.6, + (<a href="#14.4.12">Section 14.4.12, "<code>readonly</code>"</a>) + as well as composite value types (<a href="#14.3.6">Section 14.3.6, "<code>readonly</code>"</a>) as read-only.</p> - <h3><a name="12.1.5">12.1.5 <code>optimistic</code></a></h3> + <h3><a name="14.1.5">14.1.5 <code>optimistic</code></a></h3> <p>The <code>optimistic</code> specifier specifies that the persistent class has the optimistic concurrency model. A class with the optimistic concurrency model must also specify the data member that is used to store the object version using the <code>version</code> pragma - (<a href="#12.4.15">Section 12.4.15, "<code>version</code>"</a>). + (<a href="#14.4.15">Section 14.4.15, "<code>version</code>"</a>). For example:</p> <pre class="cxx"> @@ -10794,9 +11553,9 @@ class person same class.</p> <p>For a more detailed discussion of optimistic concurrency, refer to - <a href="#11">Chapter 11, "Optimistic Concurrency"</a>.</p> + <a href="#12">Chapter 12, "Optimistic Concurrency"</a>.</p> - <h3><a name="12.1.6">12.1.6 <code>no_id</code></a></h3> + <h3><a name="14.1.6">14.1.6 <code>no_id</code></a></h3> <p>The <code>no_id</code> specifier specifies that the persistent class has no object id. For example:</p> @@ -10828,13 +11587,13 @@ class person <p>Furthermore, persistent classes without object ids cannot have container data members nor can they be used in object relationships. Such objects are not entered into the session object cache - (<a href="#10.1">Section 10.1, "Object Cache"</a>) either.</p> + (<a href="#11.1">Section 11.1, "Object Cache"</a>) either.</p> <p>To declare a persistent class with an object id, use the data member - <code>id</code> specifier (<a href="#12.4.1">Section 12.4.1, + <code>id</code> specifier (<a href="#14.4.1">Section 14.4.1, "<code>id</code>"</a>).</p> - <h3><a name="12.1.7">12.1.7 <code>callback</code></a></h3> + <h3><a name="14.1.7">14.1.7 <code>callback</code></a></h3> <p>The <code>callback</code> specifier specifies the persist class member function that should be called before and after a @@ -10958,7 +11717,7 @@ private: }; </pre> - <h3><a name="12.1.8">12.1.8 <code>schema</code></a></h3> + <h3><a name="14.1.8">14.1.8 <code>schema</code></a></h3> <p>The <code>schema</code> specifier specifies a database schema that should be used for the persistent class.</p> @@ -11147,8 +11906,8 @@ class employee <p>The standard syntax for qualified names used in the <code>schema</code> and <code>table</code> specifiers as well - as the view <code>column</code> specifier (<a href="#12.4.10">Section - 12.4.10, "<code>column</code> (view)"</a>) has the + as the view <code>column</code> specifier (<a href="#14.4.10">Section + 14.4.10, "<code>column</code> (view)"</a>) has the <code>"</code><i>name</i><code>.</code><i>name</i>...<code>"</code> form where, as discussed above, the leading name component can be empty to denote a fully qualified name. This form, however, @@ -11176,17 +11935,17 @@ class employee }; </pre> - <p>Table prefixes (<a href="#12.5.2">Section 12.5.2, "<code>table</code>"</a>) + <p>Table prefixes (<a href="#14.5.2">Section 14.5.2, "<code>table</code>"</a>) can be used as an alternative to database schemas if the target database system does not support schemas.</p> - <h3><a name="12.1.9">12.1.9 <code>polymorphic</code></a></h3> + <h3><a name="14.1.9">14.1.9 <code>polymorphic</code></a></h3> <p>The <code>polymorphic</code> specifier specifies that the persistent class is polymorphic. For more information on polymorphism support, refer to <a href="#8">Chapter 8, "Inheritance"</a>.</p> - <h3><a name="12.1.10">12.1.10 <code>session</code></a></h3> + <h3><a name="14.1.10">14.1.10 <code>session</code></a></h3> <p>The <code>session</code> specifier specifies whether to enable session support for the persistent class. For example:</p> @@ -11214,11 +11973,11 @@ class employer <p>Session support is disabled by default unless the <code>--generate-session</code> ODB compiler option is specified or session support is enabled at the namespace level - (<a href="#12.5.4">Section 12.5.4, "<code>session</code>"</a>). - For more information on sessions, refer to <a href="#10">Chapter - 10, "Session"</a>.</p> + (<a href="#14.5.4">Section 14.5.4, "<code>session</code>"</a>). + For more information on sessions, refer to <a href="#11">Chapter + 11, "Session"</a>.</p> - <h3><a name="12.1.11">12.1.11 <code>definition</code></a></h3> + <h3><a name="14.1.11">14.1.11 <code>definition</code></a></h3> <p>The <code>definition</code> specifier specifies an alternative <em>definition location</em> for the persistent class. By @@ -11230,18 +11989,27 @@ class employer containing this pragma.</p> <p>For more information on this functionality, refer to - <a href="#12.3.7">Section 12.3.7, "<code>definition</code>"</a>.</p> + <a href="#14.3.7">Section 14.3.7, "<code>definition</code>"</a>.</p> - <h3><a name="12.1.12">12.1.12 <code>transient</code></a></h3> + <h3><a name="14.1.12">14.1.12 <code>transient</code></a></h3> <p>The <code>transient</code> specifier instructs the ODB compiler to treat all non-virtual data members in the persistent class as transient - (<a href="#12.4.1">Section 12.4.1, "<code>transient</code>"</a>). + (<a href="#14.4.1">Section 14.4.1, "<code>transient</code>"</a>). This specifier is primarily useful when declaring virtual data - members, as discussed in <a href="#12.4.13">Section 12.4.13, + members, as discussed in <a href="#14.4.13">Section 14.4.13, "<code>virtual</code>"</a>.</p> - <h2><a name="12.2">12.2 View Type Pragmas</a></h2> + <h3><a name="14.1.13">14.1.13 <code>sectionable</code></a></h3> + + <p>The <code>sectionable</code> specifier instructs the ODB compiler + to generate support for the addition of new object sections in + derived classes in a hierarchy with the optimistic concurrency + model. For more information on this functionality, refer to + <a href="#9.2">Section 9.2, "Sections and Optimistic + Concurrency"</a>.</p> + + <h2><a name="14.2">14.2 View Type Pragmas</a></h2> <p>A pragma with the <code>view</code> qualifier declares a C++ class as a view type. The qualifier can be optionally followed, @@ -11259,84 +12027,84 @@ class employer <tr> <td><code>object</code></td> <td>object associated with a view</td> - <td><a href="#12.2.1">12.2.1</a></td> + <td><a href="#14.2.1">14.2.1</a></td> </tr> <tr> <td><code>table</code></td> <td>table associated with a view</td> - <td><a href="#12.2.2">12.2.2</a></td> + <td><a href="#14.2.2">14.2.2</a></td> </tr> <tr> <td><code>query</code></td> <td>view query condition</td> - <td><a href="#12.2.3">12.2.3</a></td> + <td><a href="#14.2.3">14.2.3</a></td> </tr> <tr> <td><code>pointer</code></td> <td>pointer type for a view</td> - <td><a href="#12.2.4">12.2.4</a></td> + <td><a href="#14.2.4">14.2.4</a></td> </tr> <tr> <td><code>callback</code></td> <td>database operations callback</td> - <td><a href="#12.2.5">12.2.5</a></td> + <td><a href="#14.2.5">14.2.5</a></td> </tr> <tr> <td><code>definition</code></td> <td>definition location for a view</td> - <td><a href="#12.2.6">12.2.6</a></td> + <td><a href="#14.2.6">14.2.6</a></td> </tr> <tr> <td><code>transient</code></td> <td>all non-virtual data members in a view are transient</td> - <td><a href="#12.2.7">12.2.7</a></td> + <td><a href="#14.2.7">14.2.7</a></td> </tr> </table> - <p>For more information on view types refer to <a href="#9"> Chapter 9, + <p>For more information on view types refer to <a href="#10"> Chapter 10, "Views"</a>.</p> - <h3><a name="12.2.1">12.2.1 <code>object</code></a></h3> + <h3><a name="14.2.1">14.2.1 <code>object</code></a></h3> <p>The <code>object</code> specifier specifies a persistent class that should be associated with the view. For more information - on object associations refer to <a href="#9.1">Section 9.1, "Object + on object associations refer to <a href="#10.1">Section 10.1, "Object Views"</a>.</p> - <h3><a name="12.2.2">12.2.2 <code>table</code></a></h3> + <h3><a name="14.2.2">14.2.2 <code>table</code></a></h3> <p>The <code>table</code> specifier specifies a database table that should be associated with the view. For more information - on table associations refer to <a href="#9.2">Section 9.2, "Table + on table associations refer to <a href="#10.2">Section 10.2, "Table Views"</a>.</p> - <h3><a name="12.2.3">12.2.3 <code>query</code></a></h3> + <h3><a name="14.2.3">14.2.3 <code>query</code></a></h3> <p>The <code>query</code> specifier specifies a query condition for an object or table view or a native SQL query for a native view. An empty <code>query</code> specifier indicates that a native SQL query is provided at runtime. For more information - on query conditions refer to <a href="#9.4">Section 9.4, "View + on query conditions refer to <a href="#10.4">Section 10.4, "View Query Conditions"</a>. For more information on native SQL queries, - refer to <a href="#9.5">Section 9.5, "Native Views"</a>.</p> + refer to <a href="#10.5">Section 10.5, "Native Views"</a>.</p> - <h3><a name="12.2.4">12.2.4 <code>pointer</code></a></h3> + <h3><a name="14.2.4">14.2.4 <code>pointer</code></a></h3> <p>The <code>pointer</code> specifier specifies the view pointer type for the view class. Similar to objects, the view pointer type is used to return dynamically allocated instances of a view class. The semantics of the <code>pointer</code> specifier for a view are the same as those of the <code>pointer</code> specifier for an object - (<a href="#12.1.2">Section 12.1.2, "<code>pointer</code>"</a>).</p> + (<a href="#14.1.2">Section 14.1.2, "<code>pointer</code>"</a>).</p> - <h3><a name="12.2.5">12.2.5 <code>callback</code></a></h3> + <h3><a name="14.2.5">14.2.5 <code>callback</code></a></h3> <p>The <code>callback</code> specifier specifies the view class member function that should be called before and after an @@ -11344,12 +12112,12 @@ class employer result iteration. The semantics of the <code>callback</code> specifier for a view are similar to those of the <code>callback</code> specifier for an object - (<a href="#12.1.7">Section 12.1.7, "<code>callback</code>"</a>) + (<a href="#14.1.7">Section 14.1.7, "<code>callback</code>"</a>) except that the only events that can trigger a callback call in the case of a view are <code>pre_load</code> and <code>post_load</code>.</p> - <h3><a name="12.2.6">12.2.6 <code>definition</code></a></h3> + <h3><a name="14.2.6">14.2.6 <code>definition</code></a></h3> <p>The <code>definition</code> specifier specifies an alternative <em>definition location</em> for the view class. By @@ -11361,18 +12129,18 @@ class employer containing this pragma.</p> <p>For more information on this functionality, refer to - <a href="#12.3.7">Section 12.3.7, "<code>definition</code>"</a>.</p> + <a href="#14.3.7">Section 14.3.7, "<code>definition</code>"</a>.</p> - <h3><a name="12.2.7">12.2.7 <code>transient</code></a></h3> + <h3><a name="14.2.7">14.2.7 <code>transient</code></a></h3> <p>The <code>transient</code> specifier instructs the ODB compiler to treat all non-virtual data members in the view class as transient - (<a href="#12.4.1">Section 12.4.1, "<code>transient</code>"</a>). + (<a href="#14.4.1">Section 14.4.1, "<code>transient</code>"</a>). This specifier is primarily useful when declaring virtual data - members, as discussed in <a href="#12.4.13">Section 12.4.13, + members, as discussed in <a href="#14.4.13">Section 14.4.13, "<code>virtual</code>"</a>.</p> - <h2><a name="12.3">12.3 Value Type Pragmas</a></h2> + <h2><a name="14.3">14.3 Value Type Pragmas</a></h2> <p>A pragma with the <code>value</code> qualifier describes a value type. It can be optionally followed, in any order, by one or more @@ -11389,133 +12157,133 @@ class employer <tr> <td><code>type</code></td> <td>database type for a value type</td> - <td><a href="#12.3.1">12.3.1</a></td> + <td><a href="#14.3.1">14.3.1</a></td> </tr> <tr> <td><code>id_type</code></td> <td>database type for a value type when used as an object id</td> - <td><a href="#12.3.2">12.3.2</a></td> + <td><a href="#14.3.2">14.3.2</a></td> </tr> <tr> <td><code>null</code>/<code>not_null</code></td> <td>type can/cannot be <code>NULL</code></td> - <td><a href="#12.3.3">12.3.3</a></td> + <td><a href="#14.3.3">14.3.3</a></td> </tr> <tr> <td><code>default</code></td> <td>default value for a value type</td> - <td><a href="#12.3.4">12.3.4</a></td> + <td><a href="#14.3.4">14.3.4</a></td> </tr> <tr> <td><code>options</code></td> <td>database options for a value type</td> - <td><a href="#12.3.5">12.3.5</a></td> + <td><a href="#14.3.5">14.3.5</a></td> </tr> <tr> <td><code>readonly</code></td> <td>composite value type is read-only</td> - <td><a href="#12.3.6">12.3.6</a></td> + <td><a href="#14.3.6">14.3.6</a></td> </tr> <tr> <td><code>definition</code></td> <td>definition location for a composite value type</td> - <td><a href="#12.3.7">12.3.7</a></td> + <td><a href="#14.3.7">14.3.7</a></td> </tr> <tr> <td><code>transient</code></td> <td>all non-virtual data members in a composite value are transient</td> - <td><a href="#12.3.8">12.3.8</a></td> + <td><a href="#14.3.8">14.3.8</a></td> </tr> <tr> <td><code>unordered</code></td> <td>ordered container should be stored unordered</td> - <td><a href="#12.3.9">12.3.9</a></td> + <td><a href="#14.3.9">14.3.9</a></td> </tr> <tr> <td><code>index_type</code></td> <td>database type for a container's index type</td> - <td><a href="#12.3.10">12.3.10</a></td> + <td><a href="#14.3.10">14.3.10</a></td> </tr> <tr> <td><code>key_type</code></td> <td>database type for a container's key type</td> - <td><a href="#12.3.11">12.3.11</a></td> + <td><a href="#14.3.11">14.3.11</a></td> </tr> <tr> <td><code>value_type</code></td> <td>database type for a container's value type</td> - <td><a href="#12.3.12">12.3.12</a></td> + <td><a href="#14.3.12">14.3.12</a></td> </tr> <tr> <td><code>value_null</code>/<code>value_not_null</code></td> <td>container's value can/cannot be <code>NULL</code></td> - <td><a href="#12.3.13">12.3.13</a></td> + <td><a href="#14.3.13">14.3.13</a></td> </tr> <tr> <td><code>id_options</code></td> <td>database options for a container's id column</td> - <td><a href="#12.3.14">12.3.14</a></td> + <td><a href="#14.3.14">14.3.14</a></td> </tr> <tr> <td><code>index_options</code></td> <td>database options for a container's index column</td> - <td><a href="#12.3.15">12.3.15</a></td> + <td><a href="#14.3.15">14.3.15</a></td> </tr> <tr> <td><code>key_options</code></td> <td>database options for a container's key column</td> - <td><a href="#12.3.16">12.3.16</a></td> + <td><a href="#14.3.16">14.3.16</a></td> </tr> <tr> <td><code>value_options</code></td> <td>database options for a container's value column</td> - <td><a href="#12.3.17">12.3.17</a></td> + <td><a href="#14.3.17">14.3.17</a></td> </tr> <tr> <td><code>id_column</code></td> <td>column name for a container's object id</td> - <td><a href="#12.3.18">12.3.18</a></td> + <td><a href="#14.3.18">14.3.18</a></td> </tr> <tr> <td><code>index_column</code></td> <td>column name for a container's index</td> - <td><a href="#12.3.19">12.3.19</a></td> + <td><a href="#14.3.19">14.3.19</a></td> </tr> <tr> <td><code>key_column</code></td> <td>column name for a container's key</td> - <td><a href="#12.3.20">12.3.20</a></td> + <td><a href="#14.3.20">14.3.20</a></td> </tr> <tr> <td><code>value_column</code></td> <td>column name for a container's value</td> - <td><a href="#12.3.21">12.3.21</a></td> + <td><a href="#14.3.21">14.3.21</a></td> </tr> </table> <p>Many of the value type specifiers have corresponding member type - specifiers with the same names (<a href="#12.4">Section 12.4, + specifiers with the same names (<a href="#14.4">Section 14.4, "Data Member Pragmas"</a>). The behavior of such specifiers for members is similar to that for value types. The only difference is the scope. A particular value type specifier applies to all the @@ -11525,7 +12293,7 @@ class employer take precedence over and override parameters specified with value specifiers.</p> - <h3><a name="12.3.1">12.3.1 <code>type</code></a></h3> + <h3><a name="14.3.1">14.3.1 <code>type</code></a></h3> <p>The <code>type</code> specifier specifies the native database type that should be used for data members of this type. For example:</p> @@ -11547,8 +12315,8 @@ class person <code>std::string</code> and the database types for each supported database system. For more information on the default mapping, refer to <a href="#II">Part II, "Database Systems"</a>. The - <code>null</code> and <code>not_null</code> (<a href="#12.3.3">Section - 12.3.3, "<code>null</code>/<code>not_null</code>"</a>) specifiers + <code>null</code> and <code>not_null</code> (<a href="#14.3.3">Section + 14.3.3, "<code>null</code>/<code>not_null</code>"</a>) specifiers can be used to control the NULL semantics of a type.</p> <p>In the above example we changed the mapping for the <code>bool</code> @@ -11575,13 +12343,13 @@ class person <code>mapping</code> example in the <code>odb-examples</code> package shows how to do this for all the supported database systems.</p> - <h3><a name="12.3.2">12.3.2 <code>id_type</code></a></h3> + <h3><a name="14.3.2">14.3.2 <code>id_type</code></a></h3> <p>The <code>id_type</code> specifier specifies the native database type that should be used for data members of this type that are designated as - object identifiers (<a href="#12.4.1">Section 12.4.1, + object identifiers (<a href="#14.4.1">Section 14.4.1, "<code>id</code>"</a>). In combination with the <code>type</code> - specifier (<a href="#12.3.1">Section 12.3.1, "<code>type</code>"</a>) + specifier (<a href="#14.3.1">Section 14.3.1, "<code>type</code>"</a>) <code>id_type</code> allows you to map a C++ type differently depending on whether it is used in an ordinary member or an object id. For example:</p> @@ -11616,7 +12384,7 @@ class person }; </pre> - <h3><a name="12.3.3">12.3.3 <code>null</code>/<code>not_null</code></a></h3> + <h3><a name="14.3.3">14.3.3 <code>null</code>/<code>not_null</code></a></h3> <p>The <code>null</code> and <code>not_null</code> specifiers specify that a value type or object pointer can or cannot be <code>NULL</code>, @@ -11645,7 +12413,7 @@ typedef shared_ptr<person> person_ptr; </pre> <p>The <code>NULL</code> semantics can also be specified on the - per-member basis (<a href="#12.4.6">Section 12.4.6, + per-member basis (<a href="#14.4.6">Section 14.4.6, "<code>null</code>/<code>not_null</code>"</a>). If both a type and a member have <code>null</code>/<code>not_null</code> specifiers, then the member specifier takes precedence. If a member specifier @@ -11679,7 +12447,7 @@ typedef shared_ptr<person> person_ptr; discussion of the <code>NULL</code> semantics for object pointers, refer to <a href="#6">Chapter 6, "Relationships"</a>.</p> - <h3><a name="12.3.4">12.3.4 <code>default</code></a></h3> + <h3><a name="14.3.4">14.3.4 <code>default</code></a></h3> <p>The <code>default</code> specifier specifies the database default value that should be used for data members of this type. For example:</p> @@ -11698,10 +12466,10 @@ class person <p>The semantics of the <code>default</code> specifier for a value type are similar to those of the <code>default</code> specifier for a - data member (<a href="#12.4.7">Section 12.4.7, + data member (<a href="#14.4.7">Section 14.4.7, "<code>default</code>"</a>).</p> - <h3><a name="12.3.5">12.3.5 <code>options</code></a></h3> + <h3><a name="14.3.5">14.3.5 <code>options</code></a></h3> <p>The <code>options</code> specifier specifies additional column definition options that should be used for data members of this @@ -11721,10 +12489,10 @@ class person <p>The semantics of the <code>options</code> specifier for a value type are similar to those of the <code>options</code> specifier for a - data member (<a href="#12.4.8">Section 12.4.8, + data member (<a href="#14.4.8">Section 14.4.8, "<code>options</code>"</a>).</p> - <h3><a name="12.3.6">12.3.6 <code>readonly</code></a></h3> + <h3><a name="14.3.6">14.3.6 <code>readonly</code></a></h3> <p>The <code>readonly</code> specifier specifies that the composite value type is read-only. Changes to data members of a read-only @@ -11750,11 +12518,11 @@ class person_name read-only while the rest is treated as read-write.</p> <p>Note that it is also possible to declare individual data members - (<a href="#12.4.12">Section 12.4.12, "<code>readonly</code>"</a>) - as well as whole objects (<a href="#12.1.4">Section 12.1.4, + (<a href="#14.4.12">Section 14.4.12, "<code>readonly</code>"</a>) + as well as whole objects (<a href="#14.1.4">Section 14.1.4, "<code>readonly</code>"</a>) as read-only.</p> - <h3><a name="12.3.7">12.3.7 <code>definition</code></a></h3> + <h3><a name="14.3.7">14.3.7 <code>definition</code></a></h3> <p>The <code>definition</code> specifier specifies an alternative <em>definition location</em> for the composite value type. By @@ -11819,16 +12587,16 @@ class object }; </pre> - <h3><a name="12.3.8">12.3.8 <code>transient</code></a></h3> + <h3><a name="14.3.8">14.3.8 <code>transient</code></a></h3> <p>The <code>transient</code> specifier instructs the ODB compiler to treat all non-virtual data members in the composite value type - as transient (<a href="#12.4.1">Section 12.4.1, + as transient (<a href="#14.4.1">Section 14.4.1, "<code>transient</code>"</a>). This specifier is primarily useful when declaring virtual data members, as discussed in - <a href="#12.4.13">Section 12.4.13, "<code>virtual</code>"</a>.</p> + <a href="#14.4.13">Section 14.4.13, "<code>virtual</code>"</a>.</p> - <h3><a name="12.3.9">12.3.9 <code>unordered</code></a></h3> + <h3><a name="14.3.9">14.3.9 <code>unordered</code></a></h3> <p>The <code>unordered</code> specifier specifies that the ordered container should be stored unordered in the database. The database @@ -11845,13 +12613,13 @@ typedef std::vector<std::string> names; storage in the database, refer to <a href="#5.1">Section 5.1, "Ordered Containers"</a>.</p> - <h3><a name="12.3.10">12.3.10 <code>index_type</code></a></h3> + <h3><a name="14.3.10">14.3.10 <code>index_type</code></a></h3> <p>The <code>index_type</code> specifier specifies the native database type that should be used for the ordered container's index column. The semantics of <code>index_type</code> are similar to those of the <code>type</code> specifier - (<a href="#12.3.1">Section 12.3.1, "<code>type</code>"</a>). The native + (<a href="#14.3.1">Section 14.3.1, "<code>type</code>"</a>). The native database type is expected to be an integer type. For example:</p> <pre class="cxx"> @@ -11859,13 +12627,13 @@ typedef std::vector<std::string> names; #pragma db value(names) index_type("SMALLINT UNSIGNED") </pre> - <h3><a name="12.3.11">12.3.11 <code>key_type</code></a></h3> + <h3><a name="14.3.11">14.3.11 <code>key_type</code></a></h3> <p>The <code>key_type</code> specifier specifies the native database type that should be used for the map container's key column. The semantics of <code>key_type</code> are similar to those of the <code>type</code> specifier - (<a href="#12.3.1">Section 12.3.1, "<code>type</code>"</a>). For + (<a href="#14.3.1">Section 14.3.1, "<code>type</code>"</a>). For example:</p> <pre class="cxx"> @@ -11873,13 +12641,13 @@ typedef std::map<unsigned short, float> age_weight_map; #pragma db value(age_weight_map) key_type("INT UNSIGNED") </pre> - <h3><a name="12.3.12">12.3.12 <code>value_type</code></a></h3> + <h3><a name="14.3.12">14.3.12 <code>value_type</code></a></h3> <p>The <code>value_type</code> specifier specifies the native database type that should be used for the container's value column. The semantics of <code>value_type</code> are similar to those of the <code>type</code> specifier - (<a href="#12.3.1">Section 12.3.1, "<code>type</code>"</a>). For + (<a href="#14.3.1">Section 14.3.1, "<code>type</code>"</a>). For example:</p> <pre class="cxx"> @@ -11888,18 +12656,18 @@ typedef std::vector<std::string> names; </pre> <p>The <code>value_null</code> and <code>value_not_null</code> - (<a href="#12.3.13">Section 12.3.13, + (<a href="#14.3.13">Section 14.3.13, "<code>value_null</code>/<code>value_not_null</code>"</a>) specifiers can be used to control the NULL semantics of a value column.</p> - <h3><a name="12.3.13">12.3.13 <code>value_null</code>/<code>value_not_null</code></a></h3> + <h3><a name="14.3.13">14.3.13 <code>value_null</code>/<code>value_not_null</code></a></h3> <p>The <code>value_null</code> and <code>value_not_null</code> specifiers specify that the container type's element value can or cannot be <code>NULL</code>, respectively. The semantics of <code>value_null</code> and <code>value_not_null</code> are similar to those of the <code>null</code> and <code>not_null</code> specifiers - (<a href="#12.3.3">Section 12.3.3, "<code>null</code>/<code>not_null</code>"</a>). + (<a href="#14.3.3">Section 14.3.3, "<code>null</code>/<code>not_null</code>"</a>). For example:</p> <pre class="cxx"> @@ -11920,7 +12688,7 @@ typedef std::vector<shared_ptr<account> > accounts; as not allowing a <code>NULL</code> value.</p> - <h3><a name="12.3.14">12.3.14 <code>id_options</code></a></h3> + <h3><a name="14.3.14">14.3.14 <code>id_options</code></a></h3> <p>The <code>id_options</code> specifier specifies additional column definition options that should be used for the container's @@ -11933,11 +12701,11 @@ typedef std::vector<std::string> nicknames; <p>The semantics of the <code>id_options</code> specifier for a container type are similar to those of the <code>id_options</code> specifier for - a container data member (<a href="#12.4.24">Section 12.4.24, + a container data member (<a href="#14.4.26">Section 14.4.26, "<code>id_options</code>"</a>).</p> - <h3><a name="12.3.15">12.3.15 <code>index_options</code></a></h3> + <h3><a name="14.3.15">14.3.15 <code>index_options</code></a></h3> <p>The <code>index_options</code> specifier specifies additional column definition options that should be used for the container's @@ -11950,11 +12718,11 @@ typedef std::vector<std::string> nicknames; <p>The semantics of the <code>index_options</code> specifier for a container type are similar to those of the <code>index_options</code> specifier for - a container data member (<a href="#12.4.25">Section 12.4.25, + a container data member (<a href="#14.4.27">Section 14.4.27, "<code>index_options</code>"</a>).</p> - <h3><a name="12.3.16">12.3.16 <code>key_options</code></a></h3> + <h3><a name="14.3.16">14.3.16 <code>key_options</code></a></h3> <p>The <code>key_options</code> specifier specifies additional column definition options that should be used for the container's @@ -11967,11 +12735,11 @@ typedef std::map<std::string, std::string> properties; <p>The semantics of the <code>key_options</code> specifier for a container type are similar to those of the <code>key_options</code> specifier for - a container data member (<a href="#12.4.26">Section 12.4.26, + a container data member (<a href="#14.4.28">Section 14.4.28, "<code>key_options</code>"</a>).</p> - <h3><a name="12.3.17">12.3.17 <code>value_options</code></a></h3> + <h3><a name="14.3.17">14.3.17 <code>value_options</code></a></h3> <p>The <code>value_options</code> specifier specifies additional column definition options that should be used for the container's @@ -11984,11 +12752,11 @@ typedef std::set<std::string> nicknames; <p>The semantics of the <code>value_options</code> specifier for a container type are similar to those of the <code>value_options</code> specifier for - a container data member (<a href="#12.4.27">Section 12.4.27, + a container data member (<a href="#14.4.29">Section 14.4.29, "<code>value_options</code>"</a>).</p> - <h3><a name="12.3.18">12.3.18 <code>id_column</code></a></h3> + <h3><a name="14.3.18">14.3.18 <code>id_column</code></a></h3> <p>The <code>id_column</code> specifier specifies the column name that should be used to store the object id in the @@ -12002,7 +12770,7 @@ typedef std::vector<std::string> names; <p>If the column name is not specified, then <code>object_id</code> is used by default.</p> - <h3><a name="12.3.19">12.3.19 <code>index_column</code></a></h3> + <h3><a name="14.3.19">14.3.19 <code>index_column</code></a></h3> <p>The <code>index_column</code> specifier specifies the column name that should be used to store the element index in the @@ -12016,7 +12784,7 @@ typedef std::vector<std::string> names; <p>If the column name is not specified, then <code>index</code> is used by default.</p> - <h3><a name="12.3.20">12.3.20 <code>key_column</code></a></h3> + <h3><a name="14.3.20">14.3.20 <code>key_column</code></a></h3> <p>The <code>key_column</code> specifier specifies the column name that should be used to store the key in the map @@ -12030,7 +12798,7 @@ typedef std::map<unsigned short, float> age_weight_map; <p>If the column name is not specified, then <code>key</code> is used by default.</p> - <h3><a name="12.3.21">12.3.21 <code>value_column</code></a></h3> + <h3><a name="14.3.21">14.3.21 <code>value_column</code></a></h3> <p>The <code>value_column</code> specifier specifies the column name that should be used to store the element value in the @@ -12047,7 +12815,7 @@ typedef std::map<unsigned short, float> age_weight_map; <!-- Data Member Pragmas --> - <h2><a name="12.4">12.4 Data Member Pragmas</a></h2> + <h2><a name="14.4">14.4 Data Member Pragmas</a></h2> <p>A pragma with the <code>member</code> qualifier or a positioned pragma without a qualifier describes a data member. It can @@ -12065,193 +12833,205 @@ typedef std::map<unsigned short, float> age_weight_map; <tr> <td><code>id</code></td> <td>member is an object id</td> - <td><a href="#12.4.1">12.4.1</a></td> + <td><a href="#14.4.1">14.4.1</a></td> </tr> <tr> <td><code>auto</code></td> <td>id is assigned by the database</td> - <td><a href="#12.4.2">12.4.2</a></td> + <td><a href="#14.4.2">14.4.2</a></td> </tr> <tr> <td><code>type</code></td> <td>database type for a member</td> - <td><a href="#12.4.3">12.4.3</a></td> + <td><a href="#14.4.3">14.4.3</a></td> </tr> <tr> <td><code>id_type</code></td> <td>database type for a member when used as an object id</td> - <td><a href="#12.4.4">12.4.4</a></td> + <td><a href="#14.4.4">14.4.4</a></td> </tr> <tr> <td><code>get</code>/<code>set</code>/<code>access</code></td> <td>member accessor/modifier expressions</td> - <td><a href="#12.4.5">12.4.5</a></td> + <td><a href="#14.4.5">14.4.5</a></td> </tr> <tr> <td><code>null</code>/<code>not_null</code></td> <td>member can/cannot be <code>NULL</code></td> - <td><a href="#12.4.6">12.4.6</a></td> + <td><a href="#14.4.6">14.4.6</a></td> </tr> <tr> <td><code>default</code></td> <td>default value for a member</td> - <td><a href="#12.4.7">12.4.7</a></td> + <td><a href="#14.4.7">14.4.7</a></td> </tr> <tr> <td><code>options</code></td> <td>database options for a member</td> - <td><a href="#12.4.8">12.4.8</a></td> + <td><a href="#14.4.8">14.4.8</a></td> </tr> <tr> <td><code>column</code></td> <td>column name for a member of an object or composite value</td> - <td><a href="#12.4.9">12.4.9</a></td> + <td><a href="#14.4.9">14.4.9</a></td> </tr> <tr> <td><code>column</code></td> <td>column name for a member of a view</td> - <td><a href="#12.4.10">12.4.10</a></td> + <td><a href="#14.4.10">14.4.10</a></td> </tr> <tr> <td><code>transient</code></td> <td>member is not stored in the database</td> - <td><a href="#12.4.11">12.4.11</a></td> + <td><a href="#14.4.11">14.4.11</a></td> </tr> <tr> <td><code>readonly</code></td> <td>member is read-only</td> - <td><a href="#12.4.12">12.4.12</a></td> + <td><a href="#14.4.12">14.4.12</a></td> </tr> <tr> <td><code>virtual</code></td> <td>declare a virtual data member</td> - <td><a href="#12.4.13">12.4.13</a></td> + <td><a href="#14.4.13">14.4.13</a></td> </tr> <tr> <td><code>inverse</code></td> <td>member is an inverse side of a bidirectional relationship</td> - <td><a href="#12.4.14">12.4.14</a></td> + <td><a href="#14.4.14">14.4.14</a></td> </tr> <tr> <td><code>version</code></td> <td>member stores object version</td> - <td><a href="#12.4.15">12.4.15</a></td> + <td><a href="#14.4.15">14.4.15</a></td> </tr> <tr> <td><code>index</code></td> <td>define database index for a member</td> - <td><a href="#12.4.16">12.4.16</a></td> + <td><a href="#14.4.16">14.4.16</a></td> </tr> <tr> <td><code>unique</code></td> <td>define unique database index for a member</td> - <td><a href="#12.4.17">12.4.17</a></td> + <td><a href="#14.4.17">14.4.17</a></td> </tr> <tr> <td><code>unordered</code></td> <td>ordered container should be stored unordered</td> - <td><a href="#12.4.18">12.4.18</a></td> + <td><a href="#14.4.18">14.4.18</a></td> </tr> <tr> <td><code>table</code></td> <td>table name for a container</td> - <td><a href="#12.4.19">12.4.19</a></td> + <td><a href="#14.4.19">14.4.19</a></td> + </tr> + + <tr> + <td><code>load</code>/<code>update</code></td> + <td>loading/updating behavior for a section</td> + <td><a href="#14.4.20">14.4.20</a></td> + </tr> + + <tr> + <td><code>section</code></td> + <td>member belongs to a section</td> + <td><a href="#14.4.21">14.4.21</a></td> </tr> <tr> <td><code>index_type</code></td> <td>database type for a container's index type</td> - <td><a href="#12.4.20">12.4.20</a></td> + <td><a href="#14.4.22">14.4.22</a></td> </tr> <tr> <td><code>key_type</code></td> <td>database type for a container's key type</td> - <td><a href="#12.4.21">12.4.21</a></td> + <td><a href="#14.4.23">14.4.23</a></td> </tr> <tr> <td><code>value_type</code></td> <td>database type for a container's value type</td> - <td><a href="#12.4.22">12.4.22</a></td> + <td><a href="#14.4.24">14.4.24</a></td> </tr> <tr> <td><code>value_null</code>/<code>value_not_null</code></td> <td>container's value can/cannot be <code>NULL</code></td> - <td><a href="#12.4.23">12.4.23</a></td> + <td><a href="#14.4.25">14.4.25</a></td> </tr> <tr> <td><code>id_options</code></td> <td>database options for a container's id column</td> - <td><a href="#12.4.24">12.4.24</a></td> + <td><a href="#14.4.26">14.4.26</a></td> </tr> <tr> <td><code>index_options</code></td> <td>database options for a container's index column</td> - <td><a href="#12.4.25">12.4.25</a></td> + <td><a href="#14.4.27">14.4.27</a></td> </tr> <tr> <td><code>key_options</code></td> <td>database options for a container's key column</td> - <td><a href="#12.4.26">12.4.26</a></td> + <td><a href="#14.4.28">14.4.28</a></td> </tr> <tr> <td><code>value_options</code></td> <td>database options for a container's value column</td> - <td><a href="#12.4.27">12.4.27</a></td> + <td><a href="#14.4.29">14.4.29</a></td> </tr> <tr> <td><code>id_column</code></td> <td>column name for a container's object id</td> - <td><a href="#12.4.28">12.4.28</a></td> + <td><a href="#14.4.30">14.4.30</a></td> </tr> <tr> <td><code>index_column</code></td> <td>column name for a container's index</td> - <td><a href="#12.4.29">12.4.29</a></td> + <td><a href="#14.4.31">14.4.31</a></td> </tr> <tr> <td><code>key_column</code></td> <td>column name for a container's key</td> - <td><a href="#12.4.30">12.4.30</a></td> + <td><a href="#14.4.32">14.4.32</a></td> </tr> <tr> <td><code>value_column</code></td> <td>column name for a container's value</td> - <td><a href="#12.4.31">12.4.31</a></td> + <td><a href="#14.4.33">14.4.33</a></td> </tr> </table> <p>Many of the member specifiers have corresponding value type - specifiers with the same names (<a href="#12.3">Section 12.3, + specifiers with the same names (<a href="#14.3">Section 14.3, "Value Type Pragmas"</a>). The behavior of such specifiers for members is similar to that for value types. The only difference is the scope. A particular value type specifier applies to all the @@ -12261,7 +13041,7 @@ typedef std::map<unsigned short, float> age_weight_map; take precedence over and override parameters specified with value specifiers.</p> - <h3><a name="12.4.1">12.4.1 <code>id</code></a></h3> + <h3><a name="14.4.1">14.4.1 <code>id</code></a></h3> <p>The <code>id</code> specifier specifies that the data member contains the object id. In a relational database, an identifier member is @@ -12281,12 +13061,12 @@ class person <p>Normally, every persistent class has a data member designated as an object's identifier. However, it is possible to declare a persistent class without an id using the object <code>no_id</code> - specifier (<a href="#12.1.6">Section 12.1.6, "<code>no_id</code>"</a>).</p> + specifier (<a href="#14.1.6">Section 14.1.6, "<code>no_id</code>"</a>).</p> <p>Note also that the <code>id</code> specifier cannot be used for data members of composite value types or views.</p> - <h3><a name="12.4.2">12.4.2 <code>auto</code></a></h3> + <h3><a name="14.4.2">14.4.2 <code>auto</code></a></h3> <p>The <code>auto</code> specifier specifies that the object's identifier is automatically assigned by the database. Only a member that was @@ -12316,7 +13096,7 @@ class person <p>Note also that the <code>auto</code> specifier cannot be specified for data members of composite value types or views.</p> - <h3><a name="12.4.3">12.4.3 <code>type</code></a></h3> + <h3><a name="14.4.3">14.4.3 <code>type</code></a></h3> <p>The <code>type</code> specifier specifies the native database type that should be used for the data member. For example:</p> @@ -12332,14 +13112,14 @@ class person }; </pre> - <p>The <code>null</code> and <code>not_null</code> (<a href="#12.4.6">Section - 12.4.6, "<code>null</code>/<code>not_null</code>"</a>) specifiers + <p>The <code>null</code> and <code>not_null</code> (<a href="#14.4.6">Section + 14.4.6, "<code>null</code>/<code>not_null</code>"</a>) specifiers can be used to control the NULL semantics of a data member. It is also possible to specify the database type on the per-type instead of the per-member basis using the value <code>type</code> - specifier (<a href="#12.3.1">Section 12.3.1, "<code>type</code>"</a>).</p> + specifier (<a href="#14.3.1">Section 14.3.1, "<code>type</code>"</a>).</p> - <h3><a name="12.4.4">12.4.4 <code>id_type</code></a></h3> + <h3><a name="14.4.4">14.4.4 <code>id_type</code></a></h3> <p>The <code>id_type</code> specifier specifies the native database type that should be used for the data member when it is part of an @@ -12372,7 +13152,7 @@ class person }; </pre> - <h3><a name="12.4.5">12.4.5 <code>get</code>/<code>set</code>/<code>access</code></a></h3> + <h3><a name="14.4.5">14.4.5 <code>get</code>/<code>set</code>/<code>access</code></a></h3> <p>The <code>get</code> and <code>set</code> specifiers specify the data member accessor and modifier expressions, respectively. If @@ -12561,7 +13341,7 @@ class person types. They can be used for data members in persistent classes, composite value types, and views. There is also a mechanism related to accessors and modifiers called virtual data members - and which is discussed in <a href="#12.4.13">Section 12.4.13, + and which is discussed in <a href="#14.4.13">Section 14.4.13, "<code>virtual</code>"</a>.</p> <p>There are, however, certain limitations when it comes to using @@ -12604,7 +13384,7 @@ private: limitations, refer to the "Limitations" sections in <a href="#II">Part II, "Database Systems"</a>.</p> - <h3><a name="12.4.6">12.4.6 <code>null</code>/<code>not_null</code></a></h3> + <h3><a name="14.4.6">14.4.6 <code>null</code>/<code>not_null</code></a></h3> <p>The <code>null</code> and <code>not_null</code> specifiers specify that the data member can or cannot be <code>NULL</code>, respectively. @@ -12616,8 +13396,8 @@ private: not allow <code>NULL</code> values, depending on the semantics of each value type. Consult the relevant documentation to find out more about the <code>NULL</code> semantics for such value - types. A data member containing the object id (<a href="#12.4.1">Section - 12.4.1, "<code>id</code>"</a>) is automatically treated as not + types. A data member containing the object id (<a href="#14.4.1">Section + 14.4.1, "<code>id</code>"</a>) is automatically treated as not allowing a <code>NULL</code> value. Data members that allow <code>NULL</code> values are mapped in a relational database to columns that allow <code>NULL</code> values. For example:</p> @@ -12645,7 +13425,7 @@ class account </pre> <p>The <code>NULL</code> semantics can also be specified on the - per-type basis (<a href="#12.3.3">Section 12.3.3, + per-type basis (<a href="#14.3.3">Section 14.3.3, "<code>null</code>/<code>not_null</code>"</a>). If both a type and a member have <code>null</code>/<code>not_null</code> specifiers, then the member specifier takes precedence. If a member specifier @@ -12659,7 +13439,7 @@ class account discussion of the <code>NULL</code> semantics for object pointers, refer to <a href="#6">Chapter 6, "Relationships"</a>.</p> - <h3><a name="12.4.7">12.4.7 <code>default</code></a></h3> + <h3><a name="14.4.7">14.4.7 <code>default</code></a></h3> <p>The <code>default</code> specifier specifies the database default value that should be used for the data member. For example:</p> @@ -12680,8 +13460,8 @@ class person an integer literal, a floating point literal, a string literal, or an enumerator name. If you need to specify a default value that is an expression, for example an SQL function call, then you can use - the <code>options</code> specifier (<a href="#12.4.8">Section - 12.4.8, "<code>options</code>"</a>) instead. For example:</p> + the <code>options</code> specifier (<a href="#14.4.8">Section + 14.4.8, "<code>options</code>"</a>) instead. For example:</p> <pre class="cxx"> enum gender {male, female, undisclosed}; @@ -12734,7 +13514,7 @@ class person </pre> <p>A default value can also be specified on the per-type basis - (<a href="#12.3.4">Section 12.3.4, "<code>default</code>"</a>). + (<a href="#14.3.4">Section 14.3.4, "<code>default</code>"</a>). An empty <code>default</code> specifier can be used to reset a default value that was previously specified on the per-type basis. For example:</p> @@ -12752,8 +13532,8 @@ class person }; </pre> - <p>A data member containing the object id (<a href="#12.4.1">Section - 12.4.1, "<code>id</code>"</a> ) is automatically treated as not + <p>A data member containing the object id (<a href="#14.4.1">Section + 14.4.1, "<code>id</code>"</a> ) is automatically treated as not having a default value even if its type specifies a default value.</p> <p>Note also that default values do not affect the generated C++ code @@ -12767,7 +13547,7 @@ class person <p>Additionally, the <code>default</code> specifier cannot be specified for view data members.</p> - <h3><a name="12.4.8">12.4.8 <code>options</code></a></h3> + <h3><a name="14.4.8">14.4.8 <code>options</code></a></h3> <p>The <code>options</code> specifier specifies additional column definition options that should be used for the data member. For @@ -12785,7 +13565,7 @@ class person </pre> <p>Options can also be specified on the per-type basis - (<a href="#12.3.5">Section 12.3.5, "<code>options</code>"</a>). + (<a href="#14.3.5">Section 14.3.5, "<code>options</code>"</a>). By default, options are accumulating. That is, the ODB compiler first adds all the options specified for a value type followed by all the options specified for a data member. To clear the @@ -12814,10 +13594,10 @@ class person </pre> <p>ODB provides dedicated specifiers for specifying column types - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), - <code>NULL</code> constraints (<a href="#12.4.6">Section 12.4.6, + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), + <code>NULL</code> constraints (<a href="#14.4.6">Section 14.4.6, "<code>null</code>/<code>not_null</code>"</a>), and default - values (<a href="#12.4.7">Section 12.4.7, "<code>default</code>"</a>). + values (<a href="#14.4.7">Section 14.4.7, "<code>default</code>"</a>). For ODB to function correctly these specifiers should always be used instead of the opaque <code>options</code> specifier for these components of a column definition.</p> @@ -12825,7 +13605,7 @@ class person <p>Note also that the <code>options</code> specifier cannot be specified for view data members.</p> - <h3><a name="12.4.9">12.4.9 <code>column</code> (object, composite value)</a></h3> + <h3><a name="14.4.9">14.4.9 <code>column</code> (object, composite value)</a></h3> <p>The <code>column</code> specifier specifies the column name that should be used to store the data member of a persistent class @@ -12851,15 +13631,15 @@ class person the common data member name decorations, such as leading and trailing underscores, the <code>m_</code> prefix, etc.</p> - <h3><a name="12.4.10">12.4.10 <code>column</code> (view)</a></h3> + <h3><a name="14.4.10">14.4.10 <code>column</code> (view)</a></h3> <p>The <code>column</code> specifier can be used to specify the associated object data member, the potentially qualified column name, or the column expression for the data member of a view class. For more information, - refer to <a href="#9.1">Section 9.1, "Object Views"</a> and - <a href="#9.2">Section 9.2, "Table Views"</a>.</p> + refer to <a href="#10.1">Section 10.1, "Object Views"</a> and + <a href="#10.2">Section 10.2, "Table Views"</a>.</p> - <h3><a name="12.4.11">12.4.11 <code>transient</code></a></h3> + <h3><a name="14.4.11">14.4.11 <code>transient</code></a></h3> <p>The <code>transient</code> specifier instructs the ODB compiler not to store the data member in the database. For example:</p> @@ -12881,7 +13661,7 @@ class person references that are only meaningful in the application's memory, as well as utility members such as mutexes, etc.</p> - <h3><a name="12.4.12">12.4.12 <code>readonly</code></a></h3> + <h3><a name="14.4.12">14.4.12 <code>readonly</code></a></h3> <p>The <code>readonly</code> specifier specifies that the data member of an object or composite value type is read-only. Changes to a read-only @@ -12889,8 +13669,8 @@ class person (<a href="#3.10">Section 3.10, "Updating Persistent Objects"</a>) containing such a member. Since views are read-only, it is not necessary to use this specifier for view data members. Object id - (<a href="#12.4.1">Section 12.4.1, "<code>id</code>"</a>) - and inverse (<a href="#12.4.14">Section 12.4.14, + (<a href="#14.4.1">Section 14.4.1, "<code>id</code>"</a>) + and inverse (<a href="#14.4.14">Section 14.4.14, "<code>inverse</code>"</a>) data members are automatically treated as read-only and must not be explicitly declared as such. For example:</p> @@ -12970,11 +13750,11 @@ class person as read-only.</p> <p>Note that it is also possible to declare composite value types - (<a href="#12.3.6">Section 12.3.6, "<code>readonly</code>"</a>) - as well as whole objects (<a href="#12.1.4">Section 12.1.4, + (<a href="#14.3.6">Section 14.3.6, "<code>readonly</code>"</a>) + as well as whole objects (<a href="#14.1.4">Section 14.1.4, "<code>readonly</code>"</a>) as read-only.</p> - <h3><a name="12.4.13">12.4.13 <code>virtual</code></a></h3> + <h3><a name="14.4.13">14.4.13 <code>virtual</code></a></h3> <p>The <code>virtual</code> specifier is used to declare a virtual data member in an object, view, or composite value type. A virtual @@ -12992,7 +13772,7 @@ class person specifier. Finally, the virtual data member declaration must also specify the accessor and modifier expressions, unless suitable accessor and modifier functions can automatically be - found by the ODB compiler (<a href="#12.4.5">Section 12.4.5, + found by the ODB compiler (<a href="#14.4.5">Section 14.4.5, "<code>get</code>/<code>set</code>/<code>access</code>"</a>). For example:</p> @@ -13144,11 +13924,11 @@ private: data as transient. If all the real data members in a class are treated as transient, then we can use the class-level <code>transient</code> specifier - (<a href="#12.1.12">Section 12.1.12, "<code>transient</code> + (<a href="#14.1.12">Section 14.1.12, "<code>transient</code> (object)"</a>, - <a href="#12.3.8">Section 12.3.8, "<code>transient</code> + <a href="#14.3.8">Section 14.3.8, "<code>transient</code> (composite value)"</a>, - <a href="#12.2.7">Section 12.2.7, "<code>transient</code> + <a href="#14.2.7">Section 14.2.7, "<code>transient</code> (view)"</a>) instead of doing it for each individual member. For example: </p> @@ -13207,7 +13987,7 @@ private: container, or object pointer types. They can be used in persistent classes, composite value types, and views.</p> - <h3><a name="12.4.14">12.4.14 <code>inverse</code></a></h3> + <h3><a name="14.4.14">14.4.14 <code>inverse</code></a></h3> <p>The <code>inverse</code> specifier specifies that the data member of an object pointer or a container of object pointers type is an @@ -13245,18 +14025,18 @@ class person 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 - (<a href="#12.4.18">Section 12.4.18, "<code>unordered</code>"</a>).</p> + (<a href="#14.4.18">Section 14.4.18, "<code>unordered</code>"</a>).</p> <p>For a more detailed discussion of inverse members, refer to <a href="#6.2">Section 6.2, "Bidirectional Relationships"</a>.</p> - <h3><a name="12.4.15">12.4.15 <code>version</code></a></h3> + <h3><a name="14.4.15">14.4.15 <code>version</code></a></h3> <p>The <code>version</code> specifier specifies that the data member stores the object version used to support optimistic concurrency. If a class has a version data member, then it must also be declared as having the optimistic concurrency model using the <code>optimistic</code> pragma - (<a href="#12.1.5">Section 12.1.5, "<code>optimistic</code>"</a>). For + (<a href="#14.1.5">Section 14.1.5, "<code>optimistic</code>"</a>). For example:</p> <pre class="cxx"> @@ -13278,9 +14058,9 @@ class person choice.</p> <p>For a more detailed discussion of optimistic concurrency, refer to - <a href="#11">Chapter 11, "Optimistic Concurrency"</a>.</p> + <a href="#12">Chapter 12, "Optimistic Concurrency"</a>.</p> - <h3><a name="12.4.16">12.4.16 <code>index</code></a></h3> + <h3><a name="14.4.16">14.4.16 <code>index</code></a></h3> <p>The <code>index</code> specifier instructs the ODB compiler to define a database index for the data member. For example:</p> @@ -13297,9 +14077,9 @@ class person </pre> <p>For more information on defining database indexes, refer to - <a href="#12.6">Section 12.6, "Index Definition Pragmas"</a>.</p> + <a href="#14.6">Section 14.6, "Index Definition Pragmas"</a>.</p> - <h3><a name="12.4.17">12.4.17 <code>unique</code></a></h3> + <h3><a name="14.4.17">14.4.17 <code>unique</code></a></h3> <p>The <code>index</code> specifier instructs the ODB compiler to define a unique database index for the data member. For example:</p> @@ -13316,9 +14096,9 @@ class person </pre> <p>For more information on defining database indexes, refer to - <a href="#12.6">Section 12.6, "Index Definition Pragmas"</a>.</p> + <a href="#14.6">Section 14.6, "Index Definition Pragmas"</a>.</p> - <h3><a name="12.4.18">12.4.18 <code>unordered</code></a></h3> + <h3><a name="14.4.18">14.4.18 <code>unordered</code></a></h3> <p>The <code>unordered</code> specifier specifies that the member of an ordered container type should be stored unordered in the database. @@ -13341,7 +14121,7 @@ class person storage in the database, refer to <a href="#5.1">Section 5.1, "Ordered Containers"</a>.</p> - <h3><a name="12.4.19">12.4.19 <code>table</code></a></h3> + <h3><a name="14.4.19">14.4.19 <code>table</code></a></h3> <p>The <code>table</code> specifier specifies the table name that should be used to store the contents of the container member. For example:</p> @@ -13386,16 +14166,35 @@ class person </pre> <p>For more information on database schemas and the format of the - qualified names, refer to <a href="#12.1.8">Section 12.1.8, + qualified names, refer to <a href="#14.1.8">Section 14.1.8, "<code>schema</code>"</a>.</p> - <h3><a name="12.4.20">12.4.20 <code>index_type</code></a></h3> + <h3><a name="14.4.20">14.4.20 <code>load</code>/<code>update</code></a></h3> + + <p>The <code>load</code> and <code>update</code> specifiers specify the + loading and updating behavior for an object section, respectively. + Valid values for the <code>load</code> specifier are + <code>eager</code> (default) and <code>lazy</code>. Valid values for + the <code>update</code> specifier are <code>always</code> (default), + <code>change</code>, and <code>manual</code>. For more information + on object sections, refer to <a href="#9">Chapter 9, "Sections"</a>.</p> + + <h3><a name="14.4.21">14.4.21 <code>section</code></a></h3> + + <p>The <code>section</code> specifier indicates that a data member + of a persistent class belongs to an object section. The single + required argument to this specifier is the name of the section + data member. This specifier can only be used on direct data + members of a persistent class. For more information on object + sections, refer to <a href="#9">Chapter 9, "Sections"</a>.</p> + + <h3><a name="14.4.22">14.4.22 <code>index_type</code></a></h3> <p>The <code>index_type</code> specifier specifies the native database type that should be used for an ordered container's index column of the data member. The semantics of <code>index_type</code> are similar to those of the <code>type</code> specifier - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>). The native + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>). The native database type is expected to be an integer type. For example:</p> <pre class="cxx"> @@ -13409,13 +14208,13 @@ class person }; </pre> - <h3><a name="12.4.21">12.4.21 <code>key_type</code></a></h3> + <h3><a name="14.4.23">14.4.23 <code>key_type</code></a></h3> <p>The <code>key_type</code> specifier specifies the native database type that should be used for a map container's key column of the data member. The semantics of <code>key_type</code> are similar to those of the <code>type</code> specifier - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>). For + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>). For example:</p> <pre class="cxx"> @@ -13429,13 +14228,13 @@ class person }; </pre> - <h3><a name="12.4.22">12.4.22 <code>value_type</code></a></h3> + <h3><a name="14.4.24">14.4.24 <code>value_type</code></a></h3> <p>The <code>value_type</code> specifier specifies the native database type that should be used for a container's value column of the data member. The semantics of <code>value_type</code> are similar to those of the <code>type</code> specifier - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>). For + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>). For example:</p> <pre class="cxx"> @@ -13450,18 +14249,18 @@ class person </pre> <p>The <code>value_null</code> and <code>value_not_null</code> - (<a href="#12.4.23">Section 12.4.23, + (<a href="#14.4.25">Section 14.4.25, "<code>value_null</code>/<code>value_not_null</code>"</a>) specifiers can be used to control the NULL semantics of a value column.</p> - <h3><a name="12.4.23">12.4.23 <code>value_null</code>/<code>value_not_null</code></a></h3> + <h3><a name="14.4.25">14.4.25 <code>value_null</code>/<code>value_not_null</code></a></h3> <p>The <code>value_null</code> and <code>value_not_null</code> specifiers specify that a container's element value for the data member can or cannot be <code>NULL</code>, respectively. The semantics of <code>value_null</code> and <code>value_not_null</code> are similar to those of the <code>null</code> and <code>not_null</code> specifiers - (<a href="#12.4.6">Section 12.4.6, "<code>null</code>/<code>not_null</code>"</a>). + (<a href="#14.4.6">Section 14.4.6, "<code>null</code>/<code>not_null</code>"</a>). For example:</p> <pre class="cxx"> @@ -13487,7 +14286,7 @@ class account Multiset Containers"</a>) the element value is automatically treated as not allowing a <code>NULL</code> value.</p> - <h3><a name="12.4.24">12.4.24 <code>id_options</code></a></h3> + <h3><a name="14.4.26">14.4.26 <code>id_options</code></a></h3> <p>The <code>id_options</code> specifier specifies additional column definition options that should be used for a container's @@ -13508,10 +14307,10 @@ class person </pre> <p>The semantics of <code>id_options</code> are similar to those - of the <code>options</code> specifier (<a href="#12.4.8">Section - 12.4.8, "<code>options</code>"</a>).</p> + of the <code>options</code> specifier (<a href="#14.4.8">Section + 14.4.8, "<code>options</code>"</a>).</p> - <h3><a name="12.4.25">12.4.25 <code>index_options</code></a></h3> + <h3><a name="14.4.27">14.4.27 <code>index_options</code></a></h3> <p>The <code>index_options</code> specifier specifies additional column definition options that should be used for a container's @@ -13529,10 +14328,10 @@ class person </pre> <p>The semantics of <code>index_options</code> are similar to those - of the <code>options</code> specifier (<a href="#12.4.8">Section - 12.4.8, "<code>options</code>"</a>).</p> + of the <code>options</code> specifier (<a href="#14.4.8">Section + 14.4.8, "<code>options</code>"</a>).</p> - <h3><a name="12.4.26">12.4.26 <code>key_options</code></a></h3> + <h3><a name="14.4.28">14.4.28 <code>key_options</code></a></h3> <p>The <code>key_options</code> specifier specifies additional column definition options that should be used for a container's @@ -13550,10 +14349,10 @@ class person </pre> <p>The semantics of <code>key_options</code> are similar to those - of the <code>options</code> specifier (<a href="#12.4.8">Section - 12.4.8, "<code>options</code>"</a>).</p> + of the <code>options</code> specifier (<a href="#14.4.8">Section + 14.4.8, "<code>options</code>"</a>).</p> - <h3><a name="12.4.27">12.4.27 <code>value_options</code></a></h3> + <h3><a name="14.4.29">14.4.29 <code>value_options</code></a></h3> <p>The <code>value_options</code> specifier specifies additional column definition options that should be used for a container's @@ -13571,17 +14370,17 @@ class person </pre> <p>The semantics of <code>value_options</code> are similar to those - of the <code>options</code> specifier (<a href="#12.4.8">Section - 12.4.8, "<code>options</code>"</a>).</p> + of the <code>options</code> specifier (<a href="#14.4.8">Section + 14.4.8, "<code>options</code>"</a>).</p> - <h3><a name="12.4.28">12.4.28 <code>id_column</code></a></h3> + <h3><a name="14.4.30">14.4.30 <code>id_column</code></a></h3> <p>The <code>id_column</code> specifier specifies the column name that should be used to store the object id in a container's table for the data member. The semantics of <code>id_column</code> are similar to those of the <code>column</code> specifier - (<a href="#12.4.9">Section 12.4.9, "<code>column</code>"</a>). + (<a href="#14.4.9">Section 14.4.9, "<code>column</code>"</a>). For example:</p> <pre class="cxx"> @@ -13598,14 +14397,14 @@ class person <p>If the column name is not specified, then <code>object_id</code> is used by default.</p> - <h3><a name="12.4.29">12.4.29 <code>index_column</code></a></h3> + <h3><a name="14.4.31">14.4.31 <code>index_column</code></a></h3> <p>The <code>index_column</code> specifier specifies the column name that should be used to store the element index in an ordered container's table for the data member. The semantics of <code>index_column</code> are similar to those of the <code>column</code> specifier - (<a href="#12.4.9">Section 12.4.9, "<code>column</code>"</a>). + (<a href="#14.4.9">Section 14.4.9, "<code>column</code>"</a>). For example:</p> <pre class="cxx"> @@ -13622,14 +14421,14 @@ class person <p>If the column name is not specified, then <code>index</code> is used by default.</p> - <h3><a name="12.4.30">12.4.30 <code>key_column</code></a></h3> + <h3><a name="14.4.32">14.4.32 <code>key_column</code></a></h3> <p>The <code>key_column</code> specifier specifies the column name that should be used to store the key in a map container's table for the data member. The semantics of <code>key_column</code> are similar to those of the <code>column</code> specifier - (<a href="#12.4.9">Section 12.4.9, "<code>column</code>"</a>). + (<a href="#14.4.9">Section 14.4.9, "<code>column</code>"</a>). For example:</p> <pre class="cxx"> @@ -13646,14 +14445,14 @@ class person <p>If the column name is not specified, then <code>key</code> is used by default.</p> - <h3><a name="12.4.31">12.4.31 <code>value_column</code></a></h3> + <h3><a name="14.4.33">14.4.33 <code>value_column</code></a></h3> <p>The <code>value_column</code> specifier specifies the column name that should be used to store the element value in a container's table for the data member. The semantics of <code>value_column</code> are similar to those of the <code>column</code> specifier - (<a href="#12.4.9">Section 12.4.9, "<code>column</code>"</a>). + (<a href="#14.4.9">Section 14.4.9, "<code>column</code>"</a>). For example:</p> <pre class="cxx"> @@ -13670,7 +14469,7 @@ class person <p>If the column name is not specified, then <code>value</code> is used by default.</p> - <h2><a name="12.5">12.5 Namespace Pragmas</a></h2> + <h2><a name="14.5">14.5 Namespace Pragmas</a></h2> <p>A pragma with the <code>namespace</code> qualifier describes a C++ namespace. Similar to other qualifiers, <code>namespace</code> @@ -13707,30 +14506,30 @@ namespace test <tr> <td><code>pointer</code></td> <td>pointer type for persistent classes and views inside a namespace</td> - <td><a href="#12.5.1">12.5.1</a></td> + <td><a href="#14.5.1">14.5.1</a></td> </tr> <tr> <td><code>table</code></td> <td>table name prefix for persistent classes inside a namespace</td> - <td><a href="#12.5.2">12.5.2</a></td> + <td><a href="#14.5.2">14.5.2</a></td> </tr> <tr> <td><code>schema</code></td> <td>database schema for persistent classes inside a namespace</td> - <td><a href="#12.5.3">12.5.3</a></td> + <td><a href="#14.5.3">14.5.3</a></td> </tr> <tr> <td><code>session</code></td> <td>enable/disable session support for persistent classes inside a namespace</td> - <td><a href="#12.5.4">12.5.4</a></td> + <td><a href="#14.5.4">14.5.4</a></td> </tr> </table> - <h3><a name="12.5.1">12.5.1 <code>pointer</code></a></h3> + <h3><a name="14.5.1">14.5.1 <code>pointer</code></a></h3> <p>The <code>pointer</code> specifier specifies the default pointer type for persistent classes and views inside the namespace. For @@ -13786,7 +14585,7 @@ namespace accounting <p>For a more detailed discussion of object and view pointers, refer to <a href="#3.3">Section 3.3, "Object and View Pointers"</a>.</p> - <h3><a name="12.5.2">12.5.2 <code>table</code></a></h3> + <h3><a name="14.5.2">14.5.2 <code>table</code></a></h3> <p>The <code>table</code> specifier specifies a table prefix that should be added to table names of persistent classes inside @@ -13845,17 +14644,17 @@ class employer <code>test_audit_employers</code>.</p> <p>Table prefixes can be used as an alternative to database schemas - (<a href="#12.1.8">Section 12.1.8, "<code>schema</code>"</a>) if + (<a href="#14.1.8">Section 14.1.8, "<code>schema</code>"</a>) if the target database system does not support schemas.</p> - <h3><a name="12.5.3">12.5.3 <code>schema</code></a></h3> + <h3><a name="14.5.3">14.5.3 <code>schema</code></a></h3> <p>The <code>schema</code> specifier specifies a database schema that should be used for persistent classes inside the namespace. For more information on specifying a database schema refer to - <a href="#12.1.8">Section 12.1.8, "<code>schema</code>"</a>.</p> + <a href="#14.1.8">Section 14.1.8, "<code>schema</code>"</a>.</p> - <h3><a name="12.5.4">12.5.4 <code>session</code></a></h3> + <h3><a name="14.5.4">14.5.4 <code>session</code></a></h3> <p>The <code>session</code> specifier specifies whether to enable session support for persistent classes inside the namespace. For @@ -13882,11 +14681,11 @@ namespace hr <p>Session support is disabled by default unless the <code>--generate-session</code> ODB compiler option is specified. Session support specified at the namespace level can be overridden - on the per object basis (<a href="#12.1.10">Section 12.1.10, + on the per object basis (<a href="#14.1.10">Section 14.1.10, "<code>session</code>"</a>). For more information on sessions, - refer to <a href="#10">Chapter 10, "Session"</a>.</p> + refer to <a href="#11">Chapter 11, "Session"</a>.</p> - <h2><a name="12.6">12.6 Index Definition Pragmas</a></h2> + <h2><a name="14.6">14.6 Index Definition Pragmas</a></h2> <p>While it is possible to manually add indexes to the generated database schema, it is more convenient to do this as part of @@ -13965,9 +14764,9 @@ class object <p>ODB also offers a shortcut for defining an index with the default method and options for a single data member. Such an index can - be defined using the <code>index</code> (<a href="#12.4.16">Section - 12.4.16, "<code>index</code>"</a>) or <code>unique</code> - (<a href="#12.4.17">Section 12.4.17, "<code>unique</code>"</a>) + be defined using the <code>index</code> (<a href="#14.4.16">Section + 14.4.16, "<code>index</code>"</a>) or <code>unique</code> + (<a href="#14.4.17">Section 14.4.17, "<code>unique</code>"</a>) member specifier. For example:</p> <pre class="cxx"> @@ -14086,7 +14885,7 @@ class object }; </pre> - <h2><a name="12.7">12.7 Database Type Mapping Pragmas</a></h2> + <h2><a name="14.7">14.7 Database Type Mapping Pragmas</a></h2> <p>A pragma with the <code>map</code> qualifier describes a mapping between two database types. For each database system @@ -14287,7 +15086,7 @@ class object for each database, shows how to provide custom mapping for some of the extended types.</p> - <h2><a name="12.8">12.8 C++ Compiler Warnings</a></h2> + <h2><a name="14.8">14.8 C++ Compiler Warnings</a></h2> <p>When a C++ header file defining persistent classes and containing ODB pragmas is used to build the application, the C++ compiler may @@ -14340,7 +15139,7 @@ class person <p>The disadvantage of this approach is that it can quickly become overly verbose when positioned pragmas are used.</p> - <h3><a name="12.8.1">12.8.1 GNU C++</a></h3> + <h3><a name="14.8.1">14.8.1 GNU C++</a></h3> <p>GNU g++ does not issue warnings about unknown pragmas unless requested with the <code>-Wall</code> command line option. @@ -14352,7 +15151,7 @@ class person g++ -Wall -Wno-unknown-pragmas ... </pre> - <h3><a name="12.8.2">12.8.2 Visual C++</a></h3> + <h3><a name="14.8.2">14.8.2 Visual C++</a></h3> <p>Microsoft Visual C++ issues an unknown pragma warning (C4068) at warning level 1 or higher. This means that unless we have disabled @@ -14386,7 +15185,7 @@ class person #pragma warning (pop) </pre> - <h3><a name="12.8.3">12.8.3 Sun C++</a></h3> + <h3><a name="14.8.3">14.8.3 Sun C++</a></h3> <p>The Sun C++ compiler does not issue warnings about unknown pragmas unless the <code>+w</code> or <code>+w2</code> option is specified. @@ -14398,7 +15197,7 @@ class person CC +w -erroff=unknownpragma ... </pre> - <h3><a name="12.8.4">12.8.4 IBM XL C++</a></h3> + <h3><a name="14.8.4">14.8.4 IBM XL C++</a></h3> <p>IBM XL C++ issues an unknown pragma warning (1540-1401) by default. To disable this warning we can add the <code>-qsuppress=1540-1401</code> @@ -14408,7 +15207,7 @@ CC +w -erroff=unknownpragma ... xlC -qsuppress=1540-1401 ... </pre> - <h3><a name="12.8.5">12.8.5 HP aC++</a></h3> + <h3><a name="14.8.5">14.8.5 HP aC++</a></h3> <p>HP aC++ (aCC) issues an unknown pragma warning (2161) by default. To disable this warning we can add the <code>+W2161</code> @@ -14418,7 +15217,7 @@ xlC -qsuppress=1540-1401 ... aCC +W2161 ... </pre> - <h3><a name="12.8.6">12.8.6 Clang</a></h3> + <h3><a name="14.8.6">14.8.6 Clang</a></h3> <p>Clang does not issue warnings about unknown pragmas unless requested with the <code>-Wall</code> command line option. @@ -14457,12 +15256,12 @@ class person <hr class="page-break"/> - <h1><a name="13">13 Advanced Techniques and Mechanisms</a></h1> + <h1><a name="15">15 Advanced Techniques and Mechanisms</a></h1> <p>This chapter covers more advanced techniques and mechanisms provided by ODB that may be useful in certain situations.</p> - <h2><a name="13.1">13.1 Transaction Callbacks</a></h2> + <h2><a name="15.1">15.1 Transaction Callbacks</a></h2> <p>The ODB transaction class (<code>odb::transaction</code>) allows an application to register a callback that will be called after @@ -14559,7 +15358,7 @@ namespace odb <p>The following example shows how we can use transaction callbacks together with database operation callbacks - (<a href="#12.1.7">Section 12.1.7, "<code>callback</code>"</a>) + (<a href="#14.1.7">Section 14.1.7, "<code>callback</code>"</a>) to manage the object's "dirty" flag.</p> <pre class="cxx"> @@ -14639,12 +15438,12 @@ class object II consists of the following chapters.</p> <table class="toc"> - <tr><th>14</th><td><a href="#14">Multi-Database Support</a></td></tr> - <tr><th>15</th><td><a href="#15">MySQL Database</a></td></tr> - <tr><th>16</th><td><a href="#16">SQLite Database</a></td></tr> - <tr><th>17</th><td><a href="#17">PostgreSQL Database</a></td></tr> - <tr><th>18</th><td><a href="#18">Oracle Database</a></td></tr> - <tr><th>19</th><td><a href="#19">Microsoft SQL Server Database</a></td></tr> + <tr><th>16</th><td><a href="#16">Multi-Database Support</a></td></tr> + <tr><th>17</th><td><a href="#17">MySQL Database</a></td></tr> + <tr><th>18</th><td><a href="#18">SQLite Database</a></td></tr> + <tr><th>19</th><td><a href="#19">PostgreSQL Database</a></td></tr> + <tr><th>20</th><td><a href="#20">Oracle Database</a></td></tr> + <tr><th>21</th><td><a href="#21">Microsoft SQL Server Database</a></td></tr> </table> @@ -14652,7 +15451,7 @@ class object <hr class="page-break"/> - <h1><a name="14">14 Multi-Database Support</a></h1> + <h1><a name="16">16 Multi-Database Support</a></h1> <p>Some applications may need to access multiple database systems, either simultaneously or one at a time. For example, an application may @@ -14713,7 +15512,7 @@ class object separate libraries and loaded dynamically by the application. The disadvantages of dynamic support are slight overhead and certain limitations in functionality compared to static support (see - <a href="#14.2">Section 14.2, "Dynamic Multi-Database Support"</a> + <a href="#16.2">Section 16.2, "Dynamic Multi-Database Support"</a> for details). As a result, dynamic multi-database support is most suitable to situations where we need the same code to work with a range of database systems. For example, if your @@ -14843,7 +15642,7 @@ odb --odb-file-suffix common:-odb-common ... support in more detail.</p> - <h2><a name="14.1">14.1 Static Multi-Database Support</a></h2> + <h2><a name="16.1">16.1 Static Multi-Database Support</a></h2> <p>With static multi-database support, instead of including <code>person-odb.hxx</code>, application source code has @@ -15015,7 +15814,7 @@ odb -m static -d common -d pgsql -d sqlite --default-database pgsql ... support is enabled, then the common (dynamic) interface is always made the default database.</p> - <h2><a name="14.2">14.2 Dynamic Multi-Database Support</a></h2> + <h2><a name="16.2">16.2 Dynamic Multi-Database Support</a></h2> <p>With dynamic multi-database support, application source code only needs to include the <code>person-odb.hxx</code> header file, just @@ -15186,7 +15985,7 @@ namespace odb expression). Every <code>odb::<db>::query</code> class provides such a translation constructor.</p> - <h3><a name="14.2.2">14.2.2 Dynamic Loading of Database Support Code</a></h3> + <h3><a name="16.2.2">16.2.2 Dynamic Loading of Database Support Code</a></h3> <p>With dynamic multi-database support, the generated database support code automatically registers itself with the function tables that @@ -15364,7 +16163,7 @@ person.hxx <hr class="page-break"/> - <h1><a name="15">15 MySQL Database</a></h1> + <h1><a name="17">17 MySQL Database</a></h1> <p>To generate support code for the MySQL database you will need to pass the "<code>--database mysql</code>" @@ -15373,12 +16172,12 @@ person.hxx library (<code>libodb-mysql</code>). All MySQL-specific ODB classes are defined in the <code>odb::mysql</code> namespace.</p> - <h2><a name="15.1">15.1 MySQL Type Mapping</a></h2> + <h2><a name="17.1">17.1 MySQL Type Mapping</a></h2> <p>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 - Pragma Language (<a href="#12">Chapter 12, "ODB Pragma + Pragma Language (<a href="#14">Chapter 14, "ODB Pragma Language"</a>).</p> <!-- border="1" is necessary for html2ps --> @@ -15488,7 +16287,7 @@ person.hxx <p>It is possible to map the <code>char</code> C++ type to an integer database type (for example, <code>TINYINT</code>) using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>).</p> <p>Note that the <code>std::string</code> type is mapped @@ -15527,10 +16326,10 @@ class object <p>It is also possible to add support for additional MySQL types, such as geospatial types. For more information, refer to - <a href="#12.7">Section 12.7, "Database Type Mapping + <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h3><a name="15.1.1">15.1.1 String Type Mapping</a></h3> + <h3><a name="17.1.1">17.1.1 String Type Mapping</a></h3> <p>The MySQL ODB runtime library provides support for mapping the <code>std::string</code>, <code>char[N]</code>, and @@ -15540,8 +16339,8 @@ class object by default (in particular, by default, <code>std::array</code> will be treated as a container). To enable the alternative mappings for these types we need to specify the database type explicitly using - the <code>db type</code> pragma (<a href="#12.4.3">Section - 12.4.3, "<code>type</code>"</a>), for example:</p> + the <code>db type</code> pragma (<a href="#14.4.3">Section + 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> #pragma db object @@ -15576,7 +16375,7 @@ class object database, ODB will append the zero terminator if there is enough space.</p> - <h3><a name="15.1.2">15.1.2 Binary Type Mapping</a></h3> + <h3><a name="17.1.2">17.1.2 Binary Type Mapping</a></h3> <p>The MySQL ODB runtime library provides support for mapping the <code>std::vector<char></code>, @@ -15590,7 +16389,7 @@ class object <code>std::array</code> will be treated as containers). To enable the alternative mappings for these types we need to specify the database type explicitly using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), for + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> @@ -15637,7 +16436,7 @@ db.query<object> ("uuid = " + query::_val<odb::mysql::id_blob> (u)); db.query<object> (query::uuid == query::_ref (u)); </pre> - <h2><a name="15.2">15.2 MySQL Database Class</a></h2> + <h2><a name="17.2">17.2 MySQL Database Class</a></h2> <p>The MySQL <code>database</code> class has the following interface:</p> @@ -15797,7 +16596,7 @@ namespace odb <p>This constructor throws the <code>odb::mysql::cli_exception</code> exception if the MySQL option values are missing or invalid. - See section <a href="#15.4">Section 15.4, "MySQL Exceptions"</a> + See section <a href="#17.4">Section 17.4, "MySQL Exceptions"</a> for more information on this exception.</p> <p>The static <code>print_usage()</code> function prints the list of options @@ -15816,10 +16615,10 @@ namespace odb <p>The <code>connection()</code> function returns a pointer to the MySQL database connection encapsulated by the <code>odb::mysql::connection</code> class. For more information - on <code>mysql::connection</code>, refer to <a href="#15.3">Section - 15.3, "MySQL Connection and Connection Factory"</a>.</p> + on <code>mysql::connection</code>, refer to <a href="#17.3">Section + 17.3, "MySQL Connection and Connection Factory"</a>.</p> - <h2><a name="15.3">15.3 MySQL Connection and Connection Factory</a></h2> + <h2><a name="17.3">17.3 MySQL Connection and Connection Factory</a></h2> <p>The <code>mysql::connection</code> class has the following interface:</p> @@ -16011,7 +16810,7 @@ main (int argc, char* argv[]) } </pre> - <h2><a name="15.4">15.4 MySQL Exceptions</a></h2> + <h2><a name="17.4">17.4 MySQL Exceptions</a></h2> <p>The MySQL ODB runtime library defines the following MySQL-specific exceptions:</p> @@ -16063,12 +16862,12 @@ namespace odb <code>what()</code> function returns a human-readable description of an error.</p> - <h2><a name="15.5">15.5 MySQL Limitations</a></h2> + <h2><a name="17.5">17.5 MySQL Limitations</a></h2> <p>The following sections describe MySQL-specific limitations imposed by the current MySQL and ODB runtime versions.</p> - <h3><a name="15.5.1">15.5.1 Foreign Key Constraints</a></h3> + <h3><a name="17.5.1">17.5.1 Foreign Key Constraints</a></h3> <p>ODB relies on standard SQL behavior which requires that foreign key constraints checking is deferred until the transaction is @@ -16086,9 +16885,9 @@ namespace odb which you persist, update, and erase objects within a transaction becomes important.</p> - <h2><a name="15.6">15.6 MySQL Index Definitions</a></h2> + <h2><a name="17.6">17.6 MySQL Index Definitions</a></h2> - <p>When the <code>index</code> pragma (<a href="#12.6">Section 12.6, + <p>When the <code>index</code> pragma (<a href="#14.6">Section 14.6, "Index Definition Pragmas"</a>) is used to define a MySQL index, the <code>type</code> clause specifies the index type (for example, <code>UNIQUE</code>, <code>FULLTEXT</code>, <code>SPATIAL</code>), @@ -16115,7 +16914,7 @@ class object <hr class="page-break"/> - <h1><a name="16">16 SQLite Database</a></h1> + <h1><a name="18">18 SQLite Database</a></h1> <p>To generate support code for the SQLite database you will need to pass the "<code>--database sqlite</code>" @@ -16124,12 +16923,12 @@ class object library (<code>libodb-sqlite</code>). All SQLite-specific ODB classes are defined in the <code>odb::sqlite</code> namespace.</p> - <h2><a name="16.1">16.1 SQLite Type Mapping</a></h2> + <h2><a name="18.1">18.1 SQLite Type Mapping</a></h2> <p>The following table summarizes the default mapping between basic C++ value types and SQLite database types. This mapping can be customized on the per-type and per-member basis using the ODB - Pragma Language (<a href="#12">Chapter 12, "ODB Pragma + Pragma Language (<a href="#14">Chapter 14, "ODB Pragma Language"</a>).</p> <!-- border="1" is necessary for html2ps --> @@ -16251,15 +17050,15 @@ class object <p>It is possible to map the <code>char</code> C++ type to the <code>INTEGER</code> SQLite type using the <code>db type</code> - pragma (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>).</p> + pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>).</p> <p>SQLite represents the <code>NaN</code> <code>FLOAT</code> value as a <code>NULL</code> value. As a result, columns of the <code>float</code> and <code>double</code> types are by default declared as <code>NULL</code>. However, you can override this by explicitly declaring them as <code>NOT NULL</code> with the - <code>db not_null</code> pragma (<a href="#12.4.6">Section - 12.4.6, "<code>null/not_null</code>"</a>).</p> + <code>db not_null</code> pragma (<a href="#14.4.6">Section + 14.4.6, "<code>null/not_null</code>"</a>).</p> <p>Additionally, by default, C++ enumerations are automatically mapped to the SQLite <code>INTEGER</code> type with the default <code>NULL</code> @@ -16273,10 +17072,10 @@ class object <p>It is also possible to add support for additional SQLite types, such as <code>NUMERIC</code>. For more information, refer to - <a href="#12.7">Section 12.7, "Database Type Mapping + <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h3><a name="16.1.1">16.1.1 String Type Mapping</a></h3> + <h3><a name="18.1.1">18.1.1 String Type Mapping</a></h3> <p>The SQLite ODB runtime library provides support for mapping the <code>std::array<char, N></code> and, on Windows, @@ -16285,8 +17084,8 @@ class object default (in particular, by default, <code>std::array</code> will be treated as a container). To enable the alternative mapping for this type we need to specify the database type explicitly using - the <code>db type</code> pragma (<a href="#12.4.3">Section - 12.4.3, "<code>type</code>"</a>), for example:</p> + the <code>db type</code> pragma (<a href="#14.4.3">Section + 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> #pragma db object @@ -16320,7 +17119,7 @@ class object from the database, ODB will append the zero terminator if there is enough space.</p> - <h3><a name="16.1.2">16.1.2 Binary Type Mapping</a></h3> + <h3><a name="18.1.2">18.1.2 Binary Type Mapping</a></h3> <p>The SQLite ODB runtime library provides support for mapping the <code>std::vector<char></code>, @@ -16333,7 +17132,7 @@ class object <code>std::vector</code> and <code>std::array</code> will be treated as containers). To enable the alternative mappings for these types we need to specify the database type explicitly using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> @@ -16380,7 +17179,7 @@ db.query<object> ("uuid = " + query::_val<odb::sqlite::id_blob> (u)); db.query<object> (query::uuid == query::_ref (u)); </pre> - <h2><a name="16.2">16.2 SQLite Database Class</a></h2> + <h2><a name="18.2">18.2 SQLite Database Class</a></h2> <p>The SQLite <code>database</code> class has the following interface:</p> @@ -16453,7 +17252,7 @@ namespace odb values, refer to the <code>sqlite3_open_v2()</code> function description in the SQLite C API documentation. The <code>foreign_keys</code> argument specifies whether foreign key constraints checking - should be enabled. See <a href="#16.5.3">Section 16.5.3, + should be enabled. See <a href="#18.5.3">Section 18.5.3, "Foreign Key Constraints"</a> for more information on foreign keys. The <code>vfs</code> argument specifies the SQLite virtual file system module that should be used to access the @@ -16509,7 +17308,7 @@ auto_ptr<odb::database> db ( <p>The third constructor throws the <code>odb::sqlite::cli_exception</code> exception if the SQLite option values are missing or invalid. - See <a href="#16.4">Section 16.4, "SQLite Exceptions"</a> + See <a href="#18.4">Section 18.4, "SQLite Exceptions"</a> for more information on this exception.</p> <p>The static <code>print_usage()</code> function prints the list of options @@ -16538,10 +17337,10 @@ auto_ptr<odb::database> db ( <p>The <code>connection()</code> function returns a pointer to the SQLite database connection encapsulated by the <code>odb::sqlite::connection</code> class. For more information - on <code>sqlite::connection</code>, refer to <a href="#16.3">Section - 16.3, "SQLite Connection and Connection Factory"</a>.</p> + on <code>sqlite::connection</code>, refer to <a href="#18.3">Section + 18.3, "SQLite Connection and Connection Factory"</a>.</p> - <h2><a name="16.3">16.3 SQLite Connection and Connection Factory</a></h2> + <h2><a name="18.3">18.3 SQLite Connection and Connection Factory</a></h2> <p>The <code>sqlite::connection</code> class has the following interface:</p> @@ -16586,7 +17385,7 @@ namespace odb functions allow us to start an immediate and an exclusive SQLite transaction on the connection, respectively. Their semantics are equivalent to the corresponding functions defined in the - <code>sqlite::database</code> class (<a href="#16.2">Section 16.2, + <code>sqlite::database</code> class (<a href="#18.2">Section 18.2, "SQLite Database Class"</a>). The <code>handle()</code> accessor returns the SQLite handle corresponding to the connection.</p> @@ -16786,7 +17585,7 @@ main (int argc, char* argv[]) } </pre> - <h2><a name="16.4">16.4 SQLite Exceptions</a></h2> + <h2><a name="18.4">18.4 SQLite Exceptions</a></h2> <p>The SQLite ODB runtime library defines the following SQLite-specific exceptions:</p> @@ -16834,7 +17633,7 @@ namespace odb <p>The <code>odb::sqlite::forced_rollback</code> exception is thrown if SQLite is forcing the current transaction to roll back. For more - information on this behavior refer to <a href="#16.5.6">Section 16.5.6, + information on this behavior refer to <a href="#18.5.6">Section 18.5.6, "Forced Rollback"</a>.</p> <p>The <code>odb::sqlite::database_exception</code> is thrown if @@ -16851,12 +17650,12 @@ namespace odb of an error.</p> - <h2><a name="16.5">16.5 SQLite Limitations</a></h2> + <h2><a name="18.5">18.5 SQLite Limitations</a></h2> <p>The following sections describe SQLite-specific limitations imposed by the current SQLite and ODB runtime versions.</p> - <h3><a name="16.5.1">16.5.1 Query Result Caching</a></h3> + <h3><a name="18.5.1">18.5.1 Query Result Caching</a></h3> <p>SQLite ODB runtime implementation does not perform query result caching (<a href="#4.4">Section 4.4, "Query Result"</a>) even when explicitly @@ -16871,17 +17670,17 @@ namespace odb thrown. Future versions of the SQLite ODB runtime library may add support for result caching.</p> - <h3><a name="16.5.2">16.5.2 Automatic Assignment of Object Ids</a></h3> + <h3><a name="18.5.2">18.5.2 Automatic Assignment of Object Ids</a></h3> <p>Due to SQLite API limitations, every automatically assigned object id - (<a href="#12.4.2">Section 12.4.2, "<code>auto</code>"</a>) should have + (<a href="#14.4.2">Section 14.4.2, "<code>auto</code>"</a>) should have the <code>INTEGER</code> SQLite type. While SQLite will treat other integer type names (such as <code>INT</code>, <code>BIGINT</code>, etc.) as <code>INTEGER</code>, automatic id assignment will not work. By default, ODB maps all C++ integral types to <code>INTEGER</code>. This means that the only situation that requires consideration is the assignment of a custom database type using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>). For + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>). For example:</p> <pre class="cxx"> @@ -16897,7 +17696,7 @@ class person }; </pre> - <h3><a name="16.5.3">16.5.3 Foreign Key Constraints</a></h3> + <h3><a name="18.5.3">18.5.3 Foreign Key Constraints</a></h3> <p>By default the SQLite ODB runtime enables foreign key constraints checking (<code>PRAGMA foreign_keys=ON</code>). You can disable foreign @@ -16967,7 +17766,7 @@ CREATE TABLE Employee ( which you persist, update, and erase objects within a transaction becomes important.</p> - <h3><a name="16.5.4">16.5.4 Constraint Violations</a></h3> + <h3><a name="18.5.4">18.5.4 Constraint Violations</a></h3> <p>Due to the granularity of the SQLite error codes, it is impossible to distinguish between the duplicate primary key and other constraint @@ -16976,7 +17775,7 @@ CREATE TABLE Employee ( <code>object_already_persistent</code> exception (<a href="#3.14">Section 3.14, "ODB Exceptions"</a>).</p> - <h3><a name="16.5.5">16.5.5 Sharing of Queries</a></h3> + <h3><a name="18.5.5">18.5.5 Sharing of Queries</a></h3> <p>As discussed in <a href="#4.3">Section 4.3, "Executing a Query"</a>, a query instance that does not have any by-reference parameters is @@ -16985,7 +17784,7 @@ CREATE TABLE Employee ( functionality. Future versions of the library will remove this limitation.</p> - <h3><a name="16.5.6">16.5.6 Forced Rollback</a></h3> + <h3><a name="18.5.6">18.5.6 Forced Rollback</a></h3> <p>In SQLite 3.7.11 or later, if one of the connections participating in the shared cache rolls back a transaction, then ongoing transactions @@ -16996,14 +17795,14 @@ CREATE TABLE Employee ( <p>If a transaction is being forced to roll back by SQLite, then ODB throws <code>odb::sqlite::forced_rollback</code> - (<a href="#16.4">Section 16.4, "SQLite Exceptions"</a>) which is + (<a href="#18.4">Section 18.4, "SQLite Exceptions"</a>) which is a recoverable exception (<a href="#3.7">3.7 Error Handling and Recovery</a>). As a result, the recommended way to handle this exception is to re-execute the affected transaction.</p> - <h2><a name="16.6">16.6 SQLite Index Definitions</a></h2> + <h2><a name="18.6">18.6 SQLite Index Definitions</a></h2> - <p>When the <code>index</code> pragma (<a href="#12.6">Section 12.6, + <p>When the <code>index</code> pragma (<a href="#14.6">Section 14.6, "Index Definition Pragmas"</a>) is used to define an SQLite index, the <code>type</code> clause specifies the index type (for example, <code>UNIQUE</code>) while the <code>method</code> and @@ -17030,7 +17829,7 @@ class object <hr class="page-break"/> - <h1><a name="17">17 PostgreSQL Database</a></h1> + <h1><a name="19">19 PostgreSQL Database</a></h1> <p>To generate support code for the PostgreSQL database you will need to pass the "<code>--database pgsql</code>" @@ -17044,12 +17843,12 @@ class object of the messaging protocol version 3.0. For this reason, ODB supports only PostgreSQL version 7.4 and later.</p> - <h2><a name="17.1">17.1 PostgreSQL Type Mapping</a></h2> + <h2><a name="19.1">19.1 PostgreSQL Type Mapping</a></h2> <p>The following table summarizes the default mapping between basic C++ value types and PostgreSQL database types. This mapping can be customized on the per-type and per-member basis using the ODB - Pragma Language (<a href="#12">Chapter 12, "ODB Pragma + Pragma Language (<a href="#14">Chapter 14, "ODB Pragma Language"</a>).</p> <!-- border="1" is necessary for html2ps --> @@ -17159,7 +17958,7 @@ class object <p>It is possible to map the <code>char</code> C++ type to an integer database type (for example, <code>SMALLINT</code>) using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>).</p> <p>Additionally, by default, C++ enumerations are automatically @@ -17179,10 +17978,10 @@ class object such as <code>NUMERIC</code>, geometry types, <code>XML</code>, <code>JSON</code>, enumeration types, composite types, arrays, geospatial types, and the key-value store (<code>HSTORE</code>). - For more information, refer to <a href="#12.7">Section 12.7, + For more information, refer to <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h3><a name="17.1.1">17.1.1 String Type Mapping</a></h3> + <h3><a name="19.1.1">19.1.1 String Type Mapping</a></h3> <p>The PostgreSQL ODB runtime library provides support for mapping the <code>std::string</code>, <code>char[N]</code>, and @@ -17192,7 +17991,7 @@ class object particular, by default, <code>std::array</code> will be treated as a container). To enable the alternative mappings for these types we need to specify the database type explicitly using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> @@ -17228,7 +18027,7 @@ class object database, ODB will append the zero terminator if there is enough space.</p> - <h3><a name="17.1.2">17.1.2 Binary Type and <code>UUID</code> Mapping</a></h3> + <h3><a name="19.1.2">19.1.2 Binary Type and <code>UUID</code> Mapping</a></h3> <p>The PostgreSQL ODB runtime library provides support for mapping the <code>std::vector<char></code>, @@ -17242,7 +18041,7 @@ class object default, <code>std::vector</code> and <code>std::array</code> will be treated as containers). To enable the alternative mappings for these types we need to specify the database type explicitly using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> @@ -17293,7 +18092,7 @@ db.query<object> ("buf = " + query::_val<odb::pgsql::id_bytea> (u)); db.query<object> (query::uuid == query::_ref (u)); </pre> - <h2><a name="17.2">17.2 PostgreSQL Database Class</a></h2> + <h2><a name="19.2">19.2 PostgreSQL Database Class</a></h2> <p>The PostgreSQL <code>database</code> class has the following interface:</p> @@ -17413,7 +18212,7 @@ namespace odb <p>This constructor throws the <code>odb::pgsql::cli_exception</code> exception if the PostgreSQL option values are missing or invalid. - See section <a href="#17.4">Section 17.4, "PostgreSQL Exceptions"</a> + See section <a href="#19.4">Section 19.4, "PostgreSQL Exceptions"</a> for more information on this exception.</p> <p>The static <code>print_usage()</code> function prints the list of options @@ -17439,10 +18238,10 @@ namespace odb <p>The <code>connection()</code> function returns a pointer to the PostgreSQL database connection encapsulated by the <code>odb::pgsql::connection</code> class. For more information - on <code>pgsql::connection</code>, refer to <a href="#17.3">Section - 17.3, "PostgreSQL Connection and Connection Factory"</a>.</p> + on <code>pgsql::connection</code>, refer to <a href="#19.3">Section + 19.3, "PostgreSQL Connection and Connection Factory"</a>.</p> - <h2><a name="17.3">17.3 PostgreSQL Connection and Connection Factory</a></h2> + <h2><a name="19.3">19.3 PostgreSQL Connection and Connection Factory</a></h2> <p>The <code>pgsql::connection</code> class has the following interface:</p> @@ -17623,7 +18422,7 @@ main (int argc, char* argv[]) } </pre> - <h2><a name="17.4">17.4 PostgreSQL Exceptions</a></h2> + <h2><a name="19.4">19.4 PostgreSQL Exceptions</a></h2> <p>The PostgreSQL ODB runtime library defines the following PostgreSQL-specific exceptions:</p> @@ -17672,12 +18471,12 @@ namespace odb <code>what()</code> function returns a human-readable description of an error.</p> - <h2><a name="17.5">17.5 PostgreSQL Limitations</a></h2> + <h2><a name="19.5">19.5 PostgreSQL Limitations</a></h2> <p>The following sections describe PostgreSQL-specific limitations imposed by the current PostgreSQL and ODB runtime versions.</p> - <h3><a name="17.5.1">17.5.1 Query Result Caching</a></h3> + <h3><a name="19.5.1">19.5.1 Query Result Caching</a></h3> <p>The PostgreSQL ODB runtime implementation will always return a cached query result (<a href="#4.4">Section 4.4, "Query Result"</a>) @@ -17685,7 +18484,7 @@ namespace odb PostgreSQL client library (<code>libpq</code>) which does not support uncached (streaming) query results.</p> - <h3><a name="17.5.2">17.5.2 Foreign Key Constraints</a></h3> + <h3><a name="19.5.2">19.5.2 Foreign Key Constraints</a></h3> <p>ODB assumes the standard SQL behavior which requires that foreign key constraints checking is deferred until the @@ -17710,7 +18509,7 @@ CREATE TABLE Employee ( which you persist, update, and erase objects within a transaction becomes important.</p> - <h3><a name="17.5.3">17.5.3 Unique Constraint Violations</a></h3> + <h3><a name="19.5.3">19.5.3 Unique Constraint Violations</a></h3> <p>Due to the granularity of the PostgreSQL error codes, it is impossible to distinguish between the duplicate primary key and other unique @@ -17719,7 +18518,7 @@ CREATE TABLE Employee ( errors to the <code>object_already_persistent</code> exception (<a href="#3.14">Section 3.14, "ODB Exceptions"</a>).</p> - <h3><a name="17.5.4">17.5.4 Date-Time Format</a></h3> + <h3><a name="19.5.4">19.5.4 Date-Time Format</a></h3> <p>ODB expects the PostgreSQL server to use integers as a binary format for the date-time types, which is the default for most @@ -17734,14 +18533,14 @@ CREATE TABLE Employee ( SHOW integer_datetimes </pre> - <h3><a name="17.5.5">17.5.5 Timezones</a></h3> + <h3><a name="19.5.5">19.5.5 Timezones</a></h3> <p>ODB does not currently natively support the PostgreSQL date-time types with timezone information. However, these types can be accessed by mapping them to one of the natively supported types, as discussed - in <a href="#12.7">Section 12.7, "Database Type Mapping Pragmas"</a>.</p> + in <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h3><a name="17.5.6">17.5.6 <code>NUMERIC</code> Type Support</a></h3> + <h3><a name="19.5.6">19.5.6 <code>NUMERIC</code> Type Support</a></h3> <p>Support for the PostgreSQL <code>NUMERIC</code> type is limited to providing a binary buffer containing the binary representation @@ -17749,13 +18548,13 @@ SHOW integer_datetimes store <code>NUMERIC</code> values refer to the PostgreSQL documentation. An alternative approach to accessing <code>NUMERIC</code> values is to map this type to one of the natively supported - ones, as discussed in <a href="#12.7">Section 12.7, "Database + ones, as discussed in <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h2><a name="17.6">17.6 PostgreSQL Index Definitions</a></h2> + <h2><a name="19.6">19.6 PostgreSQL Index Definitions</a></h2> - <p>When the <code>index</code> pragma (<a href="#12.6">Section 12.6, + <p>When the <code>index</code> pragma (<a href="#14.6">Section 14.6, "Index Definition Pragmas"</a>) is used to define a PostgreSQL index, the <code>type</code> clause specifies the index type (for example, <code>UNIQUE</code>), the <code>method</code> clause specifies the @@ -17792,7 +18591,7 @@ class object <hr class="page-break"/> - <h1><a name="18">18 Oracle Database</a></h1> + <h1><a name="20">20 Oracle Database</a></h1> <p>To generate support code for the Oracle database you will need to pass the "<code>--database oracle</code>" @@ -17801,12 +18600,12 @@ class object library (<code>libodb-oracle</code>). All Oracle-specific ODB classes are defined in the <code>odb::oracle</code> namespace.</p> - <h2><a name="18.1">18.1 Oracle Type Mapping</a></h2> + <h2><a name="20.1">20.1 Oracle Type Mapping</a></h2> <p>The following table summarizes the default mapping between basic C++ value types and Oracle database types. This mapping can be customized on the per-type and per-member basis using the ODB - Pragma Language (<a href="#12">Chapter 12, "ODB Pragma + Pragma Language (<a href="#14">Chapter 14, "ODB Pragma Language"</a>).</p> <!-- border="1" is necessary for html2ps --> @@ -17916,7 +18715,7 @@ class object <p>It is possible to map the <code>char</code> C++ type to an integer database type (for example, <code>NUMBER(3)</code>) using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>).</p> <p>In Oracle empty <code>VARCHAR2</code> and <code>NVARCHAR2</code> @@ -17925,8 +18724,8 @@ class object types are by default declared as <code>NULL</code> except for primary key columns. However, you can override this by explicitly declaring such columns as <code>NOT NULL</code> with the - <code>db not_null</code> pragma (<a href="#12.4.6">Section - 12.4.6, "<code>null/not_null</code>"</a>). This also means that for + <code>db not_null</code> pragma (<a href="#14.4.6">Section + 14.4.6, "<code>null/not_null</code>"</a>). This also means that for object ids that are mapped to these Oracle types, an empty string is an invalid value.</p> @@ -17937,10 +18736,10 @@ class object <p>It is also possible to add support for additional Oracle types, such as <code>XML</code>, geospatial types, user-defined types, and collections (arrays, table types). For more information, refer to - <a href="#12.7">Section 12.7, "Database Type Mapping + <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h3><a name="18.1.1">18.1.1 String Type Mapping</a></h3> + <h3><a name="20.1.1">20.1.1 String Type Mapping</a></h3> <p>The Oracle ODB runtime library provides support for mapping the <code>std::string</code>, <code>char[N]</code>, and @@ -17951,7 +18750,7 @@ class object default, <code>std::array</code> will be treated as a container). To enable the alternative mappings for these types we need to specify the database type explicitly using the <code>db type</code> - pragma (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), + pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> @@ -17993,7 +18792,7 @@ class object database, ODB will append the zero terminator if there is enough space.</p> - <h3><a name="18.1.2">18.1.2 Binary Type Mapping</a></h3> + <h3><a name="20.1.2">20.1.2 Binary Type Mapping</a></h3> <p>The Oracle ODB runtime library provides support for mapping the <code>std::vector<char></code>, @@ -18006,7 +18805,7 @@ class object default, <code>std::vector</code> and <code>std::array</code> will be treated as containers). To enable the alternative mappings for these types we need to specify the database type explicitly using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> @@ -18053,7 +18852,7 @@ db.query<object> ("uuid = " + query::_val<odb::oracle::id_raw> (u)); db.query<object> (query::uuid == query::_ref (u)); </pre> - <h2><a name="18.2">18.2 Oracle Database Class</a></h2> + <h2><a name="20.2">20.2 Oracle Database Class</a></h2> <p>The Oracle <code>database</code> class encapsulates the OCI environment handle as well as the database connection string and user credentials @@ -18178,7 +18977,7 @@ namespace odb <p>This constructor throws the <code>odb::oracle::cli_exception</code> exception if the Oracle option values are missing or invalid. See section - <a href="#18.4">Section 18.4, "Oracle Exceptions"</a> for more + <a href="#20.4">Section 20.4, "Oracle Exceptions"</a> for more information on this exception.</p> <p>The static <code>print_usage()</code> function prints the list of options @@ -18228,10 +19027,10 @@ namespace odb <p>The <code>connection()</code> function returns a pointer to the Oracle database connection encapsulated by the <code>odb::oracle::connection</code> class. For more information - on <code>oracle::connection</code>, refer to <a href="#18.3">Section - 18.3, "Oracle Connection and Connection Factory"</a>.</p> + on <code>oracle::connection</code>, refer to <a href="#20.3">Section + 20.3, "Oracle Connection and Connection Factory"</a>.</p> - <h2><a name="18.3">18.3 Oracle Connection and Connection Factory</a></h2> + <h2><a name="20.3">20.3 Oracle Connection and Connection Factory</a></h2> <p>The <code>oracle::connection</code> class has the following interface:</p> @@ -18433,7 +19232,7 @@ main (int argc, char* argv[]) } </pre> - <h2><a name="18.4">18.4 Oracle Exceptions</a></h2> + <h2><a name="20.4">20.4 Oracle Exceptions</a></h2> <p>The Oracle ODB runtime library defines the following Oracle-specific exceptions:</p> @@ -18514,12 +19313,12 @@ namespace odb condition. The <code>what()</code> function returns a human-readable description of an error.</p> - <h2><a name="18.5">18.5 Oracle Limitations</a></h2> + <h2><a name="20.5">20.5 Oracle Limitations</a></h2> <p>The following sections describe Oracle-specific limitations imposed by the current Oracle and ODB runtime versions.</p> - <h3><a name="18.5.1">18.5.1 Identifier Truncation</a></h3> + <h3><a name="20.5.1">20.5.1 Identifier Truncation</a></h3> <p>Oracle limits the length of database identifiers (table, column, etc., names) to 30 characters. The ODB compiler automatically truncates @@ -18529,7 +19328,7 @@ namespace odb that a database object with the same name already exists. To resolve this problem we can assign custom, shorter identifiers using the <code>db table</code> and <code>db column</code> - pragmas (<a href="#12">Chapter 12, "ODB Pragma Language")</a>. For + pragmas (<a href="#14">Chapter 14, "ODB Pragma Language")</a>. For example:</p> <pre class="cxx"> @@ -18564,7 +19363,7 @@ class long_class_name }; </pre> - <h3><a name="18.5.2">18.5.2 Query Result Caching</a></h3> + <h3><a name="20.5.2">20.5.2 Query Result Caching</a></h3> <p>Oracle ODB runtime implementation does not perform query result caching (<a href="#4.4">Section 4.4, "Query Result"</a>) even when explicitly @@ -18579,7 +19378,7 @@ class long_class_name always thrown. Future versions of the Oracle ODB runtime library may add support for result caching.</p> - <h3><a name="18.5.3">18.5.3 Foreign Key Constraints</a></h3> + <h3><a name="20.5.3">20.5.3 Foreign Key Constraints</a></h3> <p>ODB assumes the standard SQL behavior which requires that foreign key constraints checking is deferred until the @@ -18605,7 +19404,7 @@ CREATE TABLE Employee ( which you persist, update, and erase objects within a transaction becomes important.</p> - <h3><a name="18.5.4">18.5.4 Unique Constraint Violations</a></h3> + <h3><a name="20.5.4">20.5.4 Unique Constraint Violations</a></h3> <p>Due to the granularity of the Oracle error codes, it is impossible to distinguish between the duplicate primary key and other unique @@ -18614,7 +19413,7 @@ CREATE TABLE Employee ( errors to the <code>object_already_persistent</code> exception (<a href="#3.14">Section 3.14, "ODB Exceptions"</a>).</p> - <h3><a name="18.5.5">18.5.5 Large <code>FLOAT</code> and + <h3><a name="20.5.5">20.5.5 Large <code>FLOAT</code> and <code>NUMBER</code> Types</a></h3> <p>The Oracle <code>FLOAT</code> type with a binary precision greater @@ -18632,31 +19431,31 @@ CREATE TABLE Employee ( <p>An alternative approach to accessing large <code>FLOAT</code> and <code>NUMBER</code> values is to map these type to one of the - natively supported ones, as discussed in <a href="#12.7">Section - 12.7, "Database Type Mapping Pragmas"</a>.</p> + natively supported ones, as discussed in <a href="#14.7">Section + 14.7, "Database Type Mapping Pragmas"</a>.</p> <p>Note that a <code>NUMBER</code> type that is used to represent a floating point number (declared by specifying <code>NUMBER</code> without any range and scale) can be extracted into the C++ <code>float</code> and <code>double</code> types.</p> - <h3><a name="18.5.6">18.5.6 Timezones</a></h3> + <h3><a name="20.5.6">20.5.6 Timezones</a></h3> <p>ODB does not currently support the Oracle date-time types with timezone information. However, these types can be accessed by mapping them to one of the natively supported types, as discussed in - <a href="#12.7">Section 12.7, "Database Type Mapping Pragmas"</a>.</p> + <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h3><a name="18.5.7">18.5.7 <code>LONG</code> Types</a></h3> + <h3><a name="20.5.7">20.5.7 <code>LONG</code> Types</a></h3> <p>ODB does not support the deprecated Oracle <code>LONG</code> and <code>LONG RAW</code> data types. However, these types can be accessed by mapping them to one of the natively supported types, as discussed - in <a href="#12.7">Section 12.7, "Database Type Mapping Pragmas"</a>.</p> + in <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h3><a name="18.5.8">18.5.8 LOB Types and By-Value Accessors/Modifiers</a></h3> + <h3><a name="20.5.8">20.5.8 LOB Types and By-Value Accessors/Modifiers</a></h3> - <p>As discussed in <a href="#12.4.5">Section 12.4.5, + <p>As discussed in <a href="#14.4.5">Section 14.4.5, "<code>get</code>/<code>set</code>/<code>access</code>"</a>, by-value accessor and modifier expressions cannot be used with data members of Oracle large object (LOB) data types: <code>BLOB</code>, @@ -18665,9 +19464,9 @@ CREATE TABLE Employee ( data members. As a result, by-reference accessors and modifiers should be used for these data types.</p> - <h2><a name="18.6">18.6 Oracle Index Definitions</a></h2> + <h2><a name="20.6">20.6 Oracle Index Definitions</a></h2> - <p>When the <code>index</code> pragma (<a href="#12.6">Section 12.6, + <p>When the <code>index</code> pragma (<a href="#14.6">Section 14.6, "Index Definition Pragmas"</a>) is used to define an Oracle index, the <code>type</code> clause specifies the index type (for example, <code>UNIQUE</code>, <code>BITMAP</code>), the <code>method</code> @@ -18699,7 +19498,7 @@ class object <hr class="page-break"/> - <h1><a name="19">19 Microsoft SQL Server Database</a></h1> + <h1><a name="21">21 Microsoft SQL Server Database</a></h1> <p>To generate support code for the SQL Server database you will need to pass the "<code>--database mssql</code>" @@ -18708,12 +19507,12 @@ class object library (<code>libodb-mssql</code>). All SQL Server-specific ODB classes are defined in the <code>odb::mssql</code> namespace.</p> - <h2><a name="19.1">19.1 SQL Server Type Mapping</a></h2> + <h2><a name="21.1">21.1 SQL Server Type Mapping</a></h2> <p>The following table summarizes the default mapping between basic C++ value types and SQL Server database types. This mapping can be customized on the per-type and per-member basis using the ODB - Pragma Language (<a href="#12">Chapter 12, "ODB Pragma Language"</a>).</p> + Pragma Language (<a href="#14">Chapter 14, "ODB Pragma Language"</a>).</p> <!-- border="1" is necessary for html2ps --> <table id="mapping" border="1"> @@ -18841,7 +19640,7 @@ class object <p>It is possible to map the <code>char</code> C++ type to an integer database type (for example, <code>TINYINT</code>) using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>).</p> <p>Note that the <code>std::string</code> and <code>std::wstring</code> @@ -18853,7 +19652,7 @@ class object is mapped to <code>VARCHAR(512)</code> and <code>std::wstring</code> — to <code>NVARCHAR(512)</code>. Note also that you can always change this mapping using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>).</p> + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>).</p> <p>Additionally, by default, C++ enumerations are automatically mapped to <code>INT</code> with the default <code>NULL</code> @@ -18875,10 +19674,10 @@ class object <p>It is also possible to add support for additional SQL Server types, such as geospatial types, <code>XML</code>, and user-defined types. - For more information, refer to <a href="#12.7">Section 12.7, "Database + For more information, refer to <a href="#14.7">Section 14.7, "Database Type Mapping Pragmas"</a>.</p> - <h3><a name="19.1.1">19.1.1 String Type Mapping</a></h3> + <h3><a name="21.1.1">21.1.1 String Type Mapping</a></h3> <p>The SQL Server ODB runtime library provides support for mapping the <code>std::string</code>, <code>char[N]</code>, and @@ -18891,7 +19690,7 @@ class object <code>std::array</code> will be treated as a container). To enable the alternative mappings for these types we need to specify the database type explicitly using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), for + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> @@ -18928,10 +19727,10 @@ class object from the database, ODB will append the zero terminator if there is enough space.</p> - <p>See also <a href="#19.1.4">Section 19.1.4, "Long String and Binary + <p>See also <a href="#21.1.4">Section 21.1.4, "Long String and Binary Types"</a> for certain limitations of long string types.</p> - <h3><a name="19.1.2">19.1.2 Binary Type and <code>UNIQUEIDENTIFIER</code> Mapping</a></h3> + <h3><a name="21.1.2">21.1.2 Binary Type and <code>UNIQUEIDENTIFIER</code> Mapping</a></h3> <p>The SQL Server ODB runtime library also provides support for mapping the <code>std::vector<char></code>, @@ -18945,7 +19744,7 @@ class object by default, <code>std::vector</code> and <code>std::array</code> will be treated as containers). To enable the alternative mappings for these types we need to specify the database type explicitly using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), for example:</p> <pre class="cxx"> @@ -18997,17 +19796,17 @@ db.query<object> ( db.query<object> (query::uuid == query::_ref (u)); </pre> - <p>See also <a href="#19.1.4">Section 19.1.4, "Long String and Binary + <p>See also <a href="#21.1.4">Section 21.1.4, "Long String and Binary Types"</a> for certain limitations of long binary types.</p> - <h3><a name="19.1.3">19.1.3 <code>ROWVERSION</code> Mapping</a></h3> + <h3><a name="21.1.3">21.1.3 <code>ROWVERSION</code> Mapping</a></h3> <p><code>ROWVERSION</code> is a special SQL Server data type that is automatically incremented by the database server whenever a row is inserted or updated. As such, it is normally used to implement optimistic concurrency and ODB provides support for using <code>ROWVERSION</code> instead of the more portable approach - for optimistic concurrency (<a href="#11">Chapter 11, "Optimistic + for optimistic concurrency (<a href="#12">Chapter 12, "Optimistic Concurrency"</a>).</p> <p><code>ROWVERSION</code> is a 64-bit value which is mapped by ODB @@ -19029,7 +19828,7 @@ class person }; </pre> - <h3><a name="19.1.4">19.1.4 Long String and Binary Types</a></h3> + <h3><a name="21.1.4">21.1.4 Long String and Binary Types</a></h3> <p>For SQL Server, ODB handles character, national character, and binary data in two different ways depending on its maximum length. @@ -19052,7 +19851,7 @@ class person than once as part of a query result iteration (<a href="#4.4">Section 4.4, "Query Result"</a>). Any such attempt will result in the <code>odb::mssql::long_data_reload</code> exception - (<a href="#19.4">Section 19.4, "SQL Server Exceptions"</a>). For + (<a href="#21.4">Section 21.4, "SQL Server Exceptions"</a>). For example:</p> <pre class="cxx"> @@ -19086,12 +19885,12 @@ for (result::iterator i (r.begin ()); i != r.end (); ++i) t.commit (); </pre> - <p>Finally, if a native view (<a href="#9.5">Section 9.5, "Native + <p>Finally, if a native view (<a href="#10.5">Section 10.5, "Native Views"</a>) contains one or more long data members, then such members should come last both in the select-list of the native SQL query and the list of data members in the C++ class.</p> - <h2><a name="19.2">19.2 SQL Server Database Class</a></h2> + <h2><a name="21.2">21.2 SQL Server Database Class</a></h2> <p>The SQL Server <code>database</code> class encapsulates the ODBC environment handle as well as the server instance address and @@ -19388,7 +20187,7 @@ odb::mssql::database dbA ("test", <p>This constructor throws the <code>odb::mssql::cli_exception</code> exception if the SQL Server option values are missing or invalid. See - section <a href="#19.4">Section 19.4, "SQL Server Exceptions"</a> for + section <a href="#21.4">Section 21.4, "SQL Server Exceptions"</a> for more information on this exception.</p> <p>The static <code>print_usage()</code> function prints the list of options @@ -19419,10 +20218,10 @@ odb::mssql::database dbA ("test", <p>The <code>connection()</code> function returns a pointer to the SQL Server database connection encapsulated by the <code>odb::mssql::connection</code> class. For more information - on <code>mssql::connection</code>, refer to <a href="#19.3">Section - 19.3, "SQL Server Connection and Connection Factory"</a>.</p> + on <code>mssql::connection</code>, refer to <a href="#21.3">Section + 21.3, "SQL Server Connection and Connection Factory"</a>.</p> - <h2><a name="19.3">19.3 SQL Server Connection and Connection Factory</a></h2> + <h2><a name="21.3">21.3 SQL Server Connection and Connection Factory</a></h2> <p>The <code>mssql::connection</code> class has the following interface:</p> @@ -19617,7 +20416,7 @@ main (int argc, char* argv[]) } </pre> - <h2><a name="19.4">19.4 SQL Server Exceptions</a></h2> + <h2><a name="21.4">21.4 SQL Server Exceptions</a></h2> <p>The SQL Server ODB runtime library defines the following SQL Server-specific exceptions:</p> @@ -19698,14 +20497,14 @@ namespace odb <p>The <code>odb::mssql::long_data_reload</code> is thrown if an attempt is made to re-load an object or view with long data as part of a query result iteration. For more information, refer - to <a href="#19.1">Section 19.1, "SQL Server Type Mapping"</a>.</p> + to <a href="#21.1">Section 21.1, "SQL Server Type Mapping"</a>.</p> - <h2><a name="19.5">19.5 SQL Server Limitations</a></h2> + <h2><a name="21.5">21.5 SQL Server Limitations</a></h2> <p>The following sections describe SQL Server-specific limitations imposed by the current SQL Server and ODB runtime versions.</p> - <h3><a name="19.5.1">19.5.1 Query Result Caching</a></h3> + <h3><a name="21.5.1">21.5.1 Query Result Caching</a></h3> <p>SQL Server ODB runtime implementation does not perform query result caching (<a href="#4.4">Section 4.4, "Query Result"</a>) even when @@ -19720,7 +20519,7 @@ namespace odb 3.14, "ODB Exceptions"</a>) is always thrown. Future versions of the SQL Server ODB runtime library may add support for result caching.</p> - <h3><a name="19.5.2">19.5.2 Foreign Key Constraints</a></h3> + <h3><a name="21.5.2">21.5.2 Foreign Key Constraints</a></h3> <p>ODB assumes the standard SQL behavior which requires that foreign key constraints checking is deferred until the transaction is @@ -19736,7 +20535,7 @@ namespace odb which you persist, update, and erase objects within a transaction becomes important.</p> - <h3><a name="19.5.3">19.5.3 Unique Constraint Violations</a></h3> + <h3><a name="21.5.3">21.5.3 Unique Constraint Violations</a></h3> <p>Due to the granularity of the ODBC error codes, it is impossible to distinguish between the duplicate primary key and other unique @@ -19745,7 +20544,7 @@ namespace odb errors to the <code>object_already_persistent</code> exception (<a href="#3.14">Section 3.14, "ODB Exceptions"</a>).</p> - <h3><a name="19.5.4">19.5.4 Multi-threaded Windows Applications</a></h3> + <h3><a name="21.5.4">21.5.4 Multi-threaded Windows Applications</a></h3> <p>Multi-threaded Windows applications must use the <code>_beginthread()</code>/<code>_beginthreadex()</code> and @@ -19754,7 +20553,7 @@ namespace odb Win32 functions to start and terminate threads. This is a limitation of the ODBC implementation on Windows.</p> - <h3><a name="19.5.5">19.5.5 Affected Row Count and DDL Statements</a></h3> + <h3><a name="21.5.5">21.5.5 Affected Row Count and DDL Statements</a></h3> <p>SQL Server always returns zero as the number of affected rows for DDL statements. In particular, this means that the @@ -19762,7 +20561,7 @@ namespace odb "Executing Native SQL Statements"</a>) function will always return zero for such statements.</p> - <h3><a name="19.5.6">19.5.6 Long Data and Auto Object Ids, <code>ROWVERSION</code></a></h3> + <h3><a name="21.5.6">21.5.6 Long Data and Auto Object Ids, <code>ROWVERSION</code></a></h3> <p>SQL Server 2005 has a bug that causes it to fail on an <code>INSERT</code> or <code>UPDATE</code> statement with the <code>OUTPUT</code> clause @@ -19772,7 +20571,7 @@ namespace odb by the <code>database::persist()</code> or <code>database::update()</code> function when used on an object that contains long data and has an automatically assigned object id or uses <code>ROWVERSION</code>-based - optimistic concurrency (<a href="#19.1.1">Section 19.1.1, + optimistic concurrency (<a href="#21.1.1">Section 21.1.1, "<code>ROWVERSION</code> Support"</a>). The error message reads "This operation conflicts with another pending operation on this transaction. The operation failed."</p> @@ -19789,9 +20588,9 @@ namespace odb objects that use <code>ROWVERSION</code> for optimistic concurrency and containing long data.</p> - <h3><a name="19.5.7">19.5.7 Long Data and By-Value Accessors/Modifiers</a></h3> + <h3><a name="21.5.7">21.5.7 Long Data and By-Value Accessors/Modifiers</a></h3> - <p>As discussed in <a href="#12.4.5">Section 12.4.5, + <p>As discussed in <a href="#14.4.5">Section 14.4.5, "<code>get</code>/<code>set</code>/<code>access</code>"</a>, by-value accessor and modifier expressions cannot be used with data members of long data types. The SQL Server ODB runtime uses streaming for @@ -19799,9 +20598,9 @@ namespace odb by-reference accessors and modifiers should be used for these data types.</p> - <h2><a name="19.6">19.6 SQL Server Index Definitions</a></h2> + <h2><a name="21.6">21.6 SQL Server Index Definitions</a></h2> - <p>When the <code>index</code> pragma (<a href="#12.6">Section 12.6, + <p>When the <code>index</code> pragma (<a href="#14.6">Section 14.6, "Index Definition Pragmas"</a>) is used to define an SQL Server index, the <code>type</code> clause specifies the index type (for example, <code>UNIQUE</code>, <code>CLUSTERED</code>), the <code>method</code> @@ -19836,9 +20635,9 @@ class object and libraries. It consists of the following chapters.</p> <table class="toc"> - <tr><th>20</th><td><a href="#20">Profiles Introduction</a></td></tr> - <tr><th>21</th><td><a href="#21">Boost Profile</a></td></tr> - <tr><th>22</th><td><a href="#22">Qt Profile</a></td></tr> + <tr><th>22</th><td><a href="#22">Profiles Introduction</a></td></tr> + <tr><th>23</th><td><a href="#23">Boost Profile</a></td></tr> + <tr><th>24</th><td><a href="#24">Qt Profile</a></td></tr> </table> @@ -19846,7 +20645,7 @@ class object <hr class="page-break"/> - <h1><a name="20">20 Profiles Introduction</a></h1> + <h1><a name="22">22 Profiles Introduction</a></h1> <p>ODB profiles are a generic mechanism for integrating ODB with widely-used C++ frameworks and libraries. A profile provides glue @@ -19900,7 +20699,7 @@ odb --profile boost/date-time ... <hr class="page-break"/> - <h1><a name="21">21 Boost Profile</a></h1> + <h1><a name="23">23 Boost Profile</a></h1> <p>The ODB profile implementation for Boost is provided by the <code>libodb-boost</code> library and consists of multiple sub-profiles @@ -19925,7 +20724,7 @@ odb --profile boost/date-time ... that can be thrown by the Boost sub-profiles are described in the following sections.</p> - <h2><a name="21.1">21.1 Smart Pointers Library</a></h2> + <h2><a name="23.1">23.1 Smart Pointers Library</a></h2> <p>The <code>smart-ptr</code> sub-profile provides persistence support for a subset of smart pointers from the Boost @@ -19995,7 +20794,7 @@ class employee this behavior, add the <code>--default-pointer</code> option specifying the alternative pointer type after the <code>--profile</code> option.</p> - <h2><a name="21.2">21.2 Unordered Containers Library</a></h2> + <h2><a name="23.2">23.2 Unordered Containers Library</a></h2> <p>The <code>unordered</code> sub-profile provides persistence support for the containers from the Boost <code>unordered</code> library. To enable @@ -20021,7 +20820,7 @@ class person }; </pre> - <h2><a name="21.3">21.3 Multi-Index Container Library</a></h2> + <h2><a name="23.3">23.3 Multi-Index Container Library</a></h2> <p>The <code>multi-index</code> sub-profile provides persistence support for <code>boost::multi_index_container</code> from the Boost Multi-Index @@ -20106,7 +20905,7 @@ class person }; </pre> - <h2><a name="21.4">21.4 Optional Library</a></h2> + <h2><a name="23.4">23.4 Optional Library</a></h2> <p>The <code>optional</code> sub-profile provides persistence support for the <code>boost::optional</code> container from the Boost @@ -20138,7 +20937,7 @@ class person this profile is used, the <code>NULL</code> values are automatically enabled for data members of the <code>boost::optional</code> type.</p> - <h2><a name="21.5">21.5 Date Time Library</a></h2> + <h2><a name="23.5">23.5 Date Time Library</a></h2> <p>The <code>date-time</code> sub-profile provides persistence support for a subset of types from the Boost <code>date_time</code> library. It is @@ -20211,7 +21010,7 @@ namespace odb exceptions are thrown are database system dependent and are discussed in more detail in the following sub-sections.</p> - <h3><a name="21.5.1">21.5.1 MySQL Database Type Mapping</a></h3> + <h3><a name="23.5.1">23.5.1 MySQL Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Boost <code>date_time</code> types and the MySQL database @@ -20251,7 +21050,7 @@ namespace odb support for mapping <code>posix_time::ptime</code> to the <code>TIMESTAMP</code> MySQL type. However, this mapping has to be explicitly requested using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), as shown in + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -20304,7 +21103,7 @@ class person the <code>out_of_range</code> exception. Refer to the MySQL documentation for more information on the MySQL data type ranges.</p> - <h3><a name="21.5.2">21.5.2 SQLite Database Type Mapping</a></h3> + <h3><a name="23.5.2">23.5.2 SQLite Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Boost <code>date_time</code> types and the SQLite database @@ -20347,7 +21146,7 @@ class person alternative mapping for <code>posix_time::time_duration</code> to the <code>INTEGER</code> type represents the duration as a number of seconds. These mappings have to be explicitly requested using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -20382,7 +21181,7 @@ class person will result in the <code>out_of_range</code> exception.</p> - <h3><a name="21.5.3">21.5.3 PostgreSQL Database Type Mapping</a></h3> + <h3><a name="23.5.3">23.5.3 PostgreSQL Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Boost <code>date_time</code> types and the PostgreSQL database @@ -20433,7 +21232,7 @@ class person result in the <code>special_value</code> exception.</p> - <h3><a name="21.5.4">21.5.4 Oracle Database Type Mapping</a></h3> + <h3><a name="23.5.4">23.5.4 Oracle Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Boost <code>date_time</code> types and the Oracle database @@ -20474,7 +21273,7 @@ class person <code>DATE</code> Oracle type with fractional seconds that may be stored in a <code>ptime</code> instance being ignored. This alternative mapping has to be explicitly requested using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -20495,7 +21294,7 @@ class person the <code>special_value</code> exception.</p> - <h3><a name="21.5.5">21.5.5 SQL Server Database Type Mapping</a></h3> + <h3><a name="23.5.5">23.5.5 SQL Server Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Boost <code>date_time</code> types and the SQL Server database @@ -20542,7 +21341,7 @@ class person support for mapping <code>posix_time::ptime</code> to the <code>DATETIME</code> and <code>SMALLDATETIME</code> types, however, this mapping has to be explicitly requested using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -20566,7 +21365,7 @@ class person <code>posix_time::time_duration</code> value out of this range will result in the <code>value_out_of_range</code> exception.</p> - <h2><a name="21.6">21.6 Uuid Library</a></h2> + <h2><a name="23.6">23.6 Uuid Library</a></h2> <p>The <code>uuid</code> sub-profile provides persistence support for the <code>uuid</code> type from the Boost <code>uuid</code> library. To @@ -20579,8 +21378,8 @@ class person database column with <code>NULL</code> enabled and nil <code>uuid</code> instances are stored as a <code>NULL</code> value. However, you can change this behavior by declaring the data member <code>NOT NULL</code> - with the <code>not_null</code> pragma (<a href="#12.4.6">Section - 12.4.6, "<code>null</code>/<code>not_null</code>"</a>). In this + with the <code>not_null</code> pragma (<a href="#14.4.6">Section + 14.4.6, "<code>null</code>/<code>not_null</code>"</a>). In this case, or if the data member is an object id, the implementation will store nil <code>uuid</code> instances as zero UUID values (<code>{00000000-0000-0000-0000-000000000000}</code>). For example:</p> @@ -20598,7 +21397,7 @@ class object }; </pre> - <h3><a name="21.6.1">21.6.1 MySQL Database Type Mapping</a></h3> + <h3><a name="23.6.1">23.6.1 MySQL Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the Boost <code>uuid</code> type and the MySQL database type.</p> @@ -20618,7 +21417,7 @@ class object </tr> </table> - <h3><a name="21.6.2">21.6.2 SQLite Database Type Mapping</a></h3> + <h3><a name="23.6.2">23.6.2 SQLite Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the Boost <code>uuid</code> type and the SQLite database type.</p> @@ -20638,7 +21437,7 @@ class object </tr> </table> - <h3><a name="21.6.3">21.6.3 PostgreSQL Database Type Mapping</a></h3> + <h3><a name="23.6.3">23.6.3 PostgreSQL Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the Boost <code>uuid</code> type and the PostgreSQL database type.</p> @@ -20658,7 +21457,7 @@ class object </tr> </table> - <h3><a name="21.6.4">21.6.4 Oracle Database Type Mapping</a></h3> + <h3><a name="23.6.4">23.6.4 Oracle Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the Boost <code>uuid</code> type and the Oracle database type.</p> @@ -20678,7 +21477,7 @@ class object </tr> </table> - <h3><a name="21.6.5">21.6.5 SQL Server Database Type Mapping</a></h3> + <h3><a name="23.6.5">23.6.5 SQL Server Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the Boost <code>uuid</code> type and the SQL Server database type.</p> @@ -20703,7 +21502,7 @@ class object <hr class="page-break"/> - <h1><a name="22">22 Qt Profile</a></h1> + <h1><a name="24">24 Qt Profile</a></h1> <p>The ODB profile implementation for Qt is provided by the <code>libodb-qt</code> library. Both Qt4 and Qt5 as well @@ -20732,7 +21531,7 @@ class object that can be thrown by the Qt sub-profiles are described in the following sections.</p> - <h2><a name="22.1">22.1 Basic Types Library</a></h2> + <h2><a name="24.1">24.1 Basic Types Library</a></h2> <p>The <code>basic</code> sub-profile provides persistence support for basic types defined by Qt. To enable only this profile, pass @@ -20759,8 +21558,8 @@ class Person database column with <code>NULL</code> enabled and null <code>QUuid</code> instances are stored as a <code>NULL</code> value. However, you can change this behavior by declaring the data member <code>NOT NULL</code> - with the <code>not_null</code> pragma (<a href="#12.4.6">Section - 12.4.6, "<code>null</code>/<code>not_null</code>"</a>). In this + with the <code>not_null</code> pragma (<a href="#14.4.6">Section + 14.4.6, "<code>null</code>/<code>not_null</code>"</a>). In this case, or if the data member is an object id, the implementation will store null <code>QUuid</code> instances as zero UUID values (<code>{00000000-0000-0000-0000-000000000000}</code>). For example:</p> @@ -20778,7 +21577,7 @@ class object }; </pre> - <h3><a name="22.1.1">22.1.1 MySQL Database Type Mapping</a></h3> + <h3><a name="24.1.1">24.1.1 MySQL Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported basic Qt types and the MySQL database types.</p> @@ -20826,7 +21625,7 @@ class object <code>NCHAR</code>, and <code>NVARCHAR</code> MySQL types. However, these alternative mappings have to be explicitly requested using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "type"</a>), as shown in + (<a href="#14.4.3">Section 14.4.3, "type"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -20841,7 +21640,7 @@ class Person </pre> - <h3><a name="22.1.2">22.1.2 SQLite Database Type Mapping</a></h3> + <h3><a name="24.1.2">24.1.2 SQLite Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported basic Qt types and the SQLite database types.</p> @@ -20877,7 +21676,7 @@ class Person are stored as a NULL value if their <code>isNull()</code> member function returns <code>true</code>.</p> - <h3><a name="22.1.3">22.1.3 PostgreSQL Database Type Mapping</a></h3> + <h3><a name="24.1.3">24.1.3 PostgreSQL Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported basic Qt types and the PostgreSQL database types.</p> @@ -20918,7 +21717,7 @@ class Person and <code>VARCHAR</code> PostgreSQL types. However, these alternative mappings have to be explicitly requested using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "type"</a>), as shown in + (<a href="#14.4.3">Section 14.4.3, "type"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -20932,7 +21731,7 @@ class Person }; </pre> - <h3><a name="22.1.4">22.1.4 Oracle Database Type Mapping</a></h3> + <h3><a name="24.1.4">24.1.4 Oracle Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported basic Qt types and the Oracle database types.</p> @@ -20974,7 +21773,7 @@ class Person <code>NCLOB</code> Oracle types, and for mapping <code>QByteArray</code> to the <code>RAW</code> Oracle type. However, these alternative mappings have to be explicitly requested using the <code>db type</code> - pragma (<a href="#12.4.3">Section 12.4.3, "type"</a>), as shown in the + pragma (<a href="#14.4.3">Section 14.4.3, "type"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -20991,7 +21790,7 @@ class Person }; </pre> - <h3><a name="22.1.5">22.1.5 SQL Server Database Type Mapping</a></h3> + <h3><a name="24.1.5">24.1.5 SQL Server Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported basic Qt types and the SQL Server database types.</p> @@ -21041,7 +21840,7 @@ class Person <code>QByteArray</code> to the <code>BINARY</code> and <code>IMAGE</code> SQL Server types. However, these alternative mappings have to be explicitly requested using the <code>db type</code> - pragma (<a href="#12.4.3">Section 12.4.3, "type"</a>), as shown in the + pragma (<a href="#14.4.3">Section 14.4.3, "type"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -21058,7 +21857,7 @@ class Person }; </pre> - <h2><a name="22.2">22.2 Smart Pointers Library</a></h2> + <h2><a name="24.2">24.2 Smart Pointers Library</a></h2> <p>The <code>smart-ptr</code> sub-profile provides persistence support the Qt smart pointers. To enable only this profile, pass @@ -21127,7 +21926,7 @@ class Employee this behavior, add the <code>--default-pointer</code> option specifying the alternative pointer type after the <code>--profile</code> option.</p> - <h2><a name="22.3">22.3 Containers Library</a></h2> + <h2><a name="24.3">24.3 Containers Library</a></h2> <p>The <code>containers</code> sub-profile provides persistence support for Qt containers. To enable only this profile, pass @@ -21153,13 +21952,13 @@ class Person </pre> <p>The <code>containers</code> sub-profile also provide a change-tracking - equivalent for <code>QList</code> (<a href="#22.3.1">Section 22.3.1, + equivalent for <code>QList</code> (<a href="#24.3.1">Section 24.3.1, "Change-Tracking <code>QList</code>"</a>) with support for other Qt container equivalents planned for future releases. For general information on change-tracking containers refer to <a href="#5.4">Section 5.4, "Change-Tracking Containers"</a>.</p> - <h3><a name="22.3.1">22.3.1 Change-Tracking <code>QList</code></a></h3> + <h3><a name="24.3.1">24.3.1 Change-Tracking <code>QList</code></a></h3> <p>Class template <code>QOdbList</code>, defined in <code><odb/qt/list.hxx></code>, is a change-tracking @@ -21175,8 +21974,8 @@ class Person <p><code>QOdbList</code> incurs 2-bit per element overhead in order to store the change state. It cannot - be stored unordered in the database (<a href="#12.4.18">Section - 12.4.18 "<code>unordered</code>"</a>) but can be used as an inverse + be stored unordered in the database (<a href="#14.4.18">Section + 14.4.18 "<code>unordered</code>"</a>) but can be used as an inverse side of a relationship (<a href="#6.2">6.2 "Bidirectional Relationships"</a>). In this case, no change tracking is performed since no state for such a container is stored in the database.</p> @@ -21340,7 +22139,7 @@ qSort (l.modifyBegin (), l.modifyEnd ()); that any element that such an iterator passes over with the call to <code>next()</code> is marked as modified.</p> - <h2><a name="22.4">22.4 Date Time Library</a></h2> + <h2><a name="24.4">24.4 Date Time Library</a></h2> <p>The <code>date-time</code> sub-profile provides persistence support for the Qt date-time types. To enable only this profile, pass @@ -21393,7 +22192,7 @@ namespace odb system dependent and is discussed in more detail in the following sub-sections.</p> - <h3><a name="22.4.1">22.4.1 MySQL Database Type Mapping</a></h3> + <h3><a name="24.4.1">24.4.1 MySQL Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Qt date-time types and the MySQL database types.</p> @@ -21433,7 +22232,7 @@ namespace odb support for mapping <code>QDateTime</code> to the <code>TIMESTAMP</code> MySQL type. However, this mapping has to be explicitly requested using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), as shown in + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -21484,7 +22283,7 @@ class Person the MySQL documentation for more information on the MySQL data type ranges.</p> - <h3><a name="22.4.2">22.4.2 SQLite Database Type Mapping</a></h3> + <h3><a name="24.4.2">24.4.2 SQLite Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Qt date-time types and the SQLite database types.</p> @@ -21527,7 +22326,7 @@ class Person the <code>INTEGER</code> type represents a clock time as the number of seconds since midnight. These mappings have to be explicitly requested using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), as shown + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -21546,7 +22345,7 @@ class Person epoch) as an SQLite <code>INTEGER</code> will result in the <code>out_of_range</code> exception.</p> - <h3><a name="22.4.3">22.4.3 PostgreSQL Database Type Mapping</a></h3> + <h3><a name="24.4.3">24.4.3 PostgreSQL Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Qt date-time types and the PostgreSQL database types.</p> @@ -21582,7 +22381,7 @@ class Person <code>QDateTime</code> types are stored as a NULL value if their <code>isNull()</code> member function returns true.</p> - <h3><a name="22.4.4">22.4.4 Oracle Database Type Mapping</a></h3> + <h3><a name="24.4.4">24.4.4 Oracle Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Qt date-time types and the Oracle database types.</p> @@ -21623,7 +22422,7 @@ class Person <code>DATE</code> Oracle type with fractional seconds that may be stored in a <code>QDateTime</code> instance being ignored. This alternative mapping has to be explicitly requested using the - <code>db type</code> pragma (<a href="#12.4.3">Section 12.4.3, + <code>db type</code> pragma (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), as shown in the following example:</p> <pre class="cxx"> @@ -21636,7 +22435,7 @@ class person }; </pre> - <h3><a name="22.4.5">22.4.5 SQL Server Database Type Mapping</a></h3> + <h3><a name="24.4.5">24.4.5 SQL Server Database Type Mapping</a></h3> <p>The following table summarizes the default mapping between the currently supported Qt date-time types and the SQL Server database types.</p> @@ -21683,7 +22482,7 @@ class person support for mapping <code>QDateTime</code> to the <code>DATETIME</code> and <code>SMALLDATETIME</code> types, however, this mapping has to be explicitly requested using the <code>db type</code> pragma - (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), as + (<a href="#14.4.3">Section 14.4.3, "<code>type</code>"</a>), as shown in the following example:</p> <pre class="cxx"> |