QtSql: cleanup QSqlDriverPrivate and QSqlResultPrivate

Cleanup QSqlDriverPrivate/QSqlResultPrivate and their derived classes
in ODBC, MySql, PostgreSQL and SQLite.

Change-Id: I52e69c00cf981b81dde7c3a0370f86f06ef756bb
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
This commit is contained in:
Christian Ehrlicher 2020-01-26 20:07:50 +01:00
parent fd49b4a2b9
commit 3dd5caaaec
6 changed files with 94 additions and 151 deletions

View File

@ -78,17 +78,14 @@ class QMYSQLDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QMYSQLDriver) Q_DECLARE_PUBLIC(QMYSQLDriver)
public: public:
QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0), QMYSQLDriverPrivate() : QSqlDriverPrivate(QSqlDriver::MySqlServer)
#if QT_CONFIG(textcodec) #if QT_CONFIG(textcodec)
tc(QTextCodec::codecForLocale()), , tc(QTextCodec::codecForLocale())
#else
tc(0),
#endif #endif
preparedQuerysEnabled(false) { dbmsType = QSqlDriver::MySqlServer; } {}
MYSQL *mysql; MYSQL *mysql = nullptr;
QTextCodec *tc; QTextCodec *tc = nullptr;
bool preparedQuerysEnabled = false;
bool preparedQuerysEnabled;
}; };
static inline QString toUnicode(QTextCodec *tc, const char *str) static inline QString toUnicode(QTextCodec *tc, const char *str)
@ -201,46 +198,34 @@ class QMYSQLResultPrivate: public QSqlResultPrivate
public: public:
Q_DECLARE_SQLDRIVER_PRIVATE(QMYSQLDriver) Q_DECLARE_SQLDRIVER_PRIVATE(QMYSQLDriver)
QMYSQLResultPrivate(QMYSQLResult *q, const QMYSQLDriver *drv) using QSqlResultPrivate::QSqlResultPrivate;
: QSqlResultPrivate(q, drv),
result(0),
rowsAffected(0),
hasBlobs(false)
, stmt(0), meta(0), inBinds(0), outBinds(0)
, preparedQuery(false)
{ }
MYSQL_RES *result;
MYSQL_ROW row;
int rowsAffected;
bool bindInValues(); bool bindInValues();
void bindBlobs(); void bindBlobs();
bool hasBlobs; MYSQL_RES *result = nullptr;
MYSQL_ROW row;
struct QMyField struct QMyField
{ {
QMyField() char *outField = nullptr;
: outField(0), nullIndicator(false), bufLength(0ul), MYSQL_FIELD *myField = nullptr;
myField(0), type(QMetaType::UnknownType) QMetaType::Type type = QMetaType::UnknownType;
{} my_bool nullIndicator = false;
char *outField; ulong bufLength = 0ul;
my_bool nullIndicator;
ulong bufLength;
MYSQL_FIELD *myField;
QMetaType::Type type;
}; };
QVector<QMyField> fields; QVector<QMyField> fields;
MYSQL_STMT* stmt; MYSQL_STMT *stmt = nullptr;
MYSQL_RES* meta; MYSQL_RES *meta = nullptr;
MYSQL_BIND *inBinds; MYSQL_BIND *inBinds = nullptr;
MYSQL_BIND *outBinds; MYSQL_BIND *outBinds = nullptr;
bool preparedQuery; int rowsAffected = 0;
bool hasBlobs = false;
bool preparedQuery = false;
}; };
#if QT_CONFIG(textcodec) #if QT_CONFIG(textcodec)

View File

