aboutsummaryrefslogtreecommitdiff
path: root/odb/relational/mssql/source.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-02-17 10:08:18 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-02-22 12:29:43 +0200
commit3a1eed21d4d5d0e7f6a9f400420fdc28d7be9b61 (patch)
tree97ba7338fb804c264c9eaaaa41085b08f6483c68 /odb/relational/mssql/source.cxx
parent3f73cc933b64d7d9a88325d33a3c33a0e28720c6 (diff)
Add support for composite object ids
New pragma id_type (member). New test: common/composite-id. The composite example has also been updated.
Diffstat (limited to 'odb/relational/mssql/source.cxx')
-rw-r--r--odb/relational/mssql/source.cxx343
1 files changed, 20 insertions, 323 deletions
diff --git a/odb/relational/mssql/source.cxx b/odb/relational/mssql/source.cxx
index 1c11984..1b800aa 100644
--- a/odb/relational/mssql/source.cxx
+++ b/odb/relational/mssql/source.cxx
@@ -41,17 +41,16 @@ namespace relational
virtual void
column (semantics::data_member& m,
- string const& key_prefix,
string const& table,
string const& column)
{
// Don't add a column for auto id in the INSERT statement.
//
if (!(sk_ == statement_insert &&
- key_prefix.empty () &&
- id (m) && auto_(m)))
+ key_prefix_.empty () &&
+ context::id (m) && auto_(m))) // Only simple id can be auto.
{
- base::column (m, key_prefix, table, column);
+ base::column (m, table, column);
}
}
};
@@ -413,181 +412,21 @@ namespace relational
// init image
//
- struct init_image_member: relational::init_image_member, member_base
+ struct init_image_member: relational::init_image_member_impl<sql_type>,
+ member_base
{
init_image_member (base const& x)
- : member_base::base (x), // virtual base
- base (x),
- member_base (x),
- member_database_type_id_ (base::type_override_,
- base::fq_type_override_,
- base::key_prefix_)
- {
- }
-
- virtual bool
- pre (member_info& mi)
+ : member_base::base (x), // virtual base
+ member_base::base_impl (x), // virtual base
+ base_impl (x),
+ member_base (x)
{
- // Ignore containers (they get their own table) and inverse
- // object pointers (they are not present in this binding).
- //
- if (container (mi) || inverse (mi.m, key_prefix_))
- return false;
-
- if (!member_override_.empty ())
- member = member_override_;
- else
- {
- // If we are generating standard init() and this member
- // contains version, ignore it.
- //
- if (version (mi.m))
- return false;
-
- // For SQL Server we don't send auto id in INSERT statement
- // (nor in UPDATE, as for other databases). So ignore it
- // altogether.
- //
- if (id (mi.m) && auto_ (mi.m))
- return false;
-
- string const& name (mi.m.name ());
- member = "o." + name;
-
- os << "// " << name << endl
- << "//" << endl;
-
- // If the whole class is readonly, then we will never be
- // called with sk == statement_update.
- //
- if (!readonly (*context::top_object))
- {
- semantics::class_* c;
-
- if (id (mi.m) ||
- readonly (mi.m) ||
- ((c = composite (mi.t)) && readonly (*c)))
- os << "if (sk == statement_insert)";
- }
- }
-
- // If this is a wrapped composite value, then we need to
- // "unwrap" it. For simple values this is taken care of
- // by the value_traits specializations.
- //
- if (mi.wrapper != 0 && composite (mi.t))
- {
- // Here we need the wrapper type, not the wrapped type.
- //
- member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
- "get_ref (" + member + ")";
- }
-
- if (composite (mi.t))
- {
- os << "{";
- traits = "composite_value_traits< " + mi.fq_type () + " >";
- }
- else
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_utype (mi.m, key_prefix_));
-
- if (semantics::class_* c = object_pointer (mt))
- {
- type = "obj_traits::id_type";
- db_type_id = member_database_type_id_.database_type_id (mi.m);
-
- // Handle NULL pointers and extract the id.
- //
- os << "{"
- << "typedef object_traits< " << class_fq_name (*c) <<
- " > obj_traits;";
-
- if (weak_pointer (mt))
- {
- os << "typedef pointer_traits< " << mi.fq_type () <<
- " > wptr_traits;"
- << "typedef pointer_traits< wptr_traits::" <<
- "strong_pointer_type > ptr_traits;"
- << endl
- << "wptr_traits::strong_pointer_type sp (" <<
- "wptr_traits::lock (" << member << "));";
-
- member = "sp";
- }
- else
- os << "typedef pointer_traits< " << mi.fq_type () <<
- " > ptr_traits;"
- << endl;
-
- os << "bool is_null (ptr_traits::null_ptr (" << member << "));"
- << "if (!is_null)"
- << "{"
- << "const " << type << "& id (" << endl;
-
- if (lazy_pointer (mt))
- os << "ptr_traits::object_id< ptr_traits::element_type > (" <<
- member << ")";
- else
- os << "obj_traits::id (ptr_traits::get_ref (" << member << "))";
-
- os << ");"
- << endl;
-
- member = "id";
- }
- else
- {
- type = mi.fq_type ();
- db_type_id = member_database_type_id_.database_type_id (mi.m);
-
- os << "{"
- << "bool is_null;";
- }
-
- traits = "mssql::value_traits<\n "
- + type + ",\n "
- + db_type_id + " >";
- }
-
- return true;
}
virtual void
- post (member_info& mi)
+ set_null (member_info& mi)
{
- if (composite (mi.t))
- os << "}";
- else
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- if (object_pointer (member_utype (mi.m, key_prefix_)))
- {
- os << "}"
- << "else" << endl;
-
- if (!null (mi.m, key_prefix_))
- os << "throw null_pointer ();";
- else
- os << "i." << mi.var << "size_ind = SQL_NULL_DATA;";
- }
-
- os << "}";
- }
- }
-
- virtual void
- traverse_composite (member_info& mi)
- {
- os << traits << "::init (" << endl
- << "i." << mi.var << "value," << endl
- << member << "," << endl
- << "sk);";
+ os << "i." << mi.var << "size_ind = SQL_NULL_DATA;";
}
virtual void
@@ -800,14 +639,6 @@ namespace relational
<< "i." << mi.var << "value, is_null, " << member << ");"
<< "i." << mi.var << "size_ind = is_null ? SQL_NULL_DATA : 8;";
}
-
- private:
- string type;
- string db_type_id;
- string member;
- string traits;
-
- member_database_type_id member_database_type_id_;
};
entry<init_image_member> init_image_member_;
@@ -815,147 +646,21 @@ namespace relational
// init value
//
- struct init_value_member: relational::init_value_member, member_base
+ struct init_value_member: relational::init_value_member_impl<sql_type>,
+ member_base
{
init_value_member (base const& x)
- : member_base::base (x), // virtual base
- base (x),
- member_base (x),
- member_database_type_id_ (base::type_override_,
- base::fq_type_override_,
- base::key_prefix_)
- {
- }
-
- virtual bool
- pre (member_info& mi)
- {
- if (container (mi))
- return false;
-
- if (!member_override_.empty ())
- member = member_override_;
- else
- {
- string const& name (mi.m.name ());
- member = "o." + name;
-
- if (mi.cq)
- member = "const_cast< " + mi.fq_type (false) + "& > (" +
- member + ")";
-
- os << "// " << name << endl
- << "//" << endl;
- }
-
- // If this is a wrapped composite value, then we need to
- // "unwrap" it. For simple values this is taken care of
- // by the value_traits specializations.
- //
- if (mi.wrapper != 0 && composite (mi.t))
- {
- // Here we need the wrapper type, not the wrapped type.
- //
- member = "wrapper_traits< " + mi.fq_type (false) + " >::" +
- "set_ref (\n" + member + ")";
- }
-
- if (composite (mi.t))
- traits = "composite_value_traits< " + mi.fq_type () + " >";
- else
- {
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_utype (mi.m, key_prefix_));
-
- if (semantics::class_* c = object_pointer (mt))
- {
- type = "obj_traits::id_type";
- db_type_id = member_database_type_id_.database_type_id (mi.m);
-
- // Handle NULL pointers and extract the id.
- //
- os << "{"
- << "typedef object_traits< " << class_fq_name (*c) <<
- " > obj_traits;"
- << "typedef pointer_traits< " << mi.fq_type () <<
- " > ptr_traits;"
- << endl
- << "if (i." << mi.var << "size_ind == SQL_NULL_DATA)" << endl;
-
- if (null (mi.m, key_prefix_))
- os << member << " = ptr_traits::pointer_type ();";
- else
- os << "throw null_pointer ();";
-
- os << "else"
- << "{"
- << type << " id;";
-
- member = "id";
- }
- else
- {
- type = mi.fq_type ();
- db_type_id = member_database_type_id_.database_type_id (mi.m);
- }
-
- traits = "mssql::value_traits<\n "
- + type + ",\n "
- + db_type_id + " >";
- }
-
- return true;
- }
-
- virtual void
- post (member_info& mi)
+ : member_base::base (x), // virtual base
+ member_base::base_impl (x), // virtual base
+ base_impl (x),
+ member_base (x)
{
- if (composite (mi.t))
- return;
-
- // When handling a pointer, mi.t is the id type of the referenced
- // object.
- //
- semantics::type& mt (member_utype (mi.m, key_prefix_));
-
- if (object_pointer (mt))
- {
- if (!member_override_.empty ())
- member = member_override_;
- else
- {
- member = "o." + mi.m.name ();
-
- if (mi.cq)
- member = "const_cast< " + mi.fq_type (false) + "& > (" +
- member + ")";
- }
-
- if (lazy_pointer (mt))
- os << member << " = ptr_traits::pointer_type (db, id);";
- else
- os << "// If a compiler error points to the line below, then" << endl
- << "// it most likely means that a pointer used in a member" << endl
- << "// cannot be initialized from an object pointer." << endl
- << "//" << endl
- << member << " = ptr_traits::pointer_type (" << endl
- << "db.load< obj_traits::object_type > (id));";
-
- os << "}"
- << "}";
- }
}
virtual void
- traverse_composite (member_info& mi)
+ get_null (member_info& mi)
{
- os << traits << "::init (" << endl
- << member << "," << endl
- << "i." << mi.var << "value," << endl
- << "db);"
- << endl;
+ os << "i." << mi.var << "size_ind == SQL_NULL_DATA";
}
virtual void
@@ -1141,14 +846,6 @@ namespace relational
<< "i." << mi.var << "size_ind == SQL_NULL_DATA);"
<< endl;
}
-
- private:
- string type;
- string db_type_id;
- string traits;
- string member;
-
- member_database_type_id member_database_type_id_;
};
entry<init_value_member> init_value_member_;
@@ -1172,7 +869,7 @@ namespace relational
size_t n (cols.size ());
for (statement_columns::iterator i (cols.begin ()); n != 0; --n)
{
- sql_type const& st (column_sql_type (*i->member, i->key_prefix));
+ sql_type const& st (parse_sql_type (i->type, *i->member));
bool l (false);