Isis 3 Programmer Reference
|
Create database interfaces using access profiles or generic drivers. More...
#include <DatabaseFactory.h>
Public Member Functions | |
void | setDefault (const QString &name) |
Sets the default name of the database. More... | |
QString | getDefault () const |
Returns the name of the default database. More... | |
bool | addAccessProfile (const QString &profileFile) |
Establishes an access profile for subsequent database connections. More... | |
void | addProfile (const DbProfile &profile) |
Adds a database access profile to the list of profiles. More... | |
std::vector< QString > | getProfileList () const |
Return list of names of currently available profiles. More... | |
DbProfile | getProfile (const QString &name="") const |
Get the specified database access profile. More... | |
QString | getDefaultProfileName () const |
Returns the name of the default profile. More... | |
bool | setDefaultProfileName (const QString &name) |
Sets the default profile to the name provided. More... | |
std::vector< QString > | available () const |
Determine what database drivers are available. More... | |
bool | isDriverAvailable (const QString &driver) const |
Check for the existance of a specific database driver. More... | |
bool | isAvailable (const QString &dbname="") const |
Check for availablity of a database connection resource. More... | |
bool | isConnected (const QString &dbname) const |
Determines if the database resource is connected. More... | |
bool | isPersistant (const QString &name) const |
Checks if the database resource is persistant. More... | |
QSqlDatabase | create (const QString &driver, const QString &dbname) |
Create a database using the named driver. More... | |
QSqlDatabase | create (const QString &name) |
Create a database connection from a named resource. More... | |
void | add (const QSqlDatabase &db, const QString &name, bool setAsDefault=false) |
Adds the database to the connection pool making it persistant. More... | |
void | remove (const QString &dbname) |
Removes the database from the connection pool. More... | |
void | destroy (const QString &dbname) |
Removes the database from the connection pool and destroys it. More... | |
Static Public Member Functions | |
static DatabaseFactory * | getInstance () |
Returns and instance of this DatabaseFactory singleton. More... | |
Private Types | |
typedef CollectorMap< IString, QString, NoCaseStringCompare > | Drivers |
Define list of drivers and/or databases More... | |
typedef CollectorMap< IString, DbProfile, NoCaseStringCompare > | Profiles |
Define list of Profiles. More... | |
typedef CollectorMap< IString, QSqlDatabase, NoCaseStringCompare > | Databases |
Define active database maintainer. More... | |
Private Member Functions | |
DatabaseFactory () | |
Constructor establishing the startup state of this singleton. More... | |
~DatabaseFactory () | |
Destructor implements self-destruction of this object. More... | |
void | init () |
Initializes this object upon instantiation. More... | |
void | initPreferences () |
Initializes user database preferences. More... | |
void | loadDrivers () |
Load any drivers explicity. More... | |
Drivers | getResourceList (bool drivers, bool connections) const |
Get a list of available database drivers and connections. More... | |
void | selfDestruct () |
Destroy all elements associated with this object. More... | |
Static Private Member Functions | |
static void | DieAtExit () |
Exit termination routine. More... | |
Private Attributes | |
QString | _defProfName |
Default profile name. More... | |
Profiles | _profiles |
Maintain list of profiles. More... | |
QString | _defDatabase |
Name of default database. More... | |
Databases | _dbList |
Maintains active databases. More... | |
Static Private Attributes | |
static DatabaseFactory * | _factory = 0 |
Pointer to self (singleton) More... | |
Create database interfaces using access profiles or generic drivers.
This class provides two major components for database programming: database drivers and access profiles. This class is implemented as a Singleton (see GoF Design Patterns). As such, it serves as a single access point for drivers and profiles. It should become clear why database access profiles are also provided in this class after reading the subsequent documentation.
This class creates Qt QSqlDatabase objects and subsequent use of the resulting objects from this class are dependant on a valid Qt environment. At the time this class was developed, Qt provides database drivers as plugins and this class assumes they are already available within the Qt environment. See the Qt documentation for details on options to provide database drivers in the Qt environment. Note, however, that the existance of Qt database drivers in not required to build this class or supporting classes. Proper use of instantiated classes does require database drivers to exist in the Qt environment.
The names of the Qt drivers is an issue. Qt names their drivers obscurely so that it is not readily obvious what, for example, is the MySQL driver name. This class uses access profiles, described below, that name the type of database you expect to access. This implies the user must know if the database is Oracle, PostgreSQL or MySQL and specify the proper name in the access profile. The Qt PostgreSQL driver is called QPSQL. This class tests for the specifc Qt named drivers and adds formal names to the driver list. For example, if the QPSQL exists, a driver named PostgreSQL is also added/available. If the MySQL Qt driver, QMYSQL, exists, MySQL is also added to the available drivers. For this reason, it is recommededd that access profiles use the formal names instead of the Qt driver names...just in case we decided to discontinue use of Qt as the database framework and replace it with another.
This factory generates database driver instances whereby access is defined by database access profiles. The primary profile is specified in the IsisPreferences file in the Database group. Access profiels are established by user preferences as read from the $HOME/.Isis/IsisPreferences. In the Database group, the AccessConfig keyword contains a full path to a database profile. This file contains a Database object with a AccessConfig keyword that specifies the full path to a file that contains database access information and optionally a DefaultProfile that indicates the default profile to use when creating an unnamed database. Note that the database profile file may also indicate a default, but the value of DefaultProfile overrides this default so certain applications and uses can govern behavior if needed.
The intended strategy behind this design is to allow the profile file to specify the read only access configuration to the database. An unnamed request to create a database will use the named default and create a driver to the requesting application when accessing a database. If an application is designed to update the contents of the database, the user can specify the access to the database and specify the name of the profile in the profile file that provides write access to the database. The DefaultProfile keyword in the database group is used to specify the name of the profile.
Below is an example of a Database group contained within your personal IsisPreferences file describing the location of the Database access profile file is and a commented example of how to specify the default profile to use when an unnamed database instantiation is requested:
The specification of AccessConfig indicates the file that this object reads when it is instantiated. The file, in this case, upc.conf, should contain a Database object and one or more Profile Groups. Although DefaultProfile is commented, it is also reflected in the profile file as illustrated below. If the user wants write or update access, he could simple set the value of DefaultProfile to UpcWrite, uncomment it and the UpcWrite profile then becomes the default database connection.
Below is an example of the contents of a database access configuration profile file:
Not all the keywords are critical/required but some are needed in order to sucessfully acquire access to a specified database. The Dbname keyword is needed to specify the name of the database to access. Options include User which specifies the name of the database user that provides access to the database; Password is an optional password if the user account requires one - note that under most conditions, it is unwise to reveal a password in this fashion. It is only advisable if the database user has read only access specified in its access conditions or if file permissions are set such that no other user can see the contents, which is still not advised. Users can utilize other access methods, such as environment variables, or whatever the database access system provides. FOr example, PostgreSQL uses the libpq library and it has some additional access provisions. You could set environment variables or use the password file to create a more secure access scheme. Check your database documentations for additional access options; Host is used to provide the name of the dababase host computer. And Port specifies a specific port number to use to connect. See the Qt QSqlDatabase documentation for access specifics. This access scheme is used directly in this class.
When selecting a specific Profile from within the Database object, all keywords in the Database object are first copied to a new Profile. Then the requested Profile is merged with new profile and given the name of the group profile. Under this scenario, it is intended to provide a cascading hierarchy of access parameters, whereby the Profile keywords take precendence. For any keywords that exist in both the Database object section and the specfied profile, the keywords in the Profile group replace those in the Database section. In the above example, the keyword Name exists in both the Database section and each Profile group. When the default profile Upc is selected, the Name keyword in the Profile group eith the value Upc replaces the one in the Database section that has the value UPC.
For example the code to select the Upc profile is:
Using the above example configuration scheme, the resulting Upc profile looks like this:
This allows each Profile group to change any or all access parameters, even the type of database (PostgreSQL to MySQL, for example) it needs.
When the DatabaseFactory is invoked for the first time, the users preference file is loaded and the default Database AccessConfig file is read. It governs all further access unless the programmer specifically codes its own access parameters, which is still possible through this class.
This is an example using this class to craft explicit access to a database named upc:
In the above example, a database driver for PostgreSQL is created with the name "upctest". Access parameters are set explicitly and a query is issued if access is successful. Note that access schemes supported by targeted databases apply. For example, PostgreSQL will utilize environment variables to supply some access parameters. MySQL and PostgreSQL also utilize a configuration file whereby access can be acheived through variables set there. These combinations should supply adequate options to provide flexible options for accessing databases within the Isis system.
See the Database class for an example of using a specific profile to provide access to a database.
Definition at line 244 of file DatabaseFactory.h.
|
private |
Define active database maintainer.
Definition at line 336 of file DatabaseFactory.h.
|
private |
Define list of drivers and/or databases
Definition at line 332 of file DatabaseFactory.h.
|
private |
Define list of Profiles.
Definition at line 334 of file DatabaseFactory.h.
|
private |
Constructor establishing the startup state of this singleton.
This constructor sets up the initial state of the DatabaseFactory object. This object is implementated as a singleton and must take measures to ensure that at program termination, all database connections are closed. This is acheived through setting up a Qt termination function that is executed when the Qt environment is exiting.
Note that it is an error to schedule this process outside of Qt (using the atexit() function) because it uses Qt classes that must be properly deallocated. This cannot be done once the Qt environment exits.
Upon invocation of this object, a database access scheme is read. This is explained in the class documentation and will not be repeated here.
As a safety measure, this constructor determines if a Qt application class, Gui or non-Gui is initialized. If it is not, a non-Gui QCoreApplication is instantiated to properly initialize the Qt environment. This is required in order to have any Qt-based database plugins loaded and available for subsequent use. It is highly recommended that this activity occur explicitily at a much higher level as it allows for greater programmer application control.
Definition at line 57 of file DatabaseFactory.cpp.
References DieAtExit(), init(), and loadDrivers().
Referenced by getInstance().
|
private |
Destructor implements self-destruction of this object.
Definition at line 90 of file DatabaseFactory.cpp.
References selfDestruct().
void Isis::DatabaseFactory::add | ( | const QSqlDatabase & | db, |
const QString & | name, | ||
bool | setAsDefault = false |
||
) |
Adds the database to the connection pool making it persistant.
This method can be called after the create() method, handing back the created database object. In effect, this creates a copy of the database in its current state and makes it available to subsquent create(name) calls.
If one calls create() and does not add the database using this method, then the database is destroyed/deallocated when it goes out of scope or no longer has a reference to it.
Adding a database to the connection pool using this method essentially makes it persistant and available for subsquent use.
db | Database object to add to pool |
name | Name to associate with the object |
setAsDefault | True if this is to become the default connection |
Definition at line 415 of file DatabaseFactory.cpp.
References _dbList, _defDatabase, and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::add().
Referenced by Isis::Database::makePersistant(), and Isis::Database::setAsDefault().
bool Isis::DatabaseFactory::addAccessProfile | ( | const QString & | profileFile | ) |
Establishes an access profile for subsequent database connections.
This method takes the name of a database access profile file and adds all its profiles to the internally maintained list. Users of this class can then use any one of profiles in the list as the access scheme for all database creation and connection requests.
If a profile of the same name happens to already exist, it is replaced by any new one contained in the access profiles file.
NOTE that if a default profile is specified in the added acsess scheme it supercedes all other defaults - which includes one loaded at startup from IsisPreferences and one set by the programmer explicitly. To retain current settings require the user to get the named default prior to adding these profiles and resetting it upon return.
profileFile | Name of profile file to add |
Definition at line 152 of file DatabaseFactory.cpp.
References _defProfName, _profiles, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::add(), Isis::DbProfile::exists(), Isis::FileName::fileExists(), Isis::DbAccess::getProfile(), Isis::DbProfile::Name(), Isis::DbAccess::profileCount(), and Isis::DbProfile::value().
Referenced by Isis::Database::addAccessConfig(), and initPreferences().
void Isis::DatabaseFactory::addProfile | ( | const DbProfile & | profile | ) |
Adds a database access profile to the list of profiles.
This method will add a new access profile to the list of existing profiles and make it available for subsequent access requests.
NOTE that if an profile exists with the same name, it is replaced with this one. The one is no longer accessable.
profile | New access profile to add to internal list |
Definition at line 194 of file DatabaseFactory.cpp.
References _profiles, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::add(), and Isis::DbProfile::Name().
std::vector< QString > Isis::DatabaseFactory::available | ( | ) | const |
Determine what database drivers are available.
This method returns a vector of strings that contains the names of all available database drivers.
In this list will be Qt named drivers, such as QMYSQL, formal names for drivers such as MySQL and PostgreSQL, and named database connections such as UPC. The list includes all currently availble database resources.
Definition at line 260 of file DatabaseFactory.cpp.
References getResourceList(), Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::key(), and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::size().
QSqlDatabase Isis::DatabaseFactory::create | ( | const QString & | driver, |
const QString & | dbname | ||
) |
Create a database using the named driver.
This method creats a database connection using the specified driver. The driver should be one of the available drivers as identified by the isDriverAvailable() method.
The caller provides a name of the database created by this method. This name is arbitrary and can be anything meaningful to the caller of this method. IT is intended (and required) for use of named connections that are retained for future use in this object.
driver | Name of database driver to instantiate for the connection |
dbname | Name of the database connect provided by the caller |
Definition at line 358 of file DatabaseFactory.cpp.
References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::get(), getResourceList(), isDriverAvailable(), and Isis::IException::Unknown.
Referenced by Isis::Database::init().
QSqlDatabase Isis::DatabaseFactory::create | ( | const QString & | dbname | ) |
Create a database connection from a named resource.
This method is used to create a database from an existing resource. This typically will be a database source that has been added using the add() method. It provides persistant connections from this object.
dbname | Name of database resource |
Definition at line 385 of file DatabaseFactory.cpp.
References _dbList, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists(), Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::get(), and Isis::IException::Unknown.
void Isis::DatabaseFactory::destroy | ( | const QString & | name | ) |
Removes the database from the connection pool and destroys it.
This method should be invoked only after add() has been called with the named database. It is removed from the connection pool and destroyed terminating any persistant connection it may have had.
Other references to this database are invalidated.
name | Name of the database to remove |
Definition at line 435 of file DatabaseFactory.cpp.
References remove().
Referenced by Isis::Database::remove().
|
staticprivate |
Exit termination routine.
This (static) method ensure this object is destroyed when Qt exits. This is required so that persistant database connections can be terminated and cleaned up.
Note that it is error to add this to the system _atexit() routine because this object utilizes Qt classes. At the time the atexit call stack is executed, Qt is long gone resulting in Very Bad Things. Fortunately, Qt has an exit stack function as well. This method is added to the Qt exit call stack. See the DatabaseFactory() constructor.
Definition at line 107 of file DatabaseFactory.cpp.
References _factory.
Referenced by DatabaseFactory().
|
inline |
Returns the name of the default database.
This method returns the name of the current default database. If a call to the create method is attempted without a name, this is the one used to return an instance of database.
Definition at line 271 of file DatabaseFactory.h.
References _defDatabase.
Referenced by Isis::Database::init().
|
inline |
Returns the name of the default profile.
If a default profile name has been established this will return the name of the default profile. If none are loaded, an empty string is returned.
Definition at line 289 of file DatabaseFactory.h.
References _defProfName.
|
static |
Returns and instance of this DatabaseFactory singleton.
This method is the sole source of access to the DatabaseFactory class. Upon the first call to this method, the DatabaseFactory is created. Subsequent calls simply return a pointer reference to object which can be used to reference existing databases and database drivers.
Definition at line 124 of file DatabaseFactory.cpp.
References _factory, and DatabaseFactory().
Referenced by Isis::Database::addAccessConfig(), Isis::Database::getProfile(), Isis::Database::init(), Isis::Database::isPersistant(), Isis::Database::makePersistant(), Isis::Database::remove(), Isis::Database::setAsDefault(), and Isis::Database::~Database().
DbProfile Isis::DatabaseFactory::getProfile | ( | const QString & | name = "" | ) | const |
Get the specified database access profile.
This method provides access profiles from the "system-wide" database access profile. The primary source of availability of these profiles is established upon the first instance returned from the DatabaseFactory through the preferences. See the DatabaseFactory documentation for how this is established.
If the named profile dones not exist, a black one is returned and can be checked via the DbProfile.isValid() method.
name | Name of the profile to return. If not provided by the caller, then the default will be provided (which is defined in the Pvl input Access Profile or is unspecified which will result in an invalid profile (typically)). |
Definition at line 235 of file DatabaseFactory.cpp.
References _defProfName, _profiles, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists(), and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::get().
Referenced by Isis::Database::getProfile(), and Isis::Database::init().
std::vector< QString > Isis::DatabaseFactory::getProfileList | ( | ) | const |
Return list of names of currently available profiles.
This method will return a list of the names of all currently available database access profiles as a vector of strings.
Definition at line 207 of file DatabaseFactory.cpp.
References _profiles, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::key(), Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::size(), and Isis::IString::ToQt().
|
private |
Get a list of available database drivers and connections.
This method can be called at any time to return a list of available database drivers and current connections. These data may change over the lifetime of an application. It returns a snapshot of whats available.
One thing this method does in adds formal database names for known Qt drivers that access them. This provides a generic interface to users needing connections to specific databases.
drivers | If true, return a list of database drivers |
connections | If true, return a list of existing connections |
Definition at line 516 of file DatabaseFactory.cpp.
References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::add(), and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists().
Referenced by available(), create(), isAvailable(), and isDriverAvailable().
|
private |
Initializes this object upon instantiation.
This method is called to initialize the database pool. This includes loading any explicit database drivers and loading database access profiles.
Definition at line 467 of file DatabaseFactory.cpp.
References initPreferences(), and loadDrivers().
Referenced by DatabaseFactory().
|
private |
Initializes user database preferences.
This method is typically called once at object instantiation. It references Isis user preferences and loads database access specific profiles. The access profiles and their associated database configuration parameters establish named databases with access paramters.
See the main DatabaseFactory documentation for details.
Definition at line 486 of file DatabaseFactory.cpp.
References _defProfName, addAccessProfile(), Isis::PvlObject::findGroup(), Isis::PvlObject::hasGroup(), and Isis::PvlContainer::hasKeyword().
Referenced by init().
bool Isis::DatabaseFactory::isAvailable | ( | const QString & | dbname = "" | ) | const |
Check for availablity of a database connection resource.
This method checks for the existance of a driver for the specified named database resource.
dbname | Name of the database resource to check availability |
Definition at line 297 of file DatabaseFactory.cpp.
References _defDatabase, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists(), and getResourceList().
Referenced by Isis::Database::init().
bool Isis::DatabaseFactory::isConnected | ( | const QString & | dbname | ) | const |
Determines if the database resource is connected.
Checks the named database for existance in the database connection pool.
dbname | Case insensitive name of database connection |
Definition at line 315 of file DatabaseFactory.cpp.
References _defDatabase.
bool Isis::DatabaseFactory::isDriverAvailable | ( | const QString & | dbname | ) | const |
Check for the existance of a specific database driver.
dbname can be a Qt database driver or a formal name of a database, such as MySQL. The name is case insensitve.
dbname | Name of the database driver to check availability |
Definition at line 279 of file DatabaseFactory.cpp.
References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists(), Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::get(), and getResourceList().
Referenced by create().
bool Isis::DatabaseFactory::isPersistant | ( | const QString & | dbname | ) | const |
Checks if the database resource is persistant.
This method tests the database to determine if the connection is persistant. Persistance means that the connection to the database remains open. A databases persistant state is maintained in this object by holding a reference to it.
dbname | Name of the database to check persistance status |
Definition at line 335 of file DatabaseFactory.cpp.
References _dbList, and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists().
Referenced by Isis::Database::isPersistant(), Isis::Database::makePersistant(), Isis::Database::setAsDefault(), and Isis::Database::~Database().
|
private |
Load any drivers explicity.
This method is intended to be invoked at object instantiation to load database drivers explicitly.
At this time, we are relying on Qt database driver plugins to provide this resource.
Definition at line 562 of file DatabaseFactory.cpp.
Referenced by DatabaseFactory(), and init().
void Isis::DatabaseFactory::remove | ( | const QString & | name | ) |
Removes the database from the connection pool.
This method removes the named database from the connection pool making it a non-persistant database connection. References to the database are still valid until they are destroyed in the callers environment.
name | Name of database to remove from the connection pool |
Definition at line 450 of file DatabaseFactory.cpp.
References _dbList, _defDatabase, Isis::IString::Equal(), and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::remove().
Referenced by destroy(), and Isis::Database::~Database().
|
private |
Destroy all elements associated with this object.
This method deletes the singleton reference of this object and removes all persistant existing database connections. It is typically executed when the application is terminated but can be invoked safely under other conditions.
Definition at line 576 of file DatabaseFactory.cpp.
References _dbList, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::key(), Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::remove(), and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::size().
Referenced by ~DatabaseFactory().
|
inline |
Sets the default name of the database.
This method defines the name of the database to use when none is specifed in subsequent calls to the create methods. This is typically a named profile, but could be a database driver as well as they are used in the same context.
name | Name of the default database |
Definition at line 258 of file DatabaseFactory.h.
References _defDatabase.
Referenced by Isis::Database::setAsDefault().
|
inline |
Sets the default profile to the name provided.
This allows the calling environment to establish the default database access profile by name. It returns true if the named profile exists within the current list of profiles, false if it doesn't;
name | Name of the new default database access profile |
Definition at line 304 of file DatabaseFactory.h.
References _defProfName, _profiles, and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists().
|
private |
Maintains active databases.
Definition at line 341 of file DatabaseFactory.h.
Referenced by add(), create(), isPersistant(), remove(), and selfDestruct().
|
private |
Name of default database.
Definition at line 340 of file DatabaseFactory.h.
Referenced by add(), getDefault(), isAvailable(), isConnected(), remove(), and setDefault().
|
private |
Default profile name.
Definition at line 338 of file DatabaseFactory.h.
Referenced by addAccessProfile(), getDefaultProfileName(), getProfile(), initPreferences(), and setDefaultProfileName().
|
staticprivate |
Pointer to self (singleton)
Definition at line 329 of file DatabaseFactory.h.
Referenced by DieAtExit(), and getInstance().
|
private |
Maintain list of profiles.
Definition at line 339 of file DatabaseFactory.h.
Referenced by addAccessProfile(), addProfile(), getProfile(), getProfileList(), and setDefaultProfileName().