From 615be3f955f6f0c9d2c00d55d8a53512310abd0a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 30 Nov 2011 15:32:25 +0200 Subject: Additions to Oracle documentation --- doc/manual.xhtml | 372 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 262 insertions(+), 110 deletions(-) diff --git a/doc/manual.xhtml b/doc/manual.xhtml index a9f380f..eb74640 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -587,9 +587,10 @@ for consistency. - - - + + + +
15.5.1Query Result Caching
15.5.2Foreign Key Constraints
15.5.3Date-Time Format
15.5.4Timezones
15.5.5NUMERIC Type Support
15.5.3Unique Constraint Violations
15.5.4Date-Time Format
15.5.5Timezones
15.5.6NUMERIC Type Support
@@ -607,9 +608,14 @@ for consistency. 16.5Oracle Limitations - - - + + + + + + +
16.5.1Query Result Caching
16.5.2Timezones
16.5.3NUMERIC Type Support
16.5.116.5.1 Identifier Truncation
16.5.216.5.2 Query Result Caching
16.5.316.5.3 Foreign Key Constraints
16.5.416.5.4 Unique Constraint Violations
16.5.516.5.5 Large FLOAT and + NUMBER Types
16.5.616.5.6 Timezones
16.5.716.5.7 LONG Types
@@ -10339,6 +10345,7 @@ aCC +W2161 ... 13MySQL Database 14SQLite Database 15PostgreSQL Database + 16Oracle Database @@ -11693,7 +11700,8 @@ odb::database& db = ...
 CREATE TABLE Employee (
   ...
-  employer BIGINT REFERENCES Employer (name) DEFERRABLE INITIALLY DEFERRED);
+  employer INTEGER REFERENCES Employer(id)
+           DEFERRABLE INITIALLY DEFERRED);
   
@@ -12301,10 +12309,19 @@ namespace odb
 CREATE TABLE Employee (
   ...
-  employer BIGINT REFERENCES Employer (name) INITIALLY DEFERRED);
+  employer BIGINT REFERENCES Employer(id) INITIALLY DEFERRED);
   
-

15.5.3 Date-Time Format

+

15.5.3 Unique Constraint Violations

+ +

Due to the granularity of the PostgreSQL error codes, it is impossible + to distinguish between the duplicate primary key and other unique + constraint violations. As a result, when making an object persistent, + The PostgreSQL ODB runtime will translate all unique constraint violation + errors to the object_not_persistent exception + (Section 3.13, "ODB Exceptions").

+ +

15.5.4 Date-Time Format

