<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>C++ Object Persistence with ODB</title>
<meta name="copyright" content="© 2009-2012 Code Synthesis Tools CC"/>
<meta name="keywords" content="odb,c++,object,persistence,ORM,relational,database,RDBMS,ODBMS,OODBMS"/>
<meta name="description" content="C++ Object Persistence with ODB"/>
<meta name="revision" content="2.2"/>
<meta name="version" content="2.2.0"/>
<!--
If you make changes to this document, follow these stylistic rules
for consistency.
- Don't use 'object' for instances of non-persistent classes. Use
'instance' instead.
- Each overloaded function should still be referred to as function.
When saying that a function is overloaded, use term 'version',
for example The persist() function has two overloaded versions.
Don't use version to refer to individual functions, use function
instead. The same holds for constructors.
- Use 'object id' and 'object's identifier'. But not other combinations
of the two.
@@ Check that parts TOCs are up to date.
-->
<link rel="stylesheet" type="text/css" href="default.css" />
<style type="text/css">
pre {
padding : 0 0 0 0em;
margin : 0em 0em 0em 0;
font-size : 102%
}
body {
min-width: 48em;
}
h1 {
font-weight: bold;
font-size: 200%;
line-height: 1.2em;
}
h2 {
font-weight : bold;
font-size : 150%;
padding-top : 0.8em;
}
h3 {
font-size : 140%;
padding-top : 0.8em;
}
/* Force page break for both PDF and HTML (when printing). */
hr.page-break {
height: 0;
width: 0;
border: 0;
visibility: hidden;
page-break-after: always;
}
/* Adjust indentation for three levels. */
#container {
max-width: 48em;
}
#content {
padding: 0 0.1em 0 4em;
/*background-color: red;*/
}
#content h1 {
margin-left: -2.06em;
}
#content h2 {
margin-left: -1.33em;
}
/* Title page */
#titlepage {
padding: 2em 0 1em 0;
border-bottom: 1px solid black;
}
#titlepage .title {
font-weight: bold;
font-size: 200%;
text-align: center;
padding: 1em 0 2em 0;
}
#titlepage p {
padding-bottom: 1em;
}
#titlepage #revision {
padding-bottom: 0em;
}
/* Lists */
ul.list li, ol.list li {
padding-top : 0.3em;
padding-bottom : 0.3em;
}
div.img {
text-align: center;
padding: 2em 0 2em 0;
}
/* */
dl dt {
padding : 0.8em 0 0 0;
}
/* TOC */
table.toc {
border-style : none;
border-collapse : separate;
border-spacing : 0;
margin : 0.2em 0 0.2em 0;
padding : 0 0 0 0;
}
table.toc tr {
padding : 0 0 0 0;
margin : 0 0 0 0;
}
table.toc * td, table.toc * th {
border-style : none;
margin : 0 0 0 0;
vertical-align : top;
}
table.toc * th {
font-weight : normal;
padding : 0em 0.1em 0em 0;
text-align : left;
white-space : nowrap;
}
table.toc * table.toc th {
padding-left : 1em;
}
table.toc * td {
padding : 0em 0 0em 0.7em;
text-align : left;
}
/* operators table */
#operators {
margin: 2em 0 2em 0;
border-collapse : collapse;
border : 1px solid;
border-color : #000000;
font-size : 11px;
line-height : 14px;
}
#operators th, #operators td {
border: 1px solid;
padding : 0.9em 0.9em 0.7em 0.9em;
}
#operators th {
background : #cde8f6;
}
#operators td {
text-align: left;
}
/* specifiers table */
.specifiers {
margin: 2em 0 2em 0;
border-collapse : collapse;
border : 1px solid;
border-color : #000000;
font-size : 11px;
line-height : 14px;
}
.specifiers th, .specifiers td {
border: 1px solid;
padding : 0.9em 0.9em 0.7em 0.9em;
}
.specifiers th {
background : #cde8f6;
}
.specifiers td {
text-align: left;
}
/* mapping table */
#mapping {
margin: 2em 0 2em 0;
border-collapse : collapse;
border : 1px solid;
border-color : #000000;
font-size : 11px;
line-height : 14px;
}
#mapping th, #mapping td {
border: 1px solid;
padding : 0.9em 0.9em 0.7em 0.9em;
}
#mapping th {
background : #cde8f6;
}
#mapping td {
text-align: left;
}
</style>
</head>
<body>
<div id="container">
<div id="content">
<div class="noprint">
<div id="titlepage">
<div class="title">C++ Object Persistence with ODB</div>
<p>Copyright © 2009-2012 Code Synthesis Tools CC</p>
<p>Permission is granted to copy, distribute and/or modify this
document under the terms of the
<a href="http://www.codesynthesis.com/licenses/fdl-1.3.txt">GNU Free
Documentation License, version 1.3</a>; with no Invariant Sections,
no Front-Cover Texts and no Back-Cover Texts.</p>
<!-- REMEMBER TO CHANGE VERSIONS IN THE META TAGS ABOVE! -->
<p id="revision">Revision 2.2, October 2012</p>
<p>This revision of the manual describes ODB 2.2.0 and is available
in the following formats:
<a href="http://www.codesynthesis.com/products/odb/doc/manual.xhtml">XHTML</a>,
<a href="http://www.codesynthesis.com/products/odb/doc/odb-manual.pdf">PDF</a>, and
<a href="http://www.codesynthesis.com/products/odb/doc/odb-manual.ps">PostScript</a>.</p>
</div>
<hr class="page-break"/>
<h1>Table of Contents</h1>
<table class="toc">
<tr>
<th></th><td><a href="#0">Preface</a>
<table class="toc">
<tr><th></th><td><a href="#0.1">About This Document</a></td></tr>
<tr><th></th><td><a href="#0.2">More Information</a></td></tr>
</table>
</td>
</tr>
<tr>
<th colspan="2"><a href="#I">PART I OBJECT-RELATIONAL MAPPING</a></th>
</tr>
<tr>
<th>1</th><td><a href="#1">Introduction</a>
<table class="toc">
<tr><th>1.1</th><td><a href="#1.1">Architecture and Workflow</a></td></tr>
<tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr>
<tr><th>1.3</th><td><a href="#1.3">Supported C++ Standards</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>2</th><td><a href="#2">Hello World Example</a>
<table class="toc">
<tr><th>2.1</th><td><a href="#2.1">Declaring a Persistent Class</a></td></tr>
<tr><th>2.2</th><td><a href="#2.2">Generating Database Support Code</a></td></tr>
<tr><th>2.3</th><td><a href="#2.3">Compiling and Running</a></td></tr>
<tr><th>2.4</th><td><a href="#2.4">Making Objects Persistent</a></td></tr>
<tr><th>2.5</th><td><a href="#2.5">Querying the Database for Objects</a></td></tr>
<tr><th>2.6</th><td><a href="#2.6">Updating Persistent Objects</a></td></tr>
<tr><th>2.7</th><td><a href="#2.7">Defining and Using Views</a></td></tr>
<tr><th>2.8</th><td><a href="#2.8">Deleting Persistent Objects</a></td></tr>
<tr><th>2.9</th><td><a href="#2.9">Accessing Multiple Databases</a></td></tr>
<tr><th>2.10</th><td><a href="#2.10">Summary</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>3</th><td><a href="#3">Working with Persistent Objects</a>
<table class="toc">
<tr><th>3.1</th><td><a href="#3.1">Concepts and Terminology</a></td></tr>
<tr><th>3.2</th><td><a href="#3.2">Declaring Persistent Objects and Values</a></td></tr>
<tr><th>3.3</th><td><a href="#3.3">Object and View Pointers</a></td></tr>
<tr><th>3.4</th><td><a href="#3.4">Database</a></td></tr>
<tr><th>3.5</th><td><a href="#3.5">Transactions</a></td></tr>
<tr><th>3.6</th><td><a href="#3.6">Connections</a></td></tr>
<tr><th>3.7</th><td><a href="#3.7">Error Handling and Recovery</a></td></tr>
<tr><th>3.8</th><td><a href="#3.8">Making Objects Persistent</a></td></tr>
<tr><th>3.9</th><td><a href="#3.9">Loading Persistent Objects</a></td></tr>
<tr><th>3.10</th><td><a href="#3.10">Updating Persistent Objects</a></td></tr>
<tr><th>3.11</th><td><a href="#3.11">Deleting Persistent Objects</a></td></tr>
<tr><th>3.12</th><td><a href="#3.12">Executing Native SQL Statements</a></td></tr>
<tr><th>3.13</th><td><a href="#3.13">Tracing SQL Statement Execution</a></td></tr>
<tr><th>3.14</th><td><a href="#3.14">ODB Exceptions</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>4</th><td><a href="#4">Querying the Database</a>
<table class="toc">
<tr><th>4.1</th><td><a href="#4.1">ODB Query Language</a></td></tr>
<tr><th>4.2</th><td><a href="#4.2">Parameter Binding</a></td></tr>
<tr><th>4.3</th><td><a href="#4.3">Executing a Query</a></td></tr>
<tr><th>4.4</th><td><a href="#4.4">Query Result</a></td></tr>
<tr><th>4.5</th><td><a href="#4.5">Prepared Queries</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>5</th><td><a href="#5">Containers</a>
<table class="toc">
<tr><th>5.1</th><td><a href="#5.1">Ordered Containers</a></td></tr>
<tr><th>5.2</th><td><a href="#5.2">Set and Multiset Containers</a></td></tr>
<tr><th>5.3</th><td><a href="#5.3">Map and Multimap Containers</a></td></tr>
<tr>
<th>5.4</th><td><a href="#5.4">Change-Tracking Containers</a>
<table class="toc">
<tr><th>5.4.1</th><td><a href="#5.4.1">Change-Tracking <code>vector</code></a></td></tr>
</table>
</td>
</tr>
<tr><th>5.5</th><td><a href="#5.5">Using Custom Containers</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>6</th><td><a href="#6">Relationships</a>
<table class="toc">
<tr>
<th>6.1</th><td><a href="#6.1">Unidirectional Relationships</a>
<table class="toc">
<tr><th>6.1.1</th><td><a href="#6.1.1">To-One Relationships</a></td></tr>
<tr><th>6.1.2</th><td><a href="#6.1.2">To-Many Relationships</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>6.2</th><td><a href="#6.2">Bidirectional Relationships</a>
<table class="toc">
<tr><th>6.2.1</th><td><a href="#6.2.1">One-to-One Relationships</a></td></tr>
<tr><th>6.2.2</th><td><a href="#6.2.2">One-to-Many Relationships</a></td></tr>
<tr><th>6.2.3</th><td><a href="#6.2.3">Many-to-Many Relationships</a></td></tr>
</table>
</td>
</tr>
<tr><th>6.3</th><td><a href="#6.3">Circular Relationships</a></td></tr>
<tr><th>6.4</th><td><a href="#6.4">Lazy Pointers</a></td></tr>
<tr><th>6.5</th><td><a href="#6.5">Using Custom Smart Pointers</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>7</th><td><a href="#7">Value Types</a>
<table class="toc">
<tr><th>7.1</th><td><a href="#7.1">Simple Value Types</a></td></tr>
<tr>
<th>7.2</th><td><a href="#7.2">Composite Value Types</a>
<table class="toc">
<tr><th>7.2.1</th><td><a href="#7.2.1">Composite Object Ids</a></td></tr>
<tr><th>7.2.2</th><td><a href="#7.2.2">Composite Value Column and Table Names</a></td></tr>
</table>
</td>
</tr>
<tr><th>7.3</th><td><a href="#7.3">Pointers and <code>NULL</code> Value Semantics</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>8</th><td><a href="#8">Inheritance</a>
<table class="toc">
<tr><th>8.1</th><td><a href="#8.1">Reuse Inheritance</a></td></tr>
<tr>
<th>8.2</th><td><a href="#8.2">Polymorphism Inheritance</a>
<table class="toc">
<tr><th>8.2.1</th><td><a href="#8.2.1">Performance and Limitations</a></td></tr>
</table>
</td>
</tr>
<tr><th>8.3</th><td><a href="#8.3">Mixed Inheritance</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>9</th><td><a href="#9">Views</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>
</table>
</td>
</tr>
<tr>
<th>10</th><td><a href="#10">Session</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>
</table>
</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>
<table class="toc">
<tr>
<th>12.1</th><td><a href="#12.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>
</table>
</td>
</tr>
<tr>
<th>12.2</th><td><a href="#12.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>
</table>
</td>
</tr>
<tr>
<th>12.3</th><td><a href="#12.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>
</table>
</td>
</tr>
<tr>
<th>12.4</th><td><a href="#12.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>
</table>
</td>
</tr>
<tr>
<th>12.5</th><td><a href="#12.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>
</table>
</td>
</tr>
<tr>
<th>12.6</th><td><a href="#12.6">Index Definition Pragmas</a></td>
</tr>
<tr>
<th>12.7</th><td><a href="#12.7">Database Type Mapping Pragmas</a></td>
</tr>
<tr>
<th>12.8</th><td><a href="#12.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>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>13</th><td><a href="#13">Advanced Techniques and Mechanisms</a>
<table class="toc">
<tr><th>13.1</th><td><a href="#13.1">Transaction Callbacks</a></td></tr>
</table>
</td>
</tr>
<tr>
<th colspan="2"><a href="#II">PART II DATABASE SYSTEMS</a></th>
</tr>
<tr>
<th>14</th><td><a href="#14">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>14.2</th><td><a href="#14.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>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>15</th><td><a href="#15">MySQL Database</a>
<table class="toc">
<tr>
<th>15.1</th><td><a href="#15.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>
</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>15.5</th><td><a href="#15.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>
</table>
</td>
</tr>
<tr><th>15.6</th><td><a href="#15.6">MySQL Index Definition</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>16</th><td><a href="#16">SQLite Database</a>
<table class="toc">
<tr>
<th>16.1</th><td><a href="#16.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>
</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>16.5</th><td><a href="#16.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>
</table>
</td>
</tr>
<tr><th>16.6</th><td><a href="#16.6">SQLite Index Definition</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>17</th><td><a href="#17">PostgreSQL Database</a>
<table class="toc">
<tr>
<th>17.1</th><td><a href="#17.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>
</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>17.5</th><td><a href="#17.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>
</table>
</td>
</tr>
<tr><th>17.6</th><td><a href="#17.6">PostgreSQL Index Definition</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>18</th><td><a href="#18">Oracle Database</a>
<table class="toc">
<tr>
<th>18.1</th><td><a href="#18.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>
</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>18.5</th><td><a href="#18.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>
</table>
</td>
</tr>
<tr><th>18.6</th><td><a href="#18.6">Oracle Index Definition</a></td></tr>
</table>
</td>
</tr>
<tr>
<th>19</th><td><a href="#19">Microsoft SQL Server Database</a>
<table class="toc">
<tr>
<th>19.1</th><td><a href="#19.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>
</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>19.5</th><td><a href="#19.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>
</table>
</td>
</tr>
<tr><th>19.6</th><td><a href="#19.6">SQL Server Index Definition</a></td></tr>
</table>
</td>
</tr>
<tr>
<th colspan="2"><a href="#III">PART III PROFILES</a></th>
</tr>
<tr>
<th>20</th><td><a href="#20">Profiles Introduction</a></td>
</tr>
<tr>
<th>21</th><td><a href="#21">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>21.5</th><td><a href="#21.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>
</table>
</td>
</tr>
<tr>
<th>21.6</th><td><a href="#21.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>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>22</th><td><a href="#22">Qt Profile</a>
<table class="toc">
<tr>
<th>22.1</th><td><a href="#22.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>
</table>
</td>
</tr>
<tr><th>22.2</th><td><a href="#22.2">Smart Pointers Library</a></td></tr>
<tr>
<th>22.3</th><td><a href="#22.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>
</table>
</td>
</tr>
<tr>
<th>22.4</th><td><a href="#22.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>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<hr class="page-break"/>
<h1><a name="0">Preface</a></h1>
<p>As more critical aspects of our lives become dependant on software
systems, more and more applications are required to save the data
they work on in persistent and reliable storage. Database management
systems and, in particular, relational database management systems
(RDBMS) are commonly used for such storage. However, while the
application development techniques and programming languages have
evolved significantly over the past decades, the relational database
technology in this area stayed relatively unchanged. In particular,
this led to the now infamous mismatch between the object-oriented
model used by many modern applications and the relational model still
used by RDBMS.</p>
<p>While relational databases may be inconvenient to use from modern
programming languages, they are still the main choice for many
applications due to their maturity, reliability, as well as the
availability of tools and alternative implementations.</p>
<p>To allow application developers to utilize relational databases
from their object-oriented applications, a technique called
object-relational mapping (ORM) is often used. It involves a
conversion layer that maps between objects in the application's
memory and their relational representation in the database. While
the object-relational mapping code can be written manually,
automated ORM systems are available for most object-oriented
programming languages in use today.</p>
<p>ODB is an ORM system for the C++ programming language. It was
designed and implemented with the following main goals:</p>
<ul class="list">
<li>Provide a fully-automatic ORM system. In particular, the
application developer should not have to manually write any
mapping code, neither for persistent classes nor for their
data member. </li>
<li>Provide clean and easy to use object-oriented persistence
model and database APIs that support the development of realistic
applications for a wide variety of domains.</li>
<li>Provide a portable and thread-safe implementation. ODB should be
written in standard C++ and capable of persisting any standard
C++ classes.</li>
<li>Provide profiles that integrate ODB with type systems of
widely-used frameworks and libraries such as Qt and Boost.</li>
<li>Provide a high-performance and low overhead implementation. ODB
should make efficient use of database and application resources.</li>
</ul>
<h2><a name="0.1">About This Document</a></h2>
<p>The goal of this manual is to provide you with an understanding
of the object persistence model and APIs which are implemented by ODB.
As such, this document is intended for C++ application developers and
software architects who are looking for a C++ object persistence
solution. Prior experience with C++ is required to understand
this document. A basic understanding of relational database systems
is advantageous but not expected or required.</p>
<h2><a name="0.2">More Information</a></h2>
<p>Beyond this manual, you may also find the following sources of
information useful:</p>
<ul class="list">
<li><a href="http://www.codesynthesis.com/products/odb/doc/odb.xhtml">ODB
Compiler Command Line Manual.</a></li>
<li>The <code>INSTALL</code> files in the ODB source packages provide
build instructions for various platforms.</li>
<li>The <code>odb-examples</code> package contains a collection of
examples and a README file with an overview of each example.</li>
<li>The <a href="http://www.codesynthesis.com/mailman/listinfo/odb-users">odb-users</a>
mailing list is the place to ask technical questions about ODB.
Furthermore, the searchable
<a href="http://www.codesynthesis.com/pipermail/odb-users/">archives</a>
may already have answers to some of your questions.</li>
</ul>
<!-- PART -->
<hr class="page-break"/>
<h1><a name="I">PART I
<span style="font-weight: normal;">OBJECT-RELATIONAL MAPPING</span></a></h1>
<p>Part I describes the essential database concepts, APIs, and tools that
together comprise the object-relational mapping for C++ as implemented
by ODB. It consists of the following chapters.</p>
<table class="toc">
<tr><th>1</th><td><a href="#1">Introduction</a></td></tr>
<tr><th>2</th><td><a href="#2">Hello World Example</a></td></tr>
<tr><th>3</th><td><a href="#3">Working with Persistent Objects</a></td></tr>
<tr><th>4</th><td><a href="#4">Querying the Database</a></td></tr>
<tr><th>5</th><td><a href="#5">Containers</a></td></tr>
<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>
</table>
<!-- CHAPTER -->
<hr class="page-break"/>
<h1><a name="1">1 Introduction</a></h1>
<p>ODB is an object-relational mapping (ORM) system for C++. It provides
tools, APIs, and library support that allow you to persist C++ objects
to a relational database (RDBMS) without having to deal with tables,
columns, or SQL and without manually writing any of the mapping code.</p>
<p>ODB is highly flexible and customizable. It can either completely
hide the relational nature of the underlying database or expose
some of the details as required. For example, you can automatically
map basic C++ types to suitable SQL types, generate the relational
database schema for your persistent classes, and use simple, safe,
and yet powerful object query language instead of SQL. Or you can
assign SQL types to individual data members, use the existing
database schema, and run native SQL <code>SELECT</code> queries.
In fact, at an extreme, ODB can be used as <em>just</em> a convenient
way to handle results of native SQL queries.</p>
<p>ODB is not a framework. It does not dictate how you should write
your application. Rather, it is designed to fit into your
style and architecture by only handling object persistence
and not interfering with any other functionality. There is
no common base type that all persistent classes should derive
from nor are there any restrictions on the data member types
in persistent classes. Existing classes can be made persistent
with a few or no modifications.</p>
<p>ODB has been designed for high performance and low memory
overhead. Prepared statements are used to send and receive
object state in binary format instead of text which reduces
the load on the application and the database server. Extensive
caching of connections, prepared statements, and buffers saves
time and resources on connection establishment, statement parsing,
and memory allocations. For each supported database system the
native C API is used instead of ODBC or higher-level wrapper
APIs to reduce overhead and provide the most efficient implementation
for each database operation. Finally, persistent classes have
zero memory overhead. There are no hidden "database" members
that each class must have nor are there per-object data structures
allocated by ODB.</p>
<p>In this chapter we present a high-level overview of ODB.
We will start with the ODB architecture and then outline the
workflow of building an application that uses ODB. We will
then continue by contrasting the drawbacks of the traditional
way of saving C++ objects to relational databases with the
benefits of using ODB for object persistence. We conclude the
chapter by discussing the C++ standards supported by ODB. The
next chapter takes a more hands-on approach and shows the
concrete steps necessary to implement object persistence in
a simple "Hello World" application.</p>
<h2><a name="1.1">1.1 Architecture and Workflow</a></h2>
<p>From the application developer's perspective, ODB
consists of three main components: the ODB compiler, the common
runtime library, called <code>libodb</code>, and the
database-specific runtime libraries, called
<code>libodb-<database></code>, where <database> is
the name of the database system this runtime
is for, for example, <code>libodb-mysql</code>. For instance,
if the application is going to use the MySQL database for
object persistence, then the three ODB components that this
application will use are the ODB compiler, <code>libodb</code>
and <code>libodb-mysql</code>.</p>
<p>The ODB compiler generates the database support code for
persistent classes in your application. The input to the ODB
compiler is one or more C++ header files defining C++ classes
that you want to make persistent. For each input header file
the ODB compiler generates a set of C++ source files implementing
conversion between persistent C++ classes defined in this
header and their database representation. The ODB compiler
can also generate a database schema file that creates tables
necessary to store the persistent classes.</p>
<p>The ODB compiler is a real C++ compiler except that it produces
C++ instead of assembly or machine code. In particular, it is not
an ad-hoc header pre-processor that is only capable of recognizing
a subset of C++. ODB is capable of parsing any standard C++ code.</p>
<p>The common runtime library defines database system-independent
interfaces that your application can use to manipulate persistent
objects. The database-specific runtime library provides implementations
of these interfaces for a concrete database as well as other
database-specific utilities that are used by the generated code.
Normally, the application does not use the database-specific
runtime library directly but rather works with it via the common
interfaces from <code>libodb</code>. The following diagram shows
the object persistence architecture of an application that uses
MySQL as the underlying database system:</p>
<!-- align=center is needed for html2ps -->
<div class="img" align="center"><img src="odb-arch.png"/></div>
<p>The ODB system also defines two special-purpose languages:
the ODB Pragma Language and ODB Query Language. The ODB Pragma
Language is used to communicate various properties of persistent
classes to the ODB compiler by means of special <code>#pragma</code>
directives embedded in the C++ header files. It controls aspects
of the object-relational mapping such as names of tables and columns
that are used for persistent classes and their members or mapping between
C++ types and database types.</p>
<p>The ODB Query Language is an object-oriented database query
language that can be used to search for objects matching
certain criteria. It is modeled after and is integrated into
C++ allowing you to write expressive and safe queries that look
and feel like ordinary C++.</p>
<p>The use of the ODB compiler to generate database support code
adds an additional step to your application build sequence. The
following diagram outlines the typical build workflow of an
application that uses ODB:</p>
<!-- align=center is needed for html2ps -->
<div class="img" align="center"><img src="odb-flow.png"/></div>
<h2><a name="1.2">1.2 Benefits</a></h2>
<p>The traditional way of saving C++ objects to relational databases
requires that you manually write code which converts between the database
and C++ representations of each persistent class. The actions that
such code usually performs include conversion between C++ values and
strings or database types, preparation and execution of SQL queries,
as well as handling the result sets. Writing this code manually has
the following drawbacks:</p>
<ul class="list">
<li><b>Difficult and time consuming.</b> Writing database conversion
code for any non-trivial application requires extensive
knowledge of the specific database system and its APIs.
It can also take a considerable amount of time to write
and maintain. Supporting multi-threaded applications can
complicate this task even further.</li>
<li><b>Suboptimal performance.</b> Optimal conversion often
requires writing large amounts of extra code, such as
parameter binding for prepared statements and caching
of connections, statements, and buffers. Writing code
like this in an ad-hoc manner is often too difficult
and time consuming.</li>
<li><b>Database vendor lock-in.</b> The conversion code is written for
a specific database which makes it hard to switch to another
database vendor.</li>
<li><b>Lack of type
|