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

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/sql/drivers/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**
Note: See TracChangeset for help on using the changeset viewer.