diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-01-12 10:46:55 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-01-12 10:46:55 +0200 |
commit | df1fdb4f500308adf2fff1a08b2ef62bf5a88de7 (patch) | |
tree | 1a014a6207bba19a58a8b574c6bb00b881585d13 | |
parent | bbb153b9e576cdfdb59711f68d7f26a427a55041 (diff) |
Detect and throw when object/view with long data is re-loaded from query result
-rw-r--r-- | odb/mssql/exceptions.cxx | 11 | ||||
-rw-r--r-- | odb/mssql/exceptions.hxx | 6 | ||||
-rw-r--r-- | odb/mssql/object-result.hxx | 2 | ||||
-rw-r--r-- | odb/mssql/object-result.txx | 15 | ||||
-rw-r--r-- | odb/mssql/statement.hxx | 9 | ||||
-rw-r--r-- | odb/mssql/view-result.hxx | 1 | ||||
-rw-r--r-- | odb/mssql/view-result.txx | 9 |
7 files changed, 46 insertions, 7 deletions
diff --git a/odb/mssql/exceptions.cxx b/odb/mssql/exceptions.cxx index 1b415a7..f14fc59 100644 --- a/odb/mssql/exceptions.cxx +++ b/odb/mssql/exceptions.cxx @@ -78,5 +78,16 @@ namespace odb { return what_.c_str (); } + + // + // long_data_reload + // + + const char* long_data_reload:: + what () const throw () + { + return "attempt to re-load object or view with long data " + "from query result"; + } } } diff --git a/odb/mssql/exceptions.hxx b/odb/mssql/exceptions.hxx index 3e7a845..b31a83d 100644 --- a/odb/mssql/exceptions.hxx +++ b/odb/mssql/exceptions.hxx @@ -108,6 +108,12 @@ namespace odb private: std::string what_; }; + + struct LIBODB_MSSQL_EXPORT long_data_reload: odb::exception + { + virtual const char* + what () const throw (); + }; } } diff --git a/odb/mssql/object-result.hxx b/odb/mssql/object-result.hxx index 9eaa4f5..6380993 100644 --- a/odb/mssql/object-result.hxx +++ b/odb/mssql/object-result.hxx @@ -67,6 +67,7 @@ namespace odb private: details::shared_ptr<select_statement> statement_; object_statements<object_type>& statements_; + bool can_load_; bool use_copy_; typename object_traits::image_type* image_copy_; }; @@ -113,6 +114,7 @@ namespace odb private: details::shared_ptr<select_statement> statement_; object_statements_no_id<object_type>& statements_; + bool can_load_; bool use_copy_; typename object_traits::image_type* image_copy_; }; diff --git a/odb/mssql/object-result.txx b/odb/mssql/object-result.txx index 338f78a..161978e 100644 --- a/odb/mssql/object-result.txx +++ b/odb/mssql/object-result.txx @@ -6,8 +6,9 @@ #include <cassert> #include <odb/callback.hxx> -#include <odb/exceptions.hxx> +#include <odb/exceptions.hxx> // result_not_cached +#include <odb/mssql/exceptions.hxx> // long_data_reload #include <odb/mssql/object-statements.hxx> namespace odb @@ -50,6 +51,9 @@ namespace odb void object_result_impl<T>:: load (object_type& obj, bool) { + if (!can_load_) + throw long_data_reload (); + // This is a top-level call so the statements cannot be locked. // assert (!statements_.locked ()); @@ -66,7 +70,7 @@ namespace odb // If we are using a copy, make sure the callback information for // long data also comes from the copy. // - statement_->stream_result ( + can_load_ = !statement_->stream_result ( use_copy_ ? &statements_.image () : 0, use_copy_ ? image_copy_ : 0); @@ -103,6 +107,7 @@ namespace odb void object_result_impl<T>:: next () { + can_load_ = true; this->current (pointer_type ()); typename object_traits::image_type& im (statements_.image ()); @@ -200,6 +205,9 @@ namespace odb void object_result_impl_no_id<T>:: load (object_type& obj) { + if (!can_load_) + throw long_data_reload (); + odb::database& db (this->database ()); object_traits::callback (db, obj, callback_event::pre_load); @@ -211,7 +219,7 @@ namespace odb // If we are using a copy, make sure the callback information for // long data also comes from the copy. // - statement_->stream_result ( + can_load_ = !statement_->stream_result ( use_copy_ ? &statements_.image () : 0, use_copy_ ? image_copy_ : 0); @@ -222,6 +230,7 @@ namespace odb void object_result_impl_no_id<T>:: next () { + can_load_ = true; this->current (pointer_type ()); typename object_traits::image_type& im (statements_.image ()); diff --git a/odb/mssql/statement.hxx b/odb/mssql/statement.hxx index 3bea55f..6eacec6 100644 --- a/odb/mssql/statement.hxx +++ b/odb/mssql/statement.hxx @@ -122,15 +122,20 @@ namespace odb result fetch (); - void + // Return true if any long data was streamed. + // + bool stream_result (void* old_base = 0, void* new_base = 0) { - if (first_long_ != result_.count) + bool ld (first_long_ != result_.count); + + if (ld) statement::stream_result (result_.bind, first_long_, result_.count, old_base, new_base); + return ld; } void diff --git a/odb/mssql/view-result.hxx b/odb/mssql/view-result.hxx index e4a523a..cf3dde1 100644 --- a/odb/mssql/view-result.hxx +++ b/odb/mssql/view-result.hxx @@ -63,6 +63,7 @@ namespace odb private: details::shared_ptr<select_statement> statement_; view_statements<view_type>& statements_; + bool can_load_; bool use_copy_; typename view_traits::image_type* image_copy_; }; diff --git a/odb/mssql/view-result.txx b/odb/mssql/view-result.txx index 4b5053d..3d86206 100644 --- a/odb/mssql/view-result.txx +++ b/odb/mssql/view-result.txx @@ -4,8 +4,9 @@ // license : ODB NCUEL; see accompanying LICENSE file #include <odb/callback.hxx> -#include <odb/exceptions.hxx> +#include <odb/exceptions.hxx> // result_not_cached +#include <odb/mssql/exceptions.hxx> // long_data_reload #include <odb/mssql/view-statements.hxx> namespace odb @@ -44,6 +45,9 @@ namespace odb void view_result_impl<T>:: load (view_type& view) { + if (!can_load_) + throw long_data_reload (); + odb::database& db (this->database ()); view_traits::callback (db, view, callback_event::pre_load); @@ -55,7 +59,7 @@ namespace odb // If we are using a copy, make sure the callback information for // long data also comes from the copy. // - statement_->stream_result ( + can_load_ = !statement_->stream_result ( use_copy_ ? &statements_.image () : 0, use_copy_ ? image_copy_ : 0); @@ -66,6 +70,7 @@ namespace odb void view_result_impl<T>:: next () { + can_load_ = true; this->current (pointer_type ()); typename view_traits::image_type& im (statements_.image ()); |