From 6a91d389610a1809718a5a396128580df811e476 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 31 Mar 2011 16:08:42 +0200 Subject: Add SQLite chapter --- doc/manual.xhtml | 622 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 593 insertions(+), 29 deletions(-) diff --git a/doc/manual.xhtml b/doc/manual.xhtml index b586bf9..e0d5177 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -8,8 +8,8 @@ - - + + -

Revision 1.2, March 2011

-

This revision of the manual describes ODB 1.2.0 and is available +

Revision 1.3.b1, March 2011

+

This revision of the manual describes ODB 1.3.0.b1 and is available in the following formats: XHTML, PDF, and @@ -467,29 +467,50 @@ for consistency. - +
10.1MySQL Type Mapping
10.2MySQL Database Class
10.3Connection Factory
10.3MySQL Connection Factory
10.4MySQL Exceptions
+ 11SQLite Database + + + + + + + + +
11.1SQLite Type Mapping
11.2SQLite Database Class
11.3SQLite Connection Factory
11.4SQLite Exceptions
11.5SQLite Limitations + + + + + +
11.5.1Query Result Caching
11.5.2Automatic Assignment of Object Ids
11.5.3Constraint Violations
11.5.4Sharing of Queries
+
+ + + + PART III PROFILES - 11Profiles Introduction + 12Profiles Introduction - 12Boost Profile + 13Boost Profile - - + + - @@ -6458,6 +6479,7 @@ aCC +W2161 ... as well as the default mapping between basic C++ value types and native database types.

+ @@ -6714,25 +6736,25 @@ namespace odb

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

-

The last argument to all of the constructors is the +

The last argument to all of the constructors is a pointer to the 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 allow us +

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

The connection() function returns the MySQL database connection encapsulated by the odb::mysql::connection - class. Normally, you wouldn't call this function directly and + class. Normally, we wouldn't call this function directly and instead let the ODB runtime manage the database connections. However, if for some reason you need to access the underlying MySQL connection handle, refer to the MySQL ODB runtime source code for the interface of the connection class.

-

10.3 Connection Factory

+

10.3 MySQL Connection Factory

The connection_factory abstract class has the following interface:

@@ -6763,7 +6785,7 @@ namespace odb

The two implementations of the connection_factory interface provided by the MySQL ODB runtime are - the new_connection_factory and + new_connection_factory and connection_pool_factory. You will need to include the <odb/mysql/connection-factory.hxx> header file to make the connection_factory interface @@ -6773,7 +6795,23 @@ namespace odb

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 - connection_pool_factory class implements a + new_connection_factory class has the following + interface:

