summaryrefslogtreecommitdiff
path: root/odb/relational/common.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/relational/common.hxx')
-rw-r--r--odb/relational/common.hxx189
1 files changed, 186 insertions, 3 deletions
diff --git a/odb/relational/common.hxx b/odb/relational/common.hxx
index d552a72..276868c 100644
--- a/odb/relational/common.hxx
+++ b/odb/relational/common.hxx
@@ -42,7 +42,7 @@ namespace relational
protected:
// For virtual inheritance only. Should not be actually called.
//
- member_base (); // {assert (false);}
+ member_base ();
protected:
string var_override_;
@@ -51,6 +51,176 @@ namespace relational
string key_prefix_;
};
+ // Template argument is the database SQL type (sql_type).
+ //
+ template <typename T>
+ struct member_base_impl: virtual member_base
+ {
+ typedef member_base_impl base_impl;
+
+ member_base_impl (base const& x): base (x) {}
+
+ protected:
+ member_base_impl () {}
+
+ public:
+ virtual T const&
+ member_sql_type (semantics::data_member&) = 0;
+
+ virtual void
+ traverse (semantics::data_member&);
+
+ struct member_info
+ {
+ semantics::data_member& m; // Member.
+ semantics::type& t; // Cvr-unqualified member C++ type, note
+ // that m.type () may not be the same as t.
+ semantics::class_* ptr; // Pointed-to object if m is an object
+ // pointer. In this case t is the id type
+ // while fq_type_ is the pointer fq-type.
+ semantics::type* wrapper; // Wrapper type if member is a composite or
+ // container wrapper, also cvr-unqualified.
+ // In this case t is the wrapped type.
+ bool cq; // True if the original (wrapper) type
+ // is const-qualified.
+ T const* st; // Member SQL type (only simple values).
+ string& var; // Member variable name with trailing '_'.
+
+ // C++ type fq-name.
+ //
+ string
+ fq_type (bool unwrap = true) const
+ {
+ semantics::names* hint;
+
+ if (wrapper != 0 && unwrap)
+ {
+ // Use the hint from the wrapper unless the wrapped type
+ // is qualified.
+ //
+ hint = wrapper->get<semantics::names*> ("wrapper-hint");
+ utype (*context::wrapper (*wrapper), hint);
+ return t.fq_name (hint);
+ }
+
+ // Use the original type from 'm' instead of 't' since the hint may
+ // be invalid for a different type. Plus, if a type is overriden,
+ // then the fq_type must be as well.
+ //
+ if (ptr != 0)
+ {
+ semantics::type& t (utype (*id_member (*ptr), hint));
+ return t.fq_name (hint);
+ }
+ else if (fq_type_.empty ())
+ {
+ semantics::type& t (utype (m, hint));
+ return t.fq_name (hint);
+ }
+ else
+ return fq_type_;
+ }
+
+ string
+ ptr_fq_type () const
+ {
+ assert (ptr != 0);
+
+ if (fq_type_.empty ())
+ {
+ // If type is overridden so should fq_type so it is safe to
+ // get the type from the member.
+ //
+ semantics::names* hint;
+ semantics::type& t (utype (m, hint));
+ return t.fq_name (hint);
+ }
+ else
+ return fq_type_;
+ }
+
+ string const& fq_type_;
+
+ member_info (semantics::data_member& m_,
+ semantics::type& t_,
+ semantics::type* wrapper_,
+ bool cq_,
+ string& var_,
+ string const& fq_type)
+ : m (m_),
+ t (t_),
+ ptr (0),
+ wrapper (wrapper_),
+ cq (cq_),
+ st (0),
+ var (var_),
+ fq_type_ (fq_type)
+ {
+ }
+ };
+
+ bool
+ container (member_info& mi)
+ {
+ // This cannot be a container if we have a type override.
+ //
+ return type_override_ == 0 && context::container (mi.m);
+ }
+
+ // The false return value indicates that no further callbacks
+ // should be called for this member.
+ //
+ virtual bool
+ pre (member_info&)
+ {
+ return true;
+ }
+
+ virtual void
+ post (member_info&)
+ {
+ }
+
+ virtual void
+ traverse_composite (member_info&)
+ {
+ }
+
+ virtual void
+ traverse_container (member_info&)
+ {
+ }
+
+ // Note that by default traverse_object_pointer() will traverse the
+ // pointed-to object id type.
+ //
+ virtual void
+ traverse_object_pointer (member_info&);
+
+ virtual void
+ traverse_simple (member_info&) = 0;
+ };
+
+ //
+ //
+ struct member_database_type_id: virtual member_base
+ {
+ typedef member_database_type_id base;
+
+ member_database_type_id (semantics::type* type = 0,
+ string const& fq_type = string (),
+ string const& key_prefix = string ())
+ : member_base (type, fq_type, key_prefix)
+ {
+ }
+
+ virtual string
+ database_type_id (semantics::data_member&)
+ {
+ assert (false);
+ }
+ };
+
//
//
struct query_columns_base: object_columns_base, virtual context
@@ -66,8 +236,8 @@ namespace relational
virtual void
traverse_composite (semantics::data_member*, semantics::class_&);
- virtual bool
- traverse_column (semantics::data_member&, string const&, bool);
+ virtual void
+ traverse_pointer (semantics::data_member&, semantics::class_&);
protected:
bool decl_;
@@ -103,13 +273,24 @@ namespace relational
virtual void
traverse_composite (semantics::data_member*, semantics::class_&);
+ virtual void
+ column_common (semantics::data_member&,
+ string const& type,
+ string const& column,
+ string const& suffix = "_type_");
+
virtual bool
traverse_column (semantics::data_member&, string const&, bool);
+ virtual void
+ traverse_pointer (semantics::data_member&, semantics::class_&);
+
protected:
bool ptr_;
bool decl_;
+ bool in_ptr_; // True if we are "inside" an object pointer.
+
string scope_;
string table_;
string default_table_;
@@ -349,4 +530,6 @@ namespace relational
}
}
+#include <odb/relational/common.txx>
+
#endif // ODB_RELATIONAL_COMMON_HXX