From e64485293cdf16fa5bfcc747b938752efa1869ad Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 18 Nov 2011 16:18:55 +0200 Subject: Add new chapter for SQL Server and update profile chapters --- doc/manual.xhtml | 1615 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 1380 insertions(+), 235 deletions(-) (limited to 'doc') diff --git a/doc/manual.xhtml b/doc/manual.xhtml index ef36090..f5bf6dc 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -609,14 +609,36 @@ for consistency. 16.5Oracle Limitations - - - - - - - + + + + + + + +
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
16.5.1Identifier Truncation
16.5.2Query Result Caching
16.5.3Foreign Key Constraints
16.5.4Unique Constraint Violations
16.5.5Large FLOAT and NUMBER Types
16.5.6Timezones
16.5.7LONG Types
+ + + + + + + + 17Microsoft SQL Server Database + + + + + + + @@ -629,22 +651,23 @@ for consistency. - + -
17.1SQL Server Type Mapping
17.2SQL Server Database Class
17.3SQL Server Connection and Connection Factory
17.4SQL Server Exceptions
17.5SQL Server Limitations + + + + + + +
17.5.1Query Result Caching
17.5.2Foreign Key Constraints
17.5.3Unique Constraint Violations
17.5.4Multithreaded Windows Applications
17.5.5Affected Row Count and DDL Statements
17.5.6Long Data and Automatically Assigned Object Ids
17Profiles Introduction18Profiles Introduction
18Boost Profile + 19Boost Profile - - - + + + - @@ -653,27 +676,29 @@ for consistency. -
18.1Smart Pointers Library
18.2Unordered Containers Library
18.3Optional Library
19.1Smart Pointers Library
19.2Unordered Containers Library
19.3Optional Library
18.4Date Time Library + 19.4Date Time Library - - - - + + + + +
18.4.1MySQL Database Type Mapping
18.4.2SQLite Database Type Mapping
18.4.3PostgreSQL Database Type Mapping
18.4.4Oracle Database Type Mapping
19.4.1MySQL Database Type Mapping
19.4.2SQLite Database Type Mapping
19.4.3PostgreSQL Database Type Mapping
19.4.4Oracle Database Type Mapping
19.4.5SQL Server Database Type Mapping
19Qt Profile + 20Qt Profile - - - + + - @@ -2876,19 +2901,19 @@ for (unsigned short retry_count (0); ; retry_count++) deduced from the argument being passed. The following example shows how we can call these functions:

-
+  
 person john ("John", "Doe", 33);
 shared_ptr<person> jane (new person ("Jane", "Doe", 32));
 
 transaction t (db.begin ());
 
-db->persist (john);
+db.persist (john);
 unsigned long jane_id (db.persist (jane));
 
 t.commit ();
 
 cerr << "Jane's id: " << jane_id << endl;
-
+

Notice that in the above code fragment we have created instances that we were planning to make persistent before starting the @@ -4378,7 +4403,7 @@ private:

The resulting database table (called person_nicknames) will - contain the object id column of type unsigned long + contain the object id column of type unsigned long (called object_id), the index column of an integer type (called index), and the value column of type std::string (called value).

@@ -4467,7 +4492,7 @@ private:

The resulting database table (called person_emails) will - contain the object id column of type unsigned long + contain the object id column of type unsigned long (called object_id) and the value column of type std::string (called value).

@@ -4528,7 +4553,7 @@ private:

The resulting database table (called person_age_weight_map) - will contain the object id column of type unsigned long + will contain the object id column of type unsigned long (called object_id), the key column of type unsigned short (called key), and the value column of type float (called value).

