#include <qsql_odbc.h>
Inheritance diagram for QODBCResult:


Definition at line 73 of file qsql_odbc.h.
Public Member Functions | |
| QODBCResult (const QODBCDriver *db, QODBCDriverPrivate *p) | |
| virtual | ~QODBCResult () |
| bool | prepare (const QString &query) |
| bool | exec () |
| QVariant | handle () const |
Protected Member Functions | |
| bool | fetchNext () |
| bool | fetchFirst () |
| bool | fetchLast () |
| bool | fetchPrior () |
| bool | fetch (int i) |
| bool | reset (const QString &query) |
| QVariant | data (int field) |
| bool | isNull (int field) |
| int | size () |
| int | numRowsAffected () |
| QSqlRecord | record () const |
Private Attributes | |
| QODBCPrivate * | d |
| QODBCResult::QODBCResult | ( | const QODBCDriver * | db, | |
| QODBCDriverPrivate * | p | |||
| ) |
Definition at line 642 of file qsql_odbc.cpp.
References d, QODBCPrivate::hDbc, QODBCPrivate::hEnv, p, QODBCPrivate::sql_char_type, QODBCPrivate::sql_longvarchar_type, QODBCPrivate::sql_varchar_type, QODBCPrivate::unicode, and QODBCPrivate::useSchema.
00643 : QSqlResult(db) 00644 { 00645 d = new QODBCPrivate(); 00646 d->hEnv = p->hEnv; 00647 d->hDbc = p->hDbc; 00648 d->unicode = p->unicode; 00649 d->useSchema = p->useSchema; 00650 d->sql_char_type = p->sql_char_type; 00651 d->sql_varchar_type = p->sql_varchar_type; 00652 d->sql_longvarchar_type = p->sql_longvarchar_type; 00653 }
| QODBCResult::~QODBCResult | ( | ) | [virtual] |
Definition at line 655 of file qsql_odbc.cpp.
References d, QSqlResult::driver(), QODBCPrivate::hStmt, QString::number(), and qSqlWarning().
00656 { 00657 if (d->hStmt && driver()->isOpen()) { 00658 SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt); 00659 if (r != SQL_SUCCESS) 00660 qSqlWarning(QLatin1String("QODBCDriver: Unable to free statement handle ") 00661 + QString::number(r), d); 00662 } 00663 00664 delete d; 00665 }
Here is the call graph for this function:

| bool QODBCResult::prepare | ( | const QString & | query | ) | [virtual] |
Prepares the given query for execution; the query will normally use placeholders so that it can be executed repeatedly. Returns true if the query is prepared successfully; otherwise returns false.
Reimplemented from QSqlResult.
Definition at line 973 of file qsql_odbc.cpp.
References QSql::BeforeFirstRow, QSqlRecord::clear(), d, QODBCPrivate::hDbc, QODBCPrivate::hStmt, QSqlResult::isForwardOnly(), QString::length(), qMakeError(), qSqlWarning(), QODBCPrivate::rInf, QSqlResult::setActive(), QSqlResult::setAt(), QSqlResult::setLastError(), QSqlError::StatementError, QString::toLocal8Bit(), QCoreApplication::translate(), and QString::unicode().
00974 { 00975 setActive(false); 00976 setAt(QSql::BeforeFirstRow); 00977 SQLRETURN r; 00978 00979 d->rInf.clear(); 00980 if (d->hStmt) { 00981 r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt); 00982 if (r != SQL_SUCCESS) { 00983 qSqlWarning(QLatin1String("QODBCResult::prepare: Unable to close statement"), d); 00984 return false; 00985 } 00986 } 00987 r = SQLAllocHandle(SQL_HANDLE_STMT, 00988 d->hDbc, 00989 &d->hStmt); 00990 if (r != SQL_SUCCESS) { 00991 qSqlWarning(QLatin1String("QODBCResult::prepare: Unable to allocate statement handle"), d); 00992 return false; 00993 } 00994 00995 if (isForwardOnly()) { 00996 r = SQLSetStmtAttr(d->hStmt, 00997 SQL_ATTR_CURSOR_TYPE, 00998 (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, 00999 SQL_IS_UINTEGER); 01000 } else { 01001 r = SQLSetStmtAttr(d->hStmt, 01002 SQL_ATTR_CURSOR_TYPE, 01003 (SQLPOINTER)SQL_CURSOR_STATIC, 01004 SQL_IS_UINTEGER); 01005 } 01006 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { 01007 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", 01008 "QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. " 01009 "Please check your ODBC driver configuration"), QSqlError::StatementError, d)); 01010 return false; 01011 } 01012 01013 #ifdef UNICODE 01014 r = SQLPrepare(d->hStmt, 01015 (SQLWCHAR*) query.unicode(), 01016 (SQLINTEGER) query.length()); 01017 #else 01018 QByteArray query8 = query.toLocal8Bit(); 01019 r = SQLPrepare(d->hStmt, 01020 (SQLCHAR*) query8.constData(), 01021 (SQLINTEGER) query8.length()); 01022 #endif 01023 01024 if (r != SQL_SUCCESS) { 01025 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", 01026 "Unable to prepare statement"), QSqlError::StatementError, d)); 01027 return false; 01028 } 01029 return true; 01030 }
Here is the call graph for this function:

