Isis 3.0 Programmer Reference
Back | Home
DatabaseFactory.cpp
Go to the documentation of this file.
1 
22 #include <cstdlib>
23 #include <string>
24 #include <vector>
25 #include <iostream>
26 
27 using namespace std;
28 
29 
30 #include <QString>
31 #include <QStringList>
32 #include <QCoreApplication>
33 
34 #include "DatabaseFactory.h"
35 #include "DbAccess.h"
36 #include "Preference.h"
37 #include "FileName.h"
38 #include "IString.h"
39 
40 namespace Isis {
41 
42 
43  DatabaseFactory *DatabaseFactory::_factory = 0;
44 
69  DatabaseFactory::DatabaseFactory() : _defProfName(""), _profiles(),
70  _defDatabase(""), _dbList() {
71 
72 // Checks the existance of the Qt application core. This is required in order
73 // ensure database driver plugins are loaded - if they exist.
74  QCoreApplication *cApp = QCoreApplication::instance();
75  if(cApp == 0) {
76  static char **argv = 0;
77 
78  if(!argv) {
79  argv = new char*[2];
80  argv[0] = new char[1024];
81  strcpy(argv[0], "DatabaseFactory");
82  argv[1] = 0;
83  }
84 
85  static int argc = 1;
86  new QCoreApplication(argc, argv);
87  }
88 
89  // Initializes
90  init();
91 
92  // This ensures this singleton is shut down when the application exists,
93  // so existing database connections are terminated.
94  qAddPostRoutine(DieAtExit);
95  }
96 
101  selfDestruct();
102  }
103 
118  delete _factory;
119  _factory = 0;
120  return;
121  }
122 
135  if(DatabaseFactory::_factory == 0) {
137  }
138  return (DatabaseFactory::_factory);
139  }
140 
162  bool DatabaseFactory::addAccessProfile(const QString &profileFile) {
163  try {
164  FileName dbconf(profileFile);
165  if(dbconf.fileExists()) {
166  DbAccess acp(profileFile);
167 
168  // Add the top level one - may be replaced
169  const DbProfile &topProf = acp.getProfile();
170  _profiles.add(topProf.Name(), topProf);
171 
172  // Now add each individual one
173  for(int i = 0 ; i < acp.profileCount() ; i++) {
174  const DbProfile &newProf = acp.getProfile(i);
175  _profiles.add(newProf.Name(), newProf);
176  }
177 
178  // See if a default exists
179  if(acp.exists("DefaultProfile")) {
180  _defProfName = acp.value("DefaultProfile");
181  }
182  return (true);
183  }
184  }
185  catch(...) {
186  // upon any failure, we were unsuccessful
187  return (false);
188  }
189 
190  // File did not exist
191  return (false);
192  }
204  void DatabaseFactory::addProfile(const DbProfile &profile) {
205  _profiles.add(profile.Name(), profile);
206  return;
207  }
208 
217  std::vector<QString> DatabaseFactory::getProfileList() const {
218  std::vector<QString> plist;
219  for(int i = 0 ; i < _profiles.size() ; i++) {
220  plist.push_back(_profiles.key(i).ToQt());
221  }
222  return (plist);
223  }
224 
245  DbProfile DatabaseFactory::getProfile(const QString &name) const {
246  QString profName(name);
247  if(profName.isEmpty()) profName = _defProfName;
248 
249  // Refer to user access if provided
250  if(!_profiles.exists(profName)) {
251  return(DbProfile(profName));
252  }
253  else {
254  return (_profiles.get(profName));
255  }
256  }
257 
270  std::vector<QString> DatabaseFactory::available() const {
271  Drivers drivers = getResourceList(true, true);
272  std::vector<QString> dblist;
273  for(int i = 0 ; i < drivers.size() ; i++) {
274  dblist.push_back(drivers.key(i).ToQt());
275  }
276  return (dblist);
277  }
278 
289  bool DatabaseFactory::isDriverAvailable(const QString &dbname) const {
290  Drivers drivers = getResourceList(true, false);
291  if(!drivers.exists(dbname)) {
292  return (false);
293  }
294  return (QSqlDatabase::isDriverAvailable(drivers.get(dbname)));
295  }
296 
307  bool DatabaseFactory::isAvailable(const QString &dbname) const {
308  Drivers dbdrivers = getResourceList(false, true);
309  QString name(dbname);
310  if(name.isEmpty()) {
311  name = _defDatabase;
312  }
313  return (dbdrivers.exists(name));
314  }
315 
325  bool DatabaseFactory::isConnected(const QString &dbname) const {
326  QString name(dbname);
327  if(name.isEmpty()) {
328  name = _defDatabase;
329  }
330  return (QSqlDatabase::contains(name));
331  }
332 
345  bool DatabaseFactory::isPersistant(const QString &dbname) const {
346  return (_dbList.exists(dbname));
347  }
348 
349 
368  QSqlDatabase DatabaseFactory::create(const QString &driver,
369  const QString &dbname) {
370  // Check driver availability
371  if(!isDriverAvailable(driver)) {
372  QString mess = "Driver [" + driver + "] for database [" + dbname
373  + "] does not exist";
375  }
376 
377  // Create the database with the specified driver and name
378  Drivers drivers = getResourceList(true, false);
379  return (QSqlDatabase::addDatabase(drivers.get(driver), dbname));
380  }
381 
393  QSqlDatabase DatabaseFactory::create(const QString &dbname) {
394 
395  // Return an existing connection
396  if(_dbList.exists(dbname)) {
397  return (_dbList.get(dbname));
398  }
399 
400  // One doesn't exist, throw an error
401  QString mess = "Database [" + dbname + "] does not exist";
403  }
404 
423  void DatabaseFactory::add(const QSqlDatabase &db, const QString &name,
424  bool setAsDefault) {
425  _dbList.add(name, db);
426  if(setAsDefault) {
427  _defDatabase = name;
428  }
429  return;
430  }
431 
443  void DatabaseFactory::destroy(const QString &name) {
444  remove(name);
445  QSqlDatabase::removeDatabase(name);
446  return;
447  }
448 
458  void DatabaseFactory::remove(const QString &name) {
459  _dbList.remove(name);
460 #if 0
461  if(IString::Equal(name, _defDatabase)) {
462  _defDatabase = "";
463  }
464 #endif
465  return;
466  }
467 
476  // Add the PostgreSQL database driver explicitly if it doesn't exist
477  loadDrivers();
478 
479  // Use the users Preferences to determine if a default exists
480  initPreferences();
481  return;
482  }
483 
495  Preference &userPref = Preference::Preferences();
496  if(userPref.hasGroup("Database")) {
497  PvlGroup &dbgroup = userPref.findGroup("Database");
498  if(dbgroup.hasKeyword("AccessConfig")) {
499  addAccessProfile(dbgroup["AccessConfig"]);
500  }
501  // Get default profile name for later use
502  if(dbgroup.hasKeyword("DefaultProfile"))
503  _defProfName = (QString) dbgroup["DefaultProfile"];
504  }
505  return;
506  }
507 
525  bool connections)
526  const {
527  QStringList dblist;
528  if(drivers) dblist += QSqlDatabase::drivers();
529  if(connections) dblist += QSqlDatabase::connectionNames();
530  Drivers dbDrivers;
531  for(int i = 0 ; i < dblist.size() ; i++) {
532  QString dbname(dblist.at(i));
533  dbDrivers.add(dbname, dbname);
534  }
535 
536 
537  // Now create pseudonyms for well known databases
538  // PostgreSQL and UPC
539  if(dbDrivers.exists("QPSQL")) {
540  dbDrivers.add("PostgreSQL", "QPSQL");
541  }
542 
543  // MySQL and HiCAT
544  if(dbDrivers.exists("QMYSQL")) {
545  dbDrivers.add("MySQL", "QMYSQL");
546  }
547 
548  // Oracle
549  if(dbDrivers.exists("QOCI")) {
550  dbDrivers.add("Oracle", "QOCI");
551  }
552 
553  // SQLite
554  if(dbDrivers.exists("QSQLITE")) {
555  dbDrivers.add("SQLite", "QSQLITE");
556  }
557 
558  // That's it
559  return (dbDrivers);
560  }
561 
572  // Currently relying on Qt plugins - but that could change
573  return;
574  }
575 
584  while(_dbList.size() > 0) {
586  }
587  QStringList dblist = QSqlDatabase::connectionNames();
588  for(int i = 0 ; i < dblist.size() ; i++) {
589  QSqlDatabase::removeDatabase(dblist[i]);
590  }
591  return;
592  }
593 
594 }
const K & key(int nth) const
Returns the nth key in the collection.
Definition: CollectorMap.h:683
bool exists(const K &key) const
Checks the existance of a particular key in the list.
Definition: CollectorMap.h:563
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
T & get(const K &key)
Returns the value associated with the name provided.
Definition: CollectorMap.h:579
QString ToQt() const
Retuns the object string as a QString.
Definition: IString.cpp:884
File name manipulation and expansion.
Definition: FileName.h:111
bool Equal(const std::string &str) const
Compare a string to the object IString.
Definition: IString.cpp:705
DbProfile getProfile(const QString &name="") const
Get the specified database access profile.
const DbProfile getProfile(const QString &name="") const
Retrieves the specified access profile.
Definition: DbAccess.cpp:106
void addProfile(const DbProfile &profile)
Adds a database access profile to the list of profiles.
QString Name() const
Returns the name of this property.
Definition: DbProfile.h:118
bool isAvailable(const QString &dbname="") const
Check for availablity of a database connection resource.
int remove(const K &key)
Removes and entry from the list.
Definition: CollectorMap.h:704
std::vector< QString > available() const
Determine what database drivers are available.
static DatabaseFactory * getInstance()
Returns and instance of this DatabaseFactory singleton.
std::vector< QString > getProfileList() const
Return list of names of currently available profiles.
Create database interfaces using access profiles or generic drivers.
QString value(const QString &key, int nth=0) const
Returns the specified value for the given keyword.
Definition: DbProfile.cpp:160
A DbProfile is a container for access parameters to a database.
Definition: DbProfile.h:65
int profileCount() const
Reports the number of user profiles to access this database.
Definition: DbAccess.h:141
bool addAccessProfile(const QString &profileFile)
Establishes an access profile for subsequent database connections.
void initPreferences()
Initializes user database preferences.
QString _defProfName
Default profile name.
Drivers getResourceList(bool drivers, bool connections) const
Get a list of available database drivers and connections.
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
DatabaseFactory()
Constructor establishing the startup state of this singleton.
void add(const K &key, const T &value)
Adds the element to the list.
Definition: CollectorMap.h:552
bool isDriverAvailable(const QString &driver) const
Check for the existance of a specific database driver.
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:126
bool isConnected(const QString &dbname) const
Determines if the database resource is connected.
void loadDrivers()
Load any drivers explicity.
void selfDestruct()
Destroy all elements associated with this object.
Collector/container for arbitrary items.
Definition: CollectorMap.h:433
void add(const QSqlDatabase &db, const QString &name, bool setAsDefault=false)
Adds the database to the connection pool making it persistant.
void remove(const QString &dbname)
Removes the database from the connection pool.
bool exists(const QString &key) const
Checks for the existance of a keyword.
Definition: DbProfile.h:129
void init()
Initializes this object upon instantiation.
Profiles _profiles
Maintain list of profiles.
~DatabaseFactory()
Destructor implements self-destruction of this object.
Databases _dbList
Maintains active databases.
int size() const
Returns the size of the collection.
Definition: CollectorMap.h:524
Isis exception class.
Definition: IException.h:99
DbAccess manages programatic access to a database through profiles.
Definition: DbAccess.h:120
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
Definition: PvlObject.h:222
static DatabaseFactory * _factory
Pointer to self (singleton)
static void DieAtExit()
Exit termination routine.
void destroy(const QString &dbname)
Removes the database from the connection pool and destroys it.
bool isPersistant(const QString &name) const
Checks if the database resource is persistant.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
QSqlDatabase create(const QString &driver, const QString &dbname)
Create a database using the named driver.
Reads user preferences from a data file.
Definition: Preference.h:77
QString _defDatabase
Name of default database.

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:17:22