aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-10-20 15:18:35 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-10-21 19:25:06 +0200
commit5c0867663937e5af1ca9eb44a8a2b1dfa3aea49c (patch)
tree7d6288fa282347cc6ba161d76fd794db5e326625 /doc
parenteba1738e205e6047dad2c3df9648c65c7fb0f053 (diff)
Documentation for readonly members, objects, and values
Diffstat (limited to 'doc')
-rw-r--r--doc/manual.xhtml402
1 files changed, 297 insertions, 105 deletions
diff --git a/doc/manual.xhtml b/doc/manual.xhtml
index 26cc64a..20bdf89 100644
--- a/doc/manual.xhtml
+++ b/doc/manual.xhtml
@@ -437,7 +437,8 @@ for consistency.
<tr><th>11.1.1</th><td><a href="#11.1.1"><code>table</code></a></td></tr>
<tr><th>11.1.2</th><td><a href="#11.1.2"><code>pointer</code></a></td></tr>
<tr><th>11.1.3</th><td><a href="#11.1.3"><code>abstract</code></a></td></tr>
- <tr><th>11.1.4</th><td><a href="#11.1.4"><code>callback</code></a></td></tr>
+ <tr><th>11.1.4</th><td><a href="#11.1.4"><code>readonly</code></a></td></tr>
+ <tr><th>11.1.5</th><td><a href="#11.1.5"><code>callback</code></a></td></tr>
</table>
</td>
</tr>
@@ -460,19 +461,20 @@ for consistency.
<tr><th>11.3.3</th><td><a href="#11.3.3"><code>null</code>/<code>not_null</code></a></td></tr>
<tr><th>11.3.4</th><td><a href="#11.3.4"><code>default</code></a></td></tr>
<tr><th>11.3.5</th><td><a href="#11.3.5"><code>options</code></a></td></tr>
- <tr><th>11.3.6</th><td><a href="#11.3.6"><code>unordered</code></a></td></tr>
- <tr><th>11.3.7</th><td><a href="#11.3.7"><code>index_type</code></a></td></tr>
- <tr><th>11.3.8</th><td><a href="#11.3.8"><code>key_type</code></a></td></tr>
- <tr><th>11.3.9</th><td><a href="#11.3.9"><code>value_type</code></a></td></tr>
- <tr><th>11.3.10</th><td><a href="#11.3.10"><code>value_null</code>/<code>value_not_null</code></a></td></tr>
- <tr><th>11.3.11</th><td><a href="#11.3.11"><code>id_options</code></a></td></tr>
- <tr><th>11.3.12</th><td><a href="#11.3.12"><code>index_options</code></a></td></tr>
- <tr><th>11.3.13</th><td><a href="#11.3.13"><code>key_options</code></a></td></tr>
- <tr><th>11.3.14</th><td><a href="#11.3.14"><code>value_options</code></a></td></tr>
- <tr><th>11.3.15</th><td><a href="#11.3.15"><code>id_column</code></a></td></tr>
- <tr><th>11.3.16</th><td><a href="#11.3.16"><code>index_column</code></a></td></tr>
- <tr><th>11.3.17</th><td><a href="#11.3.17"><code>key_column</code></a></td></tr>
- <tr><th>11.3.18</th><td><a href="#11.3.18"><code>value_column</code></a></td></tr>
+ <tr><th>11.3.6</th><td><a href="#11.3.6"><code>readonly</code></a></td></tr>
+ <tr><th>11.3.7</th><td><a href="#11.3.7"><code>unordered</code></a></td></tr>
+ <tr><th>11.3.8</th><td><a href="#11.3.8"><code>index_type</code></a></td></tr>
+ <tr><th>11.3.9</th><td><a href="#11.3.9"><code>key_type</code></a></td></tr>
+ <tr><th>11.3.10</th><td><a href="#11.3.10"><code>value_type</code></a></td></tr>
+ <tr><th>11.3.11</th><td><a href="#11.3.11"><code>value_null</code>/<code>value_not_null</code></a></td></tr>
+ <tr><th>11.3.12</th><td><a href="#11.3.12"><code>id_options</code></a></td></tr>
+ <tr><th>11.3.13</th><td><a href="#11.3.13"><code>index_options</code></a></td></tr>
+ <tr><th>11.3.14</th><td><a href="#11.3.14"><code>key_options</code></a></td></tr>
+ <tr><th>11.3.15</th><td><a href="#11.3.15"><code>value_options</code></a></td></tr>
+ <tr><th>11.3.16</th><td><a href="#11.3.16"><code>id_column</code></a></td></tr>
+ <tr><th>11.3.17</th><td><a href="#11.3.17"><code>index_column</code></a></td></tr>
+ <tr><th>11.3.18</th><td><a href="#11.3.18"><code>key_column</code></a></td></tr>
+ <tr><th>11.3.19</th><td><a href="#11.3.19"><code>value_column</code></a></td></tr>
</table>
</td>
</tr>
@@ -488,21 +490,22 @@ for consistency.
<tr><th>11.4.7</th><td><a href="#11.4.7"><code>column</code> (object, composite value)</a></td></tr>
<tr><th>11.4.8</th><td><a href="#11.4.8"><code>column</code> (view)</a></td></tr>
<tr><th>11.4.9</th><td><a href="#11.4.9"><code>transient</code></a></td></tr>
- <tr><th>11.4.10</th><td><a href="#11.4.10"><code>inverse</code></a></td></tr>
- <tr><th>11.4.11</th><td><a href="#11.4.11"><code>unordered</code></a></td></tr>
- <tr><th>11.4.12</th><td><a href="#11.4.12"><code>table</code></a></td></tr>
- <tr><th>11.4.13</th><td><a href="#11.4.13"><code>index_type</code></a></td></tr>
- <tr><th>11.4.14</th><td><a href="#11.4.14"><code>key_type</code></a></td></tr>
- <tr><th>11.4.15</th><td><a href="#11.4.15"><code>value_type</code></a></td></tr>
- <tr><th>11.4.16</th><td><a href="#11.4.16"><code>value_null</code>/<code>value_not_null</code></a></td></tr>
- <tr><th>11.4.17</th><td><a href="#11.4.17"><code>id_options</code></a></td></tr>
- <tr><th>11.4.18</th><td><a href="#11.4.18"><code>index_options</code></a></td></tr>
- <tr><th>11.4.19</th><td><a href="#11.4.19"><code>key_options</code></a></td></tr>
- <tr><th>11.4.20</th><td><a href="#11.4.20"><code>value_options</code></a></td></tr>
- <tr><th>11.4.21</th><td><a href="#11.4.21"><code>id_column</code></a></td></tr>
- <tr><th>11.4.22</th><td><a href="#11.4.22"><code>index_column</code></a></td></tr>
- <tr><th>11.4.23</th><td><a href="#11.4.23"><code>key_column</code></a></td></tr>
- <tr><th>11.4.24</th><td><a href="#11.4.24"><code>value_column</code></a></td></tr>
+ <tr><th>11.4.10</th><td><a href="#11.4.10"><code>readonly</code></a></td></tr>
+ <tr><th>11.4.11</th><td><a href="#11.4.11"><code>inverse</code></a></td></tr>
+ <tr><th>11.4.12</th><td><a href="#11.4.12"><code>unordered</code></a></td></tr>
+ <tr><th>11.4.13</th><td><a href="#11.4.13"><code>table</code></a></td></tr>
+ <tr><th>11.4.14</th><td><a href="#11.4.14"><code>index_type</code></a></td></tr>
+ <tr><th>11.4.15</th><td><a href="#11.4.15"><code>key_type</code></a></td></tr>
+ <tr><th>11.4.16</th><td><a href="#11.4.16"><code>value_type</code></a></td></tr>
+ <tr><th>11.4.17</th><td><a href="#11.4.17"><code>value_null</code>/<code>value_not_null</code></a></td></tr>
+ <tr><th>11.4.18</th><td><a href="#11.4.18"><code>id_options</code></a></td></tr>
+ <tr><th>11.4.19</th><td><a href="#11.4.19"><code>index_options</code></a></td></tr>
+ <tr><th>11.4.20</th><td><a href="#11.4.20"><code>key_options</code></a></td></tr>
+ <tr><th>11.4.21</th><td><a href="#11.4.21"><code>value_options</code></a></td></tr>
+ <tr><th>11.4.22</th><td><a href="#11.4.22"><code>id_column</code></a></td></tr>
+ <tr><th>11.4.23</th><td><a href="#11.4.23"><code>index_column</code></a></td></tr>
+ <tr><th>11.4.24</th><td><a href="#11.4.24"><code>key_column</code></a></td></tr>
+ <tr><th>11.4.25</th><td><a href="#11.4.25"><code>value_column</code></a></td></tr>
</table>
</td>
</tr>
@@ -2959,6 +2962,25 @@ db.update (from);
t.commit ();
</pre>
+ <p>In ODB persistent classes, composite value types, as well as individual
+ data members can be declared read-only (see <a href="#11.1.4">Section
+ 11.1.4, "<code>readonly</code> (object)"</a>, <a href="#11.3.6">Section
+ 11.3.6, "<code>readonly</code> (composite value)"</a>, and
+ <a href="#11.4.10">Section 11.4.10, "<code>readonly</code>
+ (data member)"</a>).</p>
+
+ <p>If an individual data member is declared read-only, then
+ any changes to this member will be ignored when updating the database
+ state of an object using any of the above <code>update()</code>
+ functions. A <code>const</code> data member is automatically treated
+ as read-only. If a composite value is declared read-only then all its
+ data members are treated as read-only.</p>
+
+ <p>If the whole object is declared read-only then the database state of
+ this object cannot be changed. Calling any of the above
+ <code>update()</code> functions for such an object will result in a
+ compile-time error.</p>
+
<h2><a name="3.10">3.10 Deleting Persistent Objects</a></h2>
<p>To delete a persistent object's state from the database we use the
@@ -4033,8 +4055,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&nbsp;unordered</code> pragma (<a href="#11.3.6">Section 11.3.6,
- "<code>unordered</code>"</a>, <a href="#11.4.11">Section 11.4.11,
+ <code>db&nbsp;unordered</code> pragma (<a href="#11.3.7">Section 11.3.7,
+ "<code>unordered</code>"</a>, <a href="#11.4.12">Section 11.4.12,
"<code>unordered</code>"</a>). For example:</p>
<pre class="c++">
@@ -4287,8 +4309,8 @@ class employee
use the <code>not_null</code> pragma (<a href="#11.4.4">Section
11.4.4, "<code>null</code>/<code>not_null</code>"</a>) for
single object pointers and the <code>value_not_null</code> pragma
- (<a href="#11.4.16">Section
- 11.4.16, "<code>value_null</code>/<code>value_not_null</code>"</a>)
+ (<a href="#11.4.17">Section
+ 11.4.17, "<code>value_null</code>/<code>value_not_null</code>"</a>)
for containers of object pointers. For example:</p>
<pre class="c++">
@@ -4657,7 +4679,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="#11.4.10">Section 11.4.10,
+ <code>inverse</code> pragma (<a href="#11.4.11">Section 11.4.11,
"<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>
@@ -4701,7 +4723,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="#11.4.11">Section 11.4.11, "<code>unordered</code>"</a>)
+ (<a href="#11.4.12">Section 11.4.12, "<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>
@@ -5506,9 +5528,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&nbsp;column</code>, either the <code>db&nbsp;value_column</code>
- (<a href="#11.4.24">Section 11.4.24, "<code>value_column</code>"</a>) or
+ (<a href="#11.4.25">Section 11.4.25, "<code>value_column</code>"</a>) or
<code>db&nbsp;key_column</code>
- (<a href="#11.4.23">Section 11.4.23, "<code>key_column</code>"</a>)
+ (<a href="#11.4.24">Section 11.4.24, "<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
@@ -5552,8 +5574,8 @@ CREATE TABLE person (
</pre>
<p>To customize the container table name we can use the
- <code>db&nbsp;table</code> pragma (<a href="#11.4.12">Section
- 11.4.12, "<code>table</code>"</a>), for example:</p>
+ <code>db&nbsp;table</code> pragma (<a href="#11.4.13">Section
+ 11.4.13, "<code>table</code>"</a>), for example:</p>
<pre class="c++">
#pragma db value
@@ -7461,9 +7483,15 @@ class person
</tr>
<tr>
+ <td><code>readonly</code></td>
+ <td>persistent class is read-only</td>
+ <td><a href="#11.1.4">11.1.4</a></td>
+ </tr>
+
+ <tr>
<td><code>callback</code></td>
<td>database operations callback</td>
- <td><a href="#11.1.4">11.1.4</a></td>
+ <td><a href="#11.1.5">11.1.5</a></td>
</tr>
</table>
@@ -7567,7 +7595,36 @@ class contractor: public person
discussion of persistent class inheritance, refer to
<a href="#8">Chapter 8, "Inheritance"</a>.</p>
- <h3><a name="11.1.4">11.1.4 <code>callback</code></a></h3>
+ <h3><a name="11.1.4">11.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
+ updated. In particular, this means that you cannot call the
+ <code>database::update()</code> function (<a href="#3.9">Section 3.9,
+ "Updating Persistent Objects"</a>) for such objects. For example:</p>
+
+ <pre class="c++">
+#pragma db object readonly
+class person
+{
+ ...
+};
+ </pre>
+
+ <p>Read-only and read-write objects can derive from each other without
+ any restrictions. When a read-only object derives from a read-write
+ object, the resulting whole object is read-only, including the part
+ corresponding to the read-write base. On the other hand, when a
+ read-write object derives from a read-only object, all the data
+ members that correspond to the read-only base are treated as
+ 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="#11.4.10">Section 11.4.10, "<code>readonly</code>"</a>)
+ as well as composite value types (<a href="#11.3.6">Section 11.3.6,
+ "<code>readonly</code>"</a>) as read-only.</p>
+
+ <h3><a name="11.1.5">11.1.5 <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
@@ -7776,7 +7833,7 @@ private:
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="#11.1.4">Section 11.1.4, "<code>callback</code>"</a>)
+ (<a href="#11.1.5">Section 11.1.5, "<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>
@@ -7827,81 +7884,87 @@ private:
</tr>
<tr>
+ <td><code>readonly</code></td>
+ <td>composite value type is read-only</td>
+ <td><a href="#11.3.6">11.3.6</a></td>
+ </tr>
+
+ <tr>
<td><code>unordered</code></td>
<td>ordered container should be stored unordered</td>
- <td><a href="#11.3.6">11.3.6</a></td>
+ <td><a href="#11.3.7">11.3.7</a></td>
</tr>
<tr>
<td><code>index_type</code></td>
<td>database type for a container's index type</td>
- <td><a href="#11.3.7">11.3.7</a></td>
+ <td><a href="#11.3.8">11.3.8</a></td>
</tr>
<tr>
<td><code>key_type</code></td>
<td>database type for a container's key type</td>
- <td><a href="#11.3.8">11.3.8</a></td>
+ <td><a href="#11.3.9">11.3.9</a></td>
</tr>
<tr>
<td><code>value_type</code></td>
<td>database type for a container's value type</td>
- <td><a href="#11.3.9">11.3.9</a></td>
+ <td><a href="#11.3.10">11.3.10</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="#11.3.10">11.3.10</a></td>
+ <td><a href="#11.3.11">11.3.11</a></td>
</tr>
<tr>
<td><code>id_options</code></td>
<td>database options for a container's id column</td>
- <td><a href="#11.3.11">11.3.11</a></td>
+ <td><a href="#11.3.12">11.3.12</a></td>
</tr>
<tr>
<td><code>index_options</code></td>
<td>database options for a container's index column</td>
- <td><a href="#11.3.12">11.3.12</a></td>
+ <td><a href="#11.3.13">11.3.13</a></td>
</tr>
<tr>
<td><code>key_options</code></td>
<td>database options for a container's key column</td>
- <td><a href="#11.3.13">11.3.13</a></td>
+ <td><a href="#11.3.14">11.3.14</a></td>
</tr>
<tr>
<td><code>value_options</code></td>
<td>database options for a container's value column</td>
- <td><a href="#11.3.14">11.3.14</a></td>
+ <td><a href="#11.3.15">11.3.15</a></td>
</tr>
<tr>
<td><code>id_column</code></td>
<td>column name for a container's object id</td>
- <td><a href="#11.3.15">11.3.15</a></td>
+ <td><a href="#11.3.16">11.3.16</a></td>
</tr>
<tr>
<td><code>index_column</code></td>
<td>column name for a container's index</td>
- <td><a href="#11.3.16">11.3.16</a></td>
+ <td><a href="#11.3.17">11.3.17</a></td>
</tr>
<tr>
<td><code>key_column</code></td>
<td>column name for a container's key</td>
- <td><a href="#11.3.17">11.3.17</a></td>
+ <td><a href="#11.3.18">11.3.18</a></td>
</tr>
<tr>
<td><code>value_column</code></td>
<td>column name for a container's value</td>
- <td><a href="#11.3.18">11.3.18</a></td>
+ <td><a href="#11.3.19">11.3.19</a></td>
</tr>
</table>
@@ -8116,7 +8179,37 @@ class person
data member (<a href="#11.4.6">Section 11.4.6,
"<code>options</code>"</a>).</p>
- <h3><a name="11.3.6">11.3.6 <code>unordered</code></a></h3>
+ <h3><a name="11.3.6">11.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
+ composite value type are ignored when updating the database
+ state of an object (<a href="#3.9">Section 3.9, "Updating Persistent
+ Objects"</a>) containing such a value type. Note that this specifier
+ is only valid for composite value types. For example:</p>
+
+ <pre class="c++">
+#pragma db value readonly
+class person_name
+{
+ ...
+};
+ </pre>
+
+ <p>Read-only and read-write composite values can derive from each other
+ without any restrictions. When a read-only value derives from a
+ read-write value, the resulting whole value is read-only, including
+ the part corresponding to the read-write base. On the other hand, when a
+ read-write value derives from a read-only value, all the data
+ members that correspond to the read-only base are treated as
+ 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="#11.4.10">Section 11.4.10, "<code>readonly</code>"</a>)
+ as well as whole objects (<a href="#11.1.4">Section 11.1.4,
+ "<code>readonly</code>"</a>) as read-only.</p>
+
+ <h3><a name="11.3.7">11.3.7 <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
@@ -8133,7 +8226,7 @@ typedef std::vector&lt;std::string> names;
storage in the database, refer to <a href="#5.1">Section 5.1,
"Ordered Containers"</a>.</p>
- <h3><a name="11.3.7">11.3.7 <code>index_type</code></a></h3>
+ <h3><a name="11.3.8">11.3.8 <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
@@ -8147,7 +8240,7 @@ typedef std::vector&lt;std::string> names;
#pragma db value(names) index_type("SMALLINT UNSIGNED")
</pre>
- <h3><a name="11.3.8">11.3.8 <code>key_type</code></a></h3>
+ <h3><a name="11.3.9">11.3.9 <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
@@ -8161,7 +8254,7 @@ typedef std::map&lt;unsigned short, float> age_weight_map;
#pragma db value(age_weight_map) key_type("INT UNSIGNED")
</pre>
- <h3><a name="11.3.9">11.3.9 <code>value_type</code></a></h3>
+ <h3><a name="11.3.10">11.3.10 <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
@@ -8176,11 +8269,11 @@ typedef std::vector&lt;std::string> names;
</pre>
<p>The <code>value_null</code> and <code>value_not_null</code>
- (<a href="#11.3.10">Section 11.3.10,
+ (<a href="#11.3.11">Section 11.3.11,
"<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="11.3.10">11.3.10 <code>value_null</code>/<code>value_not_null</code></a></h3>
+ <h3><a name="11.3.11">11.3.11 <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 type's element value can or cannot be
@@ -8208,7 +8301,7 @@ typedef std::vector&lt;shared_ptr&lt;account> > accounts;
as not allowing a <code>NULL</code> value.</p>
- <h3><a name="11.3.11">11.3.11 <code>id_options</code></a></h3>
+ <h3><a name="11.3.12">11.3.12 <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
@@ -8221,11 +8314,11 @@ typedef std::vector&lt;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="#11.4.17">Section 11.4.17,
+ a container data member (<a href="#11.4.18">Section 11.4.18,
"<code>id_options</code>"</a>).</p>
- <h3><a name="11.3.12">11.3.12 <code>index_options</code></a></h3>
+ <h3><a name="11.3.13">11.3.13 <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
@@ -8238,11 +8331,11 @@ typedef std::vector&lt;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="#11.4.18">Section 11.4.18,
+ a container data member (<a href="#11.4.19">Section 11.4.19,
"<code>index_options</code>"</a>).</p>
- <h3><a name="11.3.13">11.3.13 <code>key_options</code></a></h3>
+ <h3><a name="11.3.14">11.3.14 <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
@@ -8255,11 +8348,11 @@ typedef std::map&lt;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="#11.4.19">Section 11.4.19,
+ a container data member (<a href="#11.4.20">Section 11.4.20,
"<code>key_options</code>"</a>).</p>
- <h3><a name="11.3.14">11.3.14 <code>value_options</code></a></h3>
+ <h3><a name="11.3.15">11.3.15 <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
@@ -8272,11 +8365,11 @@ typedef std::set&lt;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="#11.4.20">Section 11.4.20,
+ a container data member (<a href="#11.4.21">Section 11.4.21,
"<code>value_options</code>"</a>).</p>
- <h3><a name="11.3.15">11.3.15 <code>id_column</code></a></h3>
+ <h3><a name="11.3.16">11.3.16 <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
@@ -8290,7 +8383,7 @@ typedef std::vector&lt;std::string> names;
<p>If the column name is not specified, then <code>object_id</code>
is used by default.</p>
- <h3><a name="11.3.16">11.3.16 <code>index_column</code></a></h3>
+ <h3><a name="11.3.17">11.3.17 <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
@@ -8304,7 +8397,7 @@ typedef std::vector&lt;std::string> names;
<p>If the column name is not specified, then <code>index</code>
is used by default.</p>
- <h3><a name="11.3.17">11.3.17 <code>key_column</code></a></h3>
+ <h3><a name="11.3.18">11.3.18 <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
@@ -8318,7 +8411,7 @@ typedef std::map&lt;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="11.3.18">11.3.18 <code>value_column</code></a></h3>
+ <h3><a name="11.3.19">11.3.19 <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
@@ -8405,93 +8498,99 @@ typedef std::map&lt;unsigned short, float> age_weight_map;
</tr>
<tr>
+ <td><code>readonly</code></td>
+ <td>member is read-only</td>
+ <td><a href="#11.4.10">11.4.10</a></td>
+ </tr>
+
+ <tr>
<td><code>inverse</code></td>
<td>member is an inverse side of a bidirectional relationship</td>
- <td><a href="#11.4.10">11.4.10</a></td>
+ <td><a href="#11.4.11">11.4.11</a></td>
</tr>
<tr>
<td><code>unordered</code></td>
<td>ordered container should be stored unordered</td>
- <td><a href="#11.4.11">11.4.11</a></td>
+ <td><a href="#11.4.12">11.4.12</a></td>
</tr>
<tr>
<td><code>table</code></td>
<td>table name for a container</td>
- <td><a href="#11.4.12">11.4.12</a></td>
+ <td><a href="#11.4.13">11.4.13</a></td>
</tr>
<tr>
<td><code>index_type</code></td>
<td>database type for a container's index type</td>
- <td><a href="#11.4.13">11.4.13</a></td>
+ <td><a href="#11.4.14">11.4.14</a></td>
</tr>
<tr>
<td><code>key_type</code></td>
<td>database type for a container's key type</td>
- <td><a href="#11.4.14">11.4.14</a></td>
+ <td><a href="#11.4.15">11.4.15</a></td>
</tr>
<tr>
<td><code>value_type</code></td>
<td>database type for a container's value type</td>
- <td><a href="#11.4.15">11.4.15</a></td>
+ <td><a href="#11.4.16">11.4.16</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="#11.4.16">11.4.16</a></td>
+ <td><a href="#11.4.17">11.4.17</a></td>
</tr>
<tr>
<td><code>id_options</code></td>
<td>database options for a container's id column</td>
- <td><a href="#11.4.17">11.4.17</a></td>
+ <td><a href="#11.4.18">11.4.18</a></td>
</tr>
<tr>
<td><code>index_options</code></td>
<td>database options for a container's index column</td>
- <td><a href="#11.4.18">11.4.18</a></td>
+ <td><a href="#11.4.19">11.4.19</a></td>
</tr>
<tr>
<td><code>key_options</code></td>
<td>database options for a container's key column</td>
- <td><a href="#11.4.19">11.4.19</a></td>
+ <td><a href="#11.4.20">11.4.20</a></td>
</tr>
<tr>
<td><code>value_options</code></td>
<td>database options for a container's value column</td>
- <td><a href="#11.4.20">11.4.20</a></td>
+ <td><a href="#11.4.21">11.4.21</a></td>
</tr>
<tr>
<td><code>id_column</code></td>
<td>column name for a container's object id</td>
- <td><a href="#11.4.21">11.4.21</a></td>
+ <td><a href="#11.4.22">11.4.22</a></td>
</tr>
<tr>
<td><code>index_column</code></td>
<td>column name for a container's index</td>
- <td><a href="#11.4.22">11.4.22</a></td>
+ <td><a href="#11.4.23">11.4.23</a></td>
</tr>
<tr>
<td><code>key_column</code></td>
<td>column name for a container's key</td>
- <td><a href="#11.4.23">11.4.23</a></td>
+ <td><a href="#11.4.24">11.4.24</a></td>
</tr>
<tr>
<td><code>value_column</code></td>
<td>column name for a container's value</td>
- <td><a href="#11.4.24">11.4.24</a></td>
+ <td><a href="#11.4.25">11.4.25</a></td>
</tr>
</table>
@@ -8857,7 +8956,100 @@ 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="11.4.10">11.4.10 <code>inverse</code></a></h3>
+ <h3><a name="11.4.10">11.4.10 <code>readonly</code></a></h3>
+
+ <p>The <code>readonly</code> specifier specifies that a data member of
+ an object or composite value type is read-only. Changes to a read-only
+ data member are ignored when updating the database state of an object
+ (<a href="#3.9">Section 3.9, "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="#11.4.1">Section 11.4.1, "<code>id</code>"</a>)
+ and inverse (<a href="#11.4.11">Section 11.4.11,
+ "<code>inverse</code>"</a>) data members are automatically treated
+ as read-only and must not be explicitly declared as such. For
+ example:</p>
+
+ <pre class="c++">
+#pragma db object
+class person
+{
+ ...
+
+ #pragma db readonly
+ date born_;
+};
+ </pre>
+
+ <p>Besides simple value members, object pointer, container, and composite
+ value members can also be declared read-only. A change of a pointed-to
+ object is ignored when updating the state of a read-only object
+ pointer. Similarly, any changes to the number or order of
+ elements or to the element values themselves are ignored when
+ updating the state of a read-only container. Finally, any changes
+ to the members of a read-only composite value type are also ignored
+ when updating the state of such a composite value.</p>
+
+ <p>ODB automatically treats <code>const</code> data members as read-only.
+ For example, the following <code>person</code> object is equivalent
+ to the above declaration for the database persistence purposes:</p>
+
+ <pre class="c++">
+#pragma db object
+class person
+{
+ ...
+
+ const date born_; // Automatically read-only.
+};
+ </pre>
+
+ <p>When declaring an object pointer <code>const</code>, make sure to
+ declare the pointer as <code>const</code> rather than (or in addition
+ to) the object itself. For example:</p>
+
+ <pre class="c++">
+#pragma db object
+class person
+{
+ ...
+
+ const person* father_; // Read-write pointer to a read-only object.
+ person* const mother_; // Read-only pointer to a read-write object.
+};
+ </pre>
+
+ <p>Note that in case of a wrapper type (<a href="#7.3">Section 7.3,
+ "Pointers and <code>NULL</code> Value Semantics"</a>), both the
+ wrapper and the wrapped type must be <code>const</code> in
+ order for the ODB compiler to automatically treat the data
+ member as read-only. For example:</p>
+
+ <pre class="c++">
+#pragma db object
+class person
+{
+ ...
+
+ const std::auto_ptr&lt;const date> born_;
+};
+ </pre>
+
+ <p>Read-only members are useful when dealing with
+ asynchronous changes to the state of a data member in the
+ database which should not be overwritten. In other cases,
+ where the state of a data member never changes, declaring such a member
+ read-only allows ODB to perform more efficient object updates.
+ In such cases, however, it is conceptually more correct to
+ declare such a data member as <code>const</code> rather than
+ as read-only.</p>
+
+ <p>Note that it is also possible to declare composite value types
+ (<a href="#11.3.6">Section 11.3.6, "<code>readonly</code>"</a>)
+ as well as whole objects (<a href="#11.1.4">Section 11.1.4,
+ "<code>readonly</code>"</a>) as read-only.</p>
+
+ <h3><a name="11.4.11">11.4.11 <code>inverse</code></a></h3>
<p>The <code>inverse</code> specifier specifies that a data member of
an object pointer or a container of object pointers type is an
@@ -8895,12 +9087,12 @@ 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="#11.4.11">Section 11.4.11, "<code>unordered</code>"</a>).</p>
+ (<a href="#11.4.12">Section 11.4.12, "<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="11.4.11">11.4.11 <code>unordered</code></a></h3>
+ <h3><a name="11.4.12">11.4.12 <code>unordered</code></a></h3>
<p>The <code>unordered</code> specifier specifies that a member of
an ordered container type should be stored unordered in the database.
@@ -8923,7 +9115,7 @@ class person
storage in the database, refer to <a href="#5.1">Section 5.1,
"Ordered Containers"</a>.</p>
- <h3><a name="11.4.12">11.4.12 <code>table</code></a></h3>
+ <h3><a name="11.4.13">11.4.13 <code>table</code></a></h3>
<p>The <code>table</code> specifier specifies the table name that should
be used to store the contents of a container member. For example:</p>
@@ -8953,7 +9145,7 @@ class person
to <a href="#7.2.1">Section 7.2.1, "Composite Value Column and Table
Names"</a> for details.</p>
- <h3><a name="11.4.13">11.4.13 <code>index_type</code></a></h3>
+ <h3><a name="11.4.14">11.4.14 <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
@@ -8973,7 +9165,7 @@ class person
};
</pre>
- <h3><a name="11.4.14">11.4.14 <code>key_type</code></a></h3>
+ <h3><a name="11.4.15">11.4.15 <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
@@ -8993,7 +9185,7 @@ class person
};
</pre>
- <h3><a name="11.4.15">11.4.15 <code>value_type</code></a></h3>
+ <h3><a name="11.4.16">11.4.16 <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
@@ -9014,11 +9206,11 @@ class person
</pre>
<p>The <code>value_null</code> and <code>value_not_null</code>
- (<a href="#11.4.16">Section 11.4.16,
+ (<a href="#11.4.17">Section 11.4.17,
"<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="11.4.16">11.4.16 <code>value_null</code>/<code>value_not_null</code></a></h3>
+ <h3><a name="11.4.17">11.4.17 <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 a data member can or
@@ -9051,7 +9243,7 @@ class account
Multiset Containers"</a>) the element value is automatically treated
as not allowing a <code>NULL</code> value.</p>
- <h3><a name="11.4.17">11.4.17 <code>id_options</code></a></h3>
+ <h3><a name="11.4.18">11.4.18 <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
@@ -9075,7 +9267,7 @@ class person
of the <code>options</code> specifier (<a href="#11.4.6">Section
11.4.6, "<code>options</code>"</a>).</p>
- <h3><a name="11.4.18">11.4.18 <code>index_options</code></a></h3>
+ <h3><a name="11.4.19">11.4.19 <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
@@ -9096,7 +9288,7 @@ class person
of the <code>options</code> specifier (<a href="#11.4.6">Section
11.4.6, "<code>options</code>"</a>).</p>
- <h3><a name="11.4.19">11.4.19 <code>key_options</code></a></h3>
+ <h3><a name="11.4.20">11.4.20 <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
@@ -9117,7 +9309,7 @@ class person
of the <code>options</code> specifier (<a href="#11.4.6">Section
11.4.6, "<code>options</code>"</a>).</p>
- <h3><a name="11.4.20">11.4.20 <code>value_options</code></a></h3>
+ <h3><a name="11.4.21">11.4.21 <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
@@ -9138,7 +9330,7 @@ class person
of the <code>options</code> specifier (<a href="#11.4.6">Section
11.4.6, "<code>options</code>"</a>).</p>
- <h3><a name="11.4.21">11.4.21 <code>id_column</code></a></h3>
+ <h3><a name="11.4.22">11.4.22 <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
@@ -9162,7 +9354,7 @@ class person
<p>If the column name is not specified, then <code>object_id</code>
is used by default.</p>
- <h3><a name="11.4.22">11.4.22 <code>index_column</code></a></h3>
+ <h3><a name="11.4.23">11.4.23 <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
@@ -9186,7 +9378,7 @@ class person
<p>If the column name is not specified, then <code>index</code>
is used by default.</p>
- <h3><a name="11.4.23">11.4.23 <code>key_column</code></a></h3>
+ <h3><a name="11.4.24">11.4.24 <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
@@ -9210,7 +9402,7 @@ class person
<p>If the column name is not specified, then <code>key</code>
is used by default.</p>
- <h3><a name="11.4.24">11.4.24 <code>value_column</code></a></h3>
+ <h3><a name="11.4.25">11.4.25 <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