aboutsummaryrefslogtreecommitdiff
path: root/odb/polymorphic-info.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-05-06 12:05:39 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-08-14 15:18:23 +0200
commit91830e3bd38a05c73d03a5dfb88997799d44274b (patch)
tree399f1fc61ce959ac63b8b7ebaf5e3c58f80d8a7d /odb/polymorphic-info.hxx
parent72b262ee4f375089256f6438152bd323df1ff5a3 (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.hxx63
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)
{