SQL/ODBC: misc cleanup

Cleanup the codebase a little bit:
  - move loop variable into for scope
  - use utils functions instead homebrew
  - avoid use of const_cast<>
  - simplify splitTableQualifier()

Change-Id: I6962f01c94a6b4e0e38ad1b229cdf6e8b3308c78
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Christian Ehrlicher 2023-01-25 21:22:09 +01:00
parent 694a92ab24
commit c5a2257e0b

View File

@ -22,6 +22,7 @@
#include <QSqlQuery> #include <QSqlQuery>
#include <QtSql/private/qsqldriver_p.h> #include <QtSql/private/qsqldriver_p.h>
#include <QtSql/private/qsqlresult_p.h> #include <QtSql/private/qsqlresult_p.h>
#include "private/qtools_p.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -112,7 +113,7 @@ public:
void checkDateTimePrecision(); void checkDateTimePrecision();
bool setConnectionOptions(const QString& connOpts); bool setConnectionOptions(const QString& connOpts);
void splitTableQualifier(const QString &qualifier, QString &catalog, void splitTableQualifier(const QString &qualifier, QString &catalog,
QString &schema, QString &table); QString &schema, QString &table) const;
DefaultCase defaultCase() const; DefaultCase defaultCase() const;
QString adjustCase(const QString&) const; QString adjustCase(const QString&) const;
QChar quoteChar(); QChar quoteChar();
@ -843,37 +844,30 @@ bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
} }
void QODBCDriverPrivate::splitTableQualifier(const QString &qualifier, QString &catalog, void QODBCDriverPrivate::splitTableQualifier(const QString &qualifier, QString &catalog,
QString &schema, QString &table) QString &schema, QString &table) const
{ {
if (!useSchema) { if (!useSchema) {
table = qualifier; table = qualifier;
return; return;
} }
QStringList l = qualifier.split(u'.'); const QList<QStringView> l = QStringView(qualifier).split(u'.');
if (l.count() > 3) switch (l.count()) {
return; // can't possibly be a valid table qualifier case 1:
int i = 0, n = l.count();
if (n == 1) {
table = qualifier; table = qualifier;
} else { break;
for (QStringList::Iterator it = l.begin(); it != l.end(); ++it) { case 2:
if (n == 3) { schema = l.at(0).toString();
if (i == 0) { table = l.at(1).toString();
catalog = *it; break;
} else if (i == 1) { case 3:
schema = *it; catalog = l.at(0).toString();
} else if (i == 2) { schema = l.at(1).toString();
table = *it; table = l.at(2).toString();
} break;
} else if (n == 2) { default:
if (i == 0) { qSqlWarning(QString::fromLatin1("QODBCDriver::splitTableQualifier: Unable to split table qualifier '%1'")
schema = *it; .arg(qualifier), this);
} else if (i == 1) { break;
table = *it;
}
}
i++;
}
} }
} }
@ -1016,7 +1010,7 @@ bool QODBCResult::reset (const QString& query)
SQLNumResultCols(d->hStmt, &count); SQLNumResultCols(d->hStmt, &count);
if (count) { if (count) {
setSelect(true); setSelect(true);
for (int i = 0; i < count; ++i) { for (SQLSMALLINT i = 0; i < count; ++i) {
d->rInf.append(qMakeFieldInfo(d, i)); d->rInf.append(qMakeFieldInfo(d, i));
} }
d->fieldCache.resize(count); d->fieldCache.resize(count);
@ -1387,9 +1381,8 @@ bool QODBCResult::exec()
memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN)); memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN));
// bind parameters - only positional binding allowed // bind parameters - only positional binding allowed
int i;
SQLRETURN r; SQLRETURN r;
for (i = 0; i < values.count(); ++i) { for (qsizetype i = 0; i < values.count(); ++i) {
if (bindValueType(i) & QSql::Out) if (bindValueType(i) & QSql::Out)
values[i].detach(); values[i].detach();
const QVariant &val = values.at(i); const QVariant &val = values.at(i);
@ -1692,7 +1685,7 @@ bool QODBCResult::exec()
SQLNumResultCols(d->hStmt, &count); SQLNumResultCols(d->hStmt, &count);
if (count) { if (count) {
setSelect(true); setSelect(true);
for (int i = 0; i < count; ++i) { for (SQLSMALLINT i = 0; i < count; ++i) {
d->rInf.append(qMakeFieldInfo(d, i)); d->rInf.append(qMakeFieldInfo(d, i));
} }
d->fieldCache.resize(count); d->fieldCache.resize(count);
@ -1706,7 +1699,7 @@ bool QODBCResult::exec()
if (!hasOutValues()) if (!hasOutValues())
return true; return true;
for (i = 0; i < values.count(); ++i) { for (qsizetype i = 0; i < values.count(); ++i) {
switch (values.at(i).typeId()) { switch (values.at(i).typeId()) {
case QMetaType::QDate: { case QMetaType::QDate: {
DATE_STRUCT ds = *((DATE_STRUCT *)const_cast<char *>(tmpStorage.at(i).constData())); DATE_STRUCT ds = *((DATE_STRUCT *)const_cast<char *>(tmpStorage.at(i).constData()));
@ -1832,7 +1825,7 @@ bool QODBCResult::nextResult()
SQLNumResultCols(d->hStmt, &count); SQLNumResultCols(d->hStmt, &count);
if (count) { if (count) {
setSelect(true); setSelect(true);
for (int i = 0; i < count; ++i) { for (SQLSMALLINT i = 0; i < count; ++i) {
d->rInf.append(qMakeFieldInfo(d, i)); d->rInf.append(qMakeFieldInfo(d, i));
} }
d->fieldCache.resize(count); d->fieldCache.resize(count);
@ -2124,48 +2117,49 @@ void QODBCDriverPrivate::checkUnicode()
bool QODBCDriverPrivate::checkDriver() const bool QODBCDriverPrivate::checkDriver() const
{ {
#ifdef ODBC_CHECK_DRIVER #ifdef ODBC_CHECK_DRIVER
static const SQLUSMALLINT reqFunc[] = { static constexpr SQLUSMALLINT reqFunc[] = {
SQL_API_SQLDESCRIBECOL, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS, SQL_API_SQLDESCRIBECOL, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS,
SQL_API_SQLGETSTMTATTR, SQL_API_SQLGETDIAGREC, SQL_API_SQLEXECDIRECT, SQL_API_SQLGETSTMTATTR, SQL_API_SQLGETDIAGREC, SQL_API_SQLEXECDIRECT,
SQL_API_SQLGETINFO, SQL_API_SQLTABLES, 0 SQL_API_SQLGETINFO, SQL_API_SQLTABLES
}; };
// these functions are optional // these functions are optional
static const SQLUSMALLINT optFunc[] = { static constexpr SQLUSMALLINT optFunc[] = {
SQL_API_SQLNUMRESULTCOLS, SQL_API_SQLROWCOUNT, 0 SQL_API_SQLNUMRESULTCOLS, SQL_API_SQLROWCOUNT
}; };
SQLRETURN r; SQLRETURN r;
SQLUSMALLINT sup; SQLUSMALLINT sup;
int i;
// check the required functions // check the required functions
for (i = 0; reqFunc[i] != 0; ++i) { for (const SQLUSMALLINT func : reqFunc) {
r = SQLGetFunctions(hDbc, reqFunc[i], &sup); r = SQLGetFunctions(hDbc, func, &sup);
if (r != SQL_SUCCESS) { if (r != SQL_SUCCESS) {
qSqlWarning("QODBCDriver::checkDriver: Cannot get list of supported functions"_L1, this); qSqlWarning("QODBCDriver::checkDriver: Cannot get list of supported functions"_L1, this);
return false; return false;
} }
if (sup == SQL_FALSE) { if (sup == SQL_FALSE) {
qWarning () << "QODBCDriver::open: Warning - Driver doesn't support all needed functionality (" << reqFunc[i] << qWarning () << "QODBCDriver::open: Warning - Driver doesn't support all needed functionality ("
").\nPlease look at the Qt SQL Module Driver documentation for more information."; << func
<< ").\nPlease look at the Qt SQL Module Driver documentation for more information.";
return false; return false;
} }
} }
// these functions are optional and just generate a warning // these functions are optional and just generate a warning
for (i = 0; optFunc[i] != 0; ++i) { for (const SQLUSMALLINT func : optFunc) {
r = SQLGetFunctions(hDbc, optFunc[i], &sup); r = SQLGetFunctions(hDbc, func, &sup);
if (r != SQL_SUCCESS) { if (r != SQL_SUCCESS) {
qSqlWarning("QODBCDriver::checkDriver: Cannot get list of supported functions"_L1, this); qSqlWarning("QODBCDriver::checkDriver: Cannot get list of supported functions"_L1, this);
return false; return false;
} }
if (sup == SQL_FALSE) { if (sup == SQL_FALSE) {
qWarning() << "QODBCDriver::checkDriver: Warning - Driver doesn't support some non-critical functions (" << optFunc[i] << ')'; qWarning() << "QODBCDriver::checkDriver: Warning - Driver doesn't support some non-critical functions ("
<< func << ')';
return true; return true;
} }
} }
@ -2436,7 +2430,7 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
return index; return index;
} }
QString catalog, schema, table; QString catalog, schema, table;
const_cast<QODBCDriverPrivate*>(d)->splitTableQualifier(tablename, catalog, schema, table); d->splitTableQualifier(tablename, catalog, schema, table);
if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
catalog = stripDelimiters(catalog, QSqlDriver::TableName); catalog = stripDelimiters(catalog, QSqlDriver::TableName);
@ -2533,7 +2527,7 @@ QSqlRecord QODBCDriver::record(const QString& tablename) const
SQLHANDLE hStmt; SQLHANDLE hStmt;
QString catalog, schema, table; QString catalog, schema, table;
const_cast<QODBCDriverPrivate*>(d)->splitTableQualifier(tablename, catalog, schema, table); d->splitTableQualifier(tablename, catalog, schema, table);
if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
catalog = stripDelimiters(catalog, QSqlDriver::TableName); catalog = stripDelimiters(catalog, QSqlDriver::TableName);
@ -2625,15 +2619,14 @@ QString QODBCDriver::formatValue(const QSqlField &field,
} else } else
r = "NULL"_L1; r = "NULL"_L1;
} else if (field.metaType().id() == QMetaType::QByteArray) { } else if (field.metaType().id() == QMetaType::QByteArray) {
QByteArray ba = field.value().toByteArray(); const QByteArray ba = field.value().toByteArray();
QString res; r.reserve((ba.size() + 1) * 2);
static const char hexchars[] = "0123456789abcdef"; r = "0x"_L1;
for (int i = 0; i < ba.size(); ++i) { for (const char c : ba) {
uchar s = (uchar) ba[i]; const uchar s = uchar(c);
res += QLatin1Char(hexchars[s >> 4]); r += QLatin1Char(QtMiscUtils::toHexLower(s >> 4));
res += QLatin1Char(hexchars[s & 0x0f]); r += QLatin1Char(QtMiscUtils::toHexLower(s & 0x0f));
} }
r = "0x"_L1 + res;
} else { } else {
r = QSqlDriver::formatValue(field, trimStrings); r = QSqlDriver::formatValue(field, trimStrings);
} }