From ead623bfdd2004988f13d7cade7deaea1b71f7e8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 13 Aug 2010 13:44:00 +0200 Subject: Add support for language-embedded queries --- odb/mysql/common.cxx | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++ odb/mysql/common.hxx | 44 ++++++++ odb/mysql/header.cxx | 39 +++++-- odb/mysql/inline.cxx | 22 ++++ odb/mysql/source.cxx | 8 ++ 5 files changed, 381 insertions(+), 11 deletions(-) (limited to 'odb/mysql') diff --git a/odb/mysql/common.cxx b/odb/mysql/common.cxx index e1441f1..011e510 100644 --- a/odb/mysql/common.cxx +++ b/odb/mysql/common.cxx @@ -128,4 +128,283 @@ namespace mysql post (m); } + + // + // query_column + // + + namespace + { + const char* integer_image_id[] = + { + "id_tiny", + "id_utiny", + "id_short", + "id_ushort", + "id_long", // INT24 + "id_ulong", // INT24 UNSIGNED + "id_long", + "id_ulong", + "id_longlong", + "id_ulonglong" + }; + + const char* float_image_id[] = + { + "id_float", + "id_double" + }; + + const char* date_time_image_id[] = + { + "id_date", + "id_time", + "id_datetime", + "id_timestamp", + "id_year" + }; + + const char* char_bin_image_id[] = + { + "id_string", // CHAR + "id_blob", // BINARY, + "id_string", // VARCHAR + "id_blob", // VARBINARY + "id_string", // TINYTEXT + "id_blob", // TINYBLOB + "id_string", // TEXT + "id_blob", // BLOB + "id_string", // MEDIUMTEXT + "id_blob", // MEDIUMBLOB + "id_string", // LONGTEXT + "id_blob" // LONGBLOB + }; + } + + query_column:: + query_column (context& c) + : member_base (c, false), decl_ (true) + { + } + + query_column:: + query_column (context& c, semantics::class_& cl) + : member_base (c, false), decl_ (false) + { + scope_ = "access::object_traits< " + cl.fq_name () + " >::query_type"; + table_ = table_name (cl); + } + + void query_column:: + pre (type& m) + { + type_ = "mysql::value_traits< " + m.type ().fq_name () + " >::value_type"; + name_ = escape (public_name (m)); + + if (decl_) + os << "// " << name_ << endl + << "//" << endl; + else + column_ = "\"`" + table_ + "`.`" + column_name (m) + "`\""; + } + + void query_column:: + traverse_integer (type& m, sql_type const& t) + { + size_t i ((t.type - sql_type::TINYINT) * 2 + (t.unsign ? 1 : 0)); + + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << integer_image_id[i] << ">" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << integer_image_id[i] << ">" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } + + void query_column:: + traverse_float (type& m, sql_type const& t) + { + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << float_image_id[t.type - sql_type::FLOAT] << ">" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << float_image_id[t.type - sql_type::FLOAT] << ">" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } + + void query_column:: + traverse_decimal (type& m, sql_type const& t) + { + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::id_string>" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::id_string>" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } + + void query_column:: + traverse_date_time (type& m, sql_type const& t) + { + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << date_time_image_id[t.type - sql_type::DATE] << ">" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << date_time_image_id[t.type - sql_type::DATE] << ">" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } + + void query_column:: + traverse_short_string (type& m, sql_type const& t) + { + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << char_bin_image_id[t.type - sql_type::CHAR] << ">" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << char_bin_image_id[t.type - sql_type::CHAR] << ">" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } + + void query_column:: + traverse_long_string (type& m, sql_type const& t) + { + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << char_bin_image_id[t.type - sql_type::CHAR] << ">" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::" << char_bin_image_id[t.type - sql_type::CHAR] << ">" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } + + void query_column:: + traverse_bit (type& m, sql_type const& t) + { + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::id_blob>" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::id_blob>" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } + + void query_column:: + traverse_enum (type& m, sql_type const&) + { + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::id_string>" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::id_string>" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } + + void query_column:: + traverse_set (type& m, sql_type const&) + { + if (decl_) + { + os << "static const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::id_string>" << endl + << name_ << ";" + << endl; + } + else + { + os << "const mysql::query_column<" << endl + << " " << type_ << "," << endl + << " mysql::id_string>" << endl + << scope_ << "::" << name_ << " (" << endl + << column_ << ");" + << endl; + } + } } diff --git a/odb/mysql/common.hxx b/odb/mysql/common.hxx index 5017158..452a0a6 100644 --- a/odb/mysql/common.hxx +++ b/odb/mysql/common.hxx @@ -115,6 +115,50 @@ namespace mysql private: bool r_; }; + + struct query_column: member_base + { + query_column (context&); + query_column (context&, semantics::class_&); + + virtual void + pre (type&); + + virtual void + traverse_integer (type&, sql_type const&); + + virtual void + traverse_float (type&, sql_type const&); + + virtual void + traverse_decimal (type&, sql_type const&); + + virtual void + traverse_date_time (type&, sql_type const&); + + virtual void + traverse_short_string (type&, sql_type const&); + + virtual void + traverse_long_string (type&, sql_type const&); + + virtual void + traverse_bit (type&, sql_type const&); + + virtual void + traverse_enum (type&, sql_type const&); + + virtual void + traverse_set (type&, sql_type const&); + + private: + string type_; + string name_; + string scope_; + string table_; + string column_; + bool decl_; + }; } #endif // ODB_MYSQL_COMMON_HXX diff --git a/odb/mysql/header.cxx b/odb/mysql/header.cxx index 8d32284..0d3e3f7 100644 --- a/odb/mysql/header.cxx +++ b/odb/mysql/header.cxx @@ -201,8 +201,10 @@ namespace mysql id_member_ (c), member_count_ (c), image_type_ (c), - id_image_type_ (c) + id_image_type_ (c), + query_column_ (c) { + *this >> query_column_names_ >> query_column_; } virtual void @@ -222,10 +224,10 @@ namespace mysql if (id_member_.member () == 0) { - cerr << c.file () << ":" << c.line () << ":" << c.column () + cerr << c.file () << ":" << c.line () << ":" << c.column () << ":" << " error: no data member designated as object id" << endl; - cerr << c.file () << ":" << c.line () << ":" << c.column () + cerr << c.file () << ":" << c.line () << ":" << c.column () << ":" << " info: use '#pragma odb id' to specify object id member" << endl; } @@ -238,10 +240,10 @@ namespace mysql // Can be a template-id (which we should handle eventually) or an // anonymous type in member declaration (e.g., struct {...} m_;). // - cerr << id.file () << ":" << id.line () << ":" << id.column () + cerr << id.file () << ":" << id.line () << ":" << id.column () << ":" << " error: unnamed type in data member declaration" << endl; - cerr << id.file () << ":" << id.line () << ":" << id.column () + cerr << id.file () << ":" << id.line () << ":" << id.column () << ":" << " info: use 'typedef' to name this type" << endl; @@ -253,7 +255,7 @@ namespace mysql if (column_count == 0) { - cerr << c.file () << ":" << c.line () << ":" << c.column () + cerr << c.file () << ":" << c.line () << ":" << c.column () << ":" << " error: no persistent data members in the class" << endl; throw generation_failed (); @@ -278,11 +280,6 @@ namespace mysql os << "typedef " << id_type.fq_name () << " id_type;" << endl; - // query_type - // - os << "typedef mysql::query query_type;" - << endl; - // image_type // image_type_.traverse (c); @@ -291,6 +288,23 @@ namespace mysql // id_image_type_.traverse (c); + // query_base_type + // + os << "typedef mysql::query query_base_type;" + << endl; + + // query_type + // + os << "struct query_type: query_base_type" + << "{"; + + names (c, query_column_names_); + + os << "query_type ();" + << "query_type (const std::string&);" + << "query_type (const query_base_type&);" + << "};"; + // id_source // os << "static const odb::id_source id_source = odb::ids_assigned;" @@ -395,6 +409,9 @@ namespace mysql member_count member_count_; image_type image_type_; id_image_type id_image_type_; + + query_column query_column_; + traversal::names query_column_names_; }; } diff --git a/odb/mysql/inline.cxx b/odb/mysql/inline.cxx index 19b1b41..0924077 100644 --- a/odb/mysql/inline.cxx +++ b/odb/mysql/inline.cxx @@ -45,6 +45,28 @@ namespace mysql << "//" << endl << endl; + // query_type + // + os << "inline" << endl + << traits << "::query_type::" << endl + << "query_type ()" + << "{" + << "}"; + + os << "inline" << endl + << traits << "::query_type::" << endl + << "query_type (const std::string& q)" << endl + << " : query_base_type (q)" + << "{" + << "}"; + + os << "inline" << endl + << traits << "::query_type::" << endl + << "query_type (const query_base_type& q)" << endl + << " : query_base_type (q)" + << "{" + << "}"; + // id () // os << "inline" << endl diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx index 68d5493..0e8d420 100644 --- a/odb/mysql/source.cxx +++ b/odb/mysql/source.cxx @@ -672,6 +672,14 @@ namespace mysql << "//" << endl << endl; + // query columns + // + { + query_column t (*this, c); + traversal::names n (t); + names (c, n); + } + // insert_query // os << "const char* const " << traits << "::insert_query =" << endl -- cgit v1.1