Whenever you're working with classes derived from TDataSet, such as TQuery and TTable, you often need to open and close their underlying database tables. To do so, you can use the Open and Close methods of the TDataSet class. Calling Open and Close has the same effect as setting the Active property of TDataSet to True and False, respectively. You may wonder why you'd repeatedly open and close a table. One reason is to save system resources--keep an infrequently-used table closed and open it only when you need it. Or, you may want to modify the table in some way that requires you to first close the table.
Listing A: Changing the database for a TTable
ChangeDatabase(TTable *myTable,
String dbName)
{
bool holdActive = myTable->
Active;
myTable->Active = false;
myTable->DatabaseName = dbName;
myTable->Active = holdActive;
}
Listing B: The TDSActive class
#ifndef TDSActiveH
#define TDSActiveH
#include <db.hpp>
class TDSActive
{
public:
TDSActive(TDataSet *dataset,
bool active = true);
~TDSActive();
private:
TDataSet *dataset;
bool holdActive;
};
inline TDSActive::TDSActive(TDataSet
*dataset, bool active) :
dataset(dataset)
{
holdActive = dataset->Active;
dataset->Active = active;
}
inline TDSActive::~TDSActive()
{
dataset->Active = holdActive;
}
#endif
The TDSActive constructor accepts two arguments. The first, dataset, is a
pointer to a TDataSet or a class derived from TDataSet. The second, active, is
a bool variable that determines whether the TDataSet will be made active or
inactive. The latter argument defaults to True. To open a TTable object pointed
to by myTable, you'd write the code
TDSActive(myTable)To close the TTable object, you'd write
TDSActive(myTable, false);The TDSActive constructor remembers the open or closed state of the table by storing the table's Active property in the bool variable, holdActive. Finally, when the TDSActive object goes out of scope, the destructor restores the table's Active property using holdActive.
Listing C shows the code from Listing A rewritten to take advantage of TDSActive. The code no longer cares about the current state of the object pointed to by myTable. In addition, you don't need to worry about restoring that state after changing databases.
Listing C: Changing the database for a TTable using TDSActive
ChangeDatabase(TTable *myTable,
String dbName)
{
TDSActive(myTable, false);
myTable->DatabaseName = dbName;
}
To use TDSActive, you need to declare it in the header file, as shown in
Listing B. There is no source file. TDSActive takes advantage of the C++
rules concerning the creation and destruction of objects on the stack. You
benefit because it makes working with database tables a little simpler.