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:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/sql/drivers/odbc/qsql_odbc.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**
     
    5656#include <qvector.h>
    5757#include <QDebug>
     58#include <QSqlQuery>
    5859
    5960QT_BEGIN_NAMESPACE
     
    7071
    7172// newer platform SDKs use SQLLEN instead of SQLINTEGER
    72 #if defined(SQLLEN) || defined(Q_OS_WIN64)
     73#if defined(WIN32) && (_MSC_VER < 1300)
     74# define QSQLLEN SQLINTEGER
     75# define QSQLULEN SQLUINTEGER
     76#else
    7377# define QSQLLEN SQLLEN
    74 #else
    75 # define QSQLLEN SQLINTEGER
    76 #endif
    77 
    78 #if defined(SQLULEN) || defined(Q_OS_WIN64)
    7978# define QSQLULEN SQLULEN
    80 #else
    81 # define QSQLULEN SQLUINTEGER
    82 #endif
     79#endif
     80
    8381
    8482static const int COLNAMESIZE = 256;
     
    8987{
    9088public:
     89    enum DefaultCase{Lower, Mixed, Upper, Sensitive};
    9190    QODBCDriverPrivate()
    9291    : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false),
    93            isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false)
     92           isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false),
     93           isQuoteInitialized(false), quote(QLatin1Char('"'))
    9494    {
    95         sql_char_type = sql_varchar_type = sql_longvarchar_type = QVariant::ByteArray;
    9695        unicode = false;
    9796    }
     
    102101    uint unicode :1;
    103102    uint useSchema :1;
    104     QVariant::Type sql_char_type;
    105     QVariant::Type sql_varchar_type;
    106     QVariant::Type sql_longvarchar_type;
    107103    int disconnectCount;
    108104    bool isMySqlServer;
     
    120116    void splitTableQualifier(const QString &qualifier, QString &catalog,
    121117                             QString &schema, QString &table);
     118    DefaultCase defaultCase() const;
     119    QString adjustCase(const QString&) const;
     120    QChar quoteChar();
     121private:
     122    bool isQuoteInitialized;
     123    QChar quote;
    122124};
    123125
     
    125127{
    126128public:
    127     QODBCPrivate()
    128     : hEnv(0), hDbc(0), hStmt(0), useSchema(false), hasSQLFetchScroll(true), precisionPolicy(QSql::HighPrecision)
     129    QODBCPrivate(QODBCDriverPrivate *dpp)
     130    : hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false)
    129131    {
    130         sql_char_type = sql_varchar_type = sql_longvarchar_type = QVariant::ByteArray;
    131132        unicode = false;
    132133    }
     
    135136    { fieldCache.fill(QVariant()); fieldCacheIdx = 0; }
    136137
    137     SQLHANDLE hEnv;
    138     SQLHANDLE hDbc;
     138    SQLHANDLE dpEnv() const { return driverPrivate ? driverPrivate->hEnv : 0;}
     139    SQLHANDLE dpDbc() const { return driverPrivate ? driverPrivate->hDbc : 0;}
    139140    SQLHANDLE hStmt;
    140141
    141142    uint unicode :1;
    142143    uint useSchema :1;
    143     QVariant::Type sql_char_type;
    144     QVariant::Type sql_varchar_type;
    145     QVariant::Type sql_longvarchar_type;
    146144
    147145    QSqlRecord rInf;
     
    150148    int disconnectCount;
    151149    bool hasSQLFetchScroll;
    152     QSql::NumericalPrecisionPolicy precisionPolicy;
     150    QODBCDriverPrivate *driverPrivate;
     151    bool userForwardOnly;
    153152
    154153    bool isStmtHandleValid(const QSqlDriver *driver);
     
    174173    SQLRETURN r = SQL_NO_DATA;
    175174    SQLTCHAR state_[SQL_SQLSTATE_SIZE+1];
    176     SQLTCHAR description_[SQL_MAX_MESSAGE_LENGTH];
     175    QVarLengthArray<SQLTCHAR> description_(SQL_MAX_MESSAGE_LENGTH);
    177176    QString result;
    178177    int i = 1;
    179178
    180179    description_[0] = 0;
     180    r = SQLGetDiagRec(handleType,
     181                      handle,
     182                      i,
     183                      state_,
     184                      &nativeCode_,
     185                      0,
     186                      NULL,
     187                      &msgLen);
     188    if(r == SQL_NO_DATA)
     189        return QString();
     190    description_.resize(msgLen+1);
    181191    do {
    182192        r = SQLGetDiagRec(handleType,
    183193                            handle,
    184194                            i,
    185                             (SQLTCHAR*)state_,
     195                            state_,
    186196                            &nativeCode_,
    187                             (SQLTCHAR*)description_,
    188                             SQL_MAX_MESSAGE_LENGTH, /* in bytes, not in characters */
     197                            description_.data(),
     198                            description_.size(),
    189199                            &msgLen);
    190200        if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
     
    193203            QString tmpstore;
    194204#ifdef UNICODE
    195             tmpstore = QString((const QChar*)description_, msgLen);
     205            tmpstore = QString((const QChar*)description_.data(), msgLen);
    196206#else
    197             tmpstore = QString::fromLocal8Bit((const char*)description_, msgLen);
     207            tmpstore = QString::fromLocal8Bit((const char*)description_.data(), msgLen);
    198208#endif
    199209            if(result != tmpstore) {
     
    212222static QString qODBCWarn(const QODBCPrivate* odbc, int *nativeCode = 0)
    213223{
    214     return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1String(" ")
    215              + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->hDbc) + QLatin1String(" ")
     224    return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->dpEnv()) + QLatin1Char(' ')
     225             + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->dpDbc()) + QLatin1Char(' ')
    216226             + qWarnODBCHandle(SQL_HANDLE_STMT, odbc->hStmt, nativeCode));
    217227}
     
    219229static QString qODBCWarn(const QODBCDriverPrivate* odbc, int *nativeCode = 0)
    220230{
    221     return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1String(" ")
     231    return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1Char(' ')
    222232             + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->hDbc, nativeCode));
    223233}
     
    251261static QVariant::Type qDecodeODBCType(SQLSMALLINT sqltype, const T* p, bool isSigned = true)
    252262{
     263    Q_UNUSED(p);
    253264    QVariant::Type type = QVariant::Invalid;
    254265    switch (sqltype) {
     
    263274    case SQL_INTEGER:
    264275    case SQL_BIT:
     276        type = isSigned ? QVariant::Int : QVariant::UInt;
     277        break;
    265278    case SQL_TINYINT:
    266         type = isSigned ? QVariant::Int : QVariant::UInt;
     279        type = QVariant::UInt;
    267280        break;
    268281    case SQL_BIGINT:
     
    294307#endif
    295308    case SQL_CHAR:
    296         type = p->sql_char_type;
    297         break;
    298309    case SQL_VARCHAR:
    299310    case SQL_GUID:
    300         type = p->sql_varchar_type;
    301         break;
    302311    case SQL_LONGVARCHAR:
    303         type = p->sql_longvarchar_type;
     312        type = QVariant::String;
    304313        break;
    305314    default:
     
    327336        }
    328337    }
    329     char* buf = new char[colSize];
     338    QVarLengthArray<char> buf(colSize);
    330339    while (true) {
    331340        r = SQLGetData(hStmt,
    332341                        column+1,
    333342                        unicode ? SQL_C_WCHAR : SQL_C_CHAR,
    334                         (SQLPOINTER)buf,
     343                        (SQLPOINTER)buf.data(),
    335344                        colSize,
    336345                        &lengthIndicator);
     
    347356            int rSize = (r == SQL_SUCCESS_WITH_INFO) ? (unicode ? colSize-2 : colSize-1) : lengthIndicator;
    348357            if (unicode) {
    349                 fieldVal += QString((QChar*) buf, rSize / 2);
     358                fieldVal += QString((const QChar*) buf.constData(), rSize / 2);
    350359            } else {
    351                 fieldVal += QString::fromAscii(buf, rSize);
     360                fieldVal += QString::fromAscii(buf.constData(), rSize);
    352361            }
    353             if (fieldVal.size() + lengthIndicator >= colSize) {
     362            memset(buf.data(), 0, colSize);
     363            if (lengthIndicator < colSize) {
    354364                // workaround for Drivermanagers that don't return SQL_NO_DATA
    355365                break;
     
    363373        }
    364374    }
    365     delete[] buf;
    366375    return fieldVal;
    367376}
     
    443452}
    444453
     454static QVariant qGetDoubleData(SQLHANDLE hStmt, int column)
     455{
     456    SQLDOUBLE dblbuf;
     457    QSQLLEN lengthIndicator = 0;
     458    SQLRETURN r = SQLGetData(hStmt,
     459                              column+1,
     460                              SQL_C_DOUBLE,
     461                              (SQLPOINTER) &dblbuf,
     462                              0,
     463                              &lengthIndicator);
     464    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
     465        return QVariant(QVariant::Invalid);
     466    }
     467    if(lengthIndicator == SQL_NULL_DATA)
     468        return QVariant(QVariant::Double);
     469
     470    return (double) dblbuf;
     471}
     472
     473
    445474static QVariant qGetBigIntData(SQLHANDLE hStmt, int column, bool isSigned = true)
    446475{
     
    552581    if (connOpts.contains(QLatin1String("SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC3"), Qt::CaseInsensitive))
    553582        return SQL_OV_ODBC3;
    554 #endif 
     583#endif
    555584    return SQL_OV_ODBC2;
    556585}
     586
     587QChar QODBCDriverPrivate::quoteChar()
     588{
     589    if (!isQuoteInitialized) {
     590        char driverResponse[4];
     591        SQLSMALLINT length;
     592        int r = SQLGetInfo(hDbc,
     593                SQL_IDENTIFIER_QUOTE_CHAR,
     594                &driverResponse,
     595                sizeof(driverResponse),
     596                &length);
     597        if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
     598            quote = QLatin1Char(driverResponse[0]);
     599        } else {
     600            quote = QLatin1Char('"');
     601        }
     602        isQuoteInitialized = true;
     603    }
     604    return quote;
     605}
     606
    557607
    558608bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
     
    706756}
    707757
     758QODBCDriverPrivate::DefaultCase QODBCDriverPrivate::defaultCase() const
     759{
     760    DefaultCase ret;
     761    SQLUSMALLINT casing;
     762    int r = SQLGetInfo(hDbc,
     763            SQL_IDENTIFIER_CASE,
     764            &casing,
     765            sizeof(casing),
     766            NULL);
     767    if ( r != SQL_SUCCESS)
     768        ret = Mixed;//arbitrary case if driver cannot be queried
     769    else {
     770        switch (casing) {
     771            case (SQL_IC_UPPER):
     772                ret = Upper;
     773                break;
     774            case (SQL_IC_LOWER):
     775                ret = Lower;
     776                break;
     777            case (SQL_IC_SENSITIVE):
     778                ret = Sensitive;
     779                break;
     780            case (SQL_IC_MIXED):
     781            default:
     782                ret = Mixed;
     783                break;
     784        }
     785    }
     786    return ret;
     787}
     788
     789/*
     790   Adjust the casing of an identifier to match what the
     791   database engine would have done to it.
     792*/
     793QString QODBCDriverPrivate::adjustCase(const QString &identifier) const
     794{
     795    QString ret = identifier;
     796    switch(defaultCase()) {
     797        case (Lower):
     798            ret = identifier.toLower();
     799            break;
     800        case (Upper):
     801            ret = identifier.toUpper();
     802            break;
     803        case(Mixed):
     804        case(Sensitive):
     805        default:
     806            ret = identifier;
     807    }
     808    return ret;
     809}
     810
    708811////////////////////////////////////////////////////////////////////////////
    709812
     
    711814: QSqlResult(db)
    712815{
    713     d = new QODBCPrivate();
    714     d->hEnv = p->hEnv;
    715     d->hDbc = p->hDbc;
     816    d = new QODBCPrivate(p);
    716817    d->unicode = p->unicode;
    717818    d->useSchema = p->useSchema;
    718     d->sql_char_type = p->sql_char_type;
    719     d->sql_varchar_type = p->sql_varchar_type;
    720     d->sql_longvarchar_type = p->sql_longvarchar_type;
    721819    d->disconnectCount = p->disconnectCount;
    722820    d->hasSQLFetchScroll = p->hasSQLFetchScroll;
     
    754852    }
    755853    r  = SQLAllocHandle(SQL_HANDLE_STMT,
    756                          d->hDbc,
     854                         d->dpDbc(),
    757855                         &d->hStmt);
    758856    if (r != SQL_SUCCESS) {
     
    763861    d->updateStmtHandleState(driver());
    764862
    765     if (isForwardOnly()) {
     863    if (d->userForwardOnly) {
    766864        r = SQLSetStmtAttr(d->hStmt,
    767865                            SQL_ATTR_CURSOR_TYPE,
     
    796894        return false;
    797895    }
     896
     897    SQLINTEGER isScrollable, bufferLength;
     898    r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, &bufferLength);
     899    if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
     900        QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE);
    798901
    799902    SQLSMALLINT count;
     
    883986                       SQL_FETCH_FIRST,
    884987                       0);
    885     if (r != SQL_SUCCESS) { 
     988    if (r != SQL_SUCCESS) {
    886989        if (r != SQL_NO_DATA)
    887990            setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
     
    9021005                       SQL_FETCH_PRIOR,
    9031006                       0);
    904     if (r != SQL_SUCCESS) { 
     1007    if (r != SQL_SUCCESS) {
    9051008        if (r != SQL_NO_DATA)
    9061009            setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
     
    9331036                       SQL_FETCH_LAST,
    9341037                       0);
    935     if (r != SQL_SUCCESS) { 
     1038    if (r != SQL_SUCCESS) {
    9361039        if (r != SQL_NO_DATA)
    9371040            setLastError(qMakeError(QCoreApplication::translate("QODBCResult",
     
    10241127            break;
    10251128        case QVariant::String:
    1026             d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), true);
     1129            d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), d->unicode);
    10271130            break;
    10281131        case QVariant::Double:
    1029             {
    1030                 QString value=qGetStringData(d->hStmt, i, info.length(), false);
    1031                 bool ok=false;
    1032                 switch(d->precisionPolicy) {
    1033                     case QSql::LowPrecisionInt32:
    1034                         d->fieldCache[i] = value.toInt(&ok);
    1035                         break;
    1036                     case QSql::LowPrecisionInt64:
    1037                         d->fieldCache[i] = value.toLongLong(&ok);
    1038                         break;
    1039                     case QSql::LowPrecisionDouble:
    1040                         d->fieldCache[i] = value.toDouble(&ok);
    1041                         break;
    1042                     case QSql::HighPrecision:
    1043                     default:
    1044                         d->fieldCache[i] = value;
    1045                         ok=true;
    1046                         break;
    1047                 }
    1048                 if(ok==false)
    1049                     d->fieldCache[i] = QVariant();
    1050                 break;
     1132            switch(numericalPrecisionPolicy()) {
     1133                case QSql::LowPrecisionInt32:
     1134                    d->fieldCache[i] = qGetIntData(d->hStmt, i);
     1135                    break;
     1136                case QSql::LowPrecisionInt64:
     1137                    d->fieldCache[i] = qGetBigIntData(d->hStmt, i);
     1138                    break;
     1139                case QSql::LowPrecisionDouble:
     1140                    d->fieldCache[i] = qGetDoubleData(d->hStmt, i);
     1141                    break;
     1142                case QSql::HighPrecision:
     1143                    d->fieldCache[i] = qGetStringData(d->hStmt, i, info.length(), false);
     1144                    break;
    10511145            }
     1146            break;
    10521147        default:
    10531148            d->fieldCache[i] = QVariant(qGetStringData(d->hStmt, i, info.length(), false));
     
    11031198    }
    11041199    r  = SQLAllocHandle(SQL_HANDLE_STMT,
    1105                          d->hDbc,
     1200                         d->dpDbc(),
    11061201                         &d->hStmt);
    11071202    if (r != SQL_SUCCESS) {
     
    11121207    d->updateStmtHandleState(driver());
    11131208
    1114     if (isForwardOnly()) {
     1209    if (d->userForwardOnly) {
    11151210        r = SQLSetStmtAttr(d->hStmt,
    11161211                            SQL_ATTR_CURSOR_TYPE,
     
    13721467#endif
    13731468                {
    1374                     QByteArray str = val.toString().toUtf8();
     1469                    QByteArray str = val.toString().toAscii();
    13751470                    if (*ind != SQL_NULL_DATA)
    13761471                        *ind = str.length();
    13771472                    int strSize = str.length();
    1378                    
     1473
    13791474                    r = SQLBindParameter(d->hStmt,
    13801475                                          i + 1,
     
    14231518    }
    14241519
     1520    SQLINTEGER isScrollable, bufferLength;
     1521    r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, &bufferLength);
     1522    if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
     1523        QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE);
     1524
    14251525    SQLSMALLINT count;
    14261526    SQLNumResultCols(d->hStmt, &count);
     
    14571557                               QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000)));
    14581558                break; }
     1559            case QVariant::Bool:
    14591560            case QVariant::Int:
    14601561            case QVariant::UInt:
     
    15461647        *static_cast<bool*>(data) = nextResult();
    15471648        break;
    1548     case QSqlResult::SetNumericalPrecision:
    1549         Q_ASSERT(data);
    1550         d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
    1551         break;
    15521649    default:
    15531650        QSqlResult::virtual_hook(id, data);
    15541651    }
     1652}
     1653
     1654void QODBCResult::setForwardOnly(bool forward)
     1655{
     1656    d->userForwardOnly = forward;
     1657    QSqlResult::setForwardOnly(forward);
    15551658}
    15561659
     
    16701773    if (db.contains(QLatin1String(".dsn"), Qt::CaseInsensitive))
    16711774        connQStr = QLatin1String("FILEDSN=") + db;
    1672     else if (db.contains(QLatin1String("DRIVER="), Qt::CaseInsensitive) 
     1775    else if (db.contains(QLatin1String("DRIVER="), Qt::CaseInsensitive)
    16731776            || db.contains(QLatin1String("SERVER="), Qt::CaseInsensitive))
    16741777        connQStr = db;
     
    16801783    if (!password.isEmpty())
    16811784        connQStr += QLatin1String(";PWD=") + password;
    1682    
     1785
    16831786    SQLSMALLINT cb;
    16841787    SQLTCHAR connOut[1024];
     
    17031806    if (!d->checkDriver()) {
    17041807        setLastError(qMakeError(tr("Unable to connect - Driver doesn't support all "
    1705                      "needed functionality"), QSqlError::ConnectionError, d));
     1808                     "functionality required"), QSqlError::ConnectionError, d));
    17061809        setOpenError(true);
    17071810        return false;
     
    17151818    setOpen(true);
    17161819    setOpenError(false);
     1820    if(d->isMSSqlServer) {
     1821        QSqlQuery i(createResult());
     1822        i.exec(QLatin1String("SET QUOTED_IDENTIFIER ON"));
     1823    }
    17171824    return true;
    17181825}
     
    17631870    return;
    17641871#endif
    1765 #if defined(Q_WS_WIN)
    1766     QT_WA(
    1767     {},
    1768     {
    1769         unicode = false;
    1770         return;
    1771     })
    1772 #endif
     1872
    17731873    SQLRETURN   r;
    17741874    SQLUINTEGER fFunc;
     
    17811881                    NULL);
    17821882    if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WCHAR)) {
    1783         sql_char_type = QVariant::String;
    17841883        unicode = true;
    17851884    }
     
    17911890                    NULL);
    17921891    if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WVARCHAR)) {
    1793         sql_varchar_type = QVariant::String;
    17941892        unicode = true;
    17951893    }
     
    18011899                    NULL);
    18021900    if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WLONGVARCHAR)) {
    1803         sql_longvarchar_type = QVariant::String;
    18041901        unicode = true;
    18051902    }
     
    20852182    QString catalog, schema, table;
    20862183    d->splitTableQualifier(tablename, catalog, schema, table);
     2184
     2185    if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
     2186        catalog = stripDelimiters(catalog, QSqlDriver::TableName);
     2187    else
     2188        catalog = d->adjustCase(catalog);
     2189
     2190    if (isIdentifierEscaped(schema, QSqlDriver::TableName))
     2191        schema = stripDelimiters(schema, QSqlDriver::TableName);
     2192    else
     2193        schema = d->adjustCase(schema);
     2194
     2195    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     2196        table = stripDelimiters(table, QSqlDriver::TableName);
     2197    else
     2198        table = d->adjustCase(table);
     2199
    20872200    r = SQLSetStmtAttr(hStmt,
    20882201                        SQL_ATTR_CURSOR_TYPE,
     
    21872300    QString catalog, schema, table;
    21882301    d->splitTableQualifier(tablename, catalog, schema, table);
     2302
     2303    if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
     2304        catalog = stripDelimiters(catalog, QSqlDriver::TableName);
     2305    else
     2306        catalog = d->adjustCase(catalog);
     2307
     2308    if (isIdentifierEscaped(schema, QSqlDriver::TableName))
     2309        schema = stripDelimiters(schema, QSqlDriver::TableName);
     2310    else
     2311        schema = d->adjustCase(schema);
     2312
     2313    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     2314        table = stripDelimiters(table, QSqlDriver::TableName);
     2315    else
     2316        table = d->adjustCase(table);
     2317
    21892318    SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT,
    21902319                                  d->hDbc,
     
    22942423QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType) const
    22952424{
     2425    QChar quote = d->quoteChar();
    22962426    QString res = identifier;
    2297     if (d->isMySqlServer) {
    2298         if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('`')) && identifier.right(1) != QString(QLatin1Char('`')) ) {
    2299             res.prepend(QLatin1Char('`')).append(QLatin1Char('`'));
    2300             res.replace(QLatin1Char('.'), QLatin1String("`.`"));
    2301         }
    2302     } else {
    2303         if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
    2304             res.replace(QLatin1Char('"'), QLatin1String("\"\""));
    2305             res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
    2306             res.replace(QLatin1Char('.'), QLatin1String("\".\""));
    2307         }
     2427    if(!identifier.isEmpty() && !identifier.startsWith(quote) && !identifier.endsWith(quote) ) {
     2428        res.replace(quote, QString(quote)+QString(quote));
     2429        res.prepend(quote).append(quote);
     2430        res.replace(QLatin1Char('.'), QString(quote)+QLatin1Char('.')+QString(quote));
    23082431    }
    23092432    return res;
    23102433}
    23112434
     2435bool QODBCDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType) const
     2436{
     2437    QChar quote = d->quoteChar();
     2438    return identifier.size() > 2
     2439        && identifier.startsWith(quote) //left delimited
     2440        && identifier.endsWith(quote); //right delimited
     2441}
     2442
    23122443QT_END_NAMESPACE
  • trunk/src/sql/drivers/odbc/qsql_odbc.h

    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**
     
    101101
    102102    QVariant handle() const;
     103    virtual void setForwardOnly(bool forward);
    103104
    104105protected:
     
    146147    QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
    147148
     149protected Q_SLOTS:
     150    bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const;
     151
    148152protected:
    149153    bool beginTransaction();
    150154    bool commitTransaction();
    151155    bool rollbackTransaction();
     156
    152157private:
    153158    void init();
Note: See TracChangeset for help on using the changeset viewer.