@ -118,23 +118,19 @@ class QODBCDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QODBCDriver) Q_DECLARE_PUBLIC(QODBCDriver)
public: public:
enum DefaultCase{Lower, Mixed, Upper, Sensitive}; enum DefaultCase {Lower, Mixed, Upper, Sensitive};
QODBCDriverPrivate() using QSqlDriverPrivate::QSqlDriverPrivate;
: QSqlDriverPrivate(), hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), datetime_precision(19),
isFreeTDSDriver(false), hasSQLFetchScroll(true), hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"'))
{
}
SQLHANDLE hEnv; SQLHANDLE hEnv = nullptr;
SQLHANDLE hDbc; SQLHANDLE hDbc = nullptr;
bool unicode; int disconnectCount = 0;
bool useSchema; int datetimePrecision = 19;
int disconnectCount; bool unicode = false;
int datetime_precision; bool useSchema = false;
bool isFreeTDSDriver; bool isFreeTDSDriver = false;
bool hasSQLFetchScroll; bool hasSQLFetchScroll = true;
bool hasMultiResultSets; bool hasMultiResultSets = false;
bool checkDriver() const; bool checkDriver() const;
void checkUnicode(); void checkUnicode();
@ -150,8 +146,8 @@ public:
QString adjustCase(const QString&) const; QString adjustCase(const QString&) const;
QChar quoteChar(); QChar quoteChar();
private: private:
bool isQuoteInitialized; bool isQuoteInitialized = false;
QChar quote; QChar quote = QLatin1Char('"');
}; };
class QODBCResultPrivate; class QODBCResultPrivate;
@ -194,10 +190,7 @@ class QODBCResultPrivate: public QSqlResultPrivate
public: public:
Q_DECLARE_SQLDRIVER_PRIVATE(QODBCDriver) Q_DECLARE_SQLDRIVER_PRIVATE(QODBCDriver)
QODBCResultPrivate(QODBCResult *q, const QODBCDriver *db) QODBCResultPrivate(QODBCResult *q, const QODBCDriver *db)
: QSqlResultPrivate(q, db), : QSqlResultPrivate(q, db)
hStmt(0),
useSchema(false),
hasSQLFetchScroll(true)
{ {
unicode = drv_d_func()->unicode; unicode = drv_d_func()->unicode;
useSchema = drv_d_func()->useSchema; useSchema = drv_d_func()->useSchema;
@ -210,16 +203,15 @@ public:
SQLHANDLE dpEnv() const { return drv_d_func() ? drv_d_func()->hEnv : 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 dpDbc() const { return drv_d_func() ? drv_d_func()->hDbc : 0;}
SQLHANDLE hStmt; SQLHANDLE hStmt = nullptr;
bool unicode;
bool useSchema;
QSqlRecord rInf; QSqlRecord rInf;
QVector<QVariant> fieldCache; QVector<QVariant> fieldCache;
int fieldCacheIdx; int fieldCacheIdx = 0;
int disconnectCount; int disconnectCount = 0;
bool hasSQLFetchScroll; bool hasSQLFetchScroll = true;
bool unicode = false;
bool useSchema = false;
bool isStmtHandleValid() const; bool isStmtHandleValid() const;
void updateStmtHandleState(); void updateStmtHandleState();
@ -1464,20 +1456,22 @@ bool QODBCResult::exec()
case QVariant::DateTime: { case QVariant::DateTime: {
QByteArray &ba = tmpStorage[i]; QByteArray &ba = tmpStorage[i];
ba.resize(sizeof(TIMESTAMP_STRUCT)); ba.resize(sizeof(TIMESTAMP_STRUCT));
TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)const_cast<char *>(ba.constData()); TIMESTAMP_STRUCT *dt = reinterpret_cast<TIMESTAMP_STRUCT *>(const_cast<char *>(ba.constData()));
QDateTime qdt = val.toDateTime(); const QDateTime qdt = val.toDateTime();
dt->year = qdt.date().year(); const QDate qdate = qdt.date();
dt->month = qdt.date().month(); const QTime qtime = qdt.time();
dt->day = qdt.date().day(); dt->year = qdate.year();
dt->hour = qdt.time().hour(); dt->month = qdate.month();
dt->minute = qdt.time().minute(); dt->day = qdate.day();
dt->second = qdt.time().second(); dt->hour = qtime.hour();
dt->minute = qtime.minute();
int precision = d->drv_d_func()->datetime_precision - 20; // (20 includes a separating period) dt->second = qtime.second();
// (20 includes a separating period)
const int precision = d->drv_d_func()->datetimePrecision - 20;
if (precision <= 0) { if (precision <= 0) {
dt->fraction = 0; dt->fraction = 0;
} else { } else {
dt->fraction = qdt.time().msec() * 1000000; dt->fraction = qtime.msec() * 1000000;
// (How many leading digits do we want to keep? With SQL Server 2005, this should be 3: 123000000) // (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)); int keep = (int)qPow(10.0, 9 - qMin(9, precision));
@ -1489,7 +1483,7 @@ bool QODBCResult::exec()
qParamType[bindValueType(i) & QSql::InOut], qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TIMESTAMP, SQL_C_TIMESTAMP,
SQL_TIMESTAMP, SQL_TIMESTAMP,
d->drv_d_func()->datetime_precision, d->drv_d_func()->datetimePrecision,
precision, precision,
(void *) dt, (void *) dt,
0, 0,
@ -2245,7 +2239,7 @@ void QODBCDriverPrivate::checkDateTimePrecision()
if ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) if ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO )
{ {
if (SQLGetData(hStmt, 3, SQL_INTEGER, &columnSize, sizeof(columnSize), 0) == SQL_SUCCESS) { if (SQLGetData(hStmt, 3, SQL_INTEGER, &columnSize, sizeof(columnSize), 0) == SQL_SUCCESS) {
datetime_precision = (int)columnSize; datetimePrecision = (int)columnSize;
} }
} }
} }

View File

@ -149,26 +149,17 @@ class QPSQLDriverPrivate final : public QSqlDriverPrivate
{ {
Q_DECLARE_PUBLIC(QPSQLDriver) Q_DECLARE_PUBLIC(QPSQLDriver)
public: public:
QPSQLDriverPrivate() : QSqlDriverPrivate(), QPSQLDriverPrivate() : QSqlDriverPrivate(QSqlDriver::PostgreSQL) {}
connection(nullptr),
isUtf8(false),
pro(QPSQLDriver::Version6),
sn(nullptr),
pendingNotifyCheck(false),
hasBackslashEscape(false),
stmtCount(0),
currentStmtId(InvalidStatementId)
{ dbmsType = QSqlDriver::PostgreSQL; }
PGconn *connection;
bool isUtf8;
QPSQLDriver::Protocol pro;
QSocketNotifier *sn;
QStringList seid; QStringList seid;
mutable bool pendingNotifyCheck; PGconn *connection = nullptr;
bool hasBackslashEscape; QSocketNotifier *sn = nullptr;
int stmtCount; QPSQLDriver::Protocol pro = QPSQLDriver::Version6;
StatementId currentStmtId; StatementId currentStmtId = InvalidStatementId;
int stmtCount = 0;
mutable bool pendingNotifyCheck = false;
bool hasBackslashEscape = false;
bool isUtf8 = false;
void appendTables(QStringList &tl, QSqlQuery &t, QChar type); void appendTables(QStringList &tl, QSqlQuery &t, QChar type);
PGresult *exec(const char *stmt); PGresult *exec(const char *stmt);
@ -297,25 +288,18 @@ class QPSQLResultPrivate : public QSqlResultPrivate
Q_DECLARE_PUBLIC(QPSQLResult) Q_DECLARE_PUBLIC(QPSQLResult)
public: public:
Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver) Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver)
QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv) using QSqlResultPrivate::QSqlResultPrivate;
: QSqlResultPrivate(q, drv),
result(nullptr),
stmtId(InvalidStatementId),
currentSize(-1),
canFetchMoreRows(false),
preparedQueriesEnabled(false)
{ }
QString fieldSerial(int i) const override { return QLatin1Char('$') + QString::number(i + 1); } QString fieldSerial(int i) const override { return QLatin1Char('$') + QString::number(i + 1); }
void deallocatePreparedStmt(); void deallocatePreparedStmt();
PGresult *result;
std::queue<PGresult*> nextResultSets; std::queue<PGresult*> nextResultSets;
QString preparedStmtId; QString preparedStmtId;
StatementId stmtId; PGresult *result = nullptr;
int currentSize; StatementId stmtId = InvalidStatementId;
bool canFetchMoreRows; int currentSize = -1;
bool preparedQueriesEnabled; bool canFetchMoreRows = false;
bool preparedQueriesEnabled = false;
bool processResults(); bool processResults();
}; };