+ +
+namespace odb
+{
+  namespace mysql
+  {
+    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:

@@ -6783,6 +6821,7 @@ namespace odb
   {
     class connection_pool_factory: public connection_factory
     {
+    public:
       connection_pool_factory (std::size_t max_connections = 0,
                                std::size_t min_connections = 0,
                                bool ping = true)
@@ -6804,24 +6843,24 @@ namespace odb
      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 calling thread is blocked
-     until a connection becomes available.

+ 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 threads waiting for a connection. If so, + 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 the min_connections - number and there are no threads waiting for a new connection, + connections maintained by the pool exceeds min_connections + and there are no caller waiting for a new connection, then 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 + 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.

@@ -6910,6 +6949,531 @@ namespace odb of an error.

+ + + +
+

11 SQLite Database

+ +

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

+ +

11.1 SQLite Type Mapping

+ +

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

+ + +
12.1Smart Pointers Library
12.2Unordered Containers Library
13.1Smart Pointers Library
13.2Unordered Containers Library
12.3Date Time Library + 13.3Date Time Library - +
12.3.1MySQL Database Type Mapping
13.3.1MySQL Database Type Mapping
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C++ TypeSQLite type
boolINTEGER NOT NULL
charINTEGER NOT NULL
signed charINTEGER NOT NULL
unsigned charINTEGER NOT NULL
shortINTEGER NOT NULL
unsigned shortINTEGER NOT NULL
intINTEGER NOT NULL
unsigned intINTEGER NOT NULL
longINTEGER NOT NULL
unsigned longINTEGER NOT NULL
long longINTEGER NOT NULL
unsigned long longINTEGER NOT NULL
floatREAL NOT NULL
doubleREAL NOT NULL
std::stringTEXT NOT NULL
+ +

Note 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.

+ +

11.2 SQLite Database Class

+ +

The SQLite database class has the following + interface:

+ +
+namespace odb
+{
+  namespace sqlite
+  {
+    class database: public odb::database
+    {
+    public:
+      database (const std::string& name,
+                int flags = SQLITE_OPEN_READWRITE,
+                std::auto_ptr<connection_factory> = 0);
+
+      database (int& argc,
+                char* argv[],
+                bool erase = false,
+                int flags = SQLITE_OPEN_READWRITE,
+                std::auto_ptr<connection_factory> = 0);
+
+      static void
+      print_usage (std::ostream&);
+
+    public:
+      const std::string&
+      name () const;
+
+      int
+      flags () const;
+
+    public:
+      transaction_impl*
+      begin_immediate ();
+
+      transaction_impl*
+      begin_exclusive ();
+
+    public:
+      details::shared_ptr&lt;sqlite::connection>
+      connection ();
+    };
+  }
+}
+  
+ +

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

+ +

The first constructor opens the specified SQLite database. The + name argument is the database file + name to open. If this argument is empty, then a temporary, + on-disk database is created. If this argument is the + :memory: special value, then a temporary, in-memory + database is created. The flags argument allows us to + specify SQLite opening flags. For more information on the possible + values, refer to the sqlite3_open_v2 function description + in the SQLite C API documentation. The following example shows how + we can open the test.db database in the read-write + mode and create it if it does not exist: +

+ +
+auto_ptr<odb::database> db (
+  new odb::sqlite::database (
+    "test.db",
+    SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE));
+  
+ +

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

+ +
+  --database <name>
+  --create
+  --read-only
+  --options-file <file>
+  
+ +

By default, this constructor opens the database in the read-write mode + (SQLITE_OPEN_READWRITE flag). If the --create + flag is specified, then the database file is created if it does + not already exist (SQLITE_OPEN_CREATE flag). If the + --read-only flag is specified, then the database is + opened in the read-only mode (SQLITE_OPEN_READONLY + flag instead of SQLITE_OPEN_READWRITE). 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 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 SQLite + options out of the argv array.

+ +

The flags argument has the same semantics as in + the first constructor. Flags from the command line always override + the corresponding values specified with this argument.

+ +

The second constructor throws the odb::sqlite::cli_exception + exception if the SQLite option values are missing or invalid. + See section Section 11.4, "SQLite Exceptions" + for more information on this exception.

+ +

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

+ +

The last argument to both constructors is a pointer to the 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 begin_immediate() and begin_exclusive() + functions are the SQLite-specific extensions to the standard + odb::database::begin() function (see + Section 3.4, "Transactions"). They allow us + to start an immediate (BEGIN IMMEDIATE) and an exclusive + (BEGIN EXCLUSIVE) SQLite transaction, respectively. + For more information on the semantics of the immediate and exclusive + transactions, refer to the BEGIN statement description + in the SQLite documentation.

+ +

The connection() function returns the SQLite database + connection encapsulated by the odb::sqlite::connection + class. Normally, we wouldn't call this function directly and + instead let the ODB runtime manage the database connections. However, + if for some reason you need to access the underlying SQLite connection + handle, refer to the SQLite ODB runtime source code for the interface + of the connection class.

+ +

11.3 SQLite Connection Factory

+ +

The connection_factory abstract class has the + following interface:

+ +
+namespace odb
+{
+  namespace sqlite
+  {
+    class connection_factory
+    {
+    public:
+      virtual void
+      database (sqlite::database&) = 0;
+
+      virtual details::shared_ptr<sqlite::connection>
+      connect () = 0;
+    };
+  }
+}
+  
+ +

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

+ +

The three implementations of the connection_factory + interface provided by the SQLite ODB runtime library are + single_connection_factory, + new_connection_factory, and + connection_pool_factory. You will need to include + the <odb/sqlite/connection-factory.hxx> + header file to make the connection_factory interface + and these implementation classes available in your application.

+ +

The single_connection_factory class creates a + single connection that is shared between all the threads in + an application. If the connection is currently not in use, + then it is returned to the caller. Otherwise, the caller is + blocked until the connection becomes available. The + single_connection_factory class has the following + interface:

+ +
+namespace odb
+{
+  namespace sqlite
+  {
+    class single_connection_factory: public connection_factory
+    {
+    public:
+      single_connection_factory ();
+    };
+};
+  
+ + +

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 sqlite
+  {
+    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 sqlite
+  {
+    class connection_pool_factory: public connection_factory
+    {
+    public:
+      connection_pool_factory (std::size_t max_connections = 0,
+                               std::size_t min_connections = 0)
+    };
+};
+  
+ +

The max_connections argument 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, + then 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.

+ +

By default, connections created by new_connection_factory + and connection_pool_factory enable the SQLite shared cache + mode and use the unlock notify functionality to aid concurrency. To + disable the shared cache mode you can pass the + SQLITE_OPEN_PRIVATECACHE flag when creating the database + instance. For more information on the shared cache mode refer to the + SQLite documentation.

+ +

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/sqlite/database.hxx>
+#include <odb/sqlite/connection-factory.hxx>
+
+int
+main (int argc, char* argv[])
+{
+  auto_ptr<odb::sqlite::connection_factory> f (
+    new odb::sqlite::connection_pool_factory (20));
+
+  auto_ptr<odb::database> db (
+    new sqlite::database (argc, argv, false, SQLITE_OPEN_READWRITE, f));
+}
+  
+ +

11.4 SQLite Exceptions

+ +

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

+ +
+namespace odb
+{
+  namespace sqlite
+  {
+    class database_exception: odb::database_exception
+    {
+    public:
+      int
+      error () const
+
+      int
+      extended_error () const;
+
+      const std::string&
+      message () const;
+
+      virtual const char*
+      what () const throw ();
+    };
+
+    class cli_exception: odb::exception
+    {
+    public:
+      virtual const char*
+      what () const throw ();
+    };
+  }
+}
+  
+ +

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

+ +

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

+ +

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

+ + +

11.5 SQLite Limitations

+ +

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

+ +

11.5.1 Query Result Caching

+ +

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

+ +

11.5.2 Automatic Assignment of Object Ids

+ +

Due to SQLite API limitations, every automatically assigned object id + (Section 9.3.2, "auto") should have + the INTEGER SQLite type. While SQLite will treat other + integer type names (such as INT, BIGINT, etc.) + as INTEGER, automatic id assignment will not work. By default, + ODB maps all C++ integral types to INTEGER. This means that + the only situation that requires consideration is the assignment of a + custom database type using the db type pragma + (Section 9.3.3, "type"). For + example:

+ +
+#pragma db object
+class person
+{
+  ...
+
+  //#pragma db id auto type("INT")     // Will not work.
+  //#pragma db id auto type("INTEGER") // Ok.
+  #pragma db id auto                   // Ok, Mapped to INTEGER.
+  unsigned int id_;
+};
+
+ +

11.5.3 Constraint Violations

+ +

Due to the granularity of the SQLite error codes, it is impossible + 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 + 3.11, "ODB Exceptions").

+ +

11.5.4 Sharing of Queries

+ +

As discussed in Section 4.3, "Executing a Query", a + query instance that does not have any by-reference parameters is + immutable and can be shared between multiple threads without + synchronization. Currently, the SQLite ODB runtime does not support this + functionality. Future versions of the library will remove this + limitation.

+ + @@ -6925,7 +7489,7 @@ namespace odb
-

11 Profiles Introduction

+

12 Profiles Introduction

ODB profiles are a generic mechanism for integrating ODB with widely-used C++ frameworks and libraries. A profile provides glue @@ -6979,7 +7543,7 @@ odb --profile boost/date-time ...


-

12 Boost Profile

+

13 Boost Profile

The ODB profile implementation for Boost is provided by the libodb-boost library and consists of multiple sub-profiles @@ -7004,7 +7568,7 @@ odb --profile boost/date-time ... that can be thrown by the Boost sub-profiles are described in the following sections.

-

12.1 Smart Pointers Library

+

13.1 Smart Pointers Library

The smart-ptr sub-profile provides persistence support for a subset of smart pointers from the Boost @@ -7055,7 +7619,7 @@ class employee behavior, add the --default-pointer option specifying the alternative object pointer after the --profile option.

-

12.2 Unordered Containers Library

+

13.2 Unordered Containers Library

The unordered sub-profile provides persistence support for the containers from the Boost unordered library. To enable @@ -7081,7 +7645,7 @@ class employee }; -

12.3 Date Time Library

+

13.3 Date Time Library

The date-time sub-profile provides persistence support for a subset of types from the Boost date_time library. It is @@ -7154,7 +7718,7 @@ namespace odb exceptions are thrown are database system dependent and are discussed in more detail in the following sub-sections.

-

12.3.1 MySQL Database Type Mapping

+

13.3.1 MySQL Database Type Mapping

The following table summarizes the default mapping between the currently supported Boost date_time types and the MySQL database -- cgit v1.1