From 7ae497743c7b042904fe1f6b4153ab3f4763ff2b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 10 Mar 2011 08:44:28 +0200 Subject: Split MySQL code generator into common and db-specific parts The common part (in relational/) still has some MySQL-specific parts. Also, add the notion of the current context which is used to avoid explicitly passing the context object to every generator's c-tor. --- odb/mysql/header.cxx | 1031 -------------------------------------------------- 1 file changed, 1031 deletions(-) delete mode 100644 odb/mysql/header.cxx (limited to 'odb/mysql/header.cxx') diff --git a/odb/mysql/header.cxx b/odb/mysql/header.cxx deleted file mode 100644 index 59793b0..0000000 --- a/odb/mysql/header.cxx +++ /dev/null @@ -1,1031 +0,0 @@ -// file : odb/mysql/header.cxx -// author : Boris Kolpackov -// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC -// license : GNU GPL v3; see accompanying LICENSE file - -#include - -#include -#include - -namespace mysql -{ - namespace - { - struct image_member: member_base - { - 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 bool - pre (member_info& mi) - { - if (container (mi.t)) - return false; - - image_type = member_image_type_.image_type (mi.m); - - if (var_override_.empty ()) - os << "// " << mi.m.name () << endl - << "//" << endl; - - return true; - } - - virtual void - traverse_composite (member_info& mi) - { - os << image_type << " " << mi.var << "value;" - << endl; - } - - virtual void - traverse_integer (member_info& mi) - { - os << image_type << " " << mi.var << "value;" - << "my_bool " << mi.var << "null;" - << endl; - } - - virtual void - traverse_float (member_info& mi) - { - os << image_type << " " << mi.var << "value;" - << "my_bool " << mi.var << "null;" - << endl; - } - - virtual void - 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. - // - - /* - @@ Disabled. - os << "char " << mi.var << "value[" << - (t.range ? t.range_value : 10) + 3 << "];" - */ - - os << image_type << " " << mi.var << "value;" - << "unsigned long " << mi.var << "size;" - << "my_bool " << mi.var << "null;" - << endl; - } - - virtual void - traverse_date_time (member_info& mi) - { - os << image_type << " " << mi.var << "value;" - << "my_bool " << mi.var << "null;" - << endl; - - } - - virtual void - traverse_short_string (member_info& mi) - { - // If range is not specified, the default buffer size is 255. - // - /* - @@ Disabled. - os << "char " << mi.var << "value[" << - (t.range ? t.range_value : 255) + 1 << "];" - */ - - os << image_type << " " << mi.var << "value;" - << "unsigned long " << mi.var << "size;" - << "my_bool " << mi.var << "null;" - << endl; - } - - virtual void - traverse_long_string (member_info& mi) - { - os << image_type << " " << mi.var << "value;" - << "unsigned long " << mi.var << "size;" - << "my_bool " << mi.var << "null;" - << endl; - } - - virtual void - traverse_bit (member_info& mi) - { - // Valid range is 1 to 64. - // - unsigned int n (mi.st->range / 8 + (mi.st->range % 8 ? 1 : 0)); - - os << "unsigned char " << mi.var << "value[" << n << "];" - << "unsigned long " << mi.var << "size;" - << "my_bool " << mi.var << "null;" - << endl; - } - - virtual void - traverse_enum (member_info& mi) - { - // Represented as string. - // - os << image_type << " " << mi.var << "value;" - << "unsigned long " << mi.var << "size;" - << "my_bool " << mi.var << "null;" - << endl; - } - - virtual void - traverse_set (member_info& mi) - { - // Represented as string. - // - os << image_type << " " << mi.var << "value;" - << "unsigned long " << mi.var << "size;" - << "my_bool " << mi.var << "null;" - << endl; - } - - private: - string image_type; - - member_image_type member_image_type_; - }; - - struct image_base: traversal::class_, context - { - image_base (context& c): context (c), first_ (true) {} - - virtual void - traverse (type& c) - { - // Ignore transient bases. - // - if (!(c.count ("object") || comp_value (c))) - return; - - if (first_) - { - os << ": "; - first_ = false; - } - else - { - os << "," << endl - << " "; - } - - os << "composite_value_traits< " << c.fq_name () << " >::image_type"; - } - - private: - bool first_; - }; - - struct image_type: traversal::class_, context - { - image_type (context& c) - : context (c), member_ (c) - { - *this >> names_member_ >> member_; - } - - virtual void - traverse (type& c) - { - os << "struct image_type"; - - { - image_base b (*this); - traversal::inherits i (b); - inherits (c, i); - } - - os << "{"; - - names (c); - - if (!comp_value (c)) - os << "std::size_t version;"; - - os << "};"; - } - - private: - image_member member_; - traversal::names names_member_; - }; - - // Member-specific traits types for container members. - // - struct container_traits: object_members_base, context - { - container_traits (context& c, semantics::class_& obj) - : object_members_base (c, true, false), context (c) - { - scope_ = "object_traits< " + obj.fq_name () + " >"; - } - - virtual void - container (semantics::data_member& m) - { - 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); - - bool ordered (false); - bool inverse (context::inverse (m, "value")); - - switch (ck) - { - case ck_ordered: - { - if (!unordered (m)) - { - it = &container_it (t); - ordered = true; - } - 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. - // - if (ordered) - { - 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 = in_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 += in_column_count (*vc); - else - cond_columns++; - - break; - } - } - - if (class_* vc = comp_value (vt)) - data_columns += in_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 - << "{"; - - // container_type - // container_traits - // index_type - // key_type - // value_type - // - - os << "typedef " << t.fq_name (m.belongs ().hint ()) << - " container_type;"; - os << "typedef odb::access::container_traits< container_type > " << - "container_traits;"; - - switch (ck) - { - case ck_ordered: - { - os << "typedef container_traits::index_type index_type;"; - break; - } - case ck_map: - case ck_multimap: - { - os << "typedef container_traits::key_type key_type;"; - } - case ck_set: - case ck_multiset: - { - break; - } - } - - os << "typedef container_traits::value_type value_type;" - << endl; - - // 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; - - // id_image_type - // - os << "typedef " << scope_ << "::id_image_type id_image_type;" - << endl; - - // cond_image_type (object id is taken from the object image) - // - os << "struct cond_image_type" - << "{"; - - switch (ck) - { - case ck_ordered: - { - if (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 << "std::size_t version;" - << "};"; - - // data_image_type (object id is taken from the object image) - // - os << "struct data_image_type" - << "{"; - - switch (ck) - { - case ck_ordered: - { - if (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 << "std::size_t version;" - << "};"; - - // 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 void" << endl - << "grow (data_image_type&, my_bool*);" - << endl; - - // init (data_image) - // - if (!inverse) - { - os << "static void" << endl; - - switch (ck) - { - case ck_ordered: - { - if (ordered) - os << "init (data_image_type&, index_type, const value_type&);"; - else - os << "init (data_image_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: - { - if (ordered) - os << "init (index_type&, value_type&, "; - else - os << "init (value_type&, "; - break; - } - case ck_map: - case ck_multimap: - { - os << "init (key_type&, value_type&, "; - break; - } - case ck_set: - case ck_multiset: - { - os << "init (value_type&, "; - break; - } - } - - os << "const data_image_type&, database&);" - << 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 - // - if (!inverse) - os << "static void" << endl - << "persist (const container_type&," << endl - << "id_image_type&," << endl - << "statements_type&);" - << endl; - - // load - // - os << "static void" << endl - << "load (container_type&," << endl - << "id_image_type&," << endl - << "statements_type&);" - << endl; - - // update - // - if (!inverse) - os << "static void" << endl - << "update (const container_type&," << endl - << "id_image_type&," << endl - << "statements_type&);" - << endl; - - // erase - // - if (!inverse) - os << "static void" << endl - << "erase (id_image_type&, statements_type&);" - << endl; - - os << "};"; - } - - private: - string scope_; - }; - - // - // - struct class_: traversal::class_, context - { - class_ (context& c) - : context (c), image_type_ (c), id_image_member_ (c, "id_") - { - } - - virtual void - traverse (type& c) - { - if (c.file () != unit.file ()) - return; - - if (c.count ("object")) - traverse_object (c); - else if (comp_value (c)) - traverse_value (c); - } - - virtual void - traverse_object (type& c) - { - string const& type (c.fq_name ()); - bool def_ctor (TYPE_HAS_DEFAULT_CONSTRUCTOR (c.tree_node ())); - - semantics::data_member& id (id_member (c)); - bool auto_id (id.count ("auto")); - - os << "// " << c.name () << endl - << "//" << endl; - - os << "template <>" << endl - << "class access::object_traits< " << type << " >" - << "{" - << "public:" << endl; - - // object_type & pointer_type - // - os << "typedef " << type << " object_type;" - << "typedef " << c.get ("object-pointer") << " pointer_type;"; - - // id_type - // - os << "typedef " << id.type ().fq_name (id.belongs ().hint ()) << - " id_type;" - << endl; - - // image_type - // - image_type_.traverse (c); - - // id_image_type - // - os << "struct id_image_type" - << "{"; - - id_image_member_.traverse (id); - - os << "std::size_t version;" - << "};"; - - // query_type & query_base_type - // - if (options.generate_query ()) - { - // query_base_type - // - os << "typedef mysql::query query_base_type;" - << endl; - - // query_type - // - os << "struct query_type: query_base_type" - << "{"; - - { - query_columns t (*this); - t.traverse (c); - } - - os << "query_type ();" - << "query_type (const std::string&);" - << "query_type (const query_base_type&);" - << "};"; - } - - // column_count - // - os << "static const std::size_t in_column_count = " << - in_column_count (c) << "UL;" - << "static const std::size_t out_column_count = " << - out_column_count (c) << "UL;" - << endl; - - // Statements. - // - os << "static const char* const persist_statement;" - << "static const char* const find_statement;" - << "static const char* const update_statement;" - << "static const char* const erase_statement;"; - - if (options.generate_query ()) - os << "static const char* const query_clause;"; - - os << endl; - - // - // Containers. - // - - // Traits types. - // - { - container_traits t (*this, c); - t.traverse (c); - } - - // Statement cache (forward declaration). - // - os << "struct container_statement_cache_type;" - << endl; - - // - // Functions. - // - - // id () - // - os << "static id_type" << endl - << "id (const object_type&);" - << endl; - - if (options.generate_query ()) - os << "static id_type" << endl - << "id (const image_type&);" - << endl; - - // grow () - // - os << "static void" << endl - << "grow (image_type&, my_bool*);" - << endl; - - // bind (image_type) - // - os << "static void" << endl - << "bind (MYSQL_BIND*, image_type&, bool);" - << endl; - - // bind (id_image_type) - // - os << "static void" << endl - << "bind (MYSQL_BIND*, id_image_type&);" - << endl; - - // init (image, object) - // - os << "static void" << endl - << "init (image_type&, const object_type&);" - << endl; - - // init (object, image) - // - os << "static void" << endl - << "init (object_type&, const image_type&, database&);" - << endl; - - // init (id_image, id) - // - os << "static void" << endl - << "init (id_image_type&, const id_type&);" - << endl; - - // persist () - // - os << "static void" << endl - << "persist (database&, " << (auto_id ? "" : "const ") << - "object_type&);" - << endl; - - // update () - // - os << "static void" << endl - << "update (database&, const object_type&);" - << endl; - - // erase () - // - os << "static void" << endl - << "erase (database&, const id_type&);" - << endl; - - // find () - // - if (def_ctor) - os << "static pointer_type" << endl - << "find (database&, const id_type&);" - << endl; - - os << "static bool" << endl - << "find (database&, const id_type&, object_type&);" - << endl; - - // query () - // - if (options.generate_query ()) - os << "template" << endl - << "static result" << endl - << "query (database&, const query_type&);" - << endl; - - // create_schema () - // - if (embedded_schema) - { - os << "static void" << endl - << "create_schema (database&);" - << endl; - } - - // Implementation details. - // - os << "public:" << endl; - - // Load the object image. - // - os << "static bool" << endl - << "find_ (mysql::object_statements< object_type >&, const id_type&);" - << endl; - - // Load the rest of the object (containers, etc). Expects the id - // image in the object statements to be initialized to the object - // id. - // - os << "static void" << endl - << "load_ (mysql::object_statements< object_type >&, object_type&);" - << endl; - - if (options.generate_query ()) - os << "static void" << endl - << "query_ (database&," << endl - << "const query_type&," << endl - << "mysql::object_statements< object_type >&," << endl - << "details::shared_ptr< mysql::select_statement >&);" - << endl; - - os << "};"; - } - - virtual void - traverse_value (type& c) - { - string const& type (c.fq_name ()); - - os << "// " << c.name () << endl - << "//" << endl; - - os << "template <>" << endl - << "class access::composite_value_traits< " << type << " >" - << "{" - << "public:" << endl; - - // object_type - // - os << "typedef " << type << " value_type;" - << endl; - - // image_type - // - image_type_.traverse (c); - - // grow () - // - os << "static bool" << endl - << "grow (image_type&, my_bool*);" - << endl; - - // bind (image_type) - // - os << "static void" << endl - << "bind (MYSQL_BIND*, image_type&);" - << endl; - - // init (image, object) - // - os << "static bool" << endl - << "init (image_type&, const value_type&);" - << endl; - - // init (object, image) - // - os << "static void" << endl - << "init (value_type&, const image_type&, database&);" - << endl; - - os << "};"; - } - - private: - image_type image_type_; - image_member id_image_member_; - }; - } - - void - generate_header (context& ctx) - { - traversal::unit unit; - traversal::defines unit_defines; - traversal::namespace_ ns; - class_ c (ctx); - - unit >> unit_defines >> ns; - unit_defines >> c; - - traversal::defines ns_defines; - - ns >> ns_defines >> ns; - ns_defines >> c; - - ctx.os << "#include " << endl - << "#include " << endl - << "#include " << endl; - - if (ctx.options.generate_query ()) - ctx.os << "#include " << endl; - - ctx.os << endl - << "#include " << endl - << endl; - - ctx.os << "namespace odb" - << "{"; - - unit.dispatch (ctx.unit); - - ctx.os << "}"; - } -} -- cgit v1.1