Isis 3 Programmer Reference
Database.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include <string>
10#include <vector>
11#include <iostream>
12#include "DbProfile.h"
13#include "Database.h"
14#include "DatabaseFactory.h"
15#include "IString.h"
16
17#include <QStringList>
18#include <QSqlError>
19
20using namespace std;
21
22namespace Isis {
23
24 QString Database::_actualConnectionName = "";
25
33 Database::Database() : QSqlDatabase(), _name("") { }
34
53 Database::Database(Database::Access dbConn) : QSqlDatabase(init()), _name("") {
54 _name = _actualConnectionName;
55 if((dbConn == Connect) && isValid()) {
56 if(!open()) {
57 QString mess = "Failed to open database default database [" + _name;
58 tossDbError(mess, _FILEINFO_);
59 }
60 }
61// Name cannot be set, so set to determined name
62 }
63
75 Database::Database(const QString &name, Database::Access dbConn) :
76 QSqlDatabase(init(name)), _name(name) {
77 _name = _actualConnectionName;
78 if((dbConn == Connect) && isValid()) {
79 if(!open()) {
80 QString mess = "Failed to open database specified as " + _name;
81 tossDbError(mess, _FILEINFO_);
82 }
83 }
84 }
85
104 Database::Database(const QString &connName, const QString &driverType) :
105 QSqlDatabase(init(connName, driverType)), _name(connName) {
106 _name = _actualConnectionName;
107 }
108
125 QSqlDatabase(init(profile, DoNotConnect)),
126 _name(profile.Name()) {
127 _name = _actualConnectionName;
128 if((dbConn == Connect) && isValid()) {
129 if(!open()) {
130 QString mess = "Failed to open database with profile " + _name;
131 tossDbError(mess, _FILEINFO_);
132 }
133 }
134 }
135
146 Database::Database(const QSqlDatabase &other, const QString &newName) :
147 QSqlDatabase(QSqlDatabase::cloneDatabase(other, newName)),
148 _name(newName) { }
149
150
162 if(!factory->isPersistant(_name)) {
163 if(isOpen()) {
164 close();
165 }
166 factory->remove(_name);
167 }
168 }
169
193 if(!factory->isPersistant(_name)) {
194 factory->add(*this, _name);
195 }
196 return;
197 }
198
209 return (factory->isPersistant(_name));
210 }
211
228 if(!factory->isPersistant(_name)) {
229 factory->add(*this, _name);
230 }
231 factory->setDefault(_name);
232 return;
233 }
234
254 void Database::remove(const QString &name) {
256 factory->destroy(name);
257 return;
258 }
259
275 bool Database::addAccessConfig(const QString &confFile) {
277 return (factory->addAccessProfile(confFile));
278 }
279
312 DbProfile Database::getProfile(const QString &name) {
314 return (factory->getProfile(name));
315 }
316
343 QSqlDatabase Database::init(const QString &connName,
344 const QString &driverType) {
345
346 _actualConnectionName = connName;
348
349 // First test for condition where both name and type are not provided.
350 // This tests for the default profile and returns it if it exists,
351 // otherwise it returns a default database.
352 if(connName.isEmpty() && driverType.isEmpty()) {
353 if(factory->isAvailable(factory->getDefault())) {
354 _actualConnectionName = factory->getDefault();
355 return (factory->create(_actualConnectionName));
356 }
357
358 // No default is established so retreive the default profile
359 DbProfile profile = factory->getProfile();
360 if(profile.isValid()) {
361 return (init(profile, DoNotConnect));
362 }
363 }
364
365 // If only the name and no driver is provided, get an existing connection
366 if((!connName.isEmpty()) && (driverType.isEmpty())) {
367 if(factory->isAvailable(connName)) {
368 _actualConnectionName = connName;
369 return (factory->create(connName));
370 }
371 else {
372 // See if the database exists by profile
373 DbProfile profile = factory->getProfile(connName);
374 return (init(profile, DoNotConnect));
375 }
376 }
377
378 // Finally, a driver and optional name is provided. This condition sets up
379 // a named database for subsequent definition later
380 return (factory->create(driverType, connName));
381 }
382
383
404 if(!profile.isValid()) {
405 ostringstream mess;
406 mess << "Database/profile [" << profile.Name() << "] is not valid!" << ends;
407 throw IException(IException::Programmer, mess.str(), _FILEINFO_);
408 }
409
410 _actualConnectionName = profile.Name();
412
413 // initialize the database
414 try {
415
416 // If we reach here, it is a valid profile. Create the database and
417 // return it as initialized from the profile contents
418 QSqlDatabase db = factory->create(profile("Type"), profile("Name"));
419 _actualConnectionName = profile("Name");
420 configureAccess(db, profile);
421
422 // Go ahead and connect if requested
423 if(dbConn == Connect) {
424 if(!db.open()) {
425 QString mess = "Failed to connect to database using profile " +
426 profile("Name");
427 tossDbError(mess, _FILEINFO_);
428 }
429 }
430 return (db);
431 }
432 catch(IException &ie) {
433 QString mess = "Unable to create database from " + profile.Name();
434 throw IException(ie, IException::User, mess, _FILEINFO_);
435 }
436 catch(...) {
437 QString mess = "Unknown exception while creating database from profile "
438 + profile.Name();
439 throw IException(IException::User, mess, _FILEINFO_);
440 }
441 }
442
456 if(profile.exists("Host")) {
457 db.setHostName(profile("Host"));
458 }
459
460 if(profile.exists("DbName")) {
461 db.setDatabaseName(profile("DbName"));
462 }
463
464 if(profile.exists("User")) {
465 db.setUserName(profile("User"));
466 }
467
468 if(profile.exists("Password")) {
469 db.setPassword(profile("Password"));
470 }
471
472 if(profile.exists("Port")) {
473 bool ok;
474 db.setPort(profile("Port").toInt(&ok));
475 if(!ok) {
476 ostringstream mess;
477 mess << "Invalid port number [" << profile("Port") << "] in profile "
478 << profile("Name") << ends;
479 throw IException(IException::User, mess.str().c_str(), _FILEINFO_);
480 }
481 }
482
483 if(profile.exists("Options")) {
484 db.setConnectOptions(profile("Options"));
485 }
486 return;
487 }
488
499 Database Database::clone(const QString &name) const {
500 return (Database(*this, name));
501 }
502
512 return (tables(QSql::Tables));
513 }
514
525 return (tables(QSql::Views));
526 }
527
537 return (tables(QSql::SystemTables));
538 }
539
550 void Database::tossDbError(const QString &message, const char *f, int l) const {
551 QString errmess = message + " - DatabaseError = " +
552 lastError().text();
553 throw IException(IException::Programmer, errmess, f, l);
554 }
555
556}
Create database interfaces using access profiles or generic drivers.
static DatabaseFactory * getInstance()
Returns and instance of this DatabaseFactory singleton.
Isis database class providing generalized access to a variety of databases.
Definition Database.h:70
Database clone(const QString &name) const
Clones this database into another giving it another name.
Definition Database.cpp:499
virtual ~Database()
Database destructor.
Definition Database.cpp:160
bool isPersistant() const
Checks persistancy state of a database instantiation.
Definition Database.cpp:207
static void remove(const QString &name)
Removes the named database from pool.
Definition Database.cpp:254
QStringList getSystemTables() const
Returns vector strings of all available system tables in the database.
Definition Database.cpp:536
Access
Access status for database creation.
Definition Database.h:73
@ Connect
Connect to database immediately.
Definition Database.h:74
@ DoNotConnect
Do not connect to database.
Definition Database.h:75
void tossDbError(const QString &message, const char *f, int l) const
Generic exception tosser.
Definition Database.cpp:550
QStringList getTables() const
Returns a vector string containing all the tables in the database.
Definition Database.cpp:511
static bool addAccessConfig(const QString &confFile)
Adds a user specifed access configuration file to system.
Definition Database.cpp:275
Database()
Default database constructor.
Definition Database.cpp:33
static DbProfile getProfile(const QString &name)
Retrieves the named database access profile.
Definition Database.cpp:312
void configureAccess(QSqlDatabase &db, const DbProfile &profile)
Set access parameters from a database DbProfile access specification.
Definition Database.cpp:455
QString _name
Needed due to peculiar issues with Database construction techniques.
Definition Database.h:118
void setAsDefault()
Sets this database connection/profile as the default.
Definition Database.cpp:226
QStringList getViews() const
Returns a vector string containing all views within the database.
Definition Database.cpp:524
QSqlDatabase init(const DbProfile &profile, Access dbConn=Connect)
Create and initialize a new database connection from a DbProfile.
Definition Database.cpp:403
void makePersistant()
Makes this instance persistant.
Definition Database.cpp:191
A DbProfile is a container for access parameters to a database.
Definition DbProfile.h:51
bool isValid() const
Reports if this is a valid profile.
Definition DbProfile.h:77
bool exists(const QString &key) const
Checks for the existance of a keyword.
Definition DbProfile.h:115
QString Name() const
Returns the name of this property.
Definition DbProfile.h:104
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition IString.cpp:93
Namespace for the standard library.