diff options
18 files changed, 137 insertions, 67 deletions
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 38bf3a0cbd..9f82ce4f8e 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -34,6 +34,7 @@ #include <qscopedpointer.h> #include <qstringlist.h> #include <qfileinfo.h> +#include <qversionnumber.h> QT_BEGIN_NAMESPACE @@ -618,17 +619,30 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tagValue("RootNamespace", tool.Name) << tagValue("Keyword", tool.Keyword); + QString windowsTargetPlatformVersion; if (isWinRT) { xml << tagValue("MinimumVisualStudioVersion", tool.Version) << tagValue("DefaultLanguage", "en") << tagValue("AppContainerApplication", "true") << tagValue("ApplicationType", "Windows Store") << tagValue("ApplicationTypeRevision", tool.SdkVersion); - if (tool.SdkVersion == "10.0") { - const QString ucrtVersion = qgetenv("UCRTVERSION"); - xml << tagValue("WindowsTargetPlatformVersion", ucrtVersion) - << tagValue("WindowsTargetPlatformMinVersion", ucrtVersion); - } + if (tool.SdkVersion == "10.0") + windowsTargetPlatformVersion = qgetenv("UCRTVERSION"); + } else { + QByteArray winSDKVersionStr = qgetenv("WindowsSDKVersion").trimmed(); + + // This environment variable might end with a backslash due to a VS bug. + if (winSDKVersionStr.endsWith('\\')) + winSDKVersionStr.chop(1); + + QVersionNumber winSDKVersion = QVersionNumber::fromString( + QString::fromLocal8Bit(winSDKVersionStr)); + if (!winSDKVersion.isNull()) + windowsTargetPlatformVersion = winSDKVersionStr; + } + if (!windowsTargetPlatformVersion.isEmpty()) { + xml << tagValue("WindowsTargetPlatformVersion", windowsTargetPlatformVersion) + << tagValue("WindowsTargetPlatformMinVersion", windowsTargetPlatformVersion); } xml << closetag(); diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index edc414fa0a..7d529372c4 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -214,6 +214,8 @@ QMimeGlobMatchResult QMimeDatabasePrivate::findByFileName(const QString &fileNam void QMimeDatabasePrivate::loadMimeTypePrivate(QMimeTypePrivate &mimePrivate) { QMutexLocker locker(&mutex); + if (mimePrivate.name.isEmpty()) + return; // invalid mimetype if (!mimePrivate.loaded) { // XML provider sets loaded=true, binary provider does this on demand Q_ASSERT(mimePrivate.fromCache); QMimeBinaryProvider::loadMimeTypePrivate(mimePrivate); diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc index 010659df8c..a425c8a84d 100644 --- a/src/gui/doc/src/qtgui.qdoc +++ b/src/gui/doc/src/qtgui.qdoc @@ -195,19 +195,6 @@ For more information, see the \l{Hello Vulkan Widget Example} and the \l {Hello Vulkan Window Example}. - \section1 Qt GUI Prior to Qt 5.0 - - Prior to Qt 5.0, the Qt GUI module was the monolithic container - for all things relating to graphical user interfaces in Qt, and - included the Qt widget set, the item views, the graphics view - framework and also printing. Starting Qt 5, these classes have - been moved to the Qt Widgets module. Printing has been - moved to the Qt Print Support module. Please note that these - modules can be excluded from a Qt installation. - - Qt GUI now contains only a small set of enablers, which are generally - useful for all graphical applications. - \section1 Drag and Drop More info in \l{Drag and Drop} diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 39d97f4bd9..16ad0a3edc 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -1331,14 +1331,18 @@ void dither_to_Mono(QImageData *dst, const QImageData *src, } else { bit--; } + const int e7 = ((err * 7) + 8) >> 4; + const int e5 = ((err * 5) + 8) >> 4; + const int e3 = ((err * 3) + 8) >> 4; + const int e1 = err - (e7 + e5 + e3); if (x < w) - *b1 += (err*7)>>4; // spread error to right pixel + *b1 += e7; // spread error to right pixel if (not_last_line) { - b2[0] += (err*5)>>4; // pixel below + b2[0] += e5; // pixel below if (x > 1) - b2[-1] += (err*3)>>4; // pixel below left + b2[-1] += e3; // pixel below left if (x < w) - b2[1] += err>>4; // pixel below right + b2[1] += e1; // pixel below right } b2++; } diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index b825b56d45..cea4b51a5c 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2800,6 +2800,11 @@ QOpenGLTexture::TextureFormat QOpenGLTexture::format() const return d->format; } +static bool isNpot(int width, int height = 1, int depth = 1) +{ + return width & (width-1) || height & (height-1) || depth & (depth-1); +} + /*! Sets the dimensions of this texture object to \a width, \a height, and \a depth. The default for each dimension is 1. @@ -2807,6 +2812,10 @@ QOpenGLTexture::TextureFormat QOpenGLTexture::format() const implementation. Allocating storage for a texture less than the maximum size can still fail if your system is low on resources. + If a non-power-of-two \a width, \a height or \a depth is provided and your + OpenGL implementation doesn't have support for repeating non-power-of-two + textures, then the wrap mode is automatically set to ClampToEdge. + \sa width(), height(), depth() */ void QOpenGLTexture::setSize(int width, int height, int depth) @@ -2819,6 +2828,9 @@ void QOpenGLTexture::setSize(int width, int height, int depth) return; } + if (isNpot(width, height, depth) && !hasFeature(Feature::NPOTTextureRepeat) && d->target != Target::TargetRectangle) + d->setWrapMode(WrapMode::ClampToEdge); + switch (d->target) { case QOpenGLTexture::Target1D: case QOpenGLTexture::Target1DArray: diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index 77ccc02aa5..dfd190ddd0 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -226,8 +226,11 @@ bool QDesktopServices::openUrl(const QUrl &url) qWarning("The platform plugin does not support services."); return false; } - return url.scheme() == QLatin1String("file") ? - platformServices->openDocument(url) : platformServices->openUrl(url); + // We only use openDocument if there is no fragment for the URL to + // avoid it being lost when using openDocument + if (url.isLocalFile() && !url.hasFragment()) + return platformServices->openDocument(url); + return platformServices->openUrl(url); } /*! diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 4470d19d8c..7ac6297de6 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -547,9 +547,12 @@ QNativeSocketEngine::QNativeSocketEngine(QObject *parent) d->sslSocket = qobject_cast<QSslSocket *>(parent->parent()); #endif - connect(this, SIGNAL(connectionReady()), SLOT(connectionNotification()), Qt::QueuedConnection); - connect(this, SIGNAL(readReady()), SLOT(readNotification()), Qt::QueuedConnection); - connect(this, SIGNAL(writeReady()), SLOT(writeNotification()), Qt::QueuedConnection); + connect(this, &QNativeSocketEngine::connectionReady, + this, &QNativeSocketEngine::connectionNotification, Qt::QueuedConnection); + connect(this, &QNativeSocketEngine::readReady, + this, &QNativeSocketEngine::processReadReady, Qt::QueuedConnection); + connect(this, &QNativeSocketEngine::writeReady, + this, &QNativeSocketEngine::writeNotification, Qt::QueuedConnection); connect(d->worker, &SocketEngineWorker::connectOpFinished, this, &QNativeSocketEngine::handleConnectOpFinished, Qt::QueuedConnection); connect(d->worker, &SocketEngineWorker::newDataReceived, this, &QNativeSocketEngine::handleNewData, Qt::QueuedConnection); @@ -872,12 +875,15 @@ void QNativeSocketEngine::close() if (d->closingDown) return; - d->closingDown = true; + if (d->pendingReadNotification) + processReadReady(); + d->closingDown = true; d->notifyOnRead = false; d->notifyOnWrite = false; d->notifyOnException = false; + d->emitReadReady = false; HRESULT hr; if (d->socketType == QAbstractSocket::TcpSocket) { @@ -1019,8 +1025,10 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) << copyLength << "of" << d->worker->pendingData.length() << "bytes"; readData = d->worker->pendingData.left(maxlen); d->worker->pendingData.remove(0, maxlen); - if (d->notifyOnRead) + if (d->notifyOnRead) { + d->pendingReadNotification = true; emit readReady(); + } } mutexLocker.unlock(); @@ -1341,6 +1349,7 @@ void QNativeSocketEngine::handleConnectOpFinished(bool success, QAbstractSocket: if (!success) { d->setError(error, errorString); d->socketState = QAbstractSocket::UnconnectedState; + close(); return; } @@ -1369,6 +1378,7 @@ void QNativeSocketEngine::handleNewData() if (d->socketType == QAbstractSocket::UdpSocket && !d->worker->emitDataReceived) return; qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << "Emitting readReady"; + d->pendingReadNotification = true; emit readReady(); d->worker->emitDataReceived = false; d->emitReadReady = false; @@ -1389,9 +1399,17 @@ void QNativeSocketEngine::handleTcpError(QAbstractSocket::SocketError error) } d->setError(error, errorString); - d->socketState = QAbstractSocket::UnconnectedState; - if (d->notifyOnRead) - emit readReady(); + close(); +} + +void QNativeSocketEngine::processReadReady() +{ + Q_D(QNativeSocketEngine); + if (d->closingDown) + return; + + d->pendingReadNotification = false; + readNotification(); } bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol) diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index f47e2a7dd7..6688bfe35c 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -184,6 +184,7 @@ private slots: WinRTSocketEngine::ErrorString errorString); void handleNewData(); void handleTcpError(QAbstractSocket::SocketError error); + void processReadReady(); private: Q_DECLARE_PRIVATE(QNativeSocketEngine) @@ -228,6 +229,7 @@ private: EventRegistrationToken connectionToken; bool emitReadReady = true; + bool pendingReadNotification = false; HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); diff --git a/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp b/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp index 1a24015ce5..186084abd4 100644 --- a/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp +++ b/src/plugins/platformthemes/flatpak/qflatpakfiledialog.cpp @@ -51,6 +51,7 @@ #include <QMetaType> #include <QMimeType> #include <QMimeDatabase> +#include <QRandomGenerator> #include <QWindow> QT_BEGIN_NAMESPACE @@ -231,6 +232,8 @@ void QFlatpakFileDialog::openPortal() if (!filterList.isEmpty()) options.insert(QLatin1String("filters"), QVariant::fromValue(filterList)); + options.insert(QLatin1String("handle_token"), QStringLiteral("qt%1").arg(QRandomGenerator::global()->generate())); + // TODO choices a(ssa(ss)s) // List of serialized combo boxes to add to the file chooser. diff --git a/src/plugins/sqldrivers/oci/qsql_oci.cpp b/src/plugins/sqldrivers/oci/qsql_oci.cpp index 272e1bc083..aee8e92b36 100644 --- a/src/plugins/sqldrivers/oci/qsql_oci.cpp +++ b/src/plugins/sqldrivers/oci/qsql_oci.cpp @@ -1318,7 +1318,7 @@ struct QOCIBatchColumn ub4 maxLen; ub4 recordCount; char* data; - ub2* lengths; + ub4* lengths; sb2* indicators; ub4 maxarr_len; ub4 curelep; @@ -1392,7 +1392,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b QOCIBatchColumn &col = columns[i]; col.recordCount = boundValues.at(i).toList().count(); - col.lengths = new ub2[col.recordCount]; + col.lengths = new ub4[col.recordCount]; col.indicators = new sb2[col.recordCount]; col.maxarr_len = col.recordCount; col.curelep = col.recordCount; @@ -1556,7 +1556,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b // binding the column - r = OCIBindByPos( + r = OCIBindByPos2( d->sql, &bindColumn.bindh, d->err, i + 1, bindColumn.data, bindColumn.maxLen, diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index 291b35f8a6..2c7b4b83db 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -229,12 +229,14 @@ QSqlDatabase QSqlDatabasePrivate::database(const QString& name, bool open) dict->lock.lockForRead(); QSqlDatabase db = dict->value(name); dict->lock.unlock(); - if (db.driver() && db.driver()->thread() != QThread::currentThread()) { + if (!db.isValid()) + return db; + if (db.driver()->thread() != QThread::currentThread()) { qWarning("QSqlDatabasePrivate::database: requested database does not belong to the calling thread."); return QSqlDatabase(); } - if (db.isValid() && !db.isOpen() && open) { + if (open && !db.isOpen()) { if (!db.open()) qWarning() << "QSqlDatabasePrivate::database: unable to open database:" << db.lastError().text(); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index abc06bfe85..3144c3071c 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -214,6 +214,8 @@ void tst_QMimeDatabase::mimeTypeForName() QMimeType doesNotExist = db.mimeTypeForName(QString::fromLatin1("foobar/x-doesnot-exist")); QVERIFY(!doesNotExist.isValid()); + QCOMPARE(doesNotExist.comment(), QString()); + QCOMPARE(doesNotExist.aliases(), QStringList()); // TODO move to findByFile #ifdef Q_OS_LINUX diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 919f9cb718..f8432b8472 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -2658,8 +2658,8 @@ void tst_QDateTime::zoneAtTime_data() ADDROW("before:NPT", "Asia/Kathmandu", QDate(1985, 12, 31), 19800); // 5:30 ADDROW("after:NPT", "Asia/Kathmandu", QDate(1986, 1, 1), 20700); // 5:45 // The two that have skipped a day (each): - ADDROW("before:LINT", "Pacific/Kiritimati", QDate(1994, 12, 31), -36000); - ADDROW("after:LINT", "Pacific/Kiritimati", QDate(1995, 2, 1), 14 * 3600); + ADDROW("before:LINT", "Pacific/Kiritimati", QDate(1994, 12, 30), -36000); + ADDROW("after:LINT", "Pacific/Kiritimati", QDate(1995, 1, 2), 14 * 3600); ADDROW("after:WST", "Pacific/Apia", QDate(2011, 12, 31), 14 * 3600); #endif // MS lacks ACWST, NPT; doesn't grok date-line crossings; and Windows 7 lacks LINT. ADDROW("before:WST", "Pacific/Apia", QDate(2011, 12, 29), -36000); diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index c6c16a5982..375cecd521 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -137,6 +137,7 @@ private slots: void formattedDataSize(); void bcp47Name(); + void systemLocale_data(); void systemLocale(); // *** ORDER-DEPENDENCY *** (This Is Bad.) @@ -2682,27 +2683,31 @@ private: const QLocale m_locale; }; +void tst_QLocale::systemLocale_data() +{ + QTest::addColumn<QString>("name"); + QTest::addColumn<QLocale::Language>("language"); + QTest::addRow("catalan") << QString("ca") << QLocale::Catalan; + QTest::addRow("ukrainian") << QString("uk") << QLocale::Ukrainian; + QTest::addRow("german") << QString("de") << QLocale::German; +} + void tst_QLocale::systemLocale() { QLocale originalLocale; + QLocale originalSystemLocale = QLocale::system(); - MySystemLocale *sLocale = new MySystemLocale(QLocale("uk")); - QCOMPARE(QLocale().language(), QLocale::Ukrainian); - QCOMPARE(QLocale::system().language(), QLocale::Ukrainian); - delete sLocale; - - sLocale = new MySystemLocale(QLocale("ca")); - QCOMPARE(QLocale().language(), QLocale::Catalan); - QCOMPARE(QLocale::system().language(), QLocale::Catalan); - delete sLocale; + QFETCH(QString, name); + QFETCH(QLocale::Language, language); - sLocale = new MySystemLocale(QLocale("de")); - QCOMPARE(QLocale().language(), QLocale::German); - QCOMPARE(QLocale::system().language(), QLocale::German); - delete sLocale; + { + MySystemLocale sLocale(name); + QCOMPARE(QLocale().language(), language); + QCOMPARE(QLocale::system().language(), language); + } QCOMPARE(QLocale(), originalLocale); - QCOMPARE(QLocale::system(), originalLocale); + QCOMPARE(QLocale::system(), originalSystemLocale); } QTEST_MAIN(tst_QLocale) diff --git a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp index 70e696e703..37521a64aa 100644 --- a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp +++ b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp @@ -196,7 +196,6 @@ void tst_QFocusEvent::checkReason_BackTab() // Now test the backtab key QTest::keyClick( childFocusWidgetOne, Qt::Key_Backtab ); - QTest::qWait(200); QTRY_VERIFY(childFocusWidgetOne->focusOutEventRecieved); QVERIFY(childFocusWidgetTwo->focusInEventRecieved); @@ -217,7 +216,6 @@ void tst_QFocusEvent::checkReason_Popup() QMenu* popupMenu = new QMenu( testFocusWidget ); popupMenu->addMenu( "Test" ); popupMenu->popup( QPoint(0,0) ); - QTest::qWait(50); QTRY_VERIFY(childFocusWidgetOne->focusOutEventLostFocus); @@ -308,7 +306,7 @@ void tst_QFocusEvent::checkReason_focusWidget() window1.show(); edit1.setFocus(); - QTest::qWait(100); + QTRY_VERIFY(edit1.hasFocus()); edit2.setFocus(); QVERIFY(frame1.focusWidget() != 0); @@ -344,7 +342,6 @@ void tst_QFocusEvent::checkReason_ActiveWindow() QVERIFY( !childFocusWidgetOne->hasFocus() ); d->hide(); - QTest::qWait(100); if (!QGuiApplication::platformName().compare(QLatin1String("offscreen"), Qt::CaseInsensitive) || !QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive)) { diff --git a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp index aa78d70716..e6eb51500b 100644 --- a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp +++ b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp @@ -420,11 +420,7 @@ void tst_QObjectRace::disconnectRace() threads[i]->start(); } - QTime timeLimiter; - timeLimiter.start(); - - while (timeLimiter.elapsed() < TimeLimit) - QTest::qWait(10); + QTest::qWait(TimeLimit); for (int i = 0; i < ThreadCount; ++i) { threads[i]->requestInterruption(); @@ -450,11 +446,7 @@ void tst_QObjectRace::disconnectRace() threads[i]->start(); } - QTime timeLimiter; - timeLimiter.start(); - - while (timeLimiter.elapsed() < TimeLimit) - QTest::qWait(10); + QTest::qWait(TimeLimit); senderThread->requestInterruption(); QVERIFY(senderThread->wait(300)); diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index 4130b364f4..1f055e9c33 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -2374,6 +2374,9 @@ public slots: "QSqlDatabasePrivate::database: requested database does not belong to the calling thread."); QSqlDatabase db = QSqlDatabase::database(dbName); QVERIFY(!db.isValid()); + + QSqlDatabase invalidDb = QSqlDatabase::database("invalid"); + QVERIFY(!invalidDb.isValid()); QThread::currentThread()->exit(); } private: diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 9093485c40..23c8460133 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -128,6 +128,8 @@ private slots: void mysql_outValues(); void oraClob_data() { generic_data("QOCI"); } void oraClob(); + void oraClobBatch_data() { generic_data("QOCI"); } + void oraClobBatch(); void oraLong_data() { generic_data("QOCI"); } void oraLong(); void oraOCINumber_data() { generic_data("QOCI"); } @@ -810,6 +812,28 @@ void tst_QSqlQuery::oraClob() QVERIFY( q.value( 1 ).toByteArray() == loong.toLatin1() ); } +void tst_QSqlQuery::oraClobBatch() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + const QString clobBatch(qTableName("clobBatch", __FILE__, db)); + tst_Databases::safeDropTables(db, { clobBatch }); + QSqlQuery q(db); + QVERIFY_SQL(q, exec("create table " + clobBatch + "(cl clob)")); + + const QString longString(USHRT_MAX + 1, QLatin1Char('A')); + QVERIFY_SQL(q, prepare("insert into " + clobBatch + " (cl) values(:cl)")); + const QVariantList vars = { longString }; + q.addBindValue(vars); + QVERIFY_SQL(q, execBatch()); + + QVERIFY_SQL(q, exec("select cl from " + clobBatch)); + QVERIFY(q.next()); + QCOMPARE(q.value(0).toString().count(), longString.size()); + QVERIFY(q.value(0).toString() == longString); +} + void tst_QSqlQuery::storedProceduresIBase() { QFETCH( QString, dbName ); |