@@ -4770,7 +4795,7 @@ typedef odb::result<employee> result; session s; transaction t (db.begin ()); -result r (db->query<employee> ( +result r (db.query<employee> ( query::employer->name == "Example Inc" && query::last == "Doe")); for (result::iterator i (r.begin ()); i != r.end (); ++i) @@ -4787,7 +4812,7 @@ t.commit (); employer object:

-result r (db->query<employee> (query::employer.is_null ()));
+result r (db.query<employee> (query::employer.is_null ()));
   

An important concept to keep in mind when working with object @@ -5710,7 +5735,7 @@ private: are not allowed. The following example illustrates some of the possible use cases:

-
+  
 #pragma db value
 class basic_name
 {
@@ -5747,12 +5772,12 @@ class person
 
   name name_;
 };
-
+

A composite value type can also be defined as an instantiation of a C++ class template, for example:

-
+  
 template <typename T>
 struct point
 {
@@ -5771,7 +5796,7 @@ class object
 
   int_point center_;
 };
-
+

Note that the database support code for such a composite value type is generated when compiling the header containing the @@ -5781,7 +5806,7 @@ class object std::pair defined in the utility standard header file:

-
+  
 #include <utility> // std::pair
 
 typedef std::pair<std::string, std::string> phone_numbers;
@@ -5794,7 +5819,7 @@ class person
 
   phone_numbers phone_;
 };
-
+

We can also use data members from composite value types in database queries (Chapter 4, "Querying the @@ -5816,9 +5841,9 @@ class person typedef odb::query<person> query; typedef odb::result<person> result; -transaction t (db->begin ()); +transaction t (db.begin ()); -result r (db->query<person> ( +result r (db.query<person> ( query::name.extras.nickname == "Squeaky")); ... @@ -5835,7 +5860,7 @@ t.commit (); types things are slightly more complex since they are mapped to multiple columns. Consider the following example:

-
+  
 #pragma db value
 class name
 {
@@ -5855,7 +5880,7 @@ class person
 
   name name_;
 };
-
+

The column names for the first_ and last_ members are constructed by using the sanitized name of the @@ -5909,7 +5934,7 @@ CREATE TABLE person (

We can also make the column prefix empty, for example:

-
+  
 #pragma db object
 class person
 {
@@ -6145,7 +6170,7 @@ namespace odb
      consider using a more efficient implementation of the
      optional value concept such as the
      optional class template from Boost
-     (Section 18.3, "Optional Library").

+ (Section 19.3, "Optional Library").

Another common C++ representation of a value that can be NULL is a pointer. ODB will automatically @@ -6238,7 +6263,7 @@ class contractor: public person { ... }; -

+

In the above example both the employee and contractor classes inherit the first_ @@ -6299,7 +6324,7 @@ public: return self_employed; } }; - +

With this inheritance style, which we will call polymorphism inheritance, the application code normally works with derived @@ -6354,7 +6379,7 @@ public: class is only inherited once. The following example shows a persistent class hierarchy employing reuse inheritance:

-
+  
 // Abstract person class. Note that it does not declare the
 // object id.
 //
@@ -6412,11 +6437,11 @@ class contractor: public person
   #pragma db id
   std::string email_;
 };
-
+

The sample database schema for this hierarchy is shown below.

-
+  
 CREATE TABLE permanent_employee (
   first TEXT NOT NULL,
   last TEXT NOT NULL,
@@ -6432,7 +6457,7 @@ CREATE TABLE contractor (
   first TEXT NOT NULL,
   last TEXT NOT NULL,
   email VARCHAR (255) NOT NULL PRIMARY KEY);
-
+

The complete version of the code presented in this section is available in the inheritance example in the @@ -9437,8 +9462,8 @@ class person If you have a high object turnover (that is, objects are routinely made persistent and then erased), then care must be taken not to run out of object ids. In such situations, using - unsigned long long as the identifier type is a safe - choice.

+ unsigned long long as the identifier type + is a safe choice.

For additional information on the automatic identifier assignment, refer to Section 3.7, "Making Objects Persistent".

@@ -9504,7 +9529,7 @@ class account #pragma db not_null shared_ptr<person> holder_; }; - +

The NULL semantics can also be specified on the per-type basis (Section 12.3.3, @@ -9844,7 +9869,7 @@ class person required argument to this specifier is the corresponding data member name in the referenced object. For example:

-
+  
 using std::tr1::shared_ptr;
 using std::tr1::weak_ptr;
 
@@ -9903,7 +9928,7 @@ class person
      an integer or similar database type. Note also that object versions
      are not reused. If you have a high update frequency, then care must
      be taken not to run out of versions. In such situations, using
-     unsigned long long as the version type is a safe
+     unsigned long long as the version type is a safe
      choice.

For a more detailed discussion of optimistic concurrency, refer to @@ -10394,6 +10419,7 @@ aCC +W2161 ...

+
19.1Basic Types Library + 20.1Basic Types Library - - - - + + + + +
19.1.1MySQL Database Type Mapping
19.1.2SQLite Database Type Mapping
19.1.3PostgreSQL Database Type Mapping
19.1.4Oracle Database Type Mapping
20.1.1MySQL Database Type Mapping
20.1.2SQLite Database Type Mapping
20.1.3PostgreSQL Database Type Mapping
20.1.4Oracle Database Type Mapping
20.1.5SQL Server Database Type Mapping
19.2Smart Pointers Library
19.3Containers Library
20.2Smart Pointers Library
20.3Containers Library
19.4Date Time Library + 20.4Date Time Library - - - - + + + + +
19.4.1MySQL Database Type Mapping
19.4.2SQLite Database Type Mapping
19.4.3PostgreSQL Database Type Mapping
19.4.4Oracle Database Type Mapping
20.4.1MySQL Database Type Mapping
20.4.2SQLite Database Type Mapping
20.4.3PostgreSQL Database Type Mapping
20.4.4Oracle Database Type Mapping
20.4.5SQL Server Database Type Mapping
14SQLite Database
15PostgreSQL Database
16Oracle Database
17Microsoft SQL Server Database
@@ -10518,7 +10544,7 @@ aCC +W2161 ...

Note that the std::string type is mapped - differently depending on whether the member of this type + differently depending on whether a member of this type is an object id or not. If the member is an object id, then for this member std::string is mapped to the VARCHAR(255) MySQL type. Otherwise, @@ -11205,8 +11231,9 @@ class object

Note also that SQLite only operates with signed integers and the largest value that an SQLite database can store is a signed 64-bit integer. As - a result, greater unsigned long long values will be - represented in the database as negative values.

+ a result, greater unsigned long and + unsigned long long values will be represented in + the database as negative values.

14.2 SQLite Database Class

@@ -11681,7 +11708,7 @@ namespace odb (Section 12.4.3, "type"). For example:

-
+  
 #pragma db object
 class person
 {
@@ -11692,7 +11719,7 @@ class person
   #pragma db id auto                   // Ok, Mapped to INTEGER.
   unsigned int id_;
 };
-
+

14.5.3 Foreign Key Constraints

@@ -11721,7 +11748,7 @@ class person re-creating the schema. The following code fragment shows how this can be done:

-
+  
 #include <odb/connection.hxx>
 #include <odb/transaction.hxx>
 #include <odb/schema-catalog.hxx>
@@ -11739,7 +11766,7 @@ odb::database& db = ...
 
   c->execute ("PRAGMA foreign_keys=ON");
 }
-
+

Finally, ODB relies on standard SQL behavior which requires that foreign key constraints checking is deferred until the @@ -11764,7 +11791,7 @@ CREATE TABLE Employee ( to distinguish between the duplicate primary key and other constraint violations. As a result, when making an object persistent, the SQLite ODB runtime will translate all constraint violation errors to the - object_not_persistent exception (Section + object_already_persistent exception (Section 3.13, "ODB Exceptions").

14.5.5 Sharing of Queries

@@ -11952,10 +11979,10 @@ class object semantics being NOT NULL.

Note also that because PostgreSQL does not support unsigned integers, - the unsigned short, unsigned int, and - unsigned long long C++ types are by default mapped - to the SMALLINT, INTEGER, and - BIGINT PostgreSQL types, respectively. The sign bit + the unsigned short, unsigned int, and + unsigned long/unsigned long long C++ types + are by default mapped to the SMALLINT, INTEGER, + and BIGINT PostgreSQL types, respectively. The sign bit of the value stored by the database for these types will contain the most significant bit of the actual unsigned value being persisted.

@@ -12376,7 +12403,7 @@ CREATE TABLE Employee ( 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 + errors to the object_already_persistent exception (Section 3.13, "ODB Exceptions").

15.5.4 Date-Time Format

@@ -12588,8 +12615,10 @@ class object

16.2 Oracle Database Class

-

The Oracle database class has the following - interface:

+

The Oracle database class encapsulates the OCI environment + handle as well as the database connection string and user credentials + that are used to establish connections to the database. It has the + following interface:

 namespace odb
@@ -12628,7 +12657,6 @@ namespace odb
       static void
       print_usage (std::ostream&);
 
-
     public:
       const std::string&
       user () const;
@@ -12655,7 +12683,7 @@ namespace odb
       ncharset () const;
 
       OCIEnv*
-      environment () const;
+      environment ();
 
     public:
       connection_ptr
@@ -12668,10 +12696,6 @@ namespace odb
   

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

-

The Oracle database class encapsulates 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 db argument in the first constructor is a @@ -12805,7 +12829,7 @@ namespace odb providing an already connected Oracle service context. Note that the connection instance assumes ownership of this handle. The handle() accessor returns the OCI service context handle - associated with the connection.

+ associated with the connection instance.

An OCI error handle is allocated for each connection instance and is available via the error_handle() accessor @@ -13139,7 +13163,7 @@ CREATE TABLE Employee ( 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 + errors to the object_already_persistent exception (Section 3.13, "ODB Exceptions").

16.5.5 Large FLOAT and @@ -13174,146 +13198,1074 @@ CREATE TABLE Employee ( LONG RAW data types.

- +
-

PART III   - PROFILES

+

17 Microsoft SQL Server Database

-

Part III covers the integration of ODB with popular C++ frameworks - and libraries. It consists of the following chapters.

+

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

- - - - -
17Profiles Introduction
18Boost Profile
19Qt Profile
+

17.1 SQL Server Type Mapping

+

The following table summarizes the default mapping between basic + C++ value types and SQL Server database types. This mapping can be + customized on the per-type and per-member basis using the ODB + Pragma Language (Chapter 12, "ODB Pragma Language").

- + + + + + + + + + + + + -
-

17 Profiles Introduction

+ + + + + -

ODB profiles are a generic mechanism for integrating ODB with - widely-used C++ frameworks and libraries. A profile provides glue - code which allows you to seamlessly persist various components, such - as smart pointers, containers, and value types found in these - frameworks or libraries. The code necessary to implement a profile - is packaged into the so called profile library. For example, the - Boost profile implementation is provided by the libodb-boost - profile library.

+ + + + + -

Besides linking the profile library to our application, it is also - necessary to let the ODB compiler know which profiles we - are using. This is accomplished with the --profile - (or -p alias) option. For example:

+ + + + + -
-odb --profile boost ...
-  
+ + + + + -

Some profiles, especially those covering frameworks or libraries that - consist of multiple sub-libraries, provide sub-profiles that allow you - to pick and choose which components you would like to use in your - application. For example, the boost profile contains - the boost/data-time sub-profile. If we are only - interested in the date_time types, then we can - pass boost/data-time instead of boost - to the --profile option, for example:

+ + + + + -
-odb --profile boost/date-time ...
-  
+ + + + + -

To summarize, you will need to perform the following steps in order - to make use of a profile in your application:

+ + + + + -
    -
  1. ODB compiler: if necessary, specify the path to the profile library - headers (-I option).
  2. -
  3. ODB compiler: specify the profile you would like to use with - the --profile option.
  4. -
  5. C++ compiler: if necessary, specify the path to the profile library - headers (normally -I option).
  6. -
  7. Linker: link the profile library to the application.
  8. -
+ + + + + -

The remaining chapters in this part of the manual describe the - standard profiles provided by ODB.

+ + + + + + + + + + - + + + + + + + + + + -
-

18 Boost Profile

+ + + + + -

The ODB profile implementation for Boost is provided by the - libodb-boost library and consists of multiple sub-profiles - corresponding to the individual Boost libraries. To enable all the - available Boost sub-profiles, pass boost as the profile - name to the --profile ODB compiler option. Alternatively, - you can enable only specific sub-profiles by passing individual - sub-profile names to --profile. The following sections in - this chapter discuss each Boost sub-profile in detail. The - boost example in the odb-examples - package shows how to enable and use the Boost profile.

+ + + + + -

Some sub-profiles may throw exceptions to indicate error conditions, - such as the inability to store a specific value in a particular database - system. All such exceptions derive from the - odb::boost::exception class which in turn derives from - the root of the ODB exception hierarchy, class odb::exception - (Section 3.13, "ODB Exceptions"). The - odb::boost::exception class is defined in the - <odb/boost/exception.hxx> header file and has the - same interface as odb::exception. The concrete exceptions - that can be thrown by the Boost sub-profiles are described in the - following sections.

+ + + + + -

18.1 Smart Pointers Library

+ + + + + -

The smart-ptr sub-profile provides persistence - support for a subset of smart pointers from the Boost - smart_ptr library. To enable only this profile, - pass boost/smart-ptr to the --profile - ODB compiler option.

+
C++ TypeSQL Server TypeDefault NULL Semantics
boolBITNOT NULL
charTINYINTNOT NULL
signed charTINYINTNOT NULL
unsigned charTINYINTNOT NULL
shortSMALLINTNOT NULL
unsigned shortSMALLINTNOT NULL
intINTNOT NULL
unsigned intINTNOT NULL
longBIGINTNOT NULL
unsigned longBIGINTNOT NULL
long longBIGINTNOT NULL
unsigned long longBIGINTNOT NULL
floatREALNOT NULL
doubleFLOATNOT NULL
std::stringVARCHAR(512)/VARCHAR(256)NOT NULL
std::wstringNVARCHAR(512)/NVARCHAR(256)NOT NULL
GUIDUNIQUEIDENTIFIERNOT NULL
-

The currently supported smart pointers are - boost::shared_ptr and boost::weak_ptr. For - more information on using smart pointers as pointers to objects and - views, refer to Section 3.2, "Object and View Pointers" - and Chapter 6, "Relationships". For more information - on using smart pointers as pointers to values, refer to - Section 7.3, "Pointers and NULL Value - Semantics". When used as a pointer to a value, only - boost::shared_ptr is supported. For example:

+

Note that the std::string and std::wstring + types are mapped differently depending on whether a member of one of + these types is an object id or not. If the member is an object id, + then for this member std::string is mapped + to VARCHAR(256) and std::wstring — + to NVARCHAR(256). Otherwise, std::string + is mapped to VARCHAR(512) and std::wstring + — to NVARCHAR(512). Note also that you can + always change this mapping using the db type pragma + (Section 12.4.3, "type").

+ +

The SQL Server ODB runtime library also provides support for mapping the + std::string type to the SQL Server CHAR and + TEXT types as well as std::wstring + to NCHAR and NTEXT. There is also support + for mapping the std::vector<char>, + std::vector<unsigned char>, + char[N], and unsigned char[N] types to + the SQL Server BINARY, VARBINARY, and + IMAGE types. However, these + mappings are not enabled by default (in particular, by default, + std::vector will be treated as a container). To enable the + 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:

 #pragma db object
-class person
+class object
 {
   ...
 
-  #pragma db null
-  boost::shared_ptr<std::string> middle_name_;
+  #pragma db type ("CHAR(5)")
+  std::string str_;
+
+  #pragma db type("VARBINARY(max)")
+  std::vector<char> buf_;
+
+  #pragma db type("BINARY(16)")
+  unsigned char[16] uuid_;
 };
   
-

To provide finer grained control over object relationship loading, - the smart-ptr sub-profile also provides the lazy - counterparts for the above pointers: odb::boost::lazy_shared_ptr and - odb::boost::lazy_weak_ptr. You will need to include the - <odb/boost/lazy-ptr.hxx> header file to make the lazy - variants available in your application. For the description of the lazy - pointer interface and semantics refer to Section 6.3, - "Lazy Pointers". The following example shows how we can use these - smart pointers to establish a relationship between persistent objects.

+

Alternatively, this can be done on the per-type basis, for example:

-
+  
+typedef std::vector<char> buffer;
+#pragma db value(buffer) type("VARBINARY(max)")
+
+#pragma db object
+class object
+{
+  ...
+
+  buffer buf_; // Mapped to VARBINARY(max).
+};
+  
+ +

Additionally, by default, C++ enumerations are automatically + mapped to INT with the default NULL + semantics being NOT NULL.

+ +

For SQL Server, ODB handles character, national character, and + binary data in two different ways depending on its maximum length. + If the maximum length (in bytes) is less than or equal to the limit + specified with the --mssql-short-limit ODB compiler + option (1024 by default), then it is treated as short data, + otherwise — long data. For short data ODB pre-allocates + an intermediate buffer of the maximum size and binds it directly + to a parameter or result column. This way the underlying database + API (ODBC) can read/write directly from/to this buffer. In the case + of long data, the data is read/written in chunks using the + SQLGetData()/SQLPutData() ODBC functions. + While the long data approach reduces the amount of memory used by + the application, it may require greater CPU resources.

+ +

Long data has a number of limitations. In particular, when setting + a custom short data limit, make sure that it is sufficiently large + so that no object id in the application is treated as long data. + It is also impossible to load an object or view with long data more + than once as part of a query result iteration (Section + 4.4, "Query Result"). Any such attempt will result in the + odb::mssql::long_data_reload exception + (Section 17.4, "SQL Server Exceptions"). For + example:

+ +
+#pragma db object
+class object
+{
+  ...
+
+  int num_;
+
+  #pragma db type("VARCHAR(max)") // Long data.
+  std::string str_;
+};
+
+typedef odb::query<object> query;
+typedef odb::result<object> result;
+
+transaction t (db.begin ());
+
+result r (db.query<object> (query::num < 100));
+
+for (result::iterator i (r.begin ()); i != r.end (); ++i)
+{
+  if (!i->str_.empty ()) // First load.
+  {
+    object o;
+    i.load (o); // Error: second load, long_data_reload is thrown.
+  }
+}
+
+t.commit ();
+  
+ +

Finally, if a native view (Section 9.5, "Native + Views") contains one or more long data members, then such + members should come last both in the select-list of the native + SQL query and the list of data members in the C++ class.

+ +

Note also that because SQL Server does not support unsigned integers, + the unsigned short, unsigned int, and + unsigned long/unsigned long long C++ types + are by default mapped to the SMALLINT, INT, + and BIGINT SQL Server types, respectively. The sign bit + of the value stored by the database for these types will contain + the most significant bit of the actual unsigned value being + persisted. Similarly, because there is no signed version of the + TINYINT SQL Server type, by default, char + and signed char C++ types are mapped to + TINYINT. As result, the most significant bit of + the value stored by the database for these types will contain the + sign bit of the actual signed value being persisted.

+ +

17.2 SQL Server Database Class

+ +

The SQL Server database class encapsulates the ODBC + environment handle as well as the server instance address and + user credentials that are used to establish connections to the + database. It has the following interface:

+ +
+namespace odb
+{
+  namespace mssql
+  {
+    enum protocol
+    {
+      protocol_auto,
+      protocol_tcp, // TCP/IP.
+      protocol_lpc, // Shared memory (local procedure call).
+      protocol_np   // Named pipes.
+    };
+
+    class database: public odb::database
+    {
+    public:
+      database (const std::string& user,
+                const std::string& password,
+                const std::string& db,
+                const std::string& server,
+                const std::string& driver = "",
+                const std::string& extra_connect_string = "",
+                SQLHENV environment = 0,
+                std::auto_ptr<connection_factory> = 0);
+
+      database (const std::string& user,
+                const std::string& password,
+                const std::string& db,
+                protocol_type protocol = protocol_auto,
+                const std::string& host = "",
+                const std::string& instance = "",
+                const std::string& driver = "",
+                const std::string& extra_connect_string = "",
+                SQLHENV environment = 0,
+                std::auto_ptr<connection_factory> = 0);
+
+      database (const std::string& user,
+                const std::string& password,
+                const std::string& db,
+                const std::string& host,
+                unsigned int port,
+                const std::string& driver = "",
+                const std::string& extra_connect_string = "",
+                SQLHENV environment = 0,
+                std::auto_ptr<connection_factory> = 0);
+
+      database (const std::string& connect_string,
+                SQLHENV environment = 0,
+                std::auto_ptr<connection_factory> = 0);
+
+      database (int& argc,
+                char* argv[],
+                bool erase = false,
+                const std::string& extra_connect_string = "",
+                SQLHENV environment = 0,
+                std::auto_ptr<connection_factory> = 0);
+
+      static void
+      print_usage (std::ostream&);
+
+    public:
+      const std::string&
+      user () const;
+
+      const std::string&
+      password () const;
+
+      const std::string&
+      db () const;
+
+      protocol_type
+      protocol () const;
+
+      const std::string&
+      host () const;
+
+      const std::string&
+      instance () const;
+
+      unsigned int
+      port () const;
+
+      const std::string&
+      server () const;
+
+      const std::string&
+      driver () const;
+
+      const std::string&
+      extra_connect_string () const;
+
+      const std::string&
+      connect_string () const;
+
+      SQLHENV
+      environment ();
+
+    public:
+      connection_ptr
+      connection ();
+    };
+  }
+}
+  
+ +

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

+ +

The overloaded database constructors allow us to specify the + SQL Server database parameters that should be used when connecting to the + database. The user and password arguments + specify the login name and password. If user is empty, + then Windows authentication is used and the password + argument is ignored. The db argument specifies the + database name to open. If it is empty, then the default database for + the user is used.

+ +

The server argument in the first constructor specifies + the SQL Server instance address in the standard SQL Server address + format:

+ +

+ [protocol:]host[\instance][,port] +

+ +

Where protocol can be tcp + (TCP/IP), lpc (shared memory), or + np (named pipe). If protocol is not specified, then a + suitable protocol is automatically selected based on the SQL Server + Native Client configuration. The host component + can be a host name or an IP address. If instance + is not specified, then the default SQL Server instance is assumed. + If port is not specified, then the default SQL Server port is + used (1433). Note that you would normally specify either the + instance name or the port, but not both. If both are specified, + then the instance name is ignored by the SQL Server Native Client + ODBC driver. For more information on the format of the SQL + Server address, refer to the SQL Server Native Client ODBC + driver documentation.

+ +

The second and third constructors allow us to specify all these address + components (protocol, host, instance, and port) as separate + arguments. The third constructor always connects using TCP/IP + to the specified host and port.

+ +

The driver argument specifies the SQL Server Native + Client ODBC driver that should be used to connect to the database. + If not specified, then the latest available version is used. The + following examples show common ways of connecting to the database + using the first three constructors:

+ +
+// Connect to the default SQL Server instance on the local machine
+// using the default protocol. Login as 'test' with password 'secret'
+// and open the 'example_db' database.
+//
+odb::mssql::database db1 ("test",
+                          "secret",
+                          "example_db");
+
+// As above except use Windows authentication and open the default
+// database for this user.
+//
+odb::mssql::database db2 ("",
+                          "",
+                          "");
+
+// Connect to the default SQL Server instance on 'onega' using the
+// default protocol. Login as 'test' with password 'secret' and open
+// the 'example_db' database.
+//
+odb::mssql::database db3 ("test",
+                          "secret",
+                          "example_db"
+                          "onega");
+
+// As above but connect to the 'production' SQL Server instance.
+//
+odb::mssql::database db4 ("test",
+                          "secret",
+                          "example_db"
+                          "onega\\production");
+
+// Same as above but specify protocol, host, and instance as separate
+// arguments.
+//
+odb::mssql::database db5 ("test",
+                          "secret",
+                          "example_db",
+                          odb::mssql::protocol_auto,
+                          "onega",
+                          "production");
+
+// As above, but use TCP/IP as the protocol.
+//
+odb::mssql::database db6 ("test",
+                          "secret",
+                          "example_db"
+                          "tcp:onega\\production");
+
+// Same as above but using separate arguments.
+//
+odb::mssql::database db7 ("test",
+                          "secret",
+                          "example_db",
+                          odb::mssql::protocol_tcp,
+                          "onega",
+                          "production");
+
+// As above, but use TCP/IP port instead of the instance name.
+//
+odb::mssql::database db8 ("test",
+                          "secret",
+                          "example_db"
+                          "tcp:onega,1435");
+
+// Same as above but using separate arguments. Note that here we
+// don't need to specify protocol explicitly since it can only
+// be TCP/IP.
+//
+odb::mssql::database db9 ("test",
+                          "secret",
+                          "example_db",
+                          "onega",
+                          1435);
+
+// As above but use the specific SQL Server Native Client ODBC
+// driver version.
+//
+odb::mssql::database dbA ("test",
+                          "secret",
+                          "example_db"
+                          "tcp:onega,1435",
+                          "SQL Server Native Client 10.0");
+  
+ + +

The forth constructor allows us to pass a custom ODBC connection + string that provides all the information necessary to connect to + the database. Note also that all the other constructors have the + extra_connect_string argument which can be used to + specify additional ODBC connection attributes. For more information + on the format of the ODBC connection string, refer to the SQL + Server Native Client ODBC driver documentation.

+ +

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

+ +
+  --user | -U <login>
+  --password | -P <password>
+  --database | -d <name>
+  --server | -S <address>
+  --driver <name>
+  --options-file <file>
+  
+ +

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.

+ +

If the erase argument to this constructor is true, + then the above options are removed from the argv + array and the argc count is updated accordingly. + This is primarily useful if your application accepts other + options or arguments and you would like to get the SQL Server + options out of the argv array.

+ +

This constructor throws the odb::mssql::cli_exception + exception if the SQL Server option values are missing or invalid. See + section Section 17.4, "SQL Server Exceptions" for + more information on this exception.

+ +

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

+ +

Additionally, all the constructors have the environment + argument which allows us to provide a custom ODBC environment handle. + If this argument is not NULL, then the passed handle is + used in all the ODBC 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.

+ +

The last argument to all of the constructors is a pointer to a + connection factory. If we pass a non-NULL 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.

+ +

The set of accessor functions following the constructors allows us + to query the parameters of the database instance.

+ +

The connection() function returns a pointer to the + SQL Server database connection encapsulated by the + odb::mssql::connection class. For more information + on mssql::connection, refer to Section + 17.3, "SQL Server Connection and Connection Factory".

+ +

17.3 SQL Server Connection and Connection Factory

+ +

The mssql::connection class has the following interface:

+ +
+namespace odb
+{
+  namespace mssql
+  {
+    class connection: public odb::connection
+    {
+    public:
+      connection (database&);
+      connection (database&, SQLHDBC handle);
+
+      SQLHDBC
+      handle ();
+
+      details::buffer&
+      long_data_buffer ();
+    };
+
+    typedef details::shared_ptr<connection> connection_ptr;
+  }
+}
+  
+ +

For more information on the odb::connection interface, refer + to Section 3.5, "Connections". The first overloaded + mssql::connection constructor creates a new ODBC connection. + The created connection is configured to use the manual commit mode with + multiple active result sets (MARS) enabled. The second constructor allows + us to create a connection instance by providing an already + established ODBC connection. Note that the connection + instance assumes ownership of this handle. The handle() + accessor returns the underlying ODBC connection handle associated with + the connection instance.

+ +

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

+ +

The mssql::connection_factory abstract class has the + following interface:

+ +
+namespace odb
+{
+  namespace mssql
+  {
+    class connection_factory
+    {
+    public:
+      virtual void
+      database (database&) = 0;
+
+      virtual connection_ptr
+      connect () = 0;
+    };
+  }
+}
+  
+ +

The database() function is called when a connection + factory is associated with a database instance. This happens in + the odb::mssql::database class constructors. The + connect() function is called whenever a database + connection is requested.

+ +

The two implementations of the connection_factory + interface provided by the SQL Server ODB runtime are + new_connection_factory and + connection_pool_factory. You will need to include + the <odb/mssql/connection-factory.hxx> + header file to make the connection_factory interface + and these implementation classes available in your application.

+ +

The new_connection_factory class creates a new + connection whenever one is requested. When a connection is no + longer needed, it is released and closed. The + new_connection_factory class has the following + interface:

+ +
+namespace odb
+{
+  namespace mssql
+  {
+    class new_connection_factory: public connection_factory
+    {
+    public:
+      new_connection_factory ();
+    };
+};
+  
+ +

The connection_pool_factory class implements a + connection pool. It has the following interface:

+ +
+namespace odb
+{
+  namespace mssql
+  {
+    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&);
+        pooled_connection (database_type&, SQLHDBC handle);
+      };
+
+      typedef details::shared_ptr<pooled_connection> pooled_connection_ptr;
+
+      virtual pooled_connection_ptr
+      create ();
+    };
+};
+  
+ +

The max_connections argument in the + connection_pool_factory constructor specifies the maximum + number of concurrent connections that this pool factory will + maintain. Similarly, the min_connections argument + specifies the minimum number of available connections that + should be kept open.

+ +

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 + max_connections 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.

+ +

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 min_connections + 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 min_connections + and there are no callers waiting for a new connection, + the pool will close the excess connections.

+ +

If the max_connections value is 0, then the pool will + create a new connection whenever all of the existing connections + are in use. If the min_connections value is 0, then + the pool will never close a connection and instead maintain all + the connections that were ever created.

+ +

The create() virtual function is called whenever the + pool needs to create a new connection. By deriving from the + connection_pool_factory class and overriding this + function we can implement custom connection establishment + and configuration.

+ +

If you pass NULL as the connection factory to one of the + database constructors, then the + connection_pool_factory instance will be created by default + with the min and max connections values set to 0. The + following code fragment shows how we can pass our own connection factory + instance:

+ +
+#include <odb/database.hxx>
+
+#include <odb/mssql/database.hxx>
+#include <odb/mssql/connection-factory.hxx>
+
+int
+main (int argc, char* argv[])
+{
+  auto_ptr<odb::mssql::connection_factory> f (
+    new odb::mssql::connection_pool_factory (20));
+
+  auto_ptr<odb::database> db (
+    new mssql::database (argc, argv, false, "", 0, f));
+}
+  
+ +

17.4 SQL Server Exceptions

+ +

The SQL Server ODB runtime library defines the following + SQL Server-specific exceptions:

+ +
+namespace odb
+{
+  namespace mssql
+  {
+    class database_exception: odb::database_exception
+    {
+    public:
+      class record
+      {
+      public:
+        SQLINTEGER
+        error () const;
+
+        const std::string&
+        sqlstate () 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 ();
+    };
+
+    class cli_exception: odb::exception
+    {
+    public:
+      virtual const char*
+      what () const throw ();
+    };
+
+    class long_data_reload: odb::exception
+    {
+    public:
+      virtual const char*
+      what () const throw ();
+    };
+  }
+}
+  
+ +

You will need to include the <odb/mssql/exceptions.hxx> + header file to make these exceptions available in your application.

+ +

The odb::mssql::database_exception is thrown if + an SQL Server database operation fails. The SQL Server-specific error + information is stored as a series of records, each containing + the error code as a signed 4-byte integer, the SQLSTATE code, + and the message string. All this information is also combined + and returned in a human-readable form by the what() + function.

+ +

The odb::mssql::cli_exception is thrown by the + command line parsing constructor of the odb::mssql::database + class if the SQL Server option values are missing or invalid. The + what() function returns a human-readable description + of an error.

+ +

The odb::mssql::long_data_reload is thrown if an + attempt is made to re-load an object or view with long data as + part of a query result iteration. For more information, refer + to Section 17.1, "SQL Server Type Mapping".

+ +

17.5 SQL Server Limitations

+ +

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

+ +

17.5.1 Query Result Caching

+ +

SQL Server ODB runtime implementation does not perform query result + caching (Section 4.4, "Query Result") even when + explicitly requested. The ODBC API and the SQL Server Native Client ODBC + driver support interleaving execution of multiple prepared statements + on a single connection. As a result, it is possible to have multiple + uncached results and calls to other database functions do not invalidate + them. The only limitation of the uncached SQL Server results is the + unavailability of the result::size() function. If you + call this function on an SQL Server query result, then the + odb::result_not_cached exception (Section + 3.13, "ODB Exceptions") is always thrown. Future versions of the + SQL Server ODB runtime library may add support for result caching.

+ +

17.5.2 Foreign Key Constraints

+ +

ODB relies on standard SQL behavior which requires that foreign + key constraints checking is deferred until the transaction is + committed. The only behavior supported by SQL Server is to check + such constraints immediately. As a result, schemas generated by + the ODB compiler for SQL Server have foreign key definitions + commented out. They are retained only for documentation.

+ +

17.5.3 Unique Constraint Violations

+ +

Due to the granularity of the ODBC 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 SQL Server ODB runtime will translate all unique constraint violation + errors to the object_already_persistent exception + (Section 3.13, "ODB Exceptions").

+ +

17.5.4 Multithreaded Windows Applications

+ +

Multithreaded Windows applications must use the + _beginthread()/_beginthreadex() and + _endthread()/_endthreadex() CRT functions + instead of the CreateThread() and EndThread() + Win32 functions to start and terminate threads. This is a limitation of + the ODBC implementation on Windows.

+ +

17.5.5 Affected Row Count and DDL Statements

+ +

SQL Server always returns zero as the number of affected rows + for DDL statements. In particular, this means that the + database::execute() (Section 3.11, + "Executing Native SQL Statements") function will always + return zero for such statements.

+ +

17.5.6 Long Data and Automatically Assigned Object Ids

+ +

SQL Server 2005 has a bug that causes it to fail on an INSERT + statement with the OUTPUT clause (used to return + automatically assigned object ids) if one of the inserted columns + is long data. The symptom of this bug in ODB is an exception thrown + by the database::persist() function when used on an + object that contains long data and has an automatically assigned + object id. The error message reads "This operation conflicts with + another pending operation on this transaction. The operation failed."

+ +

ODB includes a workaround for this bug which uses a less efficient + method to obtain automatically assigned object ids for objects that + contain long data. To enable this workaround you need to specify + that the generated code will be used with SQL Server 2005 or later + by passing the --mssql-server-version 9.0 ODB + compiler option.

+ + + + + +
+

PART III   + PROFILES

+ +

Part III covers the integration of ODB with popular C++ frameworks + and libraries. It consists of the following chapters.

+ + + + + +
18Profiles Introduction
19Boost Profile
20Qt Profile
+ + + + + +
+

18 Profiles Introduction

+ +

ODB profiles are a generic mechanism for integrating ODB with + widely-used C++ frameworks and libraries. A profile provides glue + code which allows you to seamlessly persist various components, such + as smart pointers, containers, and value types found in these + frameworks or libraries. The code necessary to implement a profile + is packaged into the so called profile library. For example, the + Boost profile implementation is provided by the libodb-boost + profile library.

+ +

Besides linking the profile library to our application, it is also + necessary to let the ODB compiler know which profiles we + are using. This is accomplished with the --profile + (or -p alias) option. For example:

+ +
+odb --profile boost ...
+  
+ +

Some profiles, especially those covering frameworks or libraries that + consist of multiple sub-libraries, provide sub-profiles that allow you + to pick and choose which components you would like to use in your + application. For example, the boost profile contains + the boost/data-time sub-profile. If we are only + interested in the date_time types, then we can + pass boost/data-time instead of boost + to the --profile option, for example:

+ +
+odb --profile boost/date-time ...
+  
+ +

To summarize, you will need to perform the following steps in order + to make use of a profile in your application:

+ +
    +
  1. ODB compiler: if necessary, specify the path to the profile library + headers (-I option).
  2. +
  3. ODB compiler: specify the profile you would like to use with + the --profile option.
  4. +
  5. C++ compiler: if necessary, specify the path to the profile library + headers (normally -I option).
  6. +
  7. Linker: link the profile library to the application.
  8. +
+ +

The remaining chapters in this part of the manual describe the + standard profiles provided by ODB.

+ + + + + +
+

19 Boost Profile

+ +

The ODB profile implementation for Boost is provided by the + libodb-boost library and consists of multiple sub-profiles + corresponding to the individual Boost libraries. To enable all the + available Boost sub-profiles, pass boost as the profile + name to the --profile ODB compiler option. Alternatively, + you can enable only specific sub-profiles by passing individual + sub-profile names to --profile. The following sections in + this chapter discuss each Boost sub-profile in detail. The + boost example in the odb-examples + package shows how to enable and use the Boost profile.

+ +

Some sub-profiles may throw exceptions to indicate error conditions, + such as the inability to store a specific value in a particular database + system. All such exceptions derive from the + odb::boost::exception class which in turn derives from + the root of the ODB exception hierarchy, class odb::exception + (Section 3.13, "ODB Exceptions"). The + odb::boost::exception class is defined in the + <odb/boost/exception.hxx> header file and has the + same interface as odb::exception. The concrete exceptions + that can be thrown by the Boost sub-profiles are described in the + following sections.

+ +

19.1 Smart Pointers Library

+ +

The smart-ptr sub-profile provides persistence + support for a subset of smart pointers from the Boost + smart_ptr library. To enable only this profile, + pass boost/smart-ptr to the --profile + ODB compiler option.

+ +

The currently supported smart pointers are + boost::shared_ptr and boost::weak_ptr. For + more information on using smart pointers as pointers to objects and + views, refer to Section 3.2, "Object and View Pointers" + and Chapter 6, "Relationships". For more information + on using smart pointers as pointers to values, refer to + Section 7.3, "Pointers and NULL Value + Semantics". When used as a pointer to a value, only + boost::shared_ptr is supported. For example:

+ +
+#pragma db object
+class person
+{
+  ...
+
+  #pragma db null
+  boost::shared_ptr<std::string> middle_name_;
+};
+  
+ +

To provide finer grained control over object relationship loading, + the smart-ptr sub-profile also provides the lazy + counterparts for the above pointers: odb::boost::lazy_shared_ptr and + odb::boost::lazy_weak_ptr. You will need to include the + <odb/boost/lazy-ptr.hxx> header file to make the lazy + variants available in your application. For the description of the lazy + pointer interface and semantics refer to Section 6.3, + "Lazy Pointers". The following example shows how we can use these + smart pointers to establish a relationship between persistent objects.

+ +
 class employee;
 
 #pragma db object
@@ -13333,7 +14285,7 @@ class employee
   #pragma db not_null
   boost::shared_ptr<position> position_;
 };
-
+

Besides providing persistence support for the above smart pointers, the smart-ptr sub-profile also changes the default @@ -13344,7 +14296,7 @@ class employee this behavior, add the --default-pointer option specifying the alternative pointer type after the --profile option.

-

18.2 Unordered Containers Library

+

19.2 Unordered Containers Library

The unordered sub-profile provides persistence support for the containers from the Boost unordered library. To enable @@ -13361,16 +14313,16 @@ class employee the unordered_set container may be used within a persistent object.

-
+  
 #pragma db object
 class person
 {
   ...
   boost::unordered_set<std::string> emails_;
 };
-
+
-

18.3 Optional Library

+

19.3 Optional Library

The optional sub-profile provides persistence support for the boost::optional container from the Boost @@ -13402,7 +14354,7 @@ class person this profile is used, the NULL values are automatically enabled for data members of the boost::optional type.

-

18.4 Date Time Library

+

19.4 Date Time Library

The date-time sub-profile provides persistence support for a subset of types from the Boost date_time library. It is @@ -13427,20 +14379,20 @@ class person sub-sections that follow. The example below shows how gregorian::date may be used within a persistent object.

-
+  
 #pragma db object
 class person
 {
   ...
   boost::gregorian::date date_of_birth_;
 };
-
+

The concrete exceptions that can be thrown by the date-time sub-profile implementation are presented below.

-
+  
 namespace odb
 {
   namespace boost
@@ -13461,7 +14413,7 @@ namespace odb
     }
   }
 }
-
+

You will need to include the <odb/boost/date-time/exceptions.hxx> header file to @@ -13475,7 +14427,7 @@ namespace odb exceptions are thrown are database system dependent and are discussed in more detail in the following sub-sections.

-

18.4.1 MySQL Database Type Mapping

+

19.4.1 MySQL Database Type Mapping

The following table summarizes the default mapping between the currently supported Boost date_time types and the MySQL database @@ -13518,7 +14470,7 @@ namespace odb (Section 12.4.3, "type"), as shown in the following example:

-
+  
 #pragma db object
 class person
 {
@@ -13526,7 +14478,7 @@ class person
   #pragma db type("TIMESTAMP") not_null
   boost::posix_time::ptime updated_;
 };
-
+

Some valid Boost date-time values cannot be stored in a MySQL database. An attempt to persist any Boost date-time special value other than @@ -13536,7 +14488,7 @@ class person the out_of_range exception. Refer to the MySQL documentation for more information on the MySQL data type ranges.

-

18.4.2 SQLite Database Type Mapping

+

19.4.2 SQLite Database Type Mapping

The following table summarizes the default mapping between the currently supported Boost date_time types and the SQLite database @@ -13582,7 +14534,7 @@ class person db type pragma (Section 12.4.3, "type"), as shown in the following example:

-
+  
 #pragma db object
 class person
 {
@@ -13590,7 +14542,7 @@ class person
   #pragma db type("INTEGER")
   boost::gregorian::date born_;
 };
-
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Boost date_time TypeSQL Server TypeDefault NULL Semantics
gregorian::dateDATENULL
posix_time::ptimeDATETIME2NULL
posix_time::time_durationTIMENULL
+ +

The Boost special value date_time::not_a_date_time is stored + as a NULL value in an SQL Server database.

+ +

Note that the DATE, TIME, and + DATETIME2 types are only available in SQL Server 2008 and + later. SQL Server 2005 only supports the DATETIME and + SMALLDATETIME date-time types and the new types are + also unavailable when connecting to an SQL Server 2008 or + later with the SQL Server 2005 Native Client ODBC driver.

+ +

The date-time sub-profile implementation provides + support for mapping posix_time::ptime to the + DATETIME and SMALLDATETIME types, + however, this mapping has to be explicitly requested using the + db type pragma (Section 12.4.3, + "type"), as shown in the following example:

+ +
+#pragma db object
+class person
+{
+  ...
+  #pragma db type("DATETIME")
+  boost::posix_time::ptime updated_;
+};
+  
+ +

Some valid Boost date-time values cannot be stored in an SQL Server + database. An attempt to persist a gregorian::date, + posix_time::ptime, or posix_time::time_duration + value representing any special value other than + date_time::not_a_date_time will result in the + special_value exception. The range of the TIME + type in SQL server is from 00:00:00.0000000 to + 23:59:59.9999999. An attempt to persist a + posix_time::time_duration value out of this range will + result in the value_out_of_range exception.

+ +
-

19 Qt Profile

+

20 Qt Profile

The ODB profile implementation for Qt is provided by the libodb-qt library and consists of multiple sub-profiles @@ -13739,7 +14763,7 @@ class person that can be thrown by the Qt sub-profiles are described in the following sections.

-

19.1 Basic Types

+

20.1 Basic Types

The basic sub-profile provides persistence support for basic types defined by Qt. To enable only this profile, pass @@ -13752,16 +14776,16 @@ class person sub-sections that follow. The example below shows how QString may be used within a persistent object.

-
+  
 #pragma db object
 class Person
 {
   ...
   QString name_;
 };
-
+
-

19.1.1 MySQL Database Type Mapping

+

20.1.1 MySQL Database Type Mapping

The following table summarizes the default mapping between the currently supported basic Qt types and the MySQL database types.

@@ -13792,7 +14816,7 @@ class Person function returns true.

Note also that the QString type is mapped - differently depending on whether the member of this type + differently depending on whether a member of this type is an object id or not. If the member is an object id, then for this member QString is mapped to the VARCHAR(255) MySQL type. Otherwise, @@ -13818,7 +14842,7 @@ class Person

-

19.1.2 SQLite Database Type Mapping

+

20.1.2 SQLite Database Type Mapping

The following table summarizes the default mapping between the currently supported basic Qt types and the SQLite database types.

@@ -13848,7 +14872,7 @@ class Person are stored as a NULL value if their isNull() member function returns true.

-

19.1.3 PostgreSQL Database Type Mapping

+

20.1.3 PostgreSQL Database Type Mapping

The following table summarizes the default mapping between the currently supported basic Qt types and the PostgreSQL database types.

@@ -13897,7 +14921,7 @@ class Person }; -

19.1.4 Oracle Database Type Mapping

+

20.1.4 Oracle Database Type Mapping

The following table summarizes the default mapping between the currently supported basic Qt types and the Oracle database types.

@@ -13950,7 +14974,68 @@ class Person }; -

19.2 Smart Pointers

+

20.1.5 SQL Server Database Type Mapping

+ +

The following table summarizes the default mapping between the currently + supported basic Qt types and the SQL Server database types.

+ + + + + + + + + + + + + + + + + + + + +
Qt TypeSQL Server TypeDefault NULL Semantics
QStringVARCHAR(512)/VARCHAR(256)NULL
QByteArrayVARBINARY(max)NULL
+ +

Instances of the QString and QByteArray types + are stored as a NULL value if their isNull() member + function returns true.

+ +

Note also that the QString type is mapped + differently depending on whether a member of this type + is an object id or not. If the member is an object id, + then for this member QString is mapped + to the VARCHAR(256) SQL Server type. Otherwise, + it is mapped to VARCHAR(512).

+ +

The basic sub-profile also provides support + for mapping QString to the CHAR, + NCHAR, NVARCHAR, TEXT, and + NTEXT SQL Server types, and for mapping + QByteArray to the BINARY and + IMAGE SQL Server types. However, these alternative + mappings have to be explicitly requested using the db type + pragma (Section 12.4.3, "type"), as shown in the + following example:

+ +
+#pragma db object
+class Person
+{
+  ...
+
+  #pragma db type("NVARCHAR(256)") not_null
+  QString firstName_;
+
+  #pragma db type("BINARY(16)") null
+  QByteArray uuid_;
+};
+  
+ +

20.2 Smart Pointers

The smart-ptr sub-profile provides persistence support the Qt smart pointers. To enable only this profile, pass @@ -13988,7 +15073,7 @@ class person "Lazy Pointers". The following example shows how we can use these smart pointers to establish a relationship between persistent objects.

-
+  
 class Employee;
 
 #pragma db object
@@ -14008,7 +15093,7 @@ class Employee
   #pragma db not_null
   QSharedPointer<Position> position_;
 };
-
+

Besides providing persistence support for the above smart pointers, the smart-ptr sub-profile also changes the default @@ -14019,7 +15104,7 @@ class Employee this behavior, add the --default-pointer option specifying the alternative pointer type after the --profile option.

-

19.3 Containers Library

+

20.3 Containers Library

The container sub-profile provides persistence support for Qt containers. To enable only this profile, pass @@ -14035,16 +15120,16 @@ class Employee The following example shows how the QSet container may be used within a persistent object.

-
+  
 #pragma db object
 class Person
 {
   ...
   QSet<QString> emails_;
 };
-
+
-

19.4 Date Time Types

+

20.4 Date Time Types

The date-time sub-profile provides persistence support for the Qt date-time types. To enable only this profile, pass @@ -14057,20 +15142,20 @@ class Person discussed in the sub-sections that follow. The example below shows how QDate may be used within a persistent object.

-
+  
 #pragma db object
 class Person
 {
   ...
   QDate dateOfBirth_;
 };
-
+

The single concrete exception that can be thrown by the date-time sub-profile implementation is presented below.

-
+  
 namespace odb
 {
   namespace qt
@@ -14085,7 +15170,7 @@ namespace odb
     }
   }
 }
