aboutsummaryrefslogtreecommitdiff
path: root/odb/mysql
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-08-13 13:44:00 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-08-13 13:44:00 +0200
commitead623bfdd2004988f13d7cade7deaea1b71f7e8 (patch)
tree084c13c08b362d5bc511683316cb51e2eb379e6a /odb/mysql
parent8100d903ef92d2ab3c789317fd1f187089ece8a7 (diff)
Add support for language-embedded queries
Diffstat (limited to 'odb/mysql')
-rw-r--r--odb/mysql/common.cxx279
-rw-r--r--odb/mysql/common.hxx44
-rw-r--r--odb/mysql/header.cxx39
-rw-r--r--odb/mysql/inline.cxx22
-rw-r--r--odb/mysql/source.cxx8
5 files changed, 381 insertions, 11 deletions
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