From 6eed6c47b07371349bd4c30daf2b305ff7f5b1d3 Mon Sep 17 00:00:00 2001
From: Constantin Michael <constantin@codesynthesis.com>
Date: Mon, 5 Sep 2011 11:55:41 +0200
Subject: Add exceptions and error translation

---
 odb/oracle/error.cxx      | 63 ++++++++++++++++++++++++++++++++++++++++++
 odb/oracle/error.hxx      | 49 +++++++++++++++++++++++++++++++++
 odb/oracle/exceptions.cxx | 66 ++++++++++++++++++++++++++++++++++++++++++++
 odb/oracle/exceptions.hxx | 70 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 248 insertions(+)
 create mode 100644 odb/oracle/error.cxx
 create mode 100644 odb/oracle/error.hxx
 create mode 100644 odb/oracle/exceptions.cxx
 create mode 100644 odb/oracle/exceptions.hxx

diff --git a/odb/oracle/error.cxx b/odb/oracle/error.cxx
new file mode 100644
index 0000000..900e3d9
--- /dev/null
+++ b/odb/oracle/error.cxx
@@ -0,0 +1,63 @@
+// file      : odb/oracle/errors.cxx
+// author    : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license   : ODB NCUEL; see accompanying LICENSE file
+
+#include <cassert>
+
+#include <odb/details/buffer.hxx>
+
+#include <odb/oracle/error.hxx>
+#include <odb/oracle/exceptions.hxx>
+
+using namespace std;
+
+namespace odb
+{
+  namespace oracle
+  {
+    void
+    translate_error (void* h, ub4 t, sword s)
+    {
+      assert (s == OCI_ERROR || s == OCI_INVALID_HANDLE);
+
+      if (s == OCI_INVALID_HANDLE)
+        throw invalid_oci_handle ();
+
+      sb4 e;
+      details::buffer b;
+      b.capacity (128);
+
+      bool trunc (true);
+      while (trunc)
+      {
+        trunc = OCIErrorGet (h,
+                             1,
+                             0,
+                             &e,
+                             reinterpret_cast<text*> (b.data ()),
+                             b.capacity (),
+                             t) == OCI_ERROR;
+
+        if (trunc)
+          b.capacity (b.capacity () * 2);
+      }
+
+      // @@ Need to find a source of OCI specific codes.
+      //
+      // There are no symbolic definitions for error codes in the OCI
+      // header files.
+      //
+      switch (e)
+      {
+      case 60:
+        throw deadlock ();
+      case 3135:
+      case 3136:
+        throw connection_lost ();
+      default:
+        throw database_exception (e, b.data ());
+      }
+    }
+  }
+}
diff --git a/odb/oracle/error.hxx b/odb/oracle/error.hxx
new file mode 100644
index 0000000..2b83895
--- /dev/null
+++ b/odb/oracle/error.hxx
@@ -0,0 +1,49 @@
+// file      : odb/oracle/errors.hxx
+// author    : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license   : ODB NCUEL; see accompanying LICENSE file
+
+#ifndef ODB_ORACLE_ERRORS_HXX
+#define ODB_ORACLE_ERRORS_HXX
+
+#include <odb/pre.hxx>
+
+#include <oci.h>
+
+#include <odb/oracle/version.hxx>
+#include <odb/oracle/details/export.hxx>
+
+namespace odb
+{
+  namespace oracle
+  {
+    void
+    translate_error (void* h, ub4 t, sword s);
+
+    // @@ Check connection state attribute once connection has been
+    // implemented.
+    //
+
+    // Translate OCI error given an error handle and throw an appropriate
+    // exception.
+    //
+    inline LIBODB_ORACLE_EXPORT void
+    translate_error (OCIError* h, sword s)
+    {
+      translate_error (h, OCI_HTYPE_ERROR, s);
+    }
+
+    // Translate an OCI error given an environment handle error and throw
+    // an appropriate exception.
+    //
+    inline LIBODB_ORACLE_EXPORT void
+    translate_error (OCIEnv* h)
+    {
+      translate_error (h, OCI_HTYPE_ENV, OCI_ERROR);
+    }
+  }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_ORACLE_ERRORS_HXX
diff --git a/odb/oracle/exceptions.cxx b/odb/oracle/exceptions.cxx
new file mode 100644
index 0000000..903608e
--- /dev/null
+++ b/odb/oracle/exceptions.cxx
@@ -0,0 +1,66 @@
+// file      : odb/oracle/exceptions.cxx
+// author    : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license   : ODB NCUEL; see accompanying LICENSE file
+
+#include <odb/oracle/exceptions.hxx>
+
+using namespace std;
+
+namespace odb
+{
+  namespace oracle
+  {
+    //
+    // database_exception
+    //
+
+    database_exception::
+    database_exception (int error, const string& message)
+        : error_ (error), message_ (message)
+    {
+    }
+
+    database_exception::
+    ~database_exception () throw ()
+    {
+    }
+
+    const char* database_exception::
+    what () const throw ()
+    {
+      return message_.c_str ();
+    }
+
+    //
+    // cli_exception
+    //
+
+    cli_exception::
+    cli_exception (const string& what)
+        : what_ (what)
+    {
+    }
+
+    cli_exception::
+    ~cli_exception () throw ()
+    {
+    }
+
+    const char* cli_exception::
+    what () const throw ()
+    {
+      return what_.c_str ();
+    }
+
+    //
+    // invalid_oci_handle
+    //
+
+    const char* invalid_oci_handle::
+    what () const throw ()
+    {
+      return "invalid oci handle";
+    }
+  }
+}
diff --git a/odb/oracle/exceptions.hxx b/odb/oracle/exceptions.hxx
new file mode 100644
index 0000000..ae5a0e7
--- /dev/null
+++ b/odb/oracle/exceptions.hxx
@@ -0,0 +1,70 @@
+// file      : odb/oracle/exceptions.hxx
+// author    : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license   : ODB NCUEL; see accompanying LICENSE file
+
+#ifndef ODB_ORACLE_EXCEPTIONS_HXX
+#define ODB_ORACLE_EXCEPTIONS_HXX
+
+#include <odb/pre.hxx>
+
+#include <string>
+
+#include <odb/exceptions.hxx>
+
+#include <odb/oracle/version.hxx>
+#include <odb/oracle/details/export.hxx>
+
+namespace odb
+{
+  namespace oracle
+  {
+    struct LIBODB_ORACLE_EXPORT database_exception: odb::database_exception
+    {
+      database_exception (int error, const std::string& message);
+
+      ~database_exception () throw ();
+
+      int
+      error () const
+      {
+        return error_;
+      }
+
+      const std::string&
+      message () const
+      {
+        return message_;
+      }
+
+      virtual const char*
+      what () const throw ();
+
+    private:
+      int error_;
+      std::string message_;
+    };
+
+    struct LIBODB_ORACLE_EXPORT cli_exception: odb::exception
+    {
+      cli_exception (const std::string& what);
+      ~cli_exception () throw ();
+
+      virtual const char*
+      what () const throw ();
+
+    private:
+      std::string what_;
+    };
+
+    struct LIBODB_ORACLE_EXPORT invalid_oci_handle: odb::exception
+    {
+      virtual const char*
+      what () const throw ();
+    };
+  }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_ORACLE_EXCEPTIONS_HXX
-- 
cgit v1.1