Results 1 to 3 of 3

Thread: [patch] QPSQL: set an error code so QSqlError::number() gives a useful value

  1. #1
    Join Date
    Dec 2008
    Posts
    1
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default [patch] QPSQL: set an error code so QSqlError::number() gives a useful value

    Problem: in my application (which makes use of PostgreSQL and Qt4) I
    need to distinguish between different kinds of (SQL) errors, that is,
    I need to check if the error is a foreign key violation, or uniqness
    voilation, etc. This information is available via `native' PostgreSQL
    API, the relevant function is

    char *PQresultErrorField(const PGresult *res, int fieldcode)

    However, QPSQL driver does not provide this information, i.e. QSqlError
    returned by QPSQL always has number() == -1. Also, there's no (easy)
    way to retrive PGresult* from the driver. Hence the patch below. With
    this patch number() returns an error code (as described in the Appendix A
    of the PostgreSQL manual). There's one quirk, though. PostgreSQLs error
    codes are 5 character ASCII strings, but QSqlError expects an integer
    instead. The patch treats error codes as integres in base 29. To get
    back the original error code, one should convert that integer back.

    Qt Code:
    1. Index: qt4-x11-4.4.3/src/sql/drivers/psql/qsql_psql.cpp
    2. ===================================================================
    3. --- qt4-x11-4.4.3.orig/src/sql/drivers/psql/qsql_psql.cpp 2008-12-08 11:42:21.000000000 +0200
    4. +++ qt4-x11-4.4.3/src/sql/drivers/psql/qsql_psql.cpp 2008-12-08 11:48:11.000000000 +0200
    5. @@ -146,11 +146,28 @@
    6. };
    7.  
    8. static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type,
    9. - const QPSQLDriverPrivate *p)
    10. + const QPSQLDriverPrivate *p,
    11. + const PGresult *res = 0)
    12. {
    13. const char *s = PQerrorMessage(p->connection);
    14. + int errnum = -1;
    15. + if (res) {
    16. + const char *sql_state_ = PQresultErrorField(res, PG_DIAG_SQLSTATE);
    17. + if (sql_state_) {
    18. + bool ok;
    19. + // PQresultErrorField returns 5-character error code,
    20. + // see the appendix A (titled `PostgreSQL Error Codes')
    21. + // of the PostgreSQL manual. On the other hand, Qt
    22. + // expects an integer.
    23. + static const int latin_base = 29;
    24. + // Error code contains arbitrary alphanumeric characters
    25. + errnum = QString::fromAscii(sql_state_).toInt(&ok, latin_base);
    26. + if (!ok)
    27. + errnum = -1;
    28. + }
    29. + }
    30. QString msg = p->isUtf8 ? QString::fromUtf8(s) : QString::fromLocal8Bit(s);
    31. - return QSqlError(QLatin1String("QPSQL: ") + err, msg, type);
    32. + return QSqlError(QLatin1String("QPSQL: ") + err, msg, type, errnum);
    33. }
    34.  
    35. bool QPSQLResultPrivate::processResults()
    36. @@ -171,7 +188,7 @@
    37. return true;
    38. }
    39. q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
    40. - "Unable to create query"), QSqlError::StatementError, driver));
    41. + "Unable to create query"), QSqlError::StatementError, driver, result));
    42. return false;
    43. }
    44.  
    45. @@ -543,6 +560,7 @@
    46. : stmt.toLocal8Bit().constData());
    47.  
    48. if (PQresultStatus(result) != PGRES_COMMAND_OK) {
    49. + // XXX: do we need to setNumber() here?
    50. setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
    51. "Unable to prepare statement"), QSqlError::StatementError, d->driver));
    52. PQclear(result);
    53. @@ -1173,6 +1191,7 @@
    54. d->isUtf8 ? query.toUtf8().constData()
    55. : query.toLocal8Bit().constData())
    56. ) != PGRES_COMMAND_OK) {
    57. + // XXX: do we need to setNumber() here?
    58. setLastError(qMakeError(tr("Unable to subscribe"), QSqlError::StatementError, d));
    59. return false;
    60. }
    61. @@ -1205,6 +1224,7 @@
    62. d->isUtf8 ? query.toUtf8().constData()
    63. : query.toLocal8Bit().constData())
    64. ) != PGRES_COMMAND_OK) {
    65. + // XXX: do we need to setNumber() here?
    66. setLastError(qMakeError(tr("Unable to unsubscribe"), QSqlError::StatementError, d));
    67. return false;
    68. }
    To copy to clipboard, switch view to plain text mode 
    Attached Files Attached Files

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: [patch] QPSQL: set an error code so QSqlError::number() gives a useful value

    Try sending the patch to Trolls via Task-Tracker.
    J-P Nurmi

  3. #3
    Join Date
    Aug 2007
    Location
    Fresno - Colombia
    Posts
    26
    Qt products
    Qt4
    Platforms
    Unix/X11

    Unhappy Re: [patch] QPSQL: set an error code so QSqlError::number() gives a useful value

    The problem persist on Qt4.7.4, could you please guide me for apply this patch?

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.