View File

@ -144,42 +144,33 @@ class QSQLiteDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QSQLiteDriver) Q_DECLARE_PUBLIC(QSQLiteDriver)
public: public:
inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; } inline QSQLiteDriverPrivate() : QSqlDriverPrivate(QSqlDriver::SQLite) {}
sqlite3 *access; sqlite3 *access = nullptr;
QList <QSQLiteResult *> results; QVector<QSQLiteResult *> results;
QStringList notificationid; QStringList notificationid;
}; };
class QSQLiteResultPrivate: public QSqlCachedResultPrivate class QSQLiteResultPrivate : public QSqlCachedResultPrivate
{ {
Q_DECLARE_PUBLIC(QSQLiteResult) Q_DECLARE_PUBLIC(QSQLiteResult)
public: public:
Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver) Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver)
QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv); using QSqlCachedResultPrivate::QSqlCachedResultPrivate;
void cleanup(); void cleanup();
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch); bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
// initializes the recordInfo and the cache // initializes the recordInfo and the cache
void initColumns(bool emptyResultset); void initColumns(bool emptyResultset);
void finalize(); void finalize();
sqlite3_stmt *stmt; sqlite3_stmt *stmt = nullptr;
bool skippedStatus; // the status of the fetchNext() that's skipped
bool skipRow; // skip the next fetchNext()?
QSqlRecord rInf; QSqlRecord rInf;
QVector<QVariant> firstRow; QVector<QVariant> firstRow;
bool skippedStatus = false; // the status of the fetchNext() that's skipped
bool skipRow = false; // skip the next fetchNext()?
}; };
QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv)
: QSqlCachedResultPrivate(q, drv),
stmt(0),
skippedStatus(false),
skipRow(false)
{
}
void QSQLiteResultPrivate::cleanup() void QSQLiteResultPrivate::cleanup()
{ {
Q_Q(QSQLiteResult); Q_Q(QSQLiteResult);

View File

@ -63,19 +63,16 @@ class QSqlDriverPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QSqlDriver) Q_DECLARE_PUBLIC(QSqlDriver)
public: public:
QSqlDriverPrivate() QSqlDriverPrivate(QSqlDriver::DbmsType type = QSqlDriver::UnknownDbms)
: QObjectPrivate(), : QObjectPrivate(),
isOpen(false), dbmsType(type)
isOpenError(false),
precisionPolicy(QSql::LowPrecisionDouble),
dbmsType(QSqlDriver::UnknownDbms)
{ } { }
uint isOpen;
uint isOpenError;
QSqlError error; QSqlError error;
QSql::NumericalPrecisionPolicy precisionPolicy; QSql::NumericalPrecisionPolicy precisionPolicy = QSql::LowPrecisionDouble;
QSqlDriver::DbmsType dbmsType; QSqlDriver::DbmsType dbmsType;
bool isOpen = false;
bool isOpenError = false;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -79,14 +79,7 @@ class Q_SQL_EXPORT QSqlResultPrivate
public: public:
QSqlResultPrivate(QSqlResult *q, const QSqlDriver *drv) QSqlResultPrivate(QSqlResult *q, const QSqlDriver *drv)
: q_ptr(q), : q_ptr(q),
sqldriver(const_cast<QSqlDriver*>(drv)), sqldriver(const_cast<QSqlDriver*>(drv))
idx(QSql::BeforeFirstRow),
active(false),
isSel(false),
forwardOnly(false),
precisionPolicy(QSql::LowPrecisionDouble),
bindCount(0),
binds(QSqlResult::PositionalBinding)
{ } { }
virtual ~QSqlResultPrivate() { } virtual ~QSqlResultPrivate() { }
@ -119,18 +112,17 @@ public:
QString namedToPositionalBinding(const QString &query); QString namedToPositionalBinding(const QString &query);
QString holderAt(int index) const; QString holderAt(int index) const;
QSqlResult *q_ptr; QSqlResult *q_ptr = nullptr;
QPointer<QSqlDriver> sqldriver; QPointer<QSqlDriver> sqldriver;
int idx;
QString sql; QString sql;
bool active;
bool isSel;
QSqlError error; QSqlError error;
bool forwardOnly; QSql::NumericalPrecisionPolicy precisionPolicy = QSql::LowPrecisionDouble;
QSql::NumericalPrecisionPolicy precisionPolicy; QSqlResult::BindingSyntax binds = QSqlResult::PositionalBinding;
int idx = QSql::BeforeFirstRow;
int bindCount; int bindCount = 0;
QSqlResult::BindingSyntax binds; bool active = false;
bool isSel = false;
bool forwardOnly = false;
QString executedQuery; QString executedQuery;
QHash<int, QSql::ParamType> types; QHash<int, QSql::ParamType> types;