mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-29 14:14:15 +02:00
Fix read-only queries stopping after the first row
Since #1046, QETSql::execReadOnly() runs a query with PRAGMA query_only set and switches it off before returning. Switching it off aborts a statement SQLite is still stepping through ("abort due to ROLLBACK"), and QSQLITE has already stepped to the first row by then. A query that produces its rows as it goes -- a UNION ALL without ORDER BY -- therefore came back with its first row only and no error. A sorted query was not affected, because SQLite has read every row before returning the first. Every query from the SQL box of a table, a saved <graphics_table> query and the scripting qet.query() goes through here. The checked run is now finished before query_only is switched off, and a query that passed is run again for the caller. SQLite refuses a write at its first step, so passing that step is what proves a statement reads only; the second run is of a statement already shown to be read-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G2d2Zi8BfrYRPX88zhaoFG
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
|
||||
#include <QtTest>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
class TstSqlReadOnly : public QObject
|
||||
@@ -63,6 +64,7 @@ class TstSqlReadOnly : public QObject
|
||||
void doesNotExecuteWhatItRefuses();
|
||||
void refusedQueryCannotBeRunAgain();
|
||||
void acceptedQueryRunAgainStillReads();
|
||||
void returnsEveryRowOfACompoundSelect();
|
||||
void leavesTheConnectionWritable();
|
||||
|
||||
private:
|
||||
@@ -242,6 +244,21 @@ void TstSqlReadOnly::acceptedQueryRunAgainStillReads()
|
||||
QCOMPARE(n, 2);
|
||||
}
|
||||
|
||||
void TstSqlReadOnly::returnsEveryRowOfACompoundSelect()
|
||||
{
|
||||
// Switching query_only off aborts a statement SQLite is still
|
||||
// stepping through, and an unsorted UNION ALL is one: it came back
|
||||
// with its first row only.
|
||||
QSqlQuery q = QETSql::execReadOnly(
|
||||
m_db, "SELECT uuid FROM element UNION ALL SELECT uuid FROM element");
|
||||
QStringList uuids;
|
||||
while (q.next()) {
|
||||
uuids << q.value(0).toString();
|
||||
}
|
||||
QVERIFY(!q.lastError().isValid());
|
||||
QCOMPARE(uuids, QStringList({"a", "b", "a", "b"}));
|
||||
}
|
||||
|
||||
void TstSqlReadOnly::leavesTheConnectionWritable()
|
||||
{
|
||||
// query_only must not outlive the call, whatever its outcome: the
|
||||
|
||||
Reference in New Issue
Block a user