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:
-
Several
TTCmd
methods return an error if used with an ODBC driver manager. See Considerations when Using an ODBC Driver Manager (Windows) for information. -
If you have reason to manipulate the underlying ODBC statement object directly, use the
TTCmd::getHandle()
method.
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 theDataStore
attribute setting ifLogDir
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 Handle
Xxx
()
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.