summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/sql/tqsqlquery.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/sql/tqsqlquery.cpp')
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlquery.cpp1215
1 files changed, 0 insertions, 1215 deletions
diff --git a/tqtinterface/qt4/src/sql/tqsqlquery.cpp b/tqtinterface/qt4/src/sql/tqsqlquery.cpp
deleted file mode 100644
index a1a7632..0000000
--- a/tqtinterface/qt4/src/sql/tqsqlquery.cpp
+++ /dev/null
@@ -1,1215 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQSqlQuery 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 requirements 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 "tqsqlquery.h"
-
-#ifndef TQT_NO_SQL
-
-//#define TQT_DEBUG_SQL
-
-#include "tqsqlresult.h"
-#include "tqsqldriver.h"
-#include "tqsqldatabase.h"
-#include "tqsql.h"
-#include "tqregexp.h"
-#include "private/tqsqlextension_p.h"
-
-
-/*!
-\internal
-*/
-TQSqlResultShared::TQSqlResultShared( TQSqlResult* result ): sqlResult(result)
-{
- if ( result )
- connect( result->driver(), TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotResultDestroyed()) );
-}
-
-/*!
-\internal
-*/
-TQSqlResultShared::~TQSqlResultShared()
-{
- delete sqlResult;
-}
-
-/*!
-\internal
-
-In case a plugin gets unloaded the pointer to the sqlResult gets invalid
-*/
-void TQSqlResultShared::slotResultDestroyed()
-{
- delete sqlResult;
- sqlResult = 0;
-}
-
-/*!
- \class TQSqlQuery tqsqlquery.h
- \brief The TQSqlQuery class provides a means of executing and
- manipulating SQL statements.
-
- \ingroup database
- \mainclass
- \module sql
-
- TQSqlQuery encapsulates the functionality involved in creating,
- navigating and retrieving data from SQL queries which are executed
- on a \l TQSqlDatabase. It can be used to execute DML (data
- manipulation language) statements, e.g. \c SELECT, \c INSERT, \c
- UPDATE and \c DELETE, and also DDL (data definition language)
- statements, e.g. \c{CREATE TABLE}. It can also be used to
- execute database-specific commands which are not standard SQL
- (e.g. \c{SET DATESTYLE=ISO} for PostgreSQL).
-
- Successfully executed SQL statements set the query's state to
- active (isActive() returns TRUE); otherwise the query's state is
- set to inactive. In either case, when executing a new SQL
- statement, the query is positioned on an invalid record; an active
- query must be navigated to a valid record (so that isValid()
- returns TRUE) before values can be retrieved.
-
- Navigating records is performed with the following functions:
-
- \list
- \i \c next()
- \i \c prev()
- \i \c first()
- \i \c last()
- \i \c \link TQSqlQuery::seek() seek\endlink(int)
- \endlist
-
- These functions allow the programmer to move forward, backward or
- arbitrarily through the records returned by the query. If you only
- need to move forward through the results, e.g. using next() or
- using seek() with a positive offset, you can use setForwardOnly()
- and save a significant amount of memory overhead. Once an active
- query is positioned on a valid record, data can be retrieved using
- value(). All data is transferred from the SQL backend using
- TQVariants.
-
- For example:
-
- \code
- TQSqlQuery query( "SELECT name FROM customer" );
- while ( query.next() ) {
- TQString name = query.value(0).toString();
- doSomething( name );
- }
- \endcode
-
- To access the data returned by a query, use the value() method.
- Each field in the data returned by a SELECT statement is accessed
- by passing the field's position in the statement, starting from 0.
- Information about the fields can be obtained via TQSqlDatabase::record().
- For the sake of efficiency there are no functions to access a field
- by name. (The \l TQSqlCursor class provides a higher-level interface
- with field access by name and automatic SQL generation.)
-
- TQSqlQuery supports prepared query execution and the binding of
- parameter values to placeholders. Some databases don't support
- these features, so for them TQt emulates the required
- functionality. For example, the Oracle and ODBC drivers have
- proper prepared query support, and TQt makes use of it; but for
- databases that don't have this support, TQt implements the feature
- itself, e.g. by replacing placeholders with actual values when a
- query is executed. The exception is positional binding using named
- placeholders, which requires that the database supports prepared
- queries.
-
- Oracle databases identify placeholders by using a colon-name
- syntax, e.g \c{:name}. ODBC simply uses \c ? characters. TQt
- supports both syntaxes (although you can't mix them in the same
- query).
-
- Below we present the same example using each of the four different
- binding approaches.
-
- <b>Named binding using named placeholders</b>
- \code
- TQSqlQuery query;
- query.prepare( "INSERT INTO atable (id, forename, surname) "
- "VALUES (:id, :forename, :surname)" );
- query.bindValue( ":id", 1001 );
- query.bindValue( ":forename", "Bart" );
- query.bindValue( ":surname", "Simpson" );
- query.exec();
- \endcode
-
- <b>Positional binding using named placeholders</b>
- \code
- TQSqlQuery query;
- query.prepare( "INSERT INTO atable (id, forename, surname) "
- "VALUES (:id, :forename, :surname)" );
- query.bindValue( 0, 1001 );
- query.bindValue( 1, "Bart" );
- query.bindValue( 2, "Simpson" );
- query.exec();
- \endcode
- <b>Note:</b> Using positional binding with named placeholders will
- only work if the database supports prepared queries. This can be
- checked with TQSqlDriver::hasFeature() using TQSqlDriver::PreparedQueries
- as argument for driver feature.
-
- <b>Binding values using positional placeholders #1</b>
- \code
- TQSqlQuery query;
- query.prepare( "INSERT INTO atable (id, forename, surname) "
- "VALUES (?, ?, ?)" );
- query.bindValue( 0, 1001 );
- query.bindValue( 1, "Bart" );
- query.bindValue( 2, "Simpson" );
- query.exec();
- \endcode
-
- <b>Binding values using positional placeholders #2</b>
- \code
- query.prepare( "INSERT INTO atable (id, forename, surname) "
- "VALUES (?, ?, ?)" );
- query.addBindValue( 1001 );
- query.addBindValue( "Bart" );
- query.addBindValue( "Simpson" );
- query.exec();
- \endcode
-
- <b>Binding values to a stored procedure</b>
- This code calls a stored procedure called \c AsciiToInt(), passing
- it a character through its in parameter, and taking its result in
- the out parameter.
- \code
- TQSqlQuery query;
- query.prepare( "call AsciiToInt(?, ?)" );
- query.bindValue( 0, "A" );
- query.bindValue( 1, 0, TQSql::Out );
- query.exec();
- int i = query.boundValue( 1 ).toInt(); // i is 65.
- \endcode
-
- \sa TQSqlDatabase TQSqlCursor TQVariant
-*/
-
-/*!
- Creates a TQSqlQuery object which uses the TQSqlResult \a r to
- communicate with a database.
-*/
-
-TQSqlQuery::TQSqlQuery( TQSqlResult * r )
-{
- d = new TQSqlResultShared( r );
-}
-
-/*!
- Destroys the object and frees any allocated resources.
-*/
-
-TQSqlQuery::~TQSqlQuery()
-{
- if (d->deref()) {
- delete d;
- }
-}
-
-/*!
- Constructs a copy of \a other.
-*/
-
-TQSqlQuery::TQSqlQuery( const TQSqlQuery& other )
- : d(other.d)
-{
- d->ref();
-}
-
-/*!
- Creates a TQSqlQuery object using the SQL \a query and the database
- \a db. If \a db is 0, (the default), the application's default
- database is used. If \a query is not a null string, it will be
- executed.
-
- \sa TQSqlDatabase
-*/
-TQSqlQuery::TQSqlQuery( const TQString& query, TQSqlDatabase* db )
-{
- init( query, db );
-}
-
-/*!
- Creates a TQSqlQuery object using the database \a db. If \a db is
- 0, the application's default database is used.
-
- \sa TQSqlDatabase
-*/
-
-TQSqlQuery::TQSqlQuery( TQSqlDatabase* db )
-{
- init( TQString::null, db );
-}
-
-/*! \internal
-*/
-
-void TQSqlQuery::init( const TQString& query, TQSqlDatabase* db )
-{
- d = new TQSqlResultShared( 0 );
- TQSqlDatabase* database = db;
- if ( !database )
- database = TQSqlDatabase::database( TQSqlDatabase::defaultConnection, FALSE );
- if ( database )
- *this = database->driver()->createQuery();
- if ( !query.isNull() )
- exec( query );
-}
-
-/*!
- Assigns \a other to the query.
-*/
-
-TQSqlQuery& TQSqlQuery::operator=( const TQSqlQuery& other )
-{
- other.d->ref();
- deref();
- d = other.d;
- return *this;
-}
-
-/*!
- Returns TRUE if the query is active and positioned on a valid
- record and the \a field is NULL; otherwise returns FALSE. Note
- that for some drivers isNull() will not return accurate
- information until after an attempt is made to retrieve data.
-
- \sa isActive() isValid() value()
-*/
-
-bool TQSqlQuery::isNull( int field ) const
-{
- if ( !d->sqlResult )
- return FALSE;
- if ( d->sqlResult->isActive() && d->sqlResult->isValid() )
- return d->sqlResult->isNull( field );
- return FALSE;
-}
-
-/*!
- Executes the SQL in \a query. Returns TRUE and sets the query
- state to active if the query was successful; otherwise returns
- FALSE and sets the query state to inactive. The \a query string
- must use syntax appropriate for the SQL database being queried,
- for example, standard SQL.
-
- After the query is executed, the query is positioned on an \e
- invalid record, and must be navigated to a valid record before
- data values can be retrieved, e.g. using next().
-
- Note that the last error for this query is reset when exec() is
- called.
-
- \sa isActive() isValid() next() prev() first() last() seek()
-*/
-
-bool TQSqlQuery::exec ( const TQString& query )
-{
- if ( !d->sqlResult )
- return FALSE;
- if ( d->sqlResult->extension() && driver()->hasFeature( TQSqlDriver::PreparedQueries ) )
- d->sqlResult->extension()->clear();
- d->sqlResult->setActive( FALSE );
- d->sqlResult->setLastError( TQSqlError() );
- d->sqlResult->setAt( TQSql::BeforeFirst );
- if ( !driver() ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::exec: no driver" );
-#endif
- return FALSE;
- }
- if ( d->count > 1 )
- *this = driver()->createQuery();
- d->sqlResult->setQuery( query.stripWhiteSpace() );
- d->executedQuery = d->sqlResult->lastQuery();
- if ( !driver()->isOpen() || driver()->isOpenError() ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::exec: database not open" );
-#endif
- return FALSE;
- }
- if ( query.isNull() || query.length() == 0 ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::exec: empty query" );
-#endif
- return FALSE;
- }
-#ifdef TQT_DEBUG_SQL
- qDebug( "\n TQSqlQuery: " + query );
-#endif
- return d->sqlResult->reset( query );
-}
-
-/*!
- Returns the value of the \a{i}-th field in the query (zero based).
-
- The fields are numbered from left to right using the text of the
- \c SELECT statement, e.g. in \c{SELECT forename, surname FROM people},
- field 0 is \c forename and field 1 is \c surname. Using \c{SELECT *}
- is not recommended because the order of the fields in the query is
- undefined.
-
- An invalid TQVariant is returned if field \a i does not exist, if
- the query is inactive, or if the query is positioned on an invalid
- record.
-
- \sa prev() next() first() last() seek() isActive() isValid()
-*/
-
-TQVariant TQSqlQuery::value( int i ) const
-{
- if ( !d->sqlResult )
- return TQVariant();
- if ( isActive() && isValid() && ( i > TQSql::BeforeFirst ) ) {
- return d->sqlResult->data( i );
- } else {
-#ifdef TQT_CHECK_RANGE
- qWarning( "TQSqlQuery::value: not positioned on a valid record" );
-#endif
- }
- return TQVariant();
-}
-
-/*!
- Returns the current internal position of the query. The first
- record is at position zero. If the position is invalid, a
- TQSql::Location will be returned indicating the invalid position.
-
- \sa prev() next() first() last() seek() isActive() isValid()
-*/
-
-int TQSqlQuery::at() const
-{
- if ( !d->sqlResult )
- return TQSql::BeforeFirst;
- return d->sqlResult->at();
-}
-
-/*!
- Returns the text of the current query being used, or TQString::null
- if there is no current query text.
-
- \sa executedQuery()
-*/
-
-TQString TQSqlQuery::lastQuery() const
-{
- if ( !d->sqlResult )
- return TQString::null;
- return d->sqlResult->lastQuery();
-}
-
-/*!
- Returns the database driver associated with the query.
-*/
-
-const TQSqlDriver* TQSqlQuery::driver() const
-{
- if ( !d->sqlResult )
- return 0;
- return d->sqlResult->driver();
-}
-
-/*!
- Returns the result associated with the query.
-*/
-
-const TQSqlResult* TQSqlQuery::result() const
-{
- return d->sqlResult;
-}
-
-/*!
- Retrieves the record at position (offset) \a i, if available, and
- positions the query on the retrieved record. The first record is
- at position 0. Note that the query must be in an active state and
- isSelect() must return TRUE before calling this function.
-
- If \a relative is FALSE (the default), the following rules apply:
-
- \list
- \i If \a i is negative, the result is positioned before the
- first record and FALSE is returned.
- \i Otherwise, an attempt is made to move to the record at position
- \a i. If the record at position \a i could not be retrieved, the
- result is positioned after the last record and FALSE is returned. If
- the record is successfully retrieved, TRUE is returned.
- \endlist
-
- If \a relative is TRUE, the following rules apply:
-
- \list
- \i If the result is currently positioned before the first
- record or on the first record, and \a i is negative, there is no
- change, and FALSE is returned.
- \i If the result is currently located after the last record, and
- \a i is positive, there is no change, and FALSE is returned.
- \i If the result is currently located somewhere in the middle,
- and the relative offset \a i moves the result below zero, the
- result is positioned before the first record and FALSE is
- returned.
- \i Otherwise, an attempt is made to move to the record \a i
- records ahead of the current record (or \a i records behind the
- current record if \a i is negative). If the record at offset \a i
- could not be retrieved, the result is positioned after the last
- record if \a i >= 0, (or before the first record if \a i is
- negative), and FALSE is returned. If the record is successfully
- retrieved, TRUE is returned.
- \endlist
-
- \sa next() prev() first() last() at() isActive() isValid()
-*/
-bool TQSqlQuery::seek( int i, bool relative )
-{
- if ( !isSelect() || !isActive() )
- return FALSE;
- beforeSeek();
- checkDetach();
- int actualIdx;
- if ( !relative ) { // arbitrary seek
- if ( i < 0 ) {
- d->sqlResult->setAt( TQSql::BeforeFirst );
- afterSeek();
- return FALSE;
- }
- actualIdx = i;
- } else {
- switch ( at() ) { // relative seek
- case TQSql::BeforeFirst:
- if ( i > 0 )
- actualIdx = i;
- else {
- afterSeek();
- return FALSE;
- }
- break;
- case TQSql::AfterLast:
- if ( i < 0 ) {
- d->sqlResult->fetchLast();
- actualIdx = at() + i;
- } else {
- afterSeek();
- return FALSE;
- }
- break;
- default:
- if ( ( at() + i ) < 0 ) {
- d->sqlResult->setAt( TQSql::BeforeFirst );
- afterSeek();
- return FALSE;
- }
- actualIdx = at() + i;
- break;
- }
- }
- // let drivers optimize
- if ( isForwardOnly() && actualIdx < at() ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::seek: cannot seek backwards in a forward only query" );
-#endif
- afterSeek();
- return FALSE;
- }
- if ( actualIdx == ( at() + 1 ) && at() != TQSql::BeforeFirst ) {
- if ( !d->sqlResult->fetchNext() ) {
- d->sqlResult->setAt( TQSql::AfterLast );
- afterSeek();
- return FALSE;
- }
- afterSeek();
- return TRUE;
- }
- if ( actualIdx == ( at() - 1 ) ) {
- if ( !d->sqlResult->fetchPrev() ) {
- d->sqlResult->setAt( TQSql::BeforeFirst );
- afterSeek();
- return FALSE;
- }
- afterSeek();
- return TRUE;
- }
- if ( !d->sqlResult->fetch( actualIdx ) ) {
- d->sqlResult->setAt( TQSql::AfterLast );
- afterSeek();
- return FALSE;
- }
- afterSeek();
- return TRUE;
-}
-
-/*!
- Retrieves the next record in the result, if available, and
- positions the query on the retrieved record. Note that the result
- must be in an active state and isSelect() must return TRUE before
- calling this function or it will do nothing and return FALSE.
-
- The following rules apply:
-
- \list
- \i If the result is currently located before the first
- record, e.g. immediately after a query is executed, an attempt is
- made to retrieve the first record.
-
- \i If the result is currently located after the last record,
- there is no change and FALSE is returned.
-
- \i If the result is located somewhere in the middle, an attempt
- is made to retrieve the next record.
- \endlist
-
- If the record could not be retrieved, the result is positioned after
- the last record and FALSE is returned. If the record is successfully
- retrieved, TRUE is returned.
-
- \sa prev() first() last() seek() at() isActive() isValid()
-*/
-
-bool TQSqlQuery::next()
-{
- if ( !isSelect() || !isActive() )
- return FALSE;
- beforeSeek();
- checkDetach();
- bool b = FALSE;
- switch ( at() ) {
- case TQSql::BeforeFirst:
- b = d->sqlResult->fetchFirst();
- afterSeek();
- return b;
- case TQSql::AfterLast:
- afterSeek();
- return FALSE;
- default:
- if ( !d->sqlResult->fetchNext() ) {
- d->sqlResult->setAt( TQSql::AfterLast );
- afterSeek();
- return FALSE;
- }
- afterSeek();
- return TRUE;
- }
-}
-
-/*!
- Retrieves the previous record in the result, if available, and
- positions the query on the retrieved record. Note that the result
- must be in an active state and isSelect() must return TRUE before
- calling this function or it will do nothing and return FALSE.
-
- The following rules apply:
-
- \list
- \i If the result is currently located before the first record,
- there is no change and FALSE is returned.
-
- \i If the result is currently located after the last record, an
- attempt is made to retrieve the last record.
-
- \i If the result is somewhere in the middle, an attempt is made
- to retrieve the previous record.
- \endlist
-
- If the record could not be retrieved, the result is positioned
- before the first record and FALSE is returned. If the record is
- successfully retrieved, TRUE is returned.
-
- \sa next() first() last() seek() at() isActive() isValid()
-*/
-
-bool TQSqlQuery::prev()
-{
- if ( !isSelect() || !isActive() )
- return FALSE;
- if ( isForwardOnly() ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::seek: cannot seek backwards in a forward only query" );
-#endif
- return FALSE;
- }
-
- beforeSeek();
- checkDetach();
- bool b = FALSE;
- switch ( at() ) {
- case TQSql::BeforeFirst:
- afterSeek();
- return FALSE;
- case TQSql::AfterLast:
- b = d->sqlResult->fetchLast();
- afterSeek();
- return b;
- default:
- if ( !d->sqlResult->fetchPrev() ) {
- d->sqlResult->setAt( TQSql::BeforeFirst );
- afterSeek();
- return FALSE;
- }
- afterSeek();
- return TRUE;
- }
-}
-
-/*!
- Retrieves the first record in the result, if available, and
- positions the query on the retrieved record. Note that the result
- must be in an active state and isSelect() must return TRUE before
- calling this function or it will do nothing and return FALSE.
- Returns TRUE if successful. If unsuccessful the query position is
- set to an invalid position and FALSE is returned.
-
- \sa next() prev() last() seek() at() isActive() isValid()
-*/
-
-bool TQSqlQuery::first()
-{
- if ( !isSelect() || !isActive() )
- return FALSE;
- if ( isForwardOnly() && at() > TQSql::BeforeFirst ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::seek: cannot seek backwards in a forward only query" );
-#endif
- return FALSE;
- }
- beforeSeek();
- checkDetach();
- bool b = FALSE;
- b = d->sqlResult->fetchFirst();
- afterSeek();
- return b;
-}
-
-/*!
- Retrieves the last record in the result, if available, and
- positions the query on the retrieved record. Note that the result
- must be in an active state and isSelect() must return TRUE before
- calling this function or it will do nothing and return FALSE.
- Returns TRUE if successful. If unsuccessful the query position is
- set to an invalid position and FALSE is returned.
-
- \sa next() prev() first() seek() at() isActive() isValid()
-*/
-
-bool TQSqlQuery::last()
-{
- if ( !isSelect() || !isActive() )
- return FALSE;
- beforeSeek();
- checkDetach();
- bool b = FALSE;
- b = d->sqlResult->fetchLast();
- afterSeek();
- return b;
-}
-
-/*!
- Returns the size of the result, (number of rows returned), or -1
- if the size cannot be determined or if the database does not
- support reporting information about query sizes. Note that for
- non-\c SELECT statements (isSelect() returns FALSE), size() will
- return -1. If the query is not active (isActive() returns FALSE),
- -1 is returned.
-
- To determine the number of rows affected by a non-SELECT
- statement, use numRowsAffected().
-
- \sa isActive() numRowsAffected() TQSqlDriver::hasFeature()
-*/
-int TQSqlQuery::size() const
-{
- if ( !d->sqlResult )
- return -1;
- if ( isActive() && d->sqlResult->driver()->hasFeature( TQSqlDriver::QuerySize ) )
- return d->sqlResult->size();
- return -1;
-}
-
-/*!
- Returns the number of rows affected by the result's SQL statement,
- or -1 if it cannot be determined. Note that for \c SELECT
- statements, the value is undefined; see size() instead. If the
- query is not active (isActive() returns FALSE), -1 is returned.
-
- \sa size() TQSqlDriver::hasFeature()
-*/
-
-int TQSqlQuery::numRowsAffected() const
-{
- if ( !d->sqlResult )
- return -1;
- if ( isActive() )
- return d->sqlResult->numRowsAffected();
- return -1;
-}
-
-/*!
- Returns error information about the last error (if any) that
- occurred.
-
- \sa TQSqlError
-*/
-
-TQSqlError TQSqlQuery::lastError() const
-{
- if ( !d->sqlResult )
- return TQSqlError();
- return d->sqlResult->lastError();
-}
-
-/*!
- Returns TRUE if the query is currently positioned on a valid
- record; otherwise returns FALSE.
-*/
-
-bool TQSqlQuery::isValid() const
-{
- if ( !d->sqlResult )
- return FALSE;
- return d->sqlResult->isValid();
-}
-
-/*!
- Returns TRUE if the query is currently active; otherwise returns
- FALSE.
-*/
-
-bool TQSqlQuery::isActive() const
-{
- if ( !d->sqlResult )
- return FALSE;
- return d->sqlResult->isActive();
-}
-
-/*!
- Returns TRUE if the current query is a \c SELECT statement;
- otherwise returns FALSE.
-*/
-
-bool TQSqlQuery::isSelect() const
-{
- if ( !d->sqlResult )
- return FALSE;
- return d->sqlResult->isSelect();
-}
-
-/*!
- Returns TRUE if you can only scroll \e forward through a result
- set; otherwise returns FALSE.
-
- \sa setForwardOnly()
-*/
-bool TQSqlQuery::isForwardOnly() const
-{
- if ( !d->sqlResult )
- return FALSE;
- return d->sqlResult->isForwardOnly();
-}
-
-/*!
- Sets forward only mode to \a forward. If forward is TRUE only
- next(), and seek() with positive values, are allowed for
- navigating the results. Forward only mode needs far less memory
- since results do not need to be cached.
-
- Forward only mode is off by default.
-
- Forward only mode cannot be used with data aware widgets like
- TQDataTable, since they must to be able to scroll backward as well
- as forward.
-
- \sa isForwardOnly(), next(), seek()
-*/
-void TQSqlQuery::setForwardOnly( bool forward )
-{
- if ( d->sqlResult )
- d->sqlResult->setForwardOnly( forward );
-}
-
-/*!
- \internal
-*/
-
-void TQSqlQuery::deref()
-{
- if ( d->deref() ) {
- delete d;
- d = 0;
- }
-}
-
-/*!
- \internal
-*/
-
-bool TQSqlQuery::checkDetach()
-{
- if ( d->count > 1 && d->sqlResult ) {
- TQString sql = d->sqlResult->lastQuery();
- *this = driver()->createQuery();
- exec( sql );
- return TRUE;
- }
- return FALSE;
-}
-
-
-/*!
- Protected virtual function called before the internal record
- pointer is moved to a new record. The default implementation does
- nothing.
-*/
-
-void TQSqlQuery::beforeSeek()
-{
-
-}
-
-
-/*!
- Protected virtual function called after the internal record
- pointer is moved to a new record. The default implementation does
- nothing.
-*/
-
-void TQSqlQuery::afterSeek()
-{
-
-}
-
-// XXX: Hack to keep BCI - remove in 4.0. TQSqlExtension should be
-// removed, and the prepare(), exec() etc. fu's should be
-// made virtual members of TQSqlQuery/TQSqlResult
-
-/*!
- Prepares the SQL query \a query for execution. The query may
- contain placeholders for binding values. Both Oracle style
- colon-name (e.g. \c{:surname}), and ODBC style (e.g. \c{?})
- placeholders are supported; but they cannot be mixed in the same
- query. See the \link #details Description\endlink for examples.
-
- \sa exec(), bindValue(), addBindValue()
-*/
-bool TQSqlQuery::prepare( const TQString& query )
-{
- if ( !d->sqlResult || !d->sqlResult->extension() )
- return FALSE;
- d->sqlResult->setActive( FALSE );
- d->sqlResult->setLastError( TQSqlError() );
- d->sqlResult->setAt( TQSql::BeforeFirst );
- d->sqlResult->extension()->clear();
- if ( !driver() ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::prepare: no driver" );
-#endif
- return FALSE;
- }
- if ( d->count > 1 )
- *this = driver()->createQuery();
- d->sqlResult->setQuery( query.stripWhiteSpace() );
- if ( !driver()->isOpen() || driver()->isOpenError() ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::prepare: database not open" );
-#endif
- return FALSE;
- }
- if ( query.isNull() || query.length() == 0 ) {
-#ifdef TQT_CHECK_RANGE
- qWarning("TQSqlQuery::prepare: empty query" );
-#endif
- return FALSE;
- }
-#ifdef TQT_DEBUG_SQL
- qDebug( "\n TQSqlQuery: " + query );
-#endif
- TQString q = query;
- TQRegExp rx(TQString::tqfromLatin1("'[^']*'|:([a-zA-Z0-9_]+)"));
- if ( driver()->hasFeature( TQSqlDriver::PreparedQueries ) ) {
- // below we substitute Oracle placeholders with ODBC ones and
- // vice versa to make this db independent
- int i = 0, cnt = 0;
- if ( driver()->hasFeature( TQSqlDriver::NamedPlaceholders ) ) {
- TQRegExp rx(TQString::tqfromLatin1("'[^']*'|\\?"));
- while ( (i = rx.search( q, i )) != -1 ) {
- if ( rx.cap(0) == "?" ) {
- q = q.replace( i, 1, ":f" + TQString::number(cnt) );
- cnt++;
- }
- i += rx.matchedLength();
- }
- } else if ( driver()->hasFeature( TQSqlDriver::PositionalPlaceholders ) ) {
- while ( (i = rx.search( q, i )) != -1 ) {
- if ( rx.cap(1).isEmpty() ) {
- i += rx.matchedLength();
- } else {
- // record the index of the placeholder - needed
- // for emulating named bindings with ODBC
- d->sqlResult->extension()->index[ cnt ]= rx.cap(0);
- q = q.replace( i, rx.matchedLength(), "?" );
- i++;
- cnt++;
- }
- }
- }
- d->executedQuery = q;
- return d->sqlResult->extension()->prepare( q );
- } else {
- int i = 0;
- while ( (i = rx.search( q, i )) != -1 ) {
- if ( !rx.cap(1).isEmpty() )
- d->sqlResult->extension()->holders.append( Holder( rx.cap(0), i ) );
- i += rx.matchedLength();
- }
- return TRUE; // fake prepares should always succeed
- }
-}
-
-/*!
- \overload
-
- Executes a previously prepared SQL query. Returns TRUE if the
- query executed successfully; otherwise returns FALSE.
-
- \sa prepare(), bindValue(), addBindValue()
-*/
-bool TQSqlQuery::exec()
-{
- bool ret;
- if ( !d->sqlResult || !d->sqlResult->extension() )
- return FALSE;
- if ( driver()->hasFeature( TQSqlDriver::PreparedQueries ) ) {
- ret = d->sqlResult->extension()->exec();
- } else {
- // fake preparation - just replace the placeholders..
- TQString query = d->sqlResult->lastQuery();
- if ( d->sqlResult->extension()->bindMethod() == TQSqlExtension::BindByName ) {
- int i;
- TQVariant val;
- TQString holder;
- for ( i = (int)d->sqlResult->extension()->holders.count() - 1; i >= 0; --i ) {
- holder = d->sqlResult->extension()->holders[ (uint)i ].holderName;
- val = d->sqlResult->extension()->values[ holder ].value;
- TQSqlField f( "", val.type() );
- if ( val.isNull() )
- f.setNull();
- else
- f.setValue( val );
- query = query.replace( (uint)d->sqlResult->extension()->holders[ (uint)i ].holderPos,
- holder.length(), driver()->formatValue( &f ) );
- }
- } else {
- TQMap<int, TQString>::ConstIterator it;
- TQString val;
- int i = 0;
- for ( it = d->sqlResult->extension()->index.begin();
- it != d->sqlResult->extension()->index.end(); ++it ) {
- i = query.find( '?', i );
- if ( i > -1 ) {
- TQSqlField f( "", d->sqlResult->extension()->values[ it.data() ].value.type() );
- if ( d->sqlResult->extension()->values[ it.data() ].value.isNull() )
- f.setNull();
- else
- f.setValue( d->sqlResult->extension()->values[ it.data() ].value );
- val = driver()->formatValue( &f );
- query = query.replace( i, 1, driver()->formatValue( &f ) );
- i += val.length();
- }
- }
- }
- // have to retain the original query w/placeholders..
- TQString orig = d->sqlResult->lastQuery();
- ret = exec( query );
- d->executedQuery = query;
- d->sqlResult->setQuery( orig );
- }
- d->sqlResult->extension()->resetBindCount();
- return ret;
-}
-
-/*!
- Set the placeholder \a placeholder to be bound to value \a val in
- the prepared statement. Note that the placeholder mark (e.g \c{:})
- must be included when specifying the placeholder name. If \a type
- is \c TQSql::Out or \c TQSql::InOut, the placeholder will be
- overwritten with data from the database after the exec() call.
-
- \sa addBindValue(), prepare(), exec()
-*/
-void TQSqlQuery::bindValue( const TQString& placeholder, const TQVariant& val, TQSql::ParameterType type )
-{
- if ( !d->sqlResult || !d->sqlResult->extension() )
- return;
- d->sqlResult->extension()->bindValue( placeholder, val, type );
-}
-
-/*!
- \overload
-
- Set the placeholder in position \a pos to be bound to value \a val
- in the prepared statement. Field numbering starts at 0. If \a type
- is \c TQSql::Out or \c TQSql::InOut, the placeholder will be
- overwritten with data from the database after the exec() call.
-
- \sa addBindValue(), prepare(), exec()
-*/
-void TQSqlQuery::bindValue( int pos, const TQVariant& val, TQSql::ParameterType type )
-{
- if ( !d->sqlResult || !d->sqlResult->extension() )
- return;
- d->sqlResult->extension()->bindValue( pos, val, type );
-}
-
-/*!
- Adds the value \a val to the list of values when using positional
- value binding. The order of the addBindValue() calls determines
- which placeholder a value will be bound to in the prepared query.
- If \a type is \c TQSql::Out or \c TQSql::InOut, the placeholder will
- be overwritten with data from the database after the exec() call.
-
- \sa bindValue(), prepare(), exec()
-*/
-void TQSqlQuery::addBindValue( const TQVariant& val, TQSql::ParameterType type )
-{
- if ( !d->sqlResult || !d->sqlResult->extension() )
- return;
- d->sqlResult->extension()->addBindValue( val, type );
-}
-
-
-/*!
- \overload
-
- Binds the placeholder with type \c TQSql::In.
-*/
-void TQSqlQuery::bindValue( const TQString& placeholder, const TQVariant& val )
-{
- bindValue( placeholder, val, TQSql::In );
-}
-
-/*!
- \overload
-
- Binds the placeholder at position \a pos with type \c TQSql::In.
-*/
-void TQSqlQuery::bindValue( int pos, const TQVariant& val )
-{
- bindValue( pos, val, TQSql::In );
-}
-
-/*!
- \overload
-
- Binds the placeholder with type \c TQSql::In.
-*/
-void TQSqlQuery::addBindValue( const TQVariant& val )
-{
- addBindValue( val, TQSql::In );
-}
-
-/*!
- Returns the value for the \a placeholder.
-*/
-TQVariant TQSqlQuery::boundValue( const TQString& placeholder ) const
-{
- if ( !d->sqlResult || !d->sqlResult->extension() )
- return TQVariant();
- return d->sqlResult->extension()->boundValue( placeholder );
-}
-
-/*!
- \overload
-
- Returns the value for the placeholder at position \a pos.
-*/
-TQVariant TQSqlQuery::boundValue( int pos ) const
-{
- if ( !d->sqlResult || !d->sqlResult->extension() )
- return TQVariant();
- return d->sqlResult->extension()->boundValue( pos );
-}
-
-/*!
- Returns a map of the bound values.
-
- The bound values can be examined in the following way:
- \code
- TQSqlQuery query;
- ...
- // Examine the bound values - bound using named binding
- TQMap<TQString, TQVariant>::ConstIterator it;
- TQMap<TQString, TQVariant> vals = query.boundValues();
- for ( it = vals.begin(); it != vals.end(); ++it )
- qWarning( "Placeholder: " + it.key() + ", Value: " + (*it).toString() );
- ...
-
- // Examine the bound values - bound using positional binding
- TQValueList<TQVariant>::ConstIterator it;
- TQValueList<TQVariant> list = query.boundValues().values();
- int i = 0;
- for ( it = list.begin(); it != list.end(); ++it )
- qWarning( "Placeholder pos: %d, Value: " + (*it).toString(), i++ );
- ...
-
- \endcode
-*/
-TQMap<TQString,TQVariant> TQSqlQuery::boundValues() const
-{
- if ( !d->sqlResult || !d->sqlResult->extension() )
- return TQMap<TQString,TQVariant>();
- return d->sqlResult->extension()->boundValues();
-}
-
-/*!
- Returns the last query that was executed.
-
- In most cases this function returns the same as lastQuery(). If a
- prepared query with placeholders is executed on a DBMS that does
- not support it, the preparation of this query is emulated. The
- placeholders in the original query are replaced with their bound
- values to form a new query. This function returns the modified
- query. Useful for debugging purposes.
-
- \sa lastQuery()
-*/
-TQString TQSqlQuery::executedQuery() const
-{
- return d->executedQuery;
-}
-#endif // TQT_NO_SQL