aboutsummaryrefslogtreecommitdiff
path: root/odb/sqlite/error.cxx
blob: 610742725f08573e0430863674fb1b07bd9b1222 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// file      : odb/sqlite/error.cxx
// copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC
// license   : GNU GPL v2; see accompanying LICENSE file

#include <sqlite3.h>

#include <new>    // std::bad_alloc
#include <string>

#include <odb/sqlite/connection.hxx>
#include <odb/sqlite/exceptions.hxx>

#include <odb/sqlite/details/config.hxx> // LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY

using namespace std;

namespace odb
{
  namespace sqlite
  {
    void
    translate_error (int e, connection& c)
    {
      sqlite3* h (c.handle ());

      // Extended error codes are only available in 3.6.5 and later.
      //
#if SQLITE_VERSION_NUMBER >= 3006005
      int ee (sqlite3_extended_errcode (h));
#else
      int ee (0);
#endif
      string m;

      switch (e)
      {
      case SQLITE_NOMEM:
        {
          throw bad_alloc ();
        }
      case SQLITE_MISUSE:
        {
          // In case of SQLITE_MISUSE, error code/message may or may not
          // be set.
          //
          ee = e;
          m = "SQLite API misuse";
          break;
        }
#ifdef SQLITE_ABORT_ROLLBACK
      case SQLITE_ABORT:
        {
          if (ee == SQLITE_ABORT_ROLLBACK)
            throw forced_rollback ();

          break;
        }
#endif
      case SQLITE_LOCKED:
        {
#ifdef LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY
          if (ee != SQLITE_LOCKED_SHAREDCACHE)
            throw deadlock (); // The DROP TABLE special case.
#endif
          // Getting SQLITE_LOCKED_SHAREDCACHE here means we don't have
          // the unlock notify support. Translate this to timeout.
          //
          throw timeout ();
        }
      case SQLITE_BUSY:
      case SQLITE_IOERR:
        {
#if SQLITE_VERSION_NUMBER >= 3006005
          if (e != SQLITE_IOERR || ee == SQLITE_IOERR_BLOCKED)
            throw timeout ();
#endif
          break;
        }
      default:
        break;
      }

      if (m.empty ())
        m = sqlite3_errmsg (h);

      throw database_exception (e, ee, m);
    }
  }
}