Changeset 561 for trunk/src/sql


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:
52 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/sql/drivers/db2/qsql_db2.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**
     
    5050#include <qvarlengtharray.h>
    5151#include <qvector.h>
    52 
    53 #ifndef UNICODE
    54 #define UNICODE
    55 #endif
     52#include <QDebug>
    5653
    5754#if defined(Q_CC_BOR)
     
    6360#endif
    6461
     62#define UNICODE
     63
    6564#include <sqlcli1.h>
    6665
     
    8483{
    8584public:
    86     QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0), precisionPolicy(QSql::HighPrecision)
     85    QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0)
    8786    {}
    8887    ~QDB2ResultPrivate()
    8988    {
    90         for (int i = 0; i < valueCache.count(); ++i)
     89        emptyValueCache();
     90    }
     91    void clearValueCache()
     92    {
     93        for (int i = 0; i < valueCache.count(); ++i) {
    9194            delete valueCache[i];
     95            valueCache[i] = NULL;
     96        }
     97    }
     98    void emptyValueCache()
     99    {
     100        clearValueCache();
     101        valueCache.clear();
    92102    }
    93103
     
    96106    QSqlRecord recInf;
    97107    QVector<QVariant*> valueCache;
    98     QSql::NumericalPrecisionPolicy precisionPolicy;
    99108};
    100109
    101110static QString qFromTChar(SQLTCHAR* str)
    102111{
    103 #ifdef UNICODE
    104112    return QString::fromUtf16(str);
    105 #else
    106     return QString::fromLocal8Bit((const char*) str);
    107 #endif
    108113}
    109114
     
    112117static SQLTCHAR* qToTChar(const QString& str)
    113118{
    114 #ifdef UNICODE
    115119    return (SQLTCHAR*)str.utf16();
    116 #else
    117     return (unsigned char*) str.ascii();
    118 #endif
    119120}
    120121
     
    337338    while (true) {
    338339        r = SQLGetData(hStmt,
    339                         column+1,
    340 #ifdef UNICODE
     340                        column + 1,
    341341                        SQL_C_WCHAR,
    342 #else
    343                         SQL_C_CHAR,
    344 #endif
    345342                        (SQLPOINTER)buf,
    346343                        colSize * sizeof(SQLTCHAR),
     
    545542
    546543    d->recInf.clear();
    547     d->valueCache.clear();
     544    d->emptyValueCache();
    548545
    549546    if (!qMakeStatement(d, isForwardOnly()))
     
    569566    }
    570567    d->valueCache.resize(count);
     568    d->valueCache.fill(NULL);
    571569    setActive(true);
    572570    return true;
     
    580578
    581579    d->recInf.clear();
    582     d->valueCache.clear();
     580    d->emptyValueCache();
    583581
    584582    if (!qMakeStatement(d, isForwardOnly()))
     
    608606
    609607    d->recInf.clear();
    610     d->valueCache.clear();
     608    d->emptyValueCache();
    611609
    612610    if (!qMakeStatement(d, isForwardOnly(), false))
     
    729727                break; }
    730728            case QVariant::String:
    731 #ifdef UNICODE
    732729            {
    733730                QString str(values.at(i).toString());
     
    763760                break;
    764761            }
    765 #endif
    766             // fall through
    767762            default: {
    768763                QByteArray ba = values.at(i).toString().toAscii();
     
    812807    setActive(true);
    813808    d->valueCache.resize(count);
     809    d->valueCache.fill(NULL);
    814810
    815811    //get out parameters
     
    837833                break;
    838834            case QVariant::String:
    839 #ifdef UNICODE
    840835                if (bindValueType(i) & QSql::Out)
    841836                    values[i] = QString::fromUtf16((ushort*)tmpStorage.takeFirst().constData());
    842837                break;
    843 #endif
    844                 // fall through
    845838            default: {
    846839                values[i] = QString::fromAscii(tmpStorage.takeFirst().constData());
     
    859852    if (i == at())
    860853        return true;
    861     d->valueCache.fill(0);
     854    d->clearValueCache();
    862855    int actualIdx = i + 1;
    863856    if (actualIdx <= 0) {
     
    876869                            actualIdx);
    877870    }
    878     if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
     871    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r != SQL_NO_DATA) {
    879872        setLastError(qMakeError(QCoreApplication::translate("QDB2Result",
    880873                                "Unable to fetch record %1").arg(i), QSqlError::StatementError, d));
    881874        return false;
    882875    }
     876    else if (r == SQL_NO_DATA)
     877        return false;
    883878    setAt(i);
    884879    return true;
     
    888883{
    889884    SQLRETURN r;
    890     d->valueCache.fill(0);
     885    d->clearValueCache();
    891886    r = SQLFetchScroll(d->hStmt,
    892887                       SQL_FETCH_NEXT,
     
    908903    if (isForwardOnly())
    909904        return fetchNext();
    910     d->valueCache.fill(0);
     905    d->clearValueCache();
    911906    SQLRETURN r;
    912907    r = SQLFetchScroll(d->hStmt,
     
    914909                       0);
    915910    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {
    916         setLastError(qMakeError(QCoreApplication::translate("QDB2Result", "Unable to fetch first"),
    917                                 QSqlError::StatementError, d));
     911        if(r!= SQL_NO_DATA)
     912            setLastError(qMakeError(QCoreApplication::translate("QDB2Result", "Unable to fetch first"),
     913                                    QSqlError::StatementError, d));
    918914        return false;
    919915    }
     
    924920bool QDB2Result::fetchLast()
    925921{
    926     d->valueCache.fill(0);
     922    d->clearValueCache();
    927923
    928924    int i = at();
     
    10301026        case QVariant::Double:
    10311027            {
    1032             QString value=qGetStringData(d->hStmt, field, info.length() + 1, isNull);
    1033             bool ok=false;
    1034             switch(d->precisionPolicy) {
     1028            switch(numericalPrecisionPolicy()) {
    10351029                case QSql::LowPrecisionInt32:
    1036                     v = new QVariant(value.toInt(&ok));
     1030                    v = new QVariant(qGetIntData(d->hStmt, field, isNull));
    10371031                    break;
    10381032                case QSql::LowPrecisionInt64:
    1039                     v = new QVariant(value.toLongLong(&ok));
     1033                    v = new QVariant(qGetBigIntData(d->hStmt, field, isNull));
    10401034                    break;
    10411035                case QSql::LowPrecisionDouble:
    1042                     v = new QVariant(value.toDouble(&ok));
     1036                    v = new QVariant(qGetDoubleData(d->hStmt, field, isNull));
    10431037                    break;
    10441038                case QSql::HighPrecision:
     
    10461040                    // length + 1 for the comma
    10471041                    v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull));
    1048                     ok = true;
    10491042                    break;
    10501043            }
    1051             if(!ok)
    1052                 v = new QVariant();
    10531044            break;
    10541045            }
     
    11021093    setAt(QSql::BeforeFirstRow);
    11031094    d->recInf.clear();
    1104     d->valueCache.clear();
     1095    d->emptyValueCache();
    11051096    setSelect(false);
    11061097
     
    11211112
    11221113    d->valueCache.resize(fieldCount);
     1114    d->valueCache.fill(NULL);
    11231115    setActive(true);
    11241116
     
    11331125        *static_cast<bool*>(data) = nextResult();
    11341126        break;
    1135     case QSqlResult::SetNumericalPrecision:
    1136         Q_ASSERT(data);
    1137         d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
     1127    case QSqlResult::DetachFromResultSet:
     1128        if (d->hStmt)
     1129            SQLCloseCursor(d->hStmt);
    11381130        break;
    11391131    default:
     
    11681160}
    11691161
    1170 bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString&, int,
     1162bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port,
    11711163                       const QString& connOpts)
    11721164{
     
    11911183        return false;
    11921184    }
     1185
     1186    QString protocol;
    11931187    // Set connection attributes
    11941188    const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
     
    12211215            v = val.toUInt();
    12221216            r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0);
    1223         } else {
     1217        } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) {
     1218                        protocol = tmp;
     1219        }
     1220        else {
    12241221            qWarning("QDB2Driver::open: Unknown connection attribute '%s'",
    12251222                      tmp.toLocal8Bit().constData());
     
    12301227    }
    12311228
     1229    if (protocol.isEmpty())
     1230        protocol = QLatin1String("PROTOCOL=TCPIP");
     1231
     1232    if (port < 0 )
     1233        port = 50000;
     1234
    12321235    QString connQStr;
    1233     connQStr = QLatin1String("DSN=") + db + QLatin1String(";UID=") + user + QLatin1String(";PWD=")
    1234                + password;
     1236    connQStr =  protocol + QLatin1String(";DATABASE=") + db + QLatin1String(";HOSTNAME=") + host
     1237        + QLatin1String(";PORT=") + QString::number(port) + QLatin1String(";UID=") + user
     1238        + QLatin1String(";PWD=") + password;
     1239
     1240
    12351241    SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH];
    12361242    SQLSMALLINT cb;
     
    12511257    }
    12521258
    1253     d->user = user.toUpper();
     1259    d->user = user;
    12541260    setOpen(true);
    12551261    setOpenError(false);
     
    12961302    SQLHANDLE hStmt;
    12971303    QString catalog, schema, table;
    1298     qSplitTableQualifier(tableName.toUpper(), &catalog, &schema, &table);
     1304    qSplitTableQualifier(tableName, &catalog, &schema, &table);
    12991305    if (schema.isEmpty())
    13001306        schema = d->user;
     1307
     1308    if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
     1309        catalog = stripDelimiters(catalog, QSqlDriver::TableName);
     1310    else
     1311        catalog = catalog.toUpper();
     1312
     1313    if (isIdentifierEscaped(schema, QSqlDriver::TableName))
     1314        schema = stripDelimiters(schema, QSqlDriver::TableName);
     1315    else
     1316        schema = schema.toUpper();
     1317
     1318    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     1319        table = stripDelimiters(table, QSqlDriver::TableName);
     1320    else
     1321        table = table.toUpper();
    13011322
    13021323    SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT,
     
    13131334                        SQL_IS_UINTEGER);
    13141335
     1336
     1337    //Aside: szSchemaName and szTableName parameters of SQLColumns
     1338    //are case sensitive search patterns, so no escaping is used.
    13151339    r =  SQLColumns(hStmt,
    13161340                     NULL,
     
    13931417        QString fieldVal = qGetStringData(hStmt, 2, -1, isNull);
    13941418        QString userVal = qGetStringData(hStmt, 1, -1, isNull);
    1395         if (userVal != d->user)
     1419        QString user = d->user;
     1420        if ( isIdentifierEscaped(user, QSqlDriver::TableName))
     1421            user = stripDelimiters(user, QSqlDriver::TableName);
     1422        else
     1423            user = user.toUpper();
     1424
     1425        if (userVal != user)
    13961426            fieldVal = userVal + QLatin1Char('.') + fieldVal;
    13971427        tl.append(fieldVal);
     
    14241454    }
    14251455    QString catalog, schema, table;
    1426     qSplitTableQualifier(tablename.toUpper(), &catalog, &schema, &table);
     1456    qSplitTableQualifier(tablename, &catalog, &schema, &table);
     1457
     1458    if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
     1459        catalog = stripDelimiters(catalog, QSqlDriver::TableName);
     1460    else
     1461        catalog = catalog.toUpper();
     1462
     1463    if (isIdentifierEscaped(schema, QSqlDriver::TableName))
     1464        schema = stripDelimiters(schema, QSqlDriver::TableName);
     1465    else
     1466        schema = schema.toUpper();
     1467
     1468    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     1469        table = stripDelimiters(table, QSqlDriver::TableName);
     1470    else
     1471        table = table.toUpper();
     1472
    14271473    r = SQLSetStmtAttr(hStmt,
    14281474                        SQL_ATTR_CURSOR_TYPE,
     
    14681514        case LastInsertId:
    14691515        case SimpleLocking:
    1470         case LowPrecisionNumbers:
    14711516        case EventNotifications:
    14721517            return false;
     
    14761521        case PreparedQueries:
    14771522        case PositionalPlaceholders:
     1523        case LowPrecisionNumbers:
     1524        case FinishQuery:
    14781525            return true;
    14791526        case Unicode:
    1480         // this is the query that shows the codepage for the types:
    1481         // select typename, codepage from syscat.datatypes
    1482 #ifdef UNICODE
    14831527            return true;
    1484 #else
    1485             return false;
    1486 #endif
    14871528    }
    14881529    return false;
     
    15981639{
    15991640    QString res = identifier;
    1600     if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
     1641    if(!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('"')) && !identifier.endsWith(QLatin1Char('"')) ) {
    16011642        res.replace(QLatin1Char('"'), QLatin1String("\"\""));
    16021643        res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
  • trunk/src/sql/drivers/db2/qsql_db2.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**
  • trunk/src/sql/drivers/ibase/qsql_ibase.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 <math.h>
    5757#include <qdebug.h>
     58#include <QVarLengthArray>
    5859
    5960QT_BEGIN_NAMESPACE
     
    6768enum { QIBaseChunkSize = SHRT_MAX / 2 };
    6869
    69 static bool getIBaseError(QString& msg, ISC_STATUS* status, ISC_LONG &sqlcode,
    70                           QTextCodec *tc)
     70#if defined(FB_API_VER) && FB_API_VER >= 20
     71static bool getIBaseError(QString& msg, const ISC_STATUS* status, ISC_LONG &sqlcode, QTextCodec *tc)
     72#else
     73static bool getIBaseError(QString& msg, ISC_STATUS* status, ISC_LONG &sqlcode, QTextCodec *tc)
     74#endif
    7175{
    7276    if (status[0] != 1 || status[1] <= 0)
     
    7680    sqlcode = isc_sqlcode(status);
    7781    char buf[512];
     82#if defined(FB_API_VER) && FB_API_VER >= 20
     83    while(fb_interpret(buf, 512, &status)) {
     84#else
    7885    while(isc_interprete(buf, &status)) {
     86#endif
    7987        if(!msg.isEmpty())
    8088            msg += QLatin1String(" - ");
     
    9098{
    9199    sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
     100    if (sqlda == (XSQLDA*)0) return;
    92101    sqlda->sqln = 1;
    93102    sqlda->sqld = 0;
     
    99108static void enlargeDA(XSQLDA *&sqlda, int n)
    100109{
    101     free(sqlda);
     110    if (sqlda != (XSQLDA*)0)
     111        free(sqlda);
    102112    sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(n));
     113    if (sqlda == (XSQLDA*)0) return;
    103114    sqlda->sqln = n;
    104115    sqlda->version = SQLDA_CURRENT_VERSION;
     
    119130        case SQL_TEXT:
    120131        case SQL_BLOB:
    121             sqlda->sqlvar[i].sqldata = (char*)malloc(sqlda->sqlvar[i].sqllen);
     132            sqlda->sqlvar[i].sqldata = new char[sqlda->sqlvar[i].sqllen];
    122133            break;
    123134        case SQL_ARRAY:
    124             sqlda->sqlvar[i].sqldata = (char*)malloc(sizeof(ISC_QUAD));
     135            sqlda->sqlvar[i].sqldata = new char[sizeof(ISC_QUAD)];
    125136            memset(sqlda->sqlvar[i].sqldata, 0, sizeof(ISC_QUAD));
    126137            break;
    127138        case SQL_VARYING:
    128             sqlda->sqlvar[i].sqldata = (char*)malloc(sqlda->sqlvar[i].sqllen + sizeof(short));
     139            sqlda->sqlvar[i].sqldata = new char[sqlda->sqlvar[i].sqllen + sizeof(short)];
    129140            break;
    130141        default:
     
    134145        }
    135146        if (sqlda->sqlvar[i].sqltype & 1) {
    136             sqlda->sqlvar[i].sqlind = (short*)malloc(sizeof(short));
     147            sqlda->sqlvar[i].sqlind = new short[1];
    137148            *(sqlda->sqlvar[i].sqlind) = 0;
    138149        } else {
     
    147158        return;
    148159    for (int i = 0; i < sqlda->sqld; ++i) {
    149         free(sqlda->sqlvar[i].sqlind);
    150         free(sqlda->sqlvar[i].sqldata);
     160        delete [] sqlda->sqlvar[i].sqlind;
     161        delete [] sqlda->sqlvar[i].sqldata;
    151162    }
    152163    free(sqlda);
     
    293304    ISC_LONG bufferLength;
    294305    ISC_LONG eventId;
    295    
     306
    296307    enum QIBaseSubscriptionState { Starting, Subscribed, Finished };
    297308    QIBaseSubscriptionState subscriptionState;
     
    444455    ba.resize(read);
    445456
    446     bool isErr = (status[1] == isc_segstr_eof ? false : 
    447                     isError(QT_TRANSLATE_NOOP("QIBaseResult", 
     457    bool isErr = (status[1] == isc_segstr_eof ? false :
     458                    isError(QT_TRANSLATE_NOOP("QIBaseResult",
    448459                                                "Unable to read BLOB"),
    449460                                                QSqlError::StatementError));
     
    512523                    else
    513524                        valList.append(QString::fromUtf8(buffer, o));
    514                    
     525
    515526                    buffer += strLen;
    516527                }
     
    577588    int arraySize = 1, subArraySize;
    578589    short dimensions = desc.array_desc_dimensions;
    579     short *numElements = new short[dimensions];
     590    QVarLengthArray<short> numElements(dimensions);
    580591
    581592    for(int i = 0; i < dimensions; ++i) {
     
    606617        return list;
    607618
    608     readArrayBuffer(list, ba.data(), 0, numElements, &desc, tc);
    609 
    610     delete[] numElements;
     619    readArrayBuffer(list, ba.data(), 0, numElements.data(), &desc, tc);
    611620
    612621    return QVariant(list);
     
    639648}
    640649
    641 static char* qFillBufferWithString(char *buffer, const QString& string, 
    642                                    short buflen, bool varying, bool array, 
     650static char* qFillBufferWithString(char *buffer, const QString& string,
     651                                   short buflen, bool varying, bool array,
    643652                                   QTextCodec *tc)
    644653{
     
    872881bool QIBaseResult::prepare(const QString& query)
    873882{
    874     //qDebug("prepare: %s\n", qPrintable(query));
     883//     qDebug("prepare: %s", qPrintable(query));
    875884    if (!driver() || !driver()->isOpen() || driver()->isOpenError())
    876885        return false;
     
    880889
    881890    createDA(d->sqlda);
     891    if (d->sqlda == (XSQLDA*)0) {
     892        qWarning()<<"QIOBaseResult: createDA(): failed to allocate memory";
     893        return false;
     894    }
     895
    882896    createDA(d->inda);
     897    if (d->inda == (XSQLDA*)0){
     898        qWarning()<<"QIOBaseResult: createDA():  failed to allocate memory";
     899        return false;
     900    }
    883901
    884902    if (!d->transaction())
     
    901919    if (d->inda->sqld > d->inda->sqln) {
    902920        enlargeDA(d->inda, d->inda->sqld);
     921        if (d->inda == (XSQLDA*)0) {
     922            qWarning()<<"QIOBaseResult: enlargeDA(): failed to allocate memory";
     923            return false;
     924        }
    903925
    904926        isc_dsql_describe_bind(d->status, &d->stmt, FBVERSION, d->inda);
     
    911933        // need more field descriptors
    912934        enlargeDA(d->sqlda, d->sqlda->sqld);
     935        if (d->sqlda == (XSQLDA*)0) {
     936            qWarning()<<"QIOBaseResult: enlargeDA(): failed to allocate memory";
     937            return false;
     938        }
    913939
    914940        isc_dsql_describe(d->status, &d->stmt, FBVERSION, d->sqlda);
     
    9781004            case SQL_LONG:
    9791005                if (d->inda->sqlvar[para].sqlscale < 0)
    980                     *((long*)d->inda->sqlvar[para].sqldata) = 
     1006                    *((long*)d->inda->sqlvar[para].sqldata) =
    9811007                        (long)floor(0.5 + val.toDouble() * pow(10.0, d->inda->sqlvar[para].sqlscale * -1));
    9821008                else
     
    9851011            case SQL_SHORT:
    9861012                if (d->inda->sqlvar[para].sqlscale < 0)
    987                     *((short*)d->inda->sqlvar[para].sqldata) = 
     1013                    *((short*)d->inda->sqlvar[para].sqldata) =
    9881014                        (short)floor(0.5 + val.toDouble() * pow(10.0, d->inda->sqlvar[para].sqlscale * -1));
    9891015                else
     
    10261052
    10271053    if (ok) {
    1028         if (colCount()) {
     1054        if (colCount() && d->queryType != isc_info_sql_stmt_exec_procedure) {
    10291055            isc_dsql_free_statement(d->status, &d->stmt, DSQL_close);
    10301056            if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult", "Unable to close statement")))
     
    10401066
    10411067        // Not all stored procedures necessarily return values.
    1042         if (d->queryType == isc_info_sql_stmt_exec_procedure && d->sqlda->sqld == 0)
     1068        if (d->queryType == isc_info_sql_stmt_exec_procedure && d->sqlda && d->sqlda->sqld == 0)
    10431069            delDA(d->sqlda);
    10441070
     
    10981124            QVariant v;
    10991125            v.convert(qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype, d->sqlda->sqlvar[i].sqlscale < 0));
     1126            if(v.type() == QVariant::Double) {
     1127                switch(numericalPrecisionPolicy()) {
     1128                case QSql::LowPrecisionInt32:
     1129                    v.convert(QVariant::Int);
     1130                    break;
     1131                case QSql::LowPrecisionInt64:
     1132                    v.convert(QVariant::LongLong);
     1133                    break;
     1134                case QSql::HighPrecision:
     1135                    v.convert(QVariant::String);
     1136                    break;
     1137                }
     1138            }
    11001139            row[idx] = v;
    11011140            continue;
     
    11621201            row[idx] = QVariant();
    11631202            break;
     1203        }
     1204        if (d->sqlda->sqlvar[i].sqlscale < 0) {
     1205            QVariant v = row[idx];
     1206            switch(numericalPrecisionPolicy()) {
     1207            case QSql::LowPrecisionInt32:
     1208                if(v.convert(QVariant::Int))
     1209                    row[idx]=v;
     1210                break;
     1211            case QSql::LowPrecisionInt64:
     1212                if(v.convert(QVariant::LongLong))
     1213                    row[idx]=v;
     1214                break;
     1215            case QSql::LowPrecisionDouble:
     1216                if(v.convert(QVariant::Double))
     1217                    row[idx]=v;
     1218                break;
     1219            case QSql::HighPrecision:
     1220                if(v.convert(QVariant::String))
     1221                    row[idx]=v;
     1222                break;
     1223            }
    11641224        }
    11651225    }
     
    12371297        cCountType = isc_info_req_insert_count;
    12381298        break;
     1299    default:
     1300        qWarning() << "numRowsAffected: Unknown statement type (" << d->queryType << ")";
     1301        return -1;
    12391302    }
    12401303
     
    12711334        QSqlField f(QString::fromLatin1(v.aliasname, v.aliasname_length).simplified(),
    12721335                    qIBaseTypeName2(v.sqltype, v.sqlscale < 0));
    1273         QSqlQuery q(new QIBaseResult(d->db));
    1274         q.setForwardOnly(true);
    1275         q.exec(QLatin1String("select b.RDB$FIELD_PRECISION, b.RDB$FIELD_SCALE, b.RDB$FIELD_LENGTH, a.RDB$NULL_FLAG "
    1276                 "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "
    1277                 "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "
    1278                 "AND a.RDB$RELATION_NAME = '") + QString::fromAscii(v.relname, v.relname_length).toUpper() + QLatin1String("' "
    1279                 "AND a.RDB$FIELD_NAME = '") + QString::fromAscii(v.sqlname, v.sqlname_length).toUpper() + QLatin1String("' "));
    1280         if(q.first()) {
    1281             if(v.sqlscale < 0) {
    1282                 f.setLength(q.value(0).toInt());
    1283                 f.setPrecision(qAbs(q.value(1).toInt()));
    1284             } else {
    1285                 f.setLength(q.value(2).toInt());
    1286                 f.setPrecision(0);
     1336        f.setLength(v.sqllen);
     1337        f.setPrecision(qAbs(v.sqlscale));
     1338        f.setRequiredStatus((v.sqltype & 1) == 0 ? QSqlField::Required : QSqlField::Optional);
     1339        if(v.sqlscale < 0) {
     1340            QSqlQuery q(new QIBaseResult(d->db));
     1341            q.setForwardOnly(true);
     1342            q.exec(QLatin1String("select b.RDB$FIELD_PRECISION, b.RDB$FIELD_SCALE, b.RDB$FIELD_LENGTH, a.RDB$NULL_FLAG "
     1343                    "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "
     1344                    "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "
     1345                    "AND a.RDB$RELATION_NAME = '") + QString::fromAscii(v.relname, v.relname_length).toUpper() + QLatin1String("' "
     1346                    "AND a.RDB$FIELD_NAME = '") + QString::fromAscii(v.sqlname, v.sqlname_length).toUpper() + QLatin1String("' "));
     1347            if(q.first()) {
     1348                if(v.sqlscale < 0) {
     1349                    f.setLength(q.value(0).toInt());
     1350                    f.setPrecision(qAbs(q.value(1).toInt()));
     1351                } else {
     1352                    f.setLength(q.value(2).toInt());
     1353                    f.setPrecision(0);
     1354                }
     1355                f.setRequiredStatus(q.value(3).toBool() ? QSqlField::Required : QSqlField::Optional);
    12871356            }
    1288             f.setRequiredStatus(q.value(3).toBool() ? QSqlField::Required : QSqlField::Optional);
    1289         }
    1290         else {
    1291             f.setLength(0);
    1292             f.setPrecision(0);
    1293             f.setRequiredStatus(QSqlField::Unknown);
    12941357        }
    12951358        f.setSqlType(v.sqltype);
     
    13341397    case BatchOperations:
    13351398    case SimpleLocking:
    1336     case LowPrecisionNumbers:
    13371399    case FinishQuery:
    13381400    case MultipleResultSets:
     
    13441406    case BLOB:
    13451407    case EventNotifications:
     1408    case LowPrecisionNumbers:
    13461409        return true;
    13471410    }
     
    15531616    QSqlQuery q(createResult());
    15541617    q.setForwardOnly(true);
    1555 
     1618    QString table = tablename;
     1619    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     1620        table = stripDelimiters(table, QSqlDriver::TableName);
     1621    else
     1622        table = table.toUpper();
    15561623    q.exec(QLatin1String("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, "
    15571624           "b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG "
    15581625           "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "
    15591626           "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "
    1560            "AND a.RDB$RELATION_NAME = '") + tablename.toUpper() + QLatin1String("' "
     1627           "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' "
    15611628           "ORDER BY a.RDB$FIELD_POSITION"));
    15621629
     
    15861653        return index;
    15871654
     1655    QString tablename = table;
     1656    if (isIdentifierEscaped(tablename, QSqlDriver::TableName))
     1657        tablename = stripDelimiters(tablename, QSqlDriver::TableName);
     1658    else
     1659        tablename = tablename.toUpper();
     1660
    15881661    QSqlQuery q(createResult());
    15891662    q.setForwardOnly(true);
     
    15911664           "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d "
    15921665           "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "
    1593            "AND a.RDB$RELATION_NAME = '") + table.toUpper() +
     1666           "AND a.RDB$RELATION_NAME = '") + tablename +
    15941667           QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME "
    15951668           "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME "
     
    16681741    QIBaseDriver *driver = qBufferDriverMap()->value(result);
    16691742    qMutex()->unlock();
    1670    
     1743
    16711744    // We use an asynchronous call (i.e., queued connection) because the event callback
    16721745    // is executed in a different thread than the one in which the driver lives.
     
    17171790
    17181791    if (status[0] == 1 && status[1]) {
    1719         setLastError(QSqlError(QString(QLatin1String("Could not subscribe to event notifications for %1.")).arg(name)));
     1792        setLastError(QSqlError(QString::fromLatin1("Could not subscribe to event notifications for %1.").arg(name)));
    17201793        d->eventBuffers.remove(name);
    17211794        qFreeEventBuffer(eBuffer);
     
    17451818
    17461819    if (status[0] == 1 && status[1]) {
    1747         setLastError(QSqlError(QString(QLatin1String("Could not unsubscribe from event notifications for %1.")).arg(name)));
     1820        setLastError(QSqlError(QString::fromLatin1("Could not unsubscribe from event notifications for %1.").arg(name)));
    17481821        return false;
    17491822    }
     
    18031876{
    18041877    QString res = identifier;
    1805     if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
     1878    if(!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('"')) && !identifier.endsWith(QLatin1Char('"')) ) {
    18061879        res.replace(QLatin1Char('"'), QLatin1String("\"\""));
    18071880        res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
  • trunk/src/sql/drivers/ibase/qsql_ibase.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**
  • trunk/src/sql/drivers/mysql/qsql_mysql.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**
     
    8686        tc(0),
    8787#endif
    88         preparedQuerys(false), preparedQuerysEnabled(false) {}
     88        preparedQuerysEnabled(false) {}
    8989    MYSQL *mysql;
    9090    QTextCodec *tc;
    9191
    92     bool preparedQuerys;
    9392    bool preparedQuerysEnabled;
    9493};
     
    164163}
    165164
    166 class QMYSQLResultPrivate
    167 {
     165class QMYSQLResultPrivate : public QObject
     166{
     167    Q_OBJECT
    168168public:
    169     QMYSQLResultPrivate(QMYSQLDriverPrivate* dp) : d(dp), result(0),
     169    QMYSQLResultPrivate(const QMYSQLDriver* dp, const QMYSQLResult* d) : driver(dp), result(0), q(d),
    170170        rowsAffected(0), hasBlobs(false)
    171171#if MYSQL_VERSION_ID >= 40108
    172172        , stmt(0), meta(0), inBinds(0), outBinds(0)
    173173#endif
    174         , precisionPolicy(QSql::HighPrecision)
    175         {}
    176 
    177     QMYSQLDriverPrivate* d;
     174        , preparedQuery(false)
     175        {
     176            connect(dp, SIGNAL(destroyed()), this, SLOT(driverDestroyed()));
     177        }
     178
     179    const QMYSQLDriver* driver;
    178180    MYSQL_RES *result;
    179181    MYSQL_ROW row;
     182    const QMYSQLResult* q;
    180183
    181184    int rowsAffected;
     
    207210    MYSQL_BIND *outBinds;
    208211#endif
    209     QSql::NumericalPrecisionPolicy precisionPolicy;
     212
     213    bool preparedQuery;
     214
     215private Q_SLOTS:
     216    void driverDestroyed() { driver = NULL; }
    210217};
    211218
     
    225232                            const QMYSQLDriverPrivate* p)
    226233{
    227     const char *cerr = mysql_error(p->mysql);
     234    const char *cerr = p->mysql ? mysql_error(p->mysql) : 0;
    228235    return QSqlError(QLatin1String("QMYSQL: ") + err,
    229236                     p->tc ? toUnicode(p->tc, cerr) : QString::fromLatin1(cerr),
     
    250257    case FIELD_TYPE_FLOAT :
    251258    case FIELD_TYPE_DOUBLE :
     259    case FIELD_TYPE_DECIMAL :
     260#if defined(FIELD_TYPE_NEWDECIMAL)
     261    case FIELD_TYPE_NEWDECIMAL:
     262#endif
    252263        type = QVariant::Double;
    253264        break;
     
    273284    case FIELD_TYPE_ENUM :
    274285    case FIELD_TYPE_SET :
    275     case FIELD_TYPE_DECIMAL :
    276286        type = QVariant::String;
    277287        break;
     
    350360        QMyField &f = fields[i];
    351361        f.myField = fieldInfo;
     362
    352363        f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
    353364        if (qIsBlob(fieldInfo->type)) {
     
    380391: QSqlResult(db)
    381392{
    382     d = new QMYSQLResultPrivate(db->d);
     393    d = new QMYSQLResultPrivate(db, this);
    383394}
    384395
     
    392403{
    393404#if MYSQL_VERSION_ID >= 40108
    394     if(d->d->preparedQuerys)
     405    if(d->preparedQuery)
    395406        return d->meta ? qVariantFromValue(d->meta) : qVariantFromValue(d->stmt);
    396407    else
     
    407418// if this isn't done subsequent queries will fail with "Commands out of sync"
    408419#if MYSQL_VERSION_ID >= 40100
    409     while (d->d->mysql && mysql_next_result(d->d->mysql) == 0) {
    410         MYSQL_RES *res = mysql_store_result(d->d->mysql);
     420    while (d->driver && d->driver->d->mysql && mysql_next_result(d->driver->d->mysql) == 0) {
     421        MYSQL_RES *res = mysql_store_result(d->driver->d->mysql);
    411422        if (res)
    412423            mysql_free_result(res);
     
    447458    setAt(-1);
    448459    setActive(false);
    449 
    450     d->d->preparedQuerys = d->d->preparedQuerysEnabled;
    451460}
    452461
    453462bool QMYSQLResult::fetch(int i)
    454463{
     464    if(!d->driver)
     465        return false;
    455466    if (isForwardOnly()) { // fake a forward seek
    456467        if (at() < i) {
     
    464475    if (at() == i)
    465476        return true;
    466     if (d->d->preparedQuerys) {
     477    if (d->preparedQuery) {
    467478#if MYSQL_VERSION_ID >= 40108
    468479        mysql_stmt_data_seek(d->stmt, i);
     
    495506bool QMYSQLResult::fetchNext()
    496507{
    497     if (d->d->preparedQuerys) {
     508    if(!d->driver)
     509        return false;
     510    if (d->preparedQuery) {
    498511#if MYSQL_VERSION_ID >= 40108
    499         if (mysql_stmt_fetch(d->stmt))
     512        int nRC = mysql_stmt_fetch(d->stmt);
     513        if (nRC) {
     514#ifdef MYSQL_DATA_TRUNCATED
     515            if (nRC == 1 || nRC == MYSQL_DATA_TRUNCATED)
     516#else
     517            if (nRC == 1)
     518#endif // MYSQL_DATA_TRUNCATED
     519                setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult",
     520                                    "Unable to fetch data"), QSqlError::StatementError, d->stmt));
    500521            return false;
     522        }
    501523#else
    502524        return false;
    503525#endif
    504526    } else {
    505     d->row = mysql_fetch_row(d->result);
    506     if (!d->row)
    507         return false;
     527        d->row = mysql_fetch_row(d->result);
     528        if (!d->row)
     529            return false;
    508530    }
    509531    setAt(at() + 1);
     
    513535bool QMYSQLResult::fetchLast()
    514536{
     537    if(!d->driver)
     538        return false;
    515539    if (isForwardOnly()) { // fake this since MySQL can't seek on forward only queries
    516540        bool success = fetchNext(); // did we move at all?
     
    520544
    521545    my_ulonglong numRows;
    522     if (d->d->preparedQuerys) {
     546    if (d->preparedQuery) {
    523547#if MYSQL_VERSION_ID >= 40108
    524548        numRows = mysql_stmt_num_rows(d->stmt);
     
    554578    }
    555579
     580    if (!d->driver)
     581        return QVariant();
     582
    556583    int fieldLength = 0;
    557584    const QMYSQLResultPrivate::QMyField &f = d->fields.at(field);
    558585    QString val;
    559     if (d->d->preparedQuerys) {
     586    if (d->preparedQuery) {
    560587        if (f.nullIndicator)
    561588            return QVariant(f.type);
    562589
    563590        if (f.type != QVariant::ByteArray)
    564             val = toUnicode(d->d->tc, f.outField, f.bufLength);
     591            val = toUnicode(d->driver->d->tc, f.outField, f.bufLength);
    565592    } else {
    566593        if (d->row[field] == NULL) {
     
    570597        fieldLength = mysql_fetch_lengths(d->result)[field];
    571598        if (f.type != QVariant::ByteArray)
    572             val = toUnicode(d->d->tc, d->row[field], fieldLength);
     599            val = toUnicode(d->driver->d->tc, d->row[field], fieldLength);
    573600    }
    574601
     
    585612        QVariant v;
    586613        bool ok=false;
    587         switch(d->precisionPolicy) {
     614        double dbl = val.toDouble(&ok);
     615        switch(numericalPrecisionPolicy()) {
    588616            case QSql::LowPrecisionInt32:
    589                 v=val.toInt(&ok);
     617                v=QVariant(dbl).toInt();
    590618                break;
    591619            case QSql::LowPrecisionInt64:
    592                 v = val.toLongLong(&ok);
     620                v = QVariant(dbl).toLongLong();
    593621                break;
    594622            case QSql::LowPrecisionDouble:
    595                 v = val.toDouble(&ok);
     623                v = QVariant(dbl);
    596624                break;
    597625            case QSql::HighPrecision:
     
    606634            return QVariant();
    607635    }
     636        return QVariant(val.toDouble());
    608637    case QVariant::Date:
    609638        return qDateFromString(val);
     
    615644
    616645        QByteArray ba;
    617         if (d->d->preparedQuerys) {
     646        if (d->preparedQuery) {
    618647            ba = QByteArray(f.outField, f.bufLength);
    619648        } else {
     
    632661bool QMYSQLResult::isNull(int field)
    633662{
    634    if (d->d->preparedQuerys)
     663   if (d->preparedQuery)
    635664       return d->fields.at(field).nullIndicator;
    636665   else
     
    640669bool QMYSQLResult::reset (const QString& query)
    641670{
    642     if (!driver() || !driver()->isOpen() || driver()->isOpenError())
    643         return false;
    644 
    645     if(d->d->preparedQuerysEnabled && prepare(query)) {
    646         d->d->preparedQuerys = true;
    647         return exec();
    648     }
    649     d->d->preparedQuerys = false;
    650 
    651     const QByteArray encQuery(fromUnicode(d->d->tc, query));
    652     if (mysql_real_query(d->d->mysql, encQuery.data(), encQuery.length())) {
     671    if (!driver() || !driver()->isOpen() || driver()->isOpenError() || !d->driver)
     672        return false;
     673
     674    d->preparedQuery = false;
     675
     676    cleanup();
     677
     678    const QByteArray encQuery(fromUnicode(d->driver->d->tc, query));
     679    if (mysql_real_query(d->driver->d->mysql, encQuery.data(), encQuery.length())) {
    653680        setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute query"),
    654                      QSqlError::StatementError, d->d));
    655         return false;
    656     }
    657     d->result = mysql_store_result(d->d->mysql);
    658     if (!d->result && mysql_field_count(d->d->mysql) > 0) {
     681                     QSqlError::StatementError, d->driver->d));
     682        return false;
     683    }
     684    d->result = mysql_store_result(d->driver->d->mysql);
     685    if (!d->result && mysql_field_count(d->driver->d->mysql) > 0) {
    659686        setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store result"),
    660                     QSqlError::StatementError, d->d));
    661         return false;
    662     }
    663     int numFields = mysql_field_count(d->d->mysql);
     687                    QSqlError::StatementError, d->driver->d));
     688        return false;
     689    }
     690    int numFields = mysql_field_count(d->driver->d->mysql);
    664691    setSelect(numFields != 0);
    665692    d->fields.resize(numFields);
    666     d->rowsAffected = mysql_affected_rows(d->d->mysql);
     693    d->rowsAffected = mysql_affected_rows(d->driver->d->mysql);
     694
    667695    if (isSelect()) {
    668696        for(int i = 0; i < numFields; i++) {
     
    678706int QMYSQLResult::size()
    679707{
    680     if (isSelect())
    681         if (d->d->preparedQuerys)
     708    if (d->driver && isSelect())
     709        if (d->preparedQuery)
    682710#if MYSQL_VERSION_ID >= 40108
    683711            return mysql_stmt_num_rows(d->stmt);
     
    698726QVariant QMYSQLResult::lastInsertId() const
    699727{
    700     if (!isActive())
     728    if (!isActive() || !d->driver)
    701729        return QVariant();
    702730
    703     if (d->d->preparedQuerys) {
     731    if (d->preparedQuery) {
    704732#if MYSQL_VERSION_ID >= 40108
    705733        quint64 id = mysql_stmt_insert_id(d->stmt);
     
    708736#endif
    709737    } else {
    710         quint64 id = mysql_insert_id(d->d->mysql);
     738        quint64 id = mysql_insert_id(d->driver->d->mysql);
    711739        if (id)
    712740            return QVariant(id);
     
    719747    QSqlRecord info;
    720748    MYSQL_RES *res;
    721     if (!isActive() || !isSelect())
     749    if (!isActive() || !isSelect() || !d->driver)
    722750        return info;
    723751
    724752#if MYSQL_VERSION_ID >= 40108
    725     res = d->d->preparedQuerys ? d->meta : d->result;
     753    res = d->preparedQuery ? d->meta : d->result;
    726754#else
    727755    res = d->result;
    728756#endif
    729757
    730     if (!mysql_errno(d->d->mysql)) {
     758    if (!mysql_errno(d->driver->d->mysql)) {
    731759        mysql_field_seek(res, 0);
    732760        MYSQL_FIELD* field = mysql_fetch_field(res);
    733761        while(field) {
    734             info.append(qToField(field, d->d->tc));
     762            info.append(qToField(field, d->driver->d->tc));
    735763            field = mysql_fetch_field(res);
    736764        }
     
    742770bool QMYSQLResult::nextResult()
    743771{
     772    if(!d->driver)
     773        return false;
    744774#if MYSQL_VERSION_ID >= 40100
    745775    setAt(-1);
     
    755785    d->fields.clear();
    756786
    757     int status = mysql_next_result(d->d->mysql);
     787    int status = mysql_next_result(d->driver->d->mysql);
    758788    if (status > 0) {
    759789        setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute next query"),
    760                      QSqlError::StatementError, d->d));
     790                     QSqlError::StatementError, d->driver->d));
    761791        return false;
    762792    } else if (status == -1) {
     
    764794    }
    765795
    766     d->result = mysql_store_result(d->d->mysql);
    767     int numFields = mysql_field_count(d->d->mysql);
     796    d->result = mysql_store_result(d->driver->d->mysql);
     797    int numFields = mysql_field_count(d->driver->d->mysql);
    768798    if (!d->result && numFields > 0) {
    769799        setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store next result"),
    770                      QSqlError::StatementError, d->d));
     800                     QSqlError::StatementError, d->driver->d));
    771801        return false;
    772802    }
     
    774804    setSelect(numFields > 0);
    775805    d->fields.resize(numFields);
    776     d->rowsAffected = mysql_affected_rows(d->d->mysql);
     806    d->rowsAffected = mysql_affected_rows(d->driver->d->mysql);
    777807
    778808    if (isSelect()) {
     
    797827        *static_cast<bool*>(data) = nextResult();
    798828        break;
    799     case QSqlResult::SetNumericalPrecision:
    800         Q_ASSERT(data);
    801         d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
    802         break;
    803829    default:
    804830        QSqlResult::virtual_hook(id, data);
     
    834860bool QMYSQLResult::prepare(const QString& query)
    835861{
     862    if(!d->driver)
     863        return false;
    836864#if MYSQL_VERSION_ID >= 40108
    837865    cleanup();
    838     if (!d->d->preparedQuerys)
     866    if (!d->driver->d->preparedQuerysEnabled)
    839867        return QSqlResult::prepare(query);
    840868
     
    845873
    846874    if (!d->stmt)
    847         d->stmt = mysql_stmt_init(d->d->mysql);
     875        d->stmt = mysql_stmt_init(d->driver->d->mysql);
    848876    if (!d->stmt) {
    849877        setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"),
    850                      QSqlError::StatementError, d->d));
    851         return false;
    852     }
    853 
    854     const QByteArray encQuery(fromUnicode(d->d->tc, query));
     878                     QSqlError::StatementError, d->driver->d));
     879        return false;
     880    }
     881
     882    const QByteArray encQuery(fromUnicode(d->driver->d->tc, query));
    855883    r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length());
    856884    if (r != 0) {
     
    866894
    867895    setSelect(d->bindInValues());
     896    d->preparedQuery = true;
    868897    return true;
    869898#else
     
    874903bool QMYSQLResult::exec()
    875904{
    876     if (!d->d->preparedQuerys)
     905    if (!d->driver)
     906        return false;
     907    if (!d->preparedQuery)
    877908        return QSqlResult::exec();
    878909    if (!d->stmt)
     
    907938            currBind->is_null = &nullVector[i];
    908939            currBind->length = 0;
     940            currBind->is_unsigned = 0;
    909941
    910942            switch (val.type()) {
     
    953985                    currBind->buffer = data;
    954986                    currBind->buffer_length = sizeof(double);
    955                     currBind->is_unsigned = 0;
    956987                    break;
    957988                case QVariant::LongLong:
     
    964995                case QVariant::String:
    965996                default: {
    966                     QByteArray ba = fromUnicode(d->d->tc, val.toString());
     997                    QByteArray ba = fromUnicode(d->driver->d->tc, val.toString());
    967998                    stringVector.append(ba);
    968999                    currBind->buffer_type = MYSQL_TYPE_STRING;
    9691000                    currBind->buffer = const_cast<char *>(ba.constData());
    9701001                    currBind->buffer_length = ba.length();
    971                     currBind->is_unsigned = 0;
    9721002                    break; }
    9731003            }
     
    11291159    case BatchOperations:
    11301160    case SimpleLocking:
    1131     case LowPrecisionNumbers:
    11321161    case EventNotifications:
    11331162    case FinishQuery:
     
    11371166    case LastInsertId:
    11381167    case Unicode:
     1168    case LowPrecisionNumbers:
    11391169        return true;
    11401170    case PreparedQueries:
     
    11931223    const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts));
    11941224    QString unixSocket;
     1225#if MYSQL_VERSION_ID >= 50000
     1226    my_bool reconnect=false;
     1227#endif
    11951228
    11961229    // extract the real options from the string
     
    12031236            if (opt == QLatin1String("UNIX_SOCKET"))
    12041237                unixSocket = val;
     1238#if MYSQL_VERSION_ID >= 50000
     1239            else if (opt == QLatin1String("MYSQL_OPT_RECONNECT")) {
     1240                if (val == QLatin1String("TRUE") || val == QLatin1String("1") || val.isEmpty())
     1241                    reconnect = true;
     1242            }
     1243#endif
    12051244            else if (val == QLatin1String("TRUE") || val == QLatin1String("1"))
    12061245                setOptionFlag(optionFlags, tmp.left(idx).simplified());
     
    12351274            return false;
    12361275        }
     1276#if MYSQL_VERSION_ID >= 50000
     1277        if(reconnect)
     1278            mysql_options(d->mysql, MYSQL_OPT_RECONNECT, &reconnect);
     1279#endif
    12371280    } else {
    12381281        setLastError(qMakeError(tr("Unable to connect"),
     
    12591302#endif
    12601303
     1304#ifndef QT_NO_THREAD
     1305    mysql_thread_init();
     1306#endif
     1307
     1308
    12611309    setOpen(true);
    12621310    setOpenError(false);
     
    12671315{
    12681316    if (isOpen()) {
     1317#ifndef QT_NO_THREAD
     1318        mysql_thread_end();
     1319#endif
    12691320        mysql_close(d->mysql);
    12701321        d->mysql = NULL;
     
    12821333{
    12831334    QStringList tl;
    1284     if (!isOpen())
    1285         return tl;
    1286     if (!(type & QSql::Tables))
    1287         return tl;
    1288 
    1289     MYSQL_RES* tableRes = mysql_list_tables(d->mysql, NULL);
    1290     MYSQL_ROW row;
    1291     int i = 0;
    1292     while (tableRes) {
    1293         mysql_data_seek(tableRes, i);
    1294         row = mysql_fetch_row(tableRes);
    1295         if (!row)
    1296             break;
    1297         tl.append(toUnicode(d->tc, row[0]));
    1298         i++;
    1299     }
    1300     mysql_free_result(tableRes);
     1335#if MYSQL_VERSION_ID >= 40100
     1336    if( mysql_get_server_version(d->mysql) < 50000)
     1337    {
     1338#endif
     1339        if (!isOpen())
     1340            return tl;
     1341        if (!(type & QSql::Tables))
     1342            return tl;
     1343
     1344        MYSQL_RES* tableRes = mysql_list_tables(d->mysql, NULL);
     1345        MYSQL_ROW row;
     1346        int i = 0;
     1347        while (tableRes) {
     1348            mysql_data_seek(tableRes, i);
     1349            row = mysql_fetch_row(tableRes);
     1350            if (!row)
     1351                break;
     1352            tl.append(toUnicode(d->tc, row[0]));
     1353            i++;
     1354        }
     1355        mysql_free_result(tableRes);
     1356#if MYSQL_VERSION_ID >= 40100
     1357    } else {
     1358        QSqlQuery q(createResult());
     1359        if(type & QSql::Tables) {
     1360            q.exec(QLatin1String("select table_name from information_schema.tables where table_type = 'BASE TABLE'"));
     1361            while(q.next())
     1362                tl.append(q.value(0).toString());
     1363        }
     1364        if(type & QSql::Views) {
     1365            q.exec(QLatin1String("select table_name from information_schema.tables where table_type = 'VIEW'"));
     1366            while(q.next())
     1367                tl.append(q.value(0).toString());
     1368        }
     1369    }
     1370#endif
    13011371    return tl;
    13021372}
     
    13051375{
    13061376    QSqlIndex idx;
    1307     bool prepQ;
    13081377    if (!isOpen())
    13091378        return idx;
    1310 
    1311     prepQ = d->preparedQuerys;
    1312     d->preparedQuerys = false;
    13131379
    13141380    QSqlQuery i(createResult());
    13151381    QString stmt(QLatin1String("show index from %1;"));
    13161382    QSqlRecord fil = record(tablename);
    1317     i.exec(stmt.arg(escapeIdentifier(tablename, QSqlDriver::TableName)));
     1383    i.exec(stmt.arg(tablename));
    13181384    while (i.isActive() && i.next()) {
    13191385        if (i.value(2).toString() == QLatin1String("PRIMARY")) {
     
    13241390    }
    13251391
    1326     d->preparedQuerys = prepQ;
    13271392    return idx;
    13281393}
     
    13301395QSqlRecord QMYSQLDriver::record(const QString& tablename) const
    13311396{
     1397    QString table=tablename;
     1398    if(isIdentifierEscaped(table, QSqlDriver::TableName))
     1399        table = stripDelimiters(table, QSqlDriver::TableName);
     1400
    13321401    QSqlRecord info;
    13331402    if (!isOpen())
    13341403        return info;
    1335     MYSQL_RES* r = mysql_list_fields(d->mysql, tablename.toLocal8Bit().constData(), 0);
     1404    MYSQL_RES* r = mysql_list_fields(d->mysql, table.toLocal8Bit().constData(), 0);
    13361405    if (!r) {
    13371406        return info;
    13381407    }
    13391408    MYSQL_FIELD* field;
     1409
    13401410    while ((field = mysql_fetch_field(r)))
    13411411        info.append(qToField(field, d->tc));
     
    14371507{
    14381508    QString res = identifier;
    1439     if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('`')) && identifier.right(1) != QString(QLatin1Char('`')) ) {
     1509    if(!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('`')) && !identifier.endsWith(QLatin1Char('`')) ) {
    14401510        res.prepend(QLatin1Char('`')).append(QLatin1Char('`'));
    14411511        res.replace(QLatin1Char('.'), QLatin1String("`.`"));
     
    14441514}
    14451515
     1516bool QMYSQLDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const
     1517{
     1518    Q_UNUSED(type);
     1519    return identifier.size() > 2
     1520        && identifier.startsWith(QLatin1Char('`')) //left delimited
     1521        && identifier.endsWith(QLatin1Char('`')); //right delimited
     1522}
     1523
    14461524QT_END_NAMESPACE
     1525
     1526#include "qsql_mysql.moc"
  • trunk/src/sql/drivers/mysql/qsql_mysql.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**
     
    7070{
    7171    friend class QMYSQLDriver;
     72    friend class QMYSQLResultPrivate;
    7273public:
    7374    explicit QMYSQLResult(const QMYSQLDriver* db);
     
    124125    QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
    125126
     127protected Q_SLOTS:
     128    bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const;
     129
    126130protected:
    127131    bool beginTransaction();
  • trunk/src/sql/drivers/oci/qsql_oci.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**
     
    149149    int serverVersion;
    150150    int prefetchRows, prefetchMem;
    151     QSql::NumericalPrecisionPolicy precisionPolicy;
    152151
    153152    void setCharset(OCIBind* hbnd);
     
    406405    ub4 prefetchRows;
    407406    ub2 prefetchMem;
    408     QSql::NumericalPrecisionPolicy precisionPolicy;
    409407    QString user;
    410408
     
    414412QOCIDriverPrivate::QOCIDriverPrivate()
    415413    : env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false), serverVersion(-1),
    416       prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM), precisionPolicy(QSql::HighPrecision)
     414      prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM)
    417415{
    418416}
     
    520518    else if (ocitype == QLatin1String("LONG") || ocitype == QLatin1String("NCLOB")
    521519             || ocitype == QLatin1String("CLOB"))
    522         type = QVariant::ByteArray;
     520        type = QVariant::String;
    523521    else if (ocitype == QLatin1String("RAW") || ocitype == QLatin1String("LONG RAW")
    524522             || ocitype == QLatin1String("ROWID") || ocitype == QLatin1String("BLOB")
     
    546544    case SQLT_RDD:
    547545    case SQLT_LNG:
     546    case SQLT_CLOB:
    548547#ifdef SQLT_INTERVAL_YM
    549548    case SQLT_INTERVAL_YM:
     
    587586    case SQLT_REF:
    588587    case SQLT_RID:
    589     case SQLT_CLOB:
    590588        type = QVariant::ByteArray;
    591589        break;
     
    612610    f.setRequired(ofi.oraIsNull == 0);
    613611
    614     if (ofi.type == QVariant::String)
     612    if (ofi.type == QVariant::String && ofi.oraType != SQLT_NUM && ofi.oraType != SQLT_VNU)
    615613        f.setLength(ofi.oraFieldLength);
    616614    else
     
    621619    return f;
    622620}
    623 
    624 static OraFieldInfo qMakeOraField(const QOCIResultPrivate* p, OCIParam* param)
    625 {
    626     OraFieldInfo ofi;
    627     ub2 colType(0);
    628     text *colName = 0;
    629     ub4 colNameLen(0);
    630     sb1 colScale(0);
    631     ub2 colLength(0);
    632     ub2 colFieldLength(0);
    633     sb2 colPrecision(0);
    634     ub1 colIsNull(0);
    635     int r(0);
    636     QVariant::Type type(QVariant::Invalid);
    637 
    638     r = OCIAttrGet(param,
    639                    OCI_DTYPE_PARAM,
    640                    &colType,
    641                    0,
    642                    OCI_ATTR_DATA_TYPE,
    643                    p->err);
    644     if (r != 0)
    645         qOraWarning("qMakeOraField:", p->err);
    646 
    647     r = OCIAttrGet(param,
    648                    OCI_DTYPE_PARAM,
    649                    &colName,
    650                    &colNameLen,
    651                    OCI_ATTR_NAME,
    652                    p->err);
    653     if (r != 0)
    654         qOraWarning("qMakeOraField:", p->err);
    655 
    656     r = OCIAttrGet(param,
    657                    OCI_DTYPE_PARAM,
    658                    &colLength,
    659                    0,
    660                    OCI_ATTR_DATA_SIZE, /* in bytes */
    661                    p->err);
    662     if (r != 0)
    663         qOraWarning("qMakeOraField:", p->err);
    664 
    665 #ifdef OCI_ATTR_CHAR_SIZE
    666     r = OCIAttrGet(param,
    667                    OCI_DTYPE_PARAM,
    668                    &colFieldLength,
    669                    0,
    670                    OCI_ATTR_CHAR_SIZE,
    671                    p->err);
    672     if (r != 0)
    673         qOraWarning("qMakeOraField:", p->err);
    674 #else
    675     // for Oracle8.
    676     colFieldLength = colLength;
    677 #endif
    678 
    679     r = OCIAttrGet(param,
    680                    OCI_DTYPE_PARAM,
    681                    &colPrecision,
    682                    0,
    683                    OCI_ATTR_PRECISION,
    684                    p->err);
    685     if (r != 0)
    686         qOraWarning("qMakeOraField:", p->err);
    687 
    688     r = OCIAttrGet(param,
    689                    OCI_DTYPE_PARAM,
    690                    &colScale,
    691                    0,
    692                    OCI_ATTR_SCALE,
    693                    p->err);
    694     if (r != 0)
    695         qOraWarning("qMakeOraField:", p->err);
    696     r = OCIAttrGet(param,
    697                    OCI_DTYPE_PARAM,
    698                    &colType,
    699                    0,
    700                    OCI_ATTR_DATA_TYPE,
    701                    p->err);
    702     if (r != 0)
    703         qOraWarning("qMakeOraField:", p->err);
    704     r = OCIAttrGet(param,
    705                    OCI_DTYPE_PARAM,
    706                    &colIsNull,
    707                    0,
    708                    OCI_ATTR_IS_NULL,
    709                    p->err);
    710     if (r != 0)
    711         qOraWarning("qMakeOraField:", p->err);
    712 
    713     type = qDecodeOCIType(colType, p->precisionPolicy);
    714 
    715     if (type == QVariant::Int) {
    716         if (colLength == 22 && colPrecision == 0 && colScale == 0)
    717             type = QVariant::String;
    718         if (colScale > 0)
    719             type = QVariant::String;
    720     }
    721 
    722     // bind as double if the precision policy asks for it
    723     if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
    724             && (p->precisionPolicy == QSql::LowPrecisionDouble)) {
    725         type = QVariant::Double;
    726     }
    727 
    728     // bind as int32 or int64 if the precision policy asks for it
    729     if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
    730             || (colType == SQLT_INT)) {
    731         if (p->precisionPolicy == QSql::LowPrecisionInt64)
    732             type = QVariant::LongLong;
    733         else if (p->precisionPolicy == QSql::LowPrecisionInt32)
    734             type = QVariant::Int;
    735     }
    736 
    737     if (colType == SQLT_BLOB)
    738         colLength = 0;
    739 
    740     // colNameLen is length in bytes
    741     ofi.name = QString(reinterpret_cast<const QChar*>(colName), colNameLen / 2);
    742     ofi.type = type;
    743     ofi.oraType = colType;
    744     ofi.oraFieldLength = colFieldLength;
    745     ofi.oraLength = colLength;
    746     ofi.oraScale = colScale;
    747     ofi.oraPrecision = colPrecision;
    748     ofi.oraIsNull = colIsNull;
    749 
    750     return ofi;
    751 }
    752 
    753621
    754622/*!
     
    807675    char* create(int position, int size);
    808676    OCILobLocator ** createLobLocator(int position, OCIEnv* env);
     677    OraFieldInfo qMakeOraField(const QOCIResultPrivate* p, OCIParam* param) const;
    809678
    810679    class OraFieldInf
     
    11381007}
    11391008
     1009OraFieldInfo QOCICols::qMakeOraField(const QOCIResultPrivate* p, OCIParam* param) const
     1010{
     1011    OraFieldInfo ofi;
     1012    ub2 colType(0);
     1013    text *colName = 0;
     1014    ub4 colNameLen(0);
     1015    sb1 colScale(0);
     1016    ub2 colLength(0);
     1017    ub2 colFieldLength(0);
     1018    sb2 colPrecision(0);
     1019    ub1 colIsNull(0);
     1020    int r(0);
     1021    QVariant::Type type(QVariant::Invalid);
     1022
     1023    r = OCIAttrGet(param,
     1024                   OCI_DTYPE_PARAM,
     1025                   &colType,
     1026                   0,
     1027                   OCI_ATTR_DATA_TYPE,
     1028                   p->err);
     1029    if (r != 0)
     1030        qOraWarning("qMakeOraField:", p->err);
     1031
     1032    r = OCIAttrGet(param,
     1033                   OCI_DTYPE_PARAM,
     1034                   &colName,
     1035                   &colNameLen,
     1036                   OCI_ATTR_NAME,
     1037                   p->err);
     1038    if (r != 0)
     1039        qOraWarning("qMakeOraField:", p->err);
     1040
     1041    r = OCIAttrGet(param,
     1042                   OCI_DTYPE_PARAM,
     1043                   &colLength,
     1044                   0,
     1045                   OCI_ATTR_DATA_SIZE, /* in bytes */
     1046                   p->err);
     1047    if (r != 0)
     1048        qOraWarning("qMakeOraField:", p->err);
     1049
     1050#ifdef OCI_ATTR_CHAR_SIZE
     1051    r = OCIAttrGet(param,
     1052                   OCI_DTYPE_PARAM,
     1053                   &colFieldLength,
     1054                   0,
     1055                   OCI_ATTR_CHAR_SIZE,
     1056                   p->err);
     1057    if (r != 0)
     1058        qOraWarning("qMakeOraField:", p->err);
     1059#else
     1060    // for Oracle8.
     1061    colFieldLength = colLength;
     1062#endif
     1063
     1064    r = OCIAttrGet(param,
     1065                   OCI_DTYPE_PARAM,
     1066                   &colPrecision,
     1067                   0,
     1068                   OCI_ATTR_PRECISION,
     1069                   p->err);
     1070    if (r != 0)
     1071        qOraWarning("qMakeOraField:", p->err);
     1072
     1073    r = OCIAttrGet(param,
     1074                   OCI_DTYPE_PARAM,
     1075                   &colScale,
     1076                   0,
     1077                   OCI_ATTR_SCALE,
     1078                   p->err);
     1079    if (r != 0)
     1080        qOraWarning("qMakeOraField:", p->err);
     1081    r = OCIAttrGet(param,
     1082                   OCI_DTYPE_PARAM,
     1083                   &colType,
     1084                   0,
     1085                   OCI_ATTR_DATA_TYPE,
     1086                   p->err);
     1087    if (r != 0)
     1088        qOraWarning("qMakeOraField:", p->err);
     1089    r = OCIAttrGet(param,
     1090                   OCI_DTYPE_PARAM,
     1091                   &colIsNull,
     1092                   0,
     1093                   OCI_ATTR_IS_NULL,
     1094                   p->err);
     1095    if (r != 0)
     1096        qOraWarning("qMakeOraField:", p->err);
     1097
     1098    type = qDecodeOCIType(colType, p->q->numericalPrecisionPolicy());
     1099
     1100    if (type == QVariant::Int) {
     1101        if (colLength == 22 && colPrecision == 0 && colScale == 0)
     1102            type = QVariant::String;
     1103        if (colScale > 0)
     1104            type = QVariant::String;
     1105    }
     1106
     1107    // bind as double if the precision policy asks for it
     1108    if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
     1109            && (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)) {
     1110        type = QVariant::Double;
     1111    }
     1112
     1113    // bind as int32 or int64 if the precision policy asks for it
     1114    if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
     1115            || (colType == SQLT_INT)) {
     1116        if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
     1117            type = QVariant::LongLong;
     1118        else if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
     1119            type = QVariant::Int;
     1120    }
     1121
     1122    if (colType == SQLT_BLOB)
     1123        colLength = 0;
     1124
     1125    // colNameLen is length in bytes
     1126    ofi.name = QString(reinterpret_cast<const QChar*>(colName), colNameLen / 2);
     1127    ofi.type = type;
     1128    ofi.oraType = colType;
     1129    ofi.oraFieldLength = colFieldLength;
     1130    ofi.oraLength = colLength;
     1131    ofi.oraScale = colScale;
     1132    ofi.oraPrecision = colPrecision;
     1133    ofi.oraIsNull = colIsNull;
     1134
     1135    return ofi;
     1136}
     1137
    11401138struct QOCIBatchColumn
    11411139{
     
    12601258                col.bindAs = SQLT_STR;
    12611259                for (uint j = 0; j < col.recordCount; ++j) {
    1262                     uint len = boundValues.at(i).toList().at(j).toString().length() + 1;
     1260                    uint len;
     1261                    if(d->isOutValue(i))
     1262                        len = boundValues.at(i).toList().at(j).toString().capacity() + 1;
     1263                    else
     1264                        len = boundValues.at(i).toList().at(j).toString().length() + 1;
    12631265                    if (len > col.maxLen)
    12641266                        col.maxLen = len;
     
    12711273                col.bindAs = SQLT_LBI;
    12721274                for (uint j = 0; j < col.recordCount; ++j) {
    1273                     col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().size();
     1275                    if(d->isOutValue(i))
     1276                        col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().capacity();
     1277                    else
     1278                        col.lengths[j] = boundValues.at(i).toList().at(j).toByteArray().size();
    12741279                    if (col.lengths[j] > col.maxLen)
    12751280                        col.maxLen = col.lengths[j];
     
    15811586        case QVariant::Int:
    15821587        case QVariant::LongLong:
    1583             if (d->precisionPolicy != QSql::HighPrecision) {
    1584                 if ((d->precisionPolicy == QSql::LowPrecisionDouble)
     1588            if (d->q->numericalPrecisionPolicy() != QSql::HighPrecision) {
     1589                if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
    15851590                        && (fld.typ == QVariant::Double)) {
    15861591                    v[index + i] = *reinterpret_cast<double *>(fld.data);
    15871592                    break;
    1588                 } else if ((d->precisionPolicy == QSql::LowPrecisionInt64)
     1593                } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
    15891594                        && (fld.typ == QVariant::LongLong)) {
    15901595                    qint64 qll = 0;
    1591                     OCINumberToInt(d->err, reinterpret_cast<OCINumber *>(fld.data), sizeof(qint64),
     1596                    int r = OCINumberToInt(d->err, reinterpret_cast<OCINumber *>(fld.data), sizeof(qint64),
    15921597                                   OCI_NUMBER_SIGNED, &qll);
    1593                     v[index + i] = qll;
     1598                    if(r == OCI_SUCCESS)
     1599                        v[index + i] = qll;
     1600                    else
     1601                        v[index + i] = QVariant();
    15941602                    break;
    1595                 } else if ((d->precisionPolicy == QSql::LowPrecisionInt32)
     1603                } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
    15961604                        && (fld.typ == QVariant::Int)) {
    15971605                    v[index + i] = *reinterpret_cast<int *>(fld.data);
     
    16191627    : cols(0), q(result), env(driver->env), err(0), svc(const_cast<OCISvcCtx*&>(driver->svc)),
    16201628      sql(0), transaction(driver->transaction), serverVersion(driver->serverVersion),
    1621       prefetchRows(driver->prefetchRows), prefetchMem(driver->prefetchMem),
    1622       precisionPolicy(driver->precisionPolicy)
     1629      prefetchRows(driver->prefetchRows), prefetchMem(driver->prefetchMem)
    16231630{
    16241631    int r = OCIHandleAlloc(env,
     
    17901797{
    17911798    int r = 0;
    1792     ub2 stmtType;
     1799    ub2 stmtType=0;
    17931800    ub4 iters;
    17941801    ub4 mode;
     
    18031810                    OCI_ATTR_STMT_TYPE,
    18041811                    d->err);
     1812
     1813    if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
     1814        qOraWarning("QOCIResult::exec: Unable to get statement type:", d->err);
     1815        setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
     1816                     "Unable to get statement type"), QSqlError::StatementError, d->err));
     1817#ifdef QOCI_DEBUG
     1818        qDebug() << "lastQuery()" << lastQuery();
     1819#endif
     1820        return false;
     1821    }
    18051822
    18061823    if (stmtType == OCI_STMT_SELECT) {
     
    18921909        QOCICols::execBatch(d, boundValues(), *reinterpret_cast<bool *>(data));
    18931910        break;
    1894     case QSqlResult::SetNumericalPrecision:
    1895         d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
    1896         break;
    18971911    default:
    1898         QSqlResult::virtual_hook(id, data);
     1912        QSqlCachedResult::virtual_hook(id, data);
    18991913    }
    19001914}
     
    20312045    if (!hostname.isEmpty())
    20322046        connectionString =
    2033             QString(QLatin1String("(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
    2034                 "(CONNECT_DATA=(SID=%3)))")).arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
     2047        QString::fromLatin1("(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=%1)(Port=%2))"
     2048                "(CONNECT_DATA=(SID=%3)))").arg(hostname).arg((port > -1 ? port : 1521)).arg(db);
    20352049
    20362050    r = OCIHandleAlloc(d->env, reinterpret_cast<void **>(&d->srvhp), OCI_HTYPE_SERVER, 0, 0);
     
    20992113    setOpen(true);
    21002114    setOpenError(false);
    2101     d->user = user.toUpper();
     2115    d->user = user;
    21022116
    21032117    return true;
     
    21872201{
    21882202    QStringList tl;
     2203    QStringList sysUsers = QStringList() << QLatin1String("MDSYS")
     2204                                    << QLatin1String("LBACSYS")
     2205                                    << QLatin1String("SYS")
     2206                                    << QLatin1String("SYSTEM")
     2207                                    << QLatin1String("WKSYS")
     2208                                    << QLatin1String("CTXSYS")
     2209                                    << QLatin1String("WMSYS");
     2210
     2211    QString user = d->user;
     2212    if ( isIdentifierEscaped(user, QSqlDriver::TableName))
     2213        user = stripDelimiters(user, QSqlDriver::TableName);
     2214    else
     2215        user = user.toUpper();
     2216
     2217    if(sysUsers.contains(user))
     2218        sysUsers.removeAll(user);;
     2219
    21892220    if (!isOpen())
    21902221        return tl;
     
    21932224    t.setForwardOnly(true);
    21942225    if (type & QSql::Tables) {
    2195         t.exec(QLatin1String("select owner, table_name from all_tables "
    2196                 "where owner != 'MDSYS' "
    2197                 "and owner != 'LBACSYS' "
    2198                 "and owner != 'SYS' "
    2199                 "and owner != 'SYSTEM' "
    2200                 "and owner != 'WKSYS'"
    2201                 "and owner != 'CTXSYS'"
    2202                 "and owner != 'WMSYS'"));
     2226        QString query = QLatin1String("select owner, table_name from all_tables where ");
     2227        QStringList whereList;
     2228        foreach(const QString &sysUserName, sysUsers)
     2229            whereList << QLatin1String("owner != '") + sysUserName + QLatin1String("' ");
     2230        t.exec(query + whereList.join(QLatin1String(" and ")));
     2231
     2232        while (t.next()) {
     2233            if (t.value(0).toString().toUpper() != user.toUpper())
     2234                tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString());
     2235            else
     2236                tl.append(t.value(1).toString());
     2237        }
     2238
     2239        // list all table synonyms as well
     2240        query = QLatin1String("select owner, synonym_name from all_synonyms where ");
     2241        t.exec(query + whereList.join(QLatin1String(" and ")));
     2242        while (t.next()) {
     2243            if (t.value(0).toString() != d->user)
     2244                tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString());
     2245            else
     2246                tl.append(t.value(1).toString());
     2247        }
     2248    }
     2249    if (type & QSql::Views) {
     2250        QString query = QLatin1String("select owner, view_name from all_views where ");
     2251        QStringList whereList;
     2252        foreach(const QString &sysUserName, sysUsers)
     2253            whereList << QLatin1String("owner != '") + sysUserName + QLatin1String("' ");
     2254        t.exec(query + whereList.join(QLatin1String(" and ")));
     2255        while (t.next()) {
     2256            if (t.value(0).toString().toUpper() != d->user.toUpper())
     2257                tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString());
     2258            else
     2259                tl.append(t.value(1).toString());
     2260        }
     2261    }
     2262    if (type & QSql::SystemTables) {
     2263        t.exec(QLatin1String("select table_name from dictionary"));
     2264        while (t.next()) {
     2265            tl.append(t.value(0).toString());
     2266        }
     2267        QString query = QLatin1String("select owner, table_name from all_tables where ");
     2268        QStringList whereList;
     2269        foreach(const QString &sysUserName, sysUsers)
     2270            whereList << QLatin1String("owner = '") + sysUserName + QLatin1String("' ");
     2271        t.exec(query + whereList.join(QLatin1String(" or ")));
     2272
     2273        while (t.next()) {
     2274            if (t.value(0).toString().toUpper() != user.toUpper())
     2275                tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString());
     2276            else
     2277                tl.append(t.value(1).toString());
     2278        }
     2279
     2280        // list all table synonyms as well
     2281        query = QLatin1String("select owner, synonym_name from all_synonyms where ");
     2282        t.exec(query + whereList.join(QLatin1String(" or ")));
    22032283        while (t.next()) {
    22042284            if (t.value(0).toString() != d->user)
     
    22082288        }
    22092289    }
    2210     if (type & QSql::Views) {
    2211         t.exec(QLatin1String("select owner, view_name from all_views "
    2212                 "where owner != 'MDSYS' "
    2213                 "and owner != 'LBACSYS' "
    2214                 "and owner != 'SYS' "
    2215                 "and owner != 'SYSTEM' "
    2216                 "and owner != 'WKSYS'"
    2217                 "and owner != 'CTXSYS'"
    2218                 "and owner != 'WMSYS'"));
    2219         while (t.next()) {
    2220             if (t.value(0).toString() != d->user)
    2221                 tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString());
    2222             else
    2223                 tl.append(t.value(1).toString());
    2224         }
    2225     }
    2226     if (type & QSql::SystemTables) {
    2227         t.exec(QLatin1String("select table_name from dictionary"));
    2228         while (t.next()) {
    2229             tl.append(t.value(0).toString());
    2230         }
    2231     }
    22322290    return tl;
    22332291}
     
    22382296    int i = tname.indexOf(QLatin1Char('.')); // prefixed with owner?
    22392297    if (i != -1) {
    2240         *tbl = tname.right(tname.length() - i - 1).toUpper();
    2241         *owner = tname.left(i).toUpper();
     2298        *tbl = tname.right(tname.length() - i - 1);
     2299        *owner = tname.left(i);
    22422300    } else {
    2243         *tbl = tname.toUpper();
     2301        *tbl = tname;
    22442302    }
    22452303}
     
    22562314    QString stmt(QLatin1String("select column_name, data_type, data_length, "
    22572315                  "data_precision, data_scale, nullable, data_default%1"
    2258                   "from all_tab_columns "
    2259                   "where upper(table_name)=%2"));
     2316                  "from all_tab_columns a "
     2317                  "where a.table_name=%2"));
    22602318    if (d->serverVersion >= 9)
    22612319        stmt = stmt.arg(QLatin1String(", char_length "));
     
    22652323    QString table, owner, tmpStmt;
    22662324    qSplitTableAndOwner(tablename, &table, &owner);
     2325
     2326    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     2327        table = stripDelimiters(table, QSqlDriver::TableName);
     2328    else
     2329        table = table.toUpper();
     2330
    22672331    tmpStmt = stmt.arg(QLatin1Char('\'') + table + QLatin1Char('\''));
    22682332    if (owner.isEmpty()) {
    22692333        owner = d->user;
    22702334    }
    2271     tmpStmt += QLatin1String(" and upper(owner)='") + owner + QLatin1String("'");
     2335
     2336    if (isIdentifierEscaped(owner, QSqlDriver::TableName))
     2337        owner = stripDelimiters(owner, QSqlDriver::TableName);
     2338    else
     2339        owner = owner.toUpper();
     2340
     2341    tmpStmt += QLatin1String(" and a.owner='") + owner + QLatin1Char('\'');
    22722342    t.setForwardOnly(true);
    22732343    t.exec(tmpStmt);
    22742344    if (!t.next()) { // try and see if the tablename is a synonym
    2275         stmt= stmt.arg(QLatin1String("(select tname from sys.synonyms where sname='")
    2276                         + table + QLatin1String("' and creator=owner)"));
     2345        stmt = stmt + QLatin1String(" join all_synonyms b "
     2346                              "on a.owner=b.table_owner and a.table_name=b.table_name "
     2347                              "where b.owner='") + owner +
     2348                      QLatin1String("' and b.synonym_name='") + table +
     2349                      QLatin1Char('\'');
    22772350        t.setForwardOnly(true);
    22782351        t.exec(stmt);
     
    22862359    if (buildRecordInfo) {
    22872360        do {
    2288             QVariant::Type ty = qDecodeOCIType(t.value(1).toString(),t.numericalPrecisionPolicy());
     2361            QVariant::Type ty = qDecodeOCIType(t.value(1).toString(), t.numericalPrecisionPolicy());
    22892362            QSqlField f(t.value(0).toString(), ty);
    22902363            f.setRequired(t.value(5).toString() == QLatin1String("N"));
     
    23182391    QString table, owner, tmpStmt;
    23192392    qSplitTableAndOwner(tablename, &table, &owner);
    2320     tmpStmt = stmt + QLatin1String(" and upper(a.table_name)='") + table + QLatin1String("'");
     2393
     2394    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     2395        table = stripDelimiters(table, QSqlDriver::TableName);
     2396    else
     2397        table = table.toUpper();
     2398
     2399    tmpStmt = stmt + QLatin1String(" and a.table_name='") + table + QLatin1Char('\'');
    23212400    if (owner.isEmpty()) {
    23222401        owner = d->user;
    23232402    }
    2324     tmpStmt += QLatin1String(" and upper(a.owner)='") + owner + QLatin1String("'");
     2403
     2404    if (isIdentifierEscaped(owner, QSqlDriver::TableName))
     2405        owner = stripDelimiters(owner, QSqlDriver::TableName);
     2406    else
     2407        owner = owner.toUpper();
     2408
     2409    tmpStmt += QLatin1String(" and a.owner='") + owner + QLatin1Char('\'');
    23252410    t.setForwardOnly(true);
    23262411    t.exec(tmpStmt);
     
    23462431                     t.value(2).toString() + QLatin1String("' and column_name='") +
    23472432                     t.value(0).toString() + QLatin1String("' and owner='") +
    2348                      owner +QLatin1String("'"));
     2433                     owner + QLatin1Char('\''));
    23492434            if (!tt.next()) {
    23502435                return QSqlIndex();
     
    24162501}
    24172502
    2418 QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType /* type */) const
     2503QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
    24192504{
    24202505    QString res = identifier;
    2421     res.replace(QLatin1Char('"'), QLatin1String("\"\""));
    2422     if (identifier.indexOf(QLatin1Char(' ')) != -1)
     2506    if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type)) {
     2507        res.replace(QLatin1Char('"'), QLatin1String("\"\""));
    24232508        res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
    2424 //     res.replace(QLatin1Char('.'), QLatin1String("\".\""));
     2509        res.replace(QLatin1Char('.'), QLatin1String("\".\""));
     2510    }
    24252511    return res;
    24262512}
  • trunk/src/sql/drivers/oci/qsql_oci.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**
  • 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();
  • trunk/src/sql/drivers/psql/qsql_psql.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**
     
    5555#include <qmutex.h>
    5656
     57
    5758#include <libpq-fe.h>
    5859#include <pg_config.h>
     
    6061#include <stdlib.h>
    6162#include <math.h>
     63// below code taken from an example at http://www.gnu.org/software/hello/manual/autoconf/Function-Portability.html
     64#ifndef isnan
     65    # define isnan(x) \
     66        (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
     67        : sizeof (x) == sizeof (double) ? isnan_d (x) \
     68        : isnan_f (x))
     69    static inline int isnan_f  (float       x) { return x != x; }
     70    static inline int isnan_d  (double      x) { return x != x; }
     71    static inline int isnan_ld (long double x) { return x != x; }
     72#endif
     73
     74#ifndef isinf
     75    # define isinf(x) \
     76        (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
     77        : sizeof (x) == sizeof (double) ? isinf_d (x) \
     78        : isinf_f (x))
     79    static inline int isinf_f  (float       x) { return isnan (x - x); }
     80    static inline int isinf_d  (double      x) { return isnan (x - x); }
     81    static inline int isinf_ld (long double x) { return isnan (x - x); }
     82#endif
     83
    6284
    6385// workaround for postgres defining their OIDs in a private header file
     
    137159{
    138160public:
    139     QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1), precisionPolicy(QSql::HighPrecision) {}
     161    QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1), preparedQueriesEnabled(false) {}
    140162
    141163    QPSQLResult *q;
     
    143165    PGresult *result;
    144166    int currentSize;
    145     QSql::NumericalPrecisionPolicy precisionPolicy;
    146167    bool preparedQueriesEnabled;
    147168    QString preparedStmtId;
     
    321342    case QVariant::Double:
    322343        if (ptype == QNUMERICOID) {
    323             if (d->precisionPolicy != QSql::HighPrecision) {
     344            if (numericalPrecisionPolicy() != QSql::HighPrecision) {
    324345                QVariant retval;
    325346                bool convert;
    326                 if (d->precisionPolicy == QSql::LowPrecisionInt64)
    327                     retval = QString::fromAscii(val).toLongLong(&convert);
    328                 else if (d->precisionPolicy == QSql::LowPrecisionInt32)
    329                     retval = QString::fromAscii(val).toInt(&convert);
    330                 else if (d->precisionPolicy == QSql::LowPrecisionDouble)
    331                     retval = QString::fromAscii(val).toDouble(&convert);
     347                double dbl=QString::fromAscii(val).toDouble(&convert);
     348                if (numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
     349                    retval = (qlonglong)dbl;
     350                else if (numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
     351                    retval = (int)dbl;
     352                else if (numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
     353                    retval = dbl;
    332354                if (!convert)
    333355                    return QVariant();
     
    336358            return QString::fromAscii(val);
    337359        }
    338         return strtod(val, 0);
     360        return QString::fromAscii(val).toDouble();
    339361    case QVariant::Date:
    340362        if (val[0] == '\0') {
     
    468490
    469491    switch (id) {
    470     case QSqlResult::SetNumericalPrecision:
    471         d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
    472         break;
    473492    default:
    474493        QSqlResult::virtual_hook(id, data);
     
    535554    if (!d->preparedQueriesEnabled)
    536555        return QSqlResult::prepare(query);
    537    
     556
    538557    cleanup();
    539558
     
    542561
    543562    const QString stmtId = qMakePreparedStmtId();
    544     const QString stmt = QString(QLatin1String("PREPARE %1 AS ")).arg(stmtId).append(qReplacePlaceholderMarkers(query));
     563    const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(qReplacePlaceholderMarkers(query));
    545564
    546565    PGresult *result = PQexec(d->driver->connection,
     
    571590    const QString params = qCreateParamString(boundValues(), d->q->driver());
    572591    if (params.isEmpty())
    573         stmt = QString(QLatin1String("EXECUTE %1")).arg(d->preparedStmtId);
     592        stmt = QString::fromLatin1("EXECUTE %1").arg(d->preparedStmtId);
    574593    else
    575         stmt = QString(QLatin1String("EXECUTE %1 (%2)")).arg(d->preparedStmtId).arg(params);
     594        stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId).arg(params);
    576595
    577596    d->result = PQexec(d->driver->connection,
     
    605624    QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6;
    606625    PGresult* result = PQexec(connection, "select version()");
    607     int status =  PQresultStatus(result);
     626    int status = PQresultStatus(result);
    608627    if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) {
    609628        QString val = QString::fromAscii(PQgetvalue(result, 0, 0));
    610         PQclear(result);
    611629        QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)"));
    612630        rx.setMinimal(true); // enforce non-greedy RegExp
     
    649667        }
    650668    }
     669    PQclear(result);
    651670
    652671    if (serverVersion < QPSQLDriver::Version71)
     
    825844    }
    826845    PGresult* res = PQexec(d->connection, "COMMIT");
    827     if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) {
     846
     847    bool transaction_failed = false;
     848
     849    // XXX
     850    // This hack is used to tell if the transaction has succeeded for the protocol versions of
     851    // PostgreSQL below. For 7.x and other protocol versions we are left in the dark.
     852    // This hack can dissapear once there is an API to query this sort of information.
     853    if (d->pro == QPSQLDriver::Version8 ||
     854        d->pro == QPSQLDriver::Version81 ||
     855        d->pro == QPSQLDriver::Version82) {
     856        transaction_failed = qstrcmp(PQcmdStatus(res), "ROLLBACK") == 0;
     857    }
     858
     859    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK || transaction_failed) {
    828860        PQclear(res);
    829861        setLastError(qMakeError(tr("Could not commit transaction"),
     
    895927    qSplitTableName(tbl, schema);
    896928
     929    if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
     930        tbl = stripDelimiters(tbl, QSqlDriver::TableName);
     931    else
     932        tbl = tbl.toLower();
     933
     934    if (isIdentifierEscaped(schema, QSqlDriver::TableName))
     935        schema = stripDelimiters(schema, QSqlDriver::TableName);
     936    else
     937        schema = schema.toLower();
     938
    897939    switch(d->pro) {
    898940    case QPSQLDriver::Version6:
    899941        stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname "
    900942                "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "
    901                 "where lower(pg_cl.relname) = '%1_pkey' "
     943                "where pg_cl.relname = '%1_pkey' "
    902944                "and pg_cl.oid = pg_ind.indexrelid "
    903945                "and pg_att2.attrelid = pg_ind.indexrelid "
     
    910952        stmt = QLatin1String("select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname "
    911953                "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "
    912                 "where lower(pg_cl.relname) = '%1_pkey' "
     954                "where pg_cl.relname = '%1_pkey' "
    913955                "and pg_cl.oid = pg_ind.indexrelid "
    914956                "and pg_att2.attrelid = pg_ind.indexrelid "
     
    927969                "WHERE %1 pg_class.oid IN "
    928970                "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN "
    929                 " (SELECT oid FROM pg_class WHERE lower(relname) = '%2')) "
     971                " (SELECT oid FROM pg_class WHERE relname = '%2')) "
    930972                "AND pg_attribute.attrelid = pg_class.oid "
    931973                "AND pg_attribute.attisdropped = false "
     
    935977        else
    936978            stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "
    937                    "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema.toLower()));
    938         break;
    939     }
    940 
    941     i.exec(stmt.arg(tbl.toLower()));
     979                   "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema));
     980        break;
     981    }
     982
     983    i.exec(stmt.arg(tbl));
    942984    while (i.isActive() && i.next()) {
    943985        QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt()));
     
    957999    QString schema;
    9581000    qSplitTableName(tbl, schema);
     1001
     1002    if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
     1003        tbl = stripDelimiters(tbl, QSqlDriver::TableName);
     1004    else
     1005        tbl = tbl.toLower();
     1006
     1007    if (isIdentifierEscaped(schema, QSqlDriver::TableName))
     1008        schema = stripDelimiters(schema, QSqlDriver::TableName);
     1009    else
     1010        schema = schema.toLower();
    9591011
    9601012    QString stmt;
     
    9651017                "int(pg_attribute.attrelid), pg_attribute.attnum "
    9661018                "from pg_class, pg_attribute "
    967                 "where lower(pg_class.relname) = '%1' "
     1019                "where pg_class.relname = '%1' "
    9681020                "and pg_attribute.attnum > 0 "
    9691021                "and pg_attribute.attrelid = pg_class.oid ");
     
    9741026                "pg_attribute.attrelid::int, pg_attribute.attnum "
    9751027                "from pg_class, pg_attribute "
    976                 "where lower(pg_class.relname) = '%1' "
     1028                "where pg_class.relname = '%1' "
    9771029                "and pg_attribute.attnum > 0 "
    9781030                "and pg_attribute.attrelid = pg_class.oid ");
     
    9851037                "left join pg_attrdef on (pg_attrdef.adrelid = "
    9861038                "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "
    987                 "where lower(pg_class.relname) = '%1' "
     1039                "where pg_class.relname = '%1' "
    9881040                "and pg_attribute.attnum > 0 "
    9891041                "and pg_attribute.attrelid = pg_class.oid "
     
    10021054                "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "
    10031055                "where %1 "
    1004                 "and lower(pg_class.relname) = '%2' "
     1056                "and pg_class.relname = '%2' "
    10051057                "and pg_attribute.attnum > 0 "
    10061058                "and pg_attribute.attrelid = pg_class.oid "
     
    10111063        else
    10121064            stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "
    1013                    "pg_namespace where pg_namespace.nspname = '%1')").arg(schema.toLower()));
     1065                   "pg_namespace where pg_namespace.nspname = '%1')").arg(schema));
    10141066        break;
    10151067    }
    10161068
    10171069    QSqlQuery query(createResult());
    1018     query.exec(stmt.arg(tbl.toLower()));
     1070    query.exec(stmt.arg(tbl));
    10191071    if (d->pro >= QPSQLDriver::Version71) {
    10201072        while (query.next()) {
     
    10831135                // msecs need to be right aligned otherwise psql
    10841136                // interpretes them wrong
    1085                 r = QLatin1String("'") + QString::number(dt.year()) + QLatin1String("-")
    1086                           + QString::number(dt.month()) + QLatin1String("-")
    1087                           + QString::number(dt.day()) + QLatin1String(" ")
    1088                           + tm.toString() + QLatin1String(".")
     1137                r = QLatin1Char('\'') + QString::number(dt.year()) + QLatin1Char('-')
     1138                          + QString::number(dt.month()) + QLatin1Char('-')
     1139                          + QString::number(dt.day()) + QLatin1Char(' ')
     1140                          + tm.toString() + QLatin1Char('.')
    10891141                          + QString::number(tm.msec()).rightJustified(3, QLatin1Char('0'))
    1090                           + QLatin1String("'");
     1142                          + QLatin1Char('\'');
    10911143            } else {
    10921144                r = QLatin1String("NULL");
     
    10991151#ifndef QT_NO_DATESTRING
    11001152            if (field.value().toTime().isValid()) {
    1101                 r = field.value().toTime().toString(Qt::ISODate);
     1153                r = QLatin1Char('\'') + field.value().toTime().toString(QLatin1String("hh:mm:ss.zzz")) + QLatin1Char('\'');
    11021154            } else
    11031155#endif
     
    11051157                r = QLatin1String("NULL");
    11061158            }
     1159            break;
    11071160        case QVariant::String:
    11081161        {
     
    11321185            break;
    11331186        }
     1187        case QVariant::Double: {
     1188            double val = field.value().toDouble();
     1189            if (isnan(val))
     1190                r = QLatin1String("'NaN'");
     1191            else {
     1192                int res = isinf(val);
     1193                if (res == 1)
     1194                    r = QLatin1String("'Infinity'");
     1195                else if (res == -1)
     1196                    r = QLatin1String("'-Infinity'");
     1197                else
     1198                    r = QSqlDriver::formatValue(field, trimStrings);
     1199            }
     1200            break;
     1201        }
    11341202        default:
    11351203            r = QSqlDriver::formatValue(field, trimStrings);
     
    11431211{
    11441212    QString res = identifier;
    1145     if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
     1213    if(!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('"')) && !identifier.endsWith(QLatin1Char('"')) ) {
    11461214        res.replace(QLatin1Char('"'), QLatin1String("\"\""));
    11471215        res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
     
    11731241        return false;
    11741242    }
    1175    
     1243
    11761244    int socket = PQsocket(d->connection);
    11771245    if (socket) {
    1178         QString query = QString(QLatin1String("LISTEN %1")).arg(escapeIdentifier(name, QSqlDriver::TableName));
    1179         if (PQresultStatus(PQexec(d->connection, 
    1180                                   d->isUtf8 ? query.toUtf8().constData() 
     1246        QString query = QLatin1String("LISTEN ") + escapeIdentifier(name, QSqlDriver::TableName);
     1247        if (PQresultStatus(PQexec(d->connection,
     1248                                  d->isUtf8 ? query.toUtf8().constData()
    11811249                                            : query.toLocal8Bit().constData())
    11821250                          ) != PGRES_COMMAND_OK) {
     
    12081276    }
    12091277
    1210     QString query = QString(QLatin1String("UNLISTEN %1")).arg(escapeIdentifier(name, QSqlDriver::TableName));
    1211     if (PQresultStatus(PQexec(d->connection, 
    1212                               d->isUtf8 ? query.toUtf8().constData() 
     1278    QString query = QLatin1String("UNLISTEN ") + escapeIdentifier(name, QSqlDriver::TableName);
     1279    if (PQresultStatus(PQexec(d->connection,
     1280                              d->isUtf8 ? query.toUtf8().constData()
    12131281                                        : query.toLocal8Bit().constData())
    12141282                      ) != PGRES_COMMAND_OK) {
     
    12361304{
    12371305    PQconsumeInput(d->connection);
    1238     PGnotify *notify = PQnotifies(d->connection);
    1239     if (notify) {
     1306
     1307    PGnotify *notify = 0;
     1308    while((notify = PQnotifies(d->connection)) != 0) {
    12401309        QString name(QLatin1String(notify->relname));
    1241 
    12421310        if (d->seid.contains(name))
    12431311            emit notification(name);
    12441312        else
    1245             qWarning("QPSQLDriver: received notification for '%s' which isn't subscribed to.", 
    1246                 qPrintable(name));
     1313            qWarning("QPSQLDriver: received notification for '%s' which isn't subscribed to.",
     1314                    qPrintable(name));
    12471315
    12481316        qPQfreemem(notify);
  • trunk/src/sql/drivers/psql/qsql_psql.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**
  • trunk/src/sql/drivers/sqlite/qsql_sqlite.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**
     
    6464
    6565QT_BEGIN_NAMESPACE
     66
     67static QString _q_escapeIdentifier(const QString &identifier)
     68{
     69    QString res = identifier;
     70    if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
     71        res.replace(QLatin1Char('"'), QLatin1String("\"\""));
     72        res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
     73        res.replace(QLatin1Char('.'), QLatin1String("\".\""));
     74    }
     75    return res;
     76}
    6677
    6778static QVariant::Type qGetColumnType(const QString &tpName)
     
    112123    sqlite3_stmt *stmt;
    113124
    114     uint skippedStatus: 1; // the status of the fetchNext() that's skipped
    115     uint skipRow: 1; // skip the next fetchNext()?
    116     uint utf8: 1;
     125    bool skippedStatus; // the status of the fetchNext() that's skipped
     126    bool skipRow; // skip the next fetchNext()?
    117127    QSqlRecord rInf;
    118     QSql::NumericalPrecisionPolicy precisionPolicy;
     128    QVector<QVariant> firstRow;
    119129};
    120130
    121 static const uint initial_cache_size = 128;
    122 
    123131QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult* res) : q(res), access(0),
    124     stmt(0), skippedStatus(false), skipRow(false), utf8(false), precisionPolicy(QSql::HighPrecision)
     132    stmt(0), skippedStatus(false), skipRow(false)
    125133{
    126134}
     
    182190        Q_ASSERT(!initialFetch);
    183191        skipRow = false;
     192        for(int i=0;i<firstRow.count();i++)
     193            values[i]=firstRow[i];
    184194        return skippedStatus;
    185195    }
    186196    skipRow = initialFetch;
     197
     198    if(initialFetch) {
     199        firstRow.clear();
     200        firstRow.resize(sqlite3_column_count(stmt));
     201    }
    187202
    188203    if (!stmt) {
     
    213228                break;
    214229            case SQLITE_FLOAT:
    215                 switch(precisionPolicy) {
     230                switch(q->numericalPrecisionPolicy()) {
    216231                    case QSql::LowPrecisionInt32:
    217232                        values[i + idx] = sqlite3_column_int(stmt, i);
     
    221236                        break;
    222237                    case QSql::LowPrecisionDouble:
    223                         values[i + idx] = sqlite3_column_double(stmt, i);
    224                         break;
    225238                    case QSql::HighPrecision:
    226239                    default:
    227                         values[i + idx] = QString::fromUtf16(static_cast<const ushort *>(
    228                                             sqlite3_column_text16(stmt, i)),
    229                                             sqlite3_column_bytes16(stmt, i) / sizeof(ushort));
     240                        values[i + idx] = sqlite3_column_double(stmt, i);
    230241                        break;
    231242                };
     
    290301            sqlite3_reset(d->stmt);
    291302        break;
    292     case QSqlResult::SetNumericalPrecision:
    293         Q_ASSERT(data);
    294         d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
    295         break;
    296303    default:
    297         QSqlResult::virtual_hook(id, data);
     304        QSqlCachedResult::virtual_hook(id, data);
    298305    }
    299306}
     
    400407        return false;
    401408    }
    402     d->skippedStatus = d->fetchNext(cache(), 0, true);
     409    d->skippedStatus = d->fetchNext(d->firstRow, 0, true);
    403410    if (lastError().isValid()) {
    404411        setSelect(false);
     
    482489    case SimpleLocking:
    483490    case FinishQuery:
     491    case LowPrecisionNumbers:
    484492        return true;
    485493    case QuerySize:
    486494    case NamedPlaceholders:
    487495    case BatchOperations:
    488     case LowPrecisionNumbers:
    489496    case EventNotifications:
    490497    case MultipleResultSets:
     
    499506
    500507    opts.remove(QLatin1Char(' '));
    501     if (opts.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
    502         bool ok;
    503         int nt = opts.mid(21).toInt(&ok);
    504         if (ok)
    505             return nt;
     508    foreach(QString option, opts.split(QLatin1Char(';'))) {
     509        if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
     510            bool ok;
     511            int nt = option.mid(21).toInt(&ok);
     512            if (ok)
     513                return nt;
     514        }
    506515    }
    507516    return DefaultTimeout;
     517}
     518
     519static int qGetSqliteOpenMode(QString opts)
     520{
     521    opts.remove(QLatin1Char(' '));
     522    foreach(QString option, opts.split(QLatin1Char(';'))) {
     523        if (option == QLatin1String("QSQLITE_OPEN_READONLY"))
     524                return SQLITE_OPEN_READONLY;
     525    }
     526    return SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
    508527}
    509528
     
    520539        return false;
    521540
    522     if (sqlite3_open16(db.constData(), &d->access) == SQLITE_OK) {
     541    if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, qGetSqliteOpenMode(conOpts), NULL) == SQLITE_OK) {
    523542        sqlite3_busy_timeout(d->access, qGetSqliteTimeout(conOpts));
    524543        setOpen(true);
     
    632651    QString schema;
    633652    QString table(tableName);
    634     int indexOfSeparator = tableName.indexOf(QLatin1String("."));
     653    int indexOfSeparator = tableName.indexOf(QLatin1Char('.'));
    635654    if (indexOfSeparator > -1) {
    636         schema = tableName.left(indexOfSeparator).append(QLatin1String("."));
     655        schema = tableName.left(indexOfSeparator).append(QLatin1Char('.'));
    637656        table = tableName.mid(indexOfSeparator + 1);
    638657    }
    639     q.exec(QLatin1String("PRAGMA ") + schema + QLatin1String("table_info ('") + table + QLatin1String("')"));
     658    q.exec(QLatin1String("PRAGMA ") + schema + QLatin1String("table_info (") + _q_escapeIdentifier(table) + QLatin1String(")"));
    640659
    641660    QSqlIndex ind;
     
    662681        return QSqlIndex();
    663682
     683    QString table = tblname;
     684    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     685        table = stripDelimiters(table, QSqlDriver::TableName);
     686
    664687    QSqlQuery q(createResult());
    665688    q.setForwardOnly(true);
    666     return qGetTableInfo(q, tblname, true);
     689    return qGetTableInfo(q, table, true);
    667690}
    668691
     
    672695        return QSqlRecord();
    673696
     697    QString table = tbl;
     698    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     699        table = stripDelimiters(table, QSqlDriver::TableName);
     700
    674701    QSqlQuery q(createResult());
    675702    q.setForwardOnly(true);
    676     return qGetTableInfo(q, tbl);
     703    return qGetTableInfo(q, table);
    677704}
    678705
     
    682709}
    683710
    684 QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType /*type*/) const
    685 {
    686     QString res = identifier;
    687     if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
    688         res.replace(QLatin1Char('"'), QLatin1String("\"\""));
    689         res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
    690         res.replace(QLatin1Char('.'), QLatin1String("\".\""));
    691     }
    692     return res;
     711QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
     712{
     713    Q_UNUSED(type);
     714    return _q_escapeIdentifier(identifier);
    693715}
    694716
  • trunk/src/sql/drivers/sqlite/qsql_sqlite.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**
  • trunk/src/sql/drivers/sqlite2/qsql_sqlite2.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**
     
    111111    sqlite_vm *currentMachine;
    112112
    113     uint skippedStatus: 1; // the status of the fetchNext() that's skipped
    114     uint skipRow: 1; // skip the next fetchNext()?
    115     uint utf8: 1;
     113    bool skippedStatus; // the status of the fetchNext() that's skipped
     114    bool skipRow; // skip the next fetchNext()?
     115    bool utf8;
    116116    QSqlRecord rInf;
    117     QSql::NumericalPrecisionPolicy precisionPolicy;
     117    QVector<QVariant> firstRow;
    118118};
    119119
     
    121121
    122122QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result* res) : q(res), access(0), currentTail(0),
    123     currentMachine(0), skippedStatus(false), skipRow(false), utf8(false), precisionPolicy(QSql::HighPrecision)
     123    currentMachine(0), skippedStatus(false), skipRow(false), utf8(false)
    124124{
    125125}
     
    168168        const char* lastDot = strrchr(cnames[i], '.');
    169169        const char* fieldName = lastDot ? lastDot + 1 : cnames[i];
    170         rInf.append(QSqlField(QString::fromAscii(fieldName),
     170       
     171        //remove quotations around the field name if any
     172        QString fieldStr = QString::fromAscii(fieldName);
     173        QLatin1Char quote('\"');
     174        if ( fieldStr.length() > 2 && fieldStr.startsWith(quote) && fieldStr.endsWith(quote)) {
     175            fieldStr = fieldStr.mid(1);
     176            fieldStr.chop(1);
     177        }
     178        rInf.append(QSqlField(fieldStr,
    171179                              nameToType(QString::fromAscii(cnames[i+numCols]))));
    172180    }
     
    186194        Q_ASSERT(!initialFetch);
    187195        skipRow = false;
     196        for(int i=0;i<firstRow.count(); i++)
     197            values[i] = firstRow[i];
    188198        return skippedStatus;
    189199    }
     
    203213    }
    204214
     215    if(initialFetch) {
     216        firstRow.clear();
     217        firstRow.resize(colNum);
     218    }
     219   
    205220    switch(res) {
    206221    case SQLITE_ROW:
     
    253268        d->finalize();
    254269        break;
    255     case QSqlResult::SetNumericalPrecision:
    256         Q_ASSERT(data);
    257         d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);
    258         break;
    259270    default:
    260         QSqlResult::virtual_hook(id, data);
     271        QSqlCachedResult::virtual_hook(id, data);
    261272    }
    262273}
     
    297308    // we have to fetch one row to find out about
    298309    // the structure of the result set
    299     d->skippedStatus = d->fetchNext(cache(), 0, true);
     310    d->skippedStatus = d->fetchNext(d->firstRow, 0, true);
    300311    if (lastError().isValid()) {
    301312        setSelect(false);
     
    386397    d->access = sqlite_open(QFile::encodeName(db), 0, &err);
    387398    if (err) {
    388         setLastError(QSqlError(tr("Error to open database"), QString::fromAscii(err),
     399        setLastError(QSqlError(tr("Error opening database"), QString::fromAscii(err),
    389400                     QSqlError::ConnectionError));
    390401        sqlite_freemem(err);
     
    461472        return true;
    462473
    463     setLastError(QSqlError(tr("Unable to rollback Transaction"),
     474    setLastError(QSqlError(tr("Unable to rollback transaction"),
    464475                           QString::fromAscii(err), QSqlError::TransactionError, res));
    465476    sqlite_freemem(err);
     
    504515    QSqlQuery q(createResult());
    505516    q.setForwardOnly(true);
     517    QString table = tblname;
     518    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     519        table = stripDelimiters(table, QSqlDriver::TableName);
    506520    // finrst find a UNIQUE INDEX
    507     q.exec(QLatin1String("PRAGMA index_list('") + tblname + QLatin1String("');"));
     521    q.exec(QLatin1String("PRAGMA index_list('") + table + QLatin1String("');"));
    508522    QString indexname;
    509523    while(q.next()) {
     
    518532    q.exec(QLatin1String("PRAGMA index_info('") + indexname + QLatin1String("');"));
    519533
    520     QSqlIndex index(tblname, indexname);
     534    QSqlIndex index(table, indexname);
    521535    while(q.next()) {
    522536        QString name = q.value(2).toString();
     
    533547    if (!isOpen())
    534548        return QSqlRecord();
     549    QString table = tbl;
     550    if (isIdentifierEscaped(tbl, QSqlDriver::TableName))
     551        table = stripDelimiters(table, QSqlDriver::TableName);
    535552
    536553    QSqlQuery q(createResult());
     
    548565{
    549566    QString res = identifier;
    550     if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) {
     567    if(!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('"')) && !identifier.endsWith(QLatin1Char('"')) ) {
    551568        res.replace(QLatin1Char('"'), QLatin1String("\"\""));
    552569        res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
  • trunk/src/sql/drivers/sqlite2/qsql_sqlite2.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**
  • trunk/src/sql/drivers/tds/qsql_tds.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**
     
    165165extern "C" {
    166166static int CS_PUBLIC qTdsMsgHandler (DBPROCESS* dbproc,
    167                             DBINT /*msgno*/,
     167                            DBINT msgno,
    168168                            int msgstate,
    169169                            int severity,
    170170                            char* msgtext,
    171                             char* /*srvname*/,
     171                            char* srvname,
    172172                            char* /*procname*/,
    173                             int /*line*/)
     173                            int line)
    174174{
    175175    QTDSResultPrivate* p = errs()->value(dbproc);
     
    182182
    183183    if (severity > 0) {
    184         QString errMsg = QString(QLatin1String("%1 (%2)")).arg(QString::fromAscii(msgtext)).arg(
    185                                     msgstate);
     184        QString errMsg = QString::fromLatin1("%1 (Msg %2, Level %3, State %4, Server %5, Line %6)")
     185                         .arg(QString::fromAscii(msgtext))
     186                         .arg(msgno)
     187                         .arg(severity)
     188                         .arg(msgstate)
     189                         .arg(QString::fromAscii(srvname))
     190                         .arg(line);
    186191        p->addErrorMsg(errMsg);
     192        if (severity > 10) {
     193            // Severe messages are really errors in the sense of lastError
     194            errMsg = p->getErrorMsgs();
     195            p->lastError = qMakeError(errMsg, QSqlError::UnknownError, msgno);
     196            p->clearErrorMsgs();
     197        }
    187198    }
    188199
     
    212223
    213224
    214     QString errMsg = QString(QLatin1String("%1 %2\n")).arg(QString::fromAscii(dberrstr)).arg(
    215                                 QString::fromAscii(oserrstr));
     225    QString errMsg = QString::fromLatin1("%1 %2\n").arg(QLatin1String(dberrstr)).arg(
     226                                QLatin1String(oserrstr));
    216227    errMsg += p->getErrorMsgs();
    217228    p->lastError = qMakeError(errMsg, QSqlError::UnknownError, dberr);
     
    294305    // insert d in error handler dict
    295306    errs()->insert(d->dbproc, d);
     307    dbcmd(d->dbproc, "set quoted_identifier on");
     308    dbsqlexec(d->dbproc);
    296309}
    297310
     
    368381                    values[idx] = QVariant(QVariant::String);
    369382                else
    370                     values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2));
     383                    values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed();
    371384                break;
    372385            case QVariant::ByteArray: {
     
    699712    QSqlQuery t(createResult());
    700713    t.setForwardOnly(true);
     714
     715    QString table = tablename;
     716    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     717        table = stripDelimiters(table, QSqlDriver::TableName);
     718
    701719    QString stmt (QLatin1String("select name, type, length, prec from syscolumns "
    702720                   "where id = (select id from sysobjects where name = '%1')"));
    703     t.exec(stmt.arg(tablename));
     721    t.exec(stmt.arg(table));
    704722    while (t.next()) {
    705723        QSqlField f(t.value(0).toString().simplified(), qDecodeTDSType(t.value(1).toInt()));
     
    748766    else if (field.type() == QVariant::DateTime) {
    749767        if (field.value().toDateTime().isValid()){
    750             r = field.value().toDateTime().toString(QLatin1String("'yyyyMMdd hh:mm:ss'"));
     768            r = field.value().toDateTime().toString(QLatin1String("yyyyMMdd hh:mm:ss"));
     769            r.prepend(QLatin1String("'"));
     770            r.append(QLatin1String("'"));
    751771        } else
    752772            r = QLatin1String("NULL");
     
    771791    QSqlRecord rec = record(tablename);
    772792
    773     QSqlIndex idx(tablename);
    774     if ((!isOpen()) || (tablename.isEmpty()))
     793    QString table = tablename;
     794    if (isIdentifierEscaped(table, QSqlDriver::TableName))
     795        table = stripDelimiters(table, QSqlDriver::TableName);
     796
     797    QSqlIndex idx(table);
     798    if ((!isOpen()) || (table.isEmpty()))
    775799        return QSqlIndex();
    776800
    777801    QSqlQuery t(createResult());
    778802    t.setForwardOnly(true);
    779     t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(tablename));
     803    t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table));
    780804    if (t.next()) {
    781805        QStringList fNames = t.value(2).toString().simplified().split(QLatin1Char(','));
     
    795819}
    796820
     821QString QTDSDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const
     822{
     823    QString res = identifier;
     824    if(!identifier.isEmpty() && !identifier.startsWith(QLatin1Char('"')) && !identifier.endsWith(QLatin1Char('"')) ) {
     825        res.replace(QLatin1Char('"'), QLatin1String("\"\""));
     826        res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
     827        res.replace(QLatin1Char('.'), QLatin1String("\".\""));
     828    }
     829    return res;
     830}
     831
    797832QT_END_NAMESPACE
  • trunk/src/sql/drivers/tds/qsql_tds.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**
     
    117117    QVariant handle() const;
    118118
     119    QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
     120
    119121protected:
    120122    bool beginTransaction();
  • trunk/src/sql/kernel/qsql.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**
  • trunk/src/sql/kernel/qsqlcachedresult.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**
     
    185185        setAt(d->cacheCount());
    186186    while (at() < i + 1) {
    187         if (!cacheNext())
     187        if (!cacheNext()) {
     188            if (d->canSeek(i))
     189                break;
    188190            return false;
     191        }
    189192    }
    190193    setAt(i);
     
    276279        return false;
    277280
     281    if(isForwardOnly()) {
     282        d->cache.clear();
     283        d->cache.resize(d->colCount);
     284    }
     285
    278286    if (!gotoNext(d->cache, d->nextIndex())) {
    279287        d->revertLast();
     
    295303}
    296304
     305void QSqlCachedResult::virtual_hook(int id, void *data)
     306{
     307    switch (id) {
     308    case QSqlResult::DetachFromResultSet:
     309    case QSqlResult::SetNumericalPrecision:
     310        cleanup();
     311        break;
     312    default:
     313        QSqlResult::virtual_hook(id, data);
     314    }
     315}
     316
     317
    297318QT_END_NAMESPACE
  • trunk/src/sql/kernel/qsqlcachedresult_p.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**
     
    9090    ValueCache &cache();
    9191
     92    void virtual_hook(int id, void *data);
    9293private:
    9394    bool cacheNext();
  • trunk/src/sql/kernel/qsqldatabase.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**
     
    130130{
    131131public:
    132     QSqlDatabasePrivate(QSqlDriver *dr = 0):
     132    QSqlDatabasePrivate(QSqlDatabase *d, QSqlDriver *dr = 0):
     133        q(d),
    133134        driver(dr),
    134135        port(-1)
    135136    {
    136137        ref = 1;
     138        if(driver)
     139            precisionPolicy = driver->numericalPrecisionPolicy();
     140        else
     141            precisionPolicy= QSql::LowPrecisionDouble;
    137142    }
    138143    QSqlDatabasePrivate(const QSqlDatabasePrivate &other);
     
    143148
    144149    QAtomicInt ref;
     150    QSqlDatabase *q;
    145151    QSqlDriver* driver;
    146152    QString dbname;
     
    152158    QString connOptions;
    153159    QString connName;
     160    QSql::NumericalPrecisionPolicy precisionPolicy;
    154161
    155162    static QSqlDatabasePrivate *shared_null();
     
    165172{
    166173    ref = 1;
     174    q = other.q;
    167175    dbname = other.dbname;
    168176    uname = other.uname;
     
    173181    connOptions = other.connOptions;
    174182    driver = other.driver;
     183    precisionPolicy = other.precisionPolicy;
    175184}
    176185
     
    217226{
    218227    static QSqlNullDriver dr;
    219     static QSqlDatabasePrivate n(&dr);
     228    static QSqlDatabasePrivate n(NULL, &dr);
    220229    return &n;
    221230}
     
    282291void QSqlDatabasePrivate::copy(const QSqlDatabasePrivate *other)
    283292{
     293    q = other->q;
    284294    dbname = other->dbname;
    285295    uname = other->uname;
     
    289299    port = other->port;
    290300    connOptions = other->connOptions;
     301    precisionPolicy = other->precisionPolicy;
    291302}
    292303
     
    353364
    354365    \ingroup database
    355     \mainclass
     366
    356367    \inmodule QtSql
    357368
     
    379390    name argument, the default connection is assumed. The following
    380391    snippet shows how to create and open a default connection to a
    381     MySQL database:
     392    PostgreSQL database:
    382393
    383394    \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 0
     
    444455    The database connection is referred to by \a connectionName. The
    445456    newly added database connection is returned.
     457
     458    If \a type is not available or could not be loaded, isValid() returns false.
    446459
    447460    If \a connectionName is not specified, the new connection becomes
     
    659672QSqlDatabase::QSqlDatabase(const QString &type)
    660673{
    661     d = new QSqlDatabasePrivate();
     674    d = new QSqlDatabasePrivate(this);
    662675    d->init(type);
    663676}
     
    671684QSqlDatabase::QSqlDatabase(QSqlDriver *driver)
    672685{
    673     d = new QSqlDatabasePrivate(driver);
     686    d = new QSqlDatabasePrivate(this, driver);
    674687}
    675688
     
    950963    The \e{database name} is not the \e{connection name}. The
    951964    connection name must be passed to addDatabase() at connection
    952     object create time. 
     965    object create time.
    953966
    954967    For the QOCI (Oracle) driver, the database name is the TNS
     
    12181231    \i CLIENT_INTERACTIVE
    12191232    \i UNIX_SOCKET
     1233    \i MYSQL_OPT_RECONNECT
    12201234    \endlist
    12211235
     
    12531267    \list
    12541268    \i QSQLITE_BUSY_TIMEOUT
     1269    \i QSQLITE_OPEN_READONLY
    12551270    \endlist
    12561271
     
    14701485}
    14711486
     1487/*!
     1488    \since 4.6
     1489
     1490    Sets the default numerical precision policy used by queries created
     1491    on this database connection to \a precisionPolicy.
     1492
     1493    Note: Drivers that don't support fetching numerical values with low
     1494    precision will ignore the precision policy. You can use
     1495    QSqlDriver::hasFeature() to find out whether a driver supports this
     1496    feature.
     1497
     1498    Note: Setting the default precision policy to \a precisionPolicy
     1499    doesn't affect any currently active queries.
     1500
     1501    \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(),
     1502    QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy()
     1503*/
     1504void QSqlDatabase::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
     1505{
     1506    if(driver())
     1507        driver()->setNumericalPrecisionPolicy(precisionPolicy);
     1508    d->precisionPolicy = precisionPolicy;
     1509}
     1510
     1511/*!
     1512    \since 4.6
     1513
     1514    Returns the current default precision policy for the database connection.
     1515
     1516    \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(),
     1517    QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy()
     1518*/
     1519QSql::NumericalPrecisionPolicy QSqlDatabase::numericalPrecisionPolicy() const
     1520{
     1521    if(driver())
     1522        return driver()->numericalPrecisionPolicy();
     1523    else
     1524        return d->precisionPolicy;
     1525}
     1526
     1527
    14721528#ifndef QT_NO_DEBUG_STREAM
    14731529QDebug operator<<(QDebug dbg, const QSqlDatabase &d)
  • trunk/src/sql/kernel/qsqldatabase.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**
     
    121121    QString connectOptions() const;
    122122    QString connectionName() const;
     123    void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
     124    QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
    123125
    124126    QSqlDriver* driver() const;
  • 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
  • trunk/src/sql/kernel/qsqldriver.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**
     
    128128    QStringList subscribedToNotifications() const;          // ### Qt 5: make virtual
    129129
     130    bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual
     131    QString stripDelimiters(const QString &identifier, IdentifierType type) const;  // ### Qt 5: make virtual
     132
     133    void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
     134    QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
     135
    130136Q_SIGNALS:
    131137    void notification(const QString &name);
     
    141147    QStringList subscribedToNotificationsImplementation() const;            // ### Qt 5: eliminate, see subscribedNotifications()
    142148
     149    bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const;   // ### Qt 5: eliminate, see isIdentifierEscaped()
     150    QString stripDelimitersImplementation(const QString &identifier, IdentifierType type) const;    // ### Qt 5: eliminate, see stripDelimiters()
     151
    143152private:
    144153    Q_DISABLE_COPY(QSqlDriver)
  • trunk/src/sql/kernel/qsqldriverplugin.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**
  • trunk/src/sql/kernel/qsqldriverplugin.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**
  • trunk/src/sql/kernel/qsqlerror.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{
    5050    dbg.nospace() << "QSqlError(" << s.number() << ", " << s.driverText() <<
    51                      ", " << s.databaseText() << ")";
     51                     ", " << s.databaseText() << ')';
    5252    return dbg.space();
    5353}
  • trunk/src/sql/kernel/qsqlerror.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**
  • trunk/src/sql/kernel/qsqlfield.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**
     
    515515        dbg.nospace() << ", typeID: " << f.typeID();
    516516    if (!f.defaultValue().isNull())
    517         dbg.nospace() << ", auto-value: \"" << f.defaultValue() << "\"";
    518     dbg.nospace() << ")";
     517        dbg.nospace() << ", auto-value: \"" << f.defaultValue() << '\"';
     518    dbg.nospace() << ')';
    519519    return dbg.space();
    520520#else
  • trunk/src/sql/kernel/qsqlfield.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**
  • trunk/src/sql/kernel/qsqlindex.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**
  • trunk/src/sql/kernel/qsqlindex.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**
  • trunk/src/sql/kernel/qsqlnulldriver_p.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**
  • trunk/src/sql/kernel/qsqlquery.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**
     
    6262    QAtomicInt ref;
    6363    QSqlResult* sqlResult;
    64     QSql::NumericalPrecisionPolicy precisionPolicy;
    6564
    6665    static QSqlQueryPrivate* shared_null();
     
    8281*/
    8382QSqlQueryPrivate::QSqlQueryPrivate(QSqlResult* result)
    84     : ref(1), sqlResult(result), precisionPolicy(QSql::HighPrecision)
     83    : ref(1), sqlResult(result)
    8584{
    8685    if (!sqlResult)
     
    103102    \ingroup database
    104103    \ingroup shared
    105     \mainclass
     104
    106105    \inmodule QtSql
    107106
     
    352351        bool fo = isForwardOnly();
    353352        *this = QSqlQuery(driver()->createResult());
    354         d->sqlResult->setNumericalPrecisionPolicy(d->precisionPolicy);
     353        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
    355354        setForwardOnly(fo);
    356355    } else {
     
    359358        d->sqlResult->setLastError(QSqlError());
    360359        d->sqlResult->setAt(QSql::BeforeFirstRow);
    361         d->sqlResult->setNumericalPrecisionPolicy(d->precisionPolicy);
     360        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
    362361    }
    363362    d->sqlResult->setQuery(query.trimmed());
     
    813812  efficient since results do not need to be cached. It will also
    814813  improve performance on some databases. For this to be true, you must
    815   call \c setForwardMode() before the query is prepared or executed.
     814  call \c setForwardOnly() before the query is prepared or executed.
    816815  Note that the constructor that takes a query and a database may
    817816  execute the query.
     
    819818  Forward only mode is off by default.
    820819
    821   \sa isForwardOnly(), next(), seek()
     820  Setting forward only to false is a suggestion to the database engine,
     821  which has the final say on whether a result set is forward only or
     822  scrollable. isForwardOnly() will always return the correct status of
     823  the result set.
     824
     825  \sa isForwardOnly(), next(), seek(), QSqlResult::setForwardOnly()
    822826*/
    823827void QSqlQuery::setForwardOnly(bool forward)
     
    892896        *this = QSqlQuery(driver()->createResult());
    893897        setForwardOnly(fo);
    894         d->sqlResult->setNumericalPrecisionPolicy(d->precisionPolicy);
     898        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
    895899    } else {
    896900        d->sqlResult->setActive(false);
    897901        d->sqlResult->setLastError(QSqlError());
    898902        d->sqlResult->setAt(QSql::BeforeFirstRow);
    899         d->sqlResult->setNumericalPrecisionPolicy(d->precisionPolicy);
     903        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
    900904    }
    901905    if (!driver()) {
     
    11271131  precision specified by \a precisionPolicy.
    11281132
    1129   The Oracle driver, for example, retrieves numerical values as
    1130   strings by default to prevent the loss of precision. If the high
    1131   precision doesn't matter, use this method to increase execution
    1132   speed by bypassing string conversions.
     1133  The Oracle driver, for example, can retrieve numerical values as
     1134  strings to prevent the loss of precision. If high precision doesn't
     1135  matter, use this method to increase execution speed by bypassing
     1136  string conversions.
    11331137
    11341138  Note: Drivers that don't support fetching numerical values with low
     
    11451149void QSqlQuery::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
    11461150{
    1147     d->precisionPolicy = precisionPolicy;
     1151    d->sqlResult->setNumericalPrecisionPolicy(precisionPolicy);
    11481152}
    11491153
     
    11551159QSql::NumericalPrecisionPolicy QSqlQuery::numericalPrecisionPolicy() const
    11561160{
    1157     return d->precisionPolicy;
     1161    return d->sqlResult->numericalPrecisionPolicy();
    11581162}
    11591163
     
    11961200  result set and must be navigated to a valid record before data
    11971201  values can be retrieved. If a new result set isn't available the
    1198   function returns false and the the query is set to inactive. In any
     1202  function returns false and the query is set to inactive. In any
    11991203  case the old result set will be discarded.
    12001204
  • trunk/src/sql/kernel/qsqlquery.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**
  • trunk/src/sql/kernel/qsqlrecord.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**
     
    590590QDebug operator<<(QDebug dbg, const QSqlRecord &r)
    591591{
    592     dbg << "QSqlRecord(" << r.count() << ")";
     592    dbg << "QSqlRecord(" << r.count() << ')';
    593593    for (int i = 0; i < r.count(); ++i)
    594594        dbg << '\n' << QString::fromLatin1("%1:").arg(i, 2) << r.field(i) << r.value(i).toString();
  • trunk/src/sql/kernel/qsqlrecord.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**
  • trunk/src/sql/kernel/qsqlresult.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#include "qvector.h"
    5050#include "qsqldriver.h"
     51#include <QDebug>
    5152
    5253QT_BEGIN_NAMESPACE
     
    6566    QSqlResultPrivate(QSqlResult* d)
    6667    : q(d), sqldriver(0), idx(QSql::BeforeFirstRow), active(false),
    67       isSel(false), forwardOnly(false), bindCount(0), binds(QSqlResult::PositionalBinding)
     68      isSel(false), forwardOnly(false), precisionPolicy(QSql::LowPrecisionDouble), bindCount(0), binds(QSqlResult::PositionalBinding)
    6869    {}
    6970
     
    105106    QSqlError error;
    106107    bool forwardOnly;
     108    QSql::NumericalPrecisionPolicy precisionPolicy;
    107109
    108110    int bindCount;
     
    250252    d = new QSqlResultPrivate(this);
    251253    d->sqldriver = db;
     254    if(db) {
     255        setNumericalPrecisionPolicy(db->numericalPrecisionPolicy());
     256    }
    252257}
    253258
     
    555560    cached. By default, this feature is disabled.
    556561
    557     \sa isForwardOnly(), fetchNext()
     562    Setting forward only to false is a suggestion to the database engine,
     563    which has the final say on whether a result set is forward only or
     564    scrollable. isForwardOnly() will always return the correct status of
     565    the result set.
     566
     567    \sa isForwardOnly(), fetchNext(), QSqlQuery::setForwardOnly()
    558568*/
    559569void QSqlResult::setForwardOnly(bool forward)
     
    901911void QSqlResult::virtual_hook(int, void *)
    902912{
    903     Q_ASSERT(false);
    904913}
    905914
     
    966975void QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy)
    967976{
    968     if (driver()->hasFeature(QSqlDriver::LowPrecisionNumbers))
    969         virtual_hook(SetNumericalPrecision, &policy);
     977    d->precisionPolicy = policy;
     978    virtual_hook(SetNumericalPrecision, &policy);
     979}
     980
     981/*! \internal
     982 */
     983QSql::NumericalPrecisionPolicy QSqlResult::numericalPrecisionPolicy() const
     984{
     985    return d->precisionPolicy;
    970986}
    971987
  • trunk/src/sql/kernel/qsqlresult.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**
     
    136136    void detachFromResultSet();
    137137    void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy);
     138    QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
    138139    bool nextResult();
    139140
  • trunk/src/sql/models/qsqlquerymodel.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**
     
    315315    bool columnsChanged = (newRec != d->rec);
    316316    bool hasQuerySize = query.driver()->hasFeature(QSqlDriver::QuerySize);
     317    bool hasNewData = (newRec != QSqlRecord()) || !query.lastError().isValid();
    317318
    318319    if (d->colOffsets.size() != newRec.count() || columnsChanged)
     
    329330    d->query = query;
    330331    d->rec = newRec;
    331    
     332
    332333    if (mustClearModel)
    333334        endRemoveRows();
    334    
    335     d->atEnd = false;   
    336 
    337     if (columnsChanged)
     335
     336    d->atEnd = false;
     337
     338    if (columnsChanged && hasNewData)
    338339        reset();
    339340
     
    418419{
    419420    Q_D(QSqlQueryModel);
    420     if (orientation != Qt::Horizontal || section < 0)
     421    if (orientation != Qt::Horizontal || section < 0 || columnCount() <= section)
    421422        return false;
    422423
  • trunk/src/sql/models/qsqlquerymodel.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**
  • trunk/src/sql/models/qsqlquerymodel_p.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**
  • trunk/src/sql/models/qsqlrelationaldelegate.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**
  • trunk/src/sql/models/qsqlrelationaldelegate.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**
  • trunk/src/sql/models/qsqlrelationaltablemodel.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**
     
    183183
    184184    QSqlRecord record;
     185    QString indexColumn;
     186    QString displayColumn;
    185187    for (int i=0; i < model->rowCount(); ++i) {
    186188        record = model->record(i);
    187         dictionary[record.field(rel.indexColumn()).value().toString()] =
    188             record.field(rel.displayColumn()).value();
     189
     190        indexColumn = rel.indexColumn();
     191        if (m_parent->database().driver()->isIdentifierEscaped(indexColumn, QSqlDriver::FieldName))
     192            indexColumn = m_parent->database().driver()->stripDelimiters(indexColumn, QSqlDriver::FieldName);
     193
     194        displayColumn = rel.displayColumn();
     195        if (m_parent->database().driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName))
     196            displayColumn = m_parent->database().driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName);
     197
     198        dictionary[record.field(indexColumn).value().toString()] =
     199            record.field(displayColumn).value();
    189200    }
    190201    m_dictInitialized = true;
     
    216227        : QSqlTableModelPrivate()
    217228    {}
    218     QString escapedRelationField(const QString &tableName, const QString &fieldName) const;
     229    QString relationField(const QString &tableName, const QString &fieldName) const;
    219230
    220231    int nameToIndex(const QString &name) const;
     
    256267int QSqlRelationalTableModelPrivate::nameToIndex(const QString &name) const
    257268{
    258     return baseRec.indexOf(name);
     269    QString fieldname = name;
     270    if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName))
     271        fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName);
     272    return baseRec.indexOf(fieldname);
    259273}
    260274
     
    482496}
    483497
    484 QString QSqlRelationalTableModelPrivate::escapedRelationField(const QString &tableName,
     498QString QSqlRelationalTableModelPrivate::relationField(const QString &tableName,
    485499                        const QString &fieldName) const
    486500{
    487     QString esc;
    488     esc.reserve(tableName.size() + fieldName.size() + 1);
    489     esc.append(tableName).append(QLatin1Char('.')).append(fieldName);
    490 
    491     return db.driver()->escapeIdentifier(esc, QSqlDriver::FieldName);
     501    QString ret;
     502    ret.reserve(tableName.size() + fieldName.size() + 1);
     503    ret.append(tableName).append(QLatin1Char('.')).append(fieldName);
     504
     505    return ret;
    492506}
    493507
     
    515529    // Count how many times each field name occurs in the record
    516530    QHash<QString, int> fieldNames;
     531    QStringList fieldList;
    517532    for (int i = 0; i < rec.count(); ++i) {
    518533        QSqlRelation relation = d->relations.value(i, nullRelation).rel;
    519534        QString name;
    520535        if (relation.isValid())
     536        {
    521537            // Count the display column name, not the original foreign key
    522538            name = relation.displayColumn();
     539            if (d->db.driver()->isIdentifierEscaped(name, QSqlDriver::FieldName))
     540                name = d->db.driver()->stripDelimiters(name, QSqlDriver::FieldName);
     541
     542            QSqlRecord rec = database().record(relation.tableName());
     543            for (int i = 0; i < rec.count(); ++i) {
     544                if (name.compare(rec.fieldName(i), Qt::CaseInsensitive) == 0) {
     545                    name = rec.fieldName(i);
     546                    break;
     547                }
     548            }
     549        }
    523550        else
    524551            name = rec.fieldName(i);
    525552        fieldNames.insert(name, fieldNames.value(name, 0) + 1);
     553        fieldList.append(name);
    526554    }
    527555
     
    532560            if (!fList.isEmpty())
    533561                fList.append(QLatin1String(", "));
    534             fList.append(d->escapedRelationField(relTableAlias, relation.displayColumn()));
     562            fList.append(d->relationField(relTableAlias,relation.displayColumn()));
    535563
    536564            // If there are duplicate field names they must be aliased
    537             if (fieldNames.value(relation.displayColumn()) > 1) {
    538                 fList.append(QString::fromLatin1(" AS %1_%2").arg(relation.tableName()).arg(relation.displayColumn()));
     565            if (fieldNames.value(fieldList[i]) > 1) {
     566                QString relTableName = relation.tableName().section(QChar::fromLatin1('.'), -1, -1);
     567                if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName))
     568                    relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName);
     569                QString displayColumn = relation.displayColumn();
     570                if (d->db.driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName))
     571                    displayColumn = d->db.driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName);
     572                fList.append(QString::fromLatin1(" AS %1_%2_%3").arg(relTableName).arg(displayColumn).arg(fieldNames.value(fieldList[i])));
     573                fieldNames.insert(fieldList[i], fieldNames.value(fieldList[i])-1);
    539574            }
    540575
    541576            // this needs fixing!! the below if is borken.
    542             if (!tables.contains(relation.tableName()))
    543                 tables.append(d->db.driver()->escapeIdentifier(relation.tableName(),QSqlDriver::TableName)
    544                         .append(QLatin1String(" "))
    545                         .append(d->db.driver()->escapeIdentifier(relTableAlias, QSqlDriver::TableName)));
     577            tables.append(relation.tableName().append(QLatin1Char(' ')).append(relTableAlias));
    546578            if(!where.isEmpty())
    547579                where.append(QLatin1String(" AND "));
    548             where.append(d->escapedRelationField(tableName(), rec.fieldName(i)));
     580            where.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName)));
    549581            where.append(QLatin1String(" = "));
    550             where.append(d->escapedRelationField(relTableAlias, relation.indexColumn()));
     582            where.append(d->relationField(relTableAlias, relation.indexColumn()));
    551583        } else {
    552584            if (!fList.isEmpty())
    553585                fList.append(QLatin1String(", "));
    554             fList.append(d->escapedRelationField(tableName(), rec.fieldName(i)));
     586            fList.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName)));
    555587        }
    556588    }
     
    561593    if(!tList.isEmpty())
    562594        tList.prepend(QLatin1String(", "));
    563     tList.prepend(d->db.driver()->escapeIdentifier(tableName(),QSqlDriver::TableName));
     595    tList.prepend(tableName());
    564596    query.append(QLatin1String("SELECT "));
    565597    query.append(fList).append(QLatin1String(" FROM ")).append(tList);
     
    691723
    692724    QString s = QLatin1String("ORDER BY ");
    693     s.append(d->escapedRelationField(QLatin1String("relTblAl_") + QString::number(d->sortColumn),
     725    s.append(d->relationField(QLatin1String("relTblAl_") + QString::number(d->sortColumn),
    694726                    rel.displayColumn()));
    695727    s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC");
  • trunk/src/sql/models/qsqlrelationaltablemodel.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**
  • trunk/src/sql/models/qsqltablemodel.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**
     
    9999int QSqlTableModelPrivate::nameToIndex(const QString &name) const
    100100{
    101     return rec.indexOf(name);
     101    QString fieldname = name;
     102    if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName))
     103        fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName);
     104    return rec.indexOf(fieldname);
    102105}
    103106
     
    203206        }
    204207        for (i = 0; i < whereValues.count(); ++i) {
    205             if (whereValues.isGenerated(i))
     208            if (whereValues.isGenerated(i) && !whereValues.isNull(i))
    206209                editQuery.addBindValue(whereValues.value(i));
    207210        }
     
    368371    Q_D(QSqlTableModel);
    369372    clear();
    370     if(d->db.tables().contains(tableName.toUpper()))
    371         d->tableName = tableName.toUpper();
    372     else
    373         d->tableName = tableName;
     373    d->tableName = tableName;
    374374    d->initRecordAndPrimaryIndex();
    375375    d->initColOffsets(d->rec.count());
     
    407407    setQuery(qu);
    408408
    409     if (!qu.isActive()) {
     409    if (!qu.isActive() || lastError().isValid()) {
    410410        // something went wrong - revert to non-select state
    411411        d->initRecordAndPrimaryIndex();
     
    539539        if (isOk)
    540540            select();
     541        emit dataChanged(index, index);
    541542        break; }
    542543    case OnRowChange:
     
    559560            row.op = QSqlTableModelPrivate::Update;
    560561            row.rec = d->rec;
    561                         row.primaryValues = d->primaryValues(indexInQuery(index).row());
     562            row.primaryValues = d->primaryValues(indexInQuery(index).row());
    562563        }
    563564        row.rec.setValue(index.column(), value);
     
    669670    emit beforeDelete(row);
    670671
    671     QSqlRecord rec = d->primaryValues(row);
     672    const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues : d->primaryValues(row);
    672673    bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries);
    673674    QString stmt = d->db.driver()->sqlStatement(QSqlDriver::DeleteStatement,
     
    677678    QString where = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement,
    678679                                                 d->tableName,
    679                                                  rec,
     680                                                 whereValues,
    680681                                                 prepStatement);
    681682
     
    687688    stmt.append(QLatin1Char(' ')).append(where);
    688689
    689     return d->exec(stmt, prepStatement, rec);
     690    return d->exec(stmt, prepStatement, whereValues);
    690691}
    691692
     
    977978        return s;
    978979       
    979     QString table = d->db.driver()->escapeIdentifier(d->tableName, QSqlDriver::TableName);
     980    QString table = d->tableName;
     981    //we can safely escape the field because it would have been obtained from the database
     982    //and have the correct case
    980983    QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
    981984    s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field);
     
    10971100            else {
    10981101                d->cache[idx].op = QSqlTableModelPrivate::Delete;
     1102                d->cache[idx].primaryValues = d->primaryValues(indexInQuery(createIndex(idx, 0)).row());
    10991103                emit headerDataChanged(Qt::Vertical, idx, idx);
    11001104            }
     
    13181322            mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row());
    13191323        }
     1324        QString fieldName;
    13201325        for (int i = 0; i < record.count(); ++i) {
    1321             int idx = mrow.rec.indexOf(record.fieldName(i));
     1326            fieldName = record.fieldName(i);
     1327            if (d->db.driver()->isIdentifierEscaped(fieldName, QSqlDriver::FieldName))
     1328                fieldName = d->db.driver()->stripDelimiters(fieldName, QSqlDriver::FieldName);
     1329            int idx = mrow.rec.indexOf(fieldName);
    13221330            if (idx == -1)
    13231331                isOk = false;
  • trunk/src/sql/models/qsqltablemodel.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**
  • trunk/src/sql/models/qsqltablemodel_p.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**
  • trunk/src/sql/sql.pro

    r2 r561  
    1818include(models/models.pri)
    1919
     20symbian: {
     21    TARGET.UID3=0x2001E61D
     22
     23    # Workaroud for problems with paging this dll
     24    MMP_RULES -= PAGED
     25    MMP_RULES *= UNPAGED
     26}
Note: See TracChangeset for help on using the changeset viewer.