diff options
Diffstat (limited to 'src/sql/drivers/odbc/qsql_odbc.cpp')
-rw-r--r-- | src/sql/drivers/odbc/qsql_odbc.cpp | 141 |
1 files changed, 93 insertions, 48 deletions
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 8db06e6831..db1e36daa2 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -50,6 +50,7 @@ #include <QDebug> #include <QSqlQuery> #include <QtSql/private/qsqldriver_p.h> +#include <QtSql/private/qsqlresult_p.h> QT_BEGIN_NAMESPACE @@ -106,6 +107,8 @@ inline static QVarLengthArray<SQLTCHAR> toSQLTCHAR(const QString &input) class QODBCDriverPrivate : public QSqlDriverPrivate { + Q_DECLARE_PUBLIC(QODBCDriver) + public: enum DefaultCase{Lower, Mixed, Upper, Sensitive}; QODBCDriverPrivate() @@ -143,23 +146,62 @@ private: QChar quote; }; -class QODBCPrivate +class QODBCResultPrivate; + +class QODBCResult: public QSqlResult +{ + Q_DECLARE_PRIVATE(QODBCResult) + +public: + QODBCResult(const QODBCDriver *db); + virtual ~QODBCResult(); + + bool prepare(const QString &query) Q_DECL_OVERRIDE; + bool exec() Q_DECL_OVERRIDE; + + QVariant lastInsertId() const Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; + +protected: + bool fetchNext() Q_DECL_OVERRIDE; + bool fetchFirst() Q_DECL_OVERRIDE; + bool fetchLast() Q_DECL_OVERRIDE; + bool fetchPrevious() Q_DECL_OVERRIDE; + bool fetch(int i) Q_DECL_OVERRIDE; + bool reset(const QString &query) Q_DECL_OVERRIDE; + QVariant data(int field) Q_DECL_OVERRIDE; + bool isNull(int field) Q_DECL_OVERRIDE; + int size() Q_DECL_OVERRIDE; + int numRowsAffected() Q_DECL_OVERRIDE; + QSqlRecord record() const Q_DECL_OVERRIDE; + void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; + void detachFromResultSet() Q_DECL_OVERRIDE; + bool nextResult() Q_DECL_OVERRIDE; +}; + +class QODBCResultPrivate: public QSqlResultPrivate { + Q_DECLARE_PUBLIC(QODBCResult) + public: - QODBCPrivate(QODBCDriverPrivate *dpp) - : hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false) + Q_DECLARE_SQLDRIVER_PRIVATE(QODBCDriver) + QODBCResultPrivate(QODBCResult *q, const QODBCDriver *db) + : QSqlResultPrivate(q, db), + hStmt(0), + useSchema(false), + hasSQLFetchScroll(true) { - unicode = dpp->unicode; - useSchema = dpp->useSchema; - disconnectCount = dpp->disconnectCount; - hasSQLFetchScroll = dpp->hasSQLFetchScroll; + unicode = drv_d_func()->unicode; + useSchema = drv_d_func()->useSchema; + disconnectCount = drv_d_func()->disconnectCount; + hasSQLFetchScroll = drv_d_func()->hasSQLFetchScroll; } inline void clearValues() { fieldCache.fill(QVariant()); fieldCacheIdx = 0; } - SQLHANDLE dpEnv() const { return driverPrivate ? driverPrivate->hEnv : 0;} - SQLHANDLE dpDbc() const { return driverPrivate ? driverPrivate->hDbc : 0;} + SQLHANDLE dpEnv() const { return drv_d_func() ? drv_d_func()->hEnv : 0;} + SQLHANDLE dpDbc() const { return drv_d_func() ? drv_d_func()->hDbc : 0;} SQLHANDLE hStmt; bool unicode; @@ -170,23 +212,19 @@ public: int fieldCacheIdx; int disconnectCount; bool hasSQLFetchScroll; - QODBCDriverPrivate *driverPrivate; - bool userForwardOnly; - bool isStmtHandleValid(const QSqlDriver *driver); - void updateStmtHandleState(const QSqlDriver *driver); + bool isStmtHandleValid(); + void updateStmtHandleState(); }; -bool QODBCPrivate::isStmtHandleValid(const QSqlDriver *driver) +bool QODBCResultPrivate::isStmtHandleValid() { - const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver); - return disconnectCount == odbcdriver->d_func()->disconnectCount; + return disconnectCount == drv_d_func()->disconnectCount; } -void QODBCPrivate::updateStmtHandleState(const QSqlDriver *driver) +void QODBCResultPrivate::updateStmtHandleState() { - const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver); - disconnectCount = odbcdriver->d_func()->disconnectCount; + disconnectCount = drv_d_func()->disconnectCount; } static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode = 0) @@ -261,7 +299,7 @@ static QString qODBCWarn(const SQLHANDLE hStmt, const SQLHANDLE envHandle = 0, return result; } -static QString qODBCWarn(const QODBCPrivate* odbc, int *nativeCode = 0) +static QString qODBCWarn(const QODBCResultPrivate* odbc, int *nativeCode = 0) { return qODBCWarn(odbc->hStmt, odbc->dpEnv(), odbc->dpDbc(), nativeCode); } @@ -271,7 +309,7 @@ static QString qODBCWarn(const QODBCDriverPrivate* odbc, int *nativeCode = 0) return qODBCWarn(0, odbc->hEnv, odbc->hDbc, nativeCode); } -static void qSqlWarning(const QString& message, const QODBCPrivate* odbc) +static void qSqlWarning(const QString& message, const QODBCResultPrivate* odbc) { qWarning() << message << "\tError:" << qODBCWarn(odbc); } @@ -286,7 +324,7 @@ static void qSqlWarning(const QString &message, const SQLHANDLE hStmt) qWarning() << message << "\tError:" << qODBCWarn(hStmt); } -static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, const QODBCPrivate* p) +static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, const QODBCResultPrivate* p) { int nativeCode = -1; QString message = qODBCWarn(p, &nativeCode); @@ -626,7 +664,7 @@ static QSqlField qMakeFieldInfo(const SQLHANDLE hStmt, const QODBCDriverPrivate* return f; } -static QSqlField qMakeFieldInfo(const QODBCPrivate* p, int i ) +static QSqlField qMakeFieldInfo(const QODBCResultPrivate* p, int i ) { QString errorMessage; const QSqlField result = qMakeFieldInfo(p->hStmt, i, &errorMessage); @@ -911,26 +949,25 @@ QString QODBCDriverPrivate::adjustCase(const QString &identifier) const //////////////////////////////////////////////////////////////////////////// -QODBCResult::QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p) -: QSqlResult(db) +QODBCResult::QODBCResult(const QODBCDriver *db) + : QSqlResult(*new QODBCResultPrivate(this, db)) { - d = new QODBCPrivate(p); } QODBCResult::~QODBCResult() { - if (d->hStmt && d->isStmtHandleValid(driver()) && driver()->isOpen()) { + Q_D(QODBCResult); + if (d->hStmt && d->isStmtHandleValid() && driver()->isOpen()) { SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt); if (r != SQL_SUCCESS) qSqlWarning(QLatin1String("QODBCDriver: Unable to free statement handle ") + QString::number(r), d); } - - delete d; } bool QODBCResult::reset (const QString& query) { + Q_D(QODBCResult); setActive(false); setAt(QSql::BeforeFirstRow); d->rInf.clear(); @@ -940,7 +977,7 @@ bool QODBCResult::reset (const QString& query) // Always reallocate the statement handle - the statement attributes // are not reset if SQLFreeStmt() is called which causes some problems. SQLRETURN r; - if (d->hStmt && d->isStmtHandleValid(driver())) { + if (d->hStmt && d->isStmtHandleValid()) { r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt); if (r != SQL_SUCCESS) { qSqlWarning(QLatin1String("QODBCResult::reset: Unable to free statement handle"), d); @@ -955,9 +992,9 @@ bool QODBCResult::reset (const QString& query) return false; } - d->updateStmtHandleState(driver()); + d->updateStmtHandleState(); - if (d->userForwardOnly) { + if (isForwardOnly()) { r = SQLSetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, @@ -987,7 +1024,7 @@ bool QODBCResult::reset (const QString& query) SQLULEN isScrollable = 0; r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, 0); if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) - QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE); + setForwardOnly(isScrollable == SQL_NONSCROLLABLE); SQLSMALLINT count = 0; SQLNumResultCols(d->hStmt, &count); @@ -1007,6 +1044,7 @@ bool QODBCResult::reset (const QString& query) bool QODBCResult::fetch(int i) { + Q_D(QODBCResult); if (!driver()->isOpen()) return false; @@ -1043,6 +1081,7 @@ bool QODBCResult::fetch(int i) bool QODBCResult::fetchNext() { + Q_D(QODBCResult); SQLRETURN r; d->clearValues(); @@ -1065,6 +1104,7 @@ bool QODBCResult::fetchNext() bool QODBCResult::fetchFirst() { + Q_D(QODBCResult); if (isForwardOnly() && at() != QSql::BeforeFirstRow) return false; SQLRETURN r; @@ -1087,6 +1127,7 @@ bool QODBCResult::fetchFirst() bool QODBCResult::fetchPrevious() { + Q_D(QODBCResult); if (isForwardOnly()) return false; SQLRETURN r; @@ -1106,6 +1147,7 @@ bool QODBCResult::fetchPrevious() bool QODBCResult::fetchLast() { + Q_D(QODBCResult); SQLRETURN r; d->clearValues(); @@ -1145,6 +1187,7 @@ bool QODBCResult::fetchLast() QVariant QODBCResult::data(int field) { + Q_D(QODBCResult); if (field >= d->rInf.count() || field < 0) { qWarning() << "QODBCResult::data: column" << field << "out of range"; return QVariant(); @@ -1245,6 +1288,7 @@ QVariant QODBCResult::data(int field) bool QODBCResult::isNull(int field) { + Q_D(const QODBCResult); if (field < 0 || field > d->fieldCache.size()) return true; if (field <= d->fieldCacheIdx) { @@ -1263,6 +1307,7 @@ int QODBCResult::size() int QODBCResult::numRowsAffected() { + Q_D(QODBCResult); SQLLEN affectedRowCount = 0; SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount); if (r == SQL_SUCCESS) @@ -1274,12 +1319,13 @@ int QODBCResult::numRowsAffected() bool QODBCResult::prepare(const QString& query) { + Q_D(QODBCResult); setActive(false); setAt(QSql::BeforeFirstRow); SQLRETURN r; d->rInf.clear(); - if (d->hStmt && d->isStmtHandleValid(driver())) { + if (d->hStmt && d->isStmtHandleValid()) { r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt); if (r != SQL_SUCCESS) { qSqlWarning(QLatin1String("QODBCResult::prepare: Unable to close statement"), d); @@ -1294,9 +1340,9 @@ bool QODBCResult::prepare(const QString& query) return false; } - d->updateStmtHandleState(driver()); + d->updateStmtHandleState(); - if (d->userForwardOnly) { + if (isForwardOnly()) { r = SQLSetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, @@ -1328,6 +1374,7 @@ bool QODBCResult::prepare(const QString& query) bool QODBCResult::exec() { + Q_D(QODBCResult); setActive(false); setAt(QSql::BeforeFirstRow); d->rInf.clear(); @@ -1408,7 +1455,7 @@ bool QODBCResult::exec() dt->minute = qdt.time().minute(); dt->second = qdt.time().second(); - int precision = d->driverPrivate->datetime_precision - 20; // (20 includes a separating period) + int precision = d->drv_d_func()->datetime_precision - 20; // (20 includes a separating period) if (precision <= 0) { dt->fraction = 0; } else { @@ -1424,7 +1471,7 @@ bool QODBCResult::exec() qParamType[bindValueType(i) & QSql::InOut], SQL_C_TIMESTAMP, SQL_TIMESTAMP, - d->driverPrivate->datetime_precision, + d->drv_d_func()->datetime_precision, precision, (void *) dt, 0, @@ -1608,7 +1655,7 @@ bool QODBCResult::exec() SQLULEN isScrollable = 0; r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, 0); if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) - QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE); + setForwardOnly(isScrollable == SQL_NONSCROLLABLE); SQLSMALLINT count = 0; SQLNumResultCols(d->hStmt, &count); @@ -1677,6 +1724,7 @@ bool QODBCResult::exec() QSqlRecord QODBCResult::record() const { + Q_D(const QODBCResult); if (!isActive() || !isSelect()) return QSqlRecord(); return d->rInf; @@ -1684,9 +1732,10 @@ QSqlRecord QODBCResult::record() const QVariant QODBCResult::lastInsertId() const { + Q_D(const QODBCResult); QString sql; - switch (d->driverPrivate->dbmsType) { + switch (driver()->dbmsType()) { case QSqlDriver::MSSqlServer: case QSqlDriver::Sybase: sql = QLatin1String("SELECT @@IDENTITY;"); @@ -1716,11 +1765,13 @@ QVariant QODBCResult::lastInsertId() const QVariant QODBCResult::handle() const { + Q_D(const QODBCResult); return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt); } bool QODBCResult::nextResult() { + Q_D(QODBCResult); setActive(false); setAt(QSql::BeforeFirstRow); d->rInf.clear(); @@ -1765,16 +1816,11 @@ void QODBCResult::virtual_hook(int id, void *data) void QODBCResult::detachFromResultSet() { + Q_D(QODBCResult); if (d->hStmt) SQLCloseCursor(d->hStmt); } -void QODBCResult::setForwardOnly(bool forward) -{ - d->userForwardOnly = forward; - QSqlResult::setForwardOnly(forward); -} - //////////////////////////////////////// @@ -2185,8 +2231,7 @@ void QODBCDriverPrivate::checkDateTimePrecision() QSqlResult *QODBCDriver::createResult() const { - Q_D(const QODBCDriver); - return new QODBCResult(this, const_cast<QODBCDriverPrivate*>(d)); + return new QODBCResult(this); } bool QODBCDriver::beginTransaction() |