summaryrefslogtreecommitdiff
path: root/libodb/odb/exceptions.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libodb/odb/exceptions.cxx')
-rw-r--r--libodb/odb/exceptions.cxx430
1 files changed, 430 insertions, 0 deletions
diff --git a/libodb/odb/exceptions.cxx b/libodb/odb/exceptions.cxx
new file mode 100644
index 0000000..bb13b6c
--- /dev/null
+++ b/libodb/odb/exceptions.cxx
@@ -0,0 +1,430 @@
+// file : odb/exceptions.cxx
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#include <cstring> // std::strlen
+#include <sstream>
+#include <cassert>
+
+#include <odb/exceptions.hxx>
+
+using namespace std;
+
+namespace odb
+{
+ const char* null_pointer::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "NULL pointer";
+ }
+
+ null_pointer* null_pointer::
+ clone () const
+ {
+ return new null_pointer (*this);
+ }
+
+ const char* already_in_transaction::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "transaction already in progress in this thread";
+ }
+
+ already_in_transaction* already_in_transaction::
+ clone () const
+ {
+ return new already_in_transaction (*this);
+ }
+
+ const char* not_in_transaction::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "operation can only be performed in transaction";
+ }
+
+ not_in_transaction* not_in_transaction::
+ clone () const
+ {
+ return new not_in_transaction (*this);
+ }
+
+ const char* transaction_already_finalized::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "transaction already committed or rolled back";
+ }
+
+ transaction_already_finalized* transaction_already_finalized::
+ clone () const
+ {
+ return new transaction_already_finalized (*this);
+ }
+
+ const char* already_in_session::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "session already in effect in this thread";
+ }
+
+ already_in_session* already_in_session::
+ clone () const
+ {
+ return new already_in_session (*this);
+ }
+
+ const char* not_in_session::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "session not in effect in this thread";
+ }
+
+ not_in_session* not_in_session::
+ clone () const
+ {
+ return new not_in_session (*this);
+ }
+
+ const char* session_required::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "session required to load this object relationship";
+ }
+
+ session_required* session_required::
+ clone () const
+ {
+ return new session_required (*this);
+ }
+
+ const char* deadlock::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "transaction aborted due to deadlock";
+ }
+
+ deadlock* deadlock::
+ clone () const
+ {
+ return new deadlock (*this);
+ }
+
+ const char* connection_lost::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "connection to database lost";
+ }
+
+ connection_lost* connection_lost::
+ clone () const
+ {
+ return new connection_lost (*this);
+ }
+
+ const char* timeout::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "database operation timeout";
+ }
+
+ timeout* timeout::
+ clone () const
+ {
+ return new timeout (*this);
+ }
+
+ const char* object_not_persistent::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "object not persistent";
+ }
+
+ object_not_persistent* object_not_persistent::
+ clone () const
+ {
+ return new object_not_persistent (*this);
+ }
+
+ const char* object_already_persistent::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "object already persistent";
+ }
+
+ object_already_persistent* object_already_persistent::
+ clone () const
+ {
+ return new object_already_persistent (*this);
+ }
+
+ const char* object_changed::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "object changed concurrently";
+ }
+
+ object_changed* object_changed::
+ clone () const
+ {
+ return new object_changed (*this);
+ }
+
+ const char* result_not_cached::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "query result is not cached";
+ }
+
+ result_not_cached* result_not_cached::
+ clone () const
+ {
+ return new result_not_cached (*this);
+ }
+
+ const char* abstract_class::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "database operation on instance of abstract class";
+ }
+
+ abstract_class* abstract_class::
+ clone () const
+ {
+ return new abstract_class (*this);
+ }
+
+ const char* no_type_info::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "no type information";
+ }
+
+ no_type_info* no_type_info::
+ clone () const
+ {
+ return new no_type_info (*this);
+ }
+
+ prepared_already_cached::
+ prepared_already_cached (const char* name)
+ : name_ (name)
+ {
+ what_ = "prepared query '";
+ what_ += name;
+ what_ += "' is already cached";
+ }
+
+ prepared_already_cached::
+ ~prepared_already_cached () ODB_NOTHROW_NOEXCEPT
+ {
+ }
+
+ const char* prepared_already_cached::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return what_.c_str ();
+ }
+
+ prepared_already_cached* prepared_already_cached::
+ clone () const
+ {
+ return new prepared_already_cached (*this);
+ }
+
+ prepared_type_mismatch::
+ prepared_type_mismatch (const char* name)
+ : name_ (name)
+ {
+ what_ = "type mismatch while looking up prepared query '";
+ what_ += name;
+ what_ += "'";
+ }
+
+ prepared_type_mismatch::
+ ~prepared_type_mismatch () ODB_NOTHROW_NOEXCEPT
+ {
+ }
+
+ const char* prepared_type_mismatch::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return what_.c_str ();
+ }
+
+ prepared_type_mismatch* prepared_type_mismatch::
+ clone () const
+ {
+ return new prepared_type_mismatch (*this);
+ }
+
+ unknown_schema::
+ unknown_schema (const string& name)
+ : name_ (name)
+ {
+ what_ = "unknown database schema '";
+ what_ += name;
+ what_ += "'";
+ }
+
+ unknown_schema::
+ ~unknown_schema () ODB_NOTHROW_NOEXCEPT
+ {
+ }
+
+ const char* unknown_schema::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return what_.c_str ();
+ }
+
+ unknown_schema* unknown_schema::
+ clone () const
+ {
+ return new unknown_schema (*this);
+ }
+
+ unknown_schema_version::
+ unknown_schema_version (schema_version v)
+ : version_ (v)
+ {
+ ostringstream os;
+ os << v;
+ what_ = "unknown database schema version ";
+ what_ += os.str ();
+ }
+
+ unknown_schema_version::
+ ~unknown_schema_version () ODB_NOTHROW_NOEXCEPT
+ {
+ }
+
+ const char* unknown_schema_version::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return what_.c_str ();
+ }
+
+ unknown_schema_version* unknown_schema_version::
+ clone () const
+ {
+ return new unknown_schema_version (*this);
+ }
+
+ const char* section_not_loaded::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "section is not loaded";
+ }
+
+ section_not_loaded* section_not_loaded::
+ clone () const
+ {
+ return new section_not_loaded (*this);
+ }
+
+ const char* section_not_in_object::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return "section instance is not part of an object (section was copied?)";
+ }
+
+ section_not_in_object* section_not_in_object::
+ clone () const
+ {
+ return new section_not_in_object (*this);
+ }
+
+ // multiple_exceptions
+ //
+ multiple_exceptions::
+ ~multiple_exceptions () ODB_NOTHROW_NOEXCEPT {}
+
+ void multiple_exceptions::
+ insert (size_t p, bool maybe, const odb::exception& e, bool fatal)
+ {
+ details::shared_ptr<odb::exception> pe;
+
+ if (common_exception_ti_ != typeid (e))
+ pe.reset (e.clone ());
+ else
+ {
+ if (common_exception_ == 0)
+ common_exception_.reset (e.clone ());
+
+ pe = common_exception_;
+ }
+
+ set_.insert (value_type (delta_ + p, maybe, pe));
+ fatal_ = fatal_ || fatal;
+ }
+
+ const multiple_exceptions::value_type* multiple_exceptions::
+ lookup (size_t p) const
+ {
+ p += delta_; // Called while populating multiple_exceptions.
+
+ iterator i (set_.find (value_type (p)));
+ return i == set_.end () ? 0 : &*i;
+ }
+
+ void multiple_exceptions::
+ prepare ()
+ {
+ current_ = 0;
+ delta_ = 0;
+ common_exception_.reset ();
+
+ ostringstream os;
+ os << "multiple exceptions, "
+ << attempted_ << " element" << (attempted_ != 1 ? "s" : "") <<
+ " attempted, "
+ << failed () << " failed"
+ << (fatal_ ? ", fatal" : "") << ":";
+
+ for (iterator i (begin ()); i != end ();)
+ {
+ size_t p (i->position ());
+ const odb::exception& e (i->exception ());
+
+ os << '\n';
+
+ if (!i->maybe ())
+ {
+ os << '[' << p << ']';
+ ++i;
+ }
+ else
+ {
+ // In this case we will normally have a large number of maybe
+ // failures in a row (usually the whole batch). So let's try
+ // to represent them all as a single range.
+ //
+ size_t n (0);
+ for (++i; i != end () && i->maybe (); ++i)
+ {
+ assert (&e == &i->exception ()); // The same common exception.
+ n++;
+ }
+
+ if (n == 0)
+ os << '[' << p << ']';
+ else
+ os << '[' << p << '-' << (p + n) << "] (some)";
+ }
+
+ os << ' ' << e.what ();
+ }
+
+ what_ = os.str ();
+ }
+
+ const char* multiple_exceptions::
+ what () const ODB_NOTHROW_NOEXCEPT
+ {
+ return what_.c_str ();
+ }
+
+ multiple_exceptions* multiple_exceptions::
+ clone () const
+ {
+ return new multiple_exceptions (*this);
+ }
+}