aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-03-16 07:44:43 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-04-10 18:46:43 +0200
commit08b159e18527c2d6844e569b1309b5033b4d47c9 (patch)
tree224a1d6e7c989740e9be806c0f3cc7fc20266eb2
parent9fe60de16cf9411a548c020cae5ac7b9e7938e82 (diff)
Add initial support for database model serialization to XML
-rw-r--r--odb/relational/model.cxx2
-rw-r--r--odb/relational/model.hxx59
-rw-r--r--odb/relational/schema.hxx2
-rw-r--r--odb/semantics/relational/column.cxx36
-rw-r--r--odb/semantics/relational/column.hxx15
-rw-r--r--odb/semantics/relational/elements.cxx5
-rw-r--r--odb/semantics/relational/elements.hxx49
-rw-r--r--odb/semantics/relational/elements.txx80
-rw-r--r--odb/semantics/relational/foreign-key.cxx100
-rw-r--r--odb/semantics/relational/foreign-key.hxx53
-rw-r--r--odb/semantics/relational/index.cxx35
-rw-r--r--odb/semantics/relational/index.hxx22
-rw-r--r--odb/semantics/relational/key.cxx45
-rw-r--r--odb/semantics/relational/key.hxx6
-rw-r--r--odb/semantics/relational/model.cxx20
-rw-r--r--odb/semantics/relational/model.hxx24
-rw-r--r--odb/semantics/relational/primary-key.cxx26
-rw-r--r--odb/semantics/relational/primary-key.hxx5
-rw-r--r--odb/semantics/relational/table.cxx38
-rw-r--r--odb/semantics/relational/table.hxx43
-rw-r--r--odb/traversal/relational/table.hxx2
21 files changed, 514 insertions, 153 deletions
diff --git a/odb/relational/model.cxx b/odb/relational/model.cxx
index 57f5aea..fd7c9d9 100644
--- a/odb/relational/model.cxx
+++ b/odb/relational/model.cxx
@@ -68,7 +68,7 @@ namespace relational
generate ()
{
context ctx;
- cutl::shared_ptr<sema_rel::model> m (new (shared) sema_rel::model);
+ cutl::shared_ptr<sema_rel::model> m (new (shared) sema_rel::model (0)); //@@ evo
traversal::unit unit;
traversal::defines unit_defines;
diff --git a/odb/relational/model.hxx b/odb/relational/model.hxx
index fa09f2d..b0fef6d 100644
--- a/odb/relational/model.hxx
+++ b/odb/relational/model.hxx
@@ -26,9 +26,12 @@ namespace relational
{
typedef object_columns base;
- object_columns (sema_rel::model& model, sema_rel::table& table)
+ object_columns (sema_rel::model& model,
+ sema_rel::table& table,
+ bool object)
: model_ (model),
table_ (table),
+ object_ (object),
pkey_ (0),
id_override_ (false)
{
@@ -187,7 +190,7 @@ namespace relational
string const& /* id */,
sema_rel::column& c)
{
- if (table_.is_a<sema_rel::object_table> ())
+ if (object_)
{
if (semantics::data_member* idm = id ())
{
@@ -228,8 +231,9 @@ namespace relational
(key_prefix_.empty () ? m.name () : key_prefix_));
bool deferred (m.get<bool> ("deferred", true));
- foreign_key::action on_delete (
- m.get<foreign_key::action> ("on-delete", foreign_key::no_action));
+ foreign_key::action_type on_delete (
+ m.get<foreign_key::action_type> (
+ "on-delete", foreign_key::no_action));
foreign_key& fk (
model_.new_node<foreign_key> (
@@ -320,6 +324,7 @@ namespace relational
protected:
sema_rel::model& model_;
sema_rel::table& table_;
+ bool object_;
sema_rel::primary_key* pkey_;
string id_prefix_;
bool id_override_;
@@ -384,11 +389,9 @@ namespace relational
for (object_columns_list::iterator i (ocl->begin ());
i != ocl->end (); ++i)
{
- column& c (
- dynamic_cast<column&> (
- table_.find (i->name)->nameable ()));
-
- model_.new_edge<sema_rel::contains> (in, c, im.options);
+ column* c (table_.find<column> (i->name));
+ assert (c != 0);
+ model_.new_edge<sema_rel::contains> (in, *c, im.options);
}
}
else
@@ -396,11 +399,9 @@ namespace relational
// Simple value. Get the column name and look it up in the
// table.
//
- column& c (
- dynamic_cast<column&> (
- table_.find (column_name (im.path))->nameable ()));
-
- model_.new_edge<sema_rel::contains> (in, c, im.options);
+ column* c (table_.find<column> (column_name (im.path)));
+ assert (c != 0);
+ model_.new_edge<sema_rel::contains> (in, *c, im.options);
}
}
}
@@ -486,15 +487,15 @@ namespace relational
//
string id (id_prefix_ + m.name () + "[]");
- sema_rel::container_table& t (
- model_.new_node<sema_rel::container_table> (id));
+ sema_rel::table& t (model_.new_node<sema_rel::table> (id));
t.set ("cxx-location", m.location ());
model_.new_edge<sema_rel::qnames> (model_, t, name);
// object_id
//
{
- instance<object_columns> oc (model_, t);
+ bool f (false); //@@ (im)persfect forwarding.
+ instance<object_columns> oc (model_, t, f);
oc->traverse (m, container_idt (m), "id", "object_id");
}
@@ -597,8 +598,11 @@ namespace relational
{
// Column.
//
- instance<object_columns> oc (model_, t);
- oc->traverse (m, container_it (ct), "index", "index");
+ {
+ bool f (false); //@@ (im)persfect forwarding.
+ instance<object_columns> oc (model_, t, f);
+ oc->traverse (m, container_it (ct), "index", "index");
+ }
// This is a simple value so the name cannot be empty. It is
// also a top-level column, so there is no column prefix.
@@ -631,9 +635,12 @@ namespace relational
? sin->name
: index_name (name, col));
+ column* c (t.find<column> (col));
+ assert (c != 0);
+
model_.new_edge<sema_rel::contains> (
*in,
- dynamic_cast<column&> (t.find (col)->nameable ()),
+ *c,
(sin != 0 ? sin->members.back ().options : ""));
}
@@ -641,14 +648,16 @@ namespace relational
//
if (ck == ck_map || ck == ck_multimap)
{
- instance<object_columns> oc (model_, t);
+ bool f (false); //@@ (im)persfect forwarding.
+ instance<object_columns> oc (model_, t, f);
oc->traverse (m, container_kt (ct), "key", "key");
}
// value
//
{
- instance<object_columns> oc (model_, t);
+ bool f (false); //@@ (im)persfect forwarding.
+ instance<object_columns> oc (model_, t, f);
oc->traverse (m, container_vt (ct), "value", "value");
}
}
@@ -693,8 +702,7 @@ namespace relational
string id (class_fq_name (c), 2); // Remove leading '::'.
- sema_rel::object_table& t(
- model_.new_node<sema_rel::object_table> (id));
+ sema_rel::table& t(model_.new_node<sema_rel::table> (id));
t.set ("cxx-location", c.location ());
model_.new_edge<sema_rel::qnames> (model_, t, name);
@@ -703,7 +711,8 @@ namespace relational
// Add columns.
//
{
- instance<object_columns> oc (model_, t);
+ bool tr (true); //@@ (im)persfect forwarding.
+ instance<object_columns> oc (model_, t, tr);
oc->traverse (c);
}
diff --git a/odb/relational/schema.hxx b/odb/relational/schema.hxx
index e855969..86b7419 100644
--- a/odb/relational/schema.hxx
+++ b/odb/relational/schema.hxx
@@ -435,7 +435,7 @@ namespace relational
}
virtual void
- on_delete (sema_rel::foreign_key::action a)
+ on_delete (sema_rel::foreign_key::action_type a)
{
using sema_rel::foreign_key;
diff --git a/odb/semantics/relational/column.cxx b/odb/semantics/relational/column.cxx
index 52385cc..a4c39c3 100644
--- a/odb/semantics/relational/column.cxx
+++ b/odb/semantics/relational/column.cxx
@@ -3,13 +3,41 @@
// license : GNU GPL v3; see accompanying LICENSE file
#include <cutl/compiler/type-info.hxx>
-
-#include <odb/semantics/relational/column.hxx>
+#include <odb/semantics/relational.hxx>
namespace semantics
{
namespace relational
{
+ column::
+ column (xml::parser& p, uscope&, graph& g)
+ : unameable (p, g),
+ type_ (p.attribute ("type", string ())),
+ null_ (p.attribute<bool> ("null")),
+ default__ (p.attribute ("default", string ())),
+ options_ (p.attribute ("options", string ()))
+ {
+ p.content (xml::parser::empty);
+ }
+
+ void column::
+ serialize (xml::serializer& s) const
+ {
+ s.start_element (xmlns, "column");
+ unameable::serialize_attributes (s);
+
+ s.attribute ("type", type ());
+ s.attribute ("null", null ()); // Output even if false.
+
+ if (!default_ ().empty ())
+ s.attribute ("default", default_ ());
+
+ if (!options ().empty ())
+ s.attribute ("options", options ());
+
+ s.end_element ();
+ }
+
// type info
//
namespace
@@ -18,10 +46,10 @@ namespace semantics
{
init ()
{
+ unameable::parser_map_["column"] = &unameable::parser_impl<column>;
+
using compiler::type_info;
- // column
- //
{
type_info ti (typeid (column));
ti.add_base (typeid (unameable));
diff --git a/odb/semantics/relational/column.hxx b/odb/semantics/relational/column.hxx
index 621e354..19aed98 100644
--- a/odb/semantics/relational/column.hxx
+++ b/odb/semantics/relational/column.hxx
@@ -19,11 +19,6 @@ namespace semantics
typedef std::vector<contains*> contained_list;
public:
- column (string const& id, string const& type, bool null)
- : unameable (id), type_ (type), null_ (null)
- {
- }
-
string const&
type () const
{
@@ -89,6 +84,13 @@ namespace semantics
}
public:
+ column (string const& id, string const& type, bool null)
+ : unameable (id), type_ (type), null_ (null)
+ {
+ }
+
+ column (xml::parser&, uscope&, graph&);
+
void
add_edge_right (contains& e)
{
@@ -103,6 +105,9 @@ namespace semantics
return "column";
}
+ virtual void
+ serialize (xml::serializer&) const;
+
private:
string type_;
bool null_;
diff --git a/odb/semantics/relational/elements.cxx b/odb/semantics/relational/elements.cxx
index f8f3591..89aa014 100644
--- a/odb/semantics/relational/elements.cxx
+++ b/odb/semantics/relational/elements.cxx
@@ -3,13 +3,14 @@
// license : GNU GPL v3; see accompanying LICENSE file
#include <cutl/compiler/type-info.hxx>
-
-#include <odb/semantics/relational/elements.hxx>
+#include <odb/semantics/relational.hxx>
namespace semantics
{
namespace relational
{
+ string const xmlns = "http://www.codesynthesis.com/xmlns/odb/changelog";
+
// duplicate_name
//
template <>
diff --git a/odb/semantics/relational/elements.hxx b/odb/semantics/relational/elements.hxx
index 851fbb3..76a92bc 100644
--- a/odb/semantics/relational/elements.hxx
+++ b/odb/semantics/relational/elements.hxx
@@ -15,6 +15,9 @@
#include <cutl/container/pointer-iterator.hxx>
#include <cutl/compiler/context.hxx>
+#include <cutl/xml/parser.hxx>
+#include <cutl/xml/serializer.hxx>
+
#include <odb/semantics/relational/name.hxx>
namespace semantics
@@ -25,16 +28,22 @@ namespace semantics
using std::string;
- using container::graph;
using container::pointer_iterator;
-
using compiler::context;
+ typedef unsigned int version;
+
+ //
+ //
+ extern string const xmlns;
+
//
//
class node;
class edge;
+ typedef container::graph<node, edge> graph;
+
//
//
class edge: public context
@@ -65,6 +74,12 @@ namespace semantics
virtual string
kind () const = 0;
+ // XML serialization.
+ //
+ public:
+ virtual void
+ serialize (xml::serializer&) const = 0;
+
public:
template <typename X>
bool
@@ -190,6 +205,21 @@ namespace semantics
using node::add_edge_right;
+ protected:
+ nameable (xml::parser&, graph& g);
+
+ void
+ serialize_attributes (xml::serializer&) const;
+
+ public:
+ typedef void (*parser_func) (xml::parser&, scope_type&, graph&);
+ typedef std::map<std::string, parser_func> parser_map;
+ static parser_map parser_map_;
+
+ template <typename T>
+ static void
+ parser_impl (xml::parser&, scope_type&, graph&);
+
private:
string id_;
names_type* named_;
@@ -264,6 +294,10 @@ namespace semantics
// Find.
//
+ template <typename T>
+ T*
+ find (name_type const&);
+
names_iterator
find (name_type const&);
@@ -277,14 +311,17 @@ namespace semantics
find (names_type const&) const;
public:
- scope ()
- : first_key_ (names_.end ())
- {
- }
+ scope (): first_key_ (names_.end ()) {}
void
add_edge_left (names_type&);
+ protected:
+ scope (xml::parser&, graph&);
+
+ void
+ serialize_content (xml::serializer&) const;
+
private:
names_list names_;
names_map names_map_;
diff --git a/odb/semantics/relational/elements.txx b/odb/semantics/relational/elements.txx
index 9415cab..05ae06d 100644
--- a/odb/semantics/relational/elements.txx
+++ b/odb/semantics/relational/elements.txx
@@ -6,10 +6,58 @@ namespace semantics
{
namespace relational
{
+ // nameable
+ //
+ template <typename N>
+ typename nameable<N>::parser_map nameable<N>::parser_map_;
+
+ template <typename N>
+ template <typename T>
+ void nameable<N>::
+ parser_impl (xml::parser& p, scope_type& s, graph& g)
+ {
+ name_type n (p.attribute ("name", name_type ()));
+ T& x (g.new_node<T> (p, s, g));
+ g.new_edge<names_type> (s, x, n);
+ }
+
+ template <typename N>
+ nameable<N>::
+ nameable (xml::parser&, graph&)
+ // : id_ (p.attribute<string> ("id"))
+ : named_ (0)
+ {
+ // The name attribute is handled in parser_impl().
+ }
+
+ template <typename N>
+ void nameable<N>::
+ serialize_attributes (xml::serializer& s) const
+ {
+ // Omit empty names (e.g., a primary key).
+ //
+ name_type const& n (name ());
+ if (!n.empty ())
+ s.attribute ("name", n);
+
+ //s.attribute ("id", id_);
+ }
+
// scope
//
template <typename N>
+ template <typename T>
+ T* scope<N>::
+ find (name_type const& name)
+ {
+ typename names_map::iterator i (names_map_.find (name));
+ return i != names_map_.end ()
+ ? dynamic_cast<T*> (&(*i->second)->nameable ())
+ : 0;
+ }
+
+ template <typename N>
typename scope<N>::names_iterator scope<N>::
find (name_type const& name)
{
@@ -49,6 +97,38 @@ namespace semantics
return i != iterator_map_.end () ? i->second : names_.end ();
}
+ template <typename N>
+ scope<N>::
+ scope (xml::parser& p, graph& g)
+ : first_key_ (names_.end ())
+ {
+ using namespace xml;
+ p.content (parser::complex);
+
+ for (parser::event_type e (p.peek ());
+ e == parser::start_element;
+ e = p.peek ())
+ {
+ typename nameable_type::parser_map::iterator i (
+ nameable_type::parser_map_.find (p.name ()));
+
+ if (p.namespace_ () != xmlns || i == nameable_type::parser_map_.end ())
+ break; // Not one of our elements.
+
+ p.next ();
+ i->second (p, *this, g);
+ p.next_expect (parser::end_element);
+ }
+ }
+
+ template <typename N>
+ void scope<N>::
+ serialize_content (xml::serializer& s) const
+ {
+ for (names_const_iterator i (names_begin ()); i != names_end (); ++i)
+ i->nameable ().serialize (s);
+ }
+
class column;
class primary_key;
diff --git a/odb/semantics/relational/foreign-key.cxx b/odb/semantics/relational/foreign-key.cxx
index 5ef2cf6..2c73a82 100644
--- a/odb/semantics/relational/foreign-key.cxx
+++ b/odb/semantics/relational/foreign-key.cxx
@@ -2,14 +2,107 @@
// copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
// license : GNU GPL v3; see accompanying LICENSE file
+#include <ostream>
+#include <istream>
+
#include <cutl/compiler/type-info.hxx>
+#include <odb/semantics/relational.hxx>
-#include <odb/semantics/relational/foreign-key.hxx>
+using namespace std;
namespace semantics
{
namespace relational
{
+ static const char* action_str[] = {"NO ACTION", "CASCADE"};
+
+ ostream&
+ operator<< (ostream& os, foreign_key::action_type v)
+ {
+ return os << action_str[v];
+ }
+
+ istream&
+ operator>> (istream& is, foreign_key::action_type& v)
+ {
+ string s;
+ getline (is, s);
+
+ if (!is.eof ())
+ is.setstate (istream::failbit);
+
+ if (!is.fail ())
+ {
+ if (s == "NO ACTION")
+ v = foreign_key::no_action;
+ else if (s == "CASCADE")
+ v = foreign_key::cascade;
+ else
+ is.setstate (istream::failbit);
+ }
+
+ return is;
+ }
+
+ foreign_key::
+ foreign_key (xml::parser& p, uscope& s, graph& g)
+ : key (p, s, g),
+ deferred_ (p.attribute ("deferred", false)),
+ on_delete_ (p.attribute ("on-delete", no_action))
+ {
+ using namespace xml;
+
+ p.next_expect (parser::start_element, xmlns, "references");
+ referenced_table_ = p.attribute<qname> ("table");
+ p.content (parser::complex);
+
+ for (parser::event_type e (p.peek ());
+ e == parser::start_element;
+ e = p.peek ())
+ {
+ if (p.qname () != xml::qname (xmlns, "column"))
+ break; // Not our elements.
+
+ p.next ();
+ referenced_columns_.push_back (p.attribute<uname> ("name"));
+ p.content (parser::empty);
+ p.next_expect (parser::end_element);
+ }
+
+ p.next_expect (parser::end_element);
+ }
+
+ void foreign_key::
+ serialize (xml::serializer& s) const
+ {
+ s.start_element (xmlns, "foreign-key");
+ key::serialize_attributes (s);
+
+ if (deferred ())
+ s.attribute ("deferred", true);
+
+ if (on_delete () != no_action)
+ s.attribute ("on-delete", on_delete ());
+
+ key::serialize_content (s);
+
+ // Referenced columns.
+ //
+ s.start_element (xmlns, "references");
+ s.attribute ("table", referenced_table ());
+
+ for (columns::const_iterator i (referenced_columns_.begin ());
+ i != referenced_columns_.end (); ++i)
+ {
+ s.start_element (xmlns, "column");
+ s.attribute ("name", *i);
+ s.end_element ();
+ }
+
+ s.end_element (); // references
+ s.end_element (); // foreign-key
+ }
+
// type info
//
namespace
@@ -18,10 +111,11 @@ namespace semantics
{
init ()
{
+ unameable::parser_map_["foreign-key"] =
+ &unameable::parser_impl<foreign_key>;
+
using compiler::type_info;
- // foreign_key
- //
{
type_info ti (typeid (foreign_key));
ti.add_base (typeid (unameable));
diff --git a/odb/semantics/relational/foreign-key.hxx b/odb/semantics/relational/foreign-key.hxx
index d4419dd..1c00873 100644
--- a/odb/semantics/relational/foreign-key.hxx
+++ b/odb/semantics/relational/foreign-key.hxx
@@ -5,6 +5,8 @@
#ifndef ODB_SEMANTICS_RELATIONAL_FOREIGN_KEY_HXX
#define ODB_SEMANTICS_RELATIONAL_FOREIGN_KEY_HXX
+#include <iosfwd>
+
#include <odb/semantics/relational/elements.hxx>
#include <odb/semantics/relational/key.hxx>
@@ -15,24 +17,6 @@ namespace semantics
class foreign_key: public key
{
public:
- enum action
- {
- no_action,
- cascade
- };
-
- foreign_key (string const& id,
- qname const& referenced_table,
- bool deferred,
- action on_delete = no_action)
- : key (id),
- referenced_table_ (referenced_table),
- deferred_ (deferred),
- on_delete_ (on_delete)
- {
- }
-
- public:
qname const&
referenced_table () const
{
@@ -60,26 +44,53 @@ namespace semantics
return deferred_;
}
- public:
- action
+ enum action_type
+ {
+ no_action,
+ cascade
+ };
+
+ action_type
on_delete () const
{
return on_delete_;
}
public:
+ foreign_key (string const& id,
+ qname const& referenced_table,
+ bool deferred,
+ action_type on_delete = no_action)
+ : key (id),
+ referenced_table_ (referenced_table),
+ deferred_ (deferred),
+ on_delete_ (on_delete)
+ {
+ }
+
+ foreign_key (xml::parser&, uscope&, graph&);
+
virtual string
kind () const
{
return "foreign key";
}
+ virtual void
+ serialize (xml::serializer&) const;
+
private:
qname referenced_table_;
columns referenced_columns_;
bool deferred_;
- action on_delete_;
+ action_type on_delete_;
};
+
+ std::ostream&
+ operator<< (std::ostream&, foreign_key::action_type);
+
+ std::istream&
+ operator>> (std::istream&, foreign_key::action_type&);
}
}
diff --git a/odb/semantics/relational/index.cxx b/odb/semantics/relational/index.cxx
index 11cce8d..0e62f98 100644
--- a/odb/semantics/relational/index.cxx
+++ b/odb/semantics/relational/index.cxx
@@ -3,13 +3,40 @@
// license : GNU GPL v3; see accompanying LICENSE file
#include <cutl/compiler/type-info.hxx>
-
-#include <odb/semantics/relational/index.hxx>
+#include <odb/semantics/relational.hxx>
namespace semantics
{
namespace relational
{
+ index::
+ index (xml::parser& p, uscope& s, graph& g)
+ : key (p, s, g),
+ type_ (p.attribute ("type", string ())),
+ method_ (p.attribute ("method", string ())),
+ options_ (p.attribute ("options", string ()))
+ {
+ }
+
+ void index::
+ serialize (xml::serializer& s) const
+ {
+ s.start_element (xmlns, "index");
+ key::serialize_attributes (s);
+
+ if (!type ().empty ())
+ s.attribute ("type", type ());
+
+ if (!method ().empty ())
+ s.attribute ("method", method ());
+
+ if (!options ().empty ())
+ s.attribute ("options", options ());
+
+ key::serialize_content (s);
+ s.end_element ();
+ }
+
// type info
//
namespace
@@ -18,10 +45,10 @@ namespace semantics
{
init ()
{
+ unameable::parser_map_["index"] = &unameable::parser_impl<index>;
+
using compiler::type_info;
- // index
- //
{
type_info ti (typeid (index));
ti.add_base (typeid (qnameable));
diff --git a/odb/semantics/relational/index.hxx b/odb/semantics/relational/index.hxx
index ac65eb3..802faa7 100644
--- a/odb/semantics/relational/index.hxx
+++ b/odb/semantics/relational/index.hxx
@@ -17,14 +17,6 @@ namespace semantics
class index: public key
{
public:
- index (string const& id,
- string const& t = string (),
- string const& m = string (),
- string const& o = string ())
- : key (id), type_ (t), method_ (m), options_ (o)
- {
- }
-
string const&
type () const
{
@@ -49,6 +41,20 @@ namespace semantics
return "index";
}
+ public:
+ index (string const& id,
+ string const& t = string (),
+ string const& m = string (),
+ string const& o = string ())
+ : key (id), type_ (t), method_ (m), options_ (o)
+ {
+ }
+
+ index (xml::parser&, uscope&, graph&);
+
+ virtual void
+ serialize (xml::serializer&) const;
+
private:
string type_; // E.g., "UNIQUE", etc.
string method_; // E.g., "BTREE", etc.
diff --git a/odb/semantics/relational/key.cxx b/odb/semantics/relational/key.cxx
index e80366c..2358562 100644
--- a/odb/semantics/relational/key.cxx
+++ b/odb/semantics/relational/key.cxx
@@ -3,13 +3,54 @@
// license : GNU GPL v3; see accompanying LICENSE file
#include <cutl/compiler/type-info.hxx>
-
-#include <odb/semantics/relational/key.hxx>
+#include <odb/semantics/relational.hxx>
namespace semantics
{
namespace relational
{
+ key::
+ key (xml::parser& p, uscope& s, graph& g)
+ : unameable (p, g)
+ {
+ using namespace xml;
+ p.content (parser::complex);
+
+ for (parser::event_type e (p.peek ());
+ e == parser::start_element;
+ e = p.peek ())
+ {
+ if (p.qname () != xml::qname (xmlns, "column"))
+ break; // Not our elements.
+
+ p.next ();
+ p.content (parser::empty);
+
+ uname n (p.attribute<uname> ("name"));
+ column* c (s.find<column> (n));
+ if (c == 0)
+ throw parsing (p, "invalid column name in the 'name' attribute");
+
+ string o (p.attribute ("options", string ()));
+ g.new_edge<contains> (*this, *c, o);
+
+ p.next_expect (parser::end_element);
+ }
+ }
+
+ void key::
+ serialize_content (xml::serializer& s) const
+ {
+ for (contains_iterator i (contains_begin ()); i != contains_end (); ++i)
+ {
+ s.start_element (xmlns, "column");
+ s.attribute ("name", i->column ().name ());
+ if (!i->options ().empty ())
+ s.attribute ("options", i->options ());
+ s.end_element ();
+ }
+ }
+
// type info
//
namespace
diff --git a/odb/semantics/relational/key.hxx b/odb/semantics/relational/key.hxx
index 18439be..edf8c36 100644
--- a/odb/semantics/relational/key.hxx
+++ b/odb/semantics/relational/key.hxx
@@ -95,6 +95,12 @@ namespace semantics
contains_.push_back (&e);
}
+ protected:
+ key (xml::parser&, uscope&, graph&);
+
+ void
+ serialize_content (xml::serializer&) const;
+
private:
contains_list contains_;
};
diff --git a/odb/semantics/relational/model.cxx b/odb/semantics/relational/model.cxx
index bbeea52..a9fe111 100644
--- a/odb/semantics/relational/model.cxx
+++ b/odb/semantics/relational/model.cxx
@@ -3,13 +3,29 @@
// license : GNU GPL v3; see accompanying LICENSE file
#include <cutl/compiler/type-info.hxx>
-
-#include <odb/semantics/relational/model.hxx>
+#include <odb/semantics/relational.hxx>
namespace semantics
{
namespace relational
{
+ model::
+ model (xml::parser& p)
+ : qscope (p, *this),
+ version_ (p.attribute<version_type> ("version"))
+ {
+ }
+
+ void model::
+ serialize (xml::serializer& s) const
+ {
+ s.start_element (xmlns, "model");
+ s.namespace_decl (xmlns, ""); // @@ evo
+ s.attribute ("version", version_);
+ qscope::serialize_content (s);
+ s.end_element ();
+ }
+
// type info
//
namespace
diff --git a/odb/semantics/relational/model.hxx b/odb/semantics/relational/model.hxx
index fa887d3..31715eb 100644
--- a/odb/semantics/relational/model.hxx
+++ b/odb/semantics/relational/model.hxx
@@ -11,18 +11,23 @@ namespace semantics
{
namespace relational
{
- class model: public graph<node, edge>, public qscope
+ class model: public graph, public qscope
{
public:
- model ()
- {
- }
+ typedef relational::version version_type;
+
+ version_type
+ version () const {return version_;}
+
+ public:
+ model (version_type v): version_ (v) {}
+ model (xml::parser&);
virtual string
- kind () const
- {
- return "model";
- }
+ kind () const {return "model";}
+
+ virtual void
+ serialize (xml::serializer&) const;
public:
using qscope::add_edge_left;
@@ -31,6 +36,9 @@ namespace semantics
private:
model (model const&);
model& operator= (model const&);
+
+ private:
+ version_type version_;
};
}
}
diff --git a/odb/semantics/relational/primary-key.cxx b/odb/semantics/relational/primary-key.cxx
index f5e776d..480923d 100644
--- a/odb/semantics/relational/primary-key.cxx
+++ b/odb/semantics/relational/primary-key.cxx
@@ -3,13 +3,30 @@
// license : GNU GPL v3; see accompanying LICENSE file
#include <cutl/compiler/type-info.hxx>
-
-#include <odb/semantics/relational/primary-key.hxx>
+#include <odb/semantics/relational.hxx>
namespace semantics
{
namespace relational
{
+ primary_key::
+ primary_key (xml::parser& p, uscope& s, graph& g)
+ : key (p, s, g),
+ auto__ (p.attribute ("auto", false))
+ {
+ }
+
+ void primary_key::
+ serialize (xml::serializer& s) const
+ {
+ s.start_element (xmlns, "primary-key");
+ key::serialize_attributes (s);
+ if (auto_ ())
+ s.attribute ("auto", true);
+ key::serialize_content (s);
+ s.end_element ();
+ }
+
// type info
//
namespace
@@ -18,10 +35,11 @@ namespace semantics
{
init ()
{
+ unameable::parser_map_["primary-key"] =
+ &unameable::parser_impl<primary_key>;
+
using compiler::type_info;
- // primary_key
- //
{
type_info ti (typeid (primary_key));
ti.add_base (typeid (unameable));
diff --git a/odb/semantics/relational/primary-key.hxx b/odb/semantics/relational/primary-key.hxx
index 8798dcf..88b5bcb 100644
--- a/odb/semantics/relational/primary-key.hxx
+++ b/odb/semantics/relational/primary-key.hxx
@@ -28,12 +28,17 @@ namespace semantics
{
}
+ primary_key (xml::parser&, uscope&, graph&);
+
virtual string
kind () const
{
return "primary key";
}
+ virtual void
+ serialize (xml::serializer&) const;
+
private:
bool auto__;
};
diff --git a/odb/semantics/relational/table.cxx b/odb/semantics/relational/table.cxx
index 725497e..aac50fe 100644
--- a/odb/semantics/relational/table.cxx
+++ b/odb/semantics/relational/table.cxx
@@ -3,13 +3,27 @@
// license : GNU GPL v3; see accompanying LICENSE file
#include <cutl/compiler/type-info.hxx>
-
-#include <odb/semantics/relational/table.hxx>
+#include <odb/semantics/relational.hxx>
namespace semantics
{
namespace relational
{
+ table::
+ table (xml::parser& p, qscope&, graph& g)
+ : qnameable (p, g), uscope (p, g)
+ {
+ }
+
+ void table::
+ serialize (xml::serializer& s) const
+ {
+ s.start_element (xmlns, "table");
+ qnameable::serialize_attributes (s);
+ uscope::serialize_content (s);
+ s.end_element ();
+ }
+
// type info
//
namespace
@@ -18,32 +32,16 @@ namespace semantics
{
init ()
{
+ qnameable::parser_map_["table"] = &qnameable::parser_impl<table>;
+
using compiler::type_info;
- // table
- //
{
type_info ti (typeid (table));
ti.add_base (typeid (qnameable));
ti.add_base (typeid (uscope));
insert (ti);
}
-
- // object_table
- //
- {
- type_info ti (typeid (object_table));
- ti.add_base (typeid (table));
- insert (ti);
- }
-
- // container_table
- //
- {
- type_info ti (typeid (container_table));
- ti.add_base (typeid (table));
- insert (ti);
- }
}
} init_;
}
diff --git a/odb/semantics/relational/table.hxx b/odb/semantics/relational/table.hxx
index 1dc3957..a57a7db 100644
--- a/odb/semantics/relational/table.hxx
+++ b/odb/semantics/relational/table.hxx
@@ -14,45 +14,18 @@ namespace semantics
class table: public qnameable, public uscope
{
public:
- // Resolve ambiguity.
- //
- using qnameable::scope;
-
- protected:
- table (string const& id)
- : qnameable (id)
- {
- }
- };
-
- class object_table: public table
- {
- public:
- object_table (string const& id)
- : table (id)
- {
- }
+ table (string const& id): qnameable (id) {}
+ table (xml::parser&, qscope&, graph&);
virtual string
- kind () const
- {
- return "object table";
- }
- };
+ kind () const {return "table";}
- class container_table: public table
- {
- public:
- container_table (string const& id)
- : table (id)
- {
- }
+ virtual void
+ serialize (xml::serializer&) const;
- virtual string
- kind () const
- {
- return "container table";
- }
+ // Resolve ambiguity.
+ //
+ using qnameable::scope;
};
}
}
diff --git a/odb/traversal/relational/table.hxx b/odb/traversal/relational/table.hxx
index 1aa838a..2f8438a 100644
--- a/odb/traversal/relational/table.hxx
+++ b/odb/traversal/relational/table.hxx
@@ -13,8 +13,6 @@ namespace traversal
namespace relational
{
struct table: scope_template<semantics::relational::table> {};
- struct object_table: scope_template<semantics::relational::table> {};
- struct container_table: scope_template<semantics::relational::table> {};
}
}