Isis 3 Developer Reference
Isis::DatabaseFactory Class Reference

Create database interfaces using access profiles or generic drivers. More...

#include <DatabaseFactory.h>

Collaboration diagram for Isis::DatabaseFactory:
Collaboration graph

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 DatabaseFactorygetInstance ()
 Returns and instance of this DatabaseFactory singleton. More...
 

Detailed Description

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:

########################################################
# Customize the database configuration upon startup
# of any database type application
########################################################
Group = Database
AccessConfig = $HOME/.Isis/database/upc.conf
# DefaultProfile = upc
EndGroup

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:

Object = Database
Name = UPC
Dbname = upc
Type = PostgreSQL
Host = "upcdb0.wr.usgs.gov"
Port = 3309
Description = "UPC provides GIS-capable image searches"
AlternateHosts = "upcdb1.wr.usgs.gov"
DefaultProfile = Upc
Group = Profile
Name = Upc
User = "upcread"
Access = ReadOnly
Password = "public"
EndGroup
Group = Profile
Name = UpcWrite
User = "upcwrite"
Access = Update
EndGroup
Group = Profile
Name = UpcAdmin
User = "upcmgr"
Access = Admin
EndGroup
EndObject

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:

DatabaseFactory *factory = DatabaseFactory::instance();
DbProfile upc = factory->getProfile("upc");

Using the above example configuration scheme, the resulting Upc profile looks like this:

Group = Profile
Name = Upc
Dbname = upc
Type = PostgreSQL
Host = "upcdb0.wr.usgs.gov"
Port = 3309
Description = "UPC provides GIS-capable image searches"
AlternateHosts = "upcdb1.wr.usgs.gov"
DefaultProfile = Upc
User = "upcread"
Access = ReadOnly
Password = "public"
EndGroup

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:

DatabaseFactory *factory = DatabaseFactory::getInstance();
QSqlDatabase upc = factory->create("Postgresql", "upctest");
upc.setHostName("upcdb0");
upc.setUserName("upcread");
upc.setPassword("public");
upc.setDatabaseName("upc");
if (upc.open()) {
QSqlQuery query("SELECT * FROM pg_tables where schemaname = 'public'",
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.

Author
2006-08-18 Kris Becker

Member Function Documentation

◆ add()

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.

Parameters
dbDatabase object to add to pool
nameName to associate with the object
setAsDefaultTrue if this is to become the default connection

References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::add().

Referenced by Isis::Database::makePersistant(), and Isis::Database::setAsDefault().

◆ addAccessProfile()

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.

Parameters
profileFileName of profile file to add
Returns
bool True if the new profile is successfully added, false otherwise.

References 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().

◆ addProfile()

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.

Parameters
profileNew access profile to add to internal list

References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::add(), and Isis::DbProfile::Name().

◆ available()

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.

Returns
std::vector<QString> List of database drivers

References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::key(), and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::size().

◆ create() [1/2]

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.

Parameters
driverName of database driver to instantiate for the connection
dbnameName of the database connect provided by the caller
Returns
QSqlDatabase A named Qt database object created with the specifed driver

References _FILEINFO_, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::get(), isDriverAvailable(), and Isis::IException::Unknown.

Referenced by Isis::Database::init().

◆ create() [2/2]

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.

Parameters
dbnameName of database resource
Returns
QSqlDatabase A Database object

References _FILEINFO_, Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists(), Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::get(), and Isis::IException::Unknown.

◆ destroy()

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.

Parameters
nameName of the database to remove

Referenced by Isis::Database::remove().

◆ getDefault()

QString Isis::DatabaseFactory::getDefault ( ) const
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.

Returns
QString Name of default database

Referenced by Isis::Database::init().

◆ getDefaultProfileName()

QString Isis::DatabaseFactory::getDefaultProfileName ( ) const
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.

Returns
QString Name of default profile, empty if undetermined

◆ getInstance()

DatabaseFactory * Isis::DatabaseFactory::getInstance ( )
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.

Returns
DatabaseFactory* Returns a pointer reference to a DatabaseFactory singleton object

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().

◆ getProfile()

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.

Parameters
nameName 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)).
Returns
DbProfile An database access profile resulting from the request.
See also
initPreferences().

References 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().

◆ getProfileList()

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.

Returns
std::vector<QString> List of available profile names

References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::key(), Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::size(), and Isis::IString::ToQt().

◆ isAvailable()

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.

Parameters
dbnameName of the database resource to check availability
Returns
bool True if the connection exists, otherwise false

References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists().

Referenced by Isis::Database::init().

◆ isConnected()

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.

Parameters
dbnameCase insensitive name of database connection
Returns
bool True if it exists in the pool, otherwise false

◆ isDriverAvailable()

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.

Parameters
dbnameName of the database driver to check availability
Returns
bool True if the specifed driver exists, otherwise false

References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists(), and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::get().

Referenced by create().

◆ isPersistant()

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.

Parameters
dbnameName of the database to check persistance status
Returns
bool True if the database is persistant, otherwise false

References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists().

Referenced by Isis::Database::isPersistant(), Isis::Database::makePersistant(), Isis::Database::setAsDefault(), and Isis::Database::~Database().

◆ remove()

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.

Parameters
nameName of database to remove from the connection pool

References Isis::IString::Equal(), and Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::remove().

Referenced by Isis::Database::~Database().

◆ setDefault()

void Isis::DatabaseFactory::setDefault ( const QString &  name)
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.

Parameters
nameName of the default database

Referenced by Isis::Database::setAsDefault().

◆ setDefaultProfileName()

bool Isis::DatabaseFactory::setDefaultProfileName ( const QString &  name)
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;

Parameters
nameName of the new default database access profile
Returns
bool True if it named profile exists, false otherwise

References Isis::CollectorMap< K, T, ComparePolicy, RemovalPolicy, CopyPolicy >::exists().


The documentation for this class was generated from the following files: