diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2013-05-06 12:05:39 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2013-08-14 15:18:23 +0200 |
commit | 91830e3bd38a05c73d03a5dfb88997799d44274b (patch) | |
tree | 399f1fc61ce959ac63b8b7ebaf5e3c58f80d8a7d /odb/polymorphic-info.hxx | |
parent | 72b262ee4f375089256f6438152bd323df1ff5a3 (diff) |
Add support for object sections
Sections are an optimization mechanism that allows the partitioning of
data members of a persistent class into groups that can be separately
loaded and/or updated.
Diffstat (limited to 'odb/polymorphic-info.hxx')
-rw-r--r-- | odb/polymorphic-info.hxx | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/odb/polymorphic-info.hxx b/odb/polymorphic-info.hxx index 2011133..7762525 100644 --- a/odb/polymorphic-info.hxx +++ b/odb/polymorphic-info.hxx @@ -7,9 +7,10 @@ #include <odb/pre.hxx> +#include <cstddef> // std::size_t #include <typeinfo> -#include <odb/forward.hxx> // database +#include <odb/forward.hxx> // database, connection #include <odb/traits.hxx> namespace odb @@ -17,9 +18,20 @@ namespace odb template <typename R> struct polymorphic_abstract_info { + typedef void (*section_load) (odb::connection&, R&, bool top); + typedef void (*section_update) (odb::connection&, const R&); + + struct section_functions + { + section_load load; + section_update update; + }; + + public: polymorphic_abstract_info (const std::type_info& t, - const polymorphic_abstract_info* b) - : type (t), base (b) {} + const polymorphic_abstract_info* b, + const section_functions* s) + : type (t), base (b), sections (s) {} bool derived (const polymorphic_abstract_info& b) const @@ -31,9 +43,48 @@ namespace odb return false; } + // Find the "most overridden" section functions. + // + section_load + find_section_load (std::size_t index) const + { + for (const polymorphic_abstract_info* b (this); b != 0; b = b->base) + if (b->sections != 0 && b->sections[index].load != 0) + return b->sections[index].load; + + return 0; + } + + section_update + find_section_update (std::size_t index) const + { + for (const polymorphic_abstract_info* b (this); b != 0; b = b->base) + if (b->sections != 0 && b->sections[index].update != 0) + return b->sections[index].update; + + return 0; + } + + bool + final_section_update (const polymorphic_abstract_info& i, + std::size_t index) const + { + return i.sections != 0 && + i.sections[index].update != 0 && + i.sections[index].update == find_section_update (index); + } + public: const std::type_info& type; const polymorphic_abstract_info* base; + + // Sections. + // + // There could be "concrete" (i.e., not overridden) section in an + // abstract class. Which means the section table has to be in + // abstract_info. + // + const section_functions* sections; }; template <typename R> @@ -47,6 +98,9 @@ namespace odb typedef typename root_traits::pointer_type pointer_type; typedef typename root_traits::discriminator_type discriminator_type; + typedef typename polymorphic_abstract_info<R>::section_functions + section_functions; + enum call_type { call_callback, // arg points to callback event. @@ -67,11 +121,12 @@ namespace odb public: polymorphic_concrete_info (const std::type_info& t, const polymorphic_abstract_info<R>* b, + const section_functions* s, const discriminator_type& d, create_function cf, dispatch_function df, delayed_loader_function dlf) - : polymorphic_abstract_info<R> (t, b), + : polymorphic_abstract_info<R> (t, b, s), discriminator (d), create (cf), dispatch (df), delayed_loader (dlf) { |