| bool QODBCResult::exec | ( | ) | [virtual] |
Executes the query, returning true if successful; otherwise returns false.
Reimplemented from QSqlResult.
Definition at line 1032 of file qsql_odbc.cpp.
References QSqlRecord::append(), QList< T >::append(), QSql::BeforeFirstRow, QSqlResult::bindValueType(), QSqlResult::boundValues(), QVariant::ByteArray, QString::capacity(), QSqlRecord::clear(), constData(), QString::constData(), QByteArray::constData(), d, QVarLengthArray< T, Prealloc >::data(), QVariant::Date, QDateTime::date(), QVariant::DateTime, QDate::day(), QVariant::Double, QODBCPrivate::fieldCache, QODBCPrivate::fieldCacheIdx, QString::fromAscii(), QString::fromUtf16(), QSqlResult::hasOutValues(), QTime::hour(), QODBCPrivate::hStmt, i, QSql::InOut, QVariant::Int, QSqlResult::isSelect(), QString::length(), QByteArray::length(), QTime::minute(), QDate::month(), QTime::msec(), NULL, QSql::Out, qMakeError(), qMakeFieldInfo(), qODBCWarn(), qParamType, QSQLLEN, qSqlWarning(), qWarning(), QByteArray::resize(), QVector< T >::resize(), QODBCPrivate::rInf, QTime::second(), QSqlResult::setActive(), QSqlResult::setAt(), QSqlResult::setLastError(), QSqlResult::setSelect(), QVarLengthArray< T, Prealloc >::size(), QByteArray::size(), QSqlError::StatementError, QVariant::String, QList< T >::takeFirst(), QDateTime::time(), QVariant::Time, QCoreApplication::translate(), type, QODBCPrivate::unicode, QString::utf16(), val, values, and QDate::year().
01033 { 01034 SQLRETURN r; 01035 QList<QByteArray> tmpStorage; // holds temporary buffers 01036 QVarLengthArray<QSQLLEN, 32> indicators(boundValues().count()); 01037 01038 memset(indicators.data(), 0, indicators.size() * sizeof(QSQLLEN)); 01039 setActive(false); 01040 setAt(QSql::BeforeFirstRow); 01041 d->rInf.clear(); 01042 d->fieldCacheIdx = 0; 01043 01044 if (!d->hStmt) { 01045 qSqlWarning(QLatin1String("QODBCResult::exec: No statement handle available"), d); 01046 return false; 01047 } 01048 if (isSelect()) 01049 SQLCloseCursor(d->hStmt); 01050 01051 // bind parameters - only positional binding allowed 01052 QVector<QVariant>& values = boundValues(); 01053 int i; 01054 for (i = 0; i < values.count(); ++i) { 01055 if (bindValueType(i) & QSql::Out) 01056 values[i].detach(); 01057 const QVariant &val = values.at(i); 01058 QSQLLEN *ind = &indicators[i]; 01059 if (val.isNull()) 01060 *ind = SQL_NULL_DATA; 01061 switch (val.type()) { 01062 case QVariant::Date: { 01063 QByteArray ba; 01064 ba.resize(sizeof(DATE_STRUCT)); 01065 DATE_STRUCT *dt = (DATE_STRUCT *)ba.constData(); 01066 QDate qdt = val.toDate(); 01067 dt->year = qdt.year(); 01068 dt->month = qdt.month(); 01069 dt->day = qdt.day(); 01070 r = SQLBindParameter(d->hStmt, 01071 i + 1, 01072 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01073 SQL_C_DATE, 01074 SQL_DATE, 01075 0, 01076 0, 01077 (void *) dt, 01078 0, 01079 *ind == SQL_NULL_DATA ? ind : NULL); 01080 tmpStorage.append(ba); 01081 break; } 01082 case QVariant::Time: { 01083 QByteArray ba; 01084 ba.resize(sizeof(TIME_STRUCT)); 01085 TIME_STRUCT *dt = (TIME_STRUCT *)ba.constData(); 01086 QTime qdt = val.toTime(); 01087 dt->hour = qdt.hour(); 01088 dt->minute = qdt.minute(); 01089 dt->second = qdt.second(); 01090 r = SQLBindParameter(d->hStmt, 01091 i + 1, 01092 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01093 SQL_C_TIME, 01094 SQL_TIME, 01095 0, 01096 0, 01097 (void *) dt, 01098 0, 01099 *ind == SQL_NULL_DATA ? ind : NULL); 01100 tmpStorage.append(ba); 01101 break; } 01102 case QVariant::DateTime: { 01103 QByteArray ba; 01104 ba.resize(sizeof(TIMESTAMP_STRUCT)); 01105 TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)ba.constData(); 01106 QDateTime qdt = val.toDateTime(); 01107 dt->year = qdt.date().year(); 01108 dt->month = qdt.date().month(); 01109 dt->day = qdt.date().day(); 01110 dt->hour = qdt.time().hour(); 01111 dt->minute = qdt.time().minute(); 01112 dt->second = qdt.time().second(); 01113 dt->fraction = qdt.time().msec() * 1000000; 01114 r = SQLBindParameter(d->hStmt, 01115 i + 1, 01116 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01117 SQL_C_TIMESTAMP, 01118 SQL_TIMESTAMP, 01119 19, 01120 0, 01121 (void *) dt, 01122 0, 01123 *ind == SQL_NULL_DATA ? ind : NULL); 01124 tmpStorage.append(ba); 01125 break; } 01126 case QVariant::Int: 01127 r = SQLBindParameter(d->hStmt, 01128 i + 1, 01129 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01130 SQL_C_SLONG, 01131 SQL_INTEGER, 01132 0, 01133 0, 01134 (void *) val.constData(), 01135 0, 01136 *ind == SQL_NULL_DATA ? ind : NULL); 01137 break; 01138 case QVariant::Double: 01139 r = SQLBindParameter(d->hStmt, 01140 i + 1, 01141 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01142 SQL_C_DOUBLE, 01143 SQL_DOUBLE, 01144 0, 01145 0, 01146 (void *) val.constData(), 01147 0, 01148 *ind == SQL_NULL_DATA ? ind : NULL); 01149 break; 01150 case QVariant::ByteArray: 01151 if (*ind != SQL_NULL_DATA) { 01152 *ind = val.toByteArray().size(); 01153 } 01154 r = SQLBindParameter(d->hStmt, 01155 i + 1, 01156 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01157 SQL_C_BINARY, 01158 SQL_LONGVARBINARY, 01159 val.toByteArray().size(), 01160 0, 01161 (void *) val.toByteArray().constData(), 01162 val.toByteArray().size(), 01163 ind); 01164 break; 01165 #ifndef Q_ODBC_VERSION_2 01166 case QVariant::String: 01167 if (d->unicode) { 01168 QString str = val.toString(); 01169 str.utf16(); 01170 if (*ind != SQL_NULL_DATA) 01171 *ind = str.length() * sizeof(QChar); 01172 if (bindValueType(i) & QSql::Out) { 01173 QByteArray ba((char*)str.constData(), str.capacity() * sizeof(QChar)); 01174 r = SQLBindParameter(d->hStmt, 01175 i + 1, 01176 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01177 SQL_C_WCHAR, 01178 str.length() > 4000 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, 01179 0, // god knows... don't change this! 01180 0, 01181 (void *)ba.constData(), 01182 ba.size(), 01183 ind); 01184 tmpStorage.append(ba); 01185 break; 01186 } 01187 01188 r = SQLBindParameter(d->hStmt, 01189 i + 1, 01190 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01191 SQL_C_WCHAR, 01192 str.length() > 4000 ? SQL_WLONGVARCHAR : SQL_WVARCHAR, 01193 str.length() * sizeof(QChar), 01194 0, 01195 (void *)str.constData(), 01196 str.length() * sizeof(QChar), 01197 ind); 01198 break; 01199 } 01200 #endif 01201 // fall through 01202 default: { 01203 QByteArray ba = val.toString().toAscii(); 01204 if (*ind != SQL_NULL_DATA) 01205 *ind = ba.size(); 01206 r = SQLBindParameter(d->hStmt, 01207 i + 1, 01208 qParamType[(QFlag)(bindValueType(i)) & QSql::InOut], 01209 SQL_C_CHAR, 01210 ba.length() > 4000 ? SQL_LONGVARCHAR : SQL_VARCHAR, 01211 ba.length() + 1, 01212 0, 01213 (void *) ba.constData(), 01214 ba.length() + 1, 01215 ind); 01216 tmpStorage.append(ba); 01217 break; } 01218 } 01219 if (r != SQL_SUCCESS) { 01220 qWarning("QODBCResult::exec: unable to bind variable: %s", 01221 qODBCWarn(d).toLocal8Bit().constData()); 01222 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", 01223 "Unable to bind variable"), QSqlError::StatementError, d)); 01224 return false; 01225 } 01226 } 01227 r = SQLExecute(d->hStmt); 01228 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { 01229 qWarning("QODBCResult::exec: Unable to execute statement: %s", 01230 qODBCWarn(d).toLocal8Bit().constData()); 01231 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", 01232 "Unable to execute statement"), QSqlError::StatementError, d)); 01233 return false; 01234 } 01235 SQLSMALLINT count; 01236 r = SQLNumResultCols(d->hStmt, &count); 01237 if (count) { 01238 setSelect(true); 01239 for (int i = 0; i < count; ++i) { 01240 d->rInf.append(qMakeFieldInfo(d, i)); 01241 } 01242 d->fieldCache.resize(count); 01243 } else { 01244 setSelect(false); 01245 } 01246 setActive(true); 01247 01248 //get out parameters 01249 if (!hasOutValues()) 01250 return true; 01251 01252 for (i = 0; i < values.count(); ++i) { 01253 switch (values.at(i).type()) { 01254 case QVariant::Date: { 01255 DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.takeFirst().constData()); 01256 values[i] = QVariant(QDate(ds.year, ds.month, ds.day)); 01257 break; } 01258 case QVariant::Time: { 01259 TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.takeFirst().constData()); 01260 values[i] = QVariant(QTime(dt.hour, dt.minute, dt.second)); 01261 break; } 01262 case QVariant::DateTime: { 01263 TIMESTAMP_STRUCT dt = *((TIMESTAMP_STRUCT*) 01264 tmpStorage.takeFirst().constData()); 01265 values[i] = QVariant(QDateTime(QDate(dt.year, dt.month, dt.day), 01266 QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000))); 01267 break; } 01268 case QVariant::Int: 01269 case QVariant::Double: 01270 case QVariant::ByteArray: 01271 //nothing to do 01272 break; 01273 case QVariant::String: 01274 if (d->unicode) { 01275 if (bindValueType(i) & QSql::Out) 01276 values[i] = QString::fromUtf16((ushort*)tmpStorage.takeFirst().constData()); 01277 break; 01278 } 01279 // fall through 01280 default: { 01281 QByteArray ba = tmpStorage.takeFirst(); 01282 if (bindValueType(i) & QSql::Out) 01283 values[i] = QString::fromAscii(tmpStorage.takeFirst().constData()); 01284 break; } 01285 } 01286 if (indicators[i] == SQL_NULL_DATA) 01287 values[i] = QVariant(values[i].type()); 01288 } 01289 return true; 01290 }
Here is the call graph for this function:

| QVariant QODBCResult::handle | ( | ) | const [virtual] |
Returns the low-level database handle for this result set wrapped in a QVariant or an invalid QVariant if there is no handle.
The handle returned here can become a stale pointer if the result is modified (for example, if you clear it).
The handle can be NULL if the result was not executed yet.
This example retrieves the handle for a sqlite result:
QSqlQuery query = ... QVariant v = query.result()->handle(); if (v.isValid() && v.typeName() == "sqlite3_stmt*") { // v.data() returns a pointer to the handle sqlite3_stmt *handle = *static_cast<sqlite3_stmt **>(v.data()); if (handle != 0) { // check that it is not NULL ... } }
This snippet returns the handle for PostgreSQL or MySQL:
if (v.typeName() == "PGresult*") { PGresult *handle = *static_cast<PGresult **>(v.data()); if (handle != 0) ... } if (v.typeName() == "MYSQL_STMT*") { MYSQL_STMT *handle = *static_cast<MYSQL_STMT **>(v.data()); if (handle != 0) ... }
Reimplemented from QSqlResult.
Definition at line 1299 of file qsql_odbc.cpp.
References d, and QODBCPrivate::hStmt.
| bool QODBCResult::fetchNext | ( | ) | [protected, virtual] |
Positions the result to the next available record (row) in the result.
This function is only called if the result is in an active state. The default implementation calls fetch() with the next index. Derived classes can reimplement this function and position the result to the next record in some other way, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.
Reimplemented from QSqlResult.
Definition at line 771 of file qsql_odbc.cpp.
References QSqlResult::at(), QODBCPrivate::clearValues(), QSqlError::ConnectionError, d, QODBCPrivate::hStmt, qMakeError(), QSqlResult::setAt(), QSqlResult::setLastError(), and QCoreApplication::translate().
Referenced by fetch(), fetchFirst(), and fetchLast().
00772 { 00773 SQLRETURN r; 00774 d->clearValues(); 00775 r = SQLFetchScroll(d->hStmt, 00776 SQL_FETCH_NEXT, 00777 0); 00778 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { 00779 if (r != SQL_NO_DATA) 00780 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", 00781 "Unable to fetch next"), QSqlError::ConnectionError, d)); 00782 return false; 00783 } 00784 setAt(at() + 1); 00785 return true; 00786 }
Here is the call graph for this function:

| bool QODBCResult::fetchFirst | ( | ) | [protected, virtual] |
Positions the result to the first record (row 0) in the result.
This function is only called if the result is in an active state. Derived classes must reimplement this function and position the result to the first record, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.
Implements QSqlResult.
Definition at line 788 of file qsql_odbc.cpp.
References QSqlResult::at(), QSql::BeforeFirstRow, QODBCPrivate::clearValues(), d, fetchNext(), QODBCPrivate::hStmt, QSqlResult::isForwardOnly(), and QSqlResult::setAt().
00789 { 00790 if (isForwardOnly() && at() != QSql::BeforeFirstRow) 00791 return false; 00792 SQLRETURN r; 00793 d->clearValues(); 00794 if (isForwardOnly()) { 00795 return fetchNext(); 00796 } 00797 r = SQLFetchScroll(d->hStmt, 00798 SQL_FETCH_FIRST, 00799 0); 00800 if (r != SQL_SUCCESS) 00801 return false; 00802 setAt(0); 00803 return true; 00804 }
Here is the call graph for this function:

| bool QODBCResult::fetchLast | ( | ) | [protected, virtual] |
Positions the result to the last record (last row) in the result.
This function is only called if the result is in an active state. Derived classes must reimplement this function and position the result to the last record, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.
Implements QSqlResult.
Definition at line 821 of file qsql_odbc.cpp.
References QSql::AfterLastRow, QSqlResult::at(), QSql::BeforeFirstRow, QODBCPrivate::clearValues(), d, fetchNext(), QODBCPrivate::hStmt, i, QSqlResult::isForwardOnly(), and QSqlResult::setAt().
00822 { 00823 SQLRETURN r; 00824 d->clearValues(); 00825 00826 if (isForwardOnly()) { 00827 // cannot seek to last row in forwardOnly mode, so we have to use brute force 00828 int i = at(); 00829 if (i == QSql::AfterLastRow) 00830 return false; 00831 if (i == QSql::BeforeFirstRow) 00832 i = 0; 00833 while (fetchNext()) 00834 ++i; 00835 setAt(i); 00836 return true; 00837 } 00838 00839 r = SQLFetchScroll(d->hStmt, 00840 SQL_FETCH_LAST, 00841 0); 00842 if (r != SQL_SUCCESS) { 00843 return false; 00844 } 00845 SQLINTEGER currRow; 00846 r = SQLGetStmtAttr(d->hStmt, 00847 SQL_ROW_NUMBER, 00848 &currRow, 00849 SQL_IS_INTEGER, 00850 0); 00851 if (r != SQL_SUCCESS) 00852 return false; 00853 setAt(currRow-1); 00854 return true; 00855 }
Here is the call graph for this function:

| bool QODBCResult::fetchPrior | ( | ) | [protected] |
Definition at line 806 of file qsql_odbc.cpp.
References QSqlResult::at(), QODBCPrivate::clearValues(), d, QODBCPrivate::hStmt, QSqlResult::isForwardOnly(), and QSqlResult::setAt().
00807 { 00808 if (isForwardOnly()) 00809 return false; 00810 SQLRETURN r; 00811 d->clearValues(); 00812 r = SQLFetchScroll(d->hStmt, 00813 SQL_FETCH_PRIOR, 00814 0); 00815 if (r != SQL_SUCCESS) 00816 return false; 00817 setAt(at() - 1); 00818 return true; 00819 }
Here is the call graph for this function:

| bool QODBCResult::fetch | ( | int | i | ) | [protected, virtual] |
Positions the result to an arbitrary (zero-based) row index.
This function is only called if the result is in an active state. Derived classes must reimplement this function and position the result to the row index, and call setAt() with an appropriate value. Return true to indicate success, or false to signify failure.
Implements QSqlResult.
Definition at line 741 of file qsql_odbc.cpp.
References QSqlResult::at(), QSql::BeforeFirstRow, QODBCPrivate::clearValues(), d, fetchNext(), QODBCPrivate::hStmt, QSqlResult::isForwardOnly(), and QSqlResult::setAt().
00742 { 00743 if (isForwardOnly() && i < at()) 00744 return false; 00745 if (i == at()) 00746 return true; 00747 d->clearValues(); 00748 int actualIdx = i + 1; 00749 if (actualIdx <= 0) { 00750 setAt(QSql::BeforeFirstRow); 00751 return false; 00752 } 00753 SQLRETURN r; 00754 if (isForwardOnly()) { 00755 bool ok = true; 00756 while (ok && i > at()) 00757 ok = fetchNext(); 00758 return ok; 00759 } else { 00760 r = SQLFetchScroll(d->hStmt, 00761 SQL_FETCH_ABSOLUTE, 00762 actualIdx); 00763 } 00764 if (r != SQL_SUCCESS){ 00765 return false; 00766 } 00767 setAt(i); 00768 return true; 00769 }
Here is the call graph for this function:

| bool QODBCResult::reset | ( | const QString & | query | ) | [protected, virtual] |
Sets the result to use the SQL statement query for subsequent data retrieval.
Derived classes must reimplement this function and apply the query to the database. This function is only called after the result is set to an inactive state and is positioned before the first record of the new result. Derived classes should return true if the query was successful and ready to be used, or false otherwise.
Implements QSqlResult.
Definition at line 667 of file qsql_odbc.cpp.
References QSqlRecord::append(), QSql::BeforeFirstRow, QSqlRecord::clear(), QVector< T >::clear(), d, QODBCPrivate::fieldCache, QODBCPrivate::fieldCacheIdx, QODBCPrivate::hDbc, QODBCPrivate::hStmt, i, QSqlResult::isForwardOnly(), QString::length(), qMakeError(), qMakeFieldInfo(), qSqlWarning(), QVector< T >::resize(), QODBCPrivate::rInf, QSqlResult::setActive(), QSqlResult::setAt(), QSqlResult::setLastError(), QSqlResult::setSelect(), QSqlError::StatementError, QString::toLocal8Bit(), QCoreApplication::translate(), and QString::unicode().
00668 { 00669 setActive(false); 00670 setAt(QSql::BeforeFirstRow); 00671 SQLRETURN r; 00672 00673 d->rInf.clear(); 00674 d->fieldCache.clear(); 00675 d->fieldCacheIdx = 0; 00676 // Always reallocate the statement handle - the statement attributes 00677 // are not reset if SQLFreeStmt() is called which causes some problems. 00678 if (d->hStmt) { 00679 r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt); 00680 if (r != SQL_SUCCESS) { 00681 qSqlWarning(QLatin1String("QODBCResult::reset: Unable to free statement handle"), d); 00682 return false; 00683 } 00684 } 00685 r = SQLAllocHandle(SQL_HANDLE_STMT, 00686 d->hDbc, 00687 &d->hStmt); 00688 if (r != SQL_SUCCESS) { 00689 qSqlWarning(QLatin1String("QODBCResult::reset: Unable to allocate statement handle"), d); 00690 return false; 00691 } 00692 00693 if (isForwardOnly()) { 00694 r = SQLSetStmtAttr(d->hStmt, 00695 SQL_ATTR_CURSOR_TYPE, 00696 (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, 00697 SQL_IS_UINTEGER); 00698 } else { 00699 r = SQLSetStmtAttr(d->hStmt, 00700 SQL_ATTR_CURSOR_TYPE, 00701 (SQLPOINTER)SQL_CURSOR_STATIC, 00702 SQL_IS_UINTEGER); 00703 } 00704 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { 00705 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", 00706 "QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. " 00707 "Please check your ODBC driver configuration"), QSqlError::StatementError, d)); 00708 return false; 00709 } 00710 00711 #ifdef UNICODE 00712 r = SQLExecDirect(d->hStmt, 00713 (SQLWCHAR*) query.unicode(), 00714 (SQLINTEGER) query.length()); 00715 #else 00716 QByteArray query8 = query.toLocal8Bit(); 00717 r = SQLExecDirect(d->hStmt, 00718 (SQLCHAR*) query8.constData(), 00719 (SQLINTEGER) query8.length()); 00720 #endif 00721 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { 00722 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", 00723 "Unable to execute statement"), QSqlError::StatementError, d)); 00724 return false; 00725 } 00726 SQLSMALLINT count; 00727 r = SQLNumResultCols(d->hStmt, &count); 00728 if (count) { 00729 setSelect(true); 00730 for (int i = 0; i < count; ++i) { 00731 d->rInf.append(qMakeFieldInfo(d, i)); 00732 } 00733 d->fieldCache.resize(count); 00734 } else { 00735 setSelect(false); 00736 } 00737 setActive(true); 00738 return true; 00739 }
Here is the call graph for this function:

| QVariant QODBCResult::data | ( | int | field | ) | [protected, virtual] |
Returns the data for field index in the current row as a QVariant. This function is only called if the result is in an active state and is positioned on a valid record and index is non-negative. Derived classes must reimplement this function and return the value of field index, or QVariant() if it cannot be determined.
Implements QSqlResult.
Definition at line 857 of file qsql_odbc.cpp.
References QVector< T >::at(), QVariant::ByteArray, QSqlRecord::count(), d, QVariant::Date, QVariant::DateTime, QVariant::Double, QSqlRecord::field(), QODBCPrivate::fieldCache, QODBCPrivate::fieldCacheIdx, QODBCPrivate::hStmt, i, info, QVariant::Int, QVariant::LongLong, qGetBigIntData(), qGetBinaryData(), qGetDoubleData(), qGetIntData(), qGetStringData(), QSQLLEN, qWarning(), QODBCPrivate::rInf, QVariant::String, and QVariant::Time.
Referenced by isNull().
00858 { 00859 if (field >= d->rInf.count() || field < 0) { 00860 qWarning("QODBCResult::data: column %d out of range", field); 00861 return QVariant(); 00862 } 00863 if (field < d->fieldCacheIdx) 00864 return d->fieldCache.at(field); 00865 00866 SQLRETURN r(0); 00867 QSQLLEN lengthIndicator = 0; 00868 00869 for (int i = d->fieldCacheIdx; i <= field; ++i) { 00870 // some servers do not support fetching column n after we already 00871 // fetched column n+1, so cache all previous columns here 00872 const QSqlField info = d->rInf.field(i); 00873 switch (info.type()) { 00874 case QVariant::LongLong: 00875 d->fieldCache[i] = qGetBigIntData(d->hStmt, i); 00876 break; 00877 case QVariant::Int: 00878 d->fieldCache[i] = qGetIntData(d->hStmt, i); 00879 break; 00880 case QVariant::Date: 00881 DATE_STRUCT dbuf; 00882 r = SQLGetData(d->hStmt, 00883 i + 1, 00884 SQL_C_DATE, 00885 (SQLPOINTER)&dbuf, 00886 0, 00887 &lengthIndicator); 00888 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA)) 00889 d->fieldCache[i] = QVariant(QDate(dbuf.year, dbuf.month, dbuf.day)); 00890 else 00891 d->fieldCache[i] = QVariant(QVariant::Date); 00892 break; 00893 case QVariant::Time: 00894 TIME_STRUCT tbuf; 00895 r = SQLGetData(d->hStmt, 00896 i + 1, 00897 SQL_C_TIME, 00898 (SQLPOINTER)&tbuf, 00899 0, 00900 &lengthIndicator); 00901 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA)) 00902 d->fieldCache[i] = QVariant(QTime(tbuf.hour, tbuf.minute, tbuf.second)); 00903 else 00904 d->fieldCache[i] = QVariant(QVariant::Time); 00905 break; 00906 case QVariant::DateTime: 00907 TIMESTAMP_STRUCT dtbuf; 00908 r = SQLGetData(d->hStmt, 00909 i + 1, 00910 SQL_C_TIMESTAMP, 00911 (SQLPOINTER)&dtbuf, 00912 0, 00913 &lengthIndicator); 00914 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (lengthIndicator != SQL_NULL_DATA)) 00915 d->fieldCache[i] = QVariant(QDateTime(QDate(dtbuf.year, dtbuf.month, dtbuf.day), 00916 QTime(dtbuf.hour, dtbuf.minute, dtbuf.second, dtbuf.fraction / 1000000))); 00917 else 00918 d->fieldCache[i] = QVariant(QVariant::DateTime); 00919 break; 00920 case QVariant::ByteArray: 00921 d->fieldCache[i] = qGetBinaryData(d->hStmt, i); 00922 break; 00923 case QVariant::String: 00924 d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), true); 00925 break; 00926 case QVariant::Double: 00927 if (info.typeID() == SQL_DECIMAL || info.typeID() == SQL_NUMERIC) 00928 // bind Double values as string to prevent loss of precision 00929 d->fieldCache[i] = qGetStringData(d->hStmt, i, 00930 info.length() + 1, false); // length + 1 for the comma 00931 else 00932 d->fieldCache[i] = qGetDoubleData(d->hStmt, i); 00933 break; 00934 default: 00935 d->fieldCache[i] = QVariant(qGetStringData(d->hStmt, i, 00936 info.length(), false)); 00937 break; 00938 } 00939 d->fieldCacheIdx = field + 1; 00940 } 00941 return d->fieldCache[field]; 00942 }
Here is the call graph for this function:

| bool QODBCResult::isNull | ( | int | field | ) | [protected, virtual] |
Returns true if the field at position index in the current row is null; otherwise returns false.
Implements QSqlResult.
Definition at line 944 of file qsql_odbc.cpp.
References QVector< T >::at(), d, data(), QODBCPrivate::fieldCache, QVariant::isNull(), and QVector< T >::size().
00945 { 00946 if (field < 0 || field > d->fieldCache.size()) 00947 return true; 00948 if (field <= d->fieldCacheIdx) { 00949 // since there is no good way to find out whether the value is NULL 00950 // without fetching the field we'll fetch it here. 00951 // (data() also sets the NULL flag) 00952 data(field); 00953 } 00954 return d->fieldCache.at(field).isNull(); 00955 }
Here is the call graph for this function:

| int QODBCResult::size | ( | ) | [protected, virtual] |
Returns the size of the SELECT result, or -1 if it cannot be determined or if the query is not a SELECT statement.
Implements QSqlResult.
Definition at line 957 of file qsql_odbc.cpp.
| int QODBCResult::numRowsAffected | ( | ) | [protected, virtual] |
Returns the number of rows affected by the last query executed, or -1 if it cannot be determined or if the query is a SELECT statement.
Implements QSqlResult.
Definition at line 962 of file qsql_odbc.cpp.
References d, QODBCPrivate::hStmt, QSQLLEN, and qSqlWarning().
00963 { 00964 QSQLLEN affectedRowCount = 0; 00965 SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount); 00966 if (r == SQL_SUCCESS) 00967 return affectedRowCount; 00968 else 00969 qSqlWarning(QLatin1String("QODBCResult::numRowsAffected: Unable to count affected rows"), d); 00970 return -1; 00971 }
Here is the call graph for this function:

| QSqlRecord QODBCResult::record | ( | ) | const [protected, virtual] |
Returns the current record if the query is active; otherwise returns an empty QSqlRecord.
The default implementation always returns an empty QSqlRecord.
Reimplemented from QSqlResult.
Definition at line 1292 of file qsql_odbc.cpp.
References d, QSqlResult::isActive(), QSqlResult::isSelect(), and QODBCPrivate::rInf.
01293 { 01294 if (!isActive() || !isSelect()) 01295 return QSqlRecord(); 01296 return d->rInf; 01297 }
Here is the call graph for this function:

QODBCPrivate* QODBCResult::d [private] |
Reimplemented from QSqlResult.
Definition at line 98 of file qsql_odbc.h.
Referenced by data(), exec(), fetch(), fetchFirst(), fetchLast(), fetchNext(), fetchPrior(), handle(), isNull(), numRowsAffected(), prepare(), QODBCResult(), record(), reset(), and ~QODBCResult().
1.5.1