Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/sql/kernel/qsqldriver.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtSql module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4949
    5050QT_BEGIN_NAMESPACE
     51
     52static QString prepareIdentifier(const QString &identifier,
     53        QSqlDriver::IdentifierType type, const QSqlDriver *driver)
     54{
     55    Q_ASSERT( driver != NULL );
     56    QString ret = identifier;
     57    if (!driver->isIdentifierEscaped(identifier, type)) {
     58        ret = driver->escapeIdentifier(identifier, type);
     59    }
     60    return ret;
     61}
    5162
    5263class QSqlDriverPrivate : public QObjectPrivate
     
    6273    uint isOpenError : 1;
    6374    QSqlError error;
     75    QSql::NumericalPrecisionPolicy precisionPolicy;
    6476};
    6577
    6678inline QSqlDriverPrivate::QSqlDriverPrivate()
    67     : QObjectPrivate(), isOpen(false), isOpenError(false)
     79    : QObjectPrivate(), isOpen(false), isOpenError(false), precisionPolicy(QSql::LowPrecisionDouble)
    6880{
    6981}
     
    373385
    374386    The default implementation does nothing.
     387    \sa isIdentifierEscaped()
    375388 */
    376389QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const
    377390{
    378391    return identifier;
     392}
     393
     394/*!
     395    Returns whether \a identifier is escaped according to the database rules.
     396    \a identifier can either be a table name or field name, dependent
     397    on \a type.
     398
     399    \warning Because of binary compatability constraints, this function is not virtual.
     400    If you want to provide your own implementation in your QSqlDriver subclass,
     401    reimplement the isIdentifierEscapedImplementation() slot in your subclass instead.
     402    The isIdentifierEscapedFunction() will dynamically detect the slot and call it.
     403
     404    \sa stripDelimiters(), escapeIdentifier()
     405 */
     406bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType type) const
     407{
     408    bool result;
     409    QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this),
     410                            "isIdentifierEscapedImplementation", Qt::DirectConnection,
     411                            Q_RETURN_ARG(bool, result),
     412                            Q_ARG(QString, identifier),
     413                            Q_ARG(IdentifierType, type));
     414    return result;
     415}
     416
     417/*!
     418    Returns the \a identifier with the leading and trailing delimiters removed,
     419    \a identifier can either be a table name or field name,
     420    dependent on \a type.  If \a identifier does not have leading
     421    and trailing delimiter characters, \a identifier is returned without
     422    modification.
     423
     424    \warning Because of binary compatability constraints, this function is not virtual,
     425    If you want to provide your own implementation in your QSqlDriver subclass,
     426    reimplement the stripDelimitersImplementation() slot in your subclass instead.
     427    The stripDelimiters() function will dynamically detect the slot and call it.
     428
     429    \since 4.5
     430    \sa isIdentifierEscaped()
     431 */
     432QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const
     433{
     434    QString result;
     435    QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this),
     436                            "stripDelimitersImplementation", Qt::DirectConnection,
     437                            Q_RETURN_ARG(QString, result),
     438                            Q_ARG(QString, identifier),
     439                            Q_ARG(IdentifierType, type));
     440    return result;
    379441}
    380442
     
    398460        for (i = 0; i < rec.count(); ++i) {
    399461            if (rec.isGenerated(i))
    400                 s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));
     462                s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", "));
    401463        }
    402464        if (s.isEmpty())
    403465            return s;
    404466        s.chop(2);
    405         s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(escapeIdentifier(tableName, TableName));
     467        s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName);
    406468        break;
    407469    case WhereStatement:
    408470        if (preparedStatement) {
    409             for (int i = 0; i < rec.count(); ++i)
    410                 s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(
    411                          QLatin1String(" = ? AND "));
     471            for (int i = 0; i < rec.count(); ++i) {
     472                s.append(prepareIdentifier(rec.fieldName(i), FieldName,this));
     473                if (rec.isNull(i))
     474                    s.append(QLatin1String(" IS NULL"));
     475                else
     476                    s.append(QLatin1String(" = ?"));
     477                s.append(QLatin1String(" AND "));
     478            }
    412479        } else {
    413480            for (i = 0; i < rec.count(); ++i) {
    414                 s.append(escapeIdentifier(rec.fieldName(i), FieldName));
     481                s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this));
    415482                QString val = formatValue(rec.field(i));
    416483                if (val == QLatin1String("NULL"))
     
    427494        break;
    428495    case UpdateStatement:
    429         s.append(QLatin1String("UPDATE ")).append(escapeIdentifier(tableName, TableName)).append(
     496        s.append(QLatin1String("UPDATE ")).append(tableName).append(
    430497                 QLatin1String(" SET "));
    431498        for (i = 0; i < rec.count(); ++i) {
    432499            if (!rec.isGenerated(i) || !rec.value(i).isValid())
    433500                continue;
    434             s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1Char('='));
     501            s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1Char('='));
    435502            if (preparedStatement)
    436503                s.append(QLatin1Char('?'));
     
    445512        break;
    446513    case DeleteStatement:
    447         s.append(QLatin1String("DELETE FROM ")).append(escapeIdentifier(tableName, TableName));
     514        s.append(QLatin1String("DELETE FROM ")).append(tableName);
    448515        break;
    449516    case InsertStatement: {
    450         s.append(QLatin1String("INSERT INTO ")).append(escapeIdentifier(tableName, TableName)).append(QLatin1String(" ("));
     517        s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" ("));
    451518        QString vals;
    452519        for (i = 0; i < rec.count(); ++i) {
    453520            if (!rec.isGenerated(i) || !rec.value(i).isValid())
    454521                continue;
    455             s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));
     522            s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", "));
    456523            if (preparedStatement)
    457                 vals.append(QLatin1String("?"));
     524                vals.append(QLatin1Char('?'));
    458525            else
    459526                vals.append(formatValue(rec.field(i)));
     
    465532            vals.chop(2); // remove trailing comma
    466533            s[s.length() - 2] = QLatin1Char(')');
    467             s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1String(")"));
     534            s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1Char(')'));
    468535        }
    469536        break; }
     
    560627        }
    561628        case QVariant::Bool:
    562             if (field.value().toBool())
    563                 r = QLatin1String("1");
    564             else
    565                 r = QLatin1String("0");
     629            r = QString::number(field.value().toBool());
    566630            break;
    567631        case QVariant::ByteArray : {
     
    801865}
    802866
     867/*!
     868    \since 4.6
     869
     870    This slot returns whether \a identifier is escaped according to the database rules.
     871    \a identifier can either be a table name or field name, dependent
     872    on \a type.
     873
     874    Because of binary compatability constraints, isIdentifierEscaped() function
     875    (introduced in Qt 4.5) is not virtual.  Instead, isIdentifierEscaped() will
     876    dynamically detect and call \e this slot.  The default implementation
     877    assumes the escape/delimiter character is a double quote.  Reimplement this
     878    slot in your own QSqlDriver if your database engine uses a different
     879    delimiter character.
     880
     881    \sa isIdentifierEscaped()
     882 */
     883bool QSqlDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const
     884{
     885    Q_UNUSED(type);
     886    return identifier.size() > 2
     887        && identifier.startsWith(QLatin1Char('"')) //left delimited
     888        && identifier.endsWith(QLatin1Char('"')); //right delimited
     889}
     890
     891/*!
     892    \since 4.6
     893
     894    This slot returns \a identifier with the leading and trailing delimiters removed,
     895    \a identifier can either be a tablename or field name, dependent on \a type.
     896    If \a identifier does not have leading and trailing delimiter characters, \a
     897    identifier is returned without modification.
     898
     899    Because of binary compatability constraints, the stripDelimiters() function
     900    (introduced in Qt 4.5) is not virtual.  Instead, stripDelimiters() will
     901    dynamically detect and call \e this slot.  It generally unnecessary
     902    to reimplement this slot.
     903
     904    \sa stripDelimiters()
     905 */
     906QString QSqlDriver::stripDelimitersImplementation(const QString &identifier, IdentifierType type) const
     907{
     908    QString ret;
     909    if (this->isIdentifierEscaped(identifier, type)) {
     910        ret = identifier.mid(1);
     911        ret.chop(1);
     912    } else {
     913        ret = identifier;
     914    }
     915    return ret;
     916}
     917
     918/*!
     919    \since 4.6
     920
     921    Sets the default numerical precision policy used by queries created
     922    by this driver to \a precisionPolicy.
     923
     924    Note: Setting the default precision policy to \a precisionPolicy
     925    doesn't affect any currently active queries.
     926
     927    \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(),
     928    QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy()
     929*/
     930void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
     931{
     932    d_func()->precisionPolicy = precisionPolicy;
     933}
     934
     935/*!
     936    \since 4.6
     937
     938    Returns the current default precision policy for the database connection.
     939
     940    \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(),
     941    QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy()
     942*/
     943QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const
     944{
     945    return d_func()->precisionPolicy;
     946}
     947
    803948QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.