aboutsummaryrefslogtreecommitdiff
path: root/odb/mysql/result.txx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/mysql/result.txx')
-rw-r--r--odb/mysql/result.txx95
1 files changed, 68 insertions, 27 deletions
diff --git a/odb/mysql/result.txx b/odb/mysql/result.txx
index 4b18abc..e3ef10b 100644
--- a/odb/mysql/result.txx
+++ b/odb/mysql/result.txx
@@ -3,6 +3,7 @@
// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
+#include <odb/exceptions.hxx>
#include <odb/cache-traits.hxx>
namespace odb
@@ -21,15 +22,18 @@ namespace odb
object_statements<object_type>& statements)
: odb::result_impl<T> (statements.connection ().database ()),
statement_ (statement),
- statements_ (statements)
+ statements_ (statements),
+ count_ (0)
{
- next ();
}
template <typename T>
void result_impl<T>::
load (object_type& obj)
{
+ if (count_ > statement_->fetched ())
+ fetch ();
+
// This is a top-level call so the statements cannot be locked.
//
assert (!statements_.locked ());
@@ -45,6 +49,9 @@ namespace odb
typename result_impl<T>::id_type result_impl<T>::
load_id ()
{
+ if (count_ > statement_->fetched ())
+ fetch ();
+
return object_traits::id (statements_.image ());
}
@@ -54,8 +61,25 @@ namespace odb
{
this->current (pointer_type ());
- // If the result was cached the image can grow between calls
- // to next() as a result of other statements execution.
+ // If we are cached, simply increment the position and
+ // postpone the actual row fetching until later. This way
+ // if the same object is loaded in between iteration, the
+ // image won't be messed up.
+ //
+ count_++;
+
+ if (statement_->cached ())
+ this->end_ = count_ > statement_->result_size ();
+ else
+ fetch ();
+ }
+
+ template <typename T>
+ void result_impl<T>::
+ fetch ()
+ {
+ // If the result is cached, the image can grow between calls
+ // to fetch() as a result of other statements execution.
//
if (statement_->cached ())
{
@@ -70,33 +94,41 @@ namespace odb
}
}
- select_statement::result r (statement_->fetch ());
-
- switch (r)
+ while (count_ > statement_->fetched ())
{
- case select_statement::truncated:
+ select_statement::result r (statement_->fetch ());
+
+ switch (r)
{
- typename object_traits::image_type& im (statements_.image ());
- object_traits::grow (im, statements_.out_image_error ());
+ case select_statement::truncated:
+ {
+ // Don't re-fetch data we are skipping.
+ //
+ if (count_ != statement_->fetched ())
+ continue;
+
+ typename object_traits::image_type& im (statements_.image ());
+ object_traits::grow (im, statements_.out_image_error ());
- if (im.version != statements_.out_image_version ())
+ if (im.version != statements_.out_image_version ())
+ {
+ binding& b (statements_.out_image_binding ());
+ object_traits::bind (b.bind, im, true);
+ statements_.out_image_version (im.version);
+ b.version++;
+ statement_->refetch ();
+ }
+ // Fall throught.
+ }
+ case select_statement::success:
{
- binding& b (statements_.out_image_binding ());
- object_traits::bind (b.bind, im, true);
- statements_.out_image_version (im.version);
- b.version++;
- statement_->refetch ();
+ break;
+ }
+ case select_statement::no_data:
+ {
+ this->end_ = true;
+ break;
}
- // Fall throught.
- }
- case select_statement::success:
- {
- break;
- }
- case select_statement::no_data:
- {
- this->end_ = true;
- break;
}
}
}
@@ -105,13 +137,22 @@ namespace odb
void result_impl<T>::
cache ()
{
- statement_->cache ();
+ if (!statement_->cached ())
+ {
+ statement_->cache ();
+
+ if (count_ >= statement_->result_size ())
+ this->end_ = true;
+ }
}
template <typename T>
std::size_t result_impl<T>::
size ()
{
+ if (!statement_->cached ())
+ throw result_not_cached ();
+
return statement_->result_size ();
}
}