diff options
Diffstat (limited to 'src/sql/qsqldatabase.cpp')
-rw-r--r-- | src/sql/qsqldatabase.cpp | 1332 |
1 files changed, 1332 insertions, 0 deletions
diff --git a/src/sql/qsqldatabase.cpp b/src/sql/qsqldatabase.cpp new file mode 100644 index 000000000..e54fd124d --- /dev/null +++ b/src/sql/qsqldatabase.cpp @@ -0,0 +1,1332 @@ +/**************************************************************************** +** +** Implementation of TQSqlDatabase class +** +** Created : 2000-11-03 +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the sql module of the TQt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing retquirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qsqldatabase.h" + +#ifndef QT_NO_SQL + +#ifdef Q_OS_WIN32 +// Conflicting declarations of LPCBYTE in sqlfront.h and winscard.h +#define _WINSCARD_H_ +#endif + +#ifdef QT_SQL_POSTGRES +#include "drivers/psql/qsql_psql.h" +#endif +#ifdef QT_SQL_MYSQL +#include "drivers/mysql/qsql_mysql.h" +#endif +#ifdef QT_SQL_ODBC +#include "drivers/odbc/qsql_odbc.h" +#endif +#ifdef QT_SQL_OCI +#include "drivers/oci/qsql_oci.h" +#endif +#ifdef QT_SQL_TDS +#include "drivers/tds/qsql_tds.h" +#endif +#ifdef QT_SQL_DB2 +#include "drivers/db2/qsql_db2.h" +#endif +#ifdef QT_SQL_SQLITE +#include "drivers/sqlite/qsql_sqlite.h" +#endif +#ifdef QT_SQL_IBASE +#include "drivers/ibase/qsql_ibase.h" +#endif + +#include "qapplication.h" +#include "qsqlresult.h" +#include "qsqldriver.h" +#include "qsqldriverinterface_p.h" +#include <private/qpluginmanager_p.h> +#include <private/qsqlextension_p.h> +#include "qobject.h" +#include "qguardedptr.h" +#include "qcleanuphandler.h" +#include "qdict.h" +#include <stdlib.h> + +QT_STATIC_CONST_IMPL char * const TQSqlDatabase::defaultConnection = "qt_sql_default_connection"; + +TQPtrDict<TQSqlDriverExtension> *qt_driver_extension_dict = 0; +TQPtrDict<TQSqlOpenExtension> *qt_open_extension_dict = 0; + +static TQSingleCleanupHandler< TQPtrDict<TQSqlDriverExtension> > qt_driver_ext_cleanup; +static TQSingleCleanupHandler< TQPtrDict<TQSqlOpenExtension> > qt_open_ext_cleanup; + +Q_EXPORT TQPtrDict<TQSqlDriverExtension> *qSqlDriverExtDict() +{ + if ( !qt_driver_extension_dict ) { + qt_driver_extension_dict = new TQPtrDict<TQSqlDriverExtension>; + qt_driver_ext_cleanup.set( &qt_driver_extension_dict ); + } + return qt_driver_extension_dict; +} + +Q_EXPORT TQPtrDict<TQSqlOpenExtension> *qSqlOpenExtDict() +{ + if ( !qt_open_extension_dict ) { + qt_open_extension_dict = new TQPtrDict<TQSqlOpenExtension>; + qt_open_ext_cleanup.set( &qt_open_extension_dict ); + } + return qt_open_extension_dict; +} + +class TQNullResult : public TQSqlResult +{ +public: + TQNullResult(const TQSqlDriver* d): TQSqlResult(d){} + ~TQNullResult(){} +protected: + TQVariant data( int ) { return TQVariant(); } + bool reset ( const TQString& sqlquery ) { TQString s(sqlquery); return FALSE; } + bool fetch( int i ) { i = i; return FALSE; } + bool fetchFirst() { return FALSE; } + bool fetchLast() { return FALSE; } + bool isNull( int ) {return FALSE; } + TQSqlRecord record() {return TQSqlRecord();} + int size() {return 0;} + int numRowsAffected() {return 0;} +}; + +class TQNullDriver : public TQSqlDriver +{ +public: + TQNullDriver(): TQSqlDriver(){} + ~TQNullDriver(){} + bool hasFeature( DriverFeature /* f */ ) const { return FALSE; } ; + bool open( const TQString & , + const TQString & , + const TQString & , + const TQString &, + int ) { + return FALSE; + } + void close() {} + TQSqlQuery createQuery() const { return TQSqlQuery( new TQNullResult(this) ); } +}; + +typedef TQDict<TQSqlDriverCreatorBase> TQDriverDict; + +class TQSqlDatabaseManager : public TQObject +{ +public: + TQSqlDatabaseManager( TQObject * parent = 0, const char * name = 0 ); + ~TQSqlDatabaseManager(); + static TQSqlDatabase* database( const TQString& name, bool open ); + static TQSqlDatabase* addDatabase( TQSqlDatabase* db, const TQString & name ); + static void removeDatabase( const TQString& name ); + static void removeDatabase( TQSqlDatabase* db ); + static bool contains( const TQString& name ); + static TQDriverDict* driverDict(); + +protected: + static TQSqlDatabaseManager* instance(); + TQDict< TQSqlDatabase > dbDict; + TQDriverDict* drDict; +}; + +/*! + Constructs an SQL database manager. +*/ + +TQSqlDatabaseManager::TQSqlDatabaseManager( TQObject * parent, const char * name ) + : TQObject( parent, name ), dbDict( 1 ), drDict( 0 ) +{ +} + +/*! + Destroys the object and frees any allocated resources. All open + database connections are closed. All database connections are + deleted. +*/ + +TQSqlDatabaseManager::~TQSqlDatabaseManager() +{ + TQDictIterator< TQSqlDatabase > it( dbDict ); + while ( it.current() ) { + it.current()->close(); + delete it.current(); + ++it; + } + delete drDict; +} + +/*! + \internal +*/ +TQDriverDict* TQSqlDatabaseManager::driverDict() +{ + TQSqlDatabaseManager* sqlConnection = instance(); + if ( !sqlConnection->drDict ) { + sqlConnection->drDict = new TQDriverDict(); + sqlConnection->drDict->setAutoDelete( TRUE ); + } + return sqlConnection->drDict; +} + + +/*! + \internal +*/ +TQSqlDatabaseManager* TQSqlDatabaseManager::instance() +{ + static TQGuardedPtr<TQSqlDatabaseManager> sqlConnection = 0; + if ( !sqlConnection ) { + if( qApp == 0 ){ + qFatal( "TQSqlDatabaseManager: A TQApplication object has to be " + "instantiated in order to use the SQL module." ); + return 0; + } + sqlConnection = new TQSqlDatabaseManager( qApp, "database manager" ); + } + return (TQSqlDatabaseManager*)sqlConnection; +} + +/*! + Returns the database connection called \a name. If \a open is + TRUE, the database connection is opened. If \a name does not exist + in the list of managed databases, 0 is returned. +*/ + +TQSqlDatabase* TQSqlDatabaseManager::database( const TQString& name, bool open ) +{ + if ( !contains( name ) ) + return 0; + + TQSqlDatabaseManager* sqlConnection = instance(); + TQSqlDatabase* db = sqlConnection->dbDict.find( name ); + if ( db && !db->isOpen() && open ) { + db->open(); +#ifdef QT_CHECK_RANGE + if ( !db->isOpen() ) + qWarning("TQSqlDatabaseManager::database: unable to open database: %s: %s", + db->lastError().databaseText().latin1(), db->lastError().driverText().latin1() ); +#endif + } + return db; +} + +/*! + Returns TRUE if the list of database connections contains \a name; + otherwise returns FALSE. +*/ + +bool TQSqlDatabaseManager::contains( const TQString& name ) +{ + TQSqlDatabaseManager* sqlConnection = instance(); + TQSqlDatabase* db = sqlConnection->dbDict.find( name ); + if ( db ) + return TRUE; + return FALSE; +} + + +/*! + Adds a database to the SQL connection manager. The database + connection is referred to by \a name. The newly added database + connection is returned. This function will only return 0 if it is + called \e before a TQApplication object has been instantiated. Use + the output of drivers() to determine whether a particular driver + is available or not. + + The returned TQSqlDatabase object is owned by the framework and + must not be deleted. If you want to explicitly remove the connection, + use removeDatabase(). + + \sa TQSqlDatabase database() +*/ + +TQSqlDatabase* TQSqlDatabaseManager::addDatabase( TQSqlDatabase* db, const TQString & name ) +{ + TQSqlDatabaseManager* sqlConnection = instance(); + if( sqlConnection == 0 ) + return 0; + if ( contains( name ) ) + sqlConnection->removeDatabase( name ); + sqlConnection->dbDict.insert( name, db ); + return db; +} + +/*! + Removes the database connection \a name from the SQL connection + manager. + + \warning There should be no open queries on the database + connection when this function is called, otherwise a resource leak + will occur. +*/ + +void TQSqlDatabaseManager::removeDatabase( const TQString& name ) +{ + TQSqlDatabaseManager* sqlConnection = instance(); + sqlConnection->dbDict.setAutoDelete( TRUE ); + sqlConnection->dbDict.remove( name ); + sqlConnection->dbDict.setAutoDelete( FALSE ); +} + + +/*! + Removes the database connection \a db from the SQL connection + manager. The TQSqlDatabase object is destroyed when it is removed + from the manager. + + \warning The \a db pointer is not valid after this function has + been called. +*/ + +void TQSqlDatabaseManager::removeDatabase( TQSqlDatabase* db ) +{ + TQSqlDatabaseManager* sqlConnection = instance(); + if ( !sqlConnection ) + return; + TQDictIterator< TQSqlDatabase > it( sqlConnection->dbDict ); + while ( it.current() ) { + if ( it.current() == db ) { + sqlConnection->dbDict.remove( it.currentKey() ); + db->close(); + delete db; + break; + } + ++it; + } +} + +class TQSqlDatabasePrivate +{ +public: + TQSqlDatabasePrivate(): + driver(0), +#ifndef QT_NO_COMPONENT + plugIns(0), +#endif + port(-1) {} + ~TQSqlDatabasePrivate() + { + } + TQSqlDriver* driver; +#ifndef QT_NO_COMPONENT + TQPluginManager<TQSqlDriverFactoryInterface> *plugIns; +#endif + TQString dbname; + TQString uname; + TQString pword; + TQString hname; + TQString drvName; + int port; + TQString connOptions; +}; + +/*! + \class TQSqlDatabase qsqldatabase.h + \brief The TQSqlDatabase class is used to create SQL database + connections and to provide transaction handling. + + \ingroup database + \mainclass + \module sql + + Note that transaction handling is not supported by every SQL + database. You can find out whether transactions are supported + using TQSqlDriver::hasFeature(). + + The TQSqlDatabase class provides an abstract interface for + accessing many types of database backends. Database-specific + drivers are used internally to actually access and manipulate + data, (see TQSqlDriver). Result set objects provide the interface + for executing and manipulating SQL queries (see TQSqlQuery). +*/ + +/*! + Adds a database to the list of database connections using the + driver \a type and the connection name \a connectionName. + + The database connection is referred to by \a connectionName. The + newly added database connection is returned. This pointer is owned + by TQSqlDatabase and will be deleted on program exit or when + removeDatabase() is called. + + If \a connectionName is not specified, the newly added database + connection becomes the default database connection for the + application, and subsequent calls to database() (without a + database name parameter) will return a pointer to it. If \a + connectionName is given, use \link TQSqlDatabase::database() + database(connectionName)\endlink to retrieve a pointer to the + database connection. + + \warning If you add a database with the same name as an + existing database, the new database will replace the old one. + This will happen automatically if you call this function more + than once without specifying \a connectionName. + + \sa database() removeDatabase() +*/ +TQSqlDatabase* TQSqlDatabase::addDatabase( const TQString& type, const TQString& connectionName ) +{ + return TQSqlDatabaseManager::addDatabase( new TQSqlDatabase( type, connectionName ), connectionName ); +} + +/*! + Returns the database connection called \a connectionName. The + database connection must have been previously added with + addDatabase(). If \a open is TRUE (the default) and the database + connection is not already open it is opened now. If no \a + connectionName is specified the default connection is used. If \a + connectionName does not exist in the list of databases, 0 is + returned. The pointer returned is owned by TQSqlDatabase and should + \e not be deleted. + + \warning There are restrictions on the use of database connections + in threaded applications. Please see the \link threads.html#threads-sql + Thread Support in TQt\endlink document for more information about + threading and SQL databases. +*/ + +TQSqlDatabase* TQSqlDatabase::database( const TQString& connectionName, bool open ) +{ + return TQSqlDatabaseManager::database( connectionName, open ); +} + +/*! + Removes the database connection \a connectionName from the list of + database connections. + + \warning There should be no open queries on the database + connection when this function is called, otherwise a resource leak + will occur. +*/ + +void TQSqlDatabase::removeDatabase( const TQString& connectionName ) +{ + TQSqlDatabaseManager::removeDatabase( connectionName ); +} + +/*! + \overload + + Removes the database connection \a db from the list of database + connections. The TQSqlDatabase object is destroyed when it is removed + from the list. + + \warning The \a db pointer is not valid after this function has + been called. There should be no open queries on the database + connection when this function is called, otherwise a resource leak + will occur. +*/ + +void TQSqlDatabase::removeDatabase( TQSqlDatabase* db ) +{ + TQSqlDatabaseManager::removeDatabase( db ); +} + +/*! + Returns a list of all the available database drivers. + + Note that if you want to iterate over the list, you should iterate + over a copy, e.g. + \code + TQStringList list = TQSqlDatabase::drivers(); + TQStringList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode +*/ + +TQStringList TQSqlDatabase::drivers() +{ + TQStringList l; + +#ifndef QT_NO_COMPONENT + TQPluginManager<TQSqlDriverFactoryInterface> *plugIns; + plugIns = new TQPluginManager<TQSqlDriverFactoryInterface>( IID_QSqlDriverFactory, TQApplication::libraryPaths(), "/sqldrivers" ); + + l = plugIns->featureList(); + delete plugIns; +#endif + + TQDictIterator<TQSqlDriverCreatorBase> itd( *TQSqlDatabaseManager::driverDict() ); + while ( itd.current() ) { + if ( !l.contains( itd.currentKey() ) ) + l << itd.currentKey(); + ++itd; + } + +#ifdef QT_SQL_POSTGRES + if ( !l.contains( "TQPSQL7" ) ) + l << "TQPSQL7"; +#endif +#ifdef QT_SQL_MYSQL + if ( !l.contains( "TQMYSQL3" ) ) + l << "TQMYSQL3"; +#endif +#ifdef QT_SQL_ODBC + if ( !l.contains( "TQODBC3" ) ) + l << "TQODBC3"; +#endif +#ifdef QT_SQL_OCI + if ( !l.contains( "TQOCI8" ) ) + l << "TQOCI8"; +#endif +#ifdef QT_SQL_TDS + if ( !l.contains( "TQTDS7" ) ) + l << "TQTDS7"; +#endif +#ifdef QT_SQL_DB2 + if ( !l.contains( "TQDB2" ) ) + l << "TQDB2"; +#endif +#ifdef QT_SQL_SQLITE + if ( !l.contains( "TQSQLITE" ) ) + l << "TQSQLITE"; +#endif +#ifdef QT_SQL_IBASE + if ( !l.contains( "TQIBASE" ) ) + l << "TQIBASE"; +#endif + + return l; +} + +/*! + This function registers a new SQL driver called \a name, within + the SQL framework. This is useful if you have a custom SQL driver + and don't want to compile it as a plugin. + + Example usage: + + \code + TQSqlDatabase::registerSqlDriver( "MYDRIVER", new TQSqlDriverCreator<MyDatabaseDriver> ); + TQSqlDatabase* db = TQSqlDatabase::addDatabase( "MYDRIVER" ); + ... + \endcode + + \warning The framework takes ownership of the \a creator pointer, + so it should not be deleted. +*/ +void TQSqlDatabase::registerSqlDriver( const TQString& name, const TQSqlDriverCreatorBase* creator ) +{ + TQSqlDatabaseManager::driverDict()->remove( name ); + if ( creator ) + TQSqlDatabaseManager::driverDict()->insert( name, creator ); +} + +/*! + Returns TRUE if the list of database connections contains \a + connectionName; otherwise returns FALSE. +*/ + +bool TQSqlDatabase::contains( const TQString& connectionName ) +{ + return TQSqlDatabaseManager::contains( connectionName ); +} + + +/*! + Creates a TQSqlDatabase connection called \a name that uses the + driver referred to by \a type, with the parent \a parent and the + object name \a objname. If the \a type is not recognized, the + database connection will have no functionality. + + The currently available drivers are: + + \table + \header \i Driver Type \i Description + \row \i TQODBC3 \i ODBC Driver (includes Microsoft SQL Server) + \row \i TQOCI8 \i Oracle Call Interface Driver + \row \i TQPSQL7 \i PostgreSQL v6.x and v7.x Driver + \row \i TQTDS7 \i Sybase Adaptive Server + \row \i TQMYSQL3 \i MySQL Driver + \row \i TQDB2 \i IBM DB2, v7.1 and higher + \row \i TQSQLITE \i SQLite Driver + \row \i TQIBASE \i Borland Interbase Driver + \endtable + + Additional third party drivers, including your own custom drivers, + can be loaded dynamically. + + \sa registerSqlDriver() +*/ + +TQSqlDatabase::TQSqlDatabase( const TQString& type, const TQString& name, TQObject * parent, const char * objname ) + : TQObject( parent, objname ) +{ + init( type, name ); +} + + +/*! + \overload + + Creates a database connection using the driver \a driver, with + the parent \a parent and the object name \a objname. + + \warning The framework takes ownership of the \a driver pointer, + so it should not be deleted. +*/ + +TQSqlDatabase::TQSqlDatabase( TQSqlDriver* driver, TQObject * parent, const char * objname ) + : TQObject( parent, objname ) +{ + d = new TQSqlDatabasePrivate(); + d->driver = driver; +} + +/*! + \internal + + Create the actual driver instance \a type. +*/ + +void TQSqlDatabase::init( const TQString& type, const TQString& ) +{ + d = new TQSqlDatabasePrivate(); + d->drvName = type; + + if ( !d->driver ) { + +#ifdef QT_SQL_POSTGRES + if ( type == "TQPSQL7" ) + d->driver = new TQPSQLDriver(); +#endif + +#ifdef QT_SQL_MYSQL + if ( type == "TQMYSQL3" ) + d->driver = new TQMYSQLDriver(); +#endif + +#ifdef QT_SQL_ODBC + if ( type == "TQODBC3" ) + d->driver = new TQODBCDriver(); +#endif + +#ifdef QT_SQL_OCI + if ( type == "TQOCI8" ) + d->driver = new TQOCIDriver(); +#endif + +#ifdef QT_SQL_TDS + if ( type == "TQTDS7" ) + d->driver = new TQTDSDriver(); +#endif + +#ifdef QT_SQL_DB2 + if ( type == "TQDB2" ) + d->driver = new TQDB2Driver(); +#endif + +#ifdef QT_SQL_SQLITE + if ( type == "TQSQLITE" ) + d->driver = new TQSQLiteDriver(); +#endif + +#ifdef QT_SQL_IBASE + if ( type == "TQIBASE" ) + d->driver = new TQIBaseDriver(); +#endif + + } + + if ( !d->driver ) { + TQDictIterator<TQSqlDriverCreatorBase> it( *TQSqlDatabaseManager::driverDict() ); + while ( it.current() && !d->driver ) { + if ( type == it.currentKey() ) { + d->driver = it.current()->createObject(); + } + ++it; + } + } + +#ifndef QT_NO_COMPONENT + if ( !d->driver ) { + d->plugIns = + new TQPluginManager<TQSqlDriverFactoryInterface>( IID_QSqlDriverFactory, TQApplication::libraryPaths(), "/sqldrivers" ); + + TQInterfacePtr<TQSqlDriverFactoryInterface> iface = 0; + d->plugIns->queryInterface( type, &iface ); + if( iface ) + d->driver = iface->create( type ); + } +#endif + + if ( !d->driver ) { +#ifdef QT_CHECK_RANGE + qWarning( "TQSqlDatabase: %s driver not loaded", type.latin1() ); + qWarning( "TQSqlDatabase: available drivers: %s", drivers().join(" ").latin1() ); +#endif + d->driver = new TQNullDriver(); + d->driver->setLastError( TQSqlError( "Driver not loaded", "Driver not loaded" ) ); + } +} + +/*! + Destroys the object and frees any allocated resources. +*/ + +TQSqlDatabase::~TQSqlDatabase() +{ + delete d->driver; +#ifndef QT_NO_COMPONENT + delete d->plugIns; +#endif + delete d; +} + +/*! + Executes a SQL statement (e.g. an \c INSERT, \c UPDATE or \c + DELETE statement) on the database, and returns a TQSqlQuery object. + Use lastError() to retrieve error information. If \a query is + TQString::null, an empty, invalid query is returned and lastError() + is not affected. + + \sa TQSqlQuery lastError() +*/ + +TQSqlQuery TQSqlDatabase::exec( const TQString & query ) const +{ + TQSqlQuery r = d->driver->createQuery(); + if ( !query.isNull() ) { + r.exec( query ); + d->driver->setLastError( r.lastError() ); + } + return r; +} + +/*! + Opens the database connection using the current connection values. + Returns TRUE on success; otherwise returns FALSE. Error + information can be retrieved using the lastError() function. + + \sa lastError() +*/ + +bool TQSqlDatabase::open() +{ + return d->driver->open( d->dbname, d->uname, d->pword, d->hname, + d->port, d->connOptions ); +} + +/*! + \overload + + Opens the database connection using the given \a user name and \a + password. Returns TRUE on success; otherwise returns FALSE. Error + information can be retrieved using the lastError() function. + + This function does not store the password it is given. Instead, + the password is passed directly to the driver for opening a + connection and is then discarded. + + \sa lastError() +*/ + +bool TQSqlDatabase::open( const TQString& user, const TQString& password ) +{ + setUserName( user ); + return d->driver->open( d->dbname, user, password, d->hname, + d->port, d->connOptions ); +} + +/*! + Closes the database connection, freeing any resources actquired. + + \sa removeDatabase() +*/ + +void TQSqlDatabase::close() +{ + d->driver->close(); +} + +/*! + Returns TRUE if the database connection is currently open; + otherwise returns FALSE. +*/ + +bool TQSqlDatabase::isOpen() const +{ + return d->driver->isOpen(); +} + +/*! + Returns TRUE if there was an error opening the database + connection; otherwise returns FALSE. Error information can be + retrieved using the lastError() function. +*/ + +bool TQSqlDatabase::isOpenError() const +{ + return d->driver->isOpenError(); +} + +/*! + Begins a transaction on the database if the driver supports + transactions. Returns TRUE if the operation succeeded; otherwise + returns FALSE. + + \sa TQSqlDriver::hasFeature() commit() rollback() +*/ + +bool TQSqlDatabase::transaction() +{ + if ( !d->driver->hasFeature( TQSqlDriver::Transactions ) ) + return FALSE; + return d->driver->beginTransaction(); +} + +/*! + Commits a transaction to the database if the driver supports + transactions. Returns TRUE if the operation succeeded; otherwise + returns FALSE. + + \sa TQSqlDriver::hasFeature() rollback() +*/ + +bool TQSqlDatabase::commit() +{ + if ( !d->driver->hasFeature( TQSqlDriver::Transactions ) ) + return FALSE; + return d->driver->commitTransaction(); +} + +/*! + Rolls a transaction back on the database if the driver supports + transactions. Returns TRUE if the operation succeeded; otherwise + returns FALSE. + + \sa TQSqlDriver::hasFeature() commit() transaction() +*/ + +bool TQSqlDatabase::rollback() +{ + if ( !d->driver->hasFeature( TQSqlDriver::Transactions ) ) + return FALSE; + return d->driver->rollbackTransaction(); +} + +/*! + \property TQSqlDatabase::databaseName + \brief the name of the database + + Note that the database name is the TNS Service Name for the TQOCI8 + (Oracle) driver. + + For the TQODBC3 driver it can either be a DSN, a DSN filename (the + file must have a \c .dsn extension), or a connection string. MS + Access users can for example use the following connection string + to open a \c .mdb file directly, instead of having to create a DSN + entry in the ODBC manager: + + \code + ... + db = TQSqlDatabase::addDatabase( "TQODBC3" ); + db->setDatabaseName( "DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=myaccessfile.mdb" ); + if ( db->open() ) { + // success! + } + ... + \endcode + ("FIL" is the retquired spelling in Microsoft's API.) + + There is no default value. +*/ + +void TQSqlDatabase::setDatabaseName( const TQString& name ) +{ + d->dbname = name; +} + +/*! + \property TQSqlDatabase::userName + \brief the user name connected to the database + + There is no default value. +*/ + +void TQSqlDatabase::setUserName( const TQString& name ) +{ + d->uname = name; +} + +/*! + \property TQSqlDatabase::password + \brief the password used to connect to the database + + There is no default value. + + \warning This function stores the password in plain text within + TQt. Use the open() call that takes a password as parameter to + avoid this behaviour. + + \sa open() +*/ + +void TQSqlDatabase::setPassword( const TQString& password ) +{ + d->pword = password; +} + +/*! + \property TQSqlDatabase::hostName + \brief the host name where the database resides + + There is no default value. +*/ + +void TQSqlDatabase::setHostName( const TQString& host ) +{ + d->hname = host; +} + +/*! + \property TQSqlDatabase::port + \brief the port used to connect to the database + + There is no default value. +*/ + +void TQSqlDatabase::setPort( int p ) +{ + d->port = p; +} + +TQString TQSqlDatabase::databaseName() const +{ + return d->dbname; +} + +TQString TQSqlDatabase::userName() const +{ + return d->uname; +} + +TQString TQSqlDatabase::password() const +{ + return d->pword; +} + +TQString TQSqlDatabase::hostName() const +{ + return d->hname; +} + +/*! + Returns the name of the driver used by the database connection. +*/ +TQString TQSqlDatabase::driverName() const +{ + return d->drvName; +} + +int TQSqlDatabase::port() const +{ + return d->port; +} + +/*! + Returns the database driver used to access the database + connection. +*/ + +TQSqlDriver* TQSqlDatabase::driver() const +{ + return d->driver; +} + +/*! + Returns information about the last error that occurred on the + database. See TQSqlError for more information. +*/ + +TQSqlError TQSqlDatabase::lastError() const +{ + return d->driver->lastError(); +} + + +/*! + \overload + + Returns a list of the database's tables that are visible to the + user. To include views or system tables, use the version of this + function that takes a table \c type parameter. + + Note that if you want to iterate over the list, you should iterate + over a copy, e.g. + \code + TQStringList list = myDatabase.tables(); + TQStringList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode +*/ + +TQStringList TQSqlDatabase::tables() const +{ + return tables( TQSql::Tables ); +} + +/*! + Returns a list of the database's tables, system tables and views, + as specified by the parameter \a type. + + Note that if you want to iterate over the list, you should iterate + over a copy, e.g. + \code + TQStringList list = myDatabase.tables( TQSql::Tables | TQSql::Views ); + TQStringList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode +*/ + +TQStringList TQSqlDatabase::tables( TQSql::TableType type ) const +{ + return d->driver->tables( TQString::number( (int)type ) ); +} + +/*! + Returns the primary index for table \a tablename. If no primary + index exists an empty TQSqlIndex will be returned. +*/ + +TQSqlIndex TQSqlDatabase::primaryIndex( const TQString& tablename ) const +{ + return d->driver->primaryIndex( tablename ); +} + + +/*! + Returns a TQSqlRecord populated with the names of all the fields in + the table (or view) called \a tablename. The order in which the + fields appear in the record is undefined. If no such table (or + view) exists, an empty record is returned. + + \sa recordInfo() +*/ + +TQSqlRecord TQSqlDatabase::record( const TQString& tablename ) const +{ + return d->driver->record( tablename ); +} + + +/*! + \overload + + Returns a TQSqlRecord populated with the names of all the fields + used in the SQL \a query. If the query is a "SELECT *" the order + in which fields appear in the record is undefined. + + \sa recordInfo() +*/ + +TQSqlRecord TQSqlDatabase::record( const TQSqlQuery& query ) const +{ + return d->driver->record( query ); +} + +/*! + Returns a TQSqlRecordInfo populated with meta data about the table + or view \a tablename. If no such table (or view) exists, an empty + record is returned. + + \sa TQSqlRecordInfo, TQSqlFieldInfo, record() +*/ +TQSqlRecordInfo TQSqlDatabase::recordInfo( const TQString& tablename ) const +{ + return d->driver->recordInfo( tablename ); +} + +/*! + \overload + + Returns a TQSqlRecordInfo object with meta data for the TQSqlQuery + \a query. Note that this overloaded function may return less + information than the recordInfo() function which takes the name of + a table as parameter. + + \sa TQSqlRecordInfo, TQSqlFieldInfo, record() +*/ +TQSqlRecordInfo TQSqlDatabase::recordInfo( const TQSqlQuery& query ) const +{ + return d->driver->recordInfo( query ); +} + +/*! + \property TQSqlDatabase::connectOptions + \brief the database connect options + + The format of the options string is a semi-colon separated list of + option names or option = value pairs. The options depend on the + database client used: + + \table + \header \i ODBC \i MySQL \i PostgreSQL + \row + + \i + \list + \i SQL_ATTR_ACCESS_MODE + \i SQL_ATTR_LOGIN_TIMEOUT + \i SQL_ATTR_CONNECTION_TIMEOUT + \i SQL_ATTR_CURRENT_CATALOG + \i SQL_ATTR_METADATA_ID + \i SQL_ATTR_PACKET_SIZE + \i SQL_ATTR_TRACEFILE + \i SQL_ATTR_TRACE + \endlist + + \i + \list + \i CLIENT_COMPRESS + \i CLIENT_FOUND_ROWS + \i CLIENT_IGNORE_SPACE + \i CLIENT_SSL + \i CLIENT_ODBC + \i CLIENT_NO_SCHEMA + \i CLIENT_INTERACTIVE + \endlist + + \i + \list + \i connect_timeout + \i options + \i tty + \i retquiressl + \i service + \endlist + + \header \i DB2 \i OCI \i TDS + \row + + \i + \list + \i SQL_ATTR_ACCESS_MODE + \i SQL_ATTR_LOGIN_TIMEOUT + \endlist + + \i + \e none + + \i + \e none + + \endtable + + Example of usage: + \code + ... + // MySQL connection + db->setConnectOptions( "CLIENT_SSL;CLIENT_IGNORE_SPACE" ); // use an SSL connection to the server + if ( !db->open() ) { + db->setConnectOptions(); // clears the connect option string + ... + } + ... + // PostgreSQL connection + db->setConnectOptions( "retquiressl=1" ); // enable PostgreSQL SSL connections + if ( !db->open() ) { + db->setConnectOptions(); // clear options + ... + } + ... + // ODBC connection + db->setConnectOptions( "SQL_ATTR_ACCESS_MODE=SQL_MODE_READ_ONLY;SQL_ATTR_TRACE=SQL_OPT_TRACE_ON" ); // set ODBC options + if ( !db->open() ) { + db->setConnectOptions(); // don't try to set this option + ... + } + \endcode + + Please refer to the client library documentation for more + information about the different options. The options will be set + prior to opening the database connection. Setting new options + without re-opening the connection does nothing. + + \sa connectOptions() +*/ + +void TQSqlDatabase::setConnectOptions( const TQString& options ) +{ + d->connOptions = options; +} + +TQString TQSqlDatabase::connectOptions() const +{ + return d->connOptions; +} + +/*! + Returns TRUE if a driver called \a name is available; otherwise + returns FALSE. + + \sa drivers() +*/ + +bool TQSqlDatabase::isDriverAvailable( const TQString& name ) +{ + TQStringList l = drivers(); + TQStringList::ConstIterator it = l.begin(); + for ( ;it != l.end(); ++it ) { + if ( *it == name ) + return TRUE; + } + return FALSE; +} + +/*! \overload + + This function is useful if you need to set up the database + connection and instantiate the driver yourself. If you do this, it + is recommended that you include the driver code in your own + application. For example, setting up a custom PostgreSQL + connection and instantiating the TQPSQL7 driver can be done the + following way: + + \code + #include "qtdir/src/sql/drivers/psql/qsql_psql.cpp" + \endcode + (We assume that \c qtdir is the directory where TQt is installed.) + This will pull in the code that is needed to use the PostgreSQL + client library and to instantiate a TQPSQLDriver object, assuming + that you have the PostgreSQL headers somewhere in your include + search path. + + \code + PGconn* con = PQconnectdb( "host=server user=bart password=simpson dbname=springfield" ); + TQPSQLDriver* drv = new TQPSQLDriver( con ); + TQSqlDatabase* db = TQSqlDatabase::addDatabase( drv ); // becomes the new default connection + TQSqlQuery q; + q.exec( "SELECT * FROM people" ); + ... + \endcode + + The above code sets up a PostgreSQL connection and instantiates a + TQPSQLDriver object. Next, addDatabase() is called to add the + connection to the known connections so that it can be used by the + TQt SQL classes. When a driver is instantiated with a connection + handle (or set of handles), TQt assumes that you have already + opened the database connection. + + Remember that you must link your application against the database + client library as well. The simplest way to do this is to add + lines like those below to your \c .pro file: + + \code + unix:LIBS += -lpq + win32:LIBS += libpqdll.lib + \endcode + + You will need to have the client library in your linker's search + path. + + The method described above will work for all the drivers, the only + difference is the arguments the driver constructors take. Below is + an overview of the drivers and their constructor arguments. + + \table + \header \i Driver \i Class name \i Constructor arguments \i File to include + \row + \i TQPSQL7 + \i TQPSQLDriver + \i PGconn* connection + \i \c qsql_psql.cpp + \row + \i TQMYSQL3 + \i TQMYSQLDriver + \i MYSQL* connection + \i \c qsql_mysql.cpp + \row + \i TQOCI8 + \i TQOCIDriver + \i OCIEnv* environment, OCIError* error, OCISvcCtx* serviceContext + \i \c qsql_oci.cpp + \row + \i TQODBC3 + \i TQODBCDriver + \i SQLHANDLE environment, SQLHANDLE connection + \i \c qsql_odbc.cpp + \row + \i TQDB2 + \i TQDB2 + \i SQLHANDLE environment, SQLHANDLE connection + \i \c qsql_db2.cpp + \row + \i TQTDS7 + \i TQTDSDriver + \i LOGINREC* loginRecord, DBPROCESS* dbProcess, const TQString& hostName + \i \c qsql_tds.cpp + \row + \i TQSQLITE + \i TQSQLiteDriver + \i sqlite* connection + \i \c qsql_sqlite.cpp + \row + \i TQIBASE + \i TQIBaseDriver + \i isc_db_handle connection + \i \c qsql_ibase.cpp + \endtable + + Note: The host name (or service name) is needed when constructing + the TQTDSDriver for creating new connections for internal + queries. This is to prevent the simultaneous usage of several + TQSqlQuery/\l{TQSqlCursor} objects from blocking each other. + + \warning The SQL framework takes ownership of the \a driver pointer, + and it should not be deleted. The returned TQSqlDatabase object is + owned by the framework and must not be deleted. If you want to + explicitly remove the connection, use removeDatabase() + + \sa drivers() +*/ + +TQSqlDatabase* TQSqlDatabase::addDatabase( TQSqlDriver* driver, const TQString& connectionName ) +{ + return TQSqlDatabaseManager::addDatabase( new TQSqlDatabase( driver ), connectionName ); +} +#endif // QT_NO_SQL |