Isis 3 Programmer Reference
DatabaseFactory.cpp
1 
7 /* SPDX-License-Identifier: CC0-1.0 */
8 
9 #include <cstdlib>
10 #include <string>
11 #include <vector>
12 #include <iostream>
13 
14 using namespace std;
15 
16 #include <QDebug>
17 #include <QString>
18 #include <QStringList>
19 #include <QCoreApplication>
20 #include <QSqlDatabase>
21 
22 #include "DatabaseFactory.h"
23 #include "DbAccess.h"
24 #include "Preference.h"
25 #include "FileName.h"
26 #include "IString.h"
27 
28 namespace Isis {
29 
30 
31  DatabaseFactory *DatabaseFactory::_factory = 0;
32 
57  DatabaseFactory::DatabaseFactory() : _defProfName(""), _profiles(),
58  _defDatabase(""), _dbList() {
59 
60  // insure the drivers are being loaded
61  loadDrivers();
62  // Checks the existance of the Qt application core. This is required in order
63  // ensure database driver plugins are loaded - if they exist.
64  QCoreApplication *cApp = QCoreApplication::instance();
65  if(cApp == 0) {
66  static char **argv = 0;
67 
68  if(!argv) {
69  argv = new char*[2];
70  argv[0] = new char[1024];
71  strcpy(argv[0], "DatabaseFactory");
72  argv[1] = 0;
73  }
74 
75  static int argc = 1;
76  new QCoreApplication(argc, argv);
77  }
78 
79  // Initializes
80  init();
81 
82  // This ensures this singleton is shut down when the application exists,
83  // so existing database connections are terminated.
84  qAddPostRoutine(DieAtExit);
85  }
86 
91  selfDestruct();
92  }
93 
108  delete _factory;
109  _factory = 0;
110  return;
111  }
112 
125  if(DatabaseFactory::_factory == 0) {
127  }
128  return (DatabaseFactory::_factory);
129  }
130 
152  bool DatabaseFactory::addAccessProfile(const QString &profileFile) {
153  try {
154  FileName dbconf(profileFile);
155  if(dbconf.fileExists()) {
156  DbAccess acp(profileFile);
157 
158  // Add the top level one - may be replaced
159  const DbProfile &topProf = acp.getProfile();
160  _profiles.add(topProf.Name(), topProf);
161 
162  // Now add each individual one
163  for(int i = 0 ; i < acp.profileCount() ; i++) {
164  const DbProfile &newProf = acp.getProfile(i);
165  _profiles.add(newProf.Name(), newProf);
166  }
167 
168  // See if a default exists
169  if(acp.exists("DefaultProfile")) {
170  _defProfName = acp.value("DefaultProfile");
171  }
172  return (true);
173  }
174  }
175  catch(...) {
176  // upon any failure, we were unsuccessful
177  return (false);
178  }
179 
180  // File did not exist
181  return (false);
182  }
194  void DatabaseFactory::addProfile(const DbProfile &profile) {
195  _profiles.add(profile.Name(), profile);
196  return;
197  }
198 
207  std::vector<QString> DatabaseFactory::getProfileList() const {
208  std::vector<QString> plist;
209  for(int i = 0 ; i < _profiles.size() ; i++) {
210  plist.push_back(_profiles.key(i).ToQt());
211  }
212  return (plist);
213  }
214 
235  DbProfile DatabaseFactory::getProfile(const QString &name) const {
236  QString profName(name);
237  if(profName.isEmpty()) profName = _defProfName;
238 
239  // Refer to user access if provided
240  if(!_profiles.exists(profName)) {
241  return(DbProfile(profName));
242  }
243  else {
244  return (_profiles.get(profName));
245  }
246  }
247 
260  std::vector<QString> DatabaseFactory::available() const {
261  Drivers drivers = getResourceList(true, true);
262  std::vector<QString> dblist;
263  for(int i = 0 ; i < drivers.size() ; i++) {
264  dblist.push_back(drivers.key(i).ToQt());
265  }
266  return (dblist);
267  }
268 
279  bool DatabaseFactory::isDriverAvailable(const QString &dbname) const {
280  Drivers drivers = getResourceList(true, false);
281  if(!drivers.exists(dbname)) {
282  return (false);
283  }
284  return (QSqlDatabase::isDriverAvailable(drivers.get(dbname)));
285  }
286 
297  bool DatabaseFactory::isAvailable(const QString &dbname) const {
298  Drivers dbdrivers = getResourceList(false, true);
299  QString name(dbname);
300  if(name.isEmpty()) {
301  name = _defDatabase;
302  }
303  return (dbdrivers.exists(name));
304  }
305 
315  bool DatabaseFactory::isConnected(const QString &dbname) const {
316  QString name(dbname);
317  if(name.isEmpty()) {
318  name = _defDatabase;
319  }
320  return (QSqlDatabase::contains(name));
321  }
322 
335  bool DatabaseFactory::isPersistant(const QString &dbname) const {
336  return (_dbList.exists(dbname));
337  }
338 
339 
358  QSqlDatabase DatabaseFactory::create(const QString &driver,
359  const QString &dbname) {
360 
361 
362  // Check driver availability
363  if(!isDriverAvailable(driver)) {
364  QString mess = "Driver [" + driver + "] for database [" + dbname
365  + "] does not exist";
366  throw IException(IException::Unknown, mess, _FILEINFO_);
367  }
368 
369  // Create the database with the specified driver and name
370  Drivers drivers = getResourceList(true, false);
371  return (QSqlDatabase::addDatabase(drivers.get(driver), dbname));
372  }
373 
385  QSqlDatabase DatabaseFactory::create(const QString &dbname) {
386 
387  // Return an existing connection
388  if(_dbList.exists(dbname)) {
389  return (_dbList.get(dbname));
390  }
391 
392  // One doesn't exist, throw an error
393  QString mess = "Database [" + dbname + "] does not exist";
394  throw IException(IException::Unknown, mess, _FILEINFO_);
395  }
396 
415  void DatabaseFactory::add(const QSqlDatabase &db, const QString &name,
416  bool setAsDefault) {
417  _dbList.add(name, db);
418  if(setAsDefault) {
419  _defDatabase = name;
420  }
421  return;
422  }
423 
435  void DatabaseFactory::destroy(const QString &name) {
436  remove(name);
437  QSqlDatabase::removeDatabase(name);
438  return;
439  }
440 
450  void DatabaseFactory::remove(const QString &name) {
451  _dbList.remove(name);
452 #if 0
453  if(IString::Equal(name, _defDatabase)) {
454  _defDatabase = "";
455  }
456 #endif
457  return;
458  }
459 
468  // Add the PostgreSQL database driver explicitly if it doesn't exist
469  loadDrivers();
470 
471  // Use the users Preferences to determine if a default exists
472  initPreferences();
473  return;
474  }
475 
487  Preference &userPref = Preference::Preferences();
488  if(userPref.hasGroup("Database")) {
489  PvlGroup &dbgroup = userPref.findGroup("Database");
490  if(dbgroup.hasKeyword("AccessConfig")) {
491  addAccessProfile(dbgroup["AccessConfig"]);
492  }
493  // Get default profile name for later use
494  if(dbgroup.hasKeyword("DefaultProfile"))
495  _defProfName = (QString) dbgroup["DefaultProfile"];
496  }
497  return;
498  }
499 
517  bool connections)
518  const {
519  QStringList dblist;
520  if(drivers) dblist += QSqlDatabase::drivers();
521  if(connections) dblist += QSqlDatabase::connectionNames();
522  Drivers dbDrivers;
523  for(int i = 0 ; i < dblist.size() ; i++) {
524  QString dbname(dblist.at(i));
525  dbDrivers.add(dbname, dbname);
526  }
527 
528 
529  // Now create pseudonyms for well known databases
530  // PostgreSQL and UPC
531  if(dbDrivers.exists("QPSQL")) {
532  dbDrivers.add("PostgreSQL", "QPSQL");
533  }
534 
535  // MySQL and HiCAT
536  if(dbDrivers.exists("QMYSQL")) {
537  dbDrivers.add("MySQL", "QMYSQL");
538  }
539 
540  // Oracle
541  if(dbDrivers.exists("QOCI")) {
542  dbDrivers.add("Oracle", "QOCI");
543  }
544 
545  // SQLite
546  if(dbDrivers.exists("QSQLITE")) {
547  dbDrivers.add("SQLite", "QSQLITE");
548  }
549 
550  return dbDrivers;
551  }
552 
563  // Currently relying on Qt plugins - but that could change
564  // Hack to insure drivers are being loaded correctly
565  QSqlDatabase::drivers();
566  return;
567  }
568 
577  while(_dbList.size() > 0) {
579  }
580  QStringList dblist = QSqlDatabase::connectionNames();
581  for(int i = 0 ; i < dblist.size() ; i++) {
582  QSqlDatabase::removeDatabase(dblist[i]);
583  }
584  return;
585  }
586 
587 }
Isis::DatabaseFactory::isConnected
bool isConnected(const QString &dbname) const
Determines if the database resource is connected.
Definition: DatabaseFactory.cpp:315
Isis::DatabaseFactory::DatabaseFactory
DatabaseFactory()
Constructor establishing the startup state of this singleton.
Definition: DatabaseFactory.cpp:57
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::DatabaseFactory::create
QSqlDatabase create(const QString &driver, const QString &dbname)
Create a database using the named driver.
Definition: DatabaseFactory.cpp:358
Isis::DbProfile::Name
QString Name() const
Returns the name of this property.
Definition: DbProfile.h:104
Isis::DbProfile::exists
bool exists(const QString &key) const
Checks for the existance of a keyword.
Definition: DbProfile.h:115
Isis::DatabaseFactory::getProfileList
std::vector< QString > getProfileList() const
Return list of names of currently available profiles.
Definition: DatabaseFactory.cpp:207
QSqlDatabase
Isis::DatabaseFactory::getProfile
DbProfile getProfile(const QString &name="") const
Get the specified database access profile.
Definition: DatabaseFactory.cpp:235
Isis::DbAccess
DbAccess manages programatic access to a database through profiles.
Definition: DbAccess.h:106
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::DatabaseFactory::init
void init()
Initializes this object upon instantiation.
Definition: DatabaseFactory.cpp:467
Isis::DatabaseFactory::_defDatabase
QString _defDatabase
Name of default database.
Definition: DatabaseFactory.h:340
Isis::IException::Unknown
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:118
Isis::DatabaseFactory::remove
void remove(const QString &dbname)
Removes the database from the connection pool.
Definition: DatabaseFactory.cpp:450
Isis::FileName::fileExists
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:449
Isis::CollectorMap::get
T & get(const K &key)
Returns the value associated with the name provided.
Definition: CollectorMap.h:567
Isis::PvlObject::hasGroup
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
Definition: PvlObject.h:210
Isis::CollectorMap::size
int size() const
Returns the size of the collection.
Definition: CollectorMap.h:512
Isis::CollectorMap::remove
int remove(const K &key)
Removes and entry from the list.
Definition: CollectorMap.h:694
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::DatabaseFactory::available
std::vector< QString > available() const
Determine what database drivers are available.
Definition: DatabaseFactory.cpp:260
Isis::DatabaseFactory::isDriverAvailable
bool isDriverAvailable(const QString &driver) const
Check for the existance of a specific database driver.
Definition: DatabaseFactory.cpp:279
Isis::DatabaseFactory::addProfile
void addProfile(const DbProfile &profile)
Adds a database access profile to the list of profiles.
Definition: DatabaseFactory.cpp:194
Isis::DatabaseFactory::isPersistant
bool isPersistant(const QString &name) const
Checks if the database resource is persistant.
Definition: DatabaseFactory.cpp:335
QStringList
Isis::DatabaseFactory::destroy
void destroy(const QString &dbname)
Removes the database from the connection pool and destroys it.
Definition: DatabaseFactory.cpp:435
Isis::DatabaseFactory::isAvailable
bool isAvailable(const QString &dbname="") const
Check for availablity of a database connection resource.
Definition: DatabaseFactory.cpp:297
Isis::DatabaseFactory::add
void add(const QSqlDatabase &db, const QString &name, bool setAsDefault=false)
Adds the database to the connection pool making it persistant.
Definition: DatabaseFactory.cpp:415
Isis::CollectorMap::exists
bool exists(const K &key) const
Checks the existance of a particular key in the list.
Definition: CollectorMap.h:551
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::CollectorMap::key
const K & key(int nth) const
Returns the nth key in the collection.
Definition: CollectorMap.h:673
Isis::DatabaseFactory::selfDestruct
void selfDestruct()
Destroy all elements associated with this object.
Definition: DatabaseFactory.cpp:576
Isis::DatabaseFactory::loadDrivers
void loadDrivers()
Load any drivers explicity.
Definition: DatabaseFactory.cpp:562
Isis::DatabaseFactory::_factory
static DatabaseFactory * _factory
Pointer to self (singleton)
Definition: DatabaseFactory.h:329
Isis::DatabaseFactory::addAccessProfile
bool addAccessProfile(const QString &profileFile)
Establishes an access profile for subsequent database connections.
Definition: DatabaseFactory.cpp:152
Isis::DatabaseFactory::_dbList
Databases _dbList
Maintains active databases.
Definition: DatabaseFactory.h:341
Isis::Preference
Reads user preferences from a data file.
Definition: Preference.h:60
Isis::DbProfile
A DbProfile is a container for access parameters to a database.
Definition: DbProfile.h:51
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::CollectorMap::add
void add(const K &key, const T &value)
Adds the element to the list.
Definition: CollectorMap.h:540
Isis::DatabaseFactory
Create database interfaces using access profiles or generic drivers.
Definition: DatabaseFactory.h:244
Isis::DatabaseFactory::getInstance
static DatabaseFactory * getInstance()
Returns and instance of this DatabaseFactory singleton.
Definition: DatabaseFactory.cpp:124
std
Namespace for the standard library.
Isis::CollectorMap
Collector/container for arbitrary items.
Definition: CollectorMap.h:419
Isis::DbAccess::profileCount
int profileCount() const
Reports the number of user profiles to access this database.
Definition: DbAccess.h:127
Isis::DatabaseFactory::getResourceList
Drivers getResourceList(bool drivers, bool connections) const
Get a list of available database drivers and connections.
Definition: DatabaseFactory.cpp:516
Isis::IString::Equal
bool Equal(const std::string &str) const
Compare a string to the object IString.
Definition: IString.cpp:690
Isis::DbAccess::getProfile
const DbProfile getProfile(const QString &name="") const
Retrieves the specified access profile.
Definition: DbAccess.cpp:92
Isis::DatabaseFactory::DieAtExit
static void DieAtExit()
Exit termination routine.
Definition: DatabaseFactory.cpp:107
Isis::DbProfile::value
QString value(const QString &key, int nth=0) const
Returns the specified value for the given keyword.
Definition: DbProfile.cpp:146
Isis::DatabaseFactory::~DatabaseFactory
~DatabaseFactory()
Destructor implements self-destruction of this object.
Definition: DatabaseFactory.cpp:90
Isis::DatabaseFactory::_defProfName
QString _defProfName
Default profile name.
Definition: DatabaseFactory.h:338
Isis::DatabaseFactory::initPreferences
void initPreferences()
Initializes user database preferences.
Definition: DatabaseFactory.cpp:486
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::IString::ToQt
QString ToQt() const
Retuns the object string as a QString.
Definition: IString.cpp:869
Isis::DatabaseFactory::_profiles
Profiles _profiles
Maintain list of profiles.
Definition: DatabaseFactory.h:339