Changeset 561 for trunk/src/sql/kernel/qsqldriver.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 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/kernel/qsqldriver.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtSql module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 49 49 50 50 QT_BEGIN_NAMESPACE 51 52 static QString prepareIdentifier(const QString &identifier, 53 QSqlDriver::IdentifierType type, const QSqlDriver *driver) 54 { 55 Q_ASSERT( driver != NULL ); 56 QString ret = identifier; 57 if (!driver->isIdentifierEscaped(identifier, type)) { 58 ret = driver->escapeIdentifier(identifier, type); 59 } 60 return ret; 61 } 51 62 52 63 class QSqlDriverPrivate : public QObjectPrivate … … 62 73 uint isOpenError : 1; 63 74 QSqlError error; 75 QSql::NumericalPrecisionPolicy precisionPolicy; 64 76 }; 65 77 66 78 inline QSqlDriverPrivate::QSqlDriverPrivate() 67 : QObjectPrivate(), isOpen(false), isOpenError(false) 79 : QObjectPrivate(), isOpen(false), isOpenError(false), precisionPolicy(QSql::LowPrecisionDouble) 68 80 { 69 81 } … … 373 385 374 386 The default implementation does nothing. 387 \sa isIdentifierEscaped() 375 388 */ 376 389 QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const 377 390 { 378 391 return identifier; 392 } 393 394 /*! 395 Returns whether \a identifier is escaped according to the database rules. 396 \a identifier can either be a table name or field name, dependent 397 on \a type. 398 399 \warning Because of binary compatability constraints, this function is not virtual. 400 If you want to provide your own implementation in your QSqlDriver subclass, 401 reimplement the isIdentifierEscapedImplementation() slot in your subclass instead. 402 The isIdentifierEscapedFunction() will dynamically detect the slot and call it. 403 404 \sa stripDelimiters(), escapeIdentifier() 405 */ 406 bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType type) const 407 { 408 bool result; 409 QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this), 410 "isIdentifierEscapedImplementation", Qt::DirectConnection, 411 Q_RETURN_ARG(bool, result), 412 Q_ARG(QString, identifier), 413 Q_ARG(IdentifierType, type)); 414 return result; 415 } 416 417 /*! 418 Returns the \a identifier with the leading and trailing delimiters removed, 419 \a identifier can either be a table name or field name, 420 dependent on \a type. If \a identifier does not have leading 421 and trailing delimiter characters, \a identifier is returned without 422 modification. 423 424 \warning Because of binary compatability constraints, this function is not virtual, 425 If you want to provide your own implementation in your QSqlDriver subclass, 426 reimplement the stripDelimitersImplementation() slot in your subclass instead. 427 The stripDelimiters() function will dynamically detect the slot and call it. 428 429 \since 4.5 430 \sa isIdentifierEscaped() 431 */ 432 QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const 433 { 434 QString result; 435 QMetaObject::invokeMethod(const_cast<QSqlDriver*>(this), 436 "stripDelimitersImplementation", Qt::DirectConnection, 437 Q_RETURN_ARG(QString, result), 438 Q_ARG(QString, identifier), 439 Q_ARG(IdentifierType, type)); 440 return result; 379 441 } 380 442 … … 398 460 for (i = 0; i < rec.count(); ++i) { 399 461 if (rec.isGenerated(i)) 400 s.append( escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));462 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); 401 463 } 402 464 if (s.isEmpty()) 403 465 return s; 404 466 s.chop(2); 405 s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append( escapeIdentifier(tableName, TableName));467 s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName); 406 468 break; 407 469 case WhereStatement: 408 470 if (preparedStatement) { 409 for (int i = 0; i < rec.count(); ++i) 410 s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append( 411 QLatin1String(" = ? AND ")); 471 for (int i = 0; i < rec.count(); ++i) { 472 s.append(prepareIdentifier(rec.fieldName(i), FieldName,this)); 473 if (rec.isNull(i)) 474 s.append(QLatin1String(" IS NULL")); 475 else 476 s.append(QLatin1String(" = ?")); 477 s.append(QLatin1String(" AND ")); 478 } 412 479 } else { 413 480 for (i = 0; i < rec.count(); ++i) { 414 s.append( escapeIdentifier(rec.fieldName(i), FieldName));481 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)); 415 482 QString val = formatValue(rec.field(i)); 416 483 if (val == QLatin1String("NULL")) … … 427 494 break; 428 495 case UpdateStatement: 429 s.append(QLatin1String("UPDATE ")).append( escapeIdentifier(tableName, TableName)).append(496 s.append(QLatin1String("UPDATE ")).append(tableName).append( 430 497 QLatin1String(" SET ")); 431 498 for (i = 0; i < rec.count(); ++i) { 432 499 if (!rec.isGenerated(i) || !rec.value(i).isValid()) 433 500 continue; 434 s.append( escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1Char('='));501 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1Char('=')); 435 502 if (preparedStatement) 436 503 s.append(QLatin1Char('?')); … … 445 512 break; 446 513 case DeleteStatement: 447 s.append(QLatin1String("DELETE FROM ")).append( escapeIdentifier(tableName, TableName));514 s.append(QLatin1String("DELETE FROM ")).append(tableName); 448 515 break; 449 516 case InsertStatement: { 450 s.append(QLatin1String("INSERT INTO ")).append( escapeIdentifier(tableName, TableName)).append(QLatin1String(" ("));517 s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" (")); 451 518 QString vals; 452 519 for (i = 0; i < rec.count(); ++i) { 453 520 if (!rec.isGenerated(i) || !rec.value(i).isValid()) 454 521 continue; 455 s.append( escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", "));522 s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); 456 523 if (preparedStatement) 457 vals.append(QLatin1 String("?"));524 vals.append(QLatin1Char('?')); 458 525 else 459 526 vals.append(formatValue(rec.field(i))); … … 465 532 vals.chop(2); // remove trailing comma 466 533 s[s.length() - 2] = QLatin1Char(')'); 467 s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1 String(")"));534 s.append(QLatin1String("VALUES (")).append(vals).append(QLatin1Char(')')); 468 535 } 469 536 break; } … … 560 627 } 561 628 case QVariant::Bool: 562 if (field.value().toBool()) 563 r = QLatin1String("1"); 564 else 565 r = QLatin1String("0"); 629 r = QString::number(field.value().toBool()); 566 630 break; 567 631 case QVariant::ByteArray : { … … 801 865 } 802 866 867 /*! 868 \since 4.6 869 870 This slot returns whether \a identifier is escaped according to the database rules. 871 \a identifier can either be a table name or field name, dependent 872 on \a type. 873 874 Because of binary compatability constraints, isIdentifierEscaped() function 875 (introduced in Qt 4.5) is not virtual. Instead, isIdentifierEscaped() will 876 dynamically detect and call \e this slot. The default implementation 877 assumes the escape/delimiter character is a double quote. Reimplement this 878 slot in your own QSqlDriver if your database engine uses a different 879 delimiter character. 880 881 \sa isIdentifierEscaped() 882 */ 883 bool QSqlDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const 884 { 885 Q_UNUSED(type); 886 return identifier.size() > 2 887 && identifier.startsWith(QLatin1Char('"')) //left delimited 888 && identifier.endsWith(QLatin1Char('"')); //right delimited 889 } 890 891 /*! 892 \since 4.6 893 894 This slot returns \a identifier with the leading and trailing delimiters removed, 895 \a identifier can either be a tablename or field name, dependent on \a type. 896 If \a identifier does not have leading and trailing delimiter characters, \a 897 identifier is returned without modification. 898 899 Because of binary compatability constraints, the stripDelimiters() function 900 (introduced in Qt 4.5) is not virtual. Instead, stripDelimiters() will 901 dynamically detect and call \e this slot. It generally unnecessary 902 to reimplement this slot. 903 904 \sa stripDelimiters() 905 */ 906 QString QSqlDriver::stripDelimitersImplementation(const QString &identifier, IdentifierType type) const 907 { 908 QString ret; 909 if (this->isIdentifierEscaped(identifier, type)) { 910 ret = identifier.mid(1); 911 ret.chop(1); 912 } else { 913 ret = identifier; 914 } 915 return ret; 916 } 917 918 /*! 919 \since 4.6 920 921 Sets the default numerical precision policy used by queries created 922 by this driver to \a precisionPolicy. 923 924 Note: Setting the default precision policy to \a precisionPolicy 925 doesn't affect any currently active queries. 926 927 \sa QSql::NumericalPrecisionPolicy, numericalPrecisionPolicy(), 928 QSqlQuery::setNumericalPrecisionPolicy(), QSqlQuery::numericalPrecisionPolicy() 929 */ 930 void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy) 931 { 932 d_func()->precisionPolicy = precisionPolicy; 933 } 934 935 /*! 936 \since 4.6 937 938 Returns the current default precision policy for the database connection. 939 940 \sa QSql::NumericalPrecisionPolicy, setNumericalPrecisionPolicy(), 941 QSqlQuery::numericalPrecisionPolicy(), QSqlQuery::setNumericalPrecisionPolicy() 942 */ 943 QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const 944 { 945 return d_func()->precisionPolicy; 946 } 947 803 948 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.