From ce696c26d2c9dd5a5813fd865082ab19ac49bcfa Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 6 Nov 2010 18:05:19 +0200 Subject: Add support for container persistence --- odb/mysql/header.cxx | 573 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 507 insertions(+), 66 deletions(-) (limited to 'odb/mysql/header.cxx') diff --git a/odb/mysql/header.cxx b/odb/mysql/header.cxx index 2544ff3..b4781f9 100644 --- a/odb/mysql/header.cxx +++ b/odb/mysql/header.cxx @@ -14,46 +14,59 @@ namespace mysql { struct image_member: member_base { - image_member (context& c, bool id) - : member_base (c, id), member_image_type_ (c, id) + image_member (context& c, string const& var = string ()) + : member_base (c, var), member_image_type_ (c) + { + } + + image_member (context& c, + string const& var, + semantics::type& t, + string const& fq_type, + string const& key_prefix) + : member_base (c, var, t, fq_type, key_prefix), + member_image_type_ (c, t, fq_type, key_prefix) { } virtual void - pre (type& m) + pre (member_info& mi) { - image_type = member_image_type_.image_type (m); + if (container (mi.t)) + return; - if (!id_) - os << "// " << m.name () << endl + image_type = member_image_type_.image_type (mi.m); + + if (var_override_.empty ()) + os << "// " << mi.m.name () << endl << "//" << endl; } virtual void - traverse_composite (type&) + traverse_composite (member_info& mi) { - os << image_type << " " << var << "value;" + os << image_type << " " << mi.var << "value;" << endl; } virtual void - traverse_integer (type&, sql_type const&) + traverse_integer (member_info& mi) { - os << image_type << " " << var << "value;" - << "my_bool " << var << "null;" + os << image_type << " " << mi.var << "value;" + << "my_bool " << mi.var << "null;" << endl; } virtual void - traverse_float (type&, sql_type const&) + traverse_float (member_info& mi) { - os << image_type << " " << var << "value;" - << "my_bool " << var << "null;" + os << image_type << " " << mi.var << "value;" + << "my_bool " << mi.var << "null;" << endl; } virtual void - traverse_decimal (type&, sql_type const&) + traverse_decimal (member_info& mi) { // Exchanged as strings. Can have up to 65 digits not counting // '-' and '.'. If range is not specified, the default is 10. @@ -61,83 +74,83 @@ namespace mysql /* @@ Disabled. - os << "char " << var << "value[" << + os << "char " << mi.var << "value[" << (t.range ? t.range_value : 10) + 3 << "];" */ - os << image_type << " " << var << "value;" - << "unsigned long " << var << "size;" - << "my_bool " << var << "null;" + os << image_type << " " << mi.var << "value;" + << "unsigned long " << mi.var << "size;" + << "my_bool " << mi.var << "null;" << endl; } virtual void - traverse_date_time (type&, sql_type const&) + traverse_date_time (member_info& mi) { - os << image_type << " " << var << "value;" - << "my_bool " << var << "null;" + os << image_type << " " << mi.var << "value;" + << "my_bool " << mi.var << "null;" << endl; } virtual void - traverse_short_string (type&, sql_type const&) + traverse_short_string (member_info& mi) { // If range is not specified, the default buffer size is 255. // /* @@ Disabled. - os << "char " << var << "value[" << + os << "char " << mi.var << "value[" << (t.range ? t.range_value : 255) + 1 << "];" */ - os << image_type << " " << var << "value;" - << "unsigned long " << var << "size;" - << "my_bool " << var << "null;" + os << image_type << " " << mi.var << "value;" + << "unsigned long " << mi.var << "size;" + << "my_bool " << mi.var << "null;" << endl; } virtual void - traverse_long_string (type&, sql_type const&) + traverse_long_string (member_info& mi) { - os << image_type << " " << var << "value;" - << "unsigned long " << var << "size;" - << "my_bool " << var << "null;" + os << image_type << " " << mi.var << "value;" + << "unsigned long " << mi.var << "size;" + << "my_bool " << mi.var << "null;" << endl; } virtual void - traverse_bit (type&, sql_type const& t) + traverse_bit (member_info& mi) { // Valid range is 1 to 64. // - unsigned int n (t.range / 8 + (t.range % 8 ? 1 : 0)); + unsigned int n (mi.st->range / 8 + (mi.st->range % 8 ? 1 : 0)); - os << "unsigned char " << var << "value[" << n << "];" - << "unsigned long " << var << "size;" - << "my_bool " << var << "null;" + os << "unsigned char " << mi.var << "value[" << n << "];" + << "unsigned long " << mi.var << "size;" + << "my_bool " << mi.var << "null;" << endl; } virtual void - traverse_enum (type&, sql_type const&) + traverse_enum (member_info& mi) { // Represented as string. // - os << image_type << " " << var << "value;" - << "unsigned long " << var << "size;" - << "my_bool " << var << "null;" + os << image_type << " " << mi.var << "value;" + << "unsigned long " << mi.var << "size;" + << "my_bool " << mi.var << "null;" << endl; } virtual void - traverse_set (type&, sql_type const&) + traverse_set (member_info& mi) { // Represented as string. // - os << image_type << " " << var << "value;" - << "unsigned long " << var << "size;" - << "my_bool " << var << "null;" + os << image_type << " " << mi.var << "value;" + << "unsigned long " << mi.var << "size;" + << "my_bool " << mi.var << "null;" << endl; } @@ -175,7 +188,7 @@ namespace mysql struct image_type: traversal::class_, context { image_type (context& c) - : context (c), member_ (c, false) + : context (c), member_ (c) { *this >> names_member_ >> member_; } @@ -203,36 +216,437 @@ namespace mysql traversal::names names_member_; }; - struct id_image_type: traversal::class_, context + // Member-specific traits types for container members. + // + struct container_traits: object_members_base, context { - id_image_type (context& c) - : context (c), image_member_ (c, true) + container_traits (context& c) + : object_members_base (c, true, false), context (c) { - *this >> names_image_member_ >> image_member_; } virtual void - traverse (type& c) + container (semantics::data_member& m) { - os << "struct id_image_type" + using semantics::type; + using semantics::class_; + + type& t (m.type ()); + container_kind_type ck (container_kind (t)); + + type& vt (container_vt (t)); + type* it (0); + type* kt (0); + + switch (ck) + { + case ck_ordered: + { + it = &container_it (t); + break; + } + case ck_map: + case ck_multimap: + { + kt = &container_kt (t); + break; + } + case ck_set: + case ck_multiset: + { + break; + } + } + + string name (prefix_ + public_name (m) + "_traits"); + + // Figure out column counts. + // + size_t data_columns (1), cond_columns (1); // One for object id. + + switch (ck) + { + case ck_ordered: + { + // Add one for the index. + // + data_columns++; + cond_columns++; + break; + } + case ck_map: + case ck_multimap: + { + // Add some for the key. + // + size_t n; + + if (class_* kc = comp_value (*kt)) + n = column_count (*kc); + else + n = 1; + + data_columns += n; + cond_columns += n; + break; + } + case ck_set: + case ck_multiset: + { + // Value is also a key. + // + if (class_* vc = comp_value (vt)) + cond_columns += column_count (*vc); + else + cond_columns++; + + break; + } + } + + if (class_* vc = comp_value (vt)) + data_columns += column_count (*vc); + else + data_columns++; + + // Store column counts for the source generator. + // + m.set ("cond-column-count", cond_columns); + m.set ("data-column-count", data_columns); + + os << "// " << m.name () << endl + << "//" << endl + << "struct " << name << "{"; - names (c); + // container_type + // index_type + // key_type + // value_type + // + + os << "typedef " << t.fq_name (m.belongs ().hint ()) << + " container_type;"; + + switch (ck) + { + case ck_ordered: + { + os << "typedef " << container_fq_it (m) << " index_type;"; + break; + } + case ck_map: + case ck_multimap: + { + os << "typedef " << container_fq_kt (m) << " key_type;"; + } + case ck_set: + case ck_multiset: + { + break; + } + } + + os << "typedef " << container_fq_vt (m) << " value_type;" + << endl; + + os << "typedef odb::access::container_traits< container_type > " << + "container_traits;"; + + // functions_type + // + switch (ck) + { + case ck_ordered: + { + os << "typedef ordered_functions " << + "functions_type;"; + break; + } + case ck_map: + case ck_multimap: + { + os << "typedef map_functions " << + "functions_type;"; + break; + } + case ck_set: + case ck_multiset: + { + os << "typedef set_functions functions_type;"; + break; + } + } + + os << "typedef mysql::container_statements< " << name << + " > statements_type;" + << endl; + + // column_count + // + os << "static const std::size_t cond_column_count = " << + cond_columns << "UL;" + << "static const std::size_t data_column_count = " << + data_columns << "UL;" + << endl; + + // cond_image_type (object id is taken from the object image) + // + os << "struct cond_image_type" + << "{"; + + switch (ck) + { + case ck_ordered: + { + os << "// index" << endl + << "//" << endl; + image_member im (*this, "index_", *it, "index_type", "index"); + im.traverse (m); + break; + } + case ck_map: + case ck_multimap: + { + os << "// key" << endl + << "//" << endl; + image_member im (*this, "key_", *kt, "key_type", "key"); + im.traverse (m); + break; + } + case ck_set: + case ck_multiset: + { + os << "// value" << endl + << "//" << endl; + image_member im (*this, "value_", vt, "value_type", "value"); + im.traverse (m); + break; + } + } os << "};"; - } - private: - image_member image_member_; - traversal::names names_image_member_; + // data_image_type (object id is taken from the object image) + // + os << "struct data_image_type" + << "{"; + + switch (ck) + { + case ck_ordered: + { + os << "// index" << endl + << "//" << endl; + image_member im (*this, "index_", *it, "index_type", "index"); + im.traverse (m); + break; + } + case ck_map: + case ck_multimap: + { + os << "// key" << endl + << "//" << endl; + image_member im (*this, "key_", *kt, "key_type", "key"); + im.traverse (m); + break; + } + case ck_set: + case ck_multiset: + { + break; + } + } + + os << "// value" << endl + << "//" << endl; + image_member im (*this, "value_", vt, "value_type", "value"); + im.traverse (m); + + os << "};"; + + // Statements. + // + os << "static const char* const insert_one_statement;" + << "static const char* const select_all_statement;" + << "static const char* const delete_all_statement;" + << endl; + + // bind (cond_image) + // + os << "static void" << endl + << "bind (MYSQL_BIND*, id_image_type*, cond_image_type&);" + << endl; + + // bind (data_image) + // + os << "static void" << endl + << "bind (MYSQL_BIND*, id_image_type*, data_image_type&);" + << endl; + + // grow() + // + os << "static bool" << endl + << "grow (data_image_type&, my_bool*);" + << endl; + + // init (data_image) + // + os << "static bool" << endl; + + switch (ck) + { + case ck_ordered: + { + os << "init (data_image_type&, index_type, const value_type&);"; + break; + } + case ck_map: + case ck_multimap: + { + os << "init (data_image_type&, const key_type&, const value_type&);"; + break; + } + case ck_set: + case ck_multiset: + { + os << "init (data_image_type&, const value_type&);"; + break; + } + } + + os << endl; + + // init (data) + // + os << "static void" << endl; + + switch (ck) + { + case ck_ordered: + { + os << "init (index_type&, value_type&, const data_image_type&);"; + break; + } + case ck_map: + case ck_multimap: + { + os << "init (key_type&, value_type&, const data_image_type&);"; + break; + } + case ck_set: + case ck_multiset: + { + os << "init (value_type&, const data_image_type&);"; + break; + } + } + + os << endl; + + // insert_one + // + os << "static void" << endl; + + switch (ck) + { + case ck_ordered: + { + os << "insert_one (index_type, const value_type&, void*);"; + break; + } + case ck_map: + case ck_multimap: + { + os << "insert_one (const key_type&, const value_type&, void*);"; + break; + } + case ck_set: + case ck_multiset: + { + os << "insert_one (const value_type&, void*);"; + break; + } + } + + os << endl; + + // load_all + // + os << "static bool" << endl; + + switch (ck) + { + case ck_ordered: + { + os << "load_all (index_type&, value_type&, void*);"; + break; + } + case ck_map: + case ck_multimap: + { + os << "load_all (key_type&, value_type&, void*);"; + break; + } + case ck_set: + case ck_multiset: + { + os << "load_all (value_type&, void*);"; + break; + } + } + + os << endl; + + // delete_all + // + os << "static void" << endl + << "delete_all (void*);" + << endl; + + // persist + // + os << "static void" << endl + << "persist (const container_type&," << endl + << "id_image_type&," << endl + << "bool," << endl + << "statements_type&);" + << endl; + + // load + // + os << "static void" << endl + << "load (container_type&," << endl + << "id_image_type&," << endl + << "bool," << endl + << "statements_type&);" + << endl; + + // update + // + os << "static void" << endl + << "update (const container_type&," << endl + << "id_image_type&," << endl + << "bool," << endl + << "statements_type&);" + << endl; + + // erase + // + os << "static void" << endl + << "erase (id_image_type&, bool, statements_type&);" + << endl; + + os << "};"; + } }; + // + // struct class_: traversal::class_, context { class_ (context& c) - : context (c), - image_type_ (c), - id_image_type_ (c) + : context (c), image_type_ (c), id_image_member_ (c, "id_") { } @@ -254,8 +668,7 @@ namespace mysql string const& type (c.fq_name ()); bool def_ctor (TYPE_HAS_DEFAULT_CONSTRUCTOR (c.tree_node ())); - id_member_.traverse (c); - semantics::data_member& id (*id_member_.member ()); + semantics::data_member& id (id_member (c)); bool auto_id (id.count ("auto")); os << "// " << c.name () << endl @@ -284,7 +697,12 @@ namespace mysql // id_image_type // - id_image_type_.traverse (c); + os << "struct id_image_type" + << "{"; + + id_image_member_.traverse (id); + + os << "};"; // query_type & query_base_type // @@ -317,7 +735,7 @@ namespace mysql column_count (c) << "UL;" << endl; - // Queries. + // Statements. // os << "static const char* const persist_statement;" << "static const char* const find_statement;" @@ -329,6 +747,28 @@ namespace mysql os << endl; + // + // Containers. + // + + // Traits types. + // + { + // @@ Make it class members? + // + container_traits t (*this); + t.traverse (c); + } + + // Statement cache (forward declaration). + // + os << "struct container_statement_cache_type;" + << endl; + + // + // Functions. + // + // id () // os << "static id_type" << endl @@ -406,7 +846,9 @@ namespace mysql // os << "private:" << endl << "static bool" << endl - << "find (mysql::object_statements&, const id_type&);"; + << "find (mysql::object_statements&," << endl + << "const id_type&," << endl + << "bool&);"; os << "};"; } @@ -461,9 +903,8 @@ namespace mysql } private: - id_member id_member_; image_type image_type_; - id_image_type id_image_type_; + image_member id_image_member_; }; } -- cgit v1.1