Mercurial > hg > orthanc
changeset 6468:af1bc07ae7c2
merge
| author | Alain Mazy <am@orthanc.team> |
|---|---|
| date | Thu, 20 Nov 2025 10:06:01 +0100 |
| parents | 2bf85a1e2b85 (current diff) 3cf91621c1da (diff) |
| children | 4e2f5459c43b |
| files | |
| diffstat | 1 files changed, 35 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Thu Nov 20 10:05:19 2025 +0100 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Thu Nov 20 10:06:01 2025 +0100 @@ -43,6 +43,16 @@ #include <boost/lexical_cast.hpp> +/** + * WARNING: Do not use the RETURNING clause in the SQLite statements + * of this file. Indeed, "the RETURNING syntax has been supported by + * SQLite since version 3.35.0 (2021-03-12)". However, versions of + * SQLite < 3.35.0 are still widely used (e.g. Ubuntu 22.04 LTS, which + * is supported until 2030, comes with SQLite 3.31.1). + * https://sqlite.org/lang_returning.html + **/ + + namespace Orthanc { static std::string JoinRequestedMetadata(const FindRequest::ChildrenSpecification& childrenSpec) @@ -2317,28 +2327,37 @@ } // "reservedUntil <= ?" indicates that the reservation has expired - const std::string sql = ("WITH RowToDelete AS (SELECT id FROM Queues WHERE queueId=? AND " - "(reservedUntil IS NULL OR reservedUntil <= ?) ORDER BY id " + order + " LIMIT 1) " - "DELETE FROM Queues WHERE id IN (SELECT id FROM RowToDelete) " - "RETURNING value"); - - SQLite::Statement s(db_, SQLITE_FROM_HERE_DYNAMIC(sql), sql); - - s.BindString(0, queueId); - s.BindInt64(1, GetSecondsSinceEpoch() /* now */); - - if (!s.Step()) + const std::string sql = ("SELECT id, value FROM Queues WHERE queueId=? AND " + "(reservedUntil IS NULL OR reservedUntil <= ?) ORDER BY id " + order + " LIMIT 1"); + + SQLite::Statement s1(db_, SQLITE_FROM_HERE_DYNAMIC(sql), sql); + + s1.BindString(0, queueId); + s1.BindInt64(1, GetSecondsSinceEpoch() /* now */); + + if (!s1.Step()) { // No value found return false; } else { - if (!s.ColumnBlobAsString(0, &value)) + if (!s1.ColumnBlobAsString(1, &value)) { throw OrthancException(ErrorCode_NotEnoughMemory); } + SQLite::Statement s2(db_, SQLITE_FROM_HERE, "DELETE FROM Queues WHERE queueId=? AND id=?"); + s2.BindString(0, queueId); + s2.BindInt64(1, s1.ColumnInt64(0)); + s2.Run(); + + if (db_.GetLastChangeCount() != 1) + { + // This occurs if the acknowledgment occurs after the reservation has expired + throw OrthancException(ErrorCode_UnknownResource); + } + return true; } } @@ -2427,6 +2446,10 @@ // This occurs if the acknowledgment occurs after the reservation has expired throw OrthancException(ErrorCode_UnknownResource); } + else if (db_.GetLastChangeCount() > 1) + { + throw OrthancException(ErrorCode_InternalError); + } } };
