From 3c5b84f94ac786426591d25edf2f6e19d9506859 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 19 Aug 2010 11:24:43 +0200 Subject: Add support for automatic object ids --- odb/context.hxx | 2 +- odb/mysql/context.cxx | 14 +++++ odb/mysql/context.hxx | 3 + odb/mysql/schema.cxx | 170 +++++++++++++++++++++++++------------------------- odb/mysql/source.cxx | 16 ++++- odb/pragma.cxx | 47 ++++++++++++++ 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 #include -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 tables_; - }; + private: + std::set 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 tables_; - }; -} + private: + std::set 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& sts (" << endl << "conn.statement_cache ().find ());" << "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 (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 [()] + // + + 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 ([,] "") @@ -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); -- cgit v1.1