aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-08-19 11:24:43 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-08-19 11:24:43 +0200
commit3c5b84f94ac786426591d25edf2f6e19d9506859 (patch)
treec82ae4c78842fe94da68013a74fe3d8834181993
parentc39378136e17f556608b3ea649f2ee9c92104670 (diff)
Add support for automatic object ids
-rw-r--r--odb/context.hxx2
-rw-r--r--odb/mysql/context.cxx14
-rw-r--r--odb/mysql/context.hxx3
-rw-r--r--odb/mysql/schema.cxx170
-rw-r--r--odb/mysql/source.cxx16
-rw-r--r--odb/pragma.cxx47
6 files changed, 163 insertions, 89 deletions
diff --git a/odb/context.hxx b/odb/context.hxx
index 3ca8d1e..59fa630 100644
--- a/odb/context.hxx
+++ b/odb/context.hxx
@@ -47,7 +47,7 @@ public:
string
column_name (semantics::data_member&) const;
- string
+ virtual string
column_type (semantics::data_member&) const;
public:
diff --git a/odb/mysql/context.cxx b/odb/mysql/context.cxx
index b7707cb..1778c93 100644
--- a/odb/mysql/context.cxx
+++ b/odb/mysql/context.cxx
@@ -76,6 +76,20 @@ namespace mysql
{
}
+ string context::
+ column_type (semantics::data_member& m) const
+ {
+ string r (::context::column_type (m));
+
+ if (m.count ("auto"))
+ r += " AUTO_INCREMENT";
+
+ std::cerr << r << std::endl;
+
+
+ return r;
+ }
+
static sql_type
parse_sql_type (semantics::data_member& m, std::string const& sql);
diff --git a/odb/mysql/context.hxx b/odb/mysql/context.hxx
index 4007bda..e91320e 100644
--- a/odb/mysql/context.hxx
+++ b/odb/mysql/context.hxx
@@ -87,6 +87,9 @@ namespace mysql
data* data_;
public:
+ virtual string
+ column_type (semantics::data_member&) const;
+
sql_type const&
db_type (semantics::data_member&);
diff --git a/odb/mysql/schema.cxx b/odb/mysql/schema.cxx
index b405016..866cfcc 100644
--- a/odb/mysql/schema.cxx
+++ b/odb/mysql/schema.cxx
@@ -6,124 +6,124 @@
#include <set>
#include <odb/mysql/schema.hxx>
-namespace
+namespace mysql
{
- struct data_member: traversal::data_member, context
+ namespace
{
- data_member (context& c)
- : context (c), first_ (true)
+ struct data_member: traversal::data_member, context
{
- }
+ data_member (context& c)
+ : context (c), first_ (true)
+ {
+ }
- virtual void
- traverse (type& m)
- {
- if (m.count ("transient"))
- return;
+ virtual void
+ traverse (type& m)
+ {
+ if (m.count ("transient"))
+ return;
- if (first_)
- first_ = false;
- else
- os << "," << endl;
+ if (first_)
+ first_ = false;
+ else
+ os << "," << endl;
- os << " `" << column_name (m) << "` " << column_type (m);
+ os << " `" << column_name (m) << "` " << column_type (m);
- if (m.count ("id"))
- os << " PRIMARY KEY";
- }
+ if (m.count ("id"))
+ os << " PRIMARY KEY";
+ }
- private:
- bool first_;
- };
+ private:
+ bool first_;
+ };
- struct class_create: traversal::class_, context
- {
- class_create (context& c)
- : context (c)
+ struct class_create: traversal::class_, context
{
- }
+ class_create (context& c)
+ : context (c)
+ {
+ }
- virtual void
- traverse (type& c)
- {
- if (c.file () != unit.file ())
- return;
+ virtual void
+ traverse (type& c)
+ {
+ if (c.file () != unit.file ())
+ return;
- if (!c.count ("object"))
- return;
+ if (!c.count ("object"))
+ return;
- string const& name (table_name (c));
+ string const& name (table_name (c));
- // If the table with this name was already created, assume the
- // user knows what they are doing and skip it.
- //
- if (tables_.count (name))
- return;
+ // If the table with this name was already created, assume the
+ // user knows what they are doing and skip it.
+ //
+ if (tables_.count (name))
+ return;
- os << "CREATE TABLE `" << name << "` (" << endl;
+ os << "CREATE TABLE `" << name << "` (" << endl;
- {
- data_member m (*this);
- traversal::names n (m);
- names (c, n);
- }
+ {
+ data_member m (*this);
+ traversal::names n (m);
+ names (c, n);
+ }
- os << ")";
+ os << ")";
- string const& engine (options.mysql_engine ());
+ string const& engine (options.mysql_engine ());
- if (engine != "default")
- os << endl
- << " ENGINE=" << engine;
+ if (engine != "default")
+ os << endl
+ << " ENGINE=" << engine;
- os << ";" << endl
- << endl;
+ os << ";" << endl
+ << endl;
- tables_.insert (name);
- }
+ tables_.insert (name);
+ }
- private:
- std::set<string> tables_;
- };
+ private:
+ std::set<string> tables_;
+ };
- struct class_drop: traversal::class_, context
- {
- class_drop (context& c)
- : context (c)
+ struct class_drop: traversal::class_, context
{
- }
+ class_drop (context& c)
+ : context (c)
+ {
+ }
- virtual void
- traverse (type& c)
- {
- if (c.file () != unit.file ())
- return;
+ virtual void
+ traverse (type& c)
+ {
+ if (c.file () != unit.file ())
+ return;
- if (!c.count ("object"))
- return;
+ if (!c.count ("object"))
+ return;
- string const& name (table_name (c));
+ string const& name (table_name (c));
- if (tables_.count (name))
- return;
+ if (tables_.count (name))
+ return;
- os << "DROP TABLE IF EXISTS `" << name << "`;" << endl;
+ os << "DROP TABLE IF EXISTS `" << name << "`;" << endl;
- tables_.insert (name);
- }
+ tables_.insert (name);
+ }
- private:
- std::set<string> tables_;
- };
-}
+ private:
+ std::set<string> tables_;
+ };
-static char const file_header[] =
- "/* This file was generated by CodeSynthesis ODB object persistence\n"
- " * compiler for C++.\n"
- " */\n\n";
+ static char const file_header[] =
+ "/* This file was generated by CodeSynthesis ODB object persistence\n"
+ " * compiler for C++.\n"
+ " */\n\n";
+ }
-namespace mysql
-{
void
generate_schema (context& ctx)
{
diff --git a/odb/mysql/source.cxx b/odb/mysql/source.cxx
index 1e91344..9d47541 100644
--- a/odb/mysql/source.cxx
+++ b/odb/mysql/source.cxx
@@ -838,12 +838,22 @@ namespace mysql
<< "object_statements<object_type>& sts (" << endl
<< "conn.statement_cache ().find<object_type> ());"
<< "binding& b (sts.image_binding ());"
- << endl
+ << endl;
+
+ if (id.count ("auto"))
+ os << "obj." << id.name () << " = 0;";
+
+ os << endl
<< "if (init (sts.image (), obj) || b.version == 0)" << endl
<< "bind (b, sts.image ());"
<< endl
- << "sts.persist_statement ().execute ();"
- << "}";
+ << "mysql::persist_statement& st (sts.persist_statement ());"
+ << "st.execute ();";
+
+ if (id.count ("auto"))
+ os << "obj." << id.name () << " = static_cast<id_type> (st.id ());";
+
+ os << "}";
// store ()
//
diff --git a/odb/pragma.cxx b/odb/pragma.cxx
index 0dcbf36..04291e1 100644
--- a/odb/pragma.cxx
+++ b/odb/pragma.cxx
@@ -85,6 +85,7 @@ check_decl_type (tree d, string const& name, string const& p, location_t l)
char const* pc (p.c_str ());
if (p == "id" ||
+ p == "auto" ||
p == "column" ||
p == "type" ||
p == "transient")
@@ -255,6 +256,45 @@ handle_pragma (string const& p)
}
}
}
+ else if (p == "auto")
+ {
+ // auto [(<identifier>)]
+ //
+
+ tt = pragma_lex (&t);
+
+ if (tt == CPP_OPEN_PAREN)
+ {
+ tt = pragma_lex (&t);
+
+ if (tt == CPP_NAME || tt == CPP_SCOPE)
+ {
+ string name;
+ decl = parse_scoped_name (t, tt, name, false, p);
+
+ if (decl == 0)
+ return;
+
+ // Make sure we've got the correct declaration type.
+ //
+ if (!check_decl_type (decl, name, p, loc))
+ return;
+
+ if (tt != CPP_CLOSE_PAREN)
+ {
+ error ("%qs expected at the end of odb pragma %qs", ")", pc);
+ return;
+ }
+
+ tt = pragma_lex (&t);
+ }
+ else
+ {
+ error ("data member name expected in odb pragma %qs", pc);
+ return;
+ }
+ }
+ }
else if (p == "column")
{
// column ([<identifier>,] "<name>")
@@ -447,6 +487,12 @@ handle_pragma_odb_id (cpp_reader*)
}
extern "C" void
+handle_pragma_odb_auto (cpp_reader*)
+{
+ handle_pragma ("auto");
+}
+
+extern "C" void
handle_pragma_odb_column (cpp_reader*)
{
handle_pragma ("column");
@@ -470,6 +516,7 @@ register_odb_pragmas (void*, void*)
c_register_pragma_with_expansion ("odb", "object", handle_pragma_odb_object);
c_register_pragma_with_expansion ("odb", "table", handle_pragma_odb_table);
c_register_pragma_with_expansion ("odb", "id", handle_pragma_odb_id);
+ c_register_pragma_with_expansion ("odb", "auto", handle_pragma_odb_auto);
c_register_pragma_with_expansion ("odb", "column", handle_pragma_odb_column);
c_register_pragma_with_expansion ("odb", "type", handle_pragma_odb_type);
c_register_pragma_with_expansion ("odb", "transient", handle_pragma_odb_transient);