ODB expects the PostgreSQL server to use integers as a binary format for the date-time types, which is the default for most @@ -12319,12 +12336,12 @@ CREATE TABLE Employee ( SHOW integer_datetimes -

15.5.4 Timezones

+

15.5.5 Timezones

ODB does not currently support the PostgreSQL date-time types with timezone information.

-

15.5.5 NUMERIC Type Support

+

15.5.6 NUMERIC Type Support

Support for the PostgreSQL NUMERIC type is limited to providing a binary buffer containing the binary representation @@ -12340,10 +12357,10 @@ SHOW integer_datetimes

16 Oracle Database

To generate support code for the Oracle database you will need - to pass the "‑‑database oracle" - (or "‑d oracle") option to the ODB compiler. + to pass the "--database oracle" + (or "-d oracle") option to the ODB compiler. Your application will also need to link to the Oracle ODB runtime - library (libodb‑oracle). All Oracle-specific ODB + library (libodb-oracle). All Oracle-specific ODB classes are defined in the odb::oracle namespace.

16.1 Oracle Type Mapping

@@ -12448,22 +12465,30 @@ SHOW integer_datetimes std::string - VARCHAR(4000) - NOT NULL + VARCHAR2(4000) + NULL +

In Oracle empty VARCHAR2 and NVARCHAR2 + strings are represented as NULL values. As a result, + in the generated schema, columns of these types are always + declared as NULL, even if explicitly declared as + NOT NULL with the db not_null pragma + (Section 12.4.4, "null/not_null").

+

The Oracle ODB runtime library also provides support for mapping the - std::string type to the Oracle CLOB and - NCLOB types, and for mapping the + std::string type to the Oracle CHAR, + NCHAR, NVARCHAR2, CLOB and + NCLOB types, as well as for mapping the std::vector<char>, std::vector<unsigned char>, char[N], and unsigned char[N] types to the Oracle BLOB and RAW types. However, these mappings are not enabled by default (in particular, by default, std::vector 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 db type pragma + these alternative mappings for these types we need to specify the + database type explicitly using the db type pragma (Section 12.4.3, "type"), for example:

@@ -12476,10 +12501,10 @@ class object #pragma db type ("CLOB") std::string str_; - #pragma db type("RAW(256)") + #pragma db type("BLOB") std::vector<char> buf_; - #pragma db type("BLOB") + #pragma db type("RAW(16)") unsigned char[16] uuid_; }; @@ -12585,22 +12610,22 @@ namespace odb

You will need to include the <odb/oracle/database.hxx> header file to make this class available in your application.

-

The database 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.

+

The Oracle database class contains the OCI environment + handle as well as the database connection string and user credentials + that are used to establish connections to the database.

The overloaded database constructors allow us to specify the Oracle database parameters that should be used when connecting to the - database. The database argument in the first constructor is a + database. The db 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.

+ information on the format of the connection identifier, refer to the + Oracle documentation.

-

The second constructor allows the components of a connection identifier to - be specified individually using the service, - host, and port arguments. Specifying an empty - host string is equivalent to localhost. Specifying a zero port number - indicates that the default port should be used.

+

The second constructor allows us to specify the individual components + of a connection identifier as the service, host, + and port arguments. If the host argument is + empty then localhost is used by default. Similarly, if the + port argument is zero, then the default port is used.

The last constructor extracts the database parameters from the command line. The following options are recognized:

@@ -12608,7 +12633,7 @@ namespace odb
   --user <login>
   --password <password>
-  --database <name>
+  --database <connect-id>
   --service <name>
   --host <host>
   --port <integer>
@@ -12618,9 +12643,9 @@ namespace odb
   

The --options-file 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 ‑‑database option - together with any of ‑‑service, - ‑‑host, or ‑‑port + is invalid to specify the --database option + together with any of --service, + --host, or --port options.

If the erase argument to this constructor is true, @@ -12638,18 +12663,35 @@ namespace odb

The static print_usage() function prints the list of options with short descriptions that are recognized by this constructor.

-

All the constructors take charset and ncharset - arguments. These specify the client database character set and client - national character set, respectively.

- -

Additionally, each constructor takes an environment argument - which is an OCI environment handle. If the handle is - non-NULL, it is used for all OCI function calls made against - the database instance that require an environment handle. The - database instance does not take ownership of this handle, - and it should be released by the user when it is no longer needed. The - charset and ncharset arguments are ignored if - the environment argument is non-NULL.

+

Additionally, all the constructs have the charset, + ncharset, and environment arguments. + The charset argument specifies the client-side database + character encoding. Character data corresponding to the CHAR, + VARCHAR2, and CLOB types will be delivered + to and received from the application in this encoding. Similarly, + the ncharset argument specifies the client-side national + character encoding. Character data corresponding to the NCHAR, + NVARCHAR2, and NCLOB types will be delivered + to and received from the application in this encoding. For the complete + list of available character encoding values, refer to the Oracle + documentation. Commonly used encoding values are 873 + (UTF-8), 31 (ISO-8859-1), and 1000 (UTF-16). If the + database character encoding is not specified, then the NLS_LANG + environment/registry variable is used. Similarly, if the national + character encoding is not specified, then the NLS_NCHAR + environment/registry variable is used. For more information on character + encodings, refer to the OCIEnvNlsCreate() function in + the Oracle Call Interface (OCI) documentation.

+ +

The environment argument allows us to provide a custom + OCI environment handle. If this argument is not NULL, + then the passed handle is used in all the OCI function calls made + by this database class instance. Note also that the + database instance does not assume ownership of the + passed environment handle and this handle should be valid for + the lifetime of the database instance. If a custom + environment handle is used, then the charset and + ncharset arguments have no effect.

The last argument to all of the constructors is a pointer to a connection factory. If we pass a non-NULL value, the @@ -12698,28 +12740,27 @@ namespace odb

For more information on the odb::connection interface, refer to Section 3.5, "Connections". The first overloaded - oracle::connection 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 connection instance by + oracle::connection constructor creates a new OCI service + context. The OCI statement caching is enabled for the underlying session + while the OCI connection pooling and session pooling are not used. The + second constructor allows us to create a connection instance by providing an already connected Oracle service context. Note that the connection instance assumes ownership of this handle. The - handle() accessor returns the Oracle service context handle + handle() accessor returns the OCI service context handle associated with the connection.

-

An Oracle error handle is allocated for each connection - instance. This handle is publicly available via the - error_handle() accessor. Its lifetime is managed by, and - must remain valid for the entire lifetime of its containing - connection instance.

+

An OCI error handle is allocated for each connection + instance and is available via the error_handle() accessor + function.

-

Finally, each connection 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 lob_buffer() - 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.

+

Additionally, each connection instance maintains a large + object (LOB) buffer. This buffer is used by the Oracle ODB runtime + as an intermediate storage for piecewise handling of LOB data. + By default, the LOB buffer has zero initial capacity and is + expanded to 4096 bytes when the first LOB operation is performed. + If your application requires a bigger or smaller LOB buffer, you can + specify a custom capacity using the lob_buffer() + accessor.

The oracle::connection_factory abstract class has the following interface:

@@ -12794,7 +12835,7 @@ namespace odb { public: pooled_connection (database_type&); - pooled_connection (database_type&, PGconn*); + pooled_connection (database_type&, OCISvcCtx*); }; typedef details::shared_ptr<pooled_connection> pooled_connection_ptr; @@ -12882,11 +12923,29 @@ namespace odb class database_exception: odb::database_exception { public: - int - error () const; + class record + { + public: + sb4 + error () const; - const std::string& - message () const; + const std::string& + message () const; + }; + + typedef std::vector<record> records; + + typedef records::size_type size_type; + typedef records::const_iterator iterator; + + iterator + begin () const; + + iterator + end () const; + + size_type + size () const; virtual const char* what () const throw (); @@ -12914,10 +12973,10 @@ namespace odb

The odb::oracle::database_exception is thrown if an Oracle database operation fails. The Oracle-specific error - information is accessible via the message() and - error() functions. All this information is also - combined and returned in a human-readable form by the what() - function.

+ information is stores as a series of records, each containing + the error code as a signed 4-byte integer and a message string. + All this information is also combined and returned in a + human-readable form by the what() function.

The odb::oracle::cli_exception is thrown by the command line parsing constructor of the odb::oracle::database @@ -12925,44 +12984,136 @@ namespace odb what() function returns a human-readable description of an error.

-

The odb::oracle::invalid_oci_handle is thrown if an OCI - function returns the status code OCI_INVALID_HANDLE. The - what() function returns a human-readable description - of an error.

+

The odb::oracle::invalid_oci_handle is thrown if an + invalid handle is passed to an OCI function or if an OCI function + was unable to allocate a handle. The former normally indicates + a programming error while the latter indicates an out of memory + condition. The what() function returns a human-readable + description of an error.

16.5 Oracle Limitations

The following sections describe Oracle-specific limitations imposed by the current Oracle and ODB runtime versions.

-

16.5.1 Query Result Caching

+

16.5.1 Identifier Truncation

+ +

Oracle limits the length of database identifiers (table, column, etc., + names) to 30 characters. The ODB compiler automatically truncates + any identifier that is longer than 30 character. This, however, + can lead to duplicate names. A common symptom of this problem + are errors during the database schema creation indicating + that a database object with the same name already exists. To + resolve this problem you can assign custom, shorter identifiers + using the db table and db column + pragmas (Chapter 12, "ODB Pragma Language"). For + example:

+ +
+#pragma db object
+class long_class_name
+{
+  ...
+
+  std::vector<int> long_container_x_;
+  std::vector<int> long_container_y_;
+};
+  
+ +

In the above example, the names of the two container tables will be + long_class_name_long_container_x_ and + long_class_name_long_container_y_. However, when + truncated to 30 characters, they both become + long_class_name_long_container. To resolve this + collision we can assign a custom table name for each container:

+ +
+#pragma db object
+class long_class_name
+{
+  ...
+
+  #pragma db table("long_class_name_cont_x")
+  std::vector<int> long_container_x_;
+
+  #pragma db table("long_class_name_cont_y")
+  std::vector<int> long_container_y_;
+};
+  
+ +

16.5.2 Query Result Caching

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.

- -

16.5.2 Timezones

+ (Section 4.4, "Query Result") even when explicitly + requested. The OCI API supports interleaving execution of multiple + prepared statements on a single connection. As a result, with OCI, + 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.

+ +

16.5.3 Foreign Key Constraints

+ +

ODB relies on standard SQL behavior which requires that + foreign key constraints checking is deferred until the + transaction is committed. Default Oracle behavior is + to check such constraints immediately. As a result, when + used with ODB, a custom database schema that defines foreign + key constraints must declare such constraints as + INITIALLY DEFERRED, as shown in the following example. + Schemas generated by the ODB compiler meet this requirement + automatically.

+ +
+CREATE TABLE Employee (
+  ...
+  employer NUMBER(20) REFERENCES Employer(id)
+           DEFERRABLE INITIALLY DEFERRED);
+  
+ +

16.5.4 Unique Constraint Violations

+ +

Due to the granularity of the Oracle error codes, it is impossible + to distinguish between the duplicate primary key and other unique + constraint violations. As a result, when making an object persistent, + The Oracle ODB runtime will translate all unique constraint violation + errors to the object_not_persistent exception + (Section 3.13, "ODB Exceptions").

+ +

16.5.5 Large FLOAT and + NUMBER Types

+ +

The Oracle FLOAT type with the binary precision greater + than 53 and fixed-point NUMBER type with the decimal + precision greater than 15 cannot be automatically extracted + into the C++ float and double types. + Instead, the Oracle ODB runtime uses a 21-byte buffer containing + the binary representation of a value as an image type for such + FLOAT and NUMBER types. In order to + convert them into an application-specific large number representation + you will need to provide a suitable value_traits + template specialization. For more information on the binary format + used to store the FLOAT and NUMBER values, + refer to the Oracle Call Interface (OCI) documentation.

+ +

Note that a NUMBER type that is used to represent a + floating point number (declared by specifying NUMBER + without any range and scale) can be extracted into the C++ + float and double types.

+ +

16.5.6 Timezones

ODB does not currently support the Oracle date-time types with timezone information.

-

16.5.3 Floating point NUMBER Type - Support

+

16.5.7 LONG Types

-

Support for the Oracle NUMBER 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 NUMBER values refer to the OCI - documentation.

+

ODB does not support the deprecated Oracle LONG and + LONG RAW data types.

@@ -13665,7 +13816,7 @@ class Person QString - VARCHAR(4000) + VARCHAR2(4000) NULL @@ -13680,12 +13831,13 @@ class Person are stored as a NULL value if their isNull() member function returns true.

-

The basic sub-profile implementation also provides support - for mapping QString to the CLOB and NCLOB Oracle - types, and for mapping QByteArray to the RAW Oracle type. - However, these mappings need to be explicitly requested using the - db type pragma - (Section 12.4.3, "type"), as show in the +

The basic sub-profile also provides support + for mapping QString to the CHAR, + NCHAR, NVARCHAR, CLOB and + NCLOB Oracle types, and for mapping QByteArray + to the RAW Oracle type. However, these altenative + mappings have to be explicitly requested using the db type + pragma (Section 12.4.3, "type"), as show in the following example:

@@ -13694,10 +13846,10 @@ class Person
 {
   ...
 
-  #pragma db type("NCLOB") not_null
-  QString first_name_;
+  #pragma db type("CLOB") not_null
+  QString firstName_;
 
-  #pragma db type("RAW(128)") null
+  #pragma db type("RAW(16)") null
   QByteArray uuid_;
 };
   
-- cgit v1.1