Isis 3 Programmer Reference
Database.cpp
Go to the documentation of this file.
1 
22 #include <string>
23 #include <vector>
24 #include <iostream>
25 #include "DbProfile.h"
26 #include "Database.h"
27 #include "DatabaseFactory.h"
28 #include "IString.h"
29 
30 #include <QStringList>
31 #include <QSqlError>
32 
33 using namespace std;
34 
35 namespace Isis {
36 
37  QString Database::_actualConnectionName = "";
38 
46  Database::Database() : QSqlDatabase(), _name("") { }
47 
66  Database::Database(Database::Access dbConn) : QSqlDatabase(init()), _name("") {
67  _name = _actualConnectionName;
68  if((dbConn == Connect) && isValid()) {
69  if(!open()) {
70  QString mess = "Failed to open database default database [" + _name;
71  tossDbError(mess, _FILEINFO_);
72  }
73  }
74 // Name cannot be set, so set to determined name
75  }
76 
88  Database::Database(const QString &name, Database::Access dbConn) :
89  QSqlDatabase(init(name)), _name(name) {
90  _name = _actualConnectionName;
91  if((dbConn == Connect) && isValid()) {
92  if(!open()) {
93  QString mess = "Failed to open database specified as " + _name;
94  tossDbError(mess, _FILEINFO_);
95  }
96  }
97  }
98 
117  Database::Database(const QString &connName, const QString &driverType) :
118  QSqlDatabase(init(connName, driverType)), _name(connName) {
119  _name = _actualConnectionName;
120  }
121 
138  QSqlDatabase(init(profile, DoNotConnect)),
139  _name(profile.Name()) {
140  _name = _actualConnectionName;
141  if((dbConn == Connect) && isValid()) {
142  if(!open()) {
143  QString mess = "Failed to open database with profile " + _name;
144  tossDbError(mess, _FILEINFO_);
145  }
146  }
147  }
148 
159  Database::Database(const QSqlDatabase &other, const QString &newName) :
160  QSqlDatabase(QSqlDatabase::cloneDatabase(other, newName)),
161  _name(newName) { }
162 
163 
175  if(!factory->isPersistant(_name)) {
176  if(isOpen()) {
177  close();
178  }
179  factory->remove(_name);
180  }
181  }
182 
206  if(!factory->isPersistant(_name)) {
207  factory->add(*this, _name);
208  }
209  return;
210  }
211 
220  bool Database::isPersistant() const {
222  return (factory->isPersistant(_name));
223  }
224 
241  if(!factory->isPersistant(_name)) {
242  factory->add(*this, _name);
243  }
244  factory->setDefault(_name);
245  return;
246  }
247 
267  void Database::remove(const QString &name) {
269  factory->destroy(name);
270  return;
271  }
272 
288  bool Database::addAccessConfig(const QString &confFile) {
290  return (factory->addAccessProfile(confFile));
291  }
292 
325  DbProfile Database::getProfile(const QString &name) {
327  return (factory->getProfile(name));
328  }
329 
356  QSqlDatabase Database::init(const QString &connName,
357  const QString &driverType) {
358 
359  _actualConnectionName = connName;
361 
362  // First test for condition where both name and type are not provided.
363  // This tests for the default profile and returns it if it exists,
364  // otherwise it returns a default database.
365  if(connName.isEmpty() && driverType.isEmpty()) {
366  if(factory->isAvailable(factory->getDefault())) {
367  _actualConnectionName = factory->getDefault();
368  return (factory->create(_actualConnectionName));
369  }
370 
371  // No default is established so retreive the default profile
372  DbProfile profile = factory->getProfile();
373  if(profile.isValid()) {
374  return (init(profile, DoNotConnect));
375  }
376  }
377 
378  // If only the name and no driver is provided, get an existing connection
379  if((!connName.isEmpty()) && (driverType.isEmpty())) {
380  if(factory->isAvailable(connName)) {
381  _actualConnectionName = connName;
382  return (factory->create(connName));
383  }
384  else {
385  // See if the database exists by profile
386  DbProfile profile = factory->getProfile(connName);
387  return (init(profile, DoNotConnect));
388  }
389  }
390 
391  // Finally, a driver and optional name is provided. This condition sets up
392  // a named database for subsequent definition later
393  return (factory->create(driverType, connName));
394  }
395 
396 
417  if(!profile.isValid()) {
418  ostringstream mess;
419  mess << "Database/profile [" << profile.Name() << "] is not valid!" << ends;
420  throw IException(IException::Programmer, mess.str(), _FILEINFO_);
421  }
422 
423  _actualConnectionName = profile.Name();
425 
426  // initialize the database
427  try {
428 
429  // If we reach here, it is a valid profile. Create the database and
430  // return it as initialized from the profile contents
431  QSqlDatabase db = factory->create(profile("Type"), profile("Name"));
432  _actualConnectionName = profile("Name");
433  configureAccess(db, profile);
434 
435  // Go ahead and connect if requested
436  if(dbConn == Connect) {
437  if(!db.open()) {
438  QString mess = "Failed to connect to database using profile " +
439  profile("Name");
440  tossDbError(mess, _FILEINFO_);
441  }
442  }
443  return (db);
444  }
445  catch(IException &ie) {
446  QString mess = "Unable to create database from " + profile.Name();
447  throw IException(ie, IException::User, mess, _FILEINFO_);
448  }
449  catch(...) {
450  QString mess = "Unknown exception while creating database from profile "
451  + profile.Name();
452  throw IException(IException::User, mess, _FILEINFO_);
453  }
454  }
455 
469  if(profile.exists("Host")) {
470  db.setHostName(profile("Host"));
471  }
472 
473  if(profile.exists("DbName")) {
474  db.setDatabaseName(profile("DbName"));
475  }
476 
477  if(profile.exists("User")) {
478  db.setUserName(profile("User"));
479  }
480 
481  if(profile.exists("Password")) {
482  db.setPassword(profile("Password"));
483  }
484 
485  if(profile.exists("Port")) {
486  bool ok;
487  db.setPort(profile("Port").toInt(&ok));
488  if(!ok) {
489  ostringstream mess;
490  mess << "Invalid port number [" << profile("Port") << "] in profile "
491  << profile("Name") << ends;
492  throw IException(IException::User, mess.str().c_str(), _FILEINFO_);
493  }
494  }
495 
496  if(profile.exists("Options")) {
497  db.setConnectOptions(profile("Options"));
498  }
499  return;
500  }
501 
512  Database Database::clone(const QString &name) const {
513  return (Database(*this, name));
514  }
515 
525  return (tables(QSql::Tables));
526  }
527 
538  return (tables(QSql::Views));
539  }
540 
550  return (tables(QSql::SystemTables));
551  }
552 
563  void Database::tossDbError(const QString &message, const char *f, int l) const {
564  QString errmess = message + " - DatabaseError = " +
565  lastError().text();
566  throw IException(IException::Programmer, errmess, f, l);
567  }
568 
569 }
bool isPersistant() const
Checks persistancy state of a database instantiation.
Definition: Database.cpp:220
QString getDefault() const
Returns the name of the default database.
void setDefault(const QString &name)
Sets the default name of the database.
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition: IString.cpp:108
DbProfile getProfile(const QString &name="") const
Get the specified database access profile.
Namespace for the standard library.
Do not connect to database.
Definition: Database.h:89
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
Connect to database immediately.
Definition: Database.h:88
Database clone(const QString &name) const
Clones this database into another giving it another name.
Definition: Database.cpp:512
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:162
Create database interfaces using access profiles or generic drivers.
A DbProfile is a container for access parameters to a database.
Definition: DbProfile.h:65
static DbProfile getProfile(const QString &name)
Retrieves the named database access profile.
Definition: Database.cpp:325
bool addAccessProfile(const QString &profileFile)
Establishes an access profile for subsequent database connections.
void setAsDefault()
Sets this database connection/profile as the default.
Definition: Database.cpp:239
Access
Access status for database creation.
Definition: Database.h:87
QSqlDatabase init(const DbProfile &profile, Access dbConn=Connect)
Create and initialize a new database connection from a DbProfile.
Definition: Database.cpp:416
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
QStringList getViews() const
Returns a vector string containing all views within the database.
Definition: Database.cpp:537
bool isAvailable(const QString &dbname="") const
Check for availablity of a database connection resource.
QString _name
Needed due to peculiar issues with Database construction techniques.
Definition: Database.h:132
QStringList getSystemTables() const
Returns vector strings of all available system tables in the database.
Definition: Database.cpp:549
virtual ~Database()
Database destructor.
Definition: Database.cpp:173
QStringList getTables() const
Returns a vector string containing all the tables in the database.
Definition: Database.cpp:524
void add(const QSqlDatabase &db, const QString &name, bool setAsDefault=false)
Adds the database to the connection pool making it persistant.
Isis database class providing generalized access to a variety of databases.
Definition: Database.h:84
void remove(const QString &dbname)
Removes the database from the connection pool.
void configureAccess(QSqlDatabase &db, const DbProfile &profile)
Set access parameters from a database DbProfile access specification.
Definition: Database.cpp:468
void tossDbError(const QString &message, const char *f, int l) const
Generic exception tosser.
Definition: Database.cpp:563
void makePersistant()
Makes this instance persistant.
Definition: Database.cpp:204
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool isValid() const
Reports if this is a valid profile.
Definition: DbProfile.h:91
static void remove(const QString &name)
Removes the named database from pool.
Definition: Database.cpp:267
static bool addAccessConfig(const QString &confFile)
Adds a user specifed access configuration file to system.
Definition: Database.cpp:288
QString Name() const
Returns the name of this property.
Definition: DbProfile.h:118
Database()
Default database constructor.
Definition: Database.cpp:46
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.
QSqlDatabase create(const QString &driver, const QString &dbname)
Create a database using the named driver.