From cea6fb57ac8c9a893c0f404fef6c1469f0b6222b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 22 Jul 2010 14:33:21 +0200 Subject: Next chunk of functionality Add SQL language lexer. Implement MySQL type declaration parser. Create sub-directories for databases, currently mysql and tracer. Create MySQL-specific context. --- odb/tracer/header.cxx | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++ odb/tracer/header.hxx | 17 ++++++ odb/tracer/inline.cxx | 76 ++++++++++++++++++++++++ odb/tracer/inline.hxx | 17 ++++++ odb/tracer/source.cxx | 147 +++++++++++++++++++++++++++++++++++++++++++++ odb/tracer/source.hxx | 17 ++++++ 6 files changed, 435 insertions(+) create mode 100644 odb/tracer/header.cxx create mode 100644 odb/tracer/header.hxx create mode 100644 odb/tracer/inline.cxx create mode 100644 odb/tracer/inline.hxx create mode 100644 odb/tracer/source.cxx create mode 100644 odb/tracer/source.hxx (limited to 'odb/tracer') diff --git a/odb/tracer/header.cxx b/odb/tracer/header.cxx new file mode 100644 index 0000000..c023e58 --- /dev/null +++ b/odb/tracer/header.cxx @@ -0,0 +1,161 @@ +// file : odb/tracer/header.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include +#include + +namespace +{ + struct class_: traversal::class_, context + { + class_ (context& c) + : context (c) + { + } + + virtual void + traverse (type& c) + { + if (c.file () != unit.file ()) + return; + + if (!c.count ("object")) + return; + + string const& type (c.fq_name ()); + + // Find the id member and type. + // + id_member t (*this); + t.traverse (c); + + if (t.member () == 0) + { + cerr << c.file () << ":" << c.line () << ":" << c.column () + << " error: no data member designated as object id" << endl; + + cerr << c.file () << ":" << c.line () << ":" << c.column () + << " info: use '#pragma odb id' to specify object id member" + << endl; + + throw generation_failed (); + } + + semantics::data_member& id (*t.member ()); + semantics::type& id_type (id.type ()); + + if (id_type.anonymous ()) + { + // 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 () + << " error: unnamed type in data member declaration" << endl; + + cerr << id.file () << ":" << id.line () << ":" << id.column () + << " info: use 'typedef' to name this type" + << endl; + + throw generation_failed (); + } + + os << "// " << c.name () << endl + << "//" << endl; + + os << "template <>" << endl + << "class access::object_traits< " << type << " >: " << endl + << " public access::object_memory< " << type << " >," << endl + << " public access::object_factory< " << type << " >" + << "{" + << "public:" << endl; + + // object_type & shared_ptr + // + os << "typedef " << type << " object_type;"; + + // id_type + // + os << "typedef " << id_type.fq_name () << " id_type;" + << endl; + + // id_source + // + os << "static const odb::id_source id_source = odb::ids_assigned;" + << endl; + + // type_name () + // + os << "static const char*" << endl + << "type_name ();" + << endl; + + // id () + // + os << "static id_type" << endl + << "id (const object_type&);" + << endl; + + // persist () + // + os << "static void" << endl + << "persist (database&, object_type&);" + << endl; + + // store () + // + os << "static void" << endl + << "store (database&, object_type&);" + << endl; + + // erase () + // + os << "static void" << endl + << "erase (database&, const id_type&);" + << endl; + + // find () + // + os << "static pointer_type" << endl + << "find (database&, const id_type&);" + << endl; + + os << "static bool" << endl + << "find (database&, const id_type&, object_type&);"; + + os << "};"; + } + }; +} + +namespace tracer +{ + 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 + << endl; + + ctx.os << "namespace odb" + << "{"; + + unit.dispatch (ctx.unit); + + ctx.os << "}"; + } +} diff --git a/odb/tracer/header.hxx b/odb/tracer/header.hxx new file mode 100644 index 0000000..0e67712 --- /dev/null +++ b/odb/tracer/header.hxx @@ -0,0 +1,17 @@ +// file : odb/tracer/header.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_TRACER_HEADER_HXX +#define ODB_TRACER_HEADER_HXX + +#include + +namespace tracer +{ + void + generate_header (context&); +} + +#endif // ODB_TRACER_HEADER_HXX diff --git a/odb/tracer/inline.cxx b/odb/tracer/inline.cxx new file mode 100644 index 0000000..6beb8a8 --- /dev/null +++ b/odb/tracer/inline.cxx @@ -0,0 +1,76 @@ +// file : odb/tracer/inline.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include +#include + +namespace +{ + struct class_: traversal::class_, context + { + class_ (context& c) + : context (c) + { + } + + virtual void + traverse (type& c) + { + if (c.file () != unit.file ()) + return; + + if (!c.count ("object")) + return; + + string const& type (c.fq_name ()); + string traits ("access::object_traits< " + type + " >"); + + id_member t (*this); + t.traverse (c); + semantics::data_member& id (*t.member ()); + + os << "// " << c.name () << endl + << "//" << endl + << endl; + + // id () + // + os << "inline" << endl + << traits << "::id_type" << endl + << traits << "::" << endl + << "id (const object_type& obj)" + << "{" + << "return obj." << id.name () << ";" << endl + << "}"; + } + }; +} + +namespace tracer +{ + void + generate_inline (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 << "namespace odb" + << "{"; + + unit.dispatch (ctx.unit); + + ctx.os << "}"; + } +} diff --git a/odb/tracer/inline.hxx b/odb/tracer/inline.hxx new file mode 100644 index 0000000..2b01589 --- /dev/null +++ b/odb/tracer/inline.hxx @@ -0,0 +1,17 @@ +// file : odb/tracer/inline.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_TRACER_INLINE_HXX +#define ODB_TRACER_INLINE_HXX + +#include + +namespace tracer +{ + void + generate_inline (context&); +} + +#endif // ODB_TRACER_INLINE_HXX diff --git a/odb/tracer/source.cxx b/odb/tracer/source.cxx new file mode 100644 index 0000000..e70adf1 --- /dev/null +++ b/odb/tracer/source.cxx @@ -0,0 +1,147 @@ +// file : odb/tracer/source.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include +#include + +namespace +{ + struct class_: traversal::class_, context + { + class_ (context& c) + : context (c) + { + } + + virtual void + traverse (type& c) + { + if (c.file () != unit.file ()) + return; + + if (!c.count ("object")) + return; + + string const& type (c.fq_name ()); + string traits ("access::object_traits< " + type + " >"); + + id_member t (*this); + t.traverse (c); + semantics::data_member& id (*t.member ()); + + os << "// " << c.name () << endl + << "//" << endl + << endl; + + // type_name () + // + os << "const char* " << traits << "::" << endl + << "type_name ()" + << "{" + << "return \"" << type << "\";" + << "}"; + + // persist () + // + os << "void " << traits << "::" << endl + << "persist (database&, object_type& obj)" + << "{" + << "std::cout << \"insert \" << type_name () << \" id \" << " << + "id (obj) << std::endl;" + << endl + << "if (id (obj) == id_type ())" << endl + << "throw object_already_persistent ();" + << "}"; + + // store () + // + os << "void " << traits << "::" << endl + << "store (database&, object_type& obj)" + << "{" + << "std::cout << \"update \" << type_name () << \" id \" << " << + "id (obj) << std::endl;" + << endl + << "if (id (obj) == id_type ())" << endl + << "throw object_not_persistent ();" + << "}"; + + // erase () + // + os << "void " << traits << "::" << endl + << "erase (database&, const id_type& id)" + << "{" + << "std::cout << \"delete \" << type_name () << \" id \" << " << + "id << std::endl;" + << endl + << "if (id == id_type ())" << endl + << "throw object_not_persistent ();" + << "}"; + + // find () + // + os << traits << "::pointer_type" << endl + << traits << "::" << endl + << "find (database&, const id_type& id)" + << "{" + << "std::cout << \"select \" << type_name () << \" id \" << " << + "id << std::endl;" + << endl + << "if (id == id_type ())" << endl + << "return pointer_type (0);" + << endl + << "pointer_type r (access::object_factory< " << type << + " >::create ());" + << "r->" << id.name () << " = id;" + << "return r;" + << "}"; + + os << "bool " << traits << "::" << endl + << "find (database&, const id_type& id, object_type& obj)" + << "{" + << "std::cout << \"select \" << type_name () << \" id \" << " << + "id << std::endl;" + << endl + << "if (id == id_type ())" << endl + << "return false;" + << endl + << "obj." << id.name () << " = id;" + << "return true;" + << "}"; + } + }; +} + +namespace tracer +{ + void + generate_source (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 + << endl; + + ctx.os << "#include " << endl + << endl; + + ctx.os << "namespace odb" + << "{"; + + unit.dispatch (ctx.unit); + + ctx.os << "}"; + } +} diff --git a/odb/tracer/source.hxx b/odb/tracer/source.hxx new file mode 100644 index 0000000..2c82f3a --- /dev/null +++ b/odb/tracer/source.hxx @@ -0,0 +1,17 @@ +// file : odb/tracer/source.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_TRACER_SOURCE_HXX +#define ODB_TRACER_SOURCE_HXX + +#include + +namespace tracer +{ + void + generate_source (context&); +} + +#endif // ODB_TRACER_SOURCE_HXX -- cgit v1.1