summaryrefslogtreecommitdiff
path: root/libodb/odb/exceptions.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libodb/odb/exceptions.hxx')
-rw-r--r--libodb/odb/exceptions.hxx523
1 files changed, 523 insertions, 0 deletions
diff --git a/libodb/odb/exceptions.hxx b/libodb/odb/exceptions.hxx
new file mode 100644
index 0000000..d283010
--- /dev/null
+++ b/libodb/odb/exceptions.hxx
@@ -0,0 +1,523 @@
+// file : odb/exceptions.hxx
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_EXCEPTIONS_HXX
+#define ODB_EXCEPTIONS_HXX
+
+#include <odb/pre.hxx>
+
+#include <set>
+#include <string>
+#include <cstddef> // std::size_t
+#include <typeinfo>
+
+#include <odb/forward.hxx> // schema_version, odb::core
+#include <odb/exception.hxx>
+
+#include <odb/details/config.hxx> // ODB_NOTHROW_NOEXCEPT
+#include <odb/details/export.hxx>
+#include <odb/details/shared-ptr.hxx>
+
+namespace odb
+{
+ struct LIBODB_EXPORT null_pointer: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual null_pointer*
+ clone () const;
+ };
+
+ // Transaction exceptions.
+ //
+ struct LIBODB_EXPORT already_in_transaction: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual already_in_transaction*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT not_in_transaction: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual not_in_transaction*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT transaction_already_finalized: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual transaction_already_finalized*
+ clone () const;
+ };
+
+ // Session exceptions.
+ //
+ struct LIBODB_EXPORT already_in_session: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual already_in_session*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT not_in_session: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual not_in_session*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT session_required: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual session_required*
+ clone () const;
+ };
+
+ // Database operations exceptions.
+ //
+ struct LIBODB_EXPORT recoverable: odb::exception
+ {
+ // Abstract.
+ };
+
+ struct LIBODB_EXPORT connection_lost: recoverable
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual connection_lost*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT timeout: recoverable
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual timeout*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT deadlock: recoverable
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual deadlock*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT object_not_persistent: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual object_not_persistent*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT object_already_persistent: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual object_already_persistent*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT object_changed: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual object_changed*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT result_not_cached: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual result_not_cached*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT database_exception: odb::exception
+ {
+ // Abstract.
+ };
+
+ // Polymorphism support exceptions.
+ //
+ struct LIBODB_EXPORT abstract_class: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual abstract_class*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT no_type_info: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual no_type_info*
+ clone () const;
+ };
+
+ // Prepared query support exceptions.
+ //
+ struct LIBODB_EXPORT prepared_already_cached: odb::exception
+ {
+ prepared_already_cached (const char* name);
+ ~prepared_already_cached () ODB_NOTHROW_NOEXCEPT;
+
+ const char*
+ name () const
+ {
+ return name_;
+ }
+
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual prepared_already_cached*
+ clone () const;
+
+ private:
+ const char* name_;
+ std::string what_;
+ };
+
+ struct LIBODB_EXPORT prepared_type_mismatch: odb::exception
+ {
+ prepared_type_mismatch (const char* name);
+ ~prepared_type_mismatch () ODB_NOTHROW_NOEXCEPT;
+
+ const char*
+ name () const {return name_;}
+
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual prepared_type_mismatch*
+ clone () const;
+
+ private:
+ const char* name_;
+ std::string what_;
+ };
+
+ // Schema catalog exceptions.
+ //
+ struct LIBODB_EXPORT unknown_schema: odb::exception
+ {
+ unknown_schema (const std::string& name);
+ ~unknown_schema () ODB_NOTHROW_NOEXCEPT;
+
+ const std::string&
+ name () const {return name_;}
+
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual unknown_schema*
+ clone () const;
+
+ private:
+ std::string name_;
+ std::string what_;
+ };
+
+ struct LIBODB_EXPORT unknown_schema_version: odb::exception
+ {
+ unknown_schema_version (schema_version);
+ ~unknown_schema_version () ODB_NOTHROW_NOEXCEPT;
+
+ schema_version
+ version () const {return version_;}
+
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual unknown_schema_version*
+ clone () const;
+
+ private:
+ schema_version version_;
+ std::string what_;
+ };
+
+ // Section exceptions.
+ //
+ struct LIBODB_EXPORT section_not_loaded: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual section_not_loaded*
+ clone () const;
+ };
+
+ struct LIBODB_EXPORT section_not_in_object: odb::exception
+ {
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual section_not_in_object*
+ clone () const;
+ };
+
+ // Bulk operation exceptions.
+ //
+ struct LIBODB_EXPORT multiple_exceptions: odb::exception
+ {
+ struct value_type
+ {
+ std::size_t
+ position () const {return p_;}
+
+ // If true, then this means that some positions in the batch have
+ // triggered the exception but it is not possible, due to the
+ // limitations of the underlying database API, to discern exactly
+ // which ones. As a result, all the positions in the batch are
+ // marked as "maybe failed".
+ //
+ bool
+ maybe () const {return m_;}
+
+ const odb::exception&
+ exception () const {return *e_;}
+
+ // Implementation details.
+ //
+ public:
+ value_type (std::size_t p,
+ bool maybe,
+ details::shared_ptr<odb::exception> e)
+ : m_ (maybe), p_ (p), e_ (e) {}
+
+ value_type (std::size_t p): p_ (p) {} // "Key" for set lookup.
+
+ private:
+ bool m_;
+ std::size_t p_;
+ details::shared_ptr<odb::exception> e_;
+ };
+
+ struct comparator_type
+ {
+ bool
+ operator() (const value_type& x, const value_type& y) const
+ {
+ return x.position () < y.position ();
+ }
+ };
+
+ typedef std::set<value_type, comparator_type> set_type;
+
+ // Iteration.
+ //
+ public:
+ typedef set_type::const_iterator iterator;
+ typedef set_type::const_iterator const_iterator; // For pedantic types.
+
+ iterator
+ begin () const {return set_.begin ();}
+
+ iterator
+ end () const {return set_.end ();}
+
+ // Lookup.
+ //
+ public:
+ // Return NULL if the element at this position has no exception. Note
+ // that the returned value is value_type* and not odb::exception* in
+ // order to provide access to maybe(); see value_type::maybe() for
+ // details.
+ //
+ const value_type*
+ operator[] (std::size_t p) const
+ {
+ return set_.empty () ? 0 : lookup (p);
+ }
+
+ // Severity, failed and attempt counts.
+ //
+ public:
+ // Return the number of elements for which the operation has been
+ // attempted.
+ //
+ std::size_t
+ attempted () const {return attempted_;}
+
+ // Return the number of positions for which the operation has failed.
+ // Note that this count includes the maybe failed positions.
+ //
+ std::size_t
+ failed () const {return set_.size ();}
+
+ // If fatal() returns true, then (some of) the exceptions were fatal.
+ // In this case, even for elements that were processed but did not
+ // cause the exception, no attempts were made to complete the bulk
+ // operation and the transaction must be aborted.
+ //
+ // If fatal() returns false, then the operation on the elements that
+ // don't have an exception has succeeded. The application can try to
+ // correct the errors and re-attempt the operation on the elements
+ // that did cause an exception. In either case, the transaction can
+ // be committed.
+ //
+ bool
+ fatal () const {return fatal_;}
+
+ // Normally you shouldn't need to do this explicitly but you can
+ // "upgrade" an exception to fatal, for example, for specific
+ // database error codes.
+ //
+ void
+ fatal (bool f) {fatal_ = fatal_ || f;}
+
+ // odb::exception interface.
+ //
+ public:
+ virtual const char*
+ what () const ODB_NOTHROW_NOEXCEPT;
+
+ virtual multiple_exceptions*
+ clone () const;
+
+ // Direct set access.
+ //
+ public:
+ const set_type&
+ set () const {return set_;}
+
+ // Implementation details.
+ //
+ public:
+ ~multiple_exceptions () ODB_NOTHROW_NOEXCEPT;
+
+ // All instances of the common exception must be equal since we are
+ // going to create and share just one.
+ //
+ multiple_exceptions (const std::type_info& common_exception_ti)
+ : common_exception_ti_ (common_exception_ti),
+ fatal_ (false),
+ delta_ (0),
+ current_ (0) {}
+
+ // Set the attempted count as (delta + n).
+ //
+ void
+ attempted (std::size_t n) {attempted_ = delta_ + n;}
+
+ // Increment the position of the current batch. Also resets the
+ // current position in the batch.
+ //
+ void
+ delta (std::size_t d) {delta_ += d; current_ = 0;}
+
+ // Current position in the batch.
+ //
+ std::size_t
+ current () const {return current_;}
+
+ void
+ current (std::size_t c) {current_ = c;}
+
+ void
+ insert (std::size_t p,
+ bool maybe,
+ const odb::exception& e,
+ bool fatal = false);
+
+ void
+ insert (std::size_t p, const odb::exception& e, bool fatal = false)
+ {
+ insert (p, false, e, fatal);
+ }
+
+ void
+ insert (const odb::exception& e, bool fatal = false)
+ {
+ insert (current_, e, fatal);
+ }
+
+ bool
+ empty () const {return set_.empty ();}
+
+ void
+ prepare ();
+
+ private:
+ const value_type*
+ lookup (std::size_t p) const;
+
+ private:
+ const std::type_info& common_exception_ti_;
+ details::shared_ptr<odb::exception> common_exception_;
+
+ set_type set_;
+ bool fatal_;
+ std::size_t attempted_;
+ std::size_t delta_; // Position of the batch.
+ std::size_t current_; // Position in the batch.
+ std::string what_;
+ };
+
+ namespace common
+ {
+ using odb::null_pointer;
+
+ using odb::already_in_transaction;
+ using odb::not_in_transaction;
+ using odb::transaction_already_finalized;
+
+ using odb::already_in_session;
+ using odb::not_in_session;
+ using odb::session_required;
+
+ using odb::recoverable;
+ using odb::deadlock;
+ using odb::connection_lost;
+ using odb::timeout;
+ using odb::object_not_persistent;
+ using odb::object_already_persistent;
+ using odb::object_changed;
+ using odb::result_not_cached;
+ using odb::database_exception;
+
+ using odb::abstract_class;
+ using odb::no_type_info;
+
+ using odb::unknown_schema;
+ using odb::unknown_schema_version;
+
+ using odb::section_not_loaded;
+ using odb::section_not_in_object;
+
+ using odb::multiple_exceptions;
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_EXCEPTIONS_HXX