Using the TTClasses Classes

This section provides additional information about how to use each class in the TTClasses library.

How to Use the Commonly Used Classes

This section describes how to use each of the commonly used classes in the TTClasses library.

TTCGlobal Usage

The TTGlobal class provides a logging facility within TTClasses.

This logging facility can be very useful for debugging problems inside a TTClasses program. Note, however, that the most verbose logging levels (TTLog::TTLOG_INFO and TTLog::TTLOG_DEBUG) can generate an extremely large amount of output. Use these logging levels during development or when trying to diagnose a bug. They are not appropriate for most production environments.

When logging from a multithreaded program, you may encounter a problem where log output from different program threads is intermingled when written to the file system. To alleviate this problem, disable ostream buffering with the ios_base::unitbuf I/O stream manipulator, as in the following example, which sends TTClasses logging to the app_log.txt file at logging level TTLog::TTLOG_ERR.

ofstream log_file("app_log.txt");
log_file << std::ios_base::unitbuf; 
TTGlobal::setLogStream(log_file); 
TTGlobal::setLogLevel(TTLog::TTLOG_ERR);

See Using TTClasses Logging and TTGlobal Reference for more information about TTGlobal.

TTCStatus Usage

The TTStatus class is used by other classes in the TTClasses library to catch error and warning exceptions. You can think of TTStatus as a value-added C++ wrapper around the SQLError ODBC function.

A TTStatus object is thrown as an exception whenever an error or warning occurs. This allows C++ applications to use {try/catch} blocks to detect and recover from failure.

...
TTCmd    myCmd;

try {
  myCmd.ExecuteImmediate(&conn, "create table dummy (c1 int)");
}

catch (TTStatus st) {
  cerr << "Error creating table: " << st << endl;
  // Rollback, exit(), throw -- whatever is appropriate
}
...

TTStatus has two subclasses, TTError and TTWarning. ODBC warnings (the Return Receipt warning, for example) are usually not as serious as ODBC errors and should typically be handled with different logic. ODBC errors should be handled programmatically. There may be circumstances where handling ODBC warnings programmatically is warranted, but it is usually sufficient to simply log them.

This example shows the use of TTError and TTWarning. TTError objects are thrown for ODBC errors. TTWarning objects are thrown for ODBC warnings.

// catching TTError & TTWarning exceptions

try {
  // some TTClasses method calls
}
catch (TTWarning warn) {
  cerr << "Warning encountered: " << warn << endl;
}
catch (TTError err) {
  // handle the error; this could be a serious problem
}

Note:

TimesTen automatically resolves most transient errors (which is particularly important for TimesTen Scaleout), but if an error detected by your application indicates a SQL state of TT005 through the odbc_error attribute, it is suggested to retry the current transaction. See Transient Errors (ODBC) in Oracle TimesTen In-Memory Database C Developer's Guide.

Also see TTStatus Reference.

TTConnection Usage

The TTConnection class encapsulates the concept of a connection to a database. You can think of TTConnection as a value-added C++ wrapper around the ODBC connection handle (SQLHDBC). All applications that use TimesTen must create at least one TTConnection object.

Multithreaded applications that use TimesTen from multiple threads simultaneously must create multiple TTConnection objects. Use one of the following strategies:

  • Create one TTConnection object for each thread when the thread is created.

  • Create a pool of TTConnection objects when the application process starts. They are shared by the threads in the process. See TTConnectionPool Usage.

A TimesTen connection cannot be inherited from a parent process. If a process opens a database connection before creating (forking) a child process, the child cannot use the same connection. Any attempt by a child to use a database connection of a parent can cause application failure or a core dump.

Applications should not frequently make and then drop database connections, because connecting and disconnecting are both relatively expensive operations. In addition, short-lived connections eliminate the benefits of prepared statements. Instead, establish database connections at the beginning of the application process and reuse them for the life of the process.

Tip:

If you must manipulate the underlying ODBC connection object directly, use the TTConnection::getHdbc() method.

Privilege to connect to a database must be granted to users through the CREATE SESSION privilege, either directly or through the PUBLIC role. See Connection Methods.

Also see Using TTCmd, TTConnection, and TTConnectionPool. and TTConnection Reference.

TTConnectionPool Usage

The TTConnectionPool class is used by multithreaded applications to manage a pool of connections.

