summaryrefslogtreecommitdiffstats
path: root/src/sql/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/sql/drivers')
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp25
-rw-r--r--src/sql/drivers/db2/qsql_db2.pri2
-rw-r--r--src/sql/drivers/db2/qsql_db2_p.h (renamed from src/sql/drivers/db2/qsql_db2.h)24
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.cpp62
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.pri2
-rw-r--r--src/sql/drivers/ibase/qsql_ibase_p.h (renamed from src/sql/drivers/ibase/qsql_ibase.h)51
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp89
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.pri2
-rw-r--r--src/sql/drivers/mysql/qsql_mysql_p.h (renamed from src/sql/drivers/mysql/qsql_mysql.h)24
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp66
-rw-r--r--src/sql/drivers/oci/qsql_oci.pri4
-rw-r--r--src/sql/drivers/oci/qsql_oci_p.h (renamed from src/sql/drivers/oci/qsql_oci.h)53
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp126
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.pri2
-rw-r--r--src/sql/drivers/odbc/qsql_odbc_p.h (renamed from src/sql/drivers/odbc/qsql_odbc.h)24
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp168
-rw-r--r--src/sql/drivers/psql/qsql_psql.pri2
-rw-r--r--src/sql/drivers/psql/qsql_psql_p.h (renamed from src/sql/drivers/psql/qsql_psql.h)38
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp57
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.pri2
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite_p.h (renamed from src/sql/drivers/sqlite/qsql_sqlite.h)51
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.cpp58
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.pri2
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2_p.h (renamed from src/sql/drivers/sqlite2/qsql_sqlite2.h)50
-rw-r--r--src/sql/drivers/tds/qsql_tds.cpp88
-rw-r--r--src/sql/drivers/tds/qsql_tds.pri2
-rw-r--r--src/sql/drivers/tds/qsql_tds_p.h (renamed from src/sql/drivers/tds/qsql_tds.h)43
27 files changed, 651 insertions, 466 deletions
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index 9406861d4c..e58710e0f5 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -39,7 +39,8 @@
**
****************************************************************************/
-#include "qsql_db2.h"
+#include "qsql_db2_p.h"
+#include <QtSql/private/qsqldriver_p.h>
#include <qcoreapplication.h>
#include <qdatetime.h>
#include <qsqlfield.h>
@@ -70,10 +71,10 @@ QT_BEGIN_NAMESPACE
static const int COLNAMESIZE = 255;
static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT };
-class QDB2DriverPrivate
+class QDB2DriverPrivate : public QSqlDriverPrivate
{
public:
- QDB2DriverPrivate(): hEnv(0), hDbc(0) {}
+ QDB2DriverPrivate() : QSqlDriverPrivate(), hEnv(0), hDbc(0) { dbmsType = DB2; }
SQLHANDLE hEnv;
SQLHANDLE hDbc;
QString user;
@@ -1131,15 +1132,14 @@ void QDB2Result::detachFromResultSet()
/************************************/
QDB2Driver::QDB2Driver(QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QDB2DriverPrivate, parent)
{
- d = new QDB2DriverPrivate;
}
QDB2Driver::QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QDB2DriverPrivate, parent)
{
- d = new QDB2DriverPrivate;
+ Q_D(QDB2Driver);
d->hEnv = (SQLHANDLE)env;
d->hDbc = (SQLHANDLE)con;
if (env && con) {
@@ -1151,12 +1151,12 @@ QDB2Driver::QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent)
QDB2Driver::~QDB2Driver()
{
close();
- delete d;
}
bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port,
const QString& connOpts)
{
+ Q_D(QDB2Driver);
if (isOpen())
close();
SQLRETURN r;
@@ -1259,6 +1259,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
void QDB2Driver::close()
{
+ Q_D(QDB2Driver);
SQLRETURN r;
if (d->hDbc) {
// Open statements/descriptors handles are automatically cleaned up by SQLDisconnect
@@ -1285,11 +1286,13 @@ void QDB2Driver::close()
QSqlResult *QDB2Driver::createResult() const
{
+ Q_D(const QDB2Driver);
return new QDB2Result(this, d);
}
QSqlRecord QDB2Driver::record(const QString& tableName) const
{
+ Q_D(const QDB2Driver);
QSqlRecord fil;
if (!isOpen())
return fil;
@@ -1363,6 +1366,7 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const
QStringList QDB2Driver::tables(QSql::TableType type) const
{
+ Q_D(const QDB2Driver);
QStringList tl;
if (!isOpen())
return tl;
@@ -1434,6 +1438,7 @@ QStringList QDB2Driver::tables(QSql::TableType type) const
QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const
{
+ Q_D(const QDB2Driver);
QSqlIndex index(tablename);
if (!isOpen())
return index;
@@ -1535,6 +1540,7 @@ bool QDB2Driver::beginTransaction()
bool QDB2Driver::commitTransaction()
{
+ Q_D(QDB2Driver);
if (!isOpen()) {
qWarning("QDB2Driver::commitTransaction: Database not open");
return false;
@@ -1552,6 +1558,7 @@ bool QDB2Driver::commitTransaction()
bool QDB2Driver::rollbackTransaction()
{
+ Q_D(QDB2Driver);
if (!isOpen()) {
qWarning("QDB2Driver::rollbackTransaction: Database not open");
return false;
@@ -1569,6 +1576,7 @@ bool QDB2Driver::rollbackTransaction()
bool QDB2Driver::setAutoCommit(bool autoCommit)
{
+ Q_D(QDB2Driver);
SQLUINTEGER ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
SQLRETURN r = SQLSetConnectAttr(d->hDbc,
SQL_ATTR_AUTOCOMMIT,
@@ -1627,6 +1635,7 @@ QString QDB2Driver::formatValue(const QSqlField &field, bool trimStrings) const
QVariant QDB2Driver::handle() const
{
+ Q_D(const QDB2Driver);
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hDbc);
}
diff --git a/src/sql/drivers/db2/qsql_db2.pri b/src/sql/drivers/db2/qsql_db2.pri
index 963732aaee..c9e65e2c2e 100644
--- a/src/sql/drivers/db2/qsql_db2.pri
+++ b/src/sql/drivers/db2/qsql_db2.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_db2.h
+HEADERS += $$PWD/qsql_db2_p.h
SOURCES += $$PWD/qsql_db2.cpp
unix {
diff --git a/src/sql/drivers/db2/qsql_db2.h b/src/sql/drivers/db2/qsql_db2_p.h
index 4e25c317eb..89b07c9c83 100644
--- a/src/sql/drivers/db2/qsql_db2.h
+++ b/src/sql/drivers/db2/qsql_db2_p.h
@@ -42,6 +42,19 @@
#ifndef QSQL_DB2_H
#define QSQL_DB2_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
#ifdef QT_PLUGIN
#define Q_EXPORT_SQLDRIVER_DB2
#else
@@ -51,15 +64,8 @@
#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QDB2Driver;
class QDB2DriverPrivate;
class QDB2ResultPrivate;
@@ -95,6 +101,7 @@ private:
class Q_EXPORT_SQLDRIVER_DB2 QDB2Driver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QDB2Driver)
Q_OBJECT
public:
explicit QDB2Driver(QObject* parent = 0);
@@ -121,11 +128,8 @@ public:
private:
bool setAutoCommit(bool autoCommit);
- QDB2DriverPrivate* d;
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSQL_DB2_H
diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp
index 5fd07318ec..bd97db189c 100644
--- a/src/sql/drivers/ibase/qsql_ibase.cpp
+++ b/src/sql/drivers/ibase/qsql_ibase.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qsql_ibase.h"
+#include "qsql_ibase_p.h"
#include <qcoreapplication.h>
#include <qdatetime.h>
#include <qvariant.h>
@@ -47,6 +47,8 @@
#include <qsqlfield.h>
#include <qsqlindex.h>
#include <qsqlquery.h>
+#include <QtSql/private/qsqlcachedresult_p.h>
+#include <QtSql/private/qsqldriver_p.h>
#include <qlist.h>
#include <qvector.h>
#include <qtextcodec.h>
@@ -308,13 +310,15 @@ struct QIBaseEventBuffer {
QIBaseSubscriptionState subscriptionState;
};
-class QIBaseDriverPrivate
+class QIBaseDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QIBaseDriver)
public:
- QIBaseDriverPrivate(QIBaseDriver *d) : q(d), ibase(0), trans(0), tc(0) {}
+ QIBaseDriverPrivate() : QSqlDriverPrivate(), ibase(0), trans(0), tc(0) { dbmsType = Interbase; }
bool isError(const char *msg, QSqlError::ErrorType typ = QSqlError::UnknownError)
{
+ Q_Q(QIBaseDriver);
QString imsg;
ISC_LONG sqlcode;
if (!getIBaseError(imsg, status, sqlcode, tc))
@@ -326,7 +330,6 @@ public:
}
public:
- QIBaseDriver* q;
isc_db_handle ibase;
isc_tr_handle trans;
QTextCodec *tc;
@@ -346,6 +349,31 @@ static void qFreeEventBuffer(QIBaseEventBuffer* eBuffer)
delete eBuffer;
}
+class QIBaseResultPrivate;
+
+class QIBaseResult : public QSqlCachedResult
+{
+ friend class QIBaseResultPrivate;
+
+public:
+ explicit QIBaseResult(const QIBaseDriver* db);
+ virtual ~QIBaseResult();
+
+ bool prepare(const QString& query);
+ bool exec();
+ QVariant handle() const;
+
+protected:
+ bool gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx);
+ bool reset (const QString& query);
+ int size();
+ int numRowsAffected();
+ QSqlRecord record() const;
+
+private:
+ QIBaseResultPrivate* d;
+};
+
class QIBaseResultPrivate
{
public:
@@ -391,9 +419,9 @@ public:
QIBaseResultPrivate::QIBaseResultPrivate(QIBaseResult *d, const QIBaseDriver *ddb):
- q(d), db(ddb), trans(0), stmt(0), ibase(ddb->d->ibase), sqlda(0), inda(0), queryType(-1), tc(ddb->d->tc)
+ q(d), db(ddb), trans(0), stmt(0), ibase(ddb->d_func()->ibase), sqlda(0), inda(0), queryType(-1), tc(ddb->d_func()->tc)
{
- localTransaction = (ddb->d->ibase == 0);
+ localTransaction = (ddb->d_func()->ibase == 0);
}
void QIBaseResultPrivate::cleanup()
@@ -834,9 +862,9 @@ bool QIBaseResultPrivate::transaction()
{
if (trans)
return true;
- if (db->d->trans) {
+ if (db->d_func()->trans) {
localTransaction = false;
- trans = db->d->trans;
+ trans = db->d_func()->trans;
return true;
}
localTransaction = true;
@@ -1369,15 +1397,14 @@ QVariant QIBaseResult::handle() const
/*********************************/
QIBaseDriver::QIBaseDriver(QObject * parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QIBaseDriverPrivate, parent)
{
- d = new QIBaseDriverPrivate(this);
}
QIBaseDriver::QIBaseDriver(isc_db_handle connection, QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QIBaseDriverPrivate, parent)
{
- d = new QIBaseDriverPrivate(this);
+ Q_D(QIBaseDriver);
d->ibase = connection;
setOpen(true);
setOpenError(false);
@@ -1385,7 +1412,6 @@ QIBaseDriver::QIBaseDriver(isc_db_handle connection, QObject *parent)
QIBaseDriver::~QIBaseDriver()
{
- delete d;
}
bool QIBaseDriver::hasFeature(DriverFeature f) const
@@ -1418,6 +1444,7 @@ bool QIBaseDriver::open(const QString & db,
int /*port*/,
const QString & connOpts)
{
+ Q_D(QIBaseDriver);
if (isOpen())
close();
@@ -1500,6 +1527,7 @@ bool QIBaseDriver::open(const QString & db,
void QIBaseDriver::close()
{
+ Q_D(QIBaseDriver);
if (isOpen()) {
if (d->eventBuffers.size()) {
@@ -1536,6 +1564,7 @@ QSqlResult *QIBaseDriver::createResult() const
bool QIBaseDriver::beginTransaction()
{
+ Q_D(QIBaseDriver);
if (!isOpen() || isOpenError())
return false;
if (d->trans)
@@ -1548,6 +1577,7 @@ bool QIBaseDriver::beginTransaction()
bool QIBaseDriver::commitTransaction()
{
+ Q_D(QIBaseDriver);
if (!isOpen() || isOpenError())
return false;
if (!d->trans)
@@ -1561,6 +1591,7 @@ bool QIBaseDriver::commitTransaction()
bool QIBaseDriver::rollbackTransaction()
{
+ Q_D(QIBaseDriver);
if (!isOpen() || isOpenError())
return false;
if (!d->trans)
@@ -1723,6 +1754,7 @@ QString QIBaseDriver::formatValue(const QSqlField &field, bool trimStrings) cons
QVariant QIBaseDriver::handle() const
{
+ Q_D(const QIBaseDriver);
return QVariant(qRegisterMetaType<isc_db_handle>("isc_db_handle"), &d->ibase);
}
@@ -1751,6 +1783,7 @@ static isc_callback qEventCallback(char *result, short length, char *updated)
bool QIBaseDriver::subscribeToNotification(const QString &name)
{
+ Q_D(QIBaseDriver);
if (!isOpen()) {
qWarning("QIBaseDriver::subscribeFromNotificationImplementation: database not open.");
return false;
@@ -1800,6 +1833,7 @@ bool QIBaseDriver::subscribeToNotification(const QString &name)
bool QIBaseDriver::unsubscribeFromNotification(const QString &name)
{
+ Q_D(QIBaseDriver);
if (!isOpen()) {
qWarning("QIBaseDriver::unsubscribeFromNotificationImplementation: database not open.");
return false;
@@ -1829,11 +1863,13 @@ bool QIBaseDriver::unsubscribeFromNotification(const QString &name)
QStringList QIBaseDriver::subscribedToNotifications() const
{
+ Q_D(const QIBaseDriver);
return QStringList(d->eventBuffers.keys());
}
void QIBaseDriver::qHandleEventNotification(void *updatedResultBuffer)
{
+ Q_D(QIBaseDriver);
QMap<QString, QIBaseEventBuffer *>::const_iterator i;
for (i = d->eventBuffers.constBegin(); i != d->eventBuffers.constEnd(); ++i) {
QIBaseEventBuffer* eBuffer = i.value();
diff --git a/src/sql/drivers/ibase/qsql_ibase.pri b/src/sql/drivers/ibase/qsql_ibase.pri
index 26017e8727..ef3b68d34e 100644
--- a/src/sql/drivers/ibase/qsql_ibase.pri
+++ b/src/sql/drivers/ibase/qsql_ibase.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_ibase.h
+HEADERS += $$PWD/qsql_ibase_p.h
SOURCES += $$PWD/qsql_ibase.cpp
unix {
diff --git a/src/sql/drivers/ibase/qsql_ibase.h b/src/sql/drivers/ibase/qsql_ibase_p.h
index 2ce20966c6..ab9edfd1a5 100644
--- a/src/sql/drivers/ibase/qsql_ibase.h
+++ b/src/sql/drivers/ibase/qsql_ibase_p.h
@@ -42,52 +42,31 @@
#ifndef QSQL_IBASE_H
#define QSQL_IBASE_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
-#include <QtSql/private/qsqlcachedresult_p.h>
#include <ibase.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QIBaseDriverPrivate;
-class QIBaseResultPrivate;
class QIBaseDriver;
-class QIBaseResult : public QSqlCachedResult
-{
- friend class QIBaseResultPrivate;
-
-public:
- explicit QIBaseResult(const QIBaseDriver* db);
- virtual ~QIBaseResult();
-
- bool prepare(const QString& query);
- bool exec();
- QVariant handle() const;
-
-protected:
- bool gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx);
- bool reset (const QString& query);
- int size();
- int numRowsAffected();
- QSqlRecord record() const;
-
-private:
- QIBaseResultPrivate* d;
-};
-
class QIBaseDriver : public QSqlDriver
{
- Q_OBJECT
- friend class QIBaseDriverPrivate;
friend class QIBaseResultPrivate;
+ Q_DECLARE_PRIVATE(QIBaseDriver)
+ Q_OBJECT
public:
explicit QIBaseDriver(QObject *parent = 0);
explicit QIBaseDriver(isc_db_handle connection, QObject *parent = 0);
@@ -125,12 +104,8 @@ public:
private Q_SLOTS:
void qHandleEventNotification(void* updatedResultBuffer);
-
-private:
- QIBaseDriverPrivate* d;
};
QT_END_NAMESPACE
-QT_END_HEADER
#endif // QSQL_IBASE_H
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index b4aa5cd4cc..0e20cf539e 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -39,8 +39,9 @@
**
****************************************************************************/
-#include "qsql_mysql.h"
+#include "qsql_mysql_p.h"
+#include <QtSql/private/qsqldriver_p.h>
#include <qcoreapplication.h>
#include <qvariant.h>
#include <qdatetime.h>
@@ -76,16 +77,16 @@ Q_DECLARE_METATYPE(MYSQL_STMT*)
QT_BEGIN_NAMESPACE
-class QMYSQLDriverPrivate
+class QMYSQLDriverPrivate : public QSqlDriverPrivate
{
public:
- QMYSQLDriverPrivate() : mysql(0),
+ QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0),
#ifndef QT_NO_TEXTCODEC
tc(QTextCodec::codecForLocale()),
#else
tc(0),
#endif
- preparedQuerysEnabled(false) {}
+ preparedQuerysEnabled(false) { dbmsType = MySqlServer; }
MYSQL *mysql;
QTextCodec *tc;
@@ -166,7 +167,7 @@ class QMYSQLResultPrivate : public QObject
{
Q_OBJECT
public:
- QMYSQLResultPrivate(const QMYSQLDriver* dp, const QMYSQLResult* d) : driver(dp), result(0), q(d),
+ QMYSQLResultPrivate(const QMYSQLDriver* dp, const QMYSQLResult* d) : driver(dp), result(0), q(d),
rowsAffected(0), hasBlobs(false)
#if MYSQL_VERSION_ID >= 40108
, stmt(0), meta(0), inBinds(0), outBinds(0)
@@ -434,8 +435,8 @@ void QMYSQLResult::cleanup()
// 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->mysql && mysql_next_result(d->driver->d->mysql) == 0) {
- MYSQL_RES *res = mysql_store_result(d->driver->d->mysql);
+ 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);
if (res)
mysql_free_result(res);
}
@@ -605,7 +606,7 @@ QVariant QMYSQLResult::data(int field)
return QVariant(f.type);
if (f.type != QVariant::ByteArray)
- val = toUnicode(d->driver->d->tc, f.outField, f.bufLength);
+ val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength);
} else {
if (d->row[field] == NULL) {
// NULL value
@@ -613,7 +614,7 @@ QVariant QMYSQLResult::data(int field)
}
fieldLength = mysql_fetch_lengths(d->result)[field];
if (f.type != QVariant::ByteArray)
- val = toUnicode(d->driver->d->tc, d->row[field], fieldLength);
+ val = toUnicode(d->driver->d_func()->tc, d->row[field], fieldLength);
}
switch(f.type) {
@@ -692,22 +693,22 @@ bool QMYSQLResult::reset (const QString& query)
cleanup();
- const QByteArray encQuery(fromUnicode(d->driver->d->tc, query));
- if (mysql_real_query(d->driver->d->mysql, encQuery.data(), encQuery.length())) {
+ const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query));
+ if (mysql_real_query(d->driver->d_func()->mysql, encQuery.data(), encQuery.length())) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute query"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
}
- d->result = mysql_store_result(d->driver->d->mysql);
- if (!d->result && mysql_field_count(d->driver->d->mysql) > 0) {
+ d->result = mysql_store_result(d->driver->d_func()->mysql);
+ if (!d->result && mysql_field_count(d->driver->d_func()->mysql) > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store result"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
}
- int numFields = mysql_field_count(d->driver->d->mysql);
+ int numFields = mysql_field_count(d->driver->d_func()->mysql);
setSelect(numFields != 0);
d->fields.resize(numFields);
- d->rowsAffected = mysql_affected_rows(d->driver->d->mysql);
+ d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql);
if (isSelect()) {
for(int i = 0; i < numFields; i++) {
@@ -752,7 +753,7 @@ QVariant QMYSQLResult::lastInsertId() const
return QVariant(id);
#endif
} else {
- quint64 id = mysql_insert_id(d->driver->d->mysql);
+ quint64 id = mysql_insert_id(d->driver->d_func()->mysql);
if (id)
return QVariant(id);
}
@@ -772,11 +773,11 @@ QSqlRecord QMYSQLResult::record() const
res = d->result;
#endif
- if (!mysql_errno(d->driver->d->mysql)) {
+ if (!mysql_errno(d->driver->d_func()->mysql)) {
mysql_field_seek(res, 0);
MYSQL_FIELD* field = mysql_fetch_field(res);
while(field) {
- info.append(qToField(field, d->driver->d->tc));
+ info.append(qToField(field, d->driver->d_func()->tc));
field = mysql_fetch_field(res);
}
}
@@ -788,7 +789,7 @@ bool QMYSQLResult::nextResult()
{
if(!d->driver)
return false;
-#if MYSQL_VERSION_ID >= 40100
+#if MYSQL_VERSION_ID >= 40100
setAt(-1);
setActive(false);
@@ -796,31 +797,31 @@ bool QMYSQLResult::nextResult()
mysql_free_result(d->result);
d->result = 0;
setSelect(false);
-
+
for (int i = 0; i < d->fields.count(); ++i)
delete[] d->fields[i].outField;
d->fields.clear();
- int status = mysql_next_result(d->driver->d->mysql);
+ int status = mysql_next_result(d->driver->d_func()->mysql);
if (status > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute next query"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
} else if (status == -1) {
return false; // No more result sets
}
- d->result = mysql_store_result(d->driver->d->mysql);
- int numFields = mysql_field_count(d->driver->d->mysql);
+ d->result = mysql_store_result(d->driver->d_func()->mysql);
+ int numFields = mysql_field_count(d->driver->d_func()->mysql);
if (!d->result && numFields > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store next result"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
}
setSelect(numFields > 0);
d->fields.resize(numFields);
- d->rowsAffected = mysql_affected_rows(d->driver->d->mysql);
+ d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql);
if (isSelect()) {
for (int i = 0; i < numFields; i++) {
@@ -873,7 +874,7 @@ bool QMYSQLResult::prepare(const QString& query)
return false;
#if MYSQL_VERSION_ID >= 40108
cleanup();
- if (!d->driver->d->preparedQuerysEnabled)
+ if (!d->driver->d_func()->preparedQuerysEnabled)
return QSqlResult::prepare(query);
int r;
@@ -882,14 +883,14 @@ bool QMYSQLResult::prepare(const QString& query)
return false;
if (!d->stmt)
- d->stmt = mysql_stmt_init(d->driver->d->mysql);
+ d->stmt = mysql_stmt_init(d->driver->d_func()->mysql);
if (!d->stmt) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
}
- const QByteArray encQuery(fromUnicode(d->driver->d->tc, query));
+ const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query));
r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length());
if (r != 0) {
setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult",
@@ -1009,7 +1010,7 @@ bool QMYSQLResult::exec()
break;
case QVariant::String:
default: {
- QByteArray ba = fromUnicode(d->driver->d->tc, val.toString());
+ QByteArray ba = fromUnicode(d->driver->d_func()->tc, val.toString());
stringVector.append(ba);
currBind->buffer_type = MYSQL_TYPE_STRING;
currBind->buffer = const_cast<char *>(ba.constData());
@@ -1114,7 +1115,7 @@ static void qLibraryEnd()
}
QMYSQLDriver::QMYSQLDriver(QObject * parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QMYSQLDriverPrivate, parent)
{
init();
qLibraryInit();
@@ -1126,8 +1127,9 @@ QMYSQLDriver::QMYSQLDriver(QObject * parent)
*/
QMYSQLDriver::QMYSQLDriver(MYSQL * con, QObject * parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QMYSQLDriverPrivate, parent)
{
+ Q_D(QMYSQLDriver);
init();
if (con) {
d->mysql = (MYSQL *) con;
@@ -1145,7 +1147,7 @@ QMYSQLDriver::QMYSQLDriver(MYSQL * con, QObject * parent)
void QMYSQLDriver::init()
{
- d = new QMYSQLDriverPrivate();
+ Q_D(QMYSQLDriver);
d->mysql = 0;
qMySqlConnectionCount++;
}
@@ -1155,11 +1157,11 @@ QMYSQLDriver::~QMYSQLDriver()
qMySqlConnectionCount--;
if (qMySqlConnectionCount == 0 && !qMySqlInitHandledByUser)
qLibraryEnd();
- delete d;
}
bool QMYSQLDriver::hasFeature(DriverFeature f) const
{
+ Q_D(const QMYSQLDriver);
switch (f) {
case Transactions:
// CLIENT_TRANSACTION should be defined in all recent mysql client libs > 3.23.34
@@ -1227,6 +1229,7 @@ bool QMYSQLDriver::open(const QString& db,
int port,
const QString& connOpts)
{
+ Q_D(QMYSQLDriver);
if (isOpen())
close();
@@ -1328,6 +1331,7 @@ bool QMYSQLDriver::open(const QString& db,
void QMYSQLDriver::close()
{
+ Q_D(QMYSQLDriver);
if (isOpen()) {
#ifndef QT_NO_THREAD
mysql_thread_end();
@@ -1346,6 +1350,7 @@ QSqlResult *QMYSQLDriver::createResult() const
QStringList QMYSQLDriver::tables(QSql::TableType type) const
{
+ Q_D(const QMYSQLDriver);
QStringList tl;
#if MYSQL_VERSION_ID >= 40100
if( mysql_get_server_version(d->mysql) < 50000)
@@ -1374,14 +1379,14 @@ QStringList QMYSQLDriver::tables(QSql::TableType type) const
if(type & QSql::Tables) {
QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'BASE TABLE'");
q.exec(sql);
-
+
while(q.next())
tl.append(q.value(0).toString());
}
if(type & QSql::Views) {
QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'VIEW'");
q.exec(sql);
-
+
while(q.next())
tl.append(q.value(0).toString());
}
@@ -1413,6 +1418,7 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const
QSqlRecord QMYSQLDriver::record(const QString& tablename) const
{
+ Q_D(const QMYSQLDriver);
QString table=tablename;
if(isIdentifierEscaped(table, QSqlDriver::TableName))
table = stripDelimiters(table, QSqlDriver::TableName);
@@ -1434,11 +1440,13 @@ QSqlRecord QMYSQLDriver::record(const QString& tablename) const
QVariant QMYSQLDriver::handle() const
{
+ Q_D(const QMYSQLDriver);
return QVariant::fromValue(d->mysql);
}
bool QMYSQLDriver::beginTransaction()
{
+ Q_D(QMYSQLDriver);
#ifndef CLIENT_TRANSACTIONS
return false;
#endif
@@ -1456,6 +1464,7 @@ bool QMYSQLDriver::beginTransaction()
bool QMYSQLDriver::commitTransaction()
{
+ Q_D(QMYSQLDriver);
#ifndef CLIENT_TRANSACTIONS
return false;
#endif
@@ -1473,6 +1482,7 @@ bool QMYSQLDriver::commitTransaction()
bool QMYSQLDriver::rollbackTransaction()
{
+ Q_D(QMYSQLDriver);
#ifndef CLIENT_TRANSACTIONS
return false;
#endif
@@ -1490,6 +1500,7 @@ bool QMYSQLDriver::rollbackTransaction()
QString QMYSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
{
+ Q_D(const QMYSQLDriver);
QString r;
if (field.isNull()) {
r = QLatin1String("NULL");
diff --git a/src/sql/drivers/mysql/qsql_mysql.pri b/src/sql/drivers/mysql/qsql_mysql.pri
index 0423eb4ed9..50f49ca548 100644
--- a/src/sql/drivers/mysql/qsql_mysql.pri
+++ b/src/sql/drivers/mysql/qsql_mysql.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_mysql.h
+HEADERS += $$PWD/qsql_mysql_p.h
SOURCES += $$PWD/qsql_mysql.cpp
!isEmpty(MYSQL_PATH) {
diff --git a/src/sql/drivers/mysql/qsql_mysql.h b/src/sql/drivers/mysql/qsql_mysql_p.h
index 37e18c8fb1..a1be139b2a 100644
--- a/src/sql/drivers/mysql/qsql_mysql.h
+++ b/src/sql/drivers/mysql/qsql_mysql_p.h
@@ -42,6 +42,17 @@
#ifndef QSQL_MYSQL_H
#define QSQL_MYSQL_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtSql/qsqldriver.h>
#include <QtSql/qsqlresult.h>
@@ -57,15 +68,8 @@
#define Q_EXPORT_SQLDRIVER_MYSQL Q_SQL_EXPORT
#endif
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QMYSQLDriverPrivate;
class QMYSQLResultPrivate;
class QMYSQLDriver;
@@ -106,8 +110,9 @@ private:
class Q_EXPORT_SQLDRIVER_MYSQL QMYSQLDriver : public QSqlDriver
{
- Q_OBJECT
friend class QMYSQLResult;
+ Q_DECLARE_PRIVATE(QMYSQLDriver)
+ Q_OBJECT
public:
explicit QMYSQLDriver(QObject *parent=0);
explicit QMYSQLDriver(MYSQL *con, QObject * parent=0);
@@ -137,11 +142,8 @@ protected:
bool rollbackTransaction();
private:
void init();
- QMYSQLDriverPrivate* d;
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSQL_MYSQL_H
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index e2bb9a4eaf..fe9ae42e6f 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qsql_oci.h"
+#include "qsql_oci_p.h"
#include <qcoreapplication.h>
#include <qvariant.h>
@@ -51,6 +51,8 @@
#include <qsqlfield.h>
#include <qsqlindex.h>
#include <qsqlquery.h>
+#include <QtSql/private/qsqlcachedresult_p.h>
+#include <QtSql/private/qsqldriver_p.h>
#include <qstringlist.h>
#include <qvarlengtharray.h>
#include <qvector.h>
@@ -99,7 +101,7 @@ enum { QOCIEncoding = 2000 }; // AL16UTF16
// Always set the OCI_ATTR_CHARSET_FORM to SQLCS_NCHAR is safe
// because Oracle server will deal with the implicit Conversion
// Between CHAR and NCHAR.
-// see: http://download.oracle.com/docs/cd/A91202_01/901_doc/appdev.901/a89857/oci05bnd.htm#422705
+// see: http://download.oracle.com/docs/cd/A91202_01/901_doc/appdev.901/a89857/oci05bnd.htm#422705
static const ub1 qOraCharsetForm = SQLCS_NCHAR;
#endif
@@ -162,6 +164,33 @@ Q_DECLARE_METATYPE(QOCIRowIdPointer)
QT_END_INCLUDE_NAMESPACE
class QOCICols;
+struct QOCIResultPrivate;
+
+class Q_EXPORT_SQLDRIVER_OCI QOCIResult : public QSqlCachedResult
+{
+ friend class QOCIDriver;
+ friend struct QOCIResultPrivate;
+ friend class QOCICols;
+public:
+ QOCIResult(const QOCIDriver * db, const QOCIDriverPrivate* p);
+ ~QOCIResult();
+ bool prepare(const QString& query);
+ bool exec();
+ QVariant handle() const;
+
+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;
+};
struct QOCIResultPrivate
{
@@ -464,8 +493,9 @@ void QOCIResultPrivate::outValues(QVector<QVariant> &values, IndicatorArray &ind
}
-struct QOCIDriverPrivate
+class QOCIDriverPrivate : public QSqlDriverPrivate
{
+public:
QOCIDriverPrivate();
OCIEnv *env;
@@ -483,9 +513,10 @@ struct QOCIDriverPrivate
};
QOCIDriverPrivate::QOCIDriverPrivate()
- : env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false), serverVersion(-1),
- prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM)
+ : QSqlDriverPrivate(), env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false),
+ serverVersion(-1), prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM)
{
+ dbmsType = Oracle;
}
void QOCIDriverPrivate::allocErrorHandle()
@@ -2057,10 +2088,9 @@ void QOCIResult::virtual_hook(int id, void *data)
QOCIDriver::QOCIDriver(QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QOCIDriverPrivate, parent)
{
- d = new QOCIDriverPrivate();
-
+ Q_D(QOCIDriver);
#ifdef QOCI_THREADED
const ub4 mode = OCI_UTF16 | OCI_OBJECT | OCI_THREADED;
#else
@@ -2085,9 +2115,9 @@ QOCIDriver::QOCIDriver(QObject* parent)
}
QOCIDriver::QOCIDriver(OCIEnv* env, OCISvcCtx* ctx, QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QOCIDriverPrivate, parent)
{
- d = new QOCIDriverPrivate();
+ Q_D(QOCIDriver);
d->env = env;
d->svc = ctx;
@@ -2101,6 +2131,7 @@ QOCIDriver::QOCIDriver(OCIEnv* env, OCISvcCtx* ctx, QObject* parent)
QOCIDriver::~QOCIDriver()
{
+ Q_D(QOCIDriver);
if (isOpen())
close();
int r = OCIHandleFree(d->err, OCI_HTYPE_ERROR);
@@ -2109,12 +2140,11 @@ QOCIDriver::~QOCIDriver()
r = OCIHandleFree(d->env, OCI_HTYPE_ENV);
if (r != OCI_SUCCESS)
qWarning("Unable to free Environment handle: %d", r);
-
- delete d;
}
bool QOCIDriver::hasFeature(DriverFeature f) const
{
+ Q_D(const QOCIDriver);
switch (f) {
case Transactions:
case LastInsertId:
@@ -2173,6 +2203,7 @@ bool QOCIDriver::open(const QString & db,
int port,
const QString &opts)
{
+ Q_D(QOCIDriver);
int r;
if (isOpen())
@@ -2183,7 +2214,7 @@ bool QOCIDriver::open(const QString & db,
// Connect without tnsnames.ora if a hostname is given
QString connectionString = db;
if (!hostname.isEmpty())
- connectionString =
+ connectionString =
QString::fromLatin1("(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
"(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
@@ -2259,6 +2290,7 @@ bool QOCIDriver::open(const QString & db,
void QOCIDriver::close()
{
+ Q_D(QOCIDriver);
if (!isOpen())
return;
@@ -2276,11 +2308,13 @@ void QOCIDriver::close()
QSqlResult *QOCIDriver::createResult() const
{
+ Q_D(const QOCIDriver);
return new QOCIResult(this, d);
}
bool QOCIDriver::beginTransaction()
{
+ Q_D(QOCIDriver);
if (!isOpen()) {
qWarning("QOCIDriver::beginTransaction: Database not open");
return false;
@@ -2301,6 +2335,7 @@ bool QOCIDriver::beginTransaction()
bool QOCIDriver::commitTransaction()
{
+ Q_D(QOCIDriver);
if (!isOpen()) {
qWarning("QOCIDriver::commitTransaction: Database not open");
return false;
@@ -2320,6 +2355,7 @@ bool QOCIDriver::commitTransaction()
bool QOCIDriver::rollbackTransaction()
{
+ Q_D(QOCIDriver);
if (!isOpen()) {
qWarning("QOCIDriver::rollbackTransaction: Database not open");
return false;
@@ -2339,6 +2375,7 @@ bool QOCIDriver::rollbackTransaction()
QStringList QOCIDriver::tables(QSql::TableType type) const
{
+ Q_D(const QOCIDriver);
QStringList tl;
QStringList sysUsers = QStringList() << QLatin1String("MDSYS")
<< QLatin1String("LBACSYS")
@@ -2444,6 +2481,7 @@ void qSplitTableAndOwner(const QString & tname, QString * tbl,
QSqlRecord QOCIDriver::record(const QString& tablename) const
{
+ Q_D(const QOCIDriver);
QSqlRecord fil;
if (!isOpen())
return fil;
@@ -2517,6 +2555,7 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const
QSqlIndex QOCIDriver::primaryIndex(const QString& tablename) const
{
+ Q_D(const QOCIDriver);
QSqlIndex idx(tablename);
if (!isOpen())
return idx;
@@ -2637,6 +2676,7 @@ QString QOCIDriver::formatValue(const QSqlField &field, bool trimStrings) const
QVariant QOCIDriver::handle() const
{
+ Q_D(const QOCIDriver);
return QVariant::fromValue(d->env);
}
diff --git a/src/sql/drivers/oci/qsql_oci.pri b/src/sql/drivers/oci/qsql_oci.pri
index 60ccc4c227..66ccdb1abb 100644
--- a/src/sql/drivers/oci/qsql_oci.pri
+++ b/src/sql/drivers/oci/qsql_oci.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_oci.h
+HEADERS += $$PWD/qsql_oci_p.h
SOURCES += $$PWD/qsql_oci.cpp
unix {
@@ -6,4 +6,4 @@ unix {
} else {
LIBS *= -loci
}
-macx:QMAKE_LFLAGS += -Wl,-flat_namespace,-U,_environ
+mac:QMAKE_LFLAGS += -Wl,-flat_namespace,-U,_environ
diff --git a/src/sql/drivers/oci/qsql_oci.h b/src/sql/drivers/oci/qsql_oci_p.h
index 2488e696d2..c55a4209fa 100644
--- a/src/sql/drivers/oci/qsql_oci.h
+++ b/src/sql/drivers/oci/qsql_oci_p.h
@@ -42,9 +42,19 @@
#ifndef QSQL_OCI_H
#define QSQL_OCI_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
-#include <QtSql/private/qsqlcachedresult_p.h>
#ifdef QT_PLUGIN
#define Q_EXPORT_SQLDRIVER_OCI
@@ -52,51 +62,18 @@
#define Q_EXPORT_SQLDRIVER_OCI Q_SQL_EXPORT
#endif
-QT_BEGIN_HEADER
-
typedef struct OCIEnv OCIEnv;
typedef struct OCISvcCtx OCISvcCtx;
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QOCIDriver;
class QOCICols;
-struct QOCIDriverPrivate;
-struct QOCIResultPrivate;
-
-class Q_EXPORT_SQLDRIVER_OCI QOCIResult : public QSqlCachedResult
-{
- friend class QOCIDriver;
- friend struct QOCIResultPrivate;
- friend class QOCICols;
-public:
- QOCIResult(const QOCIDriver * db, const QOCIDriverPrivate* p);
- ~QOCIResult();
- bool prepare(const QString& query);
- bool exec();
- QVariant handle() const;
-
-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;
-};
+class QOCIDriverPrivate;
class Q_EXPORT_SQLDRIVER_OCI QOCIDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QOCIDriver)
Q_OBJECT
friend struct QOCIResultPrivate;
friend class QOCIPrivate;
@@ -125,12 +102,8 @@ protected:
bool beginTransaction();
bool commitTransaction();
bool rollbackTransaction();
-private:
- QOCIDriverPrivate *d;
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSQL_OCI_H
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 9517d95fc4..d36a224d8e 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qsql_odbc.h"
+#include "qsql_odbc_p.h"
#include <qsqlrecord.h>
#if defined (Q_OS_WIN32)
@@ -57,6 +57,7 @@
#include <qmath.h>
#include <QDebug>
#include <QSqlQuery>
+#include <QtSql/private/qsqldriver_p.h>
QT_BEGIN_NAMESPACE
@@ -111,14 +112,13 @@ inline static QVarLengthArray<SQLTCHAR> toSQLTCHAR(const QString &input)
return result;
}
-class QODBCDriverPrivate
+class QODBCDriverPrivate : public QSqlDriverPrivate
{
public:
enum DefaultCase{Lower, Mixed, Upper, Sensitive};
QODBCDriverPrivate()
- : hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), datetime_precision(19), isMySqlServer(false),
- isMSSqlServer(false), isFreeTDSDriver(false), hasSQLFetchScroll(true),
- hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"'))
+ : QSqlDriverPrivate(), hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), datetime_precision(19),
+ isFreeTDSDriver(false), hasSQLFetchScroll(true), hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"'))
{
}
@@ -129,15 +129,13 @@ public:
bool useSchema;
int disconnectCount;
int datetime_precision;
- bool isMySqlServer;
- bool isMSSqlServer;
bool isFreeTDSDriver;
bool hasSQLFetchScroll;
bool hasMultiResultSets;
bool checkDriver() const;
void checkUnicode();
- void checkSqlServer();
+ void checkDBMS();
void checkHasSQLFetchScroll();
void checkHasMultiResults();
void checkSchemaUsage();
@@ -190,13 +188,13 @@ public:
bool QODBCPrivate::isStmtHandleValid(const QSqlDriver *driver)
{
const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver);
- return disconnectCount == odbcdriver->d->disconnectCount;
+ return disconnectCount == odbcdriver->d_func()->disconnectCount;
}
void QODBCPrivate::updateStmtHandleState(const QSqlDriver *driver)
{
const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver);
- disconnectCount = odbcdriver->d->disconnectCount;
+ disconnectCount = odbcdriver->d_func()->disconnectCount;
}
static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode = 0)
@@ -960,11 +958,6 @@ bool QODBCResult::reset (const QString& query)
return false;
}
- if(r == SQL_NO_DATA) {
- setSelect(false);
- return true;
- }
-
SQLINTEGER bufferLength;
SQLULEN isScrollable;
r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, &bufferLength);
@@ -1407,7 +1400,7 @@ bool QODBCResult::exec()
// (How many leading digits do we want to keep? With SQL Server 2005, this should be 3: 123000000)
int keep = (int)qPow(10.0, 9 - qMin(9, precision));
- dt->fraction /= keep * keep;
+ dt->fraction = (dt->fraction / keep) * keep;
}
r = SQLBindParameter(d->hStmt,
@@ -1592,7 +1585,7 @@ bool QODBCResult::exec()
}
}
r = SQLExecute(d->hStmt);
- if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
+ if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r != SQL_NO_DATA) {
qWarning() << "QODBCResult::exec: Unable to execute statement:" << qODBCWarn(d);
setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
"Unable to execute statement"), QSqlError::StatementError, d));
@@ -1677,6 +1670,38 @@ QSqlRecord QODBCResult::record() const
return d->rInf;
}
+QVariant QODBCResult::lastInsertId() const
+{
+ QString sql;
+
+ switch (d->driverPrivate->dbmsType) {
+ case QODBCDriverPrivate::MSSqlServer:
+ case QODBCDriverPrivate::Sybase:
+ sql = QLatin1String("SELECT @@IDENTITY;");
+ break;
+ case QODBCDriverPrivate::MySqlServer:
+ sql = QLatin1String("SELECT LAST_INSERT_ID();");
+ break;
+ case QODBCDriverPrivate::PostgreSQL:
+ sql = QLatin1String("SELECT lastval();");
+ break;
+ default:
+ break;
+ }
+
+ if (!sql.isEmpty()) {
+ QSqlQuery qry(driver()->createResult());
+ if (qry.exec(sql) && qry.next())
+ return qry.value(0);
+
+ qSqlWarning(QLatin1String("QODBCResult::lastInsertId: Unable to get lastInsertId"), d);
+ } else {
+ qSqlWarning(QLatin1String("QODBCResult::lastInsertId: not implemented for this DBMS"), d);
+ }
+
+ return QVariant();
+}
+
QVariant QODBCResult::handle() const
{
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
@@ -1742,15 +1767,14 @@ void QODBCResult::setForwardOnly(bool forward)
QODBCDriver::QODBCDriver(QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QODBCDriverPrivate, parent)
{
- init();
}
-QODBCDriver::QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent)
- : QSqlDriver(parent)
+QODBCDriver::QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject *parent)
+ : QSqlDriver(*new QODBCDriverPrivate, parent)
{
- init();
+ Q_D(QODBCDriver);
d->hEnv = env;
d->hDbc = con;
if (env && con) {
@@ -1759,19 +1783,14 @@ QODBCDriver::QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent)
}
}
-void QODBCDriver::init()
-{
- d = new QODBCDriverPrivate();
-}
-
QODBCDriver::~QODBCDriver()
{
cleanup();
- delete d;
}
bool QODBCDriver::hasFeature(DriverFeature f) const
{
+ Q_D(const QODBCDriver);
switch (f) {
case Transactions: {
if (!d->hDbc)
@@ -1797,16 +1816,20 @@ bool QODBCDriver::hasFeature(DriverFeature f) const
return true;
case QuerySize:
case NamedPlaceholders:
- case LastInsertId:
case BatchOperations:
case SimpleLocking:
case EventNotifications:
case CancelQuery:
return false;
+ case LastInsertId:
+ return (d->dbmsType == QODBCDriverPrivate::MSSqlServer)
+ || (d->dbmsType == QODBCDriverPrivate::Sybase)
+ || (d->dbmsType == QODBCDriverPrivate::MySqlServer)
+ || (d->dbmsType == QODBCDriverPrivate::PostgreSQL);
case MultipleResultSets:
return d->hasMultiResultSets;
case BLOB: {
- if(d->isMySqlServer)
+ if (d->dbmsType == QODBCDriverPrivate::MySqlServer)
return true;
else
return false;
@@ -1822,6 +1845,7 @@ bool QODBCDriver::open(const QString & db,
int,
const QString& connOpts)
{
+ Q_D(QODBCDriver);
if (isOpen())
close();
SQLRETURN r;
@@ -1896,13 +1920,13 @@ bool QODBCDriver::open(const QString & db,
d->checkUnicode();
d->checkSchemaUsage();
- d->checkSqlServer();
+ d->checkDBMS();
d->checkHasSQLFetchScroll();
d->checkHasMultiResults();
d->checkDateTimePrecision();
setOpen(true);
setOpenError(false);
- if(d->isMSSqlServer) {
+ if (d->dbmsType == QODBCDriverPrivate::MSSqlServer) {
QSqlQuery i(createResult());
i.exec(QLatin1String("SET QUOTED_IDENTIFIER ON"));
}
@@ -1918,9 +1942,8 @@ void QODBCDriver::close()
void QODBCDriver::cleanup()
{
+ Q_D(QODBCDriver);
SQLRETURN r;
- if (!d)
- return;
if(d->hDbc) {
// Open statements/descriptors handles are automatically cleaned up by SQLDisconnect
@@ -2069,7 +2092,7 @@ void QODBCDriverPrivate::checkSchemaUsage()
useSchema = (val != 0);
}
-void QODBCDriverPrivate::checkSqlServer()
+void QODBCDriverPrivate::checkDBMS()
{
SQLRETURN r;
QVarLengthArray<SQLTCHAR> serverString(200);
@@ -2088,8 +2111,16 @@ void QODBCDriverPrivate::checkSqlServer()
#else
serverType = QString::fromUtf8((const char *)serverString.constData(), t);
#endif
- isMySqlServer = serverType.contains(QLatin1String("mysql"), Qt::CaseInsensitive);
- isMSSqlServer = serverType.contains(QLatin1String("Microsoft SQL Server"), Qt::CaseInsensitive);
+ if (serverType.contains(QLatin1String("PostgreSQL"), Qt::CaseInsensitive))
+ dbmsType = PostgreSQL;
+ else if (serverType.contains(QLatin1String("Oracle"), Qt::CaseInsensitive))
+ dbmsType = Oracle;
+ else if (serverType.contains(QLatin1String("MySql"), Qt::CaseInsensitive))
+ dbmsType = MySqlServer;
+ else if (serverType.contains(QLatin1String("Microsoft SQL Server"), Qt::CaseInsensitive))
+ dbmsType = MSSqlServer;
+ else if (serverType.contains(QLatin1String("Sybase"), Qt::CaseInsensitive))
+ dbmsType = Sybase;
}
r = SQLGetInfo(hDbc,
SQL_DRIVER_NAME,
@@ -2160,11 +2191,13 @@ void QODBCDriverPrivate::checkDateTimePrecision()
QSqlResult *QODBCDriver::createResult() const
{
- return new QODBCResult(this, d);
+ Q_D(const QODBCDriver);
+ return new QODBCResult(this, const_cast<QODBCDriverPrivate*>(d));
}
bool QODBCDriver::beginTransaction()
{
+ Q_D(QODBCDriver);
if (!isOpen()) {
qWarning() << "QODBCDriver::beginTransaction: Database not open";
return false;
@@ -2184,6 +2217,7 @@ bool QODBCDriver::beginTransaction()
bool QODBCDriver::commitTransaction()
{
+ Q_D(QODBCDriver);
if (!isOpen()) {
qWarning() << "QODBCDriver::commitTransaction: Database not open";
return false;
@@ -2201,6 +2235,7 @@ bool QODBCDriver::commitTransaction()
bool QODBCDriver::rollbackTransaction()
{
+ Q_D(QODBCDriver);
if (!isOpen()) {
qWarning() << "QODBCDriver::rollbackTransaction: Database not open";
return false;
@@ -2218,6 +2253,7 @@ bool QODBCDriver::rollbackTransaction()
bool QODBCDriver::endTrans()
{
+ Q_D(QODBCDriver);
SQLUINTEGER ac(SQL_AUTOCOMMIT_ON);
SQLRETURN r = SQLSetConnectAttr(d->hDbc,
SQL_ATTR_AUTOCOMMIT,
@@ -2232,6 +2268,7 @@ bool QODBCDriver::endTrans()
QStringList QODBCDriver::tables(QSql::TableType type) const
{
+ Q_D(const QODBCDriver);
QStringList tl;
if (!isOpen())
return tl;
@@ -2309,6 +2346,7 @@ QStringList QODBCDriver::tables(QSql::TableType type) const
QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
{
+ Q_D(const QODBCDriver);
QSqlIndex index(tablename);
if (!isOpen())
return index;
@@ -2324,7 +2362,7 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
return index;
}
QString catalog, schema, table;
- d->splitTableQualifier(tablename, catalog, schema, table);
+ const_cast<QODBCDriverPrivate*>(d)->splitTableQualifier(tablename, catalog, schema, table);
if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
catalog = stripDelimiters(catalog, QSqlDriver::TableName);
@@ -2436,13 +2474,14 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
QSqlRecord QODBCDriver::record(const QString& tablename) const
{
+ Q_D(const QODBCDriver);
QSqlRecord fil;
if (!isOpen())
return fil;
SQLHANDLE hStmt;
QString catalog, schema, table;
- d->splitTableQualifier(tablename, catalog, schema, table);
+ const_cast<QODBCDriverPrivate*>(d)->splitTableQualifier(tablename, catalog, schema, table);
if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
catalog = stripDelimiters(catalog, QSqlDriver::TableName);
@@ -2561,12 +2600,14 @@ QString QODBCDriver::formatValue(const QSqlField &field,
QVariant QODBCDriver::handle() const
{
+ Q_D(const QODBCDriver);
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hDbc);
}
QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType) const
{
- QChar quote = d->quoteChar();
+ Q_D(const QODBCDriver);
+ QChar quote = const_cast<QODBCDriverPrivate*>(d)->quoteChar();
QString res = identifier;
if(!identifier.isEmpty() && !identifier.startsWith(quote) && !identifier.endsWith(quote) ) {
res.replace(quote, QString(quote)+QString(quote));
@@ -2578,7 +2619,8 @@ QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType)
bool QODBCDriver::isIdentifierEscaped(const QString &identifier, IdentifierType) const
{
- QChar quote = d->quoteChar();
+ Q_D(const QODBCDriver);
+ QChar quote = const_cast<QODBCDriverPrivate*>(d)->quoteChar();
return identifier.size() > 2
&& identifier.startsWith(quote) //left delimited
&& identifier.endsWith(quote); //right delimited
diff --git a/src/sql/drivers/odbc/qsql_odbc.pri b/src/sql/drivers/odbc/qsql_odbc.pri
index 19ff784a04..b206df37c3 100644
--- a/src/sql/drivers/odbc/qsql_odbc.pri
+++ b/src/sql/drivers/odbc/qsql_odbc.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_odbc.h
+HEADERS += $$PWD/qsql_odbc_p.h
SOURCES += $$PWD/qsql_odbc.cpp
unix {
diff --git a/src/sql/drivers/odbc/qsql_odbc.h b/src/sql/drivers/odbc/qsql_odbc_p.h
index 4fba49b9c5..b18768a5a2 100644
--- a/src/sql/drivers/odbc/qsql_odbc.h
+++ b/src/sql/drivers/odbc/qsql_odbc_p.h
@@ -42,6 +42,17 @@
#ifndef QSQL_ODBC_H
#define QSQL_ODBC_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtSql/qsqldriver.h>
#include <QtSql/qsqlresult.h>
@@ -70,15 +81,8 @@
#include <sqlext.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QODBCPrivate;
class QODBCDriverPrivate;
class QODBCDriver;
@@ -93,6 +97,7 @@ public:
bool prepare(const QString& query);
bool exec();
+ QVariant lastInsertId() const;
QVariant handle() const;
virtual void setForwardOnly(bool forward);
@@ -118,6 +123,7 @@ private:
class Q_EXPORT_SQLDRIVER_ODBC QODBCDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QODBCDriver)
Q_OBJECT
public:
explicit QODBCDriver(QObject *parent=0);
@@ -149,15 +155,11 @@ protected:
bool rollbackTransaction();
private:
- void init();
bool endTrans();
void cleanup();
- QODBCDriverPrivate* d;
friend class QODBCPrivate;
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSQL_ODBC_H
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index 0eadceb1d1..9331f5c371 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qsql_psql.h"
+#include "qsql_psql_p.h"
#include <qcoreapplication.h>
#include <qvariant.h>
@@ -54,6 +54,7 @@
#include <qstringlist.h>
#include <qmutex.h>
#include <QtSql/private/qsqlresult_p.h>
+#include <QtSql/private/qsqldriver_p.h>
#include <libpq-fe.h>
#include <pg_config.h>
@@ -121,17 +122,26 @@ inline void qPQfreemem(void *buffer)
PQfreemem(buffer);
}
-class QPSQLDriverPrivate
+class QPSQLDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QPSQLDriver)
public:
- QPSQLDriverPrivate(QPSQLDriver *qq) : q(qq), connection(0), isUtf8(false), pro(QPSQLDriver::Version6), sn(0), pendingNotifyCheck(false) {}
- QPSQLDriver *q;
+ QPSQLDriverPrivate() : QSqlDriverPrivate(),
+ connection(0),
+ isUtf8(false),
+ pro(QPSQLDriver::Version6),
+ sn(0),
+ pendingNotifyCheck(false),
+ hasBackslashEscape(false)
+ { dbmsType = PostgreSQL; }
+
PGconn *connection;
bool isUtf8;
QPSQLDriver::Protocol pro;
QSocketNotifier *sn;
QStringList seid;
mutable bool pendingNotifyCheck;
+ bool hasBackslashEscape;
void appendTables(QStringList &tl, QSqlQuery &t, QChar type);
PGresult * exec(const char * stmt) const;
@@ -139,6 +149,7 @@ public:
QPSQLDriver::Protocol getPSQLVersion();
bool setEncodingUtf8();
void setDatestyle();
+ void detectBackslashEscape();
};
void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type)
@@ -167,10 +178,11 @@ void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type)
PGresult * QPSQLDriverPrivate::exec(const char * stmt) const
{
+ Q_Q(const QPSQLDriver);
PGresult *result = PQexec(connection, stmt);
if (seid.size() && !pendingNotifyCheck) {
pendingNotifyCheck = true;
- QMetaObject::invokeMethod(q, "_q_handleNotification", Qt::QueuedConnection, Q_ARG(int,0));
+ QMetaObject::invokeMethod(const_cast<QPSQLDriver*>(q), "_q_handleNotification", Qt::QueuedConnection, Q_ARG(int,0));
}
return result;
}
@@ -180,14 +192,25 @@ PGresult * QPSQLDriverPrivate::exec(const QString & stmt) const
return exec(isUtf8 ? stmt.toUtf8().constData() : stmt.toLocal8Bit().constData());
}
-class QPSQLResultPrivate
+class QPSQLResultPrivate : public QSqlResultPrivate
{
+ Q_DECLARE_PUBLIC(QPSQLResult)
public:
- QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1), preparedQueriesEnabled(false) {}
- static QString fieldSerial(int i) { return QLatin1Char('$') + QString::number(i + 1); }
+ QPSQLResultPrivate()
+ : QSqlResultPrivate(),
+ result(0),
+ currentSize(-1),
+ preparedQueriesEnabled(false)
+ { }
+
+ QString fieldSerial(int i) const { 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();
+ }
- QPSQLResult *q;
- const QPSQLDriverPrivate *driver;
PGresult *result;
int currentSize;
bool preparedQueriesEnabled;
@@ -210,6 +233,7 @@ static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type,
bool QPSQLResultPrivate::processResults()
{
+ Q_Q(QPSQLResult);
if (!result)
return false;
@@ -226,7 +250,7 @@ bool QPSQLResultPrivate::processResults()
return true;
}
q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
- "Unable to create query"), QSqlError::StatementError, driver, result));
+ "Unable to create query"), QSqlError::StatementError, privDriver(), result));
return false;
}
@@ -276,42 +300,42 @@ static QVariant::Type qDecodePSQLType(int t)
return type;
}
-static void qDeallocatePreparedStmt(QPSQLResultPrivate *d)
+void QPSQLResultPrivate::deallocatePreparedStmt()
{
- const QString stmt = QLatin1String("DEALLOCATE ") + d->preparedStmtId;
- PGresult *result = d->driver->exec(stmt);
+ const QString stmt = QLatin1String("DEALLOCATE ") + preparedStmtId;
+ PGresult *result = privDriver()->exec(stmt);
if (PQresultStatus(result) != PGRES_COMMAND_OK)
- qWarning("Unable to free statement: %s", PQerrorMessage(d->driver->connection));
+ qWarning("Unable to free statement: %s", PQerrorMessage(privDriver()->connection));
PQclear(result);
- d->preparedStmtId.clear();
+ preparedStmtId.clear();
}
-QPSQLResult::QPSQLResult(const QPSQLDriver* db, const QPSQLDriverPrivate* p)
- : QSqlResult(db)
+QPSQLResult::QPSQLResult(const QPSQLDriver* db)
+ : QSqlResult(*new QPSQLResultPrivate, db)
{
- d = new QPSQLResultPrivate(this);
- d->driver = p;
+ Q_D(QPSQLResult);
d->preparedQueriesEnabled = db->hasFeature(QSqlDriver::PreparedQueries);
}
QPSQLResult::~QPSQLResult()
{
+ Q_D(QPSQLResult);
cleanup();
if (d->preparedQueriesEnabled && !d->preparedStmtId.isNull())
- qDeallocatePreparedStmt(d);
-
- delete d;
+ d->deallocatePreparedStmt();
}
QVariant QPSQLResult::handle() const
{
+ Q_D(const QPSQLResult);
return QVariant::fromValue(d->result);
}
void QPSQLResult::cleanup()
{
+ Q_D(QPSQLResult);
if (d->result)
PQclear(d->result);
d->result = 0;
@@ -322,6 +346,7 @@ void QPSQLResult::cleanup()
bool QPSQLResult::fetch(int i)
{
+ Q_D(const QPSQLResult);
if (!isActive())
return false;
if (i < 0)
@@ -341,11 +366,13 @@ bool QPSQLResult::fetchFirst()
bool QPSQLResult::fetchLast()
{
+ Q_D(const QPSQLResult);
return fetch(PQntuples(d->result) - 1);
}
QVariant QPSQLResult::data(int i)
{
+ Q_D(const QPSQLResult);
if (i >= PQnfields(d->result)) {
qWarning("QPSQLResult::data: column %d out of range", i);
return QVariant();
@@ -359,7 +386,7 @@ QVariant QPSQLResult::data(int i)
case QVariant::Bool:
return QVariant((bool)(val[0] == 't'));
case QVariant::String:
- return d->driver->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val);
+ return d->privDriver()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val);
case QVariant::LongLong:
if (val[0] == '-')
return QString::fromLatin1(val).toLongLong();
@@ -446,34 +473,44 @@ QVariant QPSQLResult::data(int i)
bool QPSQLResult::isNull(int field)
{
+ Q_D(const QPSQLResult);
PQgetvalue(d->result, at(), field);
return PQgetisnull(d->result, at(), field);
}
bool QPSQLResult::reset (const QString& query)
{
+ Q_D(QPSQLResult);
cleanup();
if (!driver())
return false;
if (!driver()->isOpen() || driver()->isOpenError())
return false;
- d->result = d->driver->exec(query);
+ d->result = d->privDriver()->exec(query);
return d->processResults();
}
int QPSQLResult::size()
{
+ Q_D(const QPSQLResult);
return d->currentSize;
}
int QPSQLResult::numRowsAffected()
{
+ Q_D(const QPSQLResult);
return QString::fromLatin1(PQcmdTuples(d->result)).toInt();
}
QVariant QPSQLResult::lastInsertId() const
{
- if (isActive()) {
+ Q_D(const QPSQLResult);
+ if (d->privDriver()->pro >= QPSQLDriver::Version81) {
+ QSqlQuery qry(driver()->createResult());
+ // Most recent sequence value obtained from nextval
+ if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next())
+ return qry.value(0);
+ } else if (isActive()) {
Oid id = PQoidValue(d->result);
if (id != InvalidOid)
return QVariant(id);
@@ -483,6 +520,7 @@ QVariant QPSQLResult::lastInsertId() const
QSqlRecord QPSQLResult::record() const
{
+ Q_D(const QPSQLResult);
QSqlRecord info;
if (!isActive() || !isSelect())
return info;
@@ -490,7 +528,7 @@ QSqlRecord QPSQLResult::record() const
int count = PQnfields(d->result);
for (int i = 0; i < count; ++i) {
QSqlField f;
- if (d->driver->isUtf8)
+ if (d->privDriver()->isUtf8)
f.setName(QString::fromUtf8(PQfname(d->result, i)));
else
f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
@@ -551,22 +589,23 @@ QString qMakePreparedStmtId()
bool QPSQLResult::prepare(const QString &query)
{
+ Q_D(QPSQLResult);
if (!d->preparedQueriesEnabled)
return QSqlResult::prepare(query);
cleanup();
if (!d->preparedStmtId.isEmpty())
- qDeallocatePreparedStmt(d);
+ d->deallocatePreparedStmt();
const QString stmtId = qMakePreparedStmtId();
- const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(QSqlResultPrivate::positionalToNamedBinding(query, QPSQLResultPrivate::fieldSerial));
+ const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query));
- PGresult *result = d->driver->exec(stmt);
+ PGresult *result = d->privDriver()->exec(stmt);
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
- "Unable to prepare statement"), QSqlError::StatementError, d->driver, result));
+ "Unable to prepare statement"), QSqlError::StatementError, d->privDriver(), result));
PQclear(result);
d->preparedStmtId.clear();
return false;
@@ -579,19 +618,20 @@ bool QPSQLResult::prepare(const QString &query)
bool QPSQLResult::exec()
{
+ Q_D(QPSQLResult);
if (!d->preparedQueriesEnabled)
return QSqlResult::exec();
cleanup();
QString stmt;
- const QString params = qCreateParamString(boundValues(), d->q->driver());
+ const QString params = qCreateParamString(boundValues(), driver());
if (params.isEmpty())
stmt = QString::fromLatin1("EXECUTE %1").arg(d->preparedStmtId);
else
stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId).arg(params);
- d->result = d->driver->exec(stmt);
+ d->result = d->privDriver()->exec(stmt);
return d->processResults();
}
@@ -615,6 +655,23 @@ void QPSQLDriverPrivate::setDatestyle()
PQclear(result);
}
+void QPSQLDriverPrivate::detectBackslashEscape()
+{
+ // standard_conforming_strings option introduced in 8.2
+ // http://www.postgresql.org/docs/8.2/static/runtime-config-compatible.html
+ if (pro < QPSQLDriver::Version82) {
+ hasBackslashEscape = true;
+ } else {
+ hasBackslashEscape = false;
+ PGresult* result = exec(QLatin1Literal("SELECT '\\\\' x"));
+ int status = PQresultStatus(result);
+ if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK)
+ if (QString::fromLatin1(PQgetvalue(result, 0, 0)) == QLatin1Literal("\\"))
+ hasBackslashEscape = true;
+ PQclear(result);
+ }
+}
+
static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin)
{
switch (vMaj) {
@@ -714,42 +771,39 @@ QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion()
}
QPSQLDriver::QPSQLDriver(QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QPSQLDriverPrivate, parent)
{
- init();
}
QPSQLDriver::QPSQLDriver(PGconn *conn, QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QPSQLDriverPrivate, parent)
{
- init();
+ Q_D(QPSQLDriver);
d->connection = conn;
if (conn) {
d->pro = d->getPSQLVersion();
+ d->detectBackslashEscape();
setOpen(true);
setOpenError(false);
}
}
-void QPSQLDriver::init()
-{
- d = new QPSQLDriverPrivate(this);
-}
-
QPSQLDriver::~QPSQLDriver()
{
+ Q_D(QPSQLDriver);
if (d->connection)
PQfinish(d->connection);
- delete d;
}
QVariant QPSQLDriver::handle() const
{
+ Q_D(const QPSQLDriver);
return QVariant::fromValue(d->connection);
}
bool QPSQLDriver::hasFeature(DriverFeature f) const
{
+ Q_D(const QPSQLDriver);
switch (f) {
case Transactions:
case QuerySize:
@@ -796,6 +850,7 @@ bool QPSQLDriver::open(const QString & db,
int port,
const QString& connOpts)
{
+ Q_D(QPSQLDriver);
if (isOpen())
close();
QString connectString;
@@ -827,6 +882,7 @@ bool QPSQLDriver::open(const QString & db,
}
d->pro = d->getPSQLVersion();
+ d->detectBackslashEscape();
d->isUtf8 = d->setEncodingUtf8();
d->setDatestyle();
@@ -837,6 +893,7 @@ bool QPSQLDriver::open(const QString & db,
void QPSQLDriver::close()
{
+ Q_D(QPSQLDriver);
if (isOpen()) {
d->seid.clear();
@@ -856,11 +913,12 @@ void QPSQLDriver::close()
QSqlResult *QPSQLDriver::createResult() const
{
- return new QPSQLResult(this, d);
+ return new QPSQLResult(this);
}
bool QPSQLDriver::beginTransaction()
{
+ Q_D(const QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::beginTransaction: Database not open");
return false;
@@ -878,6 +936,7 @@ bool QPSQLDriver::beginTransaction()
bool QPSQLDriver::commitTransaction()
{
+ Q_D(QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::commitTransaction: Database not open");
return false;
@@ -911,6 +970,7 @@ bool QPSQLDriver::commitTransaction()
bool QPSQLDriver::rollbackTransaction()
{
+ Q_D(QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::rollbackTransaction: Database not open");
return false;
@@ -928,6 +988,7 @@ bool QPSQLDriver::rollbackTransaction()
QStringList QPSQLDriver::tables(QSql::TableType type) const
{
+ Q_D(const QPSQLDriver);
QStringList tl;
if (!isOpen())
return tl;
@@ -935,9 +996,9 @@ QStringList QPSQLDriver::tables(QSql::TableType type) const
t.setForwardOnly(true);
if (type & QSql::Tables)
- d->appendTables(tl, t, QLatin1Char('r'));
+ const_cast<QPSQLDriverPrivate*>(d)->appendTables(tl, t, QLatin1Char('r'));
if (type & QSql::Views)
- d->appendTables(tl, t, QLatin1Char('v'));
+ const_cast<QPSQLDriverPrivate*>(d)->appendTables(tl, t, QLatin1Char('v'));
if (type & QSql::SystemTables) {
t.exec(QLatin1String("select relname from pg_class where (relkind = 'r') "
"and (relname like 'pg_%') "));
@@ -959,6 +1020,7 @@ static void qSplitTableName(QString &tablename, QString &schema)
QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
{
+ Q_D(const QPSQLDriver);
QSqlIndex idx(tablename);
if (!isOpen())
return idx;
@@ -1040,6 +1102,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
QSqlRecord QPSQLDriver::record(const QString& tablename) const
{
+ Q_D(const QPSQLDriver);
QSqlRecord info;
if (!isOpen())
return info;
@@ -1177,6 +1240,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
{
+ Q_D(const QPSQLDriver);
QString r;
if (field.isNull()) {
r = QLatin1String("NULL");
@@ -1212,12 +1276,10 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
}
break;
case QVariant::String:
- {
- // Escape '\' characters
r = QSqlDriver::formatValue(field, trimStrings);
- r.replace(QLatin1String("\\"), QLatin1String("\\\\"));
+ if (d->hasBackslashEscape)
+ r.replace(QLatin1String("\\"), QLatin1String("\\\\"));
break;
- }
case QVariant::Bool:
if (field.value().toBool())
r = QLatin1String("TRUE");
@@ -1274,16 +1336,19 @@ QString QPSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType)
bool QPSQLDriver::isOpen() const
{
+ Q_D(const QPSQLDriver);
return PQstatus(d->connection) == CONNECTION_OK;
}
QPSQLDriver::Protocol QPSQLDriver::protocol() const
{
+ Q_D(const QPSQLDriver);
return d->pro;
}
bool QPSQLDriver::subscribeToNotification(const QString &name)
{
+ Q_D(QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::subscribeToNotificationImplementation: database not open.");
return false;
@@ -1321,6 +1386,7 @@ bool QPSQLDriver::subscribeToNotification(const QString &name)
bool QPSQLDriver::unsubscribeFromNotification(const QString &name)
{
+ Q_D(QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::unsubscribeFromNotificationImplementation: database not open.");
return false;
@@ -1352,11 +1418,13 @@ bool QPSQLDriver::unsubscribeFromNotification(const QString &name)
QStringList QPSQLDriver::subscribedToNotifications() const
{
+ Q_D(const QPSQLDriver);
return d->seid;
}
void QPSQLDriver::_q_handleNotification(int)
{
+ Q_D(QPSQLDriver);
d->pendingNotifyCheck = false;
PQconsumeInput(d->connection);
diff --git a/src/sql/drivers/psql/qsql_psql.pri b/src/sql/drivers/psql/qsql_psql.pri
index 9b647d8200..d0ded5e625 100644
--- a/src/sql/drivers/psql/qsql_psql.pri
+++ b/src/sql/drivers/psql/qsql_psql.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_psql.h
+HEADERS += $$PWD/qsql_psql_p.h
SOURCES += $$PWD/qsql_psql.cpp
unix|win32-g++* {
diff --git a/src/sql/drivers/psql/qsql_psql.h b/src/sql/drivers/psql/qsql_psql_p.h
index 444ef1bccc..5f4aa68b9e 100644
--- a/src/sql/drivers/psql/qsql_psql.h
+++ b/src/sql/drivers/psql/qsql_psql_p.h
@@ -42,6 +42,17 @@
#ifndef QSQL_PSQL_H
#define QSQL_PSQL_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
@@ -51,28 +62,21 @@
#define Q_EXPORT_SQLDRIVER_PSQL Q_SQL_EXPORT
#endif
-QT_BEGIN_HEADER
-
typedef struct pg_conn PGconn;
typedef struct pg_result PGresult;
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QPSQLResultPrivate;
-class QPSQLDriverPrivate;
class QPSQLDriver;
class QSqlRecordInfo;
class QPSQLResult : public QSqlResult
{
- friend class QPSQLResultPrivate;
+ Q_DECLARE_PRIVATE(QPSQLResult)
+
public:
- QPSQLResult(const QPSQLDriver* db, const QPSQLDriverPrivate* p);
+ QPSQLResult(const QPSQLDriver* db);
~QPSQLResult();
QVariant handle() const;
@@ -92,13 +96,15 @@ protected:
QVariant lastInsertId() const;
bool prepare(const QString& query);
bool exec();
-
-private:
- QPSQLResultPrivate *d;
};
+class QPSQLDriverPrivate;
+
class Q_EXPORT_SQLDRIVER_PSQL QPSQLDriver : public QSqlDriver
{
+ friend class QPSQLResultPrivate;
+ Q_DECLARE_PRIVATE(QPSQLDriver)
+
Q_OBJECT
public:
enum Protocol {
@@ -150,14 +156,8 @@ protected:
private Q_SLOTS:
void _q_handleNotification(int);
-
-private:
- void init();
- QPSQLDriverPrivate *d;
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSQL_PSQL_H
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index f11279f262..ffeb7921b3 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qsql_sqlite.h"
+#include "qsql_sqlite_p.h"
#include <qcoreapplication.h>
#include <qvariant.h>
@@ -47,6 +47,8 @@
#include <qsqlfield.h>
#include <qsqlindex.h>
#include <qsqlquery.h>
+#include <QtSql/private/qsqlcachedresult_p.h>
+#include <QtSql/private/qsqldriver_p.h>
#include <qstringlist.h>
#include <qvector.h>
#include <qdebug.h>
@@ -67,7 +69,7 @@ Q_DECLARE_METATYPE(sqlite3_stmt*)
QT_BEGIN_NAMESPACE
-static QString _q_escapeIdentifier(const QString &identifier)
+static QString _q_escapeIdentifier(const QString &identifier)
{
QString res = identifier;
if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
@@ -106,10 +108,37 @@ static QSqlError qMakeError(sqlite3 *access, const QString &descr, QSqlError::Er
type, errorCode);
}
-class QSQLiteDriverPrivate
+class QSQLiteResultPrivate;
+
+class QSQLiteResult : public QSqlCachedResult
+{
+ friend class QSQLiteDriver;
+ friend class QSQLiteResultPrivate;
+public:
+ explicit QSQLiteResult(const QSQLiteDriver* db);
+ ~QSQLiteResult();
+ QVariant handle() const;
+
+protected:
+ bool gotoNext(QSqlCachedResult::ValueCache& row, int idx);
+ bool reset(const QString &query);
+ bool prepare(const QString &query);
+ bool exec();
+ int size();
+ int numRowsAffected();
+ QVariant lastInsertId() const;
+ QSqlRecord record() const;
+ void detachFromResultSet();
+ void virtual_hook(int id, void *data);
+
+private:
+ QSQLiteResultPrivate* d;
+};
+
+class QSQLiteDriverPrivate : public QSqlDriverPrivate
{
public:
- inline QSQLiteDriverPrivate() : access(0) {}
+ inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = SQLite; }
sqlite3 *access;
QList <QSQLiteResult *> results;
};
@@ -206,8 +235,7 @@ void QSQLiteResultPrivate::initColumns(bool emptyResultset)
}
}
- int dotIdx = colName.lastIndexOf(QLatin1Char('.'));
- QSqlField fld(colName.mid(dotIdx == -1 ? 0 : dotIdx + 1), fieldType);
+ QSqlField fld(colName, fieldType);
fld.setSqlType(stp);
rInf.append(fld);
}
@@ -318,15 +346,15 @@ QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db)
: QSqlCachedResult(db)
{
d = new QSQLiteResultPrivate(this);
- d->access = db->d->access;
- db->d->results.append(this);
+ d->access = db->d_func()->access;
+ const_cast<QSQLiteDriverPrivate*>(db->d_func())->results.append(this);
}
QSQLiteResult::~QSQLiteResult()
{
const QSqlDriver *sqlDriver = driver();
if (sqlDriver)
- qobject_cast<const QSQLiteDriver *>(sqlDriver)->d->results.removeOne(this);
+ const_cast<QSQLiteDriverPrivate*>(qobject_cast<const QSQLiteDriver *>(sqlDriver)->d_func())->results.removeOne(this);
d->cleanup();
delete d;
}
@@ -502,15 +530,14 @@ QVariant QSQLiteResult::handle() const
/////////////////////////////////////////////////////////
QSQLiteDriver::QSQLiteDriver(QObject * parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QSQLiteDriverPrivate, parent)
{
- d = new QSQLiteDriverPrivate();
}
QSQLiteDriver::QSQLiteDriver(sqlite3 *connection, QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QSQLiteDriverPrivate, parent)
{
- d = new QSQLiteDriverPrivate();
+ Q_D(QSQLiteDriver);
d->access = connection;
setOpen(true);
setOpenError(false);
@@ -519,7 +546,6 @@ QSQLiteDriver::QSQLiteDriver(sqlite3 *connection, QObject *parent)
QSQLiteDriver::~QSQLiteDriver()
{
- delete d;
}
bool QSQLiteDriver::hasFeature(DriverFeature f) const
@@ -552,6 +578,7 @@ bool QSQLiteDriver::hasFeature(DriverFeature f) const
*/
bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &conOpts)
{
+ Q_D(QSQLiteDriver);
if (isOpen())
close();
@@ -595,6 +622,7 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c
void QSQLiteDriver::close()
{
+ Q_D(QSQLiteDriver);
if (isOpen()) {
foreach (QSQLiteResult *result, d->results) {
result->d->finalize();
@@ -751,6 +779,7 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const
QVariant QSQLiteDriver::handle() const
{
+ Q_D(const QSQLiteDriver);
return QVariant::fromValue(d->access);
}
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.pri b/src/sql/drivers/sqlite/qsql_sqlite.pri
index a2e80d4c74..e323f2eba5 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.pri
+++ b/src/sql/drivers/sqlite/qsql_sqlite.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_sqlite.h
+HEADERS += $$PWD/qsql_sqlite_p.h
SOURCES += $$PWD/qsql_sqlite.cpp
!system-sqlite:!contains(LIBS, .*sqlite3.*) {
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.h b/src/sql/drivers/sqlite/qsql_sqlite_p.h
index 0fdcd4e240..526dd9a22a 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.h
+++ b/src/sql/drivers/sqlite/qsql_sqlite_p.h
@@ -42,9 +42,19 @@
#ifndef QSQL_SQLITE_H
#define QSQL_SQLITE_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtSql/qsqldriver.h>
#include <QtSql/qsqlresult.h>
-#include <QtSql/private/qsqlcachedresult_p.h>
struct sqlite3;
@@ -54,46 +64,14 @@ struct sqlite3;
#define Q_EXPORT_SQLDRIVER_SQLITE Q_SQL_EXPORT
#endif
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QSQLiteDriverPrivate;
-class QSQLiteResultPrivate;
class QSQLiteDriver;
-class QSQLiteResult : public QSqlCachedResult
-{
- friend class QSQLiteDriver;
- friend class QSQLiteResultPrivate;
-public:
- explicit QSQLiteResult(const QSQLiteDriver* db);
- ~QSQLiteResult();
- QVariant handle() const;
-
-protected:
- bool gotoNext(QSqlCachedResult::ValueCache& row, int idx);
- bool reset(const QString &query);
- bool prepare(const QString &query);
- bool exec();
- int size();
- int numRowsAffected();
- QVariant lastInsertId() const;
- QSqlRecord record() const;
- void detachFromResultSet();
- void virtual_hook(int id, void *data);
-
-private:
- QSQLiteResultPrivate* d;
-};
-
class Q_EXPORT_SQLDRIVER_SQLITE QSQLiteDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QSQLiteDriver)
Q_OBJECT
friend class QSQLiteResult;
public:
@@ -118,13 +96,8 @@ public:
QSqlIndex primaryIndex(const QString &table) const;
QVariant handle() const;
QString escapeIdentifier(const QString &identifier, IdentifierType) const;
-
-private:
- QSQLiteDriverPrivate* d;
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSQL_SQLITE_H
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
index 02e4004901..7e56d5cc17 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qsql_sqlite2.h"
+#include "qsql_sqlite2_p.h"
#include <qcoreapplication.h>
#include <qvariant.h>
@@ -50,6 +50,8 @@
#include <qsqlfield.h>
#include <qsqlindex.h>
#include <qsqlquery.h>
+#include <QtSql/private/qsqlcachedresult_p.h>
+#include <QtSql/private/qsqldriver_p.h>
#include <qstringlist.h>
#include <qvector.h>
@@ -81,7 +83,7 @@ static QVariant::Type nameToType(const QString& typeName)
return QVariant::String;
}
-class QSQLite2DriverPrivate
+class QSQLite2DriverPrivate : public QSqlDriverPrivate
{
public:
QSQLite2DriverPrivate();
@@ -89,11 +91,36 @@ public:
bool utf8;
};
-QSQLite2DriverPrivate::QSQLite2DriverPrivate() : access(0)
+QSQLite2DriverPrivate::QSQLite2DriverPrivate() : QSqlDriverPrivate(), access(0)
{
utf8 = (qstrcmp(sqlite_encoding, "UTF-8") == 0);
+ dbmsType = SQLite;
}
+class QSQLite2ResultPrivate;
+
+class QSQLite2Result : public QSqlCachedResult
+{
+ friend class QSQLite2Driver;
+ friend class QSQLite2ResultPrivate;
+public:
+ explicit QSQLite2Result(const QSQLite2Driver* db);
+ ~QSQLite2Result();
+ QVariant handle() const;
+
+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;
+};
+
class QSQLite2ResultPrivate
{
public:
@@ -170,7 +197,7 @@ void QSQLite2ResultPrivate::init(const char **cnames, int numCols)
for (int i = 0; i < numCols; ++i) {
const char* lastDot = strrchr(cnames[i], '.');
const char* fieldName = lastDot ? lastDot + 1 : cnames[i];
-
+
//remove quotations around the field name if any
QString fieldStr = QString::fromLatin1(fieldName);
QLatin1Char quote('\"');
@@ -219,7 +246,7 @@ bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int
firstRow.clear();
firstRow.resize(colNum);
}
-
+
switch(res) {
case SQLITE_ROW:
// check to see if should fill out columns
@@ -254,8 +281,8 @@ QSQLite2Result::QSQLite2Result(const QSQLite2Driver* db)
: QSqlCachedResult(db)
{
d = new QSQLite2ResultPrivate(this);
- d->access = db->d->access;
- d->utf8 = db->d->utf8;
+ d->access = db->d_func()->access;
+ d->utf8 = db->d_func()->utf8;
}
QSQLite2Result::~QSQLite2Result()
@@ -349,16 +376,15 @@ QVariant QSQLite2Result::handle() const
/////////////////////////////////////////////////////////
-QSQLite2Driver::QSQLite2Driver(QObject * parent)
- : QSqlDriver(parent)
+QSQLite2Driver::QSQLite2Driver(QObject *parent)
+ : QSqlDriver(*new QSQLite2DriverPrivate, parent)
{
- d = new QSQLite2DriverPrivate();
}
QSQLite2Driver::QSQLite2Driver(sqlite *connection, QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QSQLite2DriverPrivate, parent)
{
- d = new QSQLite2DriverPrivate();
+ Q_D(QSQLite2Driver);
d->access = connection;
setOpen(true);
setOpenError(false);
@@ -367,11 +393,11 @@ QSQLite2Driver::QSQLite2Driver(sqlite *connection, QObject *parent)
QSQLite2Driver::~QSQLite2Driver()
{
- delete d;
}
bool QSQLite2Driver::hasFeature(DriverFeature f) const
{
+ Q_D(const QSQLite2Driver);
switch (f) {
case Transactions:
case SimpleLocking:
@@ -389,6 +415,7 @@ bool QSQLite2Driver::hasFeature(DriverFeature f) const
*/
bool QSQLite2Driver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &)
{
+ Q_D(QSQLite2Driver);
if (isOpen())
close();
@@ -415,6 +442,7 @@ bool QSQLite2Driver::open(const QString & db, const QString &, const QString &,
void QSQLite2Driver::close()
{
+ Q_D(QSQLite2Driver);
if (isOpen()) {
sqlite_close(d->access);
d->access = 0;
@@ -430,6 +458,7 @@ QSqlResult *QSQLite2Driver::createResult() const
bool QSQLite2Driver::beginTransaction()
{
+ Q_D(QSQLite2Driver);
if (!isOpen() || isOpenError())
return false;
@@ -447,6 +476,7 @@ bool QSQLite2Driver::beginTransaction()
bool QSQLite2Driver::commitTransaction()
{
+ Q_D(QSQLite2Driver);
if (!isOpen() || isOpenError())
return false;
@@ -464,6 +494,7 @@ bool QSQLite2Driver::commitTransaction()
bool QSQLite2Driver::rollbackTransaction()
{
+ Q_D(QSQLite2Driver);
if (!isOpen() || isOpenError())
return false;
@@ -560,6 +591,7 @@ QSqlRecord QSQLite2Driver::record(const QString &tbl) const
QVariant QSQLite2Driver::handle() const
{
+ Q_D(const QSQLite2Driver);
return QVariant::fromValue(d->access);
}
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.pri b/src/sql/drivers/sqlite2/qsql_sqlite2.pri
index 9a9f6cdf9e..5baba30db0 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.pri
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_sqlite2.h
+HEADERS += $$PWD/qsql_sqlite2_p.h
SOURCES += $$PWD/qsql_sqlite2.cpp
!contains(LIBS, .*sqlite.*):LIBS += -lsqlite
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.h b/src/sql/drivers/sqlite2/qsql_sqlite2_p.h
index f141ad1cc2..ae38a662ac 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.h
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2_p.h
@@ -42,11 +42,21 @@
#ifndef QSQL_SQLITE2_H
#define QSQL_SQLITE2_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtSql/qsqldriver.h>
#include <QtSql/qsqlresult.h>
#include <QtSql/qsqlrecord.h>
#include <QtSql/qsqlindex.h>
-#include <QtSql/private/qsqlcachedresult_p.h>
#if defined (Q_OS_WIN32)
# include <QtCore/qt_windows.h>
@@ -54,45 +64,16 @@
struct sqlite;
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QSQLite2DriverPrivate;
-class QSQLite2ResultPrivate;
class QSQLite2Driver;
-class QSQLite2Result : public QSqlCachedResult
-{
- friend class QSQLite2Driver;
- friend class QSQLite2ResultPrivate;
-public:
- explicit QSQLite2Result(const QSQLite2Driver* db);
- ~QSQLite2Result();
- QVariant handle() const;
-
-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;
-};
-
class QSQLite2Driver : public QSqlDriver
{
- Q_OBJECT
friend class QSQLite2Result;
+ Q_DECLARE_PRIVATE(QSQLite2Driver)
+ Q_OBJECT
public:
explicit QSQLite2Driver(QObject *parent = 0);
explicit QSQLite2Driver(sqlite *connection, QObject *parent = 0);
@@ -120,13 +101,8 @@ public:
QSqlIndex primaryIndex(const QString &table) const;
QVariant handle() const;
QString escapeIdentifier(const QString &identifier, IdentifierType) const;
-
-private:
- QSQLite2DriverPrivate* d;
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSQL_SQLITE2_H
diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp
index 45bba42ca7..69534fe380 100644
--- a/src/sql/drivers/tds/qsql_tds.cpp
+++ b/src/sql/drivers/tds/qsql_tds.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qsql_tds.h"
+#include "qsql_tds_p.h"
#include <qglobal.h>
#ifdef Q_OS_WIN32 // We assume that MS SQL Server is used. Set Q_USE_SYBASE to force Sybase.
@@ -58,6 +58,8 @@
#include <qsqlfield.h>
#include <qsqlindex.h>
#include <qsqlquery.h>
+#include <QtSql/private/qsqlcachedresult_p.h>
+#include <QtSql/private/qsqldriver_p.h>
#include <qstringlist.h>
#include <qvector.h>
@@ -135,16 +137,43 @@ QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, int errNo =
return QSqlError(QLatin1String("QTDS: ") + err, QString(), type, errNo);
}
-class QTDSDriverPrivate
+class QTDSDriverPrivate : public QSqlDriverPrivate
{
public:
- QTDSDriverPrivate(): login(0), initialized(false) {}
+ QTDSDriverPrivate() : QSqlDriverPrivate(), login(0), initialized(false) { dbmsType = Sybase; }
LOGINREC* login; // login information
QString hostName;
QString db;
bool initialized;
};
+struct QTDSColumnData
+{
+ void *data;
+ DBINT nullbind;
+};
+Q_DECLARE_TYPEINFO(QTDSColumnData, Q_MOVABLE_TYPE);
+
+class QTDSResultPrivate;
+
+class QTDSResult : public QSqlCachedResult
+{
+public:
+ explicit QTDSResult(const QTDSDriver* db);
+ ~QTDSResult();
+ QVariant handle() const;
+
+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;
+};
class QTDSResultPrivate
{
@@ -156,7 +185,7 @@ public:
void addErrorMsg(QString& errMsg) { errorMsgs.append(errMsg); }
QString getErrorMsgs() { return errorMsgs.join(QLatin1String("\n")); }
void clearErrorMsgs() { errorMsgs.clear(); }
- QVector<void *> buffer;
+ QVector<QTDSColumnData> buffer;
QSqlRecord rec;
private:
@@ -298,12 +327,12 @@ QTDSResult::QTDSResult(const QTDSDriver* db)
: QSqlCachedResult(db)
{
d = new QTDSResultPrivate();
- d->login = db->d->login;
+ d->login = db->d_func()->login;
- d->dbproc = dbopen(d->login, const_cast<char*>(db->d->hostName.toLatin1().constData()));
+ d->dbproc = dbopen(d->login, const_cast<char*>(db->d_func()->hostName.toLatin1().constData()));
if (!d->dbproc)
return;
- if (dbuse(d->dbproc, const_cast<char*>(db->d->db.toLatin1().constData())) == FAIL)
+ if (dbuse(d->dbproc, const_cast<char*>(db->d_func()->db.toLatin1().constData())) == FAIL)
return;
// insert d in error handler dict
@@ -325,8 +354,8 @@ void QTDSResult::cleanup()
{
d->clearErrorMsgs();
d->rec.clear();
- for (int i = 0; i < d->buffer.size() / 2; ++i)
- free(d->buffer.at(i * 2));
+ for (int i = 0; i < d->buffer.size(); ++i)
+ free(d->buffer.at(i).data);
d->buffer.clear();
// "can" stands for "cancel"... very clever.
dbcanquery(d->dbproc);
@@ -340,9 +369,9 @@ QVariant QTDSResult::handle() const
return QVariant(qRegisterMetaType<DBPROCESS *>("DBPROCESS*"), &d->dbproc);
}
-static inline bool qIsNull(const void *ind)
+static inline bool qIsNull(const QTDSColumnData &p)
{
- return *reinterpret_cast<const DBINT *>(&ind) == -1;
+ return p.nullbind == -1;
}
bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
@@ -364,33 +393,33 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
int idx = index + i;
switch (d->rec.field(i).type()) {
case QVariant::DateTime:
- if (qIsNull(d->buffer.at(i * 2 + 1))) {
+ if (qIsNull(d->buffer.at(i))) {
values[idx] = QVariant(QVariant::DateTime);
} else {
- DBDATETIME *bdt = (DBDATETIME*) d->buffer.at(i * 2);
+ DBDATETIME *bdt = (DBDATETIME*) d->buffer.at(i).data;
QDate date = QDate::fromString(QLatin1String("1900-01-01"), Qt::ISODate);
QTime time = QTime::fromString(QLatin1String("00:00:00"), Qt::ISODate);
values[idx] = QDateTime(date.addDays(bdt->dtdays), time.addMSecs(int(bdt->dttime / 0.3)));
}
break;
case QVariant::Int:
- if (qIsNull(d->buffer.at(i * 2 + 1)))
+ if (qIsNull(d->buffer.at(i)))
values[idx] = QVariant(QVariant::Int);
else
- values[idx] = *((int*)d->buffer.at(i * 2));
+ values[idx] = *((int*)d->buffer.at(i).data);
break;
case QVariant::Double:
case QVariant::String:
- if (qIsNull(d->buffer.at(i * 2 + 1)))
+ if (qIsNull(d->buffer.at(i)))
values[idx] = QVariant(QVariant::String);
else
- values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed();
+ values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i).data).trimmed();
break;
case QVariant::ByteArray: {
- if (qIsNull(d->buffer.at(i * 2 + 1)))
+ if (qIsNull(d->buffer.at(i)))
values[idx] = QVariant(QVariant::ByteArray);
else
- values[idx] = QByteArray((const char*)d->buffer.at(i * 2));
+ values[idx] = QByteArray((const char*)d->buffer.at(i).data);
break;
}
default:
@@ -430,7 +459,7 @@ bool QTDSResult::reset (const QString& query)
setSelect((DBCMDROW(d->dbproc) == SUCCEED)); // decide whether or not we are dealing with a SELECT query
int numCols = dbnumcols(d->dbproc);
if (numCols > 0) {
- d->buffer.resize(numCols * 2);
+ d->buffer.resize(numCols);
init(numCols);
}
for (int i = 0; i < numCols; ++i) {
@@ -470,11 +499,11 @@ bool QTDSResult::reset (const QString& query)
break;
}
if (ret == SUCCEED) {
- d->buffer[i * 2] = p;
- ret = dbnullbind(d->dbproc, i+1, (DBINT*)(&d->buffer[i * 2 + 1]));
+ d->buffer[i].data = p;
+ ret = dbnullbind(d->dbproc, i+1, &d->buffer[i].nullbind);
} else {
- d->buffer[i * 2] = 0;
- d->buffer[i * 2 + 1] = 0;
+ d->buffer[i].data = 0;
+ d->buffer[i].nullbind = 0;
free(p);
}
if ((ret != SUCCEED) && (ret != -1)) {
@@ -512,14 +541,15 @@ QSqlRecord QTDSResult::record() const
///////////////////////////////////////////////////////////////////
QTDSDriver::QTDSDriver(QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QTDSDriverPrivate, parent)
{
init();
}
QTDSDriver::QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QTDSDriverPrivate, parent)
{
+ Q_D(QTDSDriver);
init();
d->login = rec;
d->hostName = host;
@@ -532,12 +562,13 @@ QTDSDriver::QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QO
QVariant QTDSDriver::handle() const
{
+ Q_D(const QTDSDriver);
return QVariant(qRegisterMetaType<LOGINREC *>("LOGINREC*"), &d->login);
}
void QTDSDriver::init()
{
- d = new QTDSDriverPrivate();
+ Q_D(QTDSDriver);
d->initialized = (dbinit() == SUCCEED);
// the following two code-lines will fail compilation on some FreeTDS versions
// just comment them out if you have FreeTDS (you won't get any errors and warnings then)
@@ -551,7 +582,6 @@ QTDSDriver::~QTDSDriver()
dbmsghandle(0);
// dbexit also calls dbclose if necessary
dbexit();
- delete d;
}
bool QTDSDriver::hasFeature(DriverFeature f) const
@@ -578,6 +608,7 @@ bool QTDSDriver::open(const QString & db,
int /*port*/,
const QString& /*connOpts*/)
{
+ Q_D(QTDSDriver);
if (isOpen())
close();
if (!d->initialized) {
@@ -617,6 +648,7 @@ bool QTDSDriver::open(const QString & db,
void QTDSDriver::close()
{
+ Q_D(QTDSDriver);
if (isOpen()) {
#ifdef Q_USE_SYBASE
dbloginfree(d->login);
diff --git a/src/sql/drivers/tds/qsql_tds.pri b/src/sql/drivers/tds/qsql_tds.pri
index 38aab2f3e4..67d037aa6b 100644
--- a/src/sql/drivers/tds/qsql_tds.pri
+++ b/src/sql/drivers/tds/qsql_tds.pri
@@ -1,4 +1,4 @@
-HEADERS += $$PWD/qsql_tds.h
+HEADERS += $$PWD/qsql_tds_p.h
SOURCES += $$PWD/qsql_tds.cpp
unix|win32-g++*: {
diff --git a/src/sql/drivers/tds/qsql_tds.h b/src/sql/drivers/tds/qsql_tds_p.h
index 38cb2dc42e..dd7088a167 100644
--- a/src/sql/drivers/tds/qsql_tds.h
+++ b/src/sql/drivers/tds/qsql_tds_p.h
@@ -42,9 +42,19 @@
#ifndef QSQL_TDS_H
#define QSQL_TDS_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
-#include <QtSql/private/qsqlcachedresult_p.h>
#ifdef Q_OS_WIN32
#define WIN32_LEAN_AND_MEAN
@@ -67,40 +77,14 @@
#define Q_EXPORT_SQLDRIVER_TDS Q_SQL_EXPORT
#endif
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
-#if 0
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
class QTDSDriverPrivate;
-class QTDSResultPrivate;
class QTDSDriver;
-class QTDSResult : public QSqlCachedResult
-{
-public:
- explicit QTDSResult(const QTDSDriver* db);
- ~QTDSResult();
- QVariant handle() const;
-
-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;
-};
-
class Q_EXPORT_SQLDRIVER_TDS QTDSDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QTDSDriver)
Q_OBJECT
friend class QTDSResult;
public:
@@ -132,11 +116,8 @@ protected:
bool rollbackTransaction();
private:
void init();
- QTDSDriverPrivate *d;
};
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QSQL_TDS_H