aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-11-29 07:30:58 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-11-30 15:54:07 +0200
commit7667f1698142e0a5ced34e6e5c73a08de00bd861 (patch)
tree46fc3c99ae5e89eb45d03570f2f6ce6343cfea21
parenteb2ec682e3f79b20dbda5f3e8b0e4c0b567dfc66 (diff)
Document Oracle support
-rw-r--r--doc/manual.xhtml876
1 files changed, 832 insertions, 44 deletions
diff --git a/doc/manual.xhtml b/doc/manual.xhtml
index 6706322..a9f380f 100644
--- a/doc/manual.xhtml
+++ b/doc/manual.xhtml
@@ -598,25 +598,46 @@ for consistency.
</tr>
<tr>
+ <th>16</th><td><a href="#16">Oracle Database</a>
+ <table class="toc">
+ <tr><th>16.1</th><td><a href="#16.1">Oracle Type Mapping</a></td></tr>
+ <tr><th>16.2</th><td><a href="#16.2">Oracle Database Class</a></td></tr>
+ <tr><th>16.3</th><td><a href="#16.3">Oracle Connection and Connection Factory</a></td></tr>
+ <tr><th>16.4</th><td><a href="#16.4">Oracle Exceptions</a></td></tr>
+ <tr>
+ <th>16.5</th><td><a href="#16.5">Oracle 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">Timezones</a></td></tr>
+ <tr><th>16.5.3</th><td><a href="#16.5.3"><code>NUMERIC</code> Type Support</a></td></tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
<th colspan="2"><a href="#III">PART III PROFILES</a></th>
</tr>
<tr>
- <th>16</th><td><a href="#16">Profiles Introduction</a></td>
+ <th>17</th><td><a href="#17">Profiles Introduction</a></td>
</tr>
<tr>
- <th>17</th><td><a href="#17">Boost Profile</a>
+ <th>18</th><td><a href="#18">Boost Profile</a>
<table class="toc">
- <tr><th>17.1</th><td><a href="#17.1">Smart Pointers Library</a></td></tr>
- <tr><th>17.2</th><td><a href="#17.2">Unordered Containers Library</a></td></tr>
- <tr><th>17.3</th><td><a href="#17.3">Optional Library</a></td></tr>
+ <tr><th>18.1</th><td><a href="#18.1">Smart Pointers Library</a></td></tr>
+ <tr><th>18.2</th><td><a href="#18.2">Unordered Containers Library</a></td></tr>
+ <tr><th>18.3</th><td><a href="#18.3">Optional Library</a></td></tr>
<tr>
- <th>17.4</th><td><a href="#17.4">Date Time Library</a>
+ <th>18.4</th><td><a href="#18.4">Date Time Library</a>
<table class="toc">
- <tr><th>17.4.1</th><td><a href="#17.4.1">MySQL Database Type Mapping</a></td></tr>
- <tr><th>17.4.2</th><td><a href="#17.4.2">SQLite Database Type Mapping</a></td></tr>
- <tr><th>17.4.3</th><td><a href="#17.4.3">PostgreSQL Database Type Mapping</a></td></tr>
+ <tr><th>18.4.1</th><td><a href="#18.4.1">MySQL Database Type Mapping</a></td></tr>
+ <tr><th>18.4.2</th><td><a href="#18.4.2">SQLite Database Type Mapping</a></td></tr>
+ <tr><th>18.4.3</th><td><a href="#18.4.3">PostgreSQL Database Type Mapping</a></td></tr>
+ <tr><th>18.4.4</th><td><a href="#18.4.4">Oracle Database Type Mapping</a></td></tr>
</table>
</td>
</tr>
@@ -625,25 +646,27 @@ for consistency.
</tr>
<tr>
- <th>18</th><td><a href="#18">Qt Profile</a>
+ <th>19</th><td><a href="#19">Qt Profile</a>
<table class="toc">
<tr>
- <th>18.1</th><td><a href="#18.1">Basic Types Library</a>
+ <th>19.1</th><td><a href="#19.1">Basic Types Library</a>
<table class="toc">
- <tr><th>18.1.1</th><td><a href="#18.1.1">MySQL Database Type Mapping</a></td></tr>
- <tr><th>18.1.2</th><td><a href="#18.1.2">SQLite Database Type Mapping</a></td></tr>
- <tr><th>18.1.3</th><td><a href="#18.1.3">PostgreSQL Database Type Mapping</a></td></tr>
+ <tr><th>19.1.1</th><td><a href="#19.1.1">MySQL Database Type Mapping</a></td></tr>
+ <tr><th>19.1.2</th><td><a href="#19.1.2">SQLite Database Type Mapping</a></td></tr>
+ <tr><th>19.1.3</th><td><a href="#19.1.3">PostgreSQL Database Type Mapping</a></td></tr>
+ <tr><th>19.1.4</th><td><a href="#19.1.4">Oracle Database Type Mapping</a></td></tr>
</table>
</td>
</tr>
- <tr><th>18.2</th><td><a href="#18.2">Smart Pointers Library</a></td></tr>
- <tr><th>18.3</th><td><a href="#18.3">Containers Library</a></td></tr>
+ <tr><th>19.2</th><td><a href="#19.2">Smart Pointers Library</a></td></tr>
+ <tr><th>19.3</th><td><a href="#19.3">Containers Library</a></td></tr>
<tr>
- <th>18.4</th><td><a href="#18.4">Date Time Library</a>
+ <th>19.4</th><td><a href="#19.4">Date Time Library</a>
<table class="toc">
- <tr><th>18.4.1</th><td><a href="#18.4.1">MySQL Database Type Mapping</a></td></tr>
- <tr><th>18.4.2</th><td><a href="#18.4.2">SQLite Database Type Mapping</a></td></tr>
- <tr><th>18.4.3</th><td><a href="#18.4.3">PostgreSQL Database Type Mapping</a></td></tr>
+ <tr><th>19.4.1</th><td><a href="#19.4.1">MySQL Database Type Mapping</a></td></tr>
+ <tr><th>19.4.2</th><td><a href="#19.4.2">SQLite Database Type Mapping</a></td></tr>
+ <tr><th>19.4.3</th><td><a href="#19.4.3">PostgreSQL Database Type Mapping</a></td></tr>
+ <tr><th>19.4.4</th><td><a href="#19.4.4">Oracle Database Type Mapping</a></td></tr>
</table>
</td>
</tr>
@@ -6068,7 +6091,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="#17.3">Section 17.3, "Optional Library"</a>).</p>
+ (<a href="#18.3">Section 18.3, "Optional Library"</a>).</p>
<p>Another common C++ representation of a value that can be
<code>NULL</code> is a pointer. ODB will automatically
@@ -12309,6 +12332,639 @@ SHOW integer_datetimes
store <code>NUMERIC</code> values refer to the PostgreSQL
documentation.</p>
+
+ <!-- CHAPTER -->
+
+
+ <hr class="page-break"/>
+ <h1><a name="16">16 Oracle Database</a></h1>
+
+ <p>To generate support code for the Oracle database you will need
+ to pass the "<code>&#8209;&#8209;database&nbsp;oracle</code>"
+ (or "<code>&#8209;d&nbsp;oracle</code>") option to the ODB compiler.
+ Your application will also need to link to the Oracle ODB runtime
+ library (<code>libodb&#8209;oracle</code>). All Oracle-specific ODB
+ classes are defined in the <code>odb::oracle</code> namespace.</p>
+
+ <h2><a name="16.1">16.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
+ Language"</a>).</p>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="mapping" border="1">
+ <tr>
+ <th>C++ Type</th>
+ <th>Oracle Type</th>
+ <th>Default <code>NULL</code> Semantics</th>
+ </tr>
+
+ <tr>
+ <td><code>bool</code></td>
+ <td><code>NUMBER(1)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>char</code></td>
+ <td><code>NUMBER(3)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>signed char</code></td>
+ <td><code>NUMBER(3)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>unsigned char</code></td>
+ <td><code>NUMBER(3)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>short</code></td>
+ <td><code>NUMBER(5)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>unsigned short</code></td>
+ <td><code>NUMBER(5)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>int</code></td>
+ <td><code>NUMBER(10)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>unsigned int</code></td>
+ <td><code>NUMBER(10)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>long</code></td>
+ <td><code>NUMBER(19)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>unsigned long</code></td>
+ <td><code>NUMBER(20)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>long long</code></td>
+ <td><code>NUMBER(19)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>unsigned long long</code></td>
+ <td><code>NUMBER(20)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>float</code></td>
+ <td><code>BINARY_FLOAT</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>double</code></td>
+ <td><code>BINARY_DOUBLE</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>std::string</code></td>
+ <td><code>VARCHAR(4000)</code></td>
+ <td><code>NOT NULL</code></td>
+ </tr>
+ </table>
+
+ <p>The Oracle ODB runtime library also provides support for mapping the
+ <code>std::string</code> type to the Oracle <code>CLOB</code> and
+ <code>NCLOB</code> types, and for mapping the
+ <code>std::vector&lt;char></code>,
+ <code>std::vector&lt;unsigned&nbsp;char></code>,
+ <code>char[N]</code>, and <code>unsigned&nbsp;char[N]</code> types to
+ the Oracle <code>BLOB</code> and <code>RAW</code> types. However, these
+ mappings are not enabled by default (in particular, by default,
+ <code>std::vector</code> will be treated as a container). To enable the
+ non-default mappings for these types we need to specify the database type
+ explicitly using the <code>db&nbsp;type</code> pragma
+ (<a href="#12.4.3">Section 12.4.3, "<code>type</code>"</a>), for
+ example:</p>
+
+ <pre class="c++">
+#pragma db object
+class object
+{
+ ...
+
+ #pragma db type ("CLOB")
+ std::string str_;
+
+ #pragma db type("RAW(256)")
+ std::vector&lt;char> buf_;
+
+ #pragma db type("BLOB")
+ unsigned char[16] uuid_;
+};
+ </pre>
+
+ <p>Alternatively, this can be done on the per-type basis, for example:</p>
+
+ <pre class="c++">
+typedef std::vector&lt;char> buffer;
+#pragma db value(buffer) type("BLOB")
+
+#pragma db object
+class object
+{
+ ...
+
+ buffer buf_; // Mapped to BLOB.
+};
+ </pre>
+
+ <p>Additionally, by default, C++ enumerations are automatically
+ mapped to <code>NUMBER(10)</code> with the default <code>NULL</code>
+ semantics being <code>NOT NULL</code>.</p>
+
+ <h2><a name="16.2">16.2 Oracle Database Class</a></h2>
+
+ <p>The Oracle <code>database</code> class has the following
+ interface:</p>
+
+ <pre class="c++">
+namespace odb
+{
+ namespace oracle
+ {
+ class database: public odb::database
+ {
+ public:
+ database (const std::string&amp; user,
+ const std::string&amp; password,
+ const std::string&amp; db,
+ ub2 charset = 0,
+ ub2 ncharset = 0,
+ OCIEnv* environment = 0,
+ std::auto_ptr&lt;connection_factory> = 0);
+
+ database (const std::string&amp; user,
+ const std::string&amp; password,
+ const std::string&amp; service,
+ const std::string&amp; host = "",
+ unsigned int port = 0,
+ ub2 charset = 0,
+ ub2 ncharset = 0,
+ OCIEnv* environment = 0,
+ std::auto_ptr&lt;connection_factory> = 0);
+
+ database (int&amp; argc,
+ char* argv[],
+ bool erase = false,
+ ub2 charset = 0,
+ ub2 ncharset = 0,
+ OCIEnv* environment = 0,
+ std::auto_ptr&lt;connection_factory> = 0);
+
+ static void
+ print_usage (std::ostream&amp;);
+
+
+ public:
+ const std::string&amp;
+ user () const;
+
+ const std::string&amp;
+ password () const;
+
+ const std::string&amp;
+ db () const;
+
+ const std::string&amp;
+ service () const;
+
+ const std::string&amp;
+ host () const;
+
+ unsigned int
+ port () const;
+
+ ub2
+ charset () const;
+
+ ub2
+ ncharset () const;
+
+ OCIEnv*
+ environment () const;
+
+ public:
+ connection_ptr
+ connection ();
+ };
+ }
+}
+ </pre>
+
+ <p>You will need to include the <code>&lt;odb/oracle/database.hxx></code>
+ header file to make this class available in your application.</p>
+
+ <p>The <code>database</code> class wraps an OCI environment handle, as well
+ as a database connection string and user credentials that can be used to
+ establish a database connection.</p>
+
+ <p>The overloaded <code>database</code> constructors allow us to specify the
+ Oracle database parameters that should be used when connecting to the
+ database. The <code>database</code> argument in the first constructor is a
+ connection identifier that specifies the database to connect to. For more
+ information on the format of the connection identifier, please refer to
+ the Oracle Net Services reference.</p>
+
+ <p>The second constructor allows the components of a connection identifier to
+ be specified individually using the <code>service</code>,
+ <code>host</code>, and <code>port</code> arguments. Specifying an empty
+ host string is equivalent to localhost. Specifying a zero port number
+ indicates that the default port should be used.</p>
+
+ <p>The last constructor extracts the database parameters
+ from the command line. The following options are recognized:</p>
+
+ <pre class="terminal">
+ --user &lt;login>
+ --password &lt;password>
+ --database &lt;name>
+ --service &lt;name>
+ --host &lt;host>
+ --port &lt;integer>
+ --options-file &lt;file>
+ </pre>
+
+ <p>The <code>--options-file</code> option allows us to specify some
+ or all of the database options in a file with each option appearing
+ on a separate line followed by a space and an option value. Note that it
+ is invalid to specify the <code>&#8209;&#8209;database</code> option
+ together with any of <code>&#8209;&#8209;service</code>,
+ <code>&#8209;&#8209;host</code>, or <code>&#8209;&#8209;port</code>
+ options.</p>
+
+ <p>If the <code>erase</code> argument to this constructor is true,
+ then the above options are removed from the <code>argv</code>
+ array and the <code>argc</code> count is updated accordingly.
+ This is primarily useful if your application accepts other
+ options or arguments and you would like to get the Oracle
+ options out of the <code>argv</code> array.</p>
+
+ <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="#16.4">Section 16.4, "Oracle Exceptions"</a> for more
+ information on this exception.</p>
+
+ <p>The static <code>print_usage()</code> function prints the list of options
+ with short descriptions that are recognized by this constructor.</p>
+
+ <p>All the constructors take <code>charset</code> and <code>ncharset</code>
+ arguments. These specify the client database character set and client
+ national character set, respectively.</p>
+
+ <p>Additionally, each constructor takes an <code>environment</code> argument
+ which is an OCI environment handle. If the handle is
+ non-<code>NULL</code>, it is used for all OCI function calls made against
+ the <code>database</code> instance that require an environment handle. The
+ <code>database</code> instance does not take ownership of this handle,
+ and it should be released by the user when it is no longer needed. The
+ <code>charset</code> and <code>ncharset</code> arguments are ignored if
+ the <code>environment</code> argument is non-<code>NULL</code>.</p>
+
+ <p>The last argument to all of the constructors is a pointer to a
+ connection factory. If we pass a non-<code>NULL</code> value, the
+ database instance assumes ownership of the factory instance. The
+ connection factory interface as well as the available implementations
+ are described in the next section.</p>
+
+ <p>The set of accessor functions following the constructors allows us
+ to query the parameters of the <code>database</code> instance.</p>
+
+ <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="#16.3">Section
+ 16.3, "Oracle Connection and Connection Factory"</a>.</p>
+
+ <h2><a name="16.3">16.3 Oracle Connection and Connection Factory</a></h2>
+
+ <p>The <code>oracle::connection</code> class has the following interface:</p>
+
+ <pre class="c++">
+namespace odb
+{
+ namespace oracle
+ {
+ class connection: public odb::connection
+ {
+ public:
+ connection (database&amp;);
+ connection (database&amp;, OCISvcCtx*);
+
+ OCISvcCtx*
+ handle ();
+
+ OCIError*
+ error_handle ();
+
+ details::buffer&amp;
+ lob_buffer ();
+ };
+
+ typedef details::shared_ptr&lt;connection> connection_ptr;
+ }
+}
+ </pre>
+
+ <p>For more information on the <code>odb::connection</code> interface, refer
+ to <a href="#3.5">Section 3.5, "Connections"</a>. The first overloaded
+ <code>oracle::connection</code> constructor creates a new Oracle service
+ context. Statement caching is enabled for the underlying session.
+ Connection pooling and session pooling are not utilized. The second
+ constructor allows us to create a <code>connection</code> instance by
+ providing an already connected Oracle service context. Note that the
+ <code>connection</code> instance assumes ownership of this handle. The
+ <code>handle()</code> accessor returns the Oracle service context handle
+ associated with the connection.</p>
+
+ <p>An Oracle error handle is allocated for each <code>connection</code>
+ instance. This handle is publicly available via the
+ <code>error_handle()</code> accessor. Its lifetime is managed by, and
+ must remain valid for the entire lifetime of its containing
+ <code>connection</code> instance.</p>
+
+ <p>Finally, each <code>connection</code> instance maintains a LOB buffer.
+ This buffer is used as intermediate storage between the OCI and ODB
+ implementations, and allows for piecewise handling of LOB data. The
+ buffer capacity may be optionaly set using the <code>lob_buffer()</code>
+ accessor. If the capacity is not explicitly set, the buffer occupies zero
+ bytes until it is used for the first time, at which point 4096 bytes of
+ space is allocated.</p>
+
+ <p>The <code>oracle::connection_factory</code> abstract class has the
+ following interface:</p>
+
+ <pre class="c++">
+namespace odb
+{
+ namespace oracle
+ {
+ class connection_factory
+ {
+ public:
+ virtual void
+ database (database&amp;) = 0;
+
+ virtual connection_ptr
+ connect () = 0;
+ };
+ }
+}
+ </pre>
+
+ <p>The <code>database()</code> function is called when a connection
+ factory is associated with a database instance. This happens in
+ the <code>odb::oracle::database</code> class constructors. The
+ <code>connect()</code> function is called whenever a database
+ connection is requested.</p>
+
+ <p>The two implementations of the <code>connection_factory</code>
+ interface provided by the Oracle ODB runtime are
+ <code>new_connection_factory</code> and
+ <code>connection_pool_factory</code>. You will need to include
+ the <code>&lt;odb/oracle/connection-factory.hxx></code>
+ header file to make the <code>connection_factory</code> interface
+ and these implementation classes available in your application.</p>
+
+ <p>The <code>new_connection_factory</code> class creates a new
+ connection whenever one is requested. When a connection is no
+ longer needed, it is released and closed. The
+ <code>new_connection_factory</code> class has the following
+ interface:</p>
+
+ <pre class="c++">
+namespace odb
+{
+ namespace oracle
+ {
+ class new_connection_factory: public connection_factory
+ {
+ public:
+ new_connection_factory ();
+ };
+};
+ </pre>
+
+ <p>The <code>connection_pool_factory</code> class implements a
+ connection pool. It has the following interface:</p>
+
+ <pre class="c++">
+namespace odb
+{
+ namespace oracle
+ {
+ class connection_pool_factory: public connection_factory
+ {
+ public:
+ connection_pool_factory (std::size_t max_connections = 0,
+ std::size_t min_connections = 0);
+
+ protected:
+ class pooled_connection: public connection
+ {
+ public:
+ pooled_connection (database_type&amp;);
+ pooled_connection (database_type&amp;, PGconn*);
+ };
+
+ typedef details::shared_ptr&lt;pooled_connection> pooled_connection_ptr;
+
+ virtual pooled_connection_ptr
+ create ();
+ };
+};
+ </pre>
+
+ <p>The <code>max_connections</code> argument in the
+ <code>connection_pool_factory</code> constructor specifies the maximum
+ number of concurrent connections that this pool factory will
+ maintain. Similarly, the <code>min_connections</code> argument
+ specifies the minimum number of available connections that
+ should be kept open.</p>
+
+ <p>Whenever a connection is requested, the pool factory first
+ checks if there is an unused connection that can be returned.
+ If there is none, the pool factory checks the
+ <code>max_connections</code> value to see if a new connection
+ can be created. If the total number of connections maintained
+ by the pool is less than this value, then a new connection is
+ created and returned. Otherwise, the caller is blocked until
+ a connection becomes available.</p>
+
+ <p>When a connection is released, the pool factory first checks
+ if there are blocked callers waiting for a connection. If so, then
+ one of them is unblocked and is given the connection. Otherwise,
+ the pool factory checks whether the total number of connections
+ maintained by the pool is greater than the <code>min_connections</code>
+ value. If that's the case, the connection is closed. Otherwise, the
+ connection is added to the pool of available connections to be
+ returned on the next request. In other words, if the number of
+ connections maintained by the pool exceeds <code>min_connections</code>
+ and there are no callers waiting for a new connection,
+ the pool will close the excess connections.</p>
+
+ <p>If the <code>max_connections</code> value is 0, then the pool will
+ create a new connection whenever all of the existing connections
+ are in use. If the <code>min_connections</code> value is 0, then
+ the pool will never close a connection and instead maintain all
+ the connections that were ever created.</p>
+
+ <p>The <code>create()</code> virtual function is called whenever the
+ pool needs to create a new connection. By deriving from the
+ <code>connection_pool_factory</code> class and overriding this
+ function we can implement custom connection establishment
+ and configuration.</p>
+
+ <p>If you pass <code>NULL</code> as the connection factory to one of the
+ <code>database</code> constructors, then the
+ <code>connection_pool_factory</code> instance will be created by default
+ with the min and max connections values set to <code>0</code>. The
+ following code fragment shows how we can pass our own connection factory
+ instance:</p>
+
+ <pre class="c++">
+#include &lt;odb/database.hxx>
+
+#include &lt;odb/oracle/database.hxx>
+#include &lt;odb/oracle/connection-factory.hxx>
+
+int
+main (int argc, char* argv[])
+{
+ auto_ptr&lt;odb::oracle::connection_factory> f (
+ new odb::oracle::connection_pool_factory (20));
+
+ auto_ptr&lt;odb::database> db (
+ new oracle::database (argc, argv, false, 0, 0, 0, f));
+}
+ </pre>
+
+ <h2><a name="16.4">16.4 Oracle Exceptions</a></h2>
+
+ <p>The Oracle ODB runtime library defines the following
+ Oracle-specific exceptions:</p>
+
+ <pre class="c++">
+namespace odb
+{
+ namespace oracle
+ {
+ class database_exception: odb::database_exception
+ {
+ public:
+ int
+ error () const;
+
+ const std::string&amp;
+ message () const;
+
+ virtual const char*
+ what () const throw ();
+ };
+
+ class cli_exception: odb::exception
+ {
+ public:
+ virtual const char*
+ what () const throw ();
+ };
+
+ class invalid_oci_handle: odb::exception
+ {
+ public:
+ virtual const char*
+ what () const throw ();
+ };
+ }
+}
+ </pre>
+
+ <p>You will need to include the <code>&lt;odb/oracle/exceptions.hxx></code>
+ header file to make these exceptions available in your application.</p>
+
+ <p>The <code>odb::oracle::database_exception</code> is thrown if
+ an Oracle database operation fails. The Oracle-specific error
+ information is accessible via the <code>message()</code> and
+ <code>error()</code> functions. All this information is also
+ combined and returned in a human-readable form by the <code>what()</code>
+ function.</p>
+
+ <p>The <code>odb::oracle::cli_exception</code> is thrown by the
+ command line parsing constructor of the <code>odb::oracle::database</code>
+ class if the Oracle option values are missing or invalid. The
+ <code>what()</code> function returns a human-readable description
+ of an error.</p>
+
+ <p>The <code>odb::oracle::invalid_oci_handle</code> is thrown if an OCI
+ function returns the status code OCI_INVALID_HANDLE. The
+ <code>what()</code> function returns a human-readable description
+ of an error.</p>
+
+ <h2><a name="16.5">16.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="16.5.1">16.5.1 Query Result Caching</a></h3>
+
+ <p>Oracle ODB runtime implementation does not perform query result caching
+ (Section 4.4, "Query Result") even when explicitly requested. OCI supports
+ supports interleaving execution of multiple prepared statements on a
+ single connection. As a result, with Oracle, it is possible to have
+ multiple uncached results and calls to other database functions do not
+ invalidate them. The only limitation of the uncached Oracle results is
+ the unavailability of the result::size() function. If you call this
+ function on an Oracle query result, then the odb::result_not_cached
+ exception (Section 3.13, "ODB Exceptions") is always thrown. Future
+ versions of the Oracle ODB runtime library may add support for result
+ caching.</p>
+
+ <h3><a name="16.5.2">16.5.2 Timezones</a></h3>
+
+ <p>ODB does not currently support the Oracle date-time types with timezone
+ information.</p>
+
+ <h3><a name="16.5.3">16.5.3 Floating point <code>NUMBER</code> Type
+ Support</a></h3>
+
+ <p>Support for the Oracle <code>NUMBER</code> type when it represents a
+ floating point number (declared by specifying NUMBER without any range or
+ scale) is limited to providing a buffer containing the binary
+ representation of the value. For more information on the binary format
+ used to store <code>NUMBER</code> values refer to the OCI
+ documentation.</p>
+
+
<!-- PART -->
@@ -12320,9 +12976,9 @@ SHOW integer_datetimes
and libraries. It consists of the following chapters.</p>
<table class="toc">
- <tr><th>16</th><td><a href="#16">Profiles Introduction</a></td></tr>
- <tr><th>17</th><td><a href="#17">Boost Profile</a></td></tr>
- <tr><th>18</th><td><a href="#18">Qt Profile</a></td></tr>
+ <tr><th>17</th><td><a href="#17">Profiles Introduction</a></td></tr>
+ <tr><th>18</th><td><a href="#18">Boost Profile</a></td></tr>
+ <tr><th>19</th><td><a href="#19">Qt Profile</a></td></tr>
</table>
@@ -12330,7 +12986,7 @@ SHOW integer_datetimes
<hr class="page-break"/>
- <h1><a name="16">16 Profiles Introduction</a></h1>
+ <h1><a name="17">17 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
@@ -12384,7 +13040,7 @@ odb --profile boost/date-time ...
<hr class="page-break"/>
- <h1><a name="17">17 Boost Profile</a></h1>
+ <h1><a name="18">18 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
@@ -12409,7 +13065,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="17.1">17.1 Smart Pointers Library</a></h2>
+ <h2><a name="18.1">18.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
@@ -12479,7 +13135,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="17.2">17.2 Unordered Containers Library</a></h2>
+ <h2><a name="18.2">18.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
@@ -12505,7 +13161,7 @@ class person
};
</pre>
- <h2><a name="17.3">17.3 Optional Library</a></h2>
+ <h2><a name="18.3">18.3 Optional Library</a></h2>
<p>The <code>optional</code> sub-profile provides persistence support for
the <code>boost::optional</code> container from the Boost
@@ -12537,7 +13193,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="17.4">17.4 Date Time Library</a></h2>
+ <h2><a name="18.4">18.4 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
@@ -12610,7 +13266,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="17.4.1">17.4.1 MySQL Database Type Mapping</a></h3>
+ <h3><a name="18.4.1">18.4.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
@@ -12671,7 +13327,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="17.4.2">17.4.2 SQLite Database Type Mapping</a></h3>
+ <h3><a name="18.4.2">18.4.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
@@ -12749,7 +13405,7 @@ class person
will result in the <code>out_of_range</code> exception.</p>
- <h3><a name="17.4.3">17.4.3 PostgreSQL Database Type Mapping</a></h3>
+ <h3><a name="18.4.3">18.4.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
@@ -12800,11 +13456,55 @@ class person
result in the <code>special_value</code> exception.</p>
+ <h3><a name="18.4.4">18.4.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
+ types.</p>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="mapping" border="1">
+ <tr>
+ <th>Boost <code>date_time</code> Type</th>
+ <th>Oracle Type</th>
+ <th>Default <code>NULL</code> Semantics</th>
+ </tr>
+
+ <tr>
+ <td><code>gregorian::date</code></td>
+ <td><code>DATE</code></td>
+ <td><code>NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>posix_time::ptime</code></td>
+ <td><code>TIMESTAMP</code></td>
+ <td><code>NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>posix_time::time_duration</code></td>
+ <td><code>INTERVAL DAY TO SECOND</code></td>
+ <td><code>NULL</code></td>
+ </tr>
+ </table>
+
+ <p>The Boost special value <code>date_time::not_a_date_time</code> is stored
+ as a <code>NULL</code> value in an Oracle database.</p>
+
+ <p>Some valid Boost date-time values cannot be stored in an Oracle database.
+ An attempt to persist a <code>gregorian::date</code>,
+ <code>posix_time::time_duration</code>, or
+ <code>posix_time::time_duration</code> value representing any special
+ value other than <code>date_time::not_a_date_time</code> will result in
+ the <code>special_value</code> exception.</p>
+
+
<!-- CHAPTER -->
<hr class="page-break"/>
- <h1><a name="18">18 Qt Profile</a></h1>
+ <h1><a name="19">19 Qt Profile</a></h1>
<p>The ODB profile implementation for Qt is provided by the
<code>libodb-qt</code> library and consists of multiple sub-profiles
@@ -12830,7 +13530,7 @@ class person
that can be thrown by the Qt sub-profiles are described in the
following sections.</p>
- <h2><a name="18.1">18.1 Basic Types</a></h2>
+ <h2><a name="19.1">19.1 Basic Types</a></h2>
<p>The <code>basic</code> sub-profile provides persistence support for basic
types defined by Qt. To enable only this profile, pass
@@ -12852,7 +13552,7 @@ class Person
};
</pre>
- <h3><a name="18.1.1">18.1.1 MySQL Database Type Mapping</a></h3>
+ <h3><a name="19.1.1">19.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>
@@ -12890,7 +13590,7 @@ class Person
it is mapped to <code>TEXT</code>.</p>
- <h3><a name="18.1.2">18.1.2 SQLite Database Type Mapping</a></h3>
+ <h3><a name="19.1.2">19.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>
@@ -12920,7 +13620,7 @@ class Person
are stored as a NULL value if their <code>isNull()</code> member
function returns <code>true</code>.</p>
- <h3><a name="18.1.3">18.1.3 PostgreSQL Database Type Mapping</a></h3>
+ <h3><a name="19.1.3">19.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>
@@ -12950,7 +13650,59 @@ class Person
are stored as a NULL value if their <code>isNull()</code> member
function returns <code>true</code>.</p>
- <h2><a name="18.2">18.2 Smart Pointers</a></h2>
+ <h3><a name="19.1.4">19.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>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="mapping" border="1">
+ <tr>
+ <th>Qt Type</th>
+ <th>Oracle Type</th>
+ <th>Default <code>NULL</code> Semantics</th>
+ </tr>
+
+ <tr>
+ <td><code>QString</code></td>
+ <td><code>VARCHAR(4000)</code></td>
+ <td><code>NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>QByteArray</code></td>
+ <td><code>BLOB</code></td>
+ <td><code>NULL</code></td>
+ </tr>
+ </table>
+
+ <p>Instances of the <code>QString</code> and <code>QByteArray</code> types
+ are stored as a NULL value if their <code>isNull()</code> member
+ function returns <code>true</code>.</p>
+
+ <p>The <code>basic</code> sub-profile implementation also provides support
+ for mapping QString to the <code>CLOB</code> and <code>NCLOB</code> Oracle
+ types, and for mapping QByteArray to the <code>RAW</code> Oracle type.
+ However, these mappings need to be explicitly requested using the
+ <code>db type</code> pragma
+ (<a href="#12.4.3">Section 12.4.3, "type"</a>), as show in the
+ following example:</p>
+
+ <pre class="c++">
+#pragma db object
+class Person
+{
+ ...
+
+ #pragma db type("NCLOB") not_null
+ QString first_name_;
+
+ #pragma db type("RAW(128)") null
+ QByteArray uuid_;
+};
+ </pre>
+
+ <h2><a name="19.2">19.2 Smart Pointers</a></h2>
<p>The <code>smart-ptr</code> sub-profile provides persistence support the
Qt smart pointers. To enable only this profile, pass
@@ -13019,7 +13771,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="18.3">18.3 Containers Library</a></h2>
+ <h2><a name="19.3">19.3 Containers Library</a></h2>
<p>The <code>container</code> sub-profile provides persistence support for
Qt containers. To enable only this profile, pass
@@ -13044,7 +13796,7 @@ class Person
};
</pre>
- <h2><a name="18.4">18.4 Date Time Types</a></h2>
+ <h2><a name="19.4">19.4 Date Time Types</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
@@ -13097,7 +13849,7 @@ namespace odb
system dependent and is discussed in more detail in the
following sub-sections.</p>
- <h3><a name="18.4.1">18.4.1 MySQL Database Type Mapping</a></h3>
+ <h3><a name="19.4.1">19.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>
@@ -13156,7 +13908,7 @@ class Person
the MySQL documentation for more information on the MySQL data type
ranges.</p>
- <h3><a name="18.4.2">18.4.2 SQLite Database Type Mapping</a></h3>
+ <h3><a name="19.4.2">19.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>
@@ -13218,7 +13970,7 @@ class Person
epoch) as an SQLite <code>INTEGER</code> will result in the
<code>out_of_range</code> exception.</p>
- <h3><a name="18.4.3">18.4.3 PostgreSQL Database Type Mapping</a></h3>
+ <h3><a name="19.4.3">19.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>
@@ -13261,6 +14013,42 @@ class Person
<code>TIMESTAMP</code> will result in the <code>out_of_range</code>
exception.</p>
+ <h3><a name="19.4.4">19.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>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="mapping" border="1">
+ <tr>
+ <th>Qt Date Time Type</th>
+ <th>Oracle Type</th>
+ <th>Default <code>NULL</code> Semantics</th>
+ </tr>
+
+ <tr>
+ <td><code>QDate</code></td>
+ <td><code>DATE</code></td>
+ <td><code>NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>QTime</code></td>
+ <td><code>INTERVAL DAY(0) TO SECOND(3)</code></td>
+ <td><code>NULL</code></td>
+ </tr>
+
+ <tr>
+ <td><code>QDateTime</code></td>
+ <td><code>TIMESTAMP(3)</code></td>
+ <td><code>NULL</code></td>
+ </tr>
+ </table>
+
+ <p>Instances of the <code>QDate</code>, <code>QTime</code>, and
+ <code>QDateTime</code> types are stored as a NULL value if their
+ <code>isNull()</code> member function returns true.</p>
+
</div>
</div>