In general, multithreaded applications can be written using one of the following strategies:

  • If there is a relatively small number of threads and the threads are long-lived, each thread can be assigned to a different connection, which is used for the duration of the application. In this scenario, the TTConnectionPool class is not necessary.

  • If there is a large number of threads in the process, or if the threads are short-lived, a pool of idle connections can be established. These connections are used for the duration of the application. When a thread must perform a database transaction, it checks out an idle connection from the pool, performs its transaction, then returns the connection to the pool. This is the scenario that the TTConnectionPool class assists with.

The constructor has two forms:

TTConnectionPool()

Or:

TTConnectionPool(const int size);

Where size specifies the maximum number of connections in a pool. Without specifying this, the maximum number of connections is 128. Note that if you specify the size setting, and you specify a value that is larger than the maximum number of connections according to the setting of the TimesTen Connections attribute, you will get an error when the number of connections exceeds the Connections value. Also see Connections in the Oracle TimesTen In-Memory Database Reference.

Tip:

For best overall performance, TimesTen recommends having one or two concurrent direct connections to the database for each CPU of the database server. For no reason should your number of concurrent direct connections (the size of your connection pool) be more than twice the number of CPUs on the database server. For client/server connections, however, TimesTen supports many more connections per CPU efficiently.

To use the TTConnectionPool class, an application creates a single instance of the class. It then creates several TTConnection objects, instances of either the TTConnection class or a user class that extends it, but does not call their Connect() methods directly. Instead, the application uses the TTConnectionPool::AddConnectionToPool() method to place connection objects into the pool, then calls TTConnectionPool::ConnectAll() to establish all the connections to TimesTen. In the background, ConnectAll() loops through all the TTConnection objects to call their Connect() methods.

Threads for TimesTen applications use the getConnection() and freeConnection() methods to get and return idle connections.

Tip:

If you want to use TTConnectionPool and extend TTConnection, do not override the TTConnection::Connect() method that has driverCompletion in the calling sequence, because there is no corresponding TTConnectionPool::ConnectAll() method. Instead, override either of the following Connect() methods:

virtual void Connect(const char* connStr)
virtual void Connect(const char* connStr, const char* username, 
                     const char* password)

Then use the appropriate corresponding ConnectAll() method.

Privilege to connect to a database must be granted to users through the CREATE SESSION privilege, either directly or through the PUBLIC role. See Connection Methods.

Also see Using TTCmd, TTConnection, and TTConnectionPool. and TTConnectionPool Reference

TTCmd Usage

A TTCmd object encapsulates a single SQL statement that is used multiple times in an application program. You can think of TTCmd as a value-added C++ wrapper around the ODBC statement handle (SQLHSTMT). TTCmd has three categories of public methods.

Each SQL statement executed multiple times in a program should have its own TTCmd object. Each of these TTCmd objects should be prepared once during program initialization, then executed with the Execute() method multiple times as the program runs.

Only database operations that are to be executed a small number of times should use the ExecuteImmediate() method. Note that ExecuteImmediate() is not compatible with any type of SELECT statement. All queries must use Prepare() plus Execute() instead. ExecuteImmediate() is also incompatible with INSERT, UPDATE, or DELETE statements that are subsequently polled using getRowcount() to see how many rows were inserted, updated or deleted. These limitations have been placed on ExecuteImmediate() to discourage its use except in a few particular situations (for example, for creating or dropping a table).

Note:

Also see Using TTCmd, TTConnection, and TTConnectionPool. and TTCmd Reference.

How to Use the System Catalog Classes

This section describes how to use each of the TTClasses system catalog classes.

TTCatalog Usage

The TTCatalog class is the top-level class used for programmatically accessing metadata information about tables in a database. You can use this class to facilitate reading metadata from the system catalog. A TTCatalog object contains data structures with the information that was read.

To use the TTCatalog object, call its fetchCatalogData() method. The fetchCatalogData() method is the only TTCatalog method that uses the database connection. All other methods simply return data retrieved by fetchCatalogData().

A TTCatalog object contains an internal array of TTCatalogTable objects. Aside from the class constructor, all public methods of TTCatalog are used to gain read-only access to this TTCatalogTable array.

The TTCatalog constructor caches the conn parameter and initializes all the internal data structures appropriately.

TTCatalog (TTConnection* conn)

The following ODBC functions are used inside TTCatalog:

  • SQLTables()

  • SQLColumns()

  • SQLSpecialColumns()

  • SQLStatistics()

Also see TTCatalog Reference.

