summaryrefslogtreecommitdiff
path: root/odb/semantics
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-01-26 12:43:16 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-01-26 12:43:16 +0200
commitaf12ffe836de09ec84f666effa4df347eeb07a43 (patch)
treedc0aec9f8fee545c84be098414772cf2b277c30d /odb/semantics
parentc1d2ec5bbd5969332f3278f39d2a7a8f0abc0493 (diff)
Implement support for database schema
New pragma qualifier: namespace. New pragma specifier: schema. The table specifier was extended to accept a schema prefix. New option: --default- schema. The common/schema test was extended to cover the new functionality.
Diffstat (limited to 'odb/semantics')
-rw-r--r--odb/semantics/namespace.cxx3
-rw-r--r--odb/semantics/namespace.hxx22
-rw-r--r--odb/semantics/relational/column.cxx2
-rw-r--r--odb/semantics/relational/column.hxx6
-rw-r--r--odb/semantics/relational/elements.cxx106
-rw-r--r--odb/semantics/relational/elements.hxx88
-rw-r--r--odb/semantics/relational/elements.txx94
-rw-r--r--odb/semantics/relational/foreign-key.cxx1
-rw-r--r--odb/semantics/relational/foreign-key.hxx10
-rw-r--r--odb/semantics/relational/index.cxx1
-rw-r--r--odb/semantics/relational/index.hxx5
-rw-r--r--odb/semantics/relational/key.cxx2
-rw-r--r--odb/semantics/relational/key.hxx10
-rw-r--r--odb/semantics/relational/model.cxx2
-rw-r--r--odb/semantics/relational/model.hxx6
-rw-r--r--odb/semantics/relational/name.cxx95
-rw-r--r--odb/semantics/relational/name.hxx146
-rw-r--r--odb/semantics/relational/primary-key.cxx1
-rw-r--r--odb/semantics/relational/primary-key.hxx8
-rw-r--r--odb/semantics/relational/table.cxx4
-rw-r--r--odb/semantics/relational/table.hxx4
21 files changed, 479 insertions, 137 deletions
diff --git a/odb/semantics/namespace.cxx b/odb/semantics/namespace.cxx
index 25c1de0..ffba0e8 100644
--- a/odb/semantics/namespace.cxx
+++ b/odb/semantics/namespace.cxx
@@ -10,12 +10,13 @@ namespace semantics
{
namespace_::
namespace_ (path const& file, size_t line, size_t column, tree tn)
- : node (file, line, column, tn)
+ : node (file, line, column, tn), original_ (0)
{
}
namespace_::
namespace_ ()
+ : original_ (0)
{
}
diff --git a/odb/semantics/namespace.hxx b/odb/semantics/namespace.hxx
index 7a886c5..96db4a7 100644
--- a/odb/semantics/namespace.hxx
+++ b/odb/semantics/namespace.hxx
@@ -13,6 +13,25 @@ namespace semantics
class namespace_: public scope
{
public:
+ bool
+ extension () const
+ {
+ return original_ != 0;
+ }
+
+ namespace_&
+ original ()
+ {
+ return *original_;
+ }
+
+ void
+ original (namespace_& ns)
+ {
+ original_ = &ns;
+ }
+
+ public:
namespace_ (path const&, size_t line, size_t column, tree);
// Resolve conflict between scope::scope and nameable::scope.
@@ -21,6 +40,9 @@ namespace semantics
protected:
namespace_ ();
+
+ private:
+ namespace_* original_;
};
}
diff --git a/odb/semantics/relational/column.cxx b/odb/semantics/relational/column.cxx
index 99df5d9..c3182eb 100644
--- a/odb/semantics/relational/column.cxx
+++ b/odb/semantics/relational/column.cxx
@@ -25,7 +25,7 @@ namespace semantics
//
{
type_info ti (typeid (column));
- ti.add_base (typeid (nameable));
+ ti.add_base (typeid (unameable));
insert (ti);
}
}
diff --git a/odb/semantics/relational/column.hxx b/odb/semantics/relational/column.hxx
index a1024cf..56487c6 100644
--- a/odb/semantics/relational/column.hxx
+++ b/odb/semantics/relational/column.hxx
@@ -15,13 +15,13 @@ namespace semantics
{
class contains;
- class column: public nameable
+ class column: public unameable
{
typedef std::vector<contains*> contained_list;
public:
column (string const& id, string const& type, bool null)
- : nameable (id), type_ (type), null_ (null)
+ : unameable (id), type_ (type), null_ (null)
{
}
@@ -96,7 +96,7 @@ namespace semantics
contained_.push_back (&e);
}
- using nameable::add_edge_right;
+ using unameable::add_edge_right;
virtual string
kind () const
diff --git a/odb/semantics/relational/elements.cxx b/odb/semantics/relational/elements.cxx
index 6ab977a..42755c8 100644
--- a/odb/semantics/relational/elements.cxx
+++ b/odb/semantics/relational/elements.cxx
@@ -6,87 +6,27 @@
#include <cutl/compiler/type-info.hxx>
#include <odb/semantics/relational/elements.hxx>
-#include <odb/semantics/relational/column.hxx>
-#include <odb/semantics/relational/primary-key.hxx>
namespace semantics
{
namespace relational
{
- // scope
+ // duplicate_name
//
-
- scope::names_iterator scope::
- find (string const& name)
- {
- names_map::iterator i (names_map_.find (name));
-
- if (i == names_map_.end ())
- return names_.end ();
- else
- return i->second;
- }
-
- scope::names_const_iterator scope::
- find (string const& name) const
+ template <>
+ duplicate_name::
+ duplicate_name (uscope& s, unameable& o, unameable& d)
+ : scope (s), orig (o), dup (d),
+ orig_name (o.name ()), dup_name (d.name ())
{
- names_map::const_iterator i (names_map_.find (name));
-
- if (i == names_map_.end ())
- return names_.end ();
- else
- return names_const_iterator (i->second);
}
- scope::names_iterator scope::
- find (names const& e)
+ template <>
+ duplicate_name::
+ duplicate_name (qscope& s, qnameable& o, qnameable& d)
+ : scope (s), orig (o), dup (d),
+ orig_name (o.name ().string ()), dup_name (d.name ().string ())
{
- names_iterator_map::iterator i (iterator_map_.find (&e));
- return i != iterator_map_.end () ? i->second : names_.end ();
- }
-
- scope::names_const_iterator scope::
- find (names const& e) const
- {
- names_iterator_map::const_iterator i (iterator_map_.find (&e));
- return i != iterator_map_.end () ? i->second : names_.end ();
- }
-
- void scope::
- add_edge_left (names& e)
- {
- nameable& n (e.nameable ());
- string const& name (e.name ());
-
- names_map::iterator i (names_map_.find (name));
-
- if (i == names_map_.end ())
- {
- names_list::iterator i;
-
- // We want the order to be columns first, then the primary key,
- // and then the foreign keys.
- //
- if (n.is_a<column> ())
- i = names_.insert (first_key_, &e);
- else
- {
- if (n.is_a<primary_key> ())
- first_key_ = i = names_.insert (first_key_, &e);
- else
- {
- i = names_.insert (names_.end (), &e);
-
- if (first_key_ == names_.end ())
- first_key_ = i;
- }
- }
-
- names_map_[name] = i;
- iterator_map_[&e] = i;
- }
- else
- throw duplicate_name (*this, (*i->second)->nameable (), n);
}
// type info
@@ -110,7 +50,13 @@ namespace semantics
// names
//
{
- type_info ti (typeid (names));
+ type_info ti (typeid (unames));
+ ti.add_base (typeid (edge));
+ insert (ti);
+ }
+
+ {
+ type_info ti (typeid (qnames));
ti.add_base (typeid (edge));
insert (ti);
}
@@ -118,7 +64,13 @@ namespace semantics
// nameable
//
{
- type_info ti (typeid (nameable));
+ type_info ti (typeid (unameable));
+ ti.add_base (typeid (node));
+ insert (ti);
+ }
+
+ {
+ type_info ti (typeid (qnameable));
ti.add_base (typeid (node));
insert (ti);
}
@@ -126,7 +78,13 @@ namespace semantics
// scope
//
{
- type_info ti (typeid (scope));
+ type_info ti (typeid (uscope));
+ ti.add_base (typeid (node));
+ insert (ti);
+ }
+
+ {
+ type_info ti (typeid (qscope));
ti.add_base (typeid (node));
insert (ti);
}
diff --git a/odb/semantics/relational/elements.hxx b/odb/semantics/relational/elements.hxx
index d07902d..d8711b3 100644
--- a/odb/semantics/relational/elements.hxx
+++ b/odb/semantics/relational/elements.hxx
@@ -16,6 +16,8 @@
#include <cutl/container/pointer-iterator.hxx>
#include <cutl/compiler/context.hxx>
+#include <odb/semantics/relational/name.hxx>
+
namespace semantics
{
namespace relational
@@ -84,18 +86,23 @@ namespace semantics
//
//
+ template <typename N>
class scope;
+
+ template <typename N>
class nameable;
//
//
+ template <typename N>
class names: public edge
{
public:
- typedef relational::scope scope_type;
- typedef relational::nameable nameable_type;
+ typedef N name_type;
+ typedef relational::scope<N> scope_type;
+ typedef relational::nameable<N> nameable_type;
- string const&
+ name_type const&
name () const
{
return name_;
@@ -114,7 +121,7 @@ namespace semantics
}
public:
- names (string const& name): name_ (name) {}
+ names (name_type const& name): name_ (name) {}
void
set_left_node (scope_type& n)
@@ -129,19 +136,25 @@ namespace semantics
}
protected:
- string name_;
+ name_type name_;
scope_type* scope_;
nameable_type* nameable_;
};
+ typedef names<uname> unames;
+ typedef names<qname> qnames;
+
//
//
+ template <typename N>
class nameable: public virtual node
{
public:
- typedef relational::scope scope_type;
+ typedef N name_type;
+ typedef relational::names<N> names_type;
+ typedef relational::scope<N> scope_type;
- string const&
+ name_type const&
name () const
{
return named_->name ();
@@ -153,7 +166,7 @@ namespace semantics
return named ().scope ();
}
- names&
+ names_type&
named () const
{
return *named_;
@@ -170,7 +183,7 @@ namespace semantics
nameable (string const& id): id_ (id), named_ (0) {}
void
- add_edge_right (names& e)
+ add_edge_right (names_type& e)
{
assert (named_ == 0);
named_ = &e;
@@ -180,38 +193,48 @@ namespace semantics
private:
string id_;
- names* named_;
+ names_type* named_;
};
+ typedef nameable<uname> unameable;
+ typedef nameable<qname> qnameable;
+
//
//
struct duplicate_name
{
- typedef relational::scope scope_type;
- typedef relational::nameable nameable_type;
+ template <typename N>
+ duplicate_name (relational::scope<N>&,
+ relational::nameable<N>& orig,
+ relational::nameable<N>& dup);
- duplicate_name (scope_type& s, nameable_type& n, nameable_type& d)
- : scope (s), nameable (n), duplicate (d)
- {
- }
+ node& scope;
+ node& orig;
+ node& dup;
- scope_type& scope;
- nameable_type& nameable;
- nameable_type& duplicate;
+ string orig_name;
+ string dup_name;
};
+ template <typename N>
class scope: public virtual node
{
protected:
- typedef std::list<names*> names_list;
- typedef std::map<string, names_list::iterator> names_map;
- typedef std::map<names const*, names_list::iterator> names_iterator_map;
+ typedef N name_type;
+ typedef relational::names<N> names_type;
+ typedef relational::nameable<N> nameable_type;
+
+ typedef std::list<names_type*> names_list;
+ typedef std::map<name_type, typename names_list::iterator> names_map;
+ typedef
+ std::map<names_type const*, typename names_list::iterator>
+ names_iterator_map;
public:
- typedef pointer_iterator<names_list::iterator> names_iterator;
+ typedef pointer_iterator<typename names_list::iterator> names_iterator;
typedef
- pointer_iterator<names_list::const_iterator>
+ pointer_iterator<typename names_list::const_iterator>
names_const_iterator;
public:
@@ -244,16 +267,16 @@ namespace semantics
// Find.
//
names_iterator
- find (string const& name);
+ find (name_type const&);
names_const_iterator
- find (string const& name) const;
+ find (name_type const&) const;
names_iterator
- find (names const&);
+ find (names_type const&);
names_const_iterator
- find (names const&) const;
+ find (names_type const&) const;
public:
scope ()
@@ -262,16 +285,21 @@ namespace semantics
}
void
- add_edge_left (names&);
+ add_edge_left (names_type&);
private:
names_list names_;
names_map names_map_;
names_iterator_map iterator_map_;
- names_list::iterator first_key_;
+ typename names_list::iterator first_key_;
};
+
+ typedef scope<uname> uscope;
+ typedef scope<qname> qscope;
}
}
+#include <odb/semantics/relational/elements.txx>
+
#endif // ODB_SEMANTICS_RELATIONAL_ELEMENTS_HXX
diff --git a/odb/semantics/relational/elements.txx b/odb/semantics/relational/elements.txx
new file mode 100644
index 0000000..f3d15c2
--- /dev/null
+++ b/odb/semantics/relational/elements.txx
@@ -0,0 +1,94 @@
+// file : odb/semantics/relational/elements.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v3; see accompanying LICENSE file
+
+namespace semantics
+{
+ namespace relational
+ {
+ // scope
+ //
+
+ template <typename N>
+ typename scope<N>::names_iterator scope<N>::
+ find (name_type const& name)
+ {
+ typename names_map::iterator i (names_map_.find (name));
+
+ if (i == names_map_.end ())
+ return names_.end ();
+ else
+ return i->second;
+ }
+
+ template <typename N>
+ typename scope<N>::names_const_iterator scope<N>::
+ find (name_type const& name) const
+ {
+ typename names_map::const_iterator i (names_map_.find (name));
+
+ if (i == names_map_.end ())
+ return names_.end ();
+ else
+ return names_const_iterator (i->second);
+ }
+
+ template <typename N>
+ typename scope<N>::names_iterator scope<N>::
+ find (names_type const& e)
+ {
+ typename names_iterator_map::iterator i (iterator_map_.find (&e));
+ return i != iterator_map_.end () ? i->second : names_.end ();
+ }
+
+ template <typename N>
+ typename scope<N>::names_const_iterator scope<N>::
+ find (names_type const& e) const
+ {
+ typename names_iterator_map::const_iterator i (iterator_map_.find (&e));
+ return i != iterator_map_.end () ? i->second : names_.end ();
+ }
+
+ class column;
+ class primary_key;
+
+ template <typename N>
+ void scope<N>::
+ add_edge_left (names_type& e)
+ {
+ nameable_type& n (e.nameable ());
+ name_type const& name (e.name ());
+
+ typename names_map::iterator i (names_map_.find (name));
+
+ if (i == names_map_.end ())
+ {
+ typename names_list::iterator i;
+
+ // We want the order to be columns first, then the primary key,
+ // and then the foreign keys.
+ //
+ if (n.is_a<column> ())
+ i = names_.insert (first_key_, &e);
+ else
+ {
+ if (n.is_a<primary_key> ())
+ first_key_ = i = names_.insert (first_key_, &e);
+ else
+ {
+ i = names_.insert (names_.end (), &e);
+
+ if (first_key_ == names_.end ())
+ first_key_ = i;
+ }
+ }
+
+ names_map_[name] = i;
+ iterator_map_[&e] = i;
+ }
+ else
+ throw duplicate_name (*this, (*i->second)->nameable (), n);
+ }
+ }
+}
diff --git a/odb/semantics/relational/foreign-key.cxx b/odb/semantics/relational/foreign-key.cxx
index eae9c5f..610466a 100644
--- a/odb/semantics/relational/foreign-key.cxx
+++ b/odb/semantics/relational/foreign-key.cxx
@@ -25,6 +25,7 @@ namespace semantics
//
{
type_info ti (typeid (foreign_key));
+ ti.add_base (typeid (unameable));
ti.add_base (typeid (key));
insert (ti);
}
diff --git a/odb/semantics/relational/foreign-key.hxx b/odb/semantics/relational/foreign-key.hxx
index 4a0b543..c47c90a 100644
--- a/odb/semantics/relational/foreign-key.hxx
+++ b/odb/semantics/relational/foreign-key.hxx
@@ -13,7 +13,7 @@ namespace semantics
{
namespace relational
{
- class foreign_key: public key
+ class foreign_key: public unameable, public key
{
public:
enum action
@@ -23,10 +23,10 @@ namespace semantics
};
foreign_key (string const& id,
- string const& referenced_table,
+ qname const& referenced_table,
bool deferred,
action on_delete = no_action)
- : key (id),
+ : unameable (id),
referenced_table_ (referenced_table),
deferred_ (deferred),
on_delete_ (on_delete)
@@ -34,7 +34,7 @@ namespace semantics
}
public:
- string
+ qname const&
referenced_table () const
{
return referenced_table_;
@@ -76,7 +76,7 @@ namespace semantics
}
private:
- string referenced_table_;
+ qname referenced_table_;
columns referenced_columns_;
bool deferred_;
action on_delete_;
diff --git a/odb/semantics/relational/index.cxx b/odb/semantics/relational/index.cxx
index 376a312..407dbf8 100644
--- a/odb/semantics/relational/index.cxx
+++ b/odb/semantics/relational/index.cxx
@@ -25,6 +25,7 @@ namespace semantics
//
{
type_info ti (typeid (index));
+ ti.add_base (typeid (qnameable));
ti.add_base (typeid (key));
insert (ti);
}
diff --git a/odb/semantics/relational/index.hxx b/odb/semantics/relational/index.hxx
index ee6b202..bb34742 100644
--- a/odb/semantics/relational/index.hxx
+++ b/odb/semantics/relational/index.hxx
@@ -7,6 +7,7 @@
#define ODB_SEMANTICS_RELATIONAL_INDEX_HXX
#include <odb/semantics/relational/elements.hxx>
+#include <odb/semantics/relational/column.hxx>
#include <odb/semantics/relational/key.hxx>
#include <odb/semantics/relational/table.hxx>
@@ -17,7 +18,7 @@ namespace semantics
// Note that unlike other keys, indexes are defined in the model
// scope, not table scope.
//
- class index: public key
+ class index: public qnameable, public key
{
public:
relational::table&
@@ -28,7 +29,7 @@ namespace semantics
public:
index (string const& id)
- : key (id)
+ : qnameable (id)
{
}
diff --git a/odb/semantics/relational/key.cxx b/odb/semantics/relational/key.cxx
index 648fb26..8fb28ca 100644
--- a/odb/semantics/relational/key.cxx
+++ b/odb/semantics/relational/key.cxx
@@ -33,7 +33,7 @@ namespace semantics
//
{
type_info ti (typeid (key));
- ti.add_base (typeid (nameable));
+ ti.add_base (typeid (node));
insert (ti);
}
}
diff --git a/odb/semantics/relational/key.hxx b/odb/semantics/relational/key.hxx
index 7e7a847..f714876 100644
--- a/odb/semantics/relational/key.hxx
+++ b/odb/semantics/relational/key.hxx
@@ -7,13 +7,13 @@
#define ODB_SEMANTICS_RELATIONAL_KEY_HXX
#include <odb/semantics/relational/elements.hxx>
-#include <odb/semantics/relational/column.hxx>
namespace semantics
{
namespace relational
{
class key;
+ class column;
class contains: public edge
{
@@ -51,7 +51,7 @@ namespace semantics
column_type* column_;
};
- class key: public nameable
+ class key: public virtual node
{
typedef std::vector<contains*> contains_list;
@@ -85,12 +85,6 @@ namespace semantics
contains_.push_back (&e);
}
- protected:
- key (string const& id)
- : nameable (id)
- {
- }
-
private:
contains_list contains_;
};
diff --git a/odb/semantics/relational/model.cxx b/odb/semantics/relational/model.cxx
index a0ac23f..d19c835 100644
--- a/odb/semantics/relational/model.cxx
+++ b/odb/semantics/relational/model.cxx
@@ -25,7 +25,7 @@ namespace semantics
//
{
type_info ti (typeid (model));
- ti.add_base (typeid (scope));
+ ti.add_base (typeid (qscope));
insert (ti);
}
}
diff --git a/odb/semantics/relational/model.hxx b/odb/semantics/relational/model.hxx
index 7d2f944..a761af1 100644
--- a/odb/semantics/relational/model.hxx
+++ b/odb/semantics/relational/model.hxx
@@ -12,7 +12,7 @@ namespace semantics
{
namespace relational
{
- class model: public graph<node, edge>, public scope
+ class model: public graph<node, edge>, public qscope
{
public:
model ()
@@ -26,8 +26,8 @@ namespace semantics
}
public:
- using scope::add_edge_left;
- using scope::add_edge_right;
+ using qscope::add_edge_left;
+ using qscope::add_edge_right;
private:
model (model const&);
diff --git a/odb/semantics/relational/name.cxx b/odb/semantics/relational/name.cxx
new file mode 100644
index 0000000..3cfd763
--- /dev/null
+++ b/odb/semantics/relational/name.cxx
@@ -0,0 +1,95 @@
+// file : odb/semantics/relational/name.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v3; see accompanying LICENSE file
+
+#include <ostream>
+#include <istream>
+
+#include <odb/semantics/relational/name.hxx>
+
+using namespace std;
+
+namespace semantics
+{
+ namespace relational
+ {
+ string qname::
+ string () const
+ {
+ std::string r;
+
+ bool f (true);
+ for (iterator i (begin ()); i < end (); ++i)
+ {
+ if (i->empty ())
+ continue;
+
+ if (f)
+ f = false;
+ else
+ r += '.';
+
+ r += *i;
+ }
+
+ return r;
+ }
+
+ ostream&
+ operator<< (ostream& os, qname const& n)
+ {
+ bool f (true);
+ for (qname::iterator i (n.begin ()); i < n.end (); ++i)
+ {
+ if (i->empty ())
+ continue;
+
+ if (f)
+ f = false;
+ else
+ os << '.';
+
+ os << *i;
+ }
+
+ return os;
+ }
+
+ istream&
+ operator>> (istream& is, qname& n)
+ {
+ n.clear ();
+
+ string s;
+ is >> s;
+
+ if (!is.fail ())
+ {
+ string::size_type p (string::npos);
+
+ for (size_t i (0); i < s.size (); ++i)
+ {
+ char c (s[i]);
+
+ if (c == '.')
+ {
+ if (p == string::npos)
+ n.append (string (s, 0, i));
+ else
+ n.append (string (s, p + 1, i - p - 1));
+
+ p = i;
+ }
+ }
+
+ if (p == string::npos)
+ n.append (s);
+ else
+ n.append (string (s, p + 1, string::npos));
+ }
+
+ return is;
+ }
+ }
+}
diff --git a/odb/semantics/relational/name.hxx b/odb/semantics/relational/name.hxx
new file mode 100644
index 0000000..ae06708
--- /dev/null
+++ b/odb/semantics/relational/name.hxx
@@ -0,0 +1,146 @@
+// file : odb/semantics/relational/name.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v3; see accompanying LICENSE file
+
+#ifndef ODB_SEMANTICS_RELATIONAL_NAME_HXX
+#define ODB_SEMANTICS_RELATIONAL_NAME_HXX
+
+#include <string>
+#include <vector>
+#include <iosfwd>
+
+namespace semantics
+{
+ namespace relational
+ {
+ typedef std::string uname;
+
+ class qname
+ {
+ public:
+ typedef relational::uname uname_type;
+
+ qname () {}
+
+ explicit
+ qname (uname_type const& n) {append (n);}
+
+ template <typename I>
+ qname (I begin, I end)
+ {
+ for (; begin != end; ++begin)
+ append (*begin);
+ }
+
+ qname&
+ operator= (uname_type const& n)
+ {
+ components_.resize (1);
+ components_[0] = n;
+ return *this;
+ }
+
+ void
+ append (uname_type const& n) {components_.push_back (n);}
+
+ void
+ append (qname const& n)
+ {
+ components_.insert (components_.end (),
+ n.components_.begin (),
+ n.components_.end ());
+ }
+
+ void
+ clear () {components_.clear ();}
+
+ // Append a string to the last component.
+ //
+ qname&
+ operator+= (std::string const& s)
+ {
+ if (empty ())
+ append (s);
+ else
+ uname () += s;
+
+ return *this;
+ }
+
+ friend qname
+ operator+ (qname const& n, std::string const& s)
+ {
+ qname r (n);
+
+ if (r.empty ())
+ r.append (s);
+ else
+ r.uname () += s;
+
+ return r;
+ }
+
+ void
+ swap (qname& n) {components_.swap (n.components_);}
+
+ public:
+ bool
+ empty () const {return components_.empty ();}
+
+ bool
+ qualified () const {return components_.size () > 1;}
+
+ bool
+ fully_qualified () const
+ {
+ return qualified () && components_.front ().empty ();
+ }
+
+ public:
+ typedef std::vector<uname_type> components;
+ typedef components::const_iterator iterator;
+
+ iterator
+ begin () const {return components_.begin ();}
+
+ iterator
+ end () const {return components_.end ();}
+
+ uname_type&
+ uname () {return components_.back ();}
+
+ uname_type const&
+ uname () const {return components_.back ();}
+
+ qname
+ qualifier () const
+ {
+ return empty ()
+ ? qname ()
+ : qname (components_.begin (), components_.end () - 1);
+ }
+
+ std::string
+ string () const;
+
+ public:
+ friend bool
+ operator< (qname const& x, qname const& y)
+ {
+ return x.components_ < y.components_;
+ }
+
+ private:
+ components components_;
+ };
+
+ std::ostream&
+ operator<< (std::ostream&, qname const&);
+
+ std::istream&
+ operator>> (std::istream&, qname&);
+ }
+}
+
+#endif // ODB_SEMANTICS_RELATIONAL_NAME_HXX
diff --git a/odb/semantics/relational/primary-key.cxx b/odb/semantics/relational/primary-key.cxx
index 367013e..5794f9a 100644
--- a/odb/semantics/relational/primary-key.cxx
+++ b/odb/semantics/relational/primary-key.cxx
@@ -25,6 +25,7 @@ namespace semantics
//
{
type_info ti (typeid (primary_key));
+ ti.add_base (typeid (unameable));
ti.add_base (typeid (key));
insert (ti);
}
diff --git a/odb/semantics/relational/primary-key.hxx b/odb/semantics/relational/primary-key.hxx
index a35e8f5..7402b8a 100644
--- a/odb/semantics/relational/primary-key.hxx
+++ b/odb/semantics/relational/primary-key.hxx
@@ -13,7 +13,7 @@ namespace semantics
{
namespace relational
{
- class primary_key: public key
+ class primary_key: public unameable, public key
{
public:
bool
@@ -23,10 +23,10 @@ namespace semantics
}
public:
- // Primary key has the implicit empty id.
- //
primary_key (bool auto_)
- : key (""), auto__ (auto_)
+ // Primary key has the implicit empty id.
+ //
+ : unameable (""), auto__ (auto_)
{
}
diff --git a/odb/semantics/relational/table.cxx b/odb/semantics/relational/table.cxx
index a9290c6..5b3ec68 100644
--- a/odb/semantics/relational/table.cxx
+++ b/odb/semantics/relational/table.cxx
@@ -25,8 +25,8 @@ namespace semantics
//
{
type_info ti (typeid (table));
- ti.add_base (typeid (nameable));
- ti.add_base (typeid (scope));
+ ti.add_base (typeid (qnameable));
+ ti.add_base (typeid (uscope));
insert (ti);
}
diff --git a/odb/semantics/relational/table.hxx b/odb/semantics/relational/table.hxx
index d2f8649..cd031b8 100644
--- a/odb/semantics/relational/table.hxx
+++ b/odb/semantics/relational/table.hxx
@@ -12,11 +12,11 @@ namespace semantics
{
namespace relational
{
- class table: public nameable, public scope
+ class table: public qnameable, public uscope
{
protected:
table (string const& id)
- : nameable (id)
+ : qnameable (id)
{
}
};