Changeset 561 for trunk/src/sql
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 52 edited
- 1 copied
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/db2/qsql_db2.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 ** … … 50 50 #include <qvarlengtharray.h> 51 51 #include <qvector.h> 52 53 #ifndef UNICODE 54 #define UNICODE 55 #endif 52 #include <QDebug> 56 53 57 54 #if defined(Q_CC_BOR) … … 63 60 #endif 64 61 62 #define UNICODE 63 65 64 #include <sqlcli1.h> 66 65 … … 84 83 { 85 84 public: 86 QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0) , precisionPolicy(QSql::HighPrecision)85 QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0) 87 86 {} 88 87 ~QDB2ResultPrivate() 89 88 { 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) { 91 94 delete valueCache[i]; 95 valueCache[i] = NULL; 96 } 97 } 98 void emptyValueCache() 99 { 100 clearValueCache(); 101 valueCache.clear(); 92 102 } 93 103 … … 96 106 QSqlRecord recInf; 97 107 QVector<QVariant*> valueCache; 98 QSql::NumericalPrecisionPolicy precisionPolicy;99 108 }; 100 109 101 110 static QString qFromTChar(SQLTCHAR* str) 102 111 { 103 #ifdef UNICODE104 112 return QString::fromUtf16(str); 105 #else106 return QString::fromLocal8Bit((const char*) str);107 #endif108 113 } 109 114 … … 112 117 static SQLTCHAR* qToTChar(const QString& str) 113 118 { 114 #ifdef UNICODE115 119 return (SQLTCHAR*)str.utf16(); 116 #else117 return (unsigned char*) str.ascii();118 #endif119 120 } 120 121 … … 337 338 while (true) { 338 339 r = SQLGetData(hStmt, 339 column+1, 340 #ifdef UNICODE 340 column + 1, 341 341 SQL_C_WCHAR, 342 #else343 SQL_C_CHAR,344 #endif345 342 (SQLPOINTER)buf, 346 343 colSize * sizeof(SQLTCHAR), … … 545 542 546 543 d->recInf.clear(); 547 d-> valueCache.clear();544 d->emptyValueCache(); 548 545 549 546 if (!qMakeStatement(d, isForwardOnly())) … … 569 566 } 570 567 d->valueCache.resize(count); 568 d->valueCache.fill(NULL); 571 569 setActive(true); 572 570 return true; … … 580 578 581 579 d->recInf.clear(); 582 d-> valueCache.clear();580 d->emptyValueCache(); 583 581 584 582 if (!qMakeStatement(d, isForwardOnly())) … … 608 606 609 607 d->recInf.clear(); 610 d-> valueCache.clear();608 d->emptyValueCache(); 611 609 612 610 if (!qMakeStatement(d, isForwardOnly(), false)) … … 729 727 break; } 730 728 case QVariant::String: 731 #ifdef UNICODE732 729 { 733 730 QString str(values.at(i).toString()); … … 763 760 break; 764 761 } 765 #endif766 // fall through767 762 default: { 768 763 QByteArray ba = values.at(i).toString().toAscii(); … … 812 807 setActive(true); 813 808 d->valueCache.resize(count); 809 d->valueCache.fill(NULL); 814 810 815 811 //get out parameters … … 837 833 break; 838 834 case QVariant::String: 839 #ifdef UNICODE840 835 if (bindValueType(i) & QSql::Out) 841 836 values[i] = QString::fromUtf16((ushort*)tmpStorage.takeFirst().constData()); 842 837 break; 843 #endif844 // fall through845 838 default: { 846 839 values[i] = QString::fromAscii(tmpStorage.takeFirst().constData()); … … 859 852 if (i == at()) 860 853 return true; 861 d-> valueCache.fill(0);854 d->clearValueCache(); 862 855 int actualIdx = i + 1; 863 856 if (actualIdx <= 0) { … … 876 869 actualIdx); 877 870 } 878 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO ) {871 if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO && r != SQL_NO_DATA) { 879 872 setLastError(qMakeError(QCoreApplication::translate("QDB2Result", 880 873 "Unable to fetch record %1").arg(i), QSqlError::StatementError, d)); 881 874 return false; 882 875 } 876 else if (r == SQL_NO_DATA) 877 return false; 883 878 setAt(i); 884 879 return true; … … 888 883 { 889 884 SQLRETURN r; 890 d-> valueCache.fill(0);885 d->clearValueCache(); 891 886 r = SQLFetchScroll(d->hStmt, 892 887 SQL_FETCH_NEXT, … … 908 903 if (isForwardOnly()) 909 904 return fetchNext(); 910 d-> valueCache.fill(0);905 d->clearValueCache(); 911 906 SQLRETURN r; 912 907 r = SQLFetchScroll(d->hStmt, … … 914 909 0); 915 910 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)); 918 914 return false; 919 915 } … … 924 920 bool QDB2Result::fetchLast() 925 921 { 926 d-> valueCache.fill(0);922 d->clearValueCache(); 927 923 928 924 int i = at(); … … 1030 1026 case QVariant::Double: 1031 1027 { 1032 QString value=qGetStringData(d->hStmt, field, info.length() + 1, isNull); 1033 bool ok=false; 1034 switch(d->precisionPolicy) { 1028 switch(numericalPrecisionPolicy()) { 1035 1029 case QSql::LowPrecisionInt32: 1036 v = new QVariant( value.toInt(&ok));1030 v = new QVariant(qGetIntData(d->hStmt, field, isNull)); 1037 1031 break; 1038 1032 case QSql::LowPrecisionInt64: 1039 v = new QVariant( value.toLongLong(&ok));1033 v = new QVariant(qGetBigIntData(d->hStmt, field, isNull)); 1040 1034 break; 1041 1035 case QSql::LowPrecisionDouble: 1042 v = new QVariant( value.toDouble(&ok));1036 v = new QVariant(qGetDoubleData(d->hStmt, field, isNull)); 1043 1037 break; 1044 1038 case QSql::HighPrecision: … … 1046 1040 // length + 1 for the comma 1047 1041 v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull)); 1048 ok = true;1049 1042 break; 1050 1043 } 1051 if(!ok)1052 v = new QVariant();1053 1044 break; 1054 1045 } … … 1102 1093 setAt(QSql::BeforeFirstRow); 1103 1094 d->recInf.clear(); 1104 d-> valueCache.clear();1095 d->emptyValueCache(); 1105 1096 setSelect(false); 1106 1097 … … 1121 1112 1122 1113 d->valueCache.resize(fieldCount); 1114 d->valueCache.fill(NULL); 1123 1115 setActive(true); 1124 1116 … … 1133 1125 *static_cast<bool*>(data) = nextResult(); 1134 1126 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); 1138 1130 break; 1139 1131 default: … … 1168 1160 } 1169 1161 1170 bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& , int,1162 bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port, 1171 1163 const QString& connOpts) 1172 1164 { … … 1191 1183 return false; 1192 1184 } 1185 1186 QString protocol; 1193 1187 // Set connection attributes 1194 1188 const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); … … 1221 1215 v = val.toUInt(); 1222 1216 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 { 1224 1221 qWarning("QDB2Driver::open: Unknown connection attribute '%s'", 1225 1222 tmp.toLocal8Bit().constData()); … … 1230 1227 } 1231 1228 1229 if (protocol.isEmpty()) 1230 protocol = QLatin1String("PROTOCOL=TCPIP"); 1231 1232 if (port < 0 ) 1233 port = 50000; 1234 1232 1235 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 1235 1241 SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH]; 1236 1242 SQLSMALLINT cb; … … 1251 1257 } 1252 1258 1253 d->user = user .toUpper();1259 d->user = user; 1254 1260 setOpen(true); 1255 1261 setOpenError(false); … … 1296 1302 SQLHANDLE hStmt; 1297 1303 QString catalog, schema, table; 1298 qSplitTableQualifier(tableName .toUpper(), &catalog, &schema, &table);1304 qSplitTableQualifier(tableName, &catalog, &schema, &table); 1299 1305 if (schema.isEmpty()) 1300 1306 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(); 1301 1322 1302 1323 SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, … … 1313 1334 SQL_IS_UINTEGER); 1314 1335 1336 1337 //Aside: szSchemaName and szTableName parameters of SQLColumns 1338 //are case sensitive search patterns, so no escaping is used. 1315 1339 r = SQLColumns(hStmt, 1316 1340 NULL, … … 1393 1417 QString fieldVal = qGetStringData(hStmt, 2, -1, isNull); 1394 1418 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) 1396 1426 fieldVal = userVal + QLatin1Char('.') + fieldVal; 1397 1427 tl.append(fieldVal); … … 1424 1454 } 1425 1455 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 1427 1473 r = SQLSetStmtAttr(hStmt, 1428 1474 SQL_ATTR_CURSOR_TYPE, … … 1468 1514 case LastInsertId: 1469 1515 case SimpleLocking: 1470 case LowPrecisionNumbers:1471 1516 case EventNotifications: 1472 1517 return false; … … 1476 1521 case PreparedQueries: 1477 1522 case PositionalPlaceholders: 1523 case LowPrecisionNumbers: 1524 case FinishQuery: 1478 1525 return true; 1479 1526 case Unicode: 1480 // this is the query that shows the codepage for the types:1481 // select typename, codepage from syscat.datatypes1482 #ifdef UNICODE1483 1527 return true; 1484 #else1485 return false;1486 #endif1487 1528 } 1488 1529 return false; … … 1598 1639 { 1599 1640 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('"')) ) { 1601 1642 res.replace(QLatin1Char('"'), QLatin1String("\"\"")); 1602 1643 res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); -
trunk/src/sql/drivers/db2/qsql_db2.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 ** -
trunk/src/sql/drivers/ibase/qsql_ibase.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 ** … … 56 56 #include <math.h> 57 57 #include <qdebug.h> 58 #include <QVarLengthArray> 58 59 59 60 QT_BEGIN_NAMESPACE … … 67 68 enum { QIBaseChunkSize = SHRT_MAX / 2 }; 68 69 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 71 static bool getIBaseError(QString& msg, const ISC_STATUS* status, ISC_LONG &sqlcode, QTextCodec *tc) 72 #else 73 static bool getIBaseError(QString& msg, ISC_STATUS* status, ISC_LONG &sqlcode, QTextCodec *tc) 74 #endif 71 75 { 72 76 if (status[0] != 1 || status[1] <= 0) … … 76 80 sqlcode = isc_sqlcode(status); 77 81 char buf[512]; 82 #if defined(FB_API_VER) && FB_API_VER >= 20 83 while(fb_interpret(buf, 512, &status)) { 84 #else 78 85 while(isc_interprete(buf, &status)) { 86 #endif 79 87 if(!msg.isEmpty()) 80 88 msg += QLatin1String(" - "); … … 90 98 { 91 99 sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1)); 100 if (sqlda == (XSQLDA*)0) return; 92 101 sqlda->sqln = 1; 93 102 sqlda->sqld = 0; … … 99 108 static void enlargeDA(XSQLDA *&sqlda, int n) 100 109 { 101 free(sqlda); 110 if (sqlda != (XSQLDA*)0) 111 free(sqlda); 102 112 sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(n)); 113 if (sqlda == (XSQLDA*)0) return; 103 114 sqlda->sqln = n; 104 115 sqlda->version = SQLDA_CURRENT_VERSION; … … 119 130 case SQL_TEXT: 120 131 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]; 122 133 break; 123 134 case SQL_ARRAY: 124 sqlda->sqlvar[i].sqldata = (char*)malloc(sizeof(ISC_QUAD));135 sqlda->sqlvar[i].sqldata = new char[sizeof(ISC_QUAD)]; 125 136 memset(sqlda->sqlvar[i].sqldata, 0, sizeof(ISC_QUAD)); 126 137 break; 127 138 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)]; 129 140 break; 130 141 default: … … 134 145 } 135 146 if (sqlda->sqlvar[i].sqltype & 1) { 136 sqlda->sqlvar[i].sqlind = (short*)malloc(sizeof(short));147 sqlda->sqlvar[i].sqlind = new short[1]; 137 148 *(sqlda->sqlvar[i].sqlind) = 0; 138 149 } else { … … 147 158 return; 148 159 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; 151 162 } 152 163 free(sqlda); … … 293 304 ISC_LONG bufferLength; 294 305 ISC_LONG eventId; 295 306 296 307 enum QIBaseSubscriptionState { Starting, Subscribed, Finished }; 297 308 QIBaseSubscriptionState subscriptionState; … … 444 455 ba.resize(read); 445 456 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", 448 459 "Unable to read BLOB"), 449 460 QSqlError::StatementError)); … … 512 523 else 513 524 valList.append(QString::fromUtf8(buffer, o)); 514 525 515 526 buffer += strLen; 516 527 } … … 577 588 int arraySize = 1, subArraySize; 578 589 short dimensions = desc.array_desc_dimensions; 579 short *numElements = new short[dimensions];590 QVarLengthArray<short> numElements(dimensions); 580 591 581 592 for(int i = 0; i < dimensions; ++i) { … … 606 617 return list; 607 618 608 readArrayBuffer(list, ba.data(), 0, numElements, &desc, tc); 609 610 delete[] numElements; 619 readArrayBuffer(list, ba.data(), 0, numElements.data(), &desc, tc); 611 620 612 621 return QVariant(list); … … 639 648 } 640 649 641 static char* qFillBufferWithString(char *buffer, const QString& string, 642 short buflen, bool varying, bool array, 650 static char* qFillBufferWithString(char *buffer, const QString& string, 651 short buflen, bool varying, bool array, 643 652 QTextCodec *tc) 644 653 { … … 872 881 bool QIBaseResult::prepare(const QString& query) 873 882 { 874 //qDebug("prepare: %s\n", qPrintable(query));883 // qDebug("prepare: %s", qPrintable(query)); 875 884 if (!driver() || !driver()->isOpen() || driver()->isOpenError()) 876 885 return false; … … 880 889 881 890 createDA(d->sqlda); 891 if (d->sqlda == (XSQLDA*)0) { 892 qWarning()<<"QIOBaseResult: createDA(): failed to allocate memory"; 893 return false; 894 } 895 882 896 createDA(d->inda); 897 if (d->inda == (XSQLDA*)0){ 898 qWarning()<<"QIOBaseResult: createDA(): failed to allocate memory"; 899 return false; 900 } 883 901 884 902 if (!d->transaction()) … … 901 919 if (d->inda->sqld > d->inda->sqln) { 902 920 enlargeDA(d->inda, d->inda->sqld); 921 if (d->inda == (XSQLDA*)0) { 922 qWarning()<<"QIOBaseResult: enlargeDA(): failed to allocate memory"; 923 return false; 924 } 903 925 904 926 isc_dsql_describe_bind(d->status, &d->stmt, FBVERSION, d->inda); … … 911 933 // need more field descriptors 912 934 enlargeDA(d->sqlda, d->sqlda->sqld); 935 if (d->sqlda == (XSQLDA*)0) { 936 qWarning()<<"QIOBaseResult: enlargeDA(): failed to allocate memory"; 937 return false; 938 } 913 939 914 940 isc_dsql_describe(d->status, &d->stmt, FBVERSION, d->sqlda); … … 978 1004 case SQL_LONG: 979 1005 if (d->inda->sqlvar[para].sqlscale < 0) 980 *((long*)d->inda->sqlvar[para].sqldata) = 1006 *((long*)d->inda->sqlvar[para].sqldata) = 981 1007 (long)floor(0.5 + val.toDouble() * pow(10.0, d->inda->sqlvar[para].sqlscale * -1)); 982 1008 else … … 985 1011 case SQL_SHORT: 986 1012 if (d->inda->sqlvar[para].sqlscale < 0) 987 *((short*)d->inda->sqlvar[para].sqldata) = 1013 *((short*)d->inda->sqlvar[para].sqldata) = 988 1014 (short)floor(0.5 + val.toDouble() * pow(10.0, d->inda->sqlvar[para].sqlscale * -1)); 989 1015 else … … 1026 1052 1027 1053 if (ok) { 1028 if (colCount() ) {1054 if (colCount() && d->queryType != isc_info_sql_stmt_exec_procedure) { 1029 1055 isc_dsql_free_statement(d->status, &d->stmt, DSQL_close); 1030 1056 if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult", "Unable to close statement"))) … … 1040 1066 1041 1067 // 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) 1043 1069 delDA(d->sqlda); 1044 1070 … … 1098 1124 QVariant v; 1099 1125 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 } 1100 1139 row[idx] = v; 1101 1140 continue; … … 1162 1201 row[idx] = QVariant(); 1163 1202 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 } 1164 1224 } 1165 1225 } … … 1237 1297 cCountType = isc_info_req_insert_count; 1238 1298 break; 1299 default: 1300 qWarning() << "numRowsAffected: Unknown statement type (" << d->queryType << ")"; 1301 return -1; 1239 1302 } 1240 1303 … … 1271 1334 QSqlField f(QString::fromLatin1(v.aliasname, v.aliasname_length).simplified(), 1272 1335 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); 1287 1356 } 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);1294 1357 } 1295 1358 f.setSqlType(v.sqltype); … … 1334 1397 case BatchOperations: 1335 1398 case SimpleLocking: 1336 case LowPrecisionNumbers:1337 1399 case FinishQuery: 1338 1400 case MultipleResultSets: … … 1344 1406 case BLOB: 1345 1407 case EventNotifications: 1408 case LowPrecisionNumbers: 1346 1409 return true; 1347 1410 } … … 1553 1616 QSqlQuery q(createResult()); 1554 1617 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(); 1556 1623 q.exec(QLatin1String("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, " 1557 1624 "b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG " 1558 1625 "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b " 1559 1626 "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE " 1560 "AND a.RDB$RELATION_NAME = '") + table name.toUpper()+ QLatin1String("' "1627 "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' " 1561 1628 "ORDER BY a.RDB$FIELD_POSITION")); 1562 1629 … … 1586 1653 return index; 1587 1654 1655 QString tablename = table; 1656 if (isIdentifierEscaped(tablename, QSqlDriver::TableName)) 1657 tablename = stripDelimiters(tablename, QSqlDriver::TableName); 1658 else 1659 tablename = tablename.toUpper(); 1660 1588 1661 QSqlQuery q(createResult()); 1589 1662 q.setForwardOnly(true); … … 1591 1664 "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d " 1592 1665 "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' " 1593 "AND a.RDB$RELATION_NAME = '") + table .toUpper()+1666 "AND a.RDB$RELATION_NAME = '") + tablename + 1594 1667 QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME " 1595 1668 "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME " … … 1668 1741 QIBaseDriver *driver = qBufferDriverMap()->value(result); 1669 1742 qMutex()->unlock(); 1670 1743 1671 1744 // We use an asynchronous call (i.e., queued connection) because the event callback 1672 1745 // is executed in a different thread than the one in which the driver lives. … … 1717 1790 1718 1791 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))); 1720 1793 d->eventBuffers.remove(name); 1721 1794 qFreeEventBuffer(eBuffer); … … 1745 1818 1746 1819 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))); 1748 1821 return false; 1749 1822 } … … 1803 1876 { 1804 1877 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('"')) ) { 1806 1879 res.replace(QLatin1Char('"'), QLatin1String("\"\"")); 1807 1880 res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); -
trunk/src/sql/drivers/ibase/qsql_ibase.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 ** -
trunk/src/sql/drivers/mysql/qsql_mysql.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 ** … … 86 86 tc(0), 87 87 #endif 88 preparedQuerys (false), preparedQuerysEnabled(false) {}88 preparedQuerysEnabled(false) {} 89 89 MYSQL *mysql; 90 90 QTextCodec *tc; 91 91 92 bool preparedQuerys;93 92 bool preparedQuerysEnabled; 94 93 }; … … 164 163 } 165 164 166 class QMYSQLResultPrivate 167 { 165 class QMYSQLResultPrivate : public QObject 166 { 167 Q_OBJECT 168 168 public: 169 QMYSQLResultPrivate( QMYSQLDriverPrivate* dp) : d(dp), result(0),169 QMYSQLResultPrivate(const QMYSQLDriver* dp, const QMYSQLResult* d) : driver(dp), result(0), q(d), 170 170 rowsAffected(0), hasBlobs(false) 171 171 #if MYSQL_VERSION_ID >= 40108 172 172 , stmt(0), meta(0), inBinds(0), outBinds(0) 173 173 #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; 178 180 MYSQL_RES *result; 179 181 MYSQL_ROW row; 182 const QMYSQLResult* q; 180 183 181 184 int rowsAffected; … … 207 210 MYSQL_BIND *outBinds; 208 211 #endif 209 QSql::NumericalPrecisionPolicy precisionPolicy; 212 213 bool preparedQuery; 214 215 private Q_SLOTS: 216 void driverDestroyed() { driver = NULL; } 210 217 }; 211 218 … … 225 232 const QMYSQLDriverPrivate* p) 226 233 { 227 const char *cerr = mysql_error(p->mysql);234 const char *cerr = p->mysql ? mysql_error(p->mysql) : 0; 228 235 return QSqlError(QLatin1String("QMYSQL: ") + err, 229 236 p->tc ? toUnicode(p->tc, cerr) : QString::fromLatin1(cerr), … … 250 257 case FIELD_TYPE_FLOAT : 251 258 case FIELD_TYPE_DOUBLE : 259 case FIELD_TYPE_DECIMAL : 260 #if defined(FIELD_TYPE_NEWDECIMAL) 261 case FIELD_TYPE_NEWDECIMAL: 262 #endif 252 263 type = QVariant::Double; 253 264 break; … … 273 284 case FIELD_TYPE_ENUM : 274 285 case FIELD_TYPE_SET : 275 case FIELD_TYPE_DECIMAL :276 286 type = QVariant::String; 277 287 break; … … 350 360 QMyField &f = fields[i]; 351 361 f.myField = fieldInfo; 362 352 363 f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags); 353 364 if (qIsBlob(fieldInfo->type)) { … … 380 391 : QSqlResult(db) 381 392 { 382 d = new QMYSQLResultPrivate(db ->d);393 d = new QMYSQLResultPrivate(db, this); 383 394 } 384 395 … … 392 403 { 393 404 #if MYSQL_VERSION_ID >= 40108 394 if(d-> d->preparedQuerys)405 if(d->preparedQuery) 395 406 return d->meta ? qVariantFromValue(d->meta) : qVariantFromValue(d->stmt); 396 407 else … … 407 418 // if this isn't done subsequent queries will fail with "Commands out of sync" 408 419 #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); 411 422 if (res) 412 423 mysql_free_result(res); … … 447 458 setAt(-1); 448 459 setActive(false); 449 450 d->d->preparedQuerys = d->d->preparedQuerysEnabled;451 460 } 452 461 453 462 bool QMYSQLResult::fetch(int i) 454 463 { 464 if(!d->driver) 465 return false; 455 466 if (isForwardOnly()) { // fake a forward seek 456 467 if (at() < i) { … … 464 475 if (at() == i) 465 476 return true; 466 if (d-> d->preparedQuerys) {477 if (d->preparedQuery) { 467 478 #if MYSQL_VERSION_ID >= 40108 468 479 mysql_stmt_data_seek(d->stmt, i); … … 495 506 bool QMYSQLResult::fetchNext() 496 507 { 497 if (d->d->preparedQuerys) { 508 if(!d->driver) 509 return false; 510 if (d->preparedQuery) { 498 511 #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)); 500 521 return false; 522 } 501 523 #else 502 524 return false; 503 525 #endif 504 526 } 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; 508 530 } 509 531 setAt(at() + 1); … … 513 535 bool QMYSQLResult::fetchLast() 514 536 { 537 if(!d->driver) 538 return false; 515 539 if (isForwardOnly()) { // fake this since MySQL can't seek on forward only queries 516 540 bool success = fetchNext(); // did we move at all? … … 520 544 521 545 my_ulonglong numRows; 522 if (d-> d->preparedQuerys) {546 if (d->preparedQuery) { 523 547 #if MYSQL_VERSION_ID >= 40108 524 548 numRows = mysql_stmt_num_rows(d->stmt); … … 554 578 } 555 579 580 if (!d->driver) 581 return QVariant(); 582 556 583 int fieldLength = 0; 557 584 const QMYSQLResultPrivate::QMyField &f = d->fields.at(field); 558 585 QString val; 559 if (d-> d->preparedQuerys) {586 if (d->preparedQuery) { 560 587 if (f.nullIndicator) 561 588 return QVariant(f.type); 562 589 563 590 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); 565 592 } else { 566 593 if (d->row[field] == NULL) { … … 570 597 fieldLength = mysql_fetch_lengths(d->result)[field]; 571 598 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); 573 600 } 574 601 … … 585 612 QVariant v; 586 613 bool ok=false; 587 switch(d->precisionPolicy) { 614 double dbl = val.toDouble(&ok); 615 switch(numericalPrecisionPolicy()) { 588 616 case QSql::LowPrecisionInt32: 589 v= val.toInt(&ok);617 v=QVariant(dbl).toInt(); 590 618 break; 591 619 case QSql::LowPrecisionInt64: 592 v = val.toLongLong(&ok);620 v = QVariant(dbl).toLongLong(); 593 621 break; 594 622 case QSql::LowPrecisionDouble: 595 v = val.toDouble(&ok);623 v = QVariant(dbl); 596 624 break; 597 625 case QSql::HighPrecision: … … 606 634 return QVariant(); 607 635 } 636 return QVariant(val.toDouble()); 608 637 case QVariant::Date: 609 638 return qDateFromString(val); … … 615 644 616 645 QByteArray ba; 617 if (d-> d->preparedQuerys) {646 if (d->preparedQuery) { 618 647 ba = QByteArray(f.outField, f.bufLength); 619 648 } else { … … 632 661 bool QMYSQLResult::isNull(int field) 633 662 { 634 if (d-> d->preparedQuerys)663 if (d->preparedQuery) 635 664 return d->fields.at(field).nullIndicator; 636 665 else … … 640 669 bool QMYSQLResult::reset (const QString& query) 641 670 { 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())) { 653 680 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) { 659 686 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); 664 691 setSelect(numFields != 0); 665 692 d->fields.resize(numFields); 666 d->rowsAffected = mysql_affected_rows(d->d->mysql); 693 d->rowsAffected = mysql_affected_rows(d->driver->d->mysql); 694 667 695 if (isSelect()) { 668 696 for(int i = 0; i < numFields; i++) { … … 678 706 int QMYSQLResult::size() 679 707 { 680 if ( isSelect())681 if (d-> d->preparedQuerys)708 if (d->driver && isSelect()) 709 if (d->preparedQuery) 682 710 #if MYSQL_VERSION_ID >= 40108 683 711 return mysql_stmt_num_rows(d->stmt); … … 698 726 QVariant QMYSQLResult::lastInsertId() const 699 727 { 700 if (!isActive() )728 if (!isActive() || !d->driver) 701 729 return QVariant(); 702 730 703 if (d-> d->preparedQuerys) {731 if (d->preparedQuery) { 704 732 #if MYSQL_VERSION_ID >= 40108 705 733 quint64 id = mysql_stmt_insert_id(d->stmt); … … 708 736 #endif 709 737 } else { 710 quint64 id = mysql_insert_id(d->d ->mysql);738 quint64 id = mysql_insert_id(d->driver->d->mysql); 711 739 if (id) 712 740 return QVariant(id); … … 719 747 QSqlRecord info; 720 748 MYSQL_RES *res; 721 if (!isActive() || !isSelect() )749 if (!isActive() || !isSelect() || !d->driver) 722 750 return info; 723 751 724 752 #if MYSQL_VERSION_ID >= 40108 725 res = d-> d->preparedQuerys? d->meta : d->result;753 res = d->preparedQuery ? d->meta : d->result; 726 754 #else 727 755 res = d->result; 728 756 #endif 729 757 730 if (!mysql_errno(d->d ->mysql)) {758 if (!mysql_errno(d->driver->d->mysql)) { 731 759 mysql_field_seek(res, 0); 732 760 MYSQL_FIELD* field = mysql_fetch_field(res); 733 761 while(field) { 734 info.append(qToField(field, d->d ->tc));762 info.append(qToField(field, d->driver->d->tc)); 735 763 field = mysql_fetch_field(res); 736 764 } … … 742 770 bool QMYSQLResult::nextResult() 743 771 { 772 if(!d->driver) 773 return false; 744 774 #if MYSQL_VERSION_ID >= 40100 745 775 setAt(-1); … … 755 785 d->fields.clear(); 756 786 757 int status = mysql_next_result(d->d ->mysql);787 int status = mysql_next_result(d->driver->d->mysql); 758 788 if (status > 0) { 759 789 setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute next query"), 760 QSqlError::StatementError, d->d ));790 QSqlError::StatementError, d->driver->d)); 761 791 return false; 762 792 } else if (status == -1) { … … 764 794 } 765 795 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); 768 798 if (!d->result && numFields > 0) { 769 799 setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store next result"), 770 QSqlError::StatementError, d->d ));800 QSqlError::StatementError, d->driver->d)); 771 801 return false; 772 802 } … … 774 804 setSelect(numFields > 0); 775 805 d->fields.resize(numFields); 776 d->rowsAffected = mysql_affected_rows(d->d ->mysql);806 d->rowsAffected = mysql_affected_rows(d->driver->d->mysql); 777 807 778 808 if (isSelect()) { … … 797 827 *static_cast<bool*>(data) = nextResult(); 798 828 break; 799 case QSqlResult::SetNumericalPrecision:800 Q_ASSERT(data);801 d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);802 break;803 829 default: 804 830 QSqlResult::virtual_hook(id, data); … … 834 860 bool QMYSQLResult::prepare(const QString& query) 835 861 { 862 if(!d->driver) 863 return false; 836 864 #if MYSQL_VERSION_ID >= 40108 837 865 cleanup(); 838 if (!d->d ->preparedQuerys)866 if (!d->driver->d->preparedQuerysEnabled) 839 867 return QSqlResult::prepare(query); 840 868 … … 845 873 846 874 if (!d->stmt) 847 d->stmt = mysql_stmt_init(d->d ->mysql);875 d->stmt = mysql_stmt_init(d->driver->d->mysql); 848 876 if (!d->stmt) { 849 877 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)); 855 883 r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length()); 856 884 if (r != 0) { … … 866 894 867 895 setSelect(d->bindInValues()); 896 d->preparedQuery = true; 868 897 return true; 869 898 #else … … 874 903 bool QMYSQLResult::exec() 875 904 { 876 if (!d->d->preparedQuerys) 905 if (!d->driver) 906 return false; 907 if (!d->preparedQuery) 877 908 return QSqlResult::exec(); 878 909 if (!d->stmt) … … 907 938 currBind->is_null = &nullVector[i]; 908 939 currBind->length = 0; 940 currBind->is_unsigned = 0; 909 941 910 942 switch (val.type()) { … … 953 985 currBind->buffer = data; 954 986 currBind->buffer_length = sizeof(double); 955 currBind->is_unsigned = 0;956 987 break; 957 988 case QVariant::LongLong: … … 964 995 case QVariant::String: 965 996 default: { 966 QByteArray ba = fromUnicode(d->d ->tc, val.toString());997 QByteArray ba = fromUnicode(d->driver->d->tc, val.toString()); 967 998 stringVector.append(ba); 968 999 currBind->buffer_type = MYSQL_TYPE_STRING; 969 1000 currBind->buffer = const_cast<char *>(ba.constData()); 970 1001 currBind->buffer_length = ba.length(); 971 currBind->is_unsigned = 0;972 1002 break; } 973 1003 } … … 1129 1159 case BatchOperations: 1130 1160 case SimpleLocking: 1131 case LowPrecisionNumbers:1132 1161 case EventNotifications: 1133 1162 case FinishQuery: … … 1137 1166 case LastInsertId: 1138 1167 case Unicode: 1168 case LowPrecisionNumbers: 1139 1169 return true; 1140 1170 case PreparedQueries: … … 1193 1223 const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); 1194 1224 QString unixSocket; 1225 #if MYSQL_VERSION_ID >= 50000 1226 my_bool reconnect=false; 1227 #endif 1195 1228 1196 1229 // extract the real options from the string … … 1203 1236 if (opt == QLatin1String("UNIX_SOCKET")) 1204 1237 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 1205 1244 else if (val == QLatin1String("TRUE") || val == QLatin1String("1")) 1206 1245 setOptionFlag(optionFlags, tmp.left(idx).simplified()); … … 1235 1274 return false; 1236 1275 } 1276 #if MYSQL_VERSION_ID >= 50000 1277 if(reconnect) 1278 mysql_options(d->mysql, MYSQL_OPT_RECONNECT, &reconnect); 1279 #endif 1237 1280 } else { 1238 1281 setLastError(qMakeError(tr("Unable to connect"), … … 1259 1302 #endif 1260 1303 1304 #ifndef QT_NO_THREAD 1305 mysql_thread_init(); 1306 #endif 1307 1308 1261 1309 setOpen(true); 1262 1310 setOpenError(false); … … 1267 1315 { 1268 1316 if (isOpen()) { 1317 #ifndef QT_NO_THREAD 1318 mysql_thread_end(); 1319 #endif 1269 1320 mysql_close(d->mysql); 1270 1321 d->mysql = NULL; … … 1282 1333 { 1283 1334 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 1301 1371 return tl; 1302 1372 } … … 1305 1375 { 1306 1376 QSqlIndex idx; 1307 bool prepQ;1308 1377 if (!isOpen()) 1309 1378 return idx; 1310 1311 prepQ = d->preparedQuerys;1312 d->preparedQuerys = false;1313 1379 1314 1380 QSqlQuery i(createResult()); 1315 1381 QString stmt(QLatin1String("show index from %1;")); 1316 1382 QSqlRecord fil = record(tablename); 1317 i.exec(stmt.arg( escapeIdentifier(tablename, QSqlDriver::TableName)));1383 i.exec(stmt.arg(tablename)); 1318 1384 while (i.isActive() && i.next()) { 1319 1385 if (i.value(2).toString() == QLatin1String("PRIMARY")) { … … 1324 1390 } 1325 1391 1326 d->preparedQuerys = prepQ;1327 1392 return idx; 1328 1393 } … … 1330 1395 QSqlRecord QMYSQLDriver::record(const QString& tablename) const 1331 1396 { 1397 QString table=tablename; 1398 if(isIdentifierEscaped(table, QSqlDriver::TableName)) 1399 table = stripDelimiters(table, QSqlDriver::TableName); 1400 1332 1401 QSqlRecord info; 1333 1402 if (!isOpen()) 1334 1403 return info; 1335 MYSQL_RES* r = mysql_list_fields(d->mysql, table name.toLocal8Bit().constData(), 0);1404 MYSQL_RES* r = mysql_list_fields(d->mysql, table.toLocal8Bit().constData(), 0); 1336 1405 if (!r) { 1337 1406 return info; 1338 1407 } 1339 1408 MYSQL_FIELD* field; 1409 1340 1410 while ((field = mysql_fetch_field(r))) 1341 1411 info.append(qToField(field, d->tc)); … … 1437 1507 { 1438 1508 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('`')) ) { 1440 1510 res.prepend(QLatin1Char('`')).append(QLatin1Char('`')); 1441 1511 res.replace(QLatin1Char('.'), QLatin1String("`.`")); … … 1444 1514 } 1445 1515 1516 bool 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 1446 1524 QT_END_NAMESPACE 1525 1526 #include "qsql_mysql.moc" -
trunk/src/sql/drivers/mysql/qsql_mysql.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 ** … … 70 70 { 71 71 friend class QMYSQLDriver; 72 friend class QMYSQLResultPrivate; 72 73 public: 73 74 explicit QMYSQLResult(const QMYSQLDriver* db); … … 124 125 QString escapeIdentifier(const QString &identifier, IdentifierType type) const; 125 126 127 protected Q_SLOTS: 128 bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; 129 126 130 protected: 127 131 bool beginTransaction(); -
trunk/src/sql/drivers/oci/qsql_oci.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 ** … … 149 149 int serverVersion; 150 150 int prefetchRows, prefetchMem; 151 QSql::NumericalPrecisionPolicy precisionPolicy;152 151 153 152 void setCharset(OCIBind* hbnd); … … 406 405 ub4 prefetchRows; 407 406 ub2 prefetchMem; 408 QSql::NumericalPrecisionPolicy precisionPolicy;409 407 QString user; 410 408 … … 414 412 QOCIDriverPrivate::QOCIDriverPrivate() 415 413 : 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) 417 415 { 418 416 } … … 520 518 else if (ocitype == QLatin1String("LONG") || ocitype == QLatin1String("NCLOB") 521 519 || ocitype == QLatin1String("CLOB")) 522 type = QVariant:: ByteArray;520 type = QVariant::String; 523 521 else if (ocitype == QLatin1String("RAW") || ocitype == QLatin1String("LONG RAW") 524 522 || ocitype == QLatin1String("ROWID") || ocitype == QLatin1String("BLOB") … … 546 544 case SQLT_RDD: 547 545 case SQLT_LNG: 546 case SQLT_CLOB: 548 547 #ifdef SQLT_INTERVAL_YM 549 548 case SQLT_INTERVAL_YM: … … 587 586 case SQLT_REF: 588 587 case SQLT_RID: 589 case SQLT_CLOB:590 588 type = QVariant::ByteArray; 591 589 break; … … 612 610 f.setRequired(ofi.oraIsNull == 0); 613 611 614 if (ofi.type == QVariant::String )612 if (ofi.type == QVariant::String && ofi.oraType != SQLT_NUM && ofi.oraType != SQLT_VNU) 615 613 f.setLength(ofi.oraFieldLength); 616 614 else … … 621 619 return f; 622 620 } 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_SIZE666 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 #else675 // for Oracle8.676 colFieldLength = colLength;677 #endif678 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 it723 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 it729 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 bytes741 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 753 621 754 622 /*! … … 807 675 char* create(int position, int size); 808 676 OCILobLocator ** createLobLocator(int position, OCIEnv* env); 677 OraFieldInfo qMakeOraField(const QOCIResultPrivate* p, OCIParam* param) const; 809 678 810 679 class OraFieldInf … … 1138 1007 } 1139 1008 1009 OraFieldInfo 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 1140 1138 struct QOCIBatchColumn 1141 1139 { … … 1260 1258 col.bindAs = SQLT_STR; 1261 1259 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; 1263 1265 if (len > col.maxLen) 1264 1266 col.maxLen = len; … … 1271 1273 col.bindAs = SQLT_LBI; 1272 1274 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(); 1274 1279 if (col.lengths[j] > col.maxLen) 1275 1280 col.maxLen = col.lengths[j]; … … 1581 1586 case QVariant::Int: 1582 1587 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) 1585 1590 && (fld.typ == QVariant::Double)) { 1586 1591 v[index + i] = *reinterpret_cast<double *>(fld.data); 1587 1592 break; 1588 } else if ((d-> precisionPolicy== QSql::LowPrecisionInt64)1593 } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64) 1589 1594 && (fld.typ == QVariant::LongLong)) { 1590 1595 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), 1592 1597 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(); 1594 1602 break; 1595 } else if ((d-> precisionPolicy== QSql::LowPrecisionInt32)1603 } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32) 1596 1604 && (fld.typ == QVariant::Int)) { 1597 1605 v[index + i] = *reinterpret_cast<int *>(fld.data); … … 1619 1627 : cols(0), q(result), env(driver->env), err(0), svc(const_cast<OCISvcCtx*&>(driver->svc)), 1620 1628 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) 1623 1630 { 1624 1631 int r = OCIHandleAlloc(env, … … 1790 1797 { 1791 1798 int r = 0; 1792 ub2 stmtType ;1799 ub2 stmtType=0; 1793 1800 ub4 iters; 1794 1801 ub4 mode; … … 1803 1810 OCI_ATTR_STMT_TYPE, 1804 1811 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 } 1805 1822 1806 1823 if (stmtType == OCI_STMT_SELECT) { … … 1892 1909 QOCICols::execBatch(d, boundValues(), *reinterpret_cast<bool *>(data)); 1893 1910 break; 1894 case QSqlResult::SetNumericalPrecision:1895 d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);1896 break;1897 1911 default: 1898 QSql Result::virtual_hook(id, data);1912 QSqlCachedResult::virtual_hook(id, data); 1899 1913 } 1900 1914 } … … 2031 2045 if (!hostname.isEmpty()) 2032 2046 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); 2035 2049 2036 2050 r = OCIHandleAlloc(d->env, reinterpret_cast<void **>(&d->srvhp), OCI_HTYPE_SERVER, 0, 0); … … 2099 2113 setOpen(true); 2100 2114 setOpenError(false); 2101 d->user = user .toUpper();2115 d->user = user; 2102 2116 2103 2117 return true; … … 2187 2201 { 2188 2202 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 2189 2220 if (!isOpen()) 2190 2221 return tl; … … 2193 2224 t.setForwardOnly(true); 2194 2225 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 "))); 2203 2283 while (t.next()) { 2204 2284 if (t.value(0).toString() != d->user) … … 2208 2288 } 2209 2289 } 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 else2223 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 }2232 2290 return tl; 2233 2291 } … … 2238 2296 int i = tname.indexOf(QLatin1Char('.')); // prefixed with owner? 2239 2297 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); 2242 2300 } else { 2243 *tbl = tname .toUpper();2301 *tbl = tname; 2244 2302 } 2245 2303 } … … 2256 2314 QString stmt(QLatin1String("select column_name, data_type, data_length, " 2257 2315 "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")); 2260 2318 if (d->serverVersion >= 9) 2261 2319 stmt = stmt.arg(QLatin1String(", char_length ")); … … 2265 2323 QString table, owner, tmpStmt; 2266 2324 qSplitTableAndOwner(tablename, &table, &owner); 2325 2326 if (isIdentifierEscaped(table, QSqlDriver::TableName)) 2327 table = stripDelimiters(table, QSqlDriver::TableName); 2328 else 2329 table = table.toUpper(); 2330 2267 2331 tmpStmt = stmt.arg(QLatin1Char('\'') + table + QLatin1Char('\'')); 2268 2332 if (owner.isEmpty()) { 2269 2333 owner = d->user; 2270 2334 } 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('\''); 2272 2342 t.setForwardOnly(true); 2273 2343 t.exec(tmpStmt); 2274 2344 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('\''); 2277 2350 t.setForwardOnly(true); 2278 2351 t.exec(stmt); … … 2286 2359 if (buildRecordInfo) { 2287 2360 do { 2288 QVariant::Type ty = qDecodeOCIType(t.value(1).toString(), t.numericalPrecisionPolicy());2361 QVariant::Type ty = qDecodeOCIType(t.value(1).toString(), t.numericalPrecisionPolicy()); 2289 2362 QSqlField f(t.value(0).toString(), ty); 2290 2363 f.setRequired(t.value(5).toString() == QLatin1String("N")); … … 2318 2391 QString table, owner, tmpStmt; 2319 2392 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('\''); 2321 2400 if (owner.isEmpty()) { 2322 2401 owner = d->user; 2323 2402 } 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('\''); 2325 2410 t.setForwardOnly(true); 2326 2411 t.exec(tmpStmt); … … 2346 2431 t.value(2).toString() + QLatin1String("' and column_name='") + 2347 2432 t.value(0).toString() + QLatin1String("' and owner='") + 2348 owner + QLatin1String("'"));2433 owner + QLatin1Char('\'')); 2349 2434 if (!tt.next()) { 2350 2435 return QSqlIndex(); … … 2416 2501 } 2417 2502 2418 QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType /* type */) const2503 QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const 2419 2504 { 2420 2505 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("\"\"")); 2423 2508 res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); 2424 // res.replace(QLatin1Char('.'), QLatin1String("\".\"")); 2509 res.replace(QLatin1Char('.'), QLatin1String("\".\"")); 2510 } 2425 2511 return res; 2426 2512 } -
trunk/src/sql/drivers/oci/qsql_oci.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 ** -
trunk/src/sql/drivers/odbc/qsql_odbc.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 ** … … 56 56 #include <qvector.h> 57 57 #include <QDebug> 58 #include <QSqlQuery> 58 59 59 60 QT_BEGIN_NAMESPACE … … 70 71 71 72 // 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 73 77 # define QSQLLEN SQLLEN 74 #else75 # define QSQLLEN SQLINTEGER76 #endif77 78 #if defined(SQLULEN) || defined(Q_OS_WIN64)79 78 # define QSQLULEN SQLULEN 80 #else 81 # define QSQLULEN SQLUINTEGER 82 #endif 79 #endif 80 83 81 84 82 static const int COLNAMESIZE = 256; … … 89 87 { 90 88 public: 89 enum DefaultCase{Lower, Mixed, Upper, Sensitive}; 91 90 QODBCDriverPrivate() 92 91 : 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('"')) 94 94 { 95 sql_char_type = sql_varchar_type = sql_longvarchar_type = QVariant::ByteArray;96 95 unicode = false; 97 96 } … … 102 101 uint unicode :1; 103 102 uint useSchema :1; 104 QVariant::Type sql_char_type;105 QVariant::Type sql_varchar_type;106 QVariant::Type sql_longvarchar_type;107 103 int disconnectCount; 108 104 bool isMySqlServer; … … 120 116 void splitTableQualifier(const QString &qualifier, QString &catalog, 121 117 QString &schema, QString &table); 118 DefaultCase defaultCase() const; 119 QString adjustCase(const QString&) const; 120 QChar quoteChar(); 121 private: 122 bool isQuoteInitialized; 123 QChar quote; 122 124 }; 123 125 … … 125 127 { 126 128 public: 127 QODBCPrivate( )128 : h Env(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) 129 131 { 130 sql_char_type = sql_varchar_type = sql_longvarchar_type = QVariant::ByteArray;131 132 unicode = false; 132 133 } … … 135 136 { fieldCache.fill(QVariant()); fieldCacheIdx = 0; } 136 137 137 SQLHANDLE hEnv;138 SQLHANDLE hDbc;138 SQLHANDLE dpEnv() const { return driverPrivate ? driverPrivate->hEnv : 0;} 139 SQLHANDLE dpDbc() const { return driverPrivate ? driverPrivate->hDbc : 0;} 139 140 SQLHANDLE hStmt; 140 141 141 142 uint unicode :1; 142 143 uint useSchema :1; 143 QVariant::Type sql_char_type;144 QVariant::Type sql_varchar_type;145 QVariant::Type sql_longvarchar_type;146 144 147 145 QSqlRecord rInf; … … 150 148 int disconnectCount; 151 149 bool hasSQLFetchScroll; 152 QSql::NumericalPrecisionPolicy precisionPolicy; 150 QODBCDriverPrivate *driverPrivate; 151 bool userForwardOnly; 153 152 154 153 bool isStmtHandleValid(const QSqlDriver *driver); … … 174 173 SQLRETURN r = SQL_NO_DATA; 175 174 SQLTCHAR state_[SQL_SQLSTATE_SIZE+1]; 176 SQLTCHAR description_[SQL_MAX_MESSAGE_LENGTH];175 QVarLengthArray<SQLTCHAR> description_(SQL_MAX_MESSAGE_LENGTH); 177 176 QString result; 178 177 int i = 1; 179 178 180 179 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); 181 191 do { 182 192 r = SQLGetDiagRec(handleType, 183 193 handle, 184 194 i, 185 (SQLTCHAR*)state_,195 state_, 186 196 &nativeCode_, 187 (SQLTCHAR*)description_,188 SQL_MAX_MESSAGE_LENGTH, /* in bytes, not in characters */197 description_.data(), 198 description_.size(), 189 199 &msgLen); 190 200 if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { … … 193 203 QString tmpstore; 194 204 #ifdef UNICODE 195 tmpstore = QString((const QChar*)description_ , msgLen);205 tmpstore = QString((const QChar*)description_.data(), msgLen); 196 206 #else 197 tmpstore = QString::fromLocal8Bit((const char*)description_ , msgLen);207 tmpstore = QString::fromLocal8Bit((const char*)description_.data(), msgLen); 198 208 #endif 199 209 if(result != tmpstore) { … … 212 222 static QString qODBCWarn(const QODBCPrivate* odbc, int *nativeCode = 0) 213 223 { 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(' ') 216 226 + qWarnODBCHandle(SQL_HANDLE_STMT, odbc->hStmt, nativeCode)); 217 227 } … … 219 229 static QString qODBCWarn(const QODBCDriverPrivate* odbc, int *nativeCode = 0) 220 230 { 221 return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1 String(" ")231 return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1Char(' ') 222 232 + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->hDbc, nativeCode)); 223 233 } … … 251 261 static QVariant::Type qDecodeODBCType(SQLSMALLINT sqltype, const T* p, bool isSigned = true) 252 262 { 263 Q_UNUSED(p); 253 264 QVariant::Type type = QVariant::Invalid; 254 265 switch (sqltype) { … … 263 274 case SQL_INTEGER: 264 275 case SQL_BIT: 276 type = isSigned ? QVariant::Int : QVariant::UInt; 277 break; 265 278 case SQL_TINYINT: 266 type = isSigned ? QVariant::Int :QVariant::UInt;279 type = QVariant::UInt; 267 280 break; 268 281 case SQL_BIGINT: … … 294 307 #endif 295 308 case SQL_CHAR: 296 type = p->sql_char_type;297 break;298 309 case SQL_VARCHAR: 299 310 case SQL_GUID: 300 type = p->sql_varchar_type;301 break;302 311 case SQL_LONGVARCHAR: 303 type = p->sql_longvarchar_type;312 type = QVariant::String; 304 313 break; 305 314 default: … … 327 336 } 328 337 } 329 char* buf = new char[colSize];338 QVarLengthArray<char> buf(colSize); 330 339 while (true) { 331 340 r = SQLGetData(hStmt, 332 341 column+1, 333 342 unicode ? SQL_C_WCHAR : SQL_C_CHAR, 334 (SQLPOINTER)buf ,343 (SQLPOINTER)buf.data(), 335 344 colSize, 336 345 &lengthIndicator); … … 347 356 int rSize = (r == SQL_SUCCESS_WITH_INFO) ? (unicode ? colSize-2 : colSize-1) : lengthIndicator; 348 357 if (unicode) { 349 fieldVal += QString(( QChar*) buf, rSize / 2);358 fieldVal += QString((const QChar*) buf.constData(), rSize / 2); 350 359 } else { 351 fieldVal += QString::fromAscii(buf , rSize);360 fieldVal += QString::fromAscii(buf.constData(), rSize); 352 361 } 353 if (fieldVal.size() + lengthIndicator >= colSize) { 362 memset(buf.data(), 0, colSize); 363 if (lengthIndicator < colSize) { 354 364 // workaround for Drivermanagers that don't return SQL_NO_DATA 355 365 break; … … 363 373 } 364 374 } 365 delete[] buf;366 375 return fieldVal; 367 376 } … … 443 452 } 444 453 454 static 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 445 474 static QVariant qGetBigIntData(SQLHANDLE hStmt, int column, bool isSigned = true) 446 475 { … … 552 581 if (connOpts.contains(QLatin1String("SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC3"), Qt::CaseInsensitive)) 553 582 return SQL_OV_ODBC3; 554 #endif 583 #endif 555 584 return SQL_OV_ODBC2; 556 585 } 586 587 QChar 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 557 607 558 608 bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts) … … 706 756 } 707 757 758 QODBCDriverPrivate::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 */ 793 QString 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 708 811 //////////////////////////////////////////////////////////////////////////// 709 812 … … 711 814 : QSqlResult(db) 712 815 { 713 d = new QODBCPrivate(); 714 d->hEnv = p->hEnv; 715 d->hDbc = p->hDbc; 816 d = new QODBCPrivate(p); 716 817 d->unicode = p->unicode; 717 818 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;721 819 d->disconnectCount = p->disconnectCount; 722 820 d->hasSQLFetchScroll = p->hasSQLFetchScroll; … … 754 852 } 755 853 r = SQLAllocHandle(SQL_HANDLE_STMT, 756 d-> hDbc,854 d->dpDbc(), 757 855 &d->hStmt); 758 856 if (r != SQL_SUCCESS) { … … 763 861 d->updateStmtHandleState(driver()); 764 862 765 if ( isForwardOnly()) {863 if (d->userForwardOnly) { 766 864 r = SQLSetStmtAttr(d->hStmt, 767 865 SQL_ATTR_CURSOR_TYPE, … … 796 894 return false; 797 895 } 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); 798 901 799 902 SQLSMALLINT count; … … 883 986 SQL_FETCH_FIRST, 884 987 0); 885 if (r != SQL_SUCCESS) { 988 if (r != SQL_SUCCESS) { 886 989 if (r != SQL_NO_DATA) 887 990 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", … … 902 1005 SQL_FETCH_PRIOR, 903 1006 0); 904 if (r != SQL_SUCCESS) { 1007 if (r != SQL_SUCCESS) { 905 1008 if (r != SQL_NO_DATA) 906 1009 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", … … 933 1036 SQL_FETCH_LAST, 934 1037 0); 935 if (r != SQL_SUCCESS) { 1038 if (r != SQL_SUCCESS) { 936 1039 if (r != SQL_NO_DATA) 937 1040 setLastError(qMakeError(QCoreApplication::translate("QODBCResult", … … 1024 1127 break; 1025 1128 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); 1027 1130 break; 1028 1131 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; 1051 1145 } 1146 break; 1052 1147 default: 1053 1148 d->fieldCache[i] = QVariant(qGetStringData(d->hStmt, i, info.length(), false)); … … 1103 1198 } 1104 1199 r = SQLAllocHandle(SQL_HANDLE_STMT, 1105 d-> hDbc,1200 d->dpDbc(), 1106 1201 &d->hStmt); 1107 1202 if (r != SQL_SUCCESS) { … … 1112 1207 d->updateStmtHandleState(driver()); 1113 1208 1114 if ( isForwardOnly()) {1209 if (d->userForwardOnly) { 1115 1210 r = SQLSetStmtAttr(d->hStmt, 1116 1211 SQL_ATTR_CURSOR_TYPE, … … 1372 1467 #endif 1373 1468 { 1374 QByteArray str = val.toString().to Utf8();1469 QByteArray str = val.toString().toAscii(); 1375 1470 if (*ind != SQL_NULL_DATA) 1376 1471 *ind = str.length(); 1377 1472 int strSize = str.length(); 1378 1473 1379 1474 r = SQLBindParameter(d->hStmt, 1380 1475 i + 1, … … 1423 1518 } 1424 1519 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 1425 1525 SQLSMALLINT count; 1426 1526 SQLNumResultCols(d->hStmt, &count); … … 1457 1557 QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000))); 1458 1558 break; } 1559 case QVariant::Bool: 1459 1560 case QVariant::Int: 1460 1561 case QVariant::UInt: … … 1546 1647 *static_cast<bool*>(data) = nextResult(); 1547 1648 break; 1548 case QSqlResult::SetNumericalPrecision:1549 Q_ASSERT(data);1550 d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);1551 break;1552 1649 default: 1553 1650 QSqlResult::virtual_hook(id, data); 1554 1651 } 1652 } 1653 1654 void QODBCResult::setForwardOnly(bool forward) 1655 { 1656 d->userForwardOnly = forward; 1657 QSqlResult::setForwardOnly(forward); 1555 1658 } 1556 1659 … … 1670 1773 if (db.contains(QLatin1String(".dsn"), Qt::CaseInsensitive)) 1671 1774 connQStr = QLatin1String("FILEDSN=") + db; 1672 else if (db.contains(QLatin1String("DRIVER="), Qt::CaseInsensitive) 1775 else if (db.contains(QLatin1String("DRIVER="), Qt::CaseInsensitive) 1673 1776 || db.contains(QLatin1String("SERVER="), Qt::CaseInsensitive)) 1674 1777 connQStr = db; … … 1680 1783 if (!password.isEmpty()) 1681 1784 connQStr += QLatin1String(";PWD=") + password; 1682 1785 1683 1786 SQLSMALLINT cb; 1684 1787 SQLTCHAR connOut[1024]; … … 1703 1806 if (!d->checkDriver()) { 1704 1807 setLastError(qMakeError(tr("Unable to connect - Driver doesn't support all " 1705 " needed functionality"), QSqlError::ConnectionError, d));1808 "functionality required"), QSqlError::ConnectionError, d)); 1706 1809 setOpenError(true); 1707 1810 return false; … … 1715 1818 setOpen(true); 1716 1819 setOpenError(false); 1820 if(d->isMSSqlServer) { 1821 QSqlQuery i(createResult()); 1822 i.exec(QLatin1String("SET QUOTED_IDENTIFIER ON")); 1823 } 1717 1824 return true; 1718 1825 } … … 1763 1870 return; 1764 1871 #endif 1765 #if defined(Q_WS_WIN) 1766 QT_WA( 1767 {}, 1768 { 1769 unicode = false; 1770 return; 1771 }) 1772 #endif 1872 1773 1873 SQLRETURN r; 1774 1874 SQLUINTEGER fFunc; … … 1781 1881 NULL); 1782 1882 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WCHAR)) { 1783 sql_char_type = QVariant::String;1784 1883 unicode = true; 1785 1884 } … … 1791 1890 NULL); 1792 1891 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WVARCHAR)) { 1793 sql_varchar_type = QVariant::String;1794 1892 unicode = true; 1795 1893 } … … 1801 1899 NULL); 1802 1900 if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WLONGVARCHAR)) { 1803 sql_longvarchar_type = QVariant::String;1804 1901 unicode = true; 1805 1902 } … … 2085 2182 QString catalog, schema, table; 2086 2183 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 2087 2200 r = SQLSetStmtAttr(hStmt, 2088 2201 SQL_ATTR_CURSOR_TYPE, … … 2187 2300 QString catalog, schema, table; 2188 2301 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 2189 2318 SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, 2190 2319 d->hDbc, … … 2294 2423 QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType) const 2295 2424 { 2425 QChar quote = d->quoteChar(); 2296 2426 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)); 2308 2431 } 2309 2432 return res; 2310 2433 } 2311 2434 2435 bool 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 2312 2443 QT_END_NAMESPACE -
trunk/src/sql/drivers/odbc/qsql_odbc.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 ** … … 101 101 102 102 QVariant handle() const; 103 virtual void setForwardOnly(bool forward); 103 104 104 105 protected: … … 146 147 QString escapeIdentifier(const QString &identifier, IdentifierType type) const; 147 148 149 protected Q_SLOTS: 150 bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; 151 148 152 protected: 149 153 bool beginTransaction(); 150 154 bool commitTransaction(); 151 155 bool rollbackTransaction(); 156 152 157 private: 153 158 void init(); -
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 ** -
trunk/src/sql/drivers/sqlite/qsql_sqlite.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 ** … … 64 64 65 65 QT_BEGIN_NAMESPACE 66 67 static 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 } 66 77 67 78 static QVariant::Type qGetColumnType(const QString &tpName) … … 112 123 sqlite3_stmt *stmt; 113 124 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()? 117 127 QSqlRecord rInf; 118 Q Sql::NumericalPrecisionPolicy precisionPolicy;128 QVector<QVariant> firstRow; 119 129 }; 120 130 121 static const uint initial_cache_size = 128;122 123 131 QSQLiteResultPrivate::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) 125 133 { 126 134 } … … 182 190 Q_ASSERT(!initialFetch); 183 191 skipRow = false; 192 for(int i=0;i<firstRow.count();i++) 193 values[i]=firstRow[i]; 184 194 return skippedStatus; 185 195 } 186 196 skipRow = initialFetch; 197 198 if(initialFetch) { 199 firstRow.clear(); 200 firstRow.resize(sqlite3_column_count(stmt)); 201 } 187 202 188 203 if (!stmt) { … … 213 228 break; 214 229 case SQLITE_FLOAT: 215 switch( precisionPolicy) {230 switch(q->numericalPrecisionPolicy()) { 216 231 case QSql::LowPrecisionInt32: 217 232 values[i + idx] = sqlite3_column_int(stmt, i); … … 221 236 break; 222 237 case QSql::LowPrecisionDouble: 223 values[i + idx] = sqlite3_column_double(stmt, i);224 break;225 238 case QSql::HighPrecision: 226 239 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); 230 241 break; 231 242 }; … … 290 301 sqlite3_reset(d->stmt); 291 302 break; 292 case QSqlResult::SetNumericalPrecision:293 Q_ASSERT(data);294 d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);295 break;296 303 default: 297 QSql Result::virtual_hook(id, data);304 QSqlCachedResult::virtual_hook(id, data); 298 305 } 299 306 } … … 400 407 return false; 401 408 } 402 d->skippedStatus = d->fetchNext( cache(), 0, true);409 d->skippedStatus = d->fetchNext(d->firstRow, 0, true); 403 410 if (lastError().isValid()) { 404 411 setSelect(false); … … 482 489 case SimpleLocking: 483 490 case FinishQuery: 491 case LowPrecisionNumbers: 484 492 return true; 485 493 case QuerySize: 486 494 case NamedPlaceholders: 487 495 case BatchOperations: 488 case LowPrecisionNumbers:489 496 case EventNotifications: 490 497 case MultipleResultSets: … … 499 506 500 507 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 } 506 515 } 507 516 return DefaultTimeout; 517 } 518 519 static 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; 508 527 } 509 528 … … 520 539 return false; 521 540 522 if (sqlite3_open 16(db.constData(), &d->access) == SQLITE_OK) {541 if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, qGetSqliteOpenMode(conOpts), NULL) == SQLITE_OK) { 523 542 sqlite3_busy_timeout(d->access, qGetSqliteTimeout(conOpts)); 524 543 setOpen(true); … … 632 651 QString schema; 633 652 QString table(tableName); 634 int indexOfSeparator = tableName.indexOf(QLatin1 String("."));653 int indexOfSeparator = tableName.indexOf(QLatin1Char('.')); 635 654 if (indexOfSeparator > -1) { 636 schema = tableName.left(indexOfSeparator).append(QLatin1 String("."));655 schema = tableName.left(indexOfSeparator).append(QLatin1Char('.')); 637 656 table = tableName.mid(indexOfSeparator + 1); 638 657 } 639 q.exec(QLatin1String("PRAGMA ") + schema + QLatin1String("table_info ( '") + table + QLatin1String("')"));658 q.exec(QLatin1String("PRAGMA ") + schema + QLatin1String("table_info (") + _q_escapeIdentifier(table) + QLatin1String(")")); 640 659 641 660 QSqlIndex ind; … … 662 681 return QSqlIndex(); 663 682 683 QString table = tblname; 684 if (isIdentifierEscaped(table, QSqlDriver::TableName)) 685 table = stripDelimiters(table, QSqlDriver::TableName); 686 664 687 QSqlQuery q(createResult()); 665 688 q.setForwardOnly(true); 666 return qGetTableInfo(q, t blname, true);689 return qGetTableInfo(q, table, true); 667 690 } 668 691 … … 672 695 return QSqlRecord(); 673 696 697 QString table = tbl; 698 if (isIdentifierEscaped(table, QSqlDriver::TableName)) 699 table = stripDelimiters(table, QSqlDriver::TableName); 700 674 701 QSqlQuery q(createResult()); 675 702 q.setForwardOnly(true); 676 return qGetTableInfo(q, t bl);703 return qGetTableInfo(q, table); 677 704 } 678 705 … … 682 709 } 683 710 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; 711 QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const 712 { 713 Q_UNUSED(type); 714 return _q_escapeIdentifier(identifier); 693 715 } 694 716 -
trunk/src/sql/drivers/sqlite/qsql_sqlite.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 ** -
trunk/src/sql/drivers/sqlite2/qsql_sqlite2.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 ** … … 111 111 sqlite_vm *currentMachine; 112 112 113 uint skippedStatus: 1; // the status of the fetchNext() that's skipped114 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; 116 116 QSqlRecord rInf; 117 Q Sql::NumericalPrecisionPolicy precisionPolicy;117 QVector<QVariant> firstRow; 118 118 }; 119 119 … … 121 121 122 122 QSQLite2ResultPrivate::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) 124 124 { 125 125 } … … 168 168 const char* lastDot = strrchr(cnames[i], '.'); 169 169 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, 171 179 nameToType(QString::fromAscii(cnames[i+numCols])))); 172 180 } … … 186 194 Q_ASSERT(!initialFetch); 187 195 skipRow = false; 196 for(int i=0;i<firstRow.count(); i++) 197 values[i] = firstRow[i]; 188 198 return skippedStatus; 189 199 } … … 203 213 } 204 214 215 if(initialFetch) { 216 firstRow.clear(); 217 firstRow.resize(colNum); 218 } 219 205 220 switch(res) { 206 221 case SQLITE_ROW: … … 253 268 d->finalize(); 254 269 break; 255 case QSqlResult::SetNumericalPrecision:256 Q_ASSERT(data);257 d->precisionPolicy = *reinterpret_cast<QSql::NumericalPrecisionPolicy *>(data);258 break;259 270 default: 260 QSql Result::virtual_hook(id, data);271 QSqlCachedResult::virtual_hook(id, data); 261 272 } 262 273 } … … 297 308 // we have to fetch one row to find out about 298 309 // the structure of the result set 299 d->skippedStatus = d->fetchNext( cache(), 0, true);310 d->skippedStatus = d->fetchNext(d->firstRow, 0, true); 300 311 if (lastError().isValid()) { 301 312 setSelect(false); … … 386 397 d->access = sqlite_open(QFile::encodeName(db), 0, &err); 387 398 if (err) { 388 setLastError(QSqlError(tr("Error to opendatabase"), QString::fromAscii(err),399 setLastError(QSqlError(tr("Error opening database"), QString::fromAscii(err), 389 400 QSqlError::ConnectionError)); 390 401 sqlite_freemem(err); … … 461 472 return true; 462 473 463 setLastError(QSqlError(tr("Unable to rollback Transaction"),474 setLastError(QSqlError(tr("Unable to rollback transaction"), 464 475 QString::fromAscii(err), QSqlError::TransactionError, res)); 465 476 sqlite_freemem(err); … … 504 515 QSqlQuery q(createResult()); 505 516 q.setForwardOnly(true); 517 QString table = tblname; 518 if (isIdentifierEscaped(table, QSqlDriver::TableName)) 519 table = stripDelimiters(table, QSqlDriver::TableName); 506 520 // finrst find a UNIQUE INDEX 507 q.exec(QLatin1String("PRAGMA index_list('") + t blname + QLatin1String("');"));521 q.exec(QLatin1String("PRAGMA index_list('") + table + QLatin1String("');")); 508 522 QString indexname; 509 523 while(q.next()) { … … 518 532 q.exec(QLatin1String("PRAGMA index_info('") + indexname + QLatin1String("');")); 519 533 520 QSqlIndex index(t blname, indexname);534 QSqlIndex index(table, indexname); 521 535 while(q.next()) { 522 536 QString name = q.value(2).toString(); … … 533 547 if (!isOpen()) 534 548 return QSqlRecord(); 549 QString table = tbl; 550 if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) 551 table = stripDelimiters(table, QSqlDriver::TableName); 535 552 536 553 QSqlQuery q(createResult()); … … 548 565 { 549 566 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('"')) ) { 551 568 res.replace(QLatin1Char('"'), QLatin1String("\"\"")); 552 569 res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); -
trunk/src/sql/drivers/sqlite2/qsql_sqlite2.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 ** -
trunk/src/sql/drivers/tds/qsql_tds.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 ** … … 165 165 extern "C" { 166 166 static int CS_PUBLIC qTdsMsgHandler (DBPROCESS* dbproc, 167 DBINT /*msgno*/,167 DBINT msgno, 168 168 int msgstate, 169 169 int severity, 170 170 char* msgtext, 171 char* /*srvname*/,171 char* srvname, 172 172 char* /*procname*/, 173 int /*line*/)173 int line) 174 174 { 175 175 QTDSResultPrivate* p = errs()->value(dbproc); … … 182 182 183 183 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); 186 191 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 } 187 198 } 188 199 … … 212 223 213 224 214 QString errMsg = QString (QLatin1String("%1 %2\n")).arg(QString::fromAscii(dberrstr)).arg(215 Q String::fromAscii(oserrstr));225 QString errMsg = QString::fromLatin1("%1 %2\n").arg(QLatin1String(dberrstr)).arg( 226 QLatin1String(oserrstr)); 216 227 errMsg += p->getErrorMsgs(); 217 228 p->lastError = qMakeError(errMsg, QSqlError::UnknownError, dberr); … … 294 305 // insert d in error handler dict 295 306 errs()->insert(d->dbproc, d); 307 dbcmd(d->dbproc, "set quoted_identifier on"); 308 dbsqlexec(d->dbproc); 296 309 } 297 310 … … 368 381 values[idx] = QVariant(QVariant::String); 369 382 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(); 371 384 break; 372 385 case QVariant::ByteArray: { … … 699 712 QSqlQuery t(createResult()); 700 713 t.setForwardOnly(true); 714 715 QString table = tablename; 716 if (isIdentifierEscaped(table, QSqlDriver::TableName)) 717 table = stripDelimiters(table, QSqlDriver::TableName); 718 701 719 QString stmt (QLatin1String("select name, type, length, prec from syscolumns " 702 720 "where id = (select id from sysobjects where name = '%1')")); 703 t.exec(stmt.arg(table name));721 t.exec(stmt.arg(table)); 704 722 while (t.next()) { 705 723 QSqlField f(t.value(0).toString().simplified(), qDecodeTDSType(t.value(1).toInt())); … … 748 766 else if (field.type() == QVariant::DateTime) { 749 767 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("'")); 751 771 } else 752 772 r = QLatin1String("NULL"); … … 771 791 QSqlRecord rec = record(tablename); 772 792 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())) 775 799 return QSqlIndex(); 776 800 777 801 QSqlQuery t(createResult()); 778 802 t.setForwardOnly(true); 779 t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table name));803 t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table)); 780 804 if (t.next()) { 781 805 QStringList fNames = t.value(2).toString().simplified().split(QLatin1Char(',')); … … 795 819 } 796 820 821 QString 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 797 832 QT_END_NAMESPACE -
trunk/src/sql/drivers/tds/qsql_tds.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 ** … … 117 117 QVariant handle() const; 118 118 119 QString escapeIdentifier(const QString &identifier, IdentifierType type) const; 120 119 121 protected: 120 122 bool beginTransaction(); -
trunk/src/sql/kernel/qsql.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 ** -
trunk/src/sql/kernel/qsqlcachedresult.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 ** … … 185 185 setAt(d->cacheCount()); 186 186 while (at() < i + 1) { 187 if (!cacheNext()) 187 if (!cacheNext()) { 188 if (d->canSeek(i)) 189 break; 188 190 return false; 191 } 189 192 } 190 193 setAt(i); … … 276 279 return false; 277 280 281 if(isForwardOnly()) { 282 d->cache.clear(); 283 d->cache.resize(d->colCount); 284 } 285 278 286 if (!gotoNext(d->cache, d->nextIndex())) { 279 287 d->revertLast(); … … 295 303 } 296 304 305 void 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 297 318 QT_END_NAMESPACE -
trunk/src/sql/kernel/qsqlcachedresult_p.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 ** … … 90 90 ValueCache &cache(); 91 91 92 void virtual_hook(int id, void *data); 92 93 private: 93 94 bool cacheNext(); -
trunk/src/sql/kernel/qsqldatabase.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 ** … … 130 130 { 131 131 public: 132 QSqlDatabasePrivate(QSqlDriver *dr = 0): 132 QSqlDatabasePrivate(QSqlDatabase *d, QSqlDriver *dr = 0): 133 q(d), 133 134 driver(dr), 134 135 port(-1) 135 136 { 136 137 ref = 1; 138 if(driver) 139 precisionPolicy = driver->numericalPrecisionPolicy(); 140 else 141 precisionPolicy= QSql::LowPrecisionDouble; 137 142 } 138 143 QSqlDatabasePrivate(const QSqlDatabasePrivate &other); … … 143 148 144 149 QAtomicInt ref; 150 QSqlDatabase *q; 145 151 QSqlDriver* driver; 146 152 QString dbname; … … 152 158 QString connOptions; 153 159 QString connName; 160 QSql::NumericalPrecisionPolicy precisionPolicy; 154 161 155 162 static QSqlDatabasePrivate *shared_null(); … … 165 172 { 166 173 ref = 1; 174 q = other.q; 167 175 dbname = other.dbname; 168 176 uname = other.uname; … … 173 181 connOptions = other.connOptions; 174 182 driver = other.driver; 183 precisionPolicy = other.precisionPolicy; 175 184 } 176 185 … … 217 226 { 218 227 static QSqlNullDriver dr; 219 static QSqlDatabasePrivate n( &dr);228 static QSqlDatabasePrivate n(NULL, &dr); 220 229 return &n; 221 230 } … … 282 291 void QSqlDatabasePrivate::copy(const QSqlDatabasePrivate *other) 283 292 { 293 q = other->q; 284 294 dbname = other->dbname; 285 295 uname = other->uname; … … 289 299 port = other->port; 290 300 connOptions = other->connOptions; 301 precisionPolicy = other->precisionPolicy; 291 302 } 292 303 … … 353 364 354 365 \ingroup database 355 \mainclass 366 356 367 \inmodule QtSql 357 368 … … 379 390 name argument, the default connection is assumed. The following 380 391 snippet shows how to create and open a default connection to a 381 MySQL database:392 PostgreSQL database: 382 393 383 394 \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 0 … … 444 455 The database connection is referred to by \a connectionName. The 445 456 newly added database connection is returned. 457 458 If \a type is not available or could not be loaded, isValid() returns false. 446 459 447 460 If \a connectionName is not specified, the new connection becomes … … 659 672 QSqlDatabase::QSqlDatabase(const QString &type) 660 673 { 661 d = new QSqlDatabasePrivate( );674 d = new QSqlDatabasePrivate(this); 662 675 d->init(type); 663 676 } … … 671 684 QSqlDatabase::QSqlDatabase(QSqlDriver *driver) 672 685 { 673 d = new QSqlDatabasePrivate( driver);686 d = new QSqlDatabasePrivate(this, driver); 674 687 } 675 688 … … 950 963 The \e{database name} is not the \e{connection name}. The 951 964 connection name must be passed to addDatabase() at connection 952 object create time. 965 object create time. 953 966 954 967 For the QOCI (Oracle) driver, the database name is the TNS … … 1218 1231 \i CLIENT_INTERACTIVE 1219 1232 \i UNIX_SOCKET 1233 \i MYSQL_OPT_RECONNECT 1220 1234 \endlist 1221 1235 … … 1253 1267 \list 1254 1268 \i QSQLITE_BUSY_TIMEOUT 1269 \i QSQLITE_OPEN_READONLY 1255 1270 \endlist 1256 1271 … … 1470 1485 } 1471 1486 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 */ 1504 void 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 */ 1519 QSql::NumericalPrecisionPolicy QSqlDatabase::numericalPrecisionPolicy() const 1520 { 1521 if(driver()) 1522 return driver()->numericalPrecisionPolicy(); 1523 else 1524 return d->precisionPolicy; 1525 } 1526 1527 1472 1528 #ifndef QT_NO_DEBUG_STREAM 1473 1529 QDebug operator<<(QDebug dbg, const QSqlDatabase &d) -
trunk/src/sql/kernel/qsqldatabase.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 ** … … 121 121 QString connectOptions() const; 122 122 QString connectionName() const; 123 void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy); 124 QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const; 123 125 124 126 QSqlDriver* driver() const; -
trunk/src/sql/kernel/qsqldriver.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 ** … … 49 49 50 50 QT_BEGIN_NAMESPACE 51 52 static 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 } 51 62 52 63 class QSqlDriverPrivate : public QObjectPrivate … … 62 73 uint isOpenError : 1; 63 74 QSqlError error; 75 QSql::NumericalPrecisionPolicy precisionPolicy; 64 76 }; 65 77 66 78 inline QSqlDriverPrivate::QSqlDriverPrivate() 67 : QObjectPrivate(), isOpen(false), isOpenError(false) 79 : QObjectPrivate(), isOpen(false), isOpenError(false), precisionPolicy(QSql::LowPrecisionDouble) 68 80 { 69 81 } … … 373 385 374 386 The default implementation does nothing. 387 \sa isIdentifierEscaped() 375 388 */ 376 389 QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const 377 390 { 378 391 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 */ 406 bool 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 */ 432 QString 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; 379 441 } 380 442 … … 398 460 for (i = 0; i < rec.count(); ++i) { 399 461 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(", ")); 401 463 } 402 464 if (s.isEmpty()) 403 465 return s; 404 466 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); 406 468 break; 407 469 case WhereStatement: 408 470 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 } 412 479 } else { 413 480 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)); 415 482 QString val = formatValue(rec.field(i)); 416 483 if (val == QLatin1String("NULL")) … … 427 494 break; 428 495 case UpdateStatement: 429 s.append(QLatin1String("UPDATE ")).append( escapeIdentifier(tableName, TableName)).append(496 s.append(QLatin1String("UPDATE ")).append(tableName).append( 430 497 QLatin1String(" SET ")); 431 498 for (i = 0; i < rec.count(); ++i) { 432 499 if (!rec.isGenerated(i) || !rec.value(i).isValid()) 433 500 continue; 434 s.append( escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1Char('='));501 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1Char('=')); 435 502 if (preparedStatement) 436 503 s.append(QLatin1Char('?')); … … 445 512 break; 446 513 case DeleteStatement: 447 s.append(QLatin1String("DELETE FROM ")).append( escapeIdentifier(tableName, TableName));514 s.append(QLatin1String("DELETE FROM ")).append(tableName); 448 515 break; 449 516 case InsertStatement: { 450 s.append(QLatin1String("INSERT INTO ")).append( escapeIdentifier(tableName, TableName)).append(QLatin1String(" ("));517 s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" (")); 451 518 QString vals; 452 519 for (i = 0; i < rec.count(); ++i) { 453 520 if (!rec.isGenerated(i) || !rec.value(i).isValid()) 454 521 continue; 455 s.append( escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));522 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); 456 523 if (preparedStatement) 457 vals.append(QLatin1 String("?"));524 vals.append(QLatin1Char('?')); 458 525 else 459 526 vals.append(formatValue(rec.field(i))); … … 465 532 vals.chop(2); // remove trailing comma 466 533 s[s.length() - 2] = QLatin1Char(')'); 467 s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1 String(")"));534 s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1Char(')')); 468 535 } 469 536 break; } … … 560 627 } 561 628 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()); 566 630 break; 567 631 case QVariant::ByteArray : { … … 801 865 } 802 866 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 */ 883 bool 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 */ 906 QString 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 */ 930 void 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 */ 943 QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const 944 { 945 return d_func()->precisionPolicy; 946 } 947 803 948 QT_END_NAMESPACE -
trunk/src/sql/kernel/qsqldriver.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 ** … … 128 128 QStringList subscribedToNotifications() const; // ### Qt 5: make virtual 129 129 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 130 136 Q_SIGNALS: 131 137 void notification(const QString &name); … … 141 147 QStringList subscribedToNotificationsImplementation() const; // ### Qt 5: eliminate, see subscribedNotifications() 142 148 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 143 152 private: 144 153 Q_DISABLE_COPY(QSqlDriver) -
trunk/src/sql/kernel/qsqldriverplugin.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 ** -
trunk/src/sql/kernel/qsqldriverplugin.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 ** -
trunk/src/sql/kernel/qsqlerror.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 ** … … 49 49 { 50 50 dbg.nospace() << "QSqlError(" << s.number() << ", " << s.driverText() << 51 ", " << s.databaseText() << ")";51 ", " << s.databaseText() << ')'; 52 52 return dbg.space(); 53 53 } -
trunk/src/sql/kernel/qsqlerror.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 ** -
trunk/src/sql/kernel/qsqlfield.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 ** … … 515 515 dbg.nospace() << ", typeID: " << f.typeID(); 516 516 if (!f.defaultValue().isNull()) 517 dbg.nospace() << ", auto-value: \"" << f.defaultValue() << "\"";518 dbg.nospace() << ")";517 dbg.nospace() << ", auto-value: \"" << f.defaultValue() << '\"'; 518 dbg.nospace() << ')'; 519 519 return dbg.space(); 520 520 #else -
trunk/src/sql/kernel/qsqlfield.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 ** -
trunk/src/sql/kernel/qsqlindex.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 ** -
trunk/src/sql/kernel/qsqlindex.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 ** -
trunk/src/sql/kernel/qsqlnulldriver_p.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 ** -
trunk/src/sql/kernel/qsqlquery.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 ** … … 62 62 QAtomicInt ref; 63 63 QSqlResult* sqlResult; 64 QSql::NumericalPrecisionPolicy precisionPolicy;65 64 66 65 static QSqlQueryPrivate* shared_null(); … … 82 81 */ 83 82 QSqlQueryPrivate::QSqlQueryPrivate(QSqlResult* result) 84 : ref(1), sqlResult(result) , precisionPolicy(QSql::HighPrecision)83 : ref(1), sqlResult(result) 85 84 { 86 85 if (!sqlResult) … … 103 102 \ingroup database 104 103 \ingroup shared 105 \mainclass 104 106 105 \inmodule QtSql 107 106 … … 352 351 bool fo = isForwardOnly(); 353 352 *this = QSqlQuery(driver()->createResult()); 354 d->sqlResult->setNumericalPrecisionPolicy(d-> precisionPolicy);353 d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy()); 355 354 setForwardOnly(fo); 356 355 } else { … … 359 358 d->sqlResult->setLastError(QSqlError()); 360 359 d->sqlResult->setAt(QSql::BeforeFirstRow); 361 d->sqlResult->setNumericalPrecisionPolicy(d-> precisionPolicy);360 d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy()); 362 361 } 363 362 d->sqlResult->setQuery(query.trimmed()); … … 813 812 efficient since results do not need to be cached. It will also 814 813 improve performance on some databases. For this to be true, you must 815 call \c setForward Mode() before the query is prepared or executed.814 call \c setForwardOnly() before the query is prepared or executed. 816 815 Note that the constructor that takes a query and a database may 817 816 execute the query. … … 819 818 Forward only mode is off by default. 820 819 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() 822 826 */ 823 827 void QSqlQuery::setForwardOnly(bool forward) … … 892 896 *this = QSqlQuery(driver()->createResult()); 893 897 setForwardOnly(fo); 894 d->sqlResult->setNumericalPrecisionPolicy(d-> precisionPolicy);898 d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy()); 895 899 } else { 896 900 d->sqlResult->setActive(false); 897 901 d->sqlResult->setLastError(QSqlError()); 898 902 d->sqlResult->setAt(QSql::BeforeFirstRow); 899 d->sqlResult->setNumericalPrecisionPolicy(d-> precisionPolicy);903 d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy()); 900 904 } 901 905 if (!driver()) { … … 1127 1131 precision specified by \a precisionPolicy. 1128 1132 1129 The Oracle driver, for example, retrievesnumerical values as1130 strings by default to prevent the loss of precision. If the high1131 precision doesn't matter, use this method to increase execution1132 s peed 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. 1133 1137 1134 1138 Note: Drivers that don't support fetching numerical values with low … … 1145 1149 void QSqlQuery::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy) 1146 1150 { 1147 d-> precisionPolicy = precisionPolicy;1151 d->sqlResult->setNumericalPrecisionPolicy(precisionPolicy); 1148 1152 } 1149 1153 … … 1155 1159 QSql::NumericalPrecisionPolicy QSqlQuery::numericalPrecisionPolicy() const 1156 1160 { 1157 return d-> precisionPolicy;1161 return d->sqlResult->numericalPrecisionPolicy(); 1158 1162 } 1159 1163 … … 1196 1200 result set and must be navigated to a valid record before data 1197 1201 values can be retrieved. If a new result set isn't available the 1198 function returns false and the thequery is set to inactive. In any1202 function returns false and the query is set to inactive. In any 1199 1203 case the old result set will be discarded. 1200 1204 -
trunk/src/sql/kernel/qsqlquery.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 ** -
trunk/src/sql/kernel/qsqlrecord.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 ** … … 590 590 QDebug operator<<(QDebug dbg, const QSqlRecord &r) 591 591 { 592 dbg << "QSqlRecord(" << r.count() << ")";592 dbg << "QSqlRecord(" << r.count() << ')'; 593 593 for (int i = 0; i < r.count(); ++i) 594 594 dbg << '\n' << QString::fromLatin1("%1:").arg(i, 2) << r.field(i) << r.value(i).toString(); -
trunk/src/sql/kernel/qsqlrecord.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 ** -
trunk/src/sql/kernel/qsqlresult.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 ** … … 49 49 #include "qvector.h" 50 50 #include "qsqldriver.h" 51 #include <QDebug> 51 52 52 53 QT_BEGIN_NAMESPACE … … 65 66 QSqlResultPrivate(QSqlResult* d) 66 67 : 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) 68 69 {} 69 70 … … 105 106 QSqlError error; 106 107 bool forwardOnly; 108 QSql::NumericalPrecisionPolicy precisionPolicy; 107 109 108 110 int bindCount; … … 250 252 d = new QSqlResultPrivate(this); 251 253 d->sqldriver = db; 254 if(db) { 255 setNumericalPrecisionPolicy(db->numericalPrecisionPolicy()); 256 } 252 257 } 253 258 … … 555 560 cached. By default, this feature is disabled. 556 561 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() 558 568 */ 559 569 void QSqlResult::setForwardOnly(bool forward) … … 901 911 void QSqlResult::virtual_hook(int, void *) 902 912 { 903 Q_ASSERT(false);904 913 } 905 914 … … 966 975 void QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy) 967 976 { 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 */ 983 QSql::NumericalPrecisionPolicy QSqlResult::numericalPrecisionPolicy() const 984 { 985 return d->precisionPolicy; 970 986 } 971 987 -
trunk/src/sql/kernel/qsqlresult.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 ** … … 136 136 void detachFromResultSet(); 137 137 void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy); 138 QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const; 138 139 bool nextResult(); 139 140 -
trunk/src/sql/models/qsqlquerymodel.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 ** … … 315 315 bool columnsChanged = (newRec != d->rec); 316 316 bool hasQuerySize = query.driver()->hasFeature(QSqlDriver::QuerySize); 317 bool hasNewData = (newRec != QSqlRecord()) || !query.lastError().isValid(); 317 318 318 319 if (d->colOffsets.size() != newRec.count() || columnsChanged) … … 329 330 d->query = query; 330 331 d->rec = newRec; 331 332 332 333 if (mustClearModel) 333 334 endRemoveRows(); 334 335 d->atEnd = false; 336 337 if (columnsChanged )335 336 d->atEnd = false; 337 338 if (columnsChanged && hasNewData) 338 339 reset(); 339 340 … … 418 419 { 419 420 Q_D(QSqlQueryModel); 420 if (orientation != Qt::Horizontal || section < 0 )421 if (orientation != Qt::Horizontal || section < 0 || columnCount() <= section) 421 422 return false; 422 423 -
trunk/src/sql/models/qsqlquerymodel.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 ** -
trunk/src/sql/models/qsqlquerymodel_p.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 ** -
trunk/src/sql/models/qsqlrelationaldelegate.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 ** -
trunk/src/sql/models/qsqlrelationaldelegate.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 ** -
trunk/src/sql/models/qsqlrelationaltablemodel.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 ** … … 183 183 184 184 QSqlRecord record; 185 QString indexColumn; 186 QString displayColumn; 185 187 for (int i=0; i < model->rowCount(); ++i) { 186 188 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(); 189 200 } 190 201 m_dictInitialized = true; … … 216 227 : QSqlTableModelPrivate() 217 228 {} 218 QString escapedRelationField(const QString &tableName, const QString &fieldName) const;229 QString relationField(const QString &tableName, const QString &fieldName) const; 219 230 220 231 int nameToIndex(const QString &name) const; … … 256 267 int QSqlRelationalTableModelPrivate::nameToIndex(const QString &name) const 257 268 { 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); 259 273 } 260 274 … … 482 496 } 483 497 484 QString QSqlRelationalTableModelPrivate:: escapedRelationField(const QString &tableName,498 QString QSqlRelationalTableModelPrivate::relationField(const QString &tableName, 485 499 const QString &fieldName) const 486 500 { 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; 492 506 } 493 507 … … 515 529 // Count how many times each field name occurs in the record 516 530 QHash<QString, int> fieldNames; 531 QStringList fieldList; 517 532 for (int i = 0; i < rec.count(); ++i) { 518 533 QSqlRelation relation = d->relations.value(i, nullRelation).rel; 519 534 QString name; 520 535 if (relation.isValid()) 536 { 521 537 // Count the display column name, not the original foreign key 522 538 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 } 523 550 else 524 551 name = rec.fieldName(i); 525 552 fieldNames.insert(name, fieldNames.value(name, 0) + 1); 553 fieldList.append(name); 526 554 } 527 555 … … 532 560 if (!fList.isEmpty()) 533 561 fList.append(QLatin1String(", ")); 534 fList.append(d-> escapedRelationField(relTableAlias,relation.displayColumn()));562 fList.append(d->relationField(relTableAlias,relation.displayColumn())); 535 563 536 564 // 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); 539 574 } 540 575 541 576 // 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)); 546 578 if(!where.isEmpty()) 547 579 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))); 549 581 where.append(QLatin1String(" = ")); 550 where.append(d-> escapedRelationField(relTableAlias, relation.indexColumn()));582 where.append(d->relationField(relTableAlias, relation.indexColumn())); 551 583 } else { 552 584 if (!fList.isEmpty()) 553 585 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))); 555 587 } 556 588 } … … 561 593 if(!tList.isEmpty()) 562 594 tList.prepend(QLatin1String(", ")); 563 tList.prepend( d->db.driver()->escapeIdentifier(tableName(),QSqlDriver::TableName));595 tList.prepend(tableName()); 564 596 query.append(QLatin1String("SELECT ")); 565 597 query.append(fList).append(QLatin1String(" FROM ")).append(tList); … … 691 723 692 724 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), 694 726 rel.displayColumn())); 695 727 s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC"); -
trunk/src/sql/models/qsqlrelationaltablemodel.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 ** -
trunk/src/sql/models/qsqltablemodel.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 ** … … 99 99 int QSqlTableModelPrivate::nameToIndex(const QString &name) const 100 100 { 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); 102 105 } 103 106 … … 203 206 } 204 207 for (i = 0; i < whereValues.count(); ++i) { 205 if (whereValues.isGenerated(i) )208 if (whereValues.isGenerated(i) && !whereValues.isNull(i)) 206 209 editQuery.addBindValue(whereValues.value(i)); 207 210 } … … 368 371 Q_D(QSqlTableModel); 369 372 clear(); 370 if(d->db.tables().contains(tableName.toUpper())) 371 d->tableName = tableName.toUpper(); 372 else 373 d->tableName = tableName; 373 d->tableName = tableName; 374 374 d->initRecordAndPrimaryIndex(); 375 375 d->initColOffsets(d->rec.count()); … … 407 407 setQuery(qu); 408 408 409 if (!qu.isActive() ) {409 if (!qu.isActive() || lastError().isValid()) { 410 410 // something went wrong - revert to non-select state 411 411 d->initRecordAndPrimaryIndex(); … … 539 539 if (isOk) 540 540 select(); 541 emit dataChanged(index, index); 541 542 break; } 542 543 case OnRowChange: … … 559 560 row.op = QSqlTableModelPrivate::Update; 560 561 row.rec = d->rec; 561 562 row.primaryValues = d->primaryValues(indexInQuery(index).row()); 562 563 } 563 564 row.rec.setValue(index.column(), value); … … 669 670 emit beforeDelete(row); 670 671 671 QSqlRecord rec =d->primaryValues(row);672 const QSqlRecord whereValues = d->strategy == OnManualSubmit ? d->cache[row].primaryValues : d->primaryValues(row); 672 673 bool prepStatement = d->db.driver()->hasFeature(QSqlDriver::PreparedQueries); 673 674 QString stmt = d->db.driver()->sqlStatement(QSqlDriver::DeleteStatement, … … 677 678 QString where = d->db.driver()->sqlStatement(QSqlDriver::WhereStatement, 678 679 d->tableName, 679 rec,680 whereValues, 680 681 prepStatement); 681 682 … … 687 688 stmt.append(QLatin1Char(' ')).append(where); 688 689 689 return d->exec(stmt, prepStatement, rec);690 return d->exec(stmt, prepStatement, whereValues); 690 691 } 691 692 … … 977 978 return s; 978 979 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 980 983 QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName); 981 984 s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field); … … 1097 1100 else { 1098 1101 d->cache[idx].op = QSqlTableModelPrivate::Delete; 1102 d->cache[idx].primaryValues = d->primaryValues(indexInQuery(createIndex(idx, 0)).row()); 1099 1103 emit headerDataChanged(Qt::Vertical, idx, idx); 1100 1104 } … … 1318 1322 mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row()); 1319 1323 } 1324 QString fieldName; 1320 1325 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); 1322 1330 if (idx == -1) 1323 1331 isOk = false; -
trunk/src/sql/models/qsqltablemodel.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 ** -
trunk/src/sql/models/qsqltablemodel_p.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 ** -
trunk/src/sql/sql.pro
r2 r561 18 18 include(models/models.pri) 19 19 20 symbian: { 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.