TTCatalogTable Usage

Each object of the top-level TTCatalog class internally contains an array of TTCatalogTable objects.

A TTCatalogTable object is retrieved through the TTCatalog::getTable() method and stores all metadata information about the columns and indexes of a table.

Each TTCatalogTable object contains an array of TTCatalogColumn objects and an array of TTCatalogIndex objects.

Also see TTCatalogTable Reference.

TTCatalogColumn Usage

Each TTCatalogTable object contains an array of TTCatalogColumn objects and an array of TTCatalogIndex objects.

The TTCatalogColumn class is used to store all metadata information about a single column of a table. This table is represented by the TTCatalogTable object from which the column was retrieved through a TTCatalogTable::getColumn() call.

Also see TTCatalogColumn Reference.

TTCatalogIndex Usage

Each TTCatalogTable object contains an array of TTCatalogColumn objects and an array of TTCatalogIndex objects.

The TTCatalogIndex class is used to store all metadata information about an index of a table. This table is represented by the TTCatalogTable object from which the index was retrieved through a TTCatalogTable::getIndex() call.

Also see TTCatalogIndex Reference

TTCatalogSpecialColumn Usage

Obtain a TTCatalogSpecialColumn object by calling the getSpecialColumn() method on the relevant TTCatalogTable object.

In TimesTen, a rowid pseudocolumn is the only type of special column supported, so a TTCatalogSpecialColumn object can only contain information about rowids.

Also see TTCatalogSpecialColumn Reference.

How to Use the XLA Classes

This section introduces the TTClasses XLA classes then describes how to use each of them.

About the XLA Classes

TTClasses provides a set of classes for applications to use with the TimesTen Transaction Log API (XLA), which is supported by TimesTen Classic.

XLA is a set of C-callable functions that allow an application to monitor changes made to one or more database tables. Whenever another application changes a monitored table, the application using XLA is informed of the changes. For more information about XLA, see XLA and TimesTen Event Management in Oracle TimesTen In-Memory Database C Developer's Guide.

The XLA classes support as many XLA columns as the maximum number of columns supported by TimesTen. For more information, see System Limits in Oracle TimesTen In-Memory Database Reference.

Note:

As mentioned in Considerations when Using an ODBC Driver Manager (Windows), XLA functionality is not supported with TTClasses when you use a generic ODBC driver manager.

TTXlaPersistConnection Usage

Use TTXlaPersistConnection to create an XLA connection to a database.

An XLA application can create multiple TTXlaPersistConnection objects if needed. Each TTXlaPersistConnection object must be associated with its own bookmark, which is specified at connect time and must be maintained through the ackUpdates() and deleteBookmarkAndDisconnect() methods. Most applications require only one or two XLA bookmarks.

After an XLA connection is established, the application should enter a loop in which the fetchUpdatesWait() method is called repeatedly until application termination. This loop should fetch updates from XLA as rapidly as possible to ensure that the transaction log does not fill up available file system space.

Note:

  • The transaction log is in a file system location according to the TimesTen LogDir attribute setting, if specified, or the DataStore attribute setting if LogDir is not specified. Refer to Data Store Attributes in Oracle TimesTen In-Memory Database Reference.

  • Each bookmark establishes its own log hold on the transaction log. (See ttLogHolds in Oracle TimesTen In-Memory Database Reference.) If any bookmark is not moved forward periodically, transaction logs cannot be purged by checkpoint operations. This can fill up the file system over time.

After processing a batch of updates, the application should call ackUpdates() to acknowledge those updates and get ready for the next call to fetchUpdatesWait(). A batch of updates can be replayed using the setBookmarkIndex() and getBookmarkIndex() methods. Also, if the XLA application disconnects after fetchUpdatesWait() but before ackUpdates(), the next connection (with the same bookmark name) that calls fetchUpdatesWait() sees that same batch of updates.

Updates that occur while a TTXlaPersistConnection object is disconnected from the database are not lost. They are stored in the transaction log until another TTXlaPersistConnection object connects with the same bookmark name.

Privilege to connect to a database must be granted to users through the CREATE SESSION privilege, either directly or through the PUBLIC role. See Connection Methods. In addition, the XLA privilege is required for XLA connections and functionality.

Also see TTXlaPersistConnection Reference.

TTXlaRowViewer Usage

TTXlaRowViewer, which represents a row image from change notification records, is used to examine XLA change notification record structures and old and new column values.

