diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2016-02-15 13:17:21 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2016-02-17 16:17:46 +0000 |
commit | 88e043a8bd1b49949777c90c75ff36314af7fe0f (patch) | |
tree | 4d08b880952a5f2ee9fc2e73b2d7401a8b5fb586 /src/sql/drivers/oci/qsql_oci.cpp | |
parent | de8229f37054b195bab4ca8e8a994832a60ae3a0 (diff) |
QOCIDriver: optimize string handling in tables()
- Instead of a QStringList, use a const char 2D array
to hold the system user names. Don't remove the
current user from that list, skip it duing processing.
- Extract Method make_where_clause, optimize it and
cache its result. Instead of creating a QStringList
and join()ing it at the end (sometimes twice), append
to the result QString directly. Reserve the max size
of the result string, which is statically known.
- Keep the query select statements in QLatin1String.
They are only used in QStringBuilder expressions.
Change-Id: I0593d2812da671a541d49a6136f3ff3d784c63d5
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/sql/drivers/oci/qsql_oci.cpp')
-rw-r--r-- | src/sql/drivers/oci/qsql_oci.cpp | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index 14a04d269f..47d6db7ea4 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -2386,17 +2386,46 @@ bool QOCIDriver::rollbackTransaction() return true; } +enum Expression { + OrExpression, + AndExpression +}; + +static QString make_where_clause(const QString &user, Expression e) +{ + static const char sysUsers[][8] = { + "MDSYS", + "LBACSYS", + "SYS", + "SYSTEM", + "WKSYS", + "CTXSYS", + "WMSYS", + }; + static const char joinC[][4] = { "or" , "and" }; + static Q_CONSTEXPR QLatin1Char bang[] = { QLatin1Char(' '), QLatin1Char('!') }; + + const QLatin1String join(joinC[e], -1); // -1: force strlen call + + QString result; + result.reserve(sizeof sysUsers / sizeof *sysUsers * + // max-sizeof(owner != <sysuser> and ) + (9 + sizeof *sysUsers + 5)); + for (const auto &sysUser : sysUsers) { + const QLatin1String l1(sysUser, -1); // -1: force strlen call + if (l1 != user) + result += QLatin1String("owner ") + bang[e] + QLatin1String("= '") + l1 + QLatin1Char(' ') + join + QLatin1Char(' '); + } + + result.chop(join.size() + 2); // remove final " <join> " + + return result; +} + QStringList QOCIDriver::tables(QSql::TableType type) const { Q_D(const QOCIDriver); QStringList tl; - QStringList sysUsers = QStringList() << QLatin1String("MDSYS") - << QLatin1String("LBACSYS") - << QLatin1String("SYS") - << QLatin1String("SYSTEM") - << QLatin1String("WKSYS") - << QLatin1String("CTXSYS") - << QLatin1String("WMSYS"); QString user = d->user; if ( isIdentifierEscaped(user, QSqlDriver::TableName)) @@ -2404,21 +2433,15 @@ QStringList QOCIDriver::tables(QSql::TableType type) const else user = user.toUpper(); - if(sysUsers.contains(user)) - sysUsers.removeAll(user);; - if (!isOpen()) return tl; QSqlQuery t(createResult()); t.setForwardOnly(true); if (type & QSql::Tables) { - QString query = QLatin1String("select owner, table_name from all_tables where "); - QStringList whereList; - foreach(const QString &sysUserName, sysUsers) - whereList << QLatin1String("owner != '") + sysUserName + QLatin1String("' "); - t.exec(query + whereList.join(QLatin1String(" and "))); - + const QLatin1String tableQuery("select owner, table_name from all_tables where "); + const QString where = make_where_clause(user, AndExpression); + t.exec(tableQuery + where); while (t.next()) { if (t.value(0).toString().toUpper() != user.toUpper()) tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString()); @@ -2427,8 +2450,8 @@ QStringList QOCIDriver::tables(QSql::TableType type) const } // list all table synonyms as well - query = QLatin1String("select owner, synonym_name from all_synonyms where "); - t.exec(query + whereList.join(QLatin1String(" and "))); + const QLatin1String synonymQuery("select owner, synonym_name from all_synonyms where "); + t.exec(synonymQuery + where); while (t.next()) { if (t.value(0).toString() != d->user) tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString()); @@ -2437,11 +2460,9 @@ QStringList QOCIDriver::tables(QSql::TableType type) const } } if (type & QSql::Views) { - QString query = QLatin1String("select owner, view_name from all_views where "); - QStringList whereList; - foreach(const QString &sysUserName, sysUsers) - whereList << QLatin1String("owner != '") + sysUserName + QLatin1String("' "); - t.exec(query + whereList.join(QLatin1String(" and "))); + const QLatin1String query("select owner, view_name from all_views where "); + const QString where = make_where_clause(user, AndExpression); + t.exec(query + where); while (t.next()) { if (t.value(0).toString().toUpper() != d->user.toUpper()) tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString()); @@ -2454,12 +2475,9 @@ QStringList QOCIDriver::tables(QSql::TableType type) const while (t.next()) { tl.append(t.value(0).toString()); } - QString query = QLatin1String("select owner, table_name from all_tables where "); - QStringList whereList; - foreach(const QString &sysUserName, sysUsers) - whereList << QLatin1String("owner = '") + sysUserName + QLatin1String("' "); - t.exec(query + whereList.join(QLatin1String(" or "))); - + const QLatin1String tableQuery("select owner, table_name from all_tables where "); + const QString where = make_where_clause(user, OrExpression); + t.exec(tableQuery + where); while (t.next()) { if (t.value(0).toString().toUpper() != user.toUpper()) tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString()); @@ -2468,8 +2486,8 @@ QStringList QOCIDriver::tables(QSql::TableType type) const } // list all table synonyms as well - query = QLatin1String("select owner, synonym_name from all_synonyms where "); - t.exec(query + whereList.join(QLatin1String(" or "))); + const QLatin1String synonymQuery("select owner, synonym_name from all_synonyms where "); + t.exec(synonymQuery + where); while (t.next()) { if (t.value(0).toString() != d->user) tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString()); |