-
+

You will need to include the <odb/qt/date-time/exceptions.hxx> header file to @@ -14097,7 +15182,7 @@ namespace odb system dependent and is discussed in more detail in the following sub-sections.

-

19.4.1 MySQL Database Type Mapping

+

20.4.1 MySQL Database Type Mapping

The following table summarizes the default mapping between the currently supported Qt date-time types and the MySQL database types.

@@ -14140,7 +15225,7 @@ namespace odb (Section 12.4.3, "type"), as shown in the following example:

-
+  
 #pragma db object
 class Person
 {
@@ -14148,7 +15233,7 @@ class Person
   #pragma db type("TIMESTAMP") not_null
   QDateTime updated_;
 };
-
+

Some valid Qt date-time values cannot be stored in a MySQL database. An attempt to persist a Qt date-time value that is out of the MySQL type @@ -14156,7 +15241,7 @@ class Person the MySQL documentation for more information on the MySQL data type ranges.

-

19.4.2 SQLite Database Type Mapping

+

20.4.2 SQLite Database Type Mapping

The following table summarizes the default mapping between the currently supported Qt date-time types and the SQLite database types.

@@ -14202,7 +15287,7 @@ class Person (Section 12.4.3, "type"), as shown in the following example:

-
+  
 #pragma db object
 class Person
 {
@@ -14210,7 +15295,7 @@ class Person
   #pragma db type("INTEGER")
   QDate born_;
 };
-
+

Some valid Qt date-time values cannot be stored in an SQLite database. An attempt to persist any Qt date-time value representing a negative UNIX @@ -14218,7 +15303,7 @@ class Person epoch) as an SQLite INTEGER will result in the out_of_range exception.

-

19.4.3 PostgreSQL Database Type Mapping

+

20.4.3 PostgreSQL Database Type Mapping

The following table summarizes the default mapping between the currently supported Qt date-time types and the PostgreSQL database types.

@@ -14254,7 +15339,7 @@ class Person QDateTime types are stored as a NULL value if their isNull() member function returns true.

-

19.4.4 Oracle Database Type Mapping

+

20.4.4 Oracle Database Type Mapping

The following table summarizes the default mapping between the currently supported Qt date-time types and the Oracle database types.

@@ -14290,6 +15375,66 @@ class Person QDateTime types are stored as a NULL value if their isNull() member function returns true.

+

20.4.5 SQL Server Database Type Mapping

+ +

The following table summarizes the default mapping between the currently + supported Qt date-time types and the SQL Server database types.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Qt Date Time TypeSQL Server TypeDefault NULL Semantics
QDateDATENULL
QTimeTIME(3)NULL
QDateTimeDATETIME2(3)NULL
+ +

Instances of the QDate, QTime, and + QDateTime types are stored as a NULL value if their + isNull() member function returns true.

+ +

Note that the DATE, TIME, and + DATETIME2 types are only available in SQL Server 2008 and + later. SQL Server 2005 only supports the DATETIME and + SMALLDATETIME date-time types and the new types are + also unavailable when connecting to an SQL Server 2008 or + later with the SQL Server 2005 Native Client ODBC driver.

+ +

The date-time sub-profile implementation provides + support for mapping QDateTime to the DATETIME + and SMALLDATETIME types, however, this mapping has to + be explicitly requested using the db type pragma + (Section 12.4.3, "type"), as + shown in the following example:

+ +
+#pragma db object
+class person
+{
+  ...
+  #pragma db type("DATETIME")
+  QDateTime updated_;
+};
+  
+ -- cgit v1.1