Changeset 561 for trunk/src/sql/drivers/psql
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/sql/drivers/psql/qsql_psql.cpp
r2 r561 2 2 ** 3 3 ** 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) 5 6 ** 6 7 ** This file is part of the QtSql module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 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. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** 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. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 55 55 #include <qmutex.h> 56 56 57 57 58 #include <libpq-fe.h> 58 59 #include <pg_config.h> … … 60 61 #include <stdlib.h> 61 62 #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 62 84 63 85 // workaround for postgres defining their OIDs in a private header file … … 137 159 { 138 160 public: 139 QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1), pre cisionPolicy(QSql::HighPrecision) {}161 QPSQLResultPrivate(QPSQLResult *qq): q(qq), driver(0), result(0), currentSize(-1), preparedQueriesEnabled(false) {} 140 162 141 163 QPSQLResult *q; … … 143 165 PGresult *result; 144 166 int currentSize; 145 QSql::NumericalPrecisionPolicy precisionPolicy;146 167 bool preparedQueriesEnabled; 147 168 QString preparedStmtId; … … 321 342 case QVariant::Double: 322 343 if (ptype == QNUMERICOID) { 323 if ( d->precisionPolicy!= QSql::HighPrecision) {344 if (numericalPrecisionPolicy() != QSql::HighPrecision) { 324 345 QVariant retval; 325 346 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; 332 354 if (!convert) 333 355 return QVariant(); … … 336 358 return QString::fromAscii(val); 337 359 } 338 return strtod(val, 0);360 return QString::fromAscii(val).toDouble(); 339 361 case QVariant::Date: 340 362 if (val[0] == '\0') { … … 468 490 469 491 switch (id) { 470 case QSqlResult::SetNumericalPrecision:471 d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);472 break;473 492 default: 474 493 QSqlResult::virtual_hook(id, data); … … 535 554 if (!d->preparedQueriesEnabled) 536 555 return QSqlResult::prepare(query); 537 556 538 557 cleanup(); 539 558 … … 542 561 543 562 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)); 545 564 546 565 PGresult *result = PQexec(d->driver->connection, … … 571 590 const QString params = qCreateParamString(boundValues(), d->q->driver()); 572 591 if (params.isEmpty()) 573 stmt = QString (QLatin1String("EXECUTE %1")).arg(d->preparedStmtId);592 stmt = QString::fromLatin1("EXECUTE %1").arg(d->preparedStmtId); 574 593 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); 576 595 577 596 d->result = PQexec(d->driver->connection, … … 605 624 QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6; 606 625 PGresult* result = PQexec(connection, "select version()"); 607 int status = 626 int status = PQresultStatus(result); 608 627 if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) { 609 628 QString val = QString::fromAscii(PQgetvalue(result, 0, 0)); 610 PQclear(result);611 629 QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)")); 612 630 rx.setMinimal(true); // enforce non-greedy RegExp … … 649 667 } 650 668 } 669 PQclear(result); 651 670 652 671 if (serverVersion < QPSQLDriver::Version71) … … 825 844 } 826 845 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) { 828 860 PQclear(res); 829 861 setLastError(qMakeError(tr("Could not commit transaction"), … … 895 927 qSplitTableName(tbl, schema); 896 928 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 897 939 switch(d->pro) { 898 940 case QPSQLDriver::Version6: 899 941 stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname " 900 942 "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' " 902 944 "and pg_cl.oid = pg_ind.indexrelid " 903 945 "and pg_att2.attrelid = pg_ind.indexrelid " … … 910 952 stmt = QLatin1String("select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname " 911 953 "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' " 913 955 "and pg_cl.oid = pg_ind.indexrelid " 914 956 "and pg_att2.attrelid = pg_ind.indexrelid " … … 927 969 "WHERE %1 pg_class.oid IN " 928 970 "(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')) " 930 972 "AND pg_attribute.attrelid = pg_class.oid " 931 973 "AND pg_attribute.attisdropped = false " … … 935 977 else 936 978 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)); 942 984 while (i.isActive() && i.next()) { 943 985 QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt())); … … 957 999 QString schema; 958 1000 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(); 959 1011 960 1012 QString stmt; … … 965 1017 "int(pg_attribute.attrelid), pg_attribute.attnum " 966 1018 "from pg_class, pg_attribute " 967 "where lower(pg_class.relname)= '%1' "1019 "where pg_class.relname = '%1' " 968 1020 "and pg_attribute.attnum > 0 " 969 1021 "and pg_attribute.attrelid = pg_class.oid "); … … 974 1026 "pg_attribute.attrelid::int, pg_attribute.attnum " 975 1027 "from pg_class, pg_attribute " 976 "where lower(pg_class.relname)= '%1' "1028 "where pg_class.relname = '%1' " 977 1029 "and pg_attribute.attnum > 0 " 978 1030 "and pg_attribute.attrelid = pg_class.oid "); … … 985 1037 "left join pg_attrdef on (pg_attrdef.adrelid = " 986 1038 "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) " 987 "where lower(pg_class.relname)= '%1' "1039 "where pg_class.relname = '%1' " 988 1040 "and pg_attribute.attnum > 0 " 989 1041 "and pg_attribute.attrelid = pg_class.oid " … … 1002 1054 "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) " 1003 1055 "where %1 " 1004 "and lower(pg_class.relname)= '%2' "1056 "and pg_class.relname = '%2' " 1005 1057 "and pg_attribute.attnum > 0 " 1006 1058 "and pg_attribute.attrelid = pg_class.oid " … … 1011 1063 else 1012 1064 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)); 1014 1066 break; 1015 1067 } 1016 1068 1017 1069 QSqlQuery query(createResult()); 1018 query.exec(stmt.arg(tbl .toLower()));1070 query.exec(stmt.arg(tbl)); 1019 1071 if (d->pro >= QPSQLDriver::Version71) { 1020 1072 while (query.next()) { … … 1083 1135 // msecs need to be right aligned otherwise psql 1084 1136 // interpretes them wrong 1085 r = QLatin1 String("'") + QString::number(dt.year()) + QLatin1String("-")1086 + QString::number(dt.month()) + QLatin1 String("-")1087 + QString::number(dt.day()) + QLatin1 String(" ")1088 + tm.toString() + QLatin1 String(".")1137 r = QLatin1Char('\'') + QString::number(dt.year()) + QLatin1Char('-') 1138 + QString::number(dt.month()) + QLatin1Char('-') 1139 + QString::number(dt.day()) + QLatin1Char(' ') 1140 + tm.toString() + QLatin1Char('.') 1089 1141 + QString::number(tm.msec()).rightJustified(3, QLatin1Char('0')) 1090 + QLatin1 String("'");1142 + QLatin1Char('\''); 1091 1143 } else { 1092 1144 r = QLatin1String("NULL"); … … 1099 1151 #ifndef QT_NO_DATESTRING 1100 1152 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('\''); 1102 1154 } else 1103 1155 #endif … … 1105 1157 r = QLatin1String("NULL"); 1106 1158 } 1159 break; 1107 1160 case QVariant::String: 1108 1161 { … … 1132 1185 break; 1133 1186 } 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 } 1134 1202 default: 1135 1203 r = QSqlDriver::formatValue(field, trimStrings); … … 1143 1211 { 1144 1212 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('"')) ) { 1146 1214 res.replace(QLatin1Char('"'), QLatin1String("\"\"")); 1147 1215 res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); … … 1173 1241 return false; 1174 1242 } 1175 1243 1176 1244 int socket = PQsocket(d->connection); 1177 1245 if (socket) { 1178 QString query = Q String(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() 1181 1249 : query.toLocal8Bit().constData()) 1182 1250 ) != PGRES_COMMAND_OK) { … … 1208 1276 } 1209 1277 1210 QString query = Q String(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() 1213 1281 : query.toLocal8Bit().constData()) 1214 1282 ) != PGRES_COMMAND_OK) { … … 1236 1304 { 1237 1305 PQconsumeInput(d->connection); 1238 PGnotify *notify = PQnotifies(d->connection); 1239 if (notify) { 1306 1307 PGnotify *notify = 0; 1308 while((notify = PQnotifies(d->connection)) != 0) { 1240 1309 QString name(QLatin1String(notify->relname)); 1241 1242 1310 if (d->seid.contains(name)) 1243 1311 emit notification(name); 1244 1312 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)); 1247 1315 1248 1316 qPQfreemem(notify); -
trunk/src/sql/drivers/psql/qsql_psql.h
r2 r561 2 2 ** 3 3 ** 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) 5 6 ** 6 7 ** This file is part of the QtSql module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 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. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** 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. 38 38 ** $QT_END_LICENSE$ 39 39 **
Note:
See TracChangeset
for help on using the changeset viewer.