Methods of this class are used to examine column values from row images contained in change notification records. Also see related information about the TTXlaTable class (TTXlaTable Usage).

Before a row can be examined, the TTXlaRowViewer object must be associated with a row using the setTuple() method, which is invoked inside the TTXlaTableHandler::HandleInsert(), HandleUpdate(), or HandleDelete() method, or by a user-written overloaded method. Columns can be checked for null values using the isNull() method. Non-null column values can be examined using the appropriate overloaded Get() method.

Also see TTXlaRowViewer Reference.

TTXlaTableHandler Usage

The TTXlaTableHandler class provides methods that enable and disable change tracking for a table. Methods are also provided to handle update notification records from XLA.

TTXlaTableHandler is intended as a base class from which application developers write customized classes to process changes to a particular table.

The constructor associates the TTXlaTableHandler object with a particular table and initializes the TTXlaTable data member contained within the TTXlaTableHandler object:

TTXlaTableHandler(TTXlaPersistConnection& conn, const char* ownerP, 
                  const char* nameP)

Also see TTXlaTable Usage.

Application developers can derive one or more classes from TTXlaTableHandler and can put most of the application logic in the HandleInsert(), HandleDelete(), and HandleUpdate() methods of that class.

One possible design is to derive multiple classes from TTXlaTableHandler, one for each table. Business logic to handle changes to customer data might be implemented in a CustomerTableHandler class, for example, while business logic to handle changes to order data might be implemented in an OrderTableHandler class.

Another possible design is to derive one or more generic classes from TTXlaTableHandler to handle various scenarios. For example, a generic class derived from TTXlaTableHandler could be used to publish changes using a publish/subscribe system.

See the xlasubscriber1 and xlasubscriber2 demos in the TimesTen Classic Quick Start for examples of classes that extend TTXlaTableHandler. (Refer to About TimesTen Quick Start and Sample Applications.)

Also see TTXlaTableHandler Reference.

TTXlaTableList Usage

The TTXlaTableList class provides a list of TTXlaTableHandler objects and is used to dispatch update notification events to the appropriate TTXlaTableHandler object.

By registering TTXlaTableHandler objects in a TTXlaTableList object, the process of fetching update notification records from XLA and dispatching them to the appropriate methods for processing can be accomplished using a loop.

When an update notification is received from XLA, the appropriate HandleXxx() method of the appropriate TTXlaTableHandler object is called to process the record.

For example, if an object of type CustomerTableHandler is handling changes to table CUSTOMER, and an object of type OrderTableHandler is handling changes to table ORDERS, the application should have both of these objects in a TTXlaTableList object. As XLA update notification records are fetched from XLA, they can be dispatched to the correct handler by a call to TTXlaTableList::HandleChange().

The constructor has two forms:

TTXlaTableList(TTXlaPersistConnection* cP, unsigned int num_tbls_to_monitor)

Where num_tbls_to_monitor is the number of database objects to monitor.

Or:

TTXlaTableList(TTXlaPersistConnection* cP);

Where cP references the database connection to be used for XLA operations. This form of the constructor can monitor up to 150 database objects.

Also see TTXlaTableList Reference.

TTXlaTable Usage

The TTXlaTable class encapsulates the metadata for a table being monitored for changes.

TTXlaTable acts as a metadata interface for the TimesTen ttXlaTblDesc_t C data structure. (See ttXlaTblDesc_t in Oracle TimesTen In-Memory Database C Developer's Guide.)

When a user application creates a class that extends TTXlaTableHandler, it typically calls TTXlaTable::getColNumber() to map a column name to its XLA column number. You can then use the column number as input to the TTXlaRowViewer::Get() method. This is shown in the xlasubscriber2 demo in the TimesTen Classic Quick Start. (Refer to About TimesTen Quick Start and Sample Applications.)

This class also provides useful metadata functions to return the name, owner, and number of columns in the table.

Also see TTXlaTable Reference

TTXlaColumn Usage

A TTXlaColumn object contains the metadata for a single column of a table being monitored for changes.

TTXlaColumn acts as a metadata interface for the TimesTen ttXlaColDesc_t C data structure. (See ttXlaColDesc_t in Oracle TimesTen In-Memory Database C Developer's Guide.) Information including the column name, type, precision, and scale can be retrieved.

Applications can associate a column with a TTXlaColumn object by using the TTXlaRowViewer::getColumn() method.

Also see TTXlaColumn Reference.