Isis 3 Programmer Reference
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 #include <QDebug>
30 #include <QString>
31 #include <QStringList>
32 #include <QCoreApplication>
33 #include <QSqlDatabase>
34 
35 #include "DatabaseFactory.h"
36 #include "DbAccess.h"
37 #include "Preference.h"
38 #include "FileName.h"
39 #include "IString.h"
40 
41 namespace Isis {
42 
43 
44  DatabaseFactory *DatabaseFactory::_factory = 0;
45 
70  DatabaseFactory::DatabaseFactory() : _defProfName(""), _profiles(),
71  _defDatabase(""), _dbList() {
72 
73  // insure the drivers are being loaded
74  loadDrivers();
75  // Checks the existance of the Qt application core. This is required in order
76  // ensure database driver plugins are loaded - if they exist.
77  QCoreApplication *cApp = QCoreApplication::instance();
78  if(cApp == 0) {
79  static char **argv = 0;
80 
81  if(!argv) {
82  argv = new char*[2];
83  argv[0] = new char[1024];
84  strcpy(argv[0], "DatabaseFactory");
85  argv[1] = 0;
86  }
87 
88  static int argc = 1;
89  new QCoreApplication(argc, argv);
90  }
91 
92  // Initializes
93  init();
94 
95  // This ensures this singleton is shut down when the application exists,
96  // so existing database connections are terminated.
97  qAddPostRoutine(DieAtExit);
98  }
99 
104  selfDestruct();
105  }
106 
121  delete _factory;
122  _factory = 0;
123  return;
124  }
125 
138  if(DatabaseFactory::_factory == 0) {
140  }
141  return (DatabaseFactory::_factory);
142  }
143 
165  bool DatabaseFactory::addAccessProfile(const QString &profileFile) {
166  try {
167  FileName dbconf(profileFile);
168  if(dbconf.fileExists()) {
169  DbAccess acp(profileFile);
170 
171  // Add the top level one - may be replaced
172  const DbProfile &topProf = acp.getProfile();
173  _profiles.add(topProf.Name(), topProf);
174 
175  // Now add each individual one
176  for(int i = 0 ; i < acp.profileCount() ; i++) {
177  const DbProfile &newProf = acp.getProfile(i);
178  _profiles.add(newProf.Name(), newProf);
179  }
180 
181  // See if a default exists
182  if(acp.exists("DefaultProfile")) {
183  _defProfName = acp.value("DefaultProfile");
184  }
185  return (true);
186  }
187  }
188  catch(...) {
189  // upon any failure, we were unsuccessful
190  return (false);
191  }
192 
193  // File did not exist
194  return (false);
195  }
207  void DatabaseFactory::addProfile(const DbProfile &profile) {
208  _profiles.add(profile.Name(), profile);
209  return;
210  }
211 
220  std::vector<QString> DatabaseFactory::getProfileList() const {
221  std::vector<QString> plist;
222  for(int i = 0 ; i < _profiles.size() ; i++) {
223  plist.push_back(_profiles.key(i).ToQt());
224  }
225  return (plist);
226  }
227 
248  DbProfile DatabaseFactory::getProfile(const QString &name) const {
249  QString profName(name);
250  if(profName.isEmpty()) profName = _defProfName;
251 
252  // Refer to user access if provided
253  if(!_profiles.exists(profName)) {
254  return(DbProfile(profName));
255  }
256  else {
257  return (_profiles.get(profName));
258  }
259  }
260 
273  std::vector<QString> DatabaseFactory::available() const {
274  Drivers drivers = getResourceList(true, true);
275  std::vector<QString> dblist;
276  for(int i = 0 ; i < drivers.size() ; i++) {
277  dblist.push_back(drivers.key(i).ToQt());
278  }
279  return (dblist);
280  }
281 
292  bool DatabaseFactory::isDriverAvailable(const QString &dbname) const {
293  Drivers drivers = getResourceList(true, false);
294  if(!drivers.exists(dbname)) {
295  return (false);
296  }
297  return (QSqlDatabase::isDriverAvailable(drivers.get(dbname)));
298  }
299 
310  bool DatabaseFactory::isAvailable(const QString &dbname) const {
311  Drivers dbdrivers = getResourceList(false, true);
312  QString name(dbname);
313  if(name.isEmpty()) {
314  name = _defDatabase;
315  }
316  return (dbdrivers.exists(name));
317  }
318 
328  bool DatabaseFactory::isConnected(const QString &dbname) const {
329  QString name(dbname);
330  if(name.isEmpty()) {
331  name = _defDatabase;
332  }
333  return (QSqlDatabase::contains(name));
334  }
335 
348  bool DatabaseFactory::isPersistant(const QString &dbname) const {
349  return (_dbList.exists(dbname));
350  }
351 
352 
371  QSqlDatabase DatabaseFactory::create(const QString &driver,
372  const QString &dbname) {
373 
374 
375  // Check driver availability
376  if(!isDriverAvailable(driver)) {
377  QString mess = "Driver [" + driver + "] for database [" + dbname
378  + "] does not exist";
380  }
381 
382  // Create the database with the specified driver and name
383  Drivers drivers = getResourceList(true, false);
384  return (QSqlDatabase::addDatabase(drivers.get(driver), dbname));
385  }
386 
398  QSqlDatabase DatabaseFactory::create(const QString &dbname) {
399 
400  // Return an existing connection
401  if(_dbList.exists(dbname)) {
402  return (_dbList.get(dbname));
403  }
404 
405  // One doesn't exist, throw an error
406  QString mess = "Database [" + dbname + "] does not exist";
408  }
409 
428  void DatabaseFactory::add(const QSqlDatabase &db, const QString &name,
429  bool setAsDefault) {
430  _dbList.add(name, db);
431  if(setAsDefault) {
432  _defDatabase = name;
433  }
434  return;
435  }
436 
448  void DatabaseFactory::destroy(const QString &name) {
449  remove(name);
450  QSqlDatabase::removeDatabase(name);
451  return;
452  }
453 
463  void DatabaseFactory::remove(const QString &name) {
464  _dbList.remove(name);
465 #if 0
466  if(IString::Equal(name, _defDatabase)) {
467  _defDatabase = "";
468  }
469 #endif
470  return;
471  }
472 
481  // Add the PostgreSQL database driver explicitly if it doesn't exist
482  loadDrivers();
483 
484  // Use the users Preferences to determine if a default exists
485  initPreferences();
486  return;
487  }
488 
500  Preference &userPref = Preference::Preferences();
501  if(userPref.hasGroup("Database")) {
502  PvlGroup &dbgroup = userPref.findGroup("Database");
503  if(dbgroup.hasKeyword("AccessConfig")) {
504  addAccessProfile(dbgroup["AccessConfig"]);
505  }
506  // Get default profile name for later use
507  if(dbgroup.hasKeyword("DefaultProfile"))
508  _defProfName = (QString) dbgroup["DefaultProfile"];
509  }
510  return;
511  }
512 
530  bool connections)
531  const {
532  QStringList dblist;
533  if(drivers) dblist += QSqlDatabase::drivers();
534  if(connections) dblist += QSqlDatabase::connectionNames();
535  Drivers dbDrivers;
536  for(int i = 0 ; i < dblist.size() ; i++) {
537  QString dbname(dblist.at(i));
538  dbDrivers.add(dbname, dbname);
539  }
540 
541 
542  // Now create pseudonyms for well known databases
543  // PostgreSQL and UPC
544  if(dbDrivers.exists("QPSQL")) {
545  dbDrivers.add("PostgreSQL", "QPSQL");
546  }
547 
548  // MySQL and HiCAT
549  if(dbDrivers.exists("QMYSQL")) {
550  dbDrivers.add("MySQL", "QMYSQL");
551  }
552 
553  // Oracle
554  if(dbDrivers.exists("QOCI")) {
555  dbDrivers.add("Oracle", "QOCI");
556  }
557 
558  // SQLite
559  if(dbDrivers.exists("QSQLITE")) {
560  dbDrivers.add("SQLite", "QSQLITE");
561  }
562 
563  return dbDrivers;
564  }
565 
576  // Currently relying on Qt plugins - but that could change
577  // Hack to insure drivers are being loaded correctly
578  QSqlDatabase::drivers();
579  return;
580  }
581 
590  while(_dbList.size() > 0) {
592  }
593  QStringList dblist = QSqlDatabase::connectionNames();
594  for(int i = 0 ; i < dblist.size() ; i++) {
595  QSqlDatabase::removeDatabase(dblist[i]);
596  }
597  return;
598  }
599 
600 }
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Drivers getResourceList(bool drivers, bool connections) const
Get a list of available database drivers and connections.
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:583
File name manipulation and expansion.
Definition: FileName.h:116
std::vector< QString > available() const
Determine what database drivers are available.
void addProfile(const DbProfile &profile)
Adds a database access profile to the list of profiles.
DbProfile getProfile(const QString &name="") const
Get the specified database access profile.
int remove(const K &key)
Removes and entry from the list.
Definition: CollectorMap.h:710
Namespace for the standard library.
static DatabaseFactory * getInstance()
Returns and instance of this DatabaseFactory singleton.
bool exists(const QString &key) const
Checks for the existance of a keyword.
Definition: DbProfile.h:129
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
int size() const
Returns the size of the collection.
Definition: CollectorMap.h:528
Create database interfaces using access profiles or generic drivers.
A DbProfile is a container for access parameters to a database.
Definition: DbProfile.h:65
bool addAccessProfile(const QString &profileFile)
Establishes an access profile for subsequent database connections.
void initPreferences()
Initializes user database preferences.
QString _defProfName
Default profile name.
const K & key(int nth) const
Returns the nth key in the collection.
Definition: CollectorMap.h:689
const DbProfile getProfile(const QString &name="") const
Retrieves the specified access profile.
Definition: DbAccess.cpp:106
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
bool exists(const K &key) const
Checks the existance of a particular key in the list.
Definition: CollectorMap.h:567
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
QString value(const QString &key, int nth=0) const
Returns the specified value for the given keyword.
Definition: DbProfile.cpp:160
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:556
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
bool isAvailable(const QString &dbname="") const
Check for availablity of a database connection resource.
QString ToQt() const
Retuns the object string as a QString.
Definition: IString.cpp:884
bool isDriverAvailable(const QString &driver) const
Check for the existance of a specific database driver.
void loadDrivers()
Load any drivers explicity.
void selfDestruct()
Destroy all elements associated with this object.
Collector/container for arbitrary items.
Definition: CollectorMap.h:435
int profileCount() const
Reports the number of user profiles to access this database.
Definition: DbAccess.h:141
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.
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.
bool Equal(const std::string &str) const
Compare a string to the object IString.
Definition: IString.cpp:705
Isis exception class.
Definition: IException.h:107
DbAccess manages programatic access to a database through profiles.
Definition: DbAccess.h:120
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
QString Name() const
Returns the name of this property.
Definition: DbProfile.h:118
static DatabaseFactory * _factory
Pointer to self (singleton)
bool isConnected(const QString &dbname) const
Determines if the database resource is connected.
static void DieAtExit()
Exit termination routine.
std::vector< QString > getProfileList() const
Return list of names of currently available profiles.
void destroy(const QString &dbname)
Removes the database from the connection pool and destroys it.
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:465
bool isPersistant(const QString &name) const
Checks if the database resource is persistant.
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.