aboutsummaryrefslogtreecommitdiff
path: root/odb/pgsql/error.cxx
blob: f823977023f9d23a9cc7d1358de5aca381f8b2e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// file      : odb/pgsql/error.cxx
// copyright : Copyright (c) 2005-2012 Code Synthesis Tools CC
// license   : GNU GPL v2; see accompanying LICENSE file

#include <string>
#include <cassert>

#include <odb/pgsql/error.hxx>
#include <odb/pgsql/exceptions.hxx>
#include <odb/pgsql/connection.hxx>

using namespace std;

namespace odb
{
  namespace pgsql
  {
    void
    translate_error (connection& c, PGresult* r)
    {
      if (!r)
      {
        if (CONNECTION_BAD == PQstatus (c.handle ()))
        {
          c.mark_failed ();
          throw connection_lost ();
        }
        else
          throw bad_alloc ();
      }

      const char* error_message (PQresultErrorMessage (r));

      switch (PQresultStatus (r))
      {
      case PGRES_BAD_RESPONSE:
        {
          if (error_message != 0)
            throw database_exception (error_message);
          else
            throw database_exception ("bad server response");
        }

      case PGRES_FATAL_ERROR:
        {
          const char* ss (PQresultErrorField (r, PG_DIAG_SQLSTATE));

          assert (ss);
          assert (error_message);

          // Deadlock detected.
          //
          if (std::string ("40P01") == ss)
            throw deadlock ();

          else if (CONNECTION_BAD == PQstatus (c.handle ()))
          {
            c.mark_failed ();
            throw connection_lost ();
          }
          else
            throw database_exception (ss, error_message);
        }
      default:
        assert (0);
        break;
      }
    }
  }
}