diff options
Diffstat (limited to 'src/sql/drivers')
-rw-r--r-- | src/sql/drivers/db2/qsql_db2.cpp | 85 | ||||
-rw-r--r-- | src/sql/drivers/db2/qsql_db2_p.h | 68 | ||||
-rw-r--r-- | src/sql/drivers/ibase/qsql_ibase.cpp | 72 | ||||
-rw-r--r-- | src/sql/drivers/ibase/qsql_ibase_p.h | 61 | ||||
-rw-r--r-- | src/sql/drivers/mysql/qsql_mysql.cpp | 159 | ||||
-rw-r--r-- | src/sql/drivers/mysql/qsql_mysql_p.h | 39 | ||||
-rw-r--r-- | src/sql/drivers/oci/qsql_oci.cpp | 148 | ||||
-rw-r--r-- | src/sql/drivers/oci/qsql_oci_p.h | 41 | ||||
-rw-r--r-- | src/sql/drivers/odbc/qsql_odbc.cpp | 141 | ||||
-rw-r--r-- | src/sql/drivers/odbc/qsql_odbc_p.h | 76 | ||||
-rw-r--r-- | src/sql/drivers/psql/qsql_psql.cpp | 61 | ||||
-rw-r--r-- | src/sql/drivers/psql/qsql_psql_p.h | 33 | ||||
-rw-r--r-- | src/sql/drivers/sqlite/qsql_sqlite.cpp | 70 | ||||
-rw-r--r-- | src/sql/drivers/sqlite/qsql_sqlite_p.h | 5 | ||||
-rw-r--r-- | src/sql/drivers/sqlite2/qsql_sqlite2.cpp | 68 | ||||
-rw-r--r-- | src/sql/drivers/sqlite2/qsql_sqlite2_p.h | 57 | ||||
-rw-r--r-- | src/sql/drivers/tds/qsql_tds.cpp | 45 | ||||
-rw-r--r-- | src/sql/drivers/tds/qsql_tds_p.h | 39 |
18 files changed, 679 insertions, 589 deletions
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 78b396f423..cc16a68916 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -32,7 +32,6 @@ ****************************************************************************/ #include "qsql_db2_p.h" -#include <QtSql/private/qsqldriver_p.h> #include <qcoreapplication.h> #include <qdatetime.h> #include <qsqlfield.h> @@ -43,6 +42,8 @@ #include <qvarlengtharray.h> #include <qvector.h> #include <QDebug> +#include <QtSql/private/qsqldriver_p.h> +#include <QtSql/private/qsqlresult_p.h> #if defined(Q_CC_BOR) // DB2's sqlsystm.h (included through sqlcli1.h) defines the SQL_BIGINT_TYPE @@ -65,6 +66,8 @@ static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL class QDB2DriverPrivate : public QSqlDriverPrivate { + Q_DECLARE_PUBLIC(QDB2Driver) + public: QDB2DriverPrivate() : QSqlDriverPrivate(), hEnv(0), hDbc(0) { dbmsType = QSqlDriver::DB2; } SQLHANDLE hEnv; @@ -72,10 +75,44 @@ public: QString user; }; -class QDB2ResultPrivate +class QDB2ResultPrivate; + +class QDB2Result: public QSqlResult { + Q_DECLARE_PRIVATE(QDB2Result) + public: - QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0) + QDB2Result(const QDB2Driver *drv); + ~QDB2Result(); + bool prepare(const QString &query) Q_DECL_OVERRIDE; + bool exec() Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; + +protected: + QVariant data(int field) Q_DECL_OVERRIDE; + bool reset(const QString &query) Q_DECL_OVERRIDE; + bool fetch(int i) Q_DECL_OVERRIDE; + bool fetchNext() Q_DECL_OVERRIDE; + bool fetchFirst() Q_DECL_OVERRIDE; + bool fetchLast() Q_DECL_OVERRIDE; + bool isNull(int i) 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 QDB2ResultPrivate: public QSqlResultPrivate +{ + Q_DECLARE_PUBLIC(QDB2Result) + +public: + Q_DECLARE_SQLDRIVER_PRIVATE(QDB2Driver) + QDB2ResultPrivate(QDB2Result *q, const QDB2Driver *drv) + : QSqlResultPrivate(q, drv), + hStmt(0) {} ~QDB2ResultPrivate() { @@ -94,7 +131,6 @@ public: valueCache.clear(); } - const QDB2DriverPrivate* dp; SQLHANDLE hStmt; QSqlRecord recInf; QVector<QVariant*> valueCache; @@ -140,8 +176,8 @@ static QString qDB2Warn(const QDB2DriverPrivate* d) static QString qDB2Warn(const QDB2ResultPrivate* d) { - return (qWarnDB2Handle(SQL_HANDLE_ENV, d->dp->hEnv) + QLatin1Char(' ') - + qWarnDB2Handle(SQL_HANDLE_DBC, d->dp->hDbc) + return (qWarnDB2Handle(SQL_HANDLE_ENV, d->drv_d_func()->hEnv) + QLatin1Char(' ') + + qWarnDB2Handle(SQL_HANDLE_DBC, d->drv_d_func()->hDbc) + qWarnDB2Handle(SQL_HANDLE_STMT, d->hStmt)); } @@ -466,7 +502,7 @@ static bool qMakeStatement(QDB2ResultPrivate* d, bool forwardOnly, bool setForwa SQLRETURN r; if (!d->hStmt) { r = SQLAllocHandle(SQL_HANDLE_STMT, - d->dp->hDbc, + d->drv_d_func()->hDbc, &d->hStmt); if (r != SQL_SUCCESS) { qSqlWarning(QLatin1String("QDB2Result::reset: Unable to allocate statement handle"), d); @@ -505,30 +541,31 @@ static bool qMakeStatement(QDB2ResultPrivate* d, bool forwardOnly, bool setForwa QVariant QDB2Result::handle() const { + Q_D(const QDB2Result); return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt); } /************************************/ -QDB2Result::QDB2Result(const QDB2Driver* dr, const QDB2DriverPrivate* dp) - : QSqlResult(dr) +QDB2Result::QDB2Result(const QDB2Driver *drv) + : QSqlResult(*new QDB2ResultPrivate(this, drv)) { - d = new QDB2ResultPrivate(dp); } QDB2Result::~QDB2Result() { + Q_D(const QDB2Result); if (d->hStmt) { SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt); if (r != SQL_SUCCESS) qSqlWarning(QLatin1String("QDB2Driver: Unable to free statement handle ") + QString::number(r), d); } - delete d; } bool QDB2Result::reset (const QString& query) { + Q_D(QDB2Result); setActive(false); setAt(QSql::BeforeFirstRow); SQLRETURN r; @@ -565,6 +602,7 @@ bool QDB2Result::reset (const QString& query) bool QDB2Result::prepare(const QString& query) { + Q_D(QDB2Result); setActive(false); setAt(QSql::BeforeFirstRow); SQLRETURN r; @@ -589,6 +627,7 @@ bool QDB2Result::prepare(const QString& query) bool QDB2Result::exec() { + Q_D(QDB2Result); QList<QByteArray> tmpStorage; // holds temporary ptrs QVarLengthArray<SQLINTEGER, 32> indicators(boundValues().count()); @@ -840,6 +879,7 @@ bool QDB2Result::exec() bool QDB2Result::fetch(int i) { + Q_D(QDB2Result); if (isForwardOnly() && i < at()) return false; if (i == at()) @@ -874,6 +914,7 @@ bool QDB2Result::fetch(int i) bool QDB2Result::fetchNext() { + Q_D(QDB2Result); SQLRETURN r; d->clearValueCache(); r = SQLFetchScroll(d->hStmt, @@ -891,6 +932,7 @@ bool QDB2Result::fetchNext() bool QDB2Result::fetchFirst() { + Q_D(QDB2Result); if (isForwardOnly() && at() != QSql::BeforeFirstRow) return false; if (isForwardOnly()) @@ -912,6 +954,7 @@ bool QDB2Result::fetchFirst() bool QDB2Result::fetchLast() { + Q_D(QDB2Result); d->clearValueCache(); int i = at(); @@ -943,6 +986,7 @@ bool QDB2Result::fetchLast() QVariant QDB2Result::data(int field) { + Q_D(QDB2Result); if (field >= d->recInf.count()) { qWarning("QDB2Result::data: column %d out of range", field); return QVariant(); @@ -1049,6 +1093,7 @@ QVariant QDB2Result::data(int field) bool QDB2Result::isNull(int i) { + Q_D(const QDB2Result); if (i >= d->valueCache.size()) return true; @@ -1059,6 +1104,7 @@ bool QDB2Result::isNull(int i) int QDB2Result::numRowsAffected() { + Q_D(const QDB2Result); SQLINTEGER affectedRowCount = 0; SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) @@ -1075,6 +1121,7 @@ int QDB2Result::size() QSqlRecord QDB2Result::record() const { + Q_D(const QDB2Result); if (isActive()) return d->recInf; return QSqlRecord(); @@ -1082,6 +1129,7 @@ QSqlRecord QDB2Result::record() const bool QDB2Result::nextResult() { + Q_D(QDB2Result); setActive(false); setAt(QSql::BeforeFirstRow); d->recInf.clear(); @@ -1117,6 +1165,7 @@ void QDB2Result::virtual_hook(int id, void *data) void QDB2Result::detachFromResultSet() { + Q_D(QDB2Result); if (d->hStmt) SQLCloseCursor(d->hStmt); } @@ -1132,8 +1181,8 @@ QDB2Driver::QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent) : QSqlDriver(*new QDB2DriverPrivate, parent) { Q_D(QDB2Driver); - d->hEnv = (SQLHANDLE)env; - d->hDbc = (SQLHANDLE)con; + d->hEnv = reinterpret_cast<intptr_t>(env); + d->hDbc = reinterpret_cast<intptr_t>(con); if (env && con) { setOpen(true); setOpenError(false); @@ -1197,10 +1246,10 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas tmp.toLocal8Bit().constData()); continue; } - r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_ACCESS_MODE, (SQLPOINTER) v, 0); + r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_ACCESS_MODE, reinterpret_cast<SQLPOINTER>(v), 0); } else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) { v = val.toUInt(); - r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0); + r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, reinterpret_cast<SQLPOINTER>(v), 0); } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) { protocol = tmp; } @@ -1278,8 +1327,7 @@ void QDB2Driver::close() QSqlResult *QDB2Driver::createResult() const { - Q_D(const QDB2Driver); - return new QDB2Result(this, d); + return new QDB2Result(this); } QSqlRecord QDB2Driver::record(const QString& tableName) const @@ -1506,6 +1554,7 @@ bool QDB2Driver::hasFeature(DriverFeature f) const case LastInsertId: case SimpleLocking: case EventNotifications: + case CancelQuery: return false; case BLOB: case Transactions: @@ -1572,7 +1621,7 @@ bool QDB2Driver::setAutoCommit(bool autoCommit) SQLUINTEGER ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF; SQLRETURN r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_AUTOCOMMIT, - (SQLPOINTER)ac, + reinterpret_cast<SQLPOINTER>(ac), sizeof(ac)); if (r != SQL_SUCCESS) { setLastError(qMakeError(tr("Unable to set autocommit"), diff --git a/src/sql/drivers/db2/qsql_db2_p.h b/src/sql/drivers/db2/qsql_db2_p.h index 7b5d751b89..0b07456122 100644 --- a/src/sql/drivers/db2/qsql_db2_p.h +++ b/src/sql/drivers/db2/qsql_db2_p.h @@ -53,70 +53,40 @@ #define Q_EXPORT_SQLDRIVER_DB2 Q_SQL_EXPORT #endif -#include <QtSql/qsqlresult.h> #include <QtSql/qsqldriver.h> QT_BEGIN_NAMESPACE -class QDB2Driver; class QDB2DriverPrivate; -class QDB2ResultPrivate; -class QSqlRecord; - -class QDB2Result : public QSqlResult -{ -public: - QDB2Result(const QDB2Driver* dr, const QDB2DriverPrivate* dp); - ~QDB2Result(); - bool prepare(const QString& query); - bool exec(); - QVariant handle() const; - -protected: - QVariant data(int field); - bool reset (const QString& query); - bool fetch(int i); - bool fetchNext(); - bool fetchFirst(); - bool fetchLast(); - bool isNull(int i); - int size(); - int numRowsAffected(); - QSqlRecord record() const; - void virtual_hook(int id, void *data); - void detachFromResultSet(); - bool nextResult(); - -private: - QDB2ResultPrivate* d; -}; class Q_EXPORT_SQLDRIVER_DB2 QDB2Driver : public QSqlDriver { Q_DECLARE_PRIVATE(QDB2Driver) Q_OBJECT + friend class QDB2ResultPrivate; + public: explicit QDB2Driver(QObject* parent = 0); QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent = 0); ~QDB2Driver(); - bool hasFeature(DriverFeature) const; - void close(); - QSqlRecord record(const QString& tableName) const; - QStringList tables(QSql::TableType type) const; - QSqlResult *createResult() const; - QSqlIndex primaryIndex(const QString& tablename) const; - bool beginTransaction(); - bool commitTransaction(); - bool rollbackTransaction(); - QString formatValue(const QSqlField &field, bool trimStrings) const; - QVariant handle() const; - bool open(const QString& db, - const QString& user, - const QString& password, - const QString& host, + bool hasFeature(DriverFeature) const Q_DECL_OVERRIDE; + void close() Q_DECL_OVERRIDE; + QSqlRecord record(const QString &tableName) const Q_DECL_OVERRIDE; + QStringList tables(QSql::TableType type) const Q_DECL_OVERRIDE; + QSqlResult *createResult() const Q_DECL_OVERRIDE; + QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE; + bool beginTransaction() Q_DECL_OVERRIDE; + bool commitTransaction() Q_DECL_OVERRIDE; + bool rollbackTransaction() Q_DECL_OVERRIDE; + QString formatValue(const QSqlField &field, bool trimStrings) const Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; + bool open(const QString &db, + const QString &user, + const QString &password, + const QString &host, int port, - const QString& connOpts); - QString escapeIdentifier(const QString &identifier, IdentifierType type) const; + const QString& connOpts) Q_DECL_OVERRIDE; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; private: bool setAutoCommit(bool autoCommit); diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index d68ac276ef..c45415b56b 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -345,36 +345,37 @@ class QIBaseResultPrivate; class QIBaseResult : public QSqlCachedResult { - friend class QIBaseResultPrivate; + Q_DECLARE_PRIVATE(QIBaseResult) public: explicit QIBaseResult(const QIBaseDriver* db); - virtual ~QIBaseResult(); - bool prepare(const QString& query); - bool exec(); - QVariant handle() const; + bool prepare(const QString &query) Q_DECL_OVERRIDE; + bool exec() Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; protected: - bool gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx); - bool reset (const QString& query); - int size(); - int numRowsAffected(); - QSqlRecord record() const; - -private: - QIBaseResultPrivate* d; + bool gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) Q_DECL_OVERRIDE; + bool reset (const QString &query) Q_DECL_OVERRIDE; + int size() Q_DECL_OVERRIDE; + int numRowsAffected() Q_DECL_OVERRIDE; + QSqlRecord record() const Q_DECL_OVERRIDE; }; -class QIBaseResultPrivate +class QIBaseResultPrivate: public QSqlCachedResultPrivate { + Q_DECLARE_PUBLIC(QIBaseResult) + public: - QIBaseResultPrivate(QIBaseResult *d, const QIBaseDriver *ddb); + Q_DECLARE_SQLDRIVER_PRIVATE(QIBaseDriver) + + QIBaseResultPrivate(QIBaseResult *q, const QIBaseDriver *drv); ~QIBaseResultPrivate() { cleanup(); } void cleanup(); bool isError(const char *msg, QSqlError::ErrorType typ = QSqlError::UnknownError) { + Q_Q(QIBaseResult); QString imsg; ISC_LONG sqlcode; if (!getIBaseError(imsg, status, sqlcode, tc)) @@ -395,8 +396,6 @@ public: bool writeArray(int i, const QList<QVariant> &list); public: - QIBaseResult *q; - const QIBaseDriver *db; ISC_STATUS status[20]; isc_tr_handle trans; //indicator whether we have a local transaction or a transaction on driver level @@ -410,14 +409,22 @@ public: }; -QIBaseResultPrivate::QIBaseResultPrivate(QIBaseResult *d, const QIBaseDriver *ddb): - q(d), db(ddb), trans(0), stmt(0), ibase(ddb->d_func()->ibase), sqlda(0), inda(0), queryType(-1), tc(ddb->d_func()->tc) +QIBaseResultPrivate::QIBaseResultPrivate(QIBaseResult *q, const QIBaseDriver *drv) + : QSqlCachedResultPrivate(q, drv), + trans(0), + localTransaction(!drv_d_func()->ibase), + stmt(0), + ibase(drv_d_func()->ibase), + sqlda(0), + inda(0), + queryType(-1), + tc(drv_d_func()->tc) { - localTransaction = (ddb->d_func()->ibase == 0); } void QIBaseResultPrivate::cleanup() { + Q_Q(QIBaseResult); commit(); if (!localTransaction) trans = 0; @@ -779,6 +786,7 @@ static char* createArrayBuffer(char *buffer, const QList<QVariant> &list, bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list) { + Q_Q(QIBaseResult); QString error; ISC_QUAD *arrayId = (ISC_QUAD*) inda->sqlvar[column].sqldata; ISC_ARRAY_DESC desc; @@ -854,9 +862,9 @@ bool QIBaseResultPrivate::transaction() { if (trans) return true; - if (db->d_func()->trans) { + if (drv_d_func()->trans) { localTransaction = false; - trans = db->d_func()->trans; + trans = drv_d_func()->trans; return true; } localTransaction = true; @@ -887,19 +895,14 @@ bool QIBaseResultPrivate::commit() ////////// -QIBaseResult::QIBaseResult(const QIBaseDriver* db): - QSqlCachedResult(db) -{ - d = new QIBaseResultPrivate(this, db); -} - -QIBaseResult::~QIBaseResult() +QIBaseResult::QIBaseResult(const QIBaseDriver *db) + : QSqlCachedResult(*new QIBaseResultPrivate(this, db)) { - delete d; } bool QIBaseResult::prepare(const QString& query) { + Q_D(QIBaseResult); // qDebug("prepare: %s", qPrintable(query)); if (!driver() || !driver()->isOpen() || driver()->isOpenError()) return false; @@ -976,6 +979,7 @@ bool QIBaseResult::prepare(const QString& query) bool QIBaseResult::exec() { + Q_D(QIBaseResult); bool ok = true; if (!d->trans) @@ -1113,6 +1117,7 @@ bool QIBaseResult::reset (const QString& query) bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) { + Q_D(QIBaseResult); ISC_STATUS stat = 0; // Stored Procedures are special - they populate our d->sqlda when executing, @@ -1307,6 +1312,7 @@ int QIBaseResult::size() int QIBaseResult::numRowsAffected() { + Q_D(QIBaseResult); static char acCountInfo[] = {isc_info_sql_records}; char cCountType; bool bIsProcedure = false; @@ -1361,6 +1367,7 @@ int QIBaseResult::numRowsAffected() QSqlRecord QIBaseResult::record() const { + Q_D(const QIBaseResult); QSqlRecord rec; if (!isActive() || !d->sqlda) return rec; @@ -1374,7 +1381,7 @@ QSqlRecord QIBaseResult::record() const f.setPrecision(qAbs(v.sqlscale)); f.setRequiredStatus((v.sqltype & 1) == 0 ? QSqlField::Required : QSqlField::Optional); if(v.sqlscale < 0) { - QSqlQuery q(new QIBaseResult(d->db)); + QSqlQuery q(driver()->createResult()); q.setForwardOnly(true); q.exec(QLatin1String("select b.RDB$FIELD_PRECISION, b.RDB$FIELD_SCALE, b.RDB$FIELD_LENGTH, a.RDB$NULL_FLAG " "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b " @@ -1400,6 +1407,7 @@ QSqlRecord QIBaseResult::record() const QVariant QIBaseResult::handle() const { + Q_D(const QIBaseResult); return QVariant(qRegisterMetaType<isc_stmt_handle>("isc_stmt_handle"), &d->stmt); } @@ -1910,7 +1918,7 @@ void QIBaseDriver::qHandleEventNotification(void *updatedResultBuffer) (isc_callback)qEventCallback, #endif eBuffer->resultBuffer); - if (status[0] == 1 && status[1]) { + if (Q_UNLIKELY(status[0] == 1 && status[1])) { qCritical("QIBaseDriver::qHandleEventNotification: could not resubscribe to '%s'", qPrintable(i.key())); } diff --git a/src/sql/drivers/ibase/qsql_ibase_p.h b/src/sql/drivers/ibase/qsql_ibase_p.h index 3a61f3394b..e052e83641 100644 --- a/src/sql/drivers/ibase/qsql_ibase_p.h +++ b/src/sql/drivers/ibase/qsql_ibase_p.h @@ -45,16 +45,21 @@ // We mean it. // -#include <QtSql/qsqlresult.h> #include <QtSql/qsqldriver.h> #include <ibase.h> +#ifdef QT_PLUGIN +#define Q_EXPORT_SQLDRIVER_IBASE +#else +#define Q_EXPORT_SQLDRIVER_IBASE Q_SQL_EXPORT +#endif + QT_BEGIN_NAMESPACE +class QSqlResult; class QIBaseDriverPrivate; -class QIBaseDriver; -class QIBaseDriver : public QSqlDriver +class Q_EXPORT_SQLDRIVER_IBASE QIBaseDriver : public QSqlDriver { friend class QIBaseResultPrivate; Q_DECLARE_PRIVATE(QIBaseDriver) @@ -63,36 +68,36 @@ public: explicit QIBaseDriver(QObject *parent = 0); explicit QIBaseDriver(isc_db_handle connection, QObject *parent = 0); virtual ~QIBaseDriver(); - bool hasFeature(DriverFeature f) const; - bool open(const QString & db, - const QString & user, - const QString & password, - const QString & host, + bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool open(const QString &db, + const QString &user, + const QString &password, + const QString &host, int port, - const QString & connOpts); - bool open(const QString & db, - const QString & user, - const QString & password, - const QString & host, - int port) { return open (db, user, password, host, port, QString()); } - void close(); - QSqlResult *createResult() const; - bool beginTransaction(); - bool commitTransaction(); - bool rollbackTransaction(); - QStringList tables(QSql::TableType) const; + const QString &connOpts) Q_DECL_OVERRIDE; + bool open(const QString &db, + const QString &user, + const QString &password, + const QString &host, + int port) { return open(db, user, password, host, port, QString()); } + void close() Q_DECL_OVERRIDE; + QSqlResult *createResult() const Q_DECL_OVERRIDE; + bool beginTransaction() Q_DECL_OVERRIDE; + bool commitTransaction() Q_DECL_OVERRIDE; + bool rollbackTransaction() Q_DECL_OVERRIDE; + QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; - QSqlRecord record(const QString& tablename) const; - QSqlIndex primaryIndex(const QString &table) const; + QSqlRecord record(const QString& tablename) const Q_DECL_OVERRIDE; + QSqlIndex primaryIndex(const QString &table) const Q_DECL_OVERRIDE; - QString formatValue(const QSqlField &field, bool trimStrings) const; - QVariant handle() const; + QString formatValue(const QSqlField &field, bool trimStrings) const Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; - bool subscribeToNotification(const QString &name); - bool unsubscribeFromNotification(const QString &name); - QStringList subscribedToNotifications() const; + bool subscribeToNotification(const QString &name) Q_DECL_OVERRIDE; + bool unsubscribeFromNotification(const QString &name) Q_DECL_OVERRIDE; + QStringList subscribedToNotifications() const Q_DECL_OVERRIDE; private Q_SLOTS: void qHandleEventNotification(void* updatedResultBuffer); diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 96bdcc42fa..99f351a2bb 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -33,7 +33,6 @@ #include "qsql_mysql_p.h" -#include <QtSql/private/qsqldriver_p.h> #include <qcoreapplication.h> #include <qvariant.h> #include <qdatetime.h> @@ -46,8 +45,9 @@ #include <qtextcodec.h> #include <qvector.h> #include <qfile.h> - #include <qdebug.h> +#include <QtSql/private/qsqldriver_p.h> +#include <QtSql/private/qsqlresult_p.h> #ifdef Q_OS_WIN32 // comment the next line out if you want to use MySQL/embedded on Win32 systems. @@ -72,6 +72,8 @@ QT_BEGIN_NAMESPACE class QMYSQLDriverPrivate : public QSqlDriverPrivate { + Q_DECLARE_PUBLIC(QMYSQLDriver) + public: QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0), #ifndef QT_NO_TEXTCODEC @@ -156,24 +158,60 @@ static inline QVariant qDateTimeFromString(QString &val) #endif } -class QMYSQLResultPrivate : public QObject +class QMYSQLResultPrivate; + +class QMYSQLResult : public QSqlResult { - Q_OBJECT + Q_DECLARE_PRIVATE(QMYSQLResult) + friend class QMYSQLDriver; + public: - QMYSQLResultPrivate(const QMYSQLDriver* dp, const QMYSQLResult* d) : driver(dp), result(0), q(d), - rowsAffected(0), hasBlobs(false) + explicit QMYSQLResult(const QMYSQLDriver *db); + ~QMYSQLResult(); + + QVariant handle() const Q_DECL_OVERRIDE; +protected: + void cleanup(); + bool fetch(int i) Q_DECL_OVERRIDE; + bool fetchNext() Q_DECL_OVERRIDE; + bool fetchLast() Q_DECL_OVERRIDE; + bool fetchFirst() Q_DECL_OVERRIDE; + QVariant data(int field) Q_DECL_OVERRIDE; + bool isNull(int field) Q_DECL_OVERRIDE; + bool reset (const QString& query) Q_DECL_OVERRIDE; + int size() Q_DECL_OVERRIDE; + int numRowsAffected() Q_DECL_OVERRIDE; + QVariant lastInsertId() const Q_DECL_OVERRIDE; + QSqlRecord record() const Q_DECL_OVERRIDE; + void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; + bool nextResult() Q_DECL_OVERRIDE; + +#if MYSQL_VERSION_ID >= 40108 + bool prepare(const QString &stmt) Q_DECL_OVERRIDE; + bool exec() Q_DECL_OVERRIDE; +#endif +}; + +class QMYSQLResultPrivate: public QSqlResultPrivate +{ + Q_DECLARE_PUBLIC(QMYSQLResult) + +public: + Q_DECLARE_SQLDRIVER_PRIVATE(QMYSQLDriver) + + QMYSQLResultPrivate(QMYSQLResult *q, const QMYSQLDriver *drv) + : QSqlResultPrivate(q, drv), + result(0), + rowsAffected(0), + hasBlobs(false) #if MYSQL_VERSION_ID >= 40108 , stmt(0), meta(0), inBinds(0), outBinds(0) #endif , preparedQuery(false) - { - connect(dp, SIGNAL(destroyed()), this, SLOT(driverDestroyed())); - } + { } - const QMYSQLDriver* driver; MYSQL_RES *result; MYSQL_ROW row; - const QMYSQLResult* q; int rowsAffected; @@ -205,9 +243,6 @@ public: #endif bool preparedQuery; - -private Q_SLOTS: - void driverDestroyed() { driver = NULL; } }; #ifndef QT_NO_TEXTCODEC @@ -396,19 +431,18 @@ bool QMYSQLResultPrivate::bindInValues() #endif QMYSQLResult::QMYSQLResult(const QMYSQLDriver* db) -: QSqlResult(db) + : QSqlResult(*new QMYSQLResultPrivate(this, db)) { - d = new QMYSQLResultPrivate(db, this); } QMYSQLResult::~QMYSQLResult() { cleanup(); - delete d; } QVariant QMYSQLResult::handle() const { + Q_D(const QMYSQLResult); #if MYSQL_VERSION_ID >= 40108 if(d->preparedQuery) return d->meta ? QVariant::fromValue(d->meta) : QVariant::fromValue(d->stmt); @@ -419,14 +453,15 @@ QVariant QMYSQLResult::handle() const void QMYSQLResult::cleanup() { + Q_D(QMYSQLResult); if (d->result) mysql_free_result(d->result); // must iterate trough leftover result sets from multi-selects or stored procedures // if this isn't done subsequent queries will fail with "Commands out of sync" #if MYSQL_VERSION_ID >= 40100 - while (d->driver && d->driver->d_func()->mysql && mysql_next_result(d->driver->d_func()->mysql) == 0) { - MYSQL_RES *res = mysql_store_result(d->driver->d_func()->mysql); + while (driver() && d->drv_d_func()->mysql && mysql_next_result(d->drv_d_func()->mysql) == 0) { + MYSQL_RES *res = mysql_store_result(d->drv_d_func()->mysql); if (res) mysql_free_result(res); } @@ -469,7 +504,8 @@ void QMYSQLResult::cleanup() bool QMYSQLResult::fetch(int i) { - if(!d->driver) + Q_D(QMYSQLResult); + if (!driver()) return false; if (isForwardOnly()) { // fake a forward seek if (at() < i) { @@ -513,7 +549,8 @@ bool QMYSQLResult::fetch(int i) bool QMYSQLResult::fetchNext() { - if(!d->driver) + Q_D(QMYSQLResult); + if (!driver()) return false; if (d->preparedQuery) { #if MYSQL_VERSION_ID >= 40108 @@ -542,7 +579,8 @@ bool QMYSQLResult::fetchNext() bool QMYSQLResult::fetchLast() { - if(!d->driver) + Q_D(QMYSQLResult); + if (!driver()) return false; if (isForwardOnly()) { // fake this since MySQL can't seek on forward only queries bool success = fetchNext(); // did we move at all? @@ -579,13 +617,13 @@ bool QMYSQLResult::fetchFirst() QVariant QMYSQLResult::data(int field) { - + Q_D(QMYSQLResult); if (!isSelect() || field >= d->fields.count()) { qWarning("QMYSQLResult::data: column %d out of range", field); return QVariant(); } - if (!d->driver) + if (!driver()) return QVariant(); int fieldLength = 0; @@ -599,7 +637,7 @@ QVariant QMYSQLResult::data(int field) return QVariant(f.type, f.outField); if (f.type != QVariant::ByteArray) - val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength); + val = toUnicode(d->drv_d_func()->tc, f.outField, f.bufLength); } else { if (d->row[field] == NULL) { // NULL value @@ -609,7 +647,7 @@ QVariant QMYSQLResult::data(int field) fieldLength = mysql_fetch_lengths(d->result)[field]; if (f.type != QVariant::ByteArray) - val = toUnicode(d->driver->d_func()->tc, d->row[field], fieldLength); + val = toUnicode(d->drv_d_func()->tc, d->row[field], fieldLength); } switch (static_cast<int>(f.type)) { @@ -677,6 +715,7 @@ QVariant QMYSQLResult::data(int field) bool QMYSQLResult::isNull(int field) { + Q_D(const QMYSQLResult); if (field < 0 || field >= d->fields.count()) return true; if (d->preparedQuery) @@ -687,29 +726,30 @@ bool QMYSQLResult::isNull(int field) bool QMYSQLResult::reset (const QString& query) { - if (!driver() || !driver()->isOpen() || driver()->isOpenError() || !d->driver) + Q_D(QMYSQLResult); + if (!driver() || !driver()->isOpen() || driver()->isOpenError()) return false; d->preparedQuery = false; cleanup(); - const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query)); - if (mysql_real_query(d->driver->d_func()->mysql, encQuery.data(), encQuery.length())) { + const QByteArray encQuery(fromUnicode(d->drv_d_func()->tc, query)); + if (mysql_real_query(d->drv_d_func()->mysql, encQuery.data(), encQuery.length())) { setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute query"), - QSqlError::StatementError, d->driver->d_func())); + QSqlError::StatementError, d->drv_d_func())); return false; } - d->result = mysql_store_result(d->driver->d_func()->mysql); - if (!d->result && mysql_field_count(d->driver->d_func()->mysql) > 0) { + d->result = mysql_store_result(d->drv_d_func()->mysql); + if (!d->result && mysql_field_count(d->drv_d_func()->mysql) > 0) { setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store result"), - QSqlError::StatementError, d->driver->d_func())); + QSqlError::StatementError, d->drv_d_func())); return false; } - int numFields = mysql_field_count(d->driver->d_func()->mysql); + int numFields = mysql_field_count(d->drv_d_func()->mysql); setSelect(numFields != 0); d->fields.resize(numFields); - d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql); + d->rowsAffected = mysql_affected_rows(d->drv_d_func()->mysql); if (isSelect()) { for(int i = 0; i < numFields; i++) { @@ -724,7 +764,8 @@ bool QMYSQLResult::reset (const QString& query) int QMYSQLResult::size() { - if (d->driver && isSelect()) + Q_D(const QMYSQLResult); + if (driver() && isSelect()) if (d->preparedQuery) #if MYSQL_VERSION_ID >= 40108 return mysql_stmt_num_rows(d->stmt); @@ -739,12 +780,14 @@ int QMYSQLResult::size() int QMYSQLResult::numRowsAffected() { + Q_D(const QMYSQLResult); return d->rowsAffected; } QVariant QMYSQLResult::lastInsertId() const { - if (!isActive() || !d->driver) + Q_D(const QMYSQLResult); + if (!isActive() || !driver()) return QVariant(); if (d->preparedQuery) { @@ -754,7 +797,7 @@ QVariant QMYSQLResult::lastInsertId() const return QVariant(id); #endif } else { - quint64 id = mysql_insert_id(d->driver->d_func()->mysql); + quint64 id = mysql_insert_id(d->drv_d_func()->mysql); if (id) return QVariant(id); } @@ -763,9 +806,10 @@ QVariant QMYSQLResult::lastInsertId() const QSqlRecord QMYSQLResult::record() const { + Q_D(const QMYSQLResult); QSqlRecord info; MYSQL_RES *res; - if (!isActive() || !isSelect() || !d->driver) + if (!isActive() || !isSelect() || !driver()) return info; #if MYSQL_VERSION_ID >= 40108 @@ -774,11 +818,11 @@ QSqlRecord QMYSQLResult::record() const res = d->result; #endif - if (!mysql_errno(d->driver->d_func()->mysql)) { + if (!mysql_errno(d->drv_d_func()->mysql)) { mysql_field_seek(res, 0); MYSQL_FIELD* field = mysql_fetch_field(res); while(field) { - info.append(qToField(field, d->driver->d_func()->tc)); + info.append(qToField(field, d->drv_d_func()->tc)); field = mysql_fetch_field(res); } } @@ -788,7 +832,8 @@ QSqlRecord QMYSQLResult::record() const bool QMYSQLResult::nextResult() { - if(!d->driver) + Q_D(QMYSQLResult); + if (!driver()) return false; #if MYSQL_VERSION_ID >= 40100 setAt(-1); @@ -803,26 +848,26 @@ bool QMYSQLResult::nextResult() delete[] d->fields[i].outField; d->fields.clear(); - int status = mysql_next_result(d->driver->d_func()->mysql); + int status = mysql_next_result(d->drv_d_func()->mysql); if (status > 0) { setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute next query"), - QSqlError::StatementError, d->driver->d_func())); + QSqlError::StatementError, d->drv_d_func())); return false; } else if (status == -1) { return false; // No more result sets } - d->result = mysql_store_result(d->driver->d_func()->mysql); - int numFields = mysql_field_count(d->driver->d_func()->mysql); + d->result = mysql_store_result(d->drv_d_func()->mysql); + int numFields = mysql_field_count(d->drv_d_func()->mysql); if (!d->result && numFields > 0) { setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store next result"), - QSqlError::StatementError, d->driver->d_func())); + QSqlError::StatementError, d->drv_d_func())); return false; } setSelect(numFields > 0); d->fields.resize(numFields); - d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql); + d->rowsAffected = mysql_affected_rows(d->drv_d_func()->mysql); if (isSelect()) { for (int i = 0; i < numFields; i++) { @@ -871,11 +916,12 @@ static MYSQL_TIME *toMySqlDate(QDate date, QTime time, QVariant::Type type) bool QMYSQLResult::prepare(const QString& query) { - if(!d->driver) + Q_D(QMYSQLResult); + if (!driver()) return false; #if MYSQL_VERSION_ID >= 40108 cleanup(); - if (!d->driver->d_func()->preparedQuerysEnabled) + if (!d->drv_d_func()->preparedQuerysEnabled) return QSqlResult::prepare(query); int r; @@ -884,14 +930,14 @@ bool QMYSQLResult::prepare(const QString& query) return false; if (!d->stmt) - d->stmt = mysql_stmt_init(d->driver->d_func()->mysql); + d->stmt = mysql_stmt_init(d->drv_d_func()->mysql); if (!d->stmt) { setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"), - QSqlError::StatementError, d->driver->d_func())); + QSqlError::StatementError, d->drv_d_func())); return false; } - const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query)); + const QByteArray encQuery(fromUnicode(d->drv_d_func()->tc, query)); r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length()); if (r != 0) { setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", @@ -914,7 +960,8 @@ bool QMYSQLResult::prepare(const QString& query) bool QMYSQLResult::exec() { - if (!d->driver) + Q_D(QMYSQLResult); + if (!driver()) return false; if (!d->preparedQuery) return QSqlResult::exec(); @@ -1011,7 +1058,7 @@ bool QMYSQLResult::exec() break; case QVariant::String: default: { - QByteArray ba = fromUnicode(d->driver->d_func()->tc, val.toString()); + QByteArray ba = fromUnicode(d->drv_d_func()->tc, val.toString()); stringVector.append(ba); currBind->buffer_type = MYSQL_TYPE_STRING; currBind->buffer = const_cast<char *>(ba.constData()); @@ -1610,5 +1657,3 @@ bool QMYSQLDriver::isIdentifierEscaped(const QString &identifier, IdentifierType } QT_END_NAMESPACE - -#include "qsql_mysql.moc" diff --git a/src/sql/drivers/mysql/qsql_mysql_p.h b/src/sql/drivers/mysql/qsql_mysql_p.h index 724cc1fd28..d8e08b1f17 100644 --- a/src/sql/drivers/mysql/qsql_mysql_p.h +++ b/src/sql/drivers/mysql/qsql_mysql_p.h @@ -46,7 +46,6 @@ // #include <QtSql/qsqldriver.h> -#include <QtSql/qsqlresult.h> #if defined (Q_OS_WIN32) #include <QtCore/qt_windows.h> @@ -63,46 +62,10 @@ QT_BEGIN_NAMESPACE class QMYSQLDriverPrivate; -class QMYSQLResultPrivate; -class QMYSQLDriver; -class QSqlRecordInfo; - -class QMYSQLResult : public QSqlResult -{ - friend class QMYSQLDriver; - friend class QMYSQLResultPrivate; -public: - explicit QMYSQLResult(const QMYSQLDriver* db); - ~QMYSQLResult(); - - QVariant handle() const Q_DECL_OVERRIDE; -protected: - void cleanup(); - bool fetch(int i) Q_DECL_OVERRIDE; - bool fetchNext() Q_DECL_OVERRIDE; - bool fetchLast() Q_DECL_OVERRIDE; - bool fetchFirst() Q_DECL_OVERRIDE; - QVariant data(int field) Q_DECL_OVERRIDE; - bool isNull(int field) Q_DECL_OVERRIDE; - bool reset (const QString& query) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QVariant lastInsertId() const Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; - bool nextResult() Q_DECL_OVERRIDE; - -#if MYSQL_VERSION_ID >= 40108 - bool prepare(const QString& stmt) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; -#endif -private: - QMYSQLResultPrivate* d; -}; class Q_EXPORT_SQLDRIVER_MYSQL QMYSQLDriver : public QSqlDriver { - friend class QMYSQLResult; + friend class QMYSQLResultPrivate; Q_DECLARE_PRIVATE(QMYSQLDriver) Q_OBJECT public: diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index f0c0b224bd..eb35c91e88 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -155,42 +155,62 @@ QT_BEGIN_INCLUDE_NAMESPACE Q_DECLARE_METATYPE(QOCIRowIdPointer) QT_END_INCLUDE_NAMESPACE +class QOCIDriverPrivate : public QSqlDriverPrivate +{ + Q_DECLARE_PUBLIC(QOCIDriver) + +public: + QOCIDriverPrivate(); + + OCIEnv *env; + OCISvcCtx *svc; + OCIServer *srvhp; + OCISession *authp; + OCIError *err; + bool transaction; + int serverVersion; + int prefetchRows; + int prefetchMem; + QString user; + + void allocErrorHandle(); +}; + class QOCICols; -struct QOCIResultPrivate; +class QOCIResultPrivate; -class Q_EXPORT_SQLDRIVER_OCI QOCIResult : public QSqlCachedResult +class QOCIResult: public QSqlCachedResult { + Q_DECLARE_PRIVATE(QOCIResult) friend class QOCIDriver; - friend struct QOCIResultPrivate; friend class QOCICols; public: - QOCIResult(const QOCIDriver * db, const QOCIDriverPrivate* p); + QOCIResult(const QOCIDriver *db); ~QOCIResult(); - bool prepare(const QString& query); - bool exec(); - QVariant handle() const; + bool prepare(const QString &query) Q_DECL_OVERRIDE; + bool exec() Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; protected: - bool gotoNext(ValueCache &values, int index); - bool reset (const QString& query); - int size(); - int numRowsAffected(); - QSqlRecord record() const; - QVariant lastInsertId() const; - bool execBatch(bool arrayBind = false); - void virtual_hook(int id, void *data); - -private: - QOCIResultPrivate *d; + bool gotoNext(ValueCache &values, int index) Q_DECL_OVERRIDE; + bool reset(const QString &query) Q_DECL_OVERRIDE; + int size() Q_DECL_OVERRIDE; + int numRowsAffected() Q_DECL_OVERRIDE; + QSqlRecord record() const Q_DECL_OVERRIDE; + QVariant lastInsertId() const Q_DECL_OVERRIDE; + bool execBatch(bool arrayBind = false) Q_DECL_OVERRIDE; + void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; }; -struct QOCIResultPrivate +class QOCIResultPrivate: public QSqlCachedResultPrivate { - QOCIResultPrivate(QOCIResult *result, const QOCIDriverPrivate *driver); +public: + Q_DECLARE_PUBLIC(QOCIResult) + Q_DECLARE_SQLDRIVER_PRIVATE(QOCIDriver) + QOCIResultPrivate(QOCIResult *q, const QOCIDriver *drv); ~QOCIResultPrivate(); QOCICols *cols; - QOCIResult *q; OCIEnv *env; OCIError *err; OCISvcCtx *&svc; @@ -207,9 +227,9 @@ struct QOCIResultPrivate void outValues(QVector<QVariant> &values, IndicatorArray &indicators, QList<QByteArray> &tmpStorage); inline bool isOutValue(int i) const - { return q->bindValueType(i) & QSql::Out; } + { Q_Q(const QOCIResult); return q->bindValueType(i) & QSql::Out; } inline bool isBinaryValue(int i) const - { return q->bindValueType(i) & QSql::Binary; } + { Q_Q(const QOCIResult); return q->bindValueType(i) & QSql::Binary; } void setCharset(dvoid* handle, ub4 type) const { @@ -485,25 +505,6 @@ void QOCIResultPrivate::outValues(QVector<QVariant> &values, IndicatorArray &ind } -class QOCIDriverPrivate : public QSqlDriverPrivate -{ -public: - QOCIDriverPrivate(); - - OCIEnv *env; - OCISvcCtx *svc; - OCIServer *srvhp; - OCISession *authp; - OCIError *err; - bool transaction; - int serverVersion; - ub4 prefetchRows; - ub2 prefetchMem; - QString user; - - void allocErrorHandle(); -}; - QOCIDriverPrivate::QOCIDriverPrivate() : QSqlDriverPrivate(), env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false), serverVersion(-1), prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM) @@ -1221,7 +1222,7 @@ OraFieldInfo QOCICols::qMakeOraField(const QOCIResultPrivate* p, OCIParam* param if (r != 0) qOraWarning("qMakeOraField:", p->err); - type = qDecodeOCIType(colType, p->q->numericalPrecisionPolicy()); + type = qDecodeOCIType(colType, p->q_func()->numericalPrecisionPolicy()); if (type == QVariant::Int) { if (colLength == 22 && colPrecision == 0 && colScale == 0) @@ -1232,16 +1233,16 @@ OraFieldInfo QOCICols::qMakeOraField(const QOCIResultPrivate* p, OCIParam* param // bind as double if the precision policy asks for it if (((colType == SQLT_FLT) || (colType == SQLT_NUM)) - && (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)) { + && (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)) { type = QVariant::Double; } // bind as int32 or int64 if the precision policy asks for it if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN) || (colType == SQLT_INT)) { - if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64) + if (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt64) type = QVariant::LongLong; - else if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32) + else if (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt32) type = QVariant::Int; } @@ -1336,7 +1337,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) { qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err); - d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult", + d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult", "Unable to bind column for batch execute"), QSqlError::StatementError, d->err)); return false; @@ -1530,7 +1531,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) { qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err); - d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult", + d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult", "Unable to bind column for batch execute"), QSqlError::StatementError, d->err)); return false; @@ -1545,7 +1546,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) { qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err); - d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult", + d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult", "Unable to bind column for batch execute"), QSqlError::StatementError, d->err)); return false; @@ -1560,7 +1561,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) { qOraWarning("QOCIPrivate::execBatch: unable to execute batch statement:", d->err); - d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult", + d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult", "Unable to execute batch statement"), QSqlError::StatementError, d->err)); return false; @@ -1635,9 +1636,9 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b } } - d->q->setSelect(false); - d->q->setAt(QSql::BeforeFirstRow); - d->q->setActive(true); + d->q_func()->setSelect(false); + d->q_func()->setAt(QSql::BeforeFirstRow); + d->q_func()->setActive(true); return true; } @@ -1752,12 +1753,12 @@ void QOCICols::getValues(QVector<QVariant> &v, int index) case QVariant::Double: case QVariant::Int: case QVariant::LongLong: - if (d->q->numericalPrecisionPolicy() != QSql::HighPrecision) { - if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble) + if (d->q_func()->numericalPrecisionPolicy() != QSql::HighPrecision) { + if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionDouble) && (fld.typ == QVariant::Double)) { v[index + i] = *reinterpret_cast<double *>(fld.data); break; - } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64) + } else if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt64) && (fld.typ == QVariant::LongLong)) { qint64 qll = 0; int r = OCINumberToInt(d->err, reinterpret_cast<OCINumber *>(fld.data), sizeof(qint64), @@ -1767,7 +1768,7 @@ void QOCICols::getValues(QVector<QVariant> &v, int index) else v[index + i] = QVariant(); break; - } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32) + } else if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt32) && (fld.typ == QVariant::Int)) { v[index + i] = *reinterpret_cast<int *>(fld.data); break; @@ -1790,10 +1791,17 @@ void QOCICols::getValues(QVector<QVariant> &v, int index) } } -QOCIResultPrivate::QOCIResultPrivate(QOCIResult *result, const QOCIDriverPrivate *driver) - : cols(0), q(result), env(driver->env), err(0), svc(const_cast<OCISvcCtx*&>(driver->svc)), - sql(0), transaction(driver->transaction), serverVersion(driver->serverVersion), - prefetchRows(driver->prefetchRows), prefetchMem(driver->prefetchMem) +QOCIResultPrivate::QOCIResultPrivate(QOCIResult *q, const QOCIDriver *drv) + : QSqlCachedResultPrivate(q, drv), + cols(0), + env(drv_d_func()->env), + err(0), + svc(const_cast<OCISvcCtx*&>(drv_d_func()->svc)), + sql(0), + transaction(drv_d_func()->transaction), + serverVersion(drv_d_func()->serverVersion), + prefetchRows(drv_d_func()->prefetchRows), + prefetchMem(drv_d_func()->prefetchMem) { int r = OCIHandleAlloc(env, reinterpret_cast<void **>(&err), @@ -1816,24 +1824,24 @@ QOCIResultPrivate::~QOCIResultPrivate() //////////////////////////////////////////////////////////////////////////// -QOCIResult::QOCIResult(const QOCIDriver * db, const QOCIDriverPrivate* p) - : QSqlCachedResult(db) +QOCIResult::QOCIResult(const QOCIDriver *db) + : QSqlCachedResult(*new QOCIResultPrivate(this, db)) { - d = new QOCIResultPrivate(this, p); } QOCIResult::~QOCIResult() { + Q_D(QOCIResult); if (d->sql) { int r = OCIHandleFree(d->sql, OCI_HTYPE_STMT); if (r != 0) qWarning("~QOCIResult: unable to free statement handle"); } - delete d; } QVariant QOCIResult::handle() const { + Q_D(const QOCIResult); return QVariant::fromValue(d->sql); } @@ -1846,6 +1854,7 @@ bool QOCIResult::reset (const QString& query) bool QOCIResult::gotoNext(QSqlCachedResult::ValueCache &values, int index) { + Q_D(QOCIResult); if (at() == QSql::AfterLastRow) return false; @@ -1905,6 +1914,7 @@ int QOCIResult::size() int QOCIResult::numRowsAffected() { + Q_D(QOCIResult); int rowCount; OCIAttrGet(d->sql, OCI_HTYPE_STMT, @@ -1917,6 +1927,7 @@ int QOCIResult::numRowsAffected() bool QOCIResult::prepare(const QString& query) { + Q_D(QOCIResult); int r = 0; QSqlResult::prepare(query); @@ -1962,6 +1973,7 @@ bool QOCIResult::prepare(const QString& query) bool QOCIResult::exec() { + Q_D(QOCIResult); int r = 0; ub2 stmtType=0; ub4 iters; @@ -2043,6 +2055,7 @@ bool QOCIResult::exec() QSqlRecord QOCIResult::record() const { + Q_D(const QOCIResult); QSqlRecord inf; if (!isActive() || !isSelect() || !d->cols) return inf; @@ -2051,6 +2064,7 @@ QSqlRecord QOCIResult::record() const QVariant QOCIResult::lastInsertId() const { + Q_D(const QOCIResult); if (isActive()) { QOCIRowIdPointer ptr(new QOCIRowId(d->env)); @@ -2064,6 +2078,7 @@ QVariant QOCIResult::lastInsertId() const bool QOCIResult::execBatch(bool arrayBind) { + Q_D(QOCIResult); QOCICols::execBatch(d, boundValues(), arrayBind); resetBindCount(); return lastError().type() == QSqlError::NoError; @@ -2301,8 +2316,7 @@ void QOCIDriver::close() QSqlResult *QOCIDriver::createResult() const { - Q_D(const QOCIDriver); - return new QOCIResult(this, d); + return new QOCIResult(this); } bool QOCIDriver::beginTransaction() diff --git a/src/sql/drivers/oci/qsql_oci_p.h b/src/sql/drivers/oci/qsql_oci_p.h index 48da952d56..c42e689437 100644 --- a/src/sql/drivers/oci/qsql_oci_p.h +++ b/src/sql/drivers/oci/qsql_oci_p.h @@ -45,7 +45,6 @@ // We mean it. // -#include <QtSql/qsqlresult.h> #include <QtSql/qsqldriver.h> #ifdef QT_PLUGIN @@ -59,41 +58,41 @@ typedef struct OCISvcCtx OCISvcCtx; QT_BEGIN_NAMESPACE -class QOCIDriver; -class QOCICols; +class QSqlResult; class QOCIDriverPrivate; class Q_EXPORT_SQLDRIVER_OCI QOCIDriver : public QSqlDriver { Q_DECLARE_PRIVATE(QOCIDriver) Q_OBJECT - friend struct QOCIResultPrivate; - friend class QOCIPrivate; + friend class QOCICols; + friend class QOCIResultPrivate; + public: explicit QOCIDriver(QObject* parent = 0); QOCIDriver(OCIEnv* env, OCISvcCtx* ctx, QObject* parent = 0); ~QOCIDriver(); bool hasFeature(DriverFeature f) const; - bool open(const QString & db, - const QString & user, - const QString & password, - const QString & host, + bool open(const QString &db, + const QString &user, + const QString &password, + const QString &host, int port, - const QString& connOpts); - void close(); - QSqlResult *createResult() const; - QStringList tables(QSql::TableType) const; - QSqlRecord record(const QString& tablename) const; - QSqlIndex primaryIndex(const QString& tablename) const; + const QString &connOpts) Q_DECL_OVERRIDE; + void close() Q_DECL_OVERRIDE; + QSqlResult *createResult() const Q_DECL_OVERRIDE; + QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; + QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE; + QSqlIndex primaryIndex(const QString& tablename) const Q_DECL_OVERRIDE; QString formatValue(const QSqlField &field, - bool trimStrings) const; - QVariant handle() const; - QString escapeIdentifier(const QString &identifier, IdentifierType) const; + bool trimStrings) const Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; + QString escapeIdentifier(const QString &identifier, IdentifierType) const Q_DECL_OVERRIDE; protected: - bool beginTransaction(); - bool commitTransaction(); - bool rollbackTransaction(); + bool beginTransaction() Q_DECL_OVERRIDE; + bool commitTransaction() Q_DECL_OVERRIDE; + bool rollbackTransaction() Q_DECL_OVERRIDE; }; QT_END_NAMESPACE 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() diff --git a/src/sql/drivers/odbc/qsql_odbc_p.h b/src/sql/drivers/odbc/qsql_odbc_p.h index 96e7abd7dd..25cc6aaa2c 100644 --- a/src/sql/drivers/odbc/qsql_odbc_p.h +++ b/src/sql/drivers/odbc/qsql_odbc_p.h @@ -46,7 +46,6 @@ // #include <QtSql/qsqldriver.h> -#include <QtSql/qsqlresult.h> #if defined (Q_OS_WIN32) #include <QtCore/qt_windows.h> @@ -75,81 +74,46 @@ QT_BEGIN_NAMESPACE -class QODBCPrivate; class QODBCDriverPrivate; -class QODBCDriver; -class QSqlRecordInfo; - -class QODBCResult : public QSqlResult -{ -public: - QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p); - virtual ~QODBCResult(); - - bool prepare(const QString& query); - bool exec(); - - QVariant lastInsertId() const; - QVariant handle() const; - virtual void setForwardOnly(bool forward); - -protected: - bool fetchNext(); - bool fetchFirst(); - bool fetchLast(); - bool fetchPrevious(); - bool fetch(int i); - bool reset (const QString& query); - QVariant data(int field); - bool isNull(int field); - int size(); - int numRowsAffected(); - QSqlRecord record() const; - void virtual_hook(int id, void *data); - void detachFromResultSet(); - bool nextResult(); - -private: - QODBCPrivate *d; -}; class Q_EXPORT_SQLDRIVER_ODBC QODBCDriver : public QSqlDriver { Q_DECLARE_PRIVATE(QODBCDriver) Q_OBJECT + friend class QODBCResultPrivate; + public: explicit QODBCDriver(QObject *parent=0); QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent=0); virtual ~QODBCDriver(); - bool hasFeature(DriverFeature f) const; - void close(); - QSqlResult *createResult() const; - QStringList tables(QSql::TableType) const; - QSqlRecord record(const QString& tablename) const; - QSqlIndex primaryIndex(const QString& tablename) const; - QVariant handle() const; + bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + void close() Q_DECL_OVERRIDE; + QSqlResult *createResult() const Q_DECL_OVERRIDE; + QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; + QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE; + QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; QString formatValue(const QSqlField &field, - bool trimStrings) const; - bool open(const QString& db, - const QString& user, - const QString& password, - const QString& host, + bool trimStrings) const Q_DECL_OVERRIDE; + bool open(const QString &db, + const QString &user, + const QString &password, + const QString &host, int port, - const QString& connOpts); + const QString &connOpts) Q_DECL_OVERRIDE; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; - bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const; + bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; protected: - bool beginTransaction(); - bool commitTransaction(); - bool rollbackTransaction(); + bool beginTransaction() Q_DECL_OVERRIDE; + bool commitTransaction() Q_DECL_OVERRIDE; + bool rollbackTransaction() Q_DECL_OVERRIDE; private: bool endTrans(); void cleanup(); - friend class QODBCPrivate; }; QT_END_NAMESPACE diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index 5dcabb0646..f9c3f8ba75 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -119,6 +119,35 @@ inline void qPQfreemem(void *buffer) PQfreemem(buffer); } +class QPSQLResultPrivate; + +class QPSQLResult: public QSqlResult +{ + Q_DECLARE_PRIVATE(QPSQLResult) + +public: + QPSQLResult(const QPSQLDriver *db); + ~QPSQLResult(); + + QVariant handle() const Q_DECL_OVERRIDE; + void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; + +protected: + void cleanup(); + bool fetch(int i) Q_DECL_OVERRIDE; + bool fetchFirst() Q_DECL_OVERRIDE; + bool fetchLast() Q_DECL_OVERRIDE; + QVariant data(int i) Q_DECL_OVERRIDE; + bool isNull(int field) Q_DECL_OVERRIDE; + bool reset (const QString &query) Q_DECL_OVERRIDE; + int size() Q_DECL_OVERRIDE; + int numRowsAffected() Q_DECL_OVERRIDE; + QSqlRecord record() const Q_DECL_OVERRIDE; + QVariant lastInsertId() const Q_DECL_OVERRIDE; + bool prepare(const QString &query) Q_DECL_OVERRIDE; + bool exec() Q_DECL_OVERRIDE; +}; + class QPSQLDriverPrivate : public QSqlDriverPrivate { Q_DECLARE_PUBLIC(QPSQLDriver) @@ -193,8 +222,9 @@ class QPSQLResultPrivate : public QSqlResultPrivate { Q_DECLARE_PUBLIC(QPSQLResult) public: - QPSQLResultPrivate() - : QSqlResultPrivate(), + Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver); + QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv) + : QSqlResultPrivate(q, drv), result(0), currentSize(-1), preparedQueriesEnabled(false) @@ -202,11 +232,6 @@ public: QString fieldSerial(int i) const Q_DECL_OVERRIDE { return QLatin1Char('$') + QString::number(i + 1); } void deallocatePreparedStmt(); - const QPSQLDriverPrivate * privDriver() const - { - Q_Q(const QPSQLResult); - return reinterpret_cast<const QPSQLDriver *>(q->driver())->d_func(); - } PGresult *result; int currentSize; @@ -248,7 +273,7 @@ bool QPSQLResultPrivate::processResults() return true; } q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult", - "Unable to create query"), QSqlError::StatementError, privDriver(), result)); + "Unable to create query"), QSqlError::StatementError, drv_d_func(), result)); return false; } @@ -301,16 +326,16 @@ static QVariant::Type qDecodePSQLType(int t) void QPSQLResultPrivate::deallocatePreparedStmt() { const QString stmt = QLatin1String("DEALLOCATE ") + preparedStmtId; - PGresult *result = privDriver()->exec(stmt); + PGresult *result = drv_d_func()->exec(stmt); if (PQresultStatus(result) != PGRES_COMMAND_OK) - qWarning("Unable to free statement: %s", PQerrorMessage(privDriver()->connection)); + qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection)); PQclear(result); preparedStmtId.clear(); } QPSQLResult::QPSQLResult(const QPSQLDriver* db) - : QSqlResult(*new QPSQLResultPrivate, db) + : QSqlResult(*new QPSQLResultPrivate(this, db)) { Q_D(QPSQLResult); d->preparedQueriesEnabled = db->hasFeature(QSqlDriver::PreparedQueries); @@ -384,7 +409,7 @@ QVariant QPSQLResult::data(int i) case QVariant::Bool: return QVariant((bool)(val[0] == 't')); case QVariant::String: - return d->privDriver()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val); + return d->drv_d_func()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val); case QVariant::LongLong: if (val[0] == '-') return QString::fromLatin1(val).toLongLong(); @@ -475,7 +500,7 @@ bool QPSQLResult::reset (const QString& query) return false; if (!driver()->isOpen() || driver()->isOpenError()) return false; - d->result = d->privDriver()->exec(query); + d->result = d->drv_d_func()->exec(query); return d->processResults(); } @@ -494,7 +519,7 @@ int QPSQLResult::numRowsAffected() QVariant QPSQLResult::lastInsertId() const { Q_D(const QPSQLResult); - if (d->privDriver()->pro >= QPSQLDriver::Version81) { + if (d->drv_d_func()->pro >= QPSQLDriver::Version81) { QSqlQuery qry(driver()->createResult()); // Most recent sequence value obtained from nextval if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next()) @@ -517,7 +542,7 @@ QSqlRecord QPSQLResult::record() const int count = PQnfields(d->result); for (int i = 0; i < count; ++i) { QSqlField f; - if (d->privDriver()->isUtf8) + if (d->drv_d_func()->isUtf8) f.setName(QString::fromUtf8(PQfname(d->result, i))); else f.setName(QString::fromLocal8Bit(PQfname(d->result, i))); @@ -611,11 +636,11 @@ bool QPSQLResult::prepare(const QString &query) const QString stmtId = qMakePreparedStmtId(); const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query)); - PGresult *result = d->privDriver()->exec(stmt); + PGresult *result = d->drv_d_func()->exec(stmt); if (PQresultStatus(result) != PGRES_COMMAND_OK) { setLastError(qMakeError(QCoreApplication::translate("QPSQLResult", - "Unable to prepare statement"), QSqlError::StatementError, d->privDriver(), result)); + "Unable to prepare statement"), QSqlError::StatementError, d->drv_d_func(), result)); PQclear(result); d->preparedStmtId.clear(); return false; @@ -641,7 +666,7 @@ bool QPSQLResult::exec() else stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId).arg(params); - d->result = d->privDriver()->exec(stmt); + d->result = d->drv_d_func()->exec(stmt); return d->processResults(); } diff --git a/src/sql/drivers/psql/qsql_psql_p.h b/src/sql/drivers/psql/qsql_psql_p.h index 61e201ae5e..d989f70ae3 100644 --- a/src/sql/drivers/psql/qsql_psql_p.h +++ b/src/sql/drivers/psql/qsql_psql_p.h @@ -45,7 +45,6 @@ // We mean it. // -#include <QtSql/qsqlresult.h> #include <QtSql/qsqldriver.h> #ifdef QT_PLUGIN @@ -59,44 +58,12 @@ typedef struct pg_result PGresult; QT_BEGIN_NAMESPACE -class QPSQLResultPrivate; -class QPSQLDriver; -class QSqlRecordInfo; - -class QPSQLResult : public QSqlResult -{ - Q_DECLARE_PRIVATE(QPSQLResult) - -public: - QPSQLResult(const QPSQLDriver* db); - ~QPSQLResult(); - - QVariant handle() const Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; - -protected: - void cleanup(); - bool fetch(int i) Q_DECL_OVERRIDE; - bool fetchFirst() Q_DECL_OVERRIDE; - bool fetchLast() Q_DECL_OVERRIDE; - QVariant data(int i) Q_DECL_OVERRIDE; - bool isNull(int field) Q_DECL_OVERRIDE; - bool reset (const QString& query) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - QVariant lastInsertId() const Q_DECL_OVERRIDE; - bool prepare(const QString& query) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; -}; - class QPSQLDriverPrivate; class Q_EXPORT_SQLDRIVER_PSQL QPSQLDriver : public QSqlDriver { friend class QPSQLResultPrivate; Q_DECLARE_PRIVATE(QPSQLDriver) - Q_OBJECT public: enum Protocol { diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 4286f5b338..66e5724e6f 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -105,8 +105,9 @@ class QSQLiteResultPrivate; class QSQLiteResult : public QSqlCachedResult { + Q_DECLARE_PRIVATE(QSQLiteResult) friend class QSQLiteDriver; - friend class QSQLiteResultPrivate; + public: explicit QSQLiteResult(const QSQLiteDriver* db); ~QSQLiteResult(); @@ -123,13 +124,12 @@ protected: QSqlRecord record() const Q_DECL_OVERRIDE; void detachFromResultSet() Q_DECL_OVERRIDE; void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; - -private: - QSQLiteResultPrivate* d; }; class QSQLiteDriverPrivate : public QSqlDriverPrivate { + Q_DECLARE_PUBLIC(QSQLiteDriver) + public: inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; } sqlite3 *access; @@ -137,19 +137,19 @@ public: }; -class QSQLiteResultPrivate +class QSQLiteResultPrivate: public QSqlCachedResultPrivate { + Q_DECLARE_PUBLIC(QSQLiteResult) + public: - QSQLiteResultPrivate(QSQLiteResult *res); + Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver) + QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv); void cleanup(); bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch); // initializes the recordInfo and the cache void initColumns(bool emptyResultset); void finalize(); - QSQLiteResult* q; - sqlite3 *access; - sqlite3_stmt *stmt; bool skippedStatus; // the status of the fetchNext() that's skipped @@ -158,13 +158,17 @@ public: QVector<QVariant> firstRow; }; -QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult* res) : q(res), access(0), - stmt(0), skippedStatus(false), skipRow(false) +QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv) + : QSqlCachedResultPrivate(q, drv), + stmt(0), + skippedStatus(false), + skipRow(false) { } void QSQLiteResultPrivate::cleanup() { + Q_Q(QSQLiteResult); finalize(); rInf.clear(); skippedStatus = false; @@ -185,6 +189,7 @@ void QSQLiteResultPrivate::finalize() void QSQLiteResultPrivate::initColumns(bool emptyResultset) { + Q_Q(QSQLiteResult); int nCols = sqlite3_column_count(stmt); if (nCols <= 0) return; @@ -236,6 +241,7 @@ void QSQLiteResultPrivate::initColumns(bool emptyResultset) bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch) { + Q_Q(QSQLiteResult); int res; int i; @@ -318,7 +324,7 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i // SQLITE_ERROR is a generic error code and we must call sqlite3_reset() // to get the specific error message. res = sqlite3_reset(stmt); - q->setLastError(qMakeError(access, QCoreApplication::translate("QSQLiteResult", + q->setLastError(qMakeError(drv_d_func()->access, QCoreApplication::translate("QSQLiteResult", "Unable to fetch row"), QSqlError::ConnectionError, res)); q->setAt(QSql::AfterLastRow); return false; @@ -326,7 +332,7 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i case SQLITE_BUSY: default: // something wrong, don't get col info, but still return false - q->setLastError(qMakeError(access, QCoreApplication::translate("QSQLiteResult", + q->setLastError(qMakeError(drv_d_func()->access, QCoreApplication::translate("QSQLiteResult", "Unable to fetch row"), QSqlError::ConnectionError, res)); sqlite3_reset(stmt); q->setAt(QSql::AfterLastRow); @@ -336,20 +342,18 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i } QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db) - : QSqlCachedResult(db) + : QSqlCachedResult(*new QSQLiteResultPrivate(this, db)) { - d = new QSQLiteResultPrivate(this); - d->access = db->d_func()->access; - const_cast<QSQLiteDriverPrivate*>(db->d_func())->results.append(this); + Q_D(QSQLiteResult); + const_cast<QSQLiteDriverPrivate*>(d->drv_d_func())->results.append(this); } QSQLiteResult::~QSQLiteResult() { - const QSqlDriver *sqlDriver = driver(); - if (sqlDriver) - const_cast<QSQLiteDriverPrivate*>(qobject_cast<const QSQLiteDriver *>(sqlDriver)->d_func())->results.removeOne(this); + Q_D(QSQLiteResult); + if (d->drv_d_func()) + const_cast<QSQLiteDriverPrivate*>(d->drv_d_func())->results.removeOne(this); d->cleanup(); - delete d; } void QSQLiteResult::virtual_hook(int id, void *data) @@ -366,6 +370,7 @@ bool QSQLiteResult::reset(const QString &query) bool QSQLiteResult::prepare(const QString &query) { + Q_D(QSQLiteResult); if (!driver() || !driver()->isOpen() || driver()->isOpenError()) return false; @@ -376,7 +381,7 @@ bool QSQLiteResult::prepare(const QString &query) const void *pzTail = NULL; #if (SQLITE_VERSION_NUMBER >= 3003011) - int res = sqlite3_prepare16_v2(d->access, query.constData(), (query.size() + 1) * sizeof(QChar), + int res = sqlite3_prepare16_v2(d->drv_d_func()->access, query.constData(), (query.size() + 1) * sizeof(QChar), &d->stmt, &pzTail); #else int res = sqlite3_prepare16(d->access, query.constData(), (query.size() + 1) * sizeof(QChar), @@ -384,12 +389,12 @@ bool QSQLiteResult::prepare(const QString &query) #endif if (res != SQLITE_OK) { - setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult", + setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult", "Unable to execute statement"), QSqlError::StatementError, res)); d->finalize(); return false; } else if (pzTail && !QString(reinterpret_cast<const QChar *>(pzTail)).trimmed().isEmpty()) { - setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult", + setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult", "Unable to execute multiple statements at a time"), QSqlError::StatementError, SQLITE_MISUSE)); d->finalize(); return false; @@ -399,6 +404,7 @@ bool QSQLiteResult::prepare(const QString &query) bool QSQLiteResult::exec() { + Q_D(QSQLiteResult); const QVector<QVariant> values = boundValues(); d->skippedStatus = false; @@ -409,7 +415,7 @@ bool QSQLiteResult::exec() int res = sqlite3_reset(d->stmt); if (res != SQLITE_OK) { - setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult", + setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult", "Unable to reset statement"), QSqlError::StatementError, res)); d->finalize(); return false; @@ -469,7 +475,7 @@ bool QSQLiteResult::exec() } } if (res != SQLITE_OK) { - setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult", + setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult", "Unable to bind parameters"), QSqlError::StatementError, res)); d->finalize(); return false; @@ -493,6 +499,7 @@ bool QSQLiteResult::exec() bool QSQLiteResult::gotoNext(QSqlCachedResult::ValueCache& row, int idx) { + Q_D(QSQLiteResult); return d->fetchNext(row, idx, false); } @@ -503,13 +510,15 @@ int QSQLiteResult::size() int QSQLiteResult::numRowsAffected() { - return sqlite3_changes(d->access); + Q_D(const QSQLiteResult); + return sqlite3_changes(d->drv_d_func()->access); } QVariant QSQLiteResult::lastInsertId() const { + Q_D(const QSQLiteResult); if (isActive()) { - qint64 id = sqlite3_last_insert_rowid(d->access); + qint64 id = sqlite3_last_insert_rowid(d->drv_d_func()->access); if (id) return id; } @@ -518,6 +527,7 @@ QVariant QSQLiteResult::lastInsertId() const QSqlRecord QSQLiteResult::record() const { + Q_D(const QSQLiteResult); if (!isActive() || !isSelect()) return QSqlRecord(); return d->rInf; @@ -525,12 +535,14 @@ QSqlRecord QSQLiteResult::record() const void QSQLiteResult::detachFromResultSet() { + Q_D(QSQLiteResult); if (d->stmt) sqlite3_reset(d->stmt); } QVariant QSQLiteResult::handle() const { + Q_D(const QSQLiteResult); return QVariant::fromValue(d->stmt); } @@ -640,7 +652,7 @@ void QSQLiteDriver::close() Q_D(QSQLiteDriver); if (isOpen()) { foreach (QSQLiteResult *result, d->results) { - result->d->finalize(); + result->d_func()->finalize(); } if (sqlite3_close(d->access) != SQLITE_OK) diff --git a/src/sql/drivers/sqlite/qsql_sqlite_p.h b/src/sql/drivers/sqlite/qsql_sqlite_p.h index 23b598de98..d0dc91daab 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite_p.h +++ b/src/sql/drivers/sqlite/qsql_sqlite_p.h @@ -46,7 +46,6 @@ // #include <QtSql/qsqldriver.h> -#include <QtSql/qsqlresult.h> struct sqlite3; @@ -58,14 +57,14 @@ struct sqlite3; QT_BEGIN_NAMESPACE +class QSqlResult; class QSQLiteDriverPrivate; -class QSQLiteDriver; class Q_EXPORT_SQLDRIVER_SQLITE QSQLiteDriver : public QSqlDriver { Q_DECLARE_PRIVATE(QSQLiteDriver) Q_OBJECT - friend class QSQLiteResult; + friend class QSQLiteResultPrivate; public: explicit QSQLiteDriver(QObject *parent = 0); explicit QSQLiteDriver(sqlite3 *connection, QObject *parent = 0); diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp index 3b540fd193..cd449e28e8 100644 --- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp +++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp @@ -77,6 +77,8 @@ static QVariant::Type nameToType(const QString& typeName) class QSQLite2DriverPrivate : public QSqlDriverPrivate { + Q_DECLARE_PUBLIC(QSQLite2Driver) + public: QSQLite2DriverPrivate(); sqlite *access; @@ -93,30 +95,31 @@ class QSQLite2ResultPrivate; class QSQLite2Result : public QSqlCachedResult { + Q_DECLARE_PRIVATE(QSQLite2Result) friend class QSQLite2Driver; - friend class QSQLite2ResultPrivate; + public: explicit QSQLite2Result(const QSQLite2Driver* db); ~QSQLite2Result(); - QVariant handle() const; + QVariant handle() const Q_DECL_OVERRIDE; protected: - bool gotoNext(QSqlCachedResult::ValueCache& row, int idx); - bool reset (const QString& query); - int size(); - int numRowsAffected(); - QSqlRecord record() const; - void detachFromResultSet(); - void virtual_hook(int id, void *data); - -private: - QSQLite2ResultPrivate* d; + bool gotoNext(QSqlCachedResult::ValueCache &row, int idx) Q_DECL_OVERRIDE; + bool reset(const QString &query) Q_DECL_OVERRIDE; + int size() Q_DECL_OVERRIDE; + int numRowsAffected() Q_DECL_OVERRIDE; + QSqlRecord record() const Q_DECL_OVERRIDE; + void detachFromResultSet() Q_DECL_OVERRIDE; + void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; }; -class QSQLite2ResultPrivate +class QSQLite2ResultPrivate: public QSqlCachedResultPrivate { + Q_DECLARE_PUBLIC(QSQLite2Result) + public: - QSQLite2ResultPrivate(QSQLite2Result *res); + Q_DECLARE_SQLDRIVER_PRIVATE(QSQLite2Driver); + QSQLite2ResultPrivate(QSQLite2Result *q, const QSQLite2Driver *drv); void cleanup(); bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch); bool isSelect(); @@ -124,9 +127,6 @@ public: void init(const char **cnames, int numCols); void finalize(); - QSQLite2Result* q; - sqlite *access; - // and we have too keep our own struct for the data (sqlite works via // callback. const char *currentTail; @@ -134,20 +134,24 @@ public: bool skippedStatus; // the status of the fetchNext() that's skipped bool skipRow; // skip the next fetchNext()? - bool utf8; QSqlRecord rInf; QVector<QVariant> firstRow; }; static const uint initial_cache_size = 128; -QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result* res) : q(res), access(0), currentTail(0), - currentMachine(0), skippedStatus(false), skipRow(false), utf8(false) +QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result *q, const QSQLite2Driver *drv) + : QSqlCachedResultPrivate(q, drv), + currentTail(0), + currentMachine(0), + skippedStatus(false), + skipRow(false) { } void QSQLite2ResultPrivate::cleanup() { + Q_Q(QSQLite2Result); finalize(); rInf.clear(); currentTail = 0; @@ -161,6 +165,7 @@ void QSQLite2ResultPrivate::cleanup() void QSQLite2ResultPrivate::finalize() { + Q_Q(QSQLite2Result); if (!currentMachine) return; @@ -178,6 +183,7 @@ void QSQLite2ResultPrivate::finalize() // called on first fetch void QSQLite2ResultPrivate::init(const char **cnames, int numCols) { + Q_Q(QSQLite2Result); if (!cnames) return; @@ -204,6 +210,7 @@ void QSQLite2ResultPrivate::init(const char **cnames, int numCols) bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch) { + Q_Q(QSQLite2Result); // may be caching. const char **fvals; const char **cnames; @@ -250,7 +257,7 @@ bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int if (idx < 0 && !initialFetch) return true; for (i = 0; i < colNum; ++i) - values[i + idx] = utf8 ? QString::fromUtf8(fvals[i]) : QString::fromLatin1(fvals[i]); + values[i + idx] = drv_d_func()->utf8 ? QString::fromUtf8(fvals[i]) : QString::fromLatin1(fvals[i]); return true; case SQLITE_DONE: if (rInf.isEmpty()) @@ -270,17 +277,14 @@ bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int } QSQLite2Result::QSQLite2Result(const QSQLite2Driver* db) -: QSqlCachedResult(db) + : QSqlCachedResult(*new QSQLite2ResultPrivate(this, db)) { - d = new QSQLite2ResultPrivate(this); - d->access = db->d_func()->access; - d->utf8 = db->d_func()->utf8; } QSQLite2Result::~QSQLite2Result() { + Q_D(QSQLite2Result); d->cleanup(); - delete d; } void QSQLite2Result::virtual_hook(int id, void *data) @@ -293,6 +297,7 @@ void QSQLite2Result::virtual_hook(int id, void *data) */ bool QSQLite2Result::reset (const QString& query) { + Q_D(QSQLite2Result); // this is where we build a query. if (!driver()) return false; @@ -304,8 +309,8 @@ bool QSQLite2Result::reset (const QString& query) // Um, ok. callback based so.... pass private static function for this. setSelect(false); char *err = 0; - int res = sqlite_compile(d->access, - d->utf8 ? query.toUtf8().constData() + int res = sqlite_compile(d->drv_d_func()->access, + d->drv_d_func()->utf8 ? query.toUtf8().constData() : query.toLatin1().constData(), &(d->currentTail), &(d->currentMachine), @@ -336,6 +341,7 @@ bool QSQLite2Result::reset (const QString& query) bool QSQLite2Result::gotoNext(QSqlCachedResult::ValueCache& row, int idx) { + Q_D(QSQLite2Result); return d->fetchNext(row, idx, false); } @@ -346,11 +352,13 @@ int QSQLite2Result::size() int QSQLite2Result::numRowsAffected() { - return sqlite_changes(d->access); + Q_D(QSQLite2Result); + return sqlite_changes(d->drv_d_func()->access); } QSqlRecord QSQLite2Result::record() const { + Q_D(const QSQLite2Result); if (!isActive() || !isSelect()) return QSqlRecord(); return d->rInf; @@ -358,11 +366,13 @@ QSqlRecord QSQLite2Result::record() const void QSQLite2Result::detachFromResultSet() { + Q_D(QSQLite2Result); d->finalize(); } QVariant QSQLite2Result::handle() const { + Q_D(const QSQLite2Result); return QVariant::fromValue(d->currentMachine); } diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2_p.h b/src/sql/drivers/sqlite2/qsql_sqlite2_p.h index 95766dacd0..408cc832a3 100644 --- a/src/sql/drivers/sqlite2/qsql_sqlite2_p.h +++ b/src/sql/drivers/sqlite2/qsql_sqlite2_p.h @@ -46,9 +46,6 @@ // #include <QtSql/qsqldriver.h> -#include <QtSql/qsqlresult.h> -#include <QtSql/qsqlrecord.h> -#include <QtSql/qsqlindex.h> #if defined (Q_OS_WIN32) # include <QtCore/qt_windows.h> @@ -56,43 +53,49 @@ struct sqlite; +#ifdef QT_PLUGIN +#define Q_EXPORT_SQLDRIVER_SQLITE2 +#else +#define Q_EXPORT_SQLDRIVER_SQLITE2 Q_SQL_EXPORT +#endif + QT_BEGIN_NAMESPACE +class QSqlResult; class QSQLite2DriverPrivate; -class QSQLite2Driver; -class QSQLite2Driver : public QSqlDriver +class Q_EXPORT_SQLDRIVER_SQLITE2 QSQLite2Driver : public QSqlDriver { - friend class QSQLite2Result; + friend class QSQLite2ResultPrivate; Q_DECLARE_PRIVATE(QSQLite2Driver) Q_OBJECT public: explicit QSQLite2Driver(QObject *parent = 0); explicit QSQLite2Driver(sqlite *connection, QObject *parent = 0); ~QSQLite2Driver(); - bool hasFeature(DriverFeature f) const; - bool open(const QString & db, - const QString & user, - const QString & password, - const QString & host, + bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool open(const QString &db, + const QString &user, + const QString &password, + const QString &host, int port, - const QString & connOpts); - bool open(const QString & db, - const QString & user, - const QString & password, - const QString & host, - int port) { return open (db, user, password, host, port, QString()); } - void close(); - QSqlResult *createResult() const; - bool beginTransaction(); - bool commitTransaction(); - bool rollbackTransaction(); - QStringList tables(QSql::TableType) const; + const QString &connOpts) Q_DECL_OVERRIDE; + bool open(const QString &db, + const QString &user, + const QString &password, + const QString &host, + int port) { return open(db, user, password, host, port, QString()); } + void close() Q_DECL_OVERRIDE; + QSqlResult *createResult() const Q_DECL_OVERRIDE; + bool beginTransaction() Q_DECL_OVERRIDE; + bool commitTransaction() Q_DECL_OVERRIDE; + bool rollbackTransaction() Q_DECL_OVERRIDE; + QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; - QSqlRecord record(const QString& tablename) const; - QSqlIndex primaryIndex(const QString &table) const; - QVariant handle() const; - QString escapeIdentifier(const QString &identifier, IdentifierType) const; + QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE; + QSqlIndex primaryIndex(const QString &table) const Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; + QString escapeIdentifier(const QString &identifier, IdentifierType) const Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp index f048440113..75d6cc2cd6 100644 --- a/src/sql/drivers/tds/qsql_tds.cpp +++ b/src/sql/drivers/tds/qsql_tds.cpp @@ -131,6 +131,8 @@ QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, int errNo = class QTDSDriverPrivate : public QSqlDriverPrivate { + Q_DECLARE_PUBLIC(QTDSDriver) + public: QTDSDriverPrivate() : QSqlDriverPrivate(), login(0), initialized(false) { dbmsType = QSqlDriver::Sybase; } LOGINREC* login; // login information @@ -150,6 +152,8 @@ class QTDSResultPrivate; class QTDSResult : public QSqlCachedResult { + Q_DECLARE_PRIVATE(QTDSResult) + public: explicit QTDSResult(const QTDSDriver* db); ~QTDSResult(); @@ -157,20 +161,23 @@ public: protected: void cleanup(); - bool reset (const QString& query); - int size(); - int numRowsAffected(); - bool gotoNext(QSqlCachedResult::ValueCache &values, int index); - QSqlRecord record() const; - -private: - QTDSResultPrivate* d; + bool reset(const QString &query) Q_DECL_OVERRIDE; + int size() Q_DECL_OVERRIDE; + int numRowsAffected() Q_DECL_OVERRIDE; + bool gotoNext(QSqlCachedResult::ValueCache &values, int index) Q_DECL_OVERRIDE; + QSqlRecord record() const Q_DECL_OVERRIDE; }; -class QTDSResultPrivate +class QTDSResultPrivate: public QSqlCachedResultPrivate { + Q_DECLARE_PUBLIC(QTDSResult) + public: - QTDSResultPrivate():login(0), dbproc(0) {} + Q_DECLARE_SQLDRIVER_PRIVATE(QTDSDriver) + QTDSResultPrivate(QTDSResult *q, const QTDSDriver *drv) + : QSqlCachedResultPrivate(q, drv), + login(0), + dbproc(0) {} LOGINREC* login; // login information DBPROCESS* dbproc; // connection from app to server QSqlError lastError; @@ -316,15 +323,15 @@ QVariant::Type qFieldType(QTDSResultPrivate* d, int i) QTDSResult::QTDSResult(const QTDSDriver* db) - : QSqlCachedResult(db) + : QSqlCachedResult(*new QTDSResultPrivate(this, db)) { - d = new QTDSResultPrivate(); - d->login = db->d_func()->login; + Q_D(QTDSResult); + d->login = d->drv_d_func()->login; - d->dbproc = dbopen(d->login, const_cast<char*>(db->d_func()->hostName.toLatin1().constData())); + d->dbproc = dbopen(d->login, const_cast<char*>(d->drv_d_func()->hostName.toLatin1().constData())); if (!d->dbproc) return; - if (dbuse(d->dbproc, const_cast<char*>(db->d_func()->db.toLatin1().constData())) == FAIL) + if (dbuse(d->dbproc, const_cast<char*>(d->drv_d_func()->db.toLatin1().constData())) == FAIL) return; // insert d in error handler dict @@ -335,15 +342,16 @@ QTDSResult::QTDSResult(const QTDSDriver* db) QTDSResult::~QTDSResult() { + Q_D(QTDSResult); cleanup(); if (d->dbproc) dbclose(d->dbproc); errs()->remove(d->dbproc); - delete d; } void QTDSResult::cleanup() { + Q_D(QTDSResult); d->clearErrorMsgs(); d->rec.clear(); for (int i = 0; i < d->buffer.size(); ++i) @@ -358,6 +366,7 @@ void QTDSResult::cleanup() QVariant QTDSResult::handle() const { + Q_D(const QTDSResult); return QVariant(qRegisterMetaType<DBPROCESS *>("DBPROCESS*"), &d->dbproc); } @@ -368,6 +377,7 @@ static inline bool qIsNull(const QTDSColumnData &p) bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index) { + Q_D(QTDSResult); STATUS stat = dbnextrow(d->dbproc); if (stat == NO_MORE_ROWS) { setAt(QSql::AfterLastRow); @@ -427,6 +437,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index) bool QTDSResult::reset (const QString& query) { + Q_D(QTDSResult); cleanup(); if (!driver() || !driver()-> isOpen() || driver()->isOpenError()) return false; @@ -515,6 +526,7 @@ int QTDSResult::size() int QTDSResult::numRowsAffected() { + Q_D(const QTDSResult); #ifdef DBNTWIN32 if (dbiscount(d->dbproc)) { return DBCOUNT(d->dbproc); @@ -527,6 +539,7 @@ int QTDSResult::numRowsAffected() QSqlRecord QTDSResult::record() const { + Q_D(const QTDSResult); return d->rec; } diff --git a/src/sql/drivers/tds/qsql_tds_p.h b/src/sql/drivers/tds/qsql_tds_p.h index fae5dc2877..25a5aa1fe7 100644 --- a/src/sql/drivers/tds/qsql_tds_p.h +++ b/src/sql/drivers/tds/qsql_tds_p.h @@ -45,7 +45,6 @@ // We mean it. // -#include <QtSql/qsqlresult.h> #include <QtSql/qsqldriver.h> #ifdef Q_OS_WIN32 @@ -71,41 +70,41 @@ QT_BEGIN_NAMESPACE +class QSqlResult; class QTDSDriverPrivate; -class QTDSDriver; class Q_EXPORT_SQLDRIVER_TDS QTDSDriver : public QSqlDriver { Q_DECLARE_PRIVATE(QTDSDriver) Q_OBJECT - friend class QTDSResult; + friend class QTDSResultPrivate; public: explicit QTDSDriver(QObject* parent = 0); QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent = 0); ~QTDSDriver(); - bool hasFeature(DriverFeature f) const; - bool open(const QString & db, - const QString & user, - const QString & password, - const QString & host, + bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool open(const QString &db, + const QString &user, + const QString &password, + const QString &host, int port, - const QString& connOpts); - void close(); - QStringList tables(QSql::TableType) const; - QSqlResult *createResult() const; - QSqlRecord record(const QString& tablename) const; - QSqlIndex primaryIndex(const QString& tablename) const; + const QString &connOpts) Q_DECL_OVERRIDE; + void close() Q_DECL_OVERRIDE; + QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; + QSqlResult *createResult() const Q_DECL_OVERRIDE; + QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE; + QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE; QString formatValue(const QSqlField &field, - bool trimStrings) const; - QVariant handle() const; + bool trimStrings) const Q_DECL_OVERRIDE; + QVariant handle() const Q_DECL_OVERRIDE; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; protected: - bool beginTransaction(); - bool commitTransaction(); - bool rollbackTransaction(); + bool beginTransaction() Q_DECL_OVERRIDE; + bool commitTransaction() Q_DECL_OVERRIDE; + bool rollbackTransaction() Q_DECL_OVERRIDE; private: void init(); }; |