Changeset 561 for trunk/src/sql/drivers
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/sql/drivers/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();
Note:
See TracChangeset
for help on using the changeset viewer.