USGS

Isis 3.0 Object Programmers' Reference

Home

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 }