\def\filedate{2010/03/25}
\def\docdate{2010/09/25}
\def\fileversion{0.16}
\def\basename{pst-dbicons}
%
% \iffalse meta-comment
%
% Package 'pst-dbicons' to use with LaTeX2e and PSTricks
%   (formerly dbicons)
% Copyright 1997-2010 by Wolfgang May. All rights reserved.
%
%  This package is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
%
% Written and maintained by 
%      Wolfgang May 
% 
% Error Reports in case of UNCHANGED versions to
% 
%   Wolfgang May
%   Institut f"ur Informatik, Universit"at G"ottingen
%   Goldschmidtstrasse 7
%   D-37077 Goettingen, Germany
%   e-mail: may@informatik.uni-goettingen.de
%
% You are not allowed to change this file.
% 
% You are allowed to distribute this file under the condition that
% it is distributed UNCHANGED. You are NOT ALLOWED to take money for
% the distribution or use of either this file or a changed version,
% except for a nominal charge for copying etc.
% \fi
%
% \CheckSum{576}
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%
% \RecordChanges
%
% \MakeShortVerb{\|}
% \makeatletter
% \def\Codelabel#1{\@bsphack  
%  \protected@write\@auxout{}{\string\newlabel{#1}{{\number\the
%            \c@CodelineNo}{\thepage}}}\@esphack}
% \newcounter{tmpcount}
% \def\Coderef#1#2{\setcounter{tmpcount}{0}\@ifundefined{r@#1}\relax
%           {\setcounter{tmpcount}{\ref{#1}}}\relax
%           \addtocounter{tmpcount}{#2}\arabic{tmpcount}}
% \makeatother
%
% \title{PSTricks Macros for Databases\thanks{This 
%          file has version number \fileversion{}, last revised \filedate.}}
% \author{Wolfgang May\\
% \texttt{may@informatik.uni-freiburg.de}\\
% Institut f\"ur Informatik \\
% Universit\"at G\"ottingen \\
% Goldschmidtstrasse 7 \\
% D-37077 G\"ottingen\\
% Germany}
% \date{\filedate}
% \maketitle          
%
% \begin{abstract}
%  \noindent
% The \emph{pst-dbicons} package (originally called \em{dbicons} only)
% provides some useful macros in the 
% database area. It focusses on typesetting ER-Diagrams in a 
% declarative style, i.e., by positioning some nodes and defining
% the position of all other nodes relative to them by using the 
% standard database terminology.
% The PSTricks package is required for using pst-dbicons, but
% there is no deep knowledge of PSTricks commands required 
% (although this is useful for exploiting the full functionality).
% \end{abstract}
%
% \section{Commands}
%
% \subsection{ER-Diagrams}
%
% ER-Diagrams are a widely used graphical representation 
% formalism for conceptual modeling; especially used in the
% database community. Their main notions are \emph{entities}
% (e.g., persons, cities, or countries), \emph{attributes} of
% entities (e.g., name, id-number, age), and relationships 
% between entities (e.g., belongs\_to, is\_capital\_of). 
% 
% \DescribeMacro\seticonparams
% With 
% \begin{quote}
% |\seticonparams{|\meta{icon-type}|}{|\meta{graphics parameters}|}|
% \end{quote}
% the graphical layout of icons (entities, relationships, and attributes)
% can be specified (by giving the optional argument for PSTricks'
% boxes). Default is
% |[fillstyle=none]| for all of them.
% in this documentation, we modify it to
%
%\begin{verbatim}
%\seticonparams{entity}{shadow=true,fillcolor=lightgray,fillstyle=solid}
%\seticonparams{attribute}{fillcolor=lightgray,fillstyle=solid}
%\seticonparams{relationship}{shadow=true,fillcolor=lightgray,fillstyle=solid}\end{verbatim}
%\seticonparams{entity}{shadow=true,fillcolor=lightgray,fillstyle=solid}
%\seticonparams{attribute}{fillcolor=lightgray,fillstyle=solid}
%\seticonparams{relationship}{shadow=true,fillcolor=lightgray,fillstyle=solid}
%
% From the user's point of view, every ER-icon (entities, relationships,
% attributes)
% has a name which should be typeset in the respective box. Additionally,
% there are \emph{internal} identifiers of the boxes/nodes to allow for
% referencing by graphics commands in the standard PSTricks way.
% These \emph{internal id}'s must start with a letter and must contain 
% only letters 
% and digits. In general, id's must be unique on every 
% page.\footnote{people who are familiar with PSTricks know under which
% conditions non-unique node identifiers can be used.} 
% Often, the \emph{name} of the entity/relationship/attribute satisfies
% these conditions; in these cases, the name is also used as id. 
% in other cases, name and id must be specified. 
%
% Thus, for all commands for typesetting ER-icons, the node id 
% \emph{must} be given, whereas the name to be typeset in the box 
% is optional; if no name is specified, the id is typeset as the name.
%
%
% \subsection{Entities and Attributes}
% \DescribeMacro\entity
% With 
% \begin{quote}
% |\entity[|\meta{property}|]{|\meta{id}|}[|\meta{text}|]|
% \end{quote}
% an entity type is set as a rectangular node.
% If the optional argument \meta{text} is not given, \meta{id} also
% provides the entity's text. \meta{property} is used for \emph{weak}
% entitiy types which are denoted by double lines:
% 
% Here is a simple entity |\entity{Person}| \quad\entity{Person}\quad where 
% |Person| serves also as node text; |\entity[weak]{cty}[City]| 
% \entity[weak]{cty}[City] makes up a weak entity type where the
% displayed name is different from the internal name.
% 
%
% \DescribeMacro\attribute
% Attribute icons are set as an oval nodes by 
% \begin{quote}
% |\attribute[|\meta{property}|]{|\meta{id}|}[|\meta{text}|]|
% \end{quote}
% Here, the optional argument \meta{property} can take the
% values |mv| (multivalued; resulting in a double-lined oval) or
% |key| (key attribute; resulting in underlining the attribute name).
% Here are three attributes:
% \begin{itemize} 
% \item an ordinary one, |\attribute{phone}[phone\_no]| 
%   \quad\attribute{phone}[phone\_no]\quad,
% \item a multivalued attribute, |\attribute[mv]{nickname}| 
%   \quad\attribute[mv]{nickname}\quad,
% \item a key attribute, |\attribute[key]{pid}[person\_id]| 
%   \quad\attribute[key]{pid}[person\_id]\quad.
% \end{itemize}
% Note that with \emph{phone\_no}, the optional argument is 
% used for the node text (in case that the node text contains 
% stuff that is not allowed in internal postscript ids -- 
% as a rough rule, only characters (and since dbicons v1.14,
% underscores) are allowed in ids).
%
% In Section~\ref{sec-relationships}, relationship nodes are defined
% analogously. 
% \DescribeMacro\attributeof
% \DescribeMacro\attrdist
% At first, it is described how to attach attributes with entities:
% 
% \begin{quote}
% |\attributeof{|\meta{id}|}[|\meta{dist}|]{|\ignorespaces
% \meta{angle}|}[|\meta{property}|]{|\meta{id$_2$}|}[|\meta{text}|]|
% \end{quote}
% typesets an attribute node at angle \meta{angle} in distance
% \meta{dist} from the node which is identified by \meta{id}
% (which can be either an entity node or a relationship node).
% The attribute is made a node named \meta{id$_2$}. 
% \meta{id$_2$} and \meta{text} work as for |\entity|.
% The argument \meta{dist} is optional, it has not to be given 
% with \emph{every} attribute. By |\attrdist{|\meta{dist}|}|, this
% value can be set to a default (as startup default, 2em is set).
% 
% 
% \attrdist2.5em
% \hspace*{0.5cm}\entity{Person}\hspace*{2cm}
% \attributeof{Person}{30}[key]{Name} 
% \attributeof{Person}{90}[mv]{Nickname} 
% \attributeof{Person}[4em]{150}{phone}[phone\_no]
% \attributeof{Person}[2em]{270}[mv]{wt}[weight\_at]
% \attributeof{wt}{240}{date}
% \attributeof{wt}{300}{weight}
% \begin{tabular}{p{8.2cm}}
% \attrdist2.5em
% |\entity{Person}| \\
% |\attributeof{Person}{30}[key]{Name}| \\
% |\attributeof{Person}{90}[mv]{Nickname}| \\
% |\attributeof{Person}[4em]{150}| \\
% |            {phone}[phone\_no]| \\
% |\attributeof{Person}{270}[mv]{wt}[weight\_at]| \\
% |\attributeof{wt}{220}{date}| \\
% |\attributeof{wt}{300}{weight}| \bigskip\\
%
% Note that \emph{phone\_no} is set with a bigger distance to 
% \emph{person}.
% Additionally, the example shows how complex attributes can be set 
% with these commands.
% \end{tabular}
%
%\subsection{Relationships}\label{sec-relationships}
% \DescribeMacro\relationship
% With |\relationship[|\meta{property}|]{|\meta{id}|}[|\meta{text}|]|, a relationship 
% type is set as a diamond-shaped node.
% Here, the optional argument \meta{property} is used to represent
% \emph{identifying} relationships, used for \emph{weak} entities --
% thus \meta{property} can be equivalently |weak| or |ident| which 
% results in a double-lined relationship type.
%
% \DescribeMacro\relationshipbetween
% For declaratively specifying nodes representing relationships
% between entities, 
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]{|\meta{entity-is$_1$}|}{|\meta{entity-id$_2$}|}|\\
% |                    {|\meta{relationship-id}|}[|\meta{relationship-name}|]| 
% \end{quote}
% is used (which can be augmented with several optional arguments). 
% In the simplest version, as given above, a relationship node is set 
% in-between two entity nodes:
%
% \begin{quote}
% | \entity{Person} \hspace*{6cm} \entity{Company}| \\
% | \relationshipbetween{Person}{Company}{worksat}[works\_at]| 
% \bigskip \\
% \entity{Person} \hspace*{6cm} \entity{Company}
% \relationshipbetween{Person}{Company}{worksat}[works\_at]
% \end{quote}
%
% Additionally, the \emph{roles} of the entities in the relationship,
% and the cardinalities can be given (both as independent optional
% arguments):
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]|\\
% |     {|\meta{entity-id$_1$}|}(|\ignorespaces
%       \meta{role$_1$}|)[|\meta{card$_1$}|]|\\
% |     {|\meta{entity-id$_2$}|}(|\ignorespaces
%       \meta{role$_2$}|)[|\meta{card$_2$}|]|\\
% |     {|\meta{relationship-id}|}[|\meta{relationship-name}|]| 
% \end{quote}
%
% \begin{quote}
% |\entity{Country} \hspace*{6cm} \entity{City}| \\
% |\relationshipbetween{Country}(of)[1:1]{City}(is)[0:1]{capital}|
% \bigskip \\
% \entity{Country} \hspace*{6cm} \entity{City}
% \relationshipbetween{Country}(of)[1:1]{City}(is)[0:1]{capital}
% \end{quote}
% 
% Moreover, the placement of the relationship node wrt.\ the
% entities can be specified: above, the relationship node was
% put in the middle of an imaginary line in-between the entity 
% nodes.
%
% As a first, small, extension, the placement ratio of the 
% diamond between the entities can be changed (default: 0.5):
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]{|\meta{entity-id$_1$}|}...{|\ignorespaces
%     \meta{entity-id$_2$}|}...|\\
% |         {|\meta{relationship-id}|}[|\ignorespaces
%     \meta{relationship-name}|](|\meta{placement-ratio}|)| 
% \end{quote}
%
% \begin{quote}
% |\entity{Country} \hspace*{6cm} \entity[weak]{City}| \\
% |\relationshipbetween[ident]{Country}[0:n]{City}[1:1]{in}(0.8)|
% \bigskip \\
% \entity{Country} \hspace*{6cm} \entity[weak]{City}
% \relationshipbetween[ident]{Country}[0:n]{City}[1:1]{in}(0.8)
% \end{quote}
%
% If this is still not enough, instead of an imaginary straight line,
% any other PSTricks node connection command can be used, most
% likely |\ncarc[...]| with suitable optional arguments:
%
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]| \\
% |     {|\meta{entity-id$_1$}|}...{|\ignorespaces
%     \meta{entity-id$_2$}|}...|\\
% |     {|\meta{relationship-id}|}[|\ignorespaces
%     \meta{relationship-name}|]|\\
% |     /|\meta{connection}|/(|\meta{placement-ratio}|)| 
% \end{quote}
% \begin{quote}
% |\entity{Country} \hspace*{6cm} \entity{City}| \\
% |\relationshipbetween{Country}[0:n]{City}[1:1]|\\
% |       {in}/\ncarc[arcangle=20]/(0.4)|
% \vspace*{1cm} \\
% \entity{Country} \hspace*{6cm} \entity{City}
% \relationshipbetween{Country}[0:n]{City}[1:1]{in}/\ncarc[arcangle=20]/(0.4)
% \end{quote}
%
% For \TeX-insiders: Note that the use of |/.../| as argument delimiter
% avoids collisions with the delimiters used by PSTricks which
% thus can be used inside |/.../|.
%
% In the above example, although the relationship is placed on an
% imaginary arc, the \emph{connections} are straight lines.
% For these lines, PSTricks commands can be given, too. 
% With this, the \emph{full} syntax is 
% \begin{quote}
% |\relationshipbetween[|\meta{property}|]|\\
% |   {|\meta{entity-id$_1$}|}(|\ignorespaces
%       \meta{role$_1$}|)[|\meta{card$_1$}|]/|\meta{connection$_1$}|/|\\
% |   {|\meta{entity-id$_2$}|}(|\meta{role$_2$}|)[|\ignorespaces
%       [\meta{card$_2$}|]/|\meta{connection$_2$}|/|\\
% |   {|\meta{relationship-id}|}[|\meta{relationship-name}|]/|%
%     \meta{connection}|/(|\meta{placement-ratio}|)| 
% \end{quote}
%
% where all arguments embraced with |(...)|, |[...]|, or |/.../| are
% optional.
%
% With this, an example can be given where two different relationships
% can hold between a pair of entity types:
%
% \begin{quote}
% |\entity{Country} \hspace*{6cm} \entity{City}| \\
% |\relationshipbetween{Country}[0:n]{City}[1:1]{in}|\\
%      |/\ncarc[arcangle=20]/(0.4)|\\
% |\relationshipbetween{Country}[1:1]/\ncarc[arcangle=-18]/|\\
% |     {City}[0:1]/\ncarc[arcangle=-12]/|\\
% |     {Capital}/\ncarc[arcangle=-30]/(0.6)|
% \vspace*{1cm} \\
% \entity{Country} \hspace*{6cm} \entity{City}
% \relationshipbetween{Country}[0:n]{City}[1:1]{in}/\ncarc[arcangle=20]/(0.4)
% \relationshipbetween{Country}[1:1]/\ncarc[arcangle=-18]/
%              {City}[0:1]/\ncarc[arcangle=12]/
%              {Capital}/\ncarc[arcangle=-30]/(0.6)
% \vspace*{1.2cm} 
% \end{quote}
% Note that for \emph{capital}, |\ncarc| is used for the lines,
% where the |arcangle| of the whole arc is divided suitably 
% to the placement ratio of the diamond node, and that the
% |arcangle| of the second entity is negative (since the connection
% always points from the entity to the relationship).
%
% There is one more interesting special case of binary relationships: 
% recursive relationships. There, the entity node cannot be set
% ``between'' the nodes -- it has to be placed relative to the
% entity type which is involved in the relationship. 
%
% In this case, the argument \meta{connection} has no effect, and last
% argument (\meta{placement ratio}) has the syntax 
% |(|\meta{distance},\meta{angle}|)|: the relationship node is set
% at angle \meta{angle} in distance \meta{dist} from the entity node.
% The default for \meta{connection$_1$} and \meta{connection$_2$}
% is set to |\ncarc[arcangleA=10,arcangleB=45]}| and \\
% |\ncarc[arcangleA=-10,arcangleB=-45]|, 
% respectively.
% \begin{quote}
% |\hspace*{6cm}\entity{Country}|\\
% |\relationshipbetween{Country}(A)[0:n]{Country}(B)[0:n]|\\
% |         {Neighbor}(8em,180)|
% \vspace*{0.8cm}\\
% \hspace*{6cm}\entity{Country} 
% \relationshipbetween{Country}(A)[0:n]{Country}(B)[0:n]{Neighbor}(8em,180) 
% \bigskip
% \end{quote}
%
% With the above commands, only binary relationships can be 
% represented. Thus, there is one more macro, relating
% entity nodes with already existing relationship nodes:
%
% \DescribeMacro\inrelationship
% \begin{quote}
% |\inrelationship[|\meta{property}|]{|\meta{entity-id}|}(|\meta{role}|)[|\ignorespaces
%       \meta{card}|]|\\
% |    /|\meta{connection}|/{|\meta{relationship-id}|}|
% \end{quote}
%
% With this, n-ary relations can be represented:
% \begin{quote}
% |\begin{tabular}{c}| \\
% |\entity{Person} \hspace*{6cm} \entity{Project} \\[2cm]| \\
% |\entity{Machine}| \\
% |\end{tabular}| \\                        
% |\relationshipbetween{Person}{Project}{worksatwith}|\ignorespaces
%        |[works\_at\_with]|\\
% |      /\ncarc[arcangle=-20]/|\\
% |\inrelationship{Machine}{worksatwith}|
% \bigskip\\
% \begin{tabular}{c}
% \entity{Person} \hspace*{6cm} \entity{Project} \\[2cm]
% \entity{Machine}
% \end{tabular}                              
% \relationshipbetween{Person}{Project}{worksatwith}[works\_at\_with]
%        /\ncarc[arcangle=-20]/
% \inrelationship{Machine}{worksatwith}
% \end{quote}
%
% Additionally, there is a straightforward extension of 
% |\inrelationship| to relationship
% nodes which do not already exist but are set by the command:
%
% \begin{quote}
% |\inrelationship{|\meta{entity-id}|}(|\meta{role}|)|\ignorespaces
%       |[|\meta{card}|]/|\meta{connection}|/|\\
% |     {|\meta{relationship-id}|}[|\meta{relationship-name}|]|\ignorespaces
%       |(|\meta{distance},\meta{angle}|)| 
% \end{quote}
%
% \begin{quote}
% |\begin{tabular}{c}| \\
% |\entity{Person} \hspace*{6cm} \entity{Project} \\[2cm]| \\
% |\entity{Machine}| \\
% |\end{tabular}| \\
% |\inrelationship{Machine}{worksatwith}[works\_at\_with](4em,90)| \\
% |\inrelationship{Person}{worksatwith}| \\
% |\inrelationship{Project}{worksatwith}| 
% \bigskip \\
% \begin{tabular}{c}
% \entity{Person} \hspace*{6cm} \entity{Project} \\[2cm]
% \entity{Machine}
% \end{tabular}                              
% \inrelationship{Machine}{worksatwith}[works\_at\_with](4em,90)
% \inrelationship{Person}{worksatwith}
% \inrelationship{Project}{worksatwith}
% \end{quote}
%
% \DescribeMacro\rolepos
% The position where roles and cardinalities are placed on the 
% node connection is determined by |\rolepos| and |\cardpos| which
% \DescribeMacro\cardpos
% can be set by |\rolepos{|\meta{number}|}| and
% |\cardpos{|\meta{number}|}|, where number underlies the same
% constraints as for |npos| in PSTricks (i.e., for |\ncline| and
% |\ncarc|, it has to be between 0 and 1, other values are allowed
% e.g.\ for |\ncbar|). The default setting is |\cardpos{0.5}| and
% |\rolepos{0.85}|.
%
% \subsection{Annotations to Objects}
% \DescribeMacro\annote
% With 
% \begin{quote}
% |\annote{|\meta{id}|}{|\meta{text}|}(|\meta{distance},\meta{angle}|)| 
% \end{quote}
% a node \meta{id} can be annoted with a comment \meta{text}.
%
% \subsection{Usage}
%
% The package is intended to be used for two purposes: 
% \begin{itemize}
% \item Typesetting small fragments of ER-diagrams, e.g., for 
% lecture notes and slides: as shown in the above 
% documentation, fragments of ER-diagrams can easily be integrated
% with the running text.
% \item Typesetting ER-Diagrams for project documentation:
% here the standard procedure is to design the ER-diagram based
% on a |tabular| environment in which the entity nodes are positioned;
% Then, attributes and relationships are positioned in the above
% declarative way. Using basic PSTricks commands, additional 
% entity nodes can also be placed declaratively.
% \end{itemize}
%
% There are the following advantages compared to using graphics tools,
% e.g., xfig:
% \begin{itemize}
% \item the source code of the diagrams is written into the running
% source code of the document, thus there is no need for a bunch
% of separate |.fig| and |.eps| files.
% \item more flexibility wrt.\ renaming and layout changes.
% \item given the positions of some basic objects, the other
%  objects are set with declarative commands, i.e.\ they
%  automatically adjust when the positions change.
% \end{itemize}
%
% \subsection{Example}
%
% TO BE FILLED
%
% \subsection{Miscellaneous}
%
% \DescribeMacro\nodeconnections
% With |\nodeconnections{|\meta{PSTricks-node-connections}|}|,
% the PSTricks-node connections and label commands do not require any
% extra horizontal or vertical space.
%
% \DescribeMacro\database
% The command
% \begin{quote}
% |\database[|\meta{pos}|]{|\meta{width}|}{|\ignorespaces
%    \meta{height}|}[|\meta{graph\_params}|]{|\ignorespaces
%    \meta{text}|}[|\meta{id}|]|
% \end{quote}
% defines a database barrel as a tabular which is vertically
% centered as given in the optional argument \meta{pos} (Default: |[c]|).
% \meta{text} is the text to be written on the front of the barrel,
% \meta{width} and \meta{height} give the width and height of the 
% barrel; both must be a dimension, e.g., {2cm}. With the optional 
% graphics parameter \meta{graph\_params}, the pstricks parameters
% \textsf{fillstyle} and
% \textsf{fillcolor} for the database can be set (see example below).
% The optional argument \meta{id} is used as an internal name,
% it must start with a letter and must contain only letters and 
% digits. \meta{id} is used for |\rnode| definitions:
% \meta{id} is the whole barrel
% |lu|\meta{id}, |ru|\meta{id}, |mu|\meta{id}, and |muf|\meta{id} 
% denote the points at the upper left corner, upper right corner,
% upper middle behind and aupper middle in front of the barrel.
% Analogously, |ll|\meta{id}, |rl|\meta{id}, and |ml|\meta{id},
% denote the lower left and lower right corner and lower middle in
% front of the barrel. \medskip
%
% \begin{tabular}{lc}
% |\psset{nodesep=2pt}|\\
% |\begin{tabular}{lc}| \\
% |  &\rnode{lu}{lu}\quad\rnode{mu}{mu}\quad| \\
% |   \rnode{muf}{muf}\quad\rnode{ru}{ru}\\[1em]| \\
% |  \rnode{db}{database}|\\
% |   &\database[t]{2cm}{1cm}| \\
% |       [fillstyle=solid,fillcolor=red]| \\
% |       {database}[example] \\[5em]| \\
% |  &\rnode{ll}{ll}\qquad\rnode{ml}{ml}|\\
% |    \qquad\rnode{rl}{rl}| \\
% |\end{tabular}| \\
% |\nodeconnections{%| \\
% |\ncline{->}{lu}{luexample}| \\
% |\ncline{->}{mu}{muexample}| \\
% |\ncline{->}{muf}{mufexample}| \\
% |\ncline{->}{ru}{ruexample}| \\
% |\ncline{->}{ll}{llexample}| \\
% |\ncline{->}{ml}{mlexample}| \\
% |\ncline{->}{db}{example}| \\
% |\ncline{->}{rl}{rlexample}}| 
% \end{tabular} 
% \hspace*{-1.5cm}
% \psset{nodesep=2pt}
%\begin{tabular}{lc}
%     &\rnode{lu}{lu}\quad\rnode{mu}{mu}\quad
%      \rnode{muf}{muf}\quad\rnode{ru}{ru}\\[1em]
%     \rnode{db}{database} 
%     &\database[t]{2cm}{1cm}
%          [fillstyle=solid,fillcolor=red]
%        {database}[example] \\[5em]
%     &\rnode{ll}{ll}\qquad\rnode{ml}{ml}\qquad\rnode{rl}{rl}
% \end{tabular}
% \nodeconnections{%
% \ncline{->}{lu}{luexample}
% \ncline{->}{mu}{muexample}
% \ncline{->}{muf}{mufexample}
% \ncline{->}{ru}{ruexample}
% \ncline{->}{ll}{llexample}
% \ncline{->}{ml}{mlexample}
% \ncline{->}{db}{example}
% \ncline{->}{rl}{rlexample}}
%
% \section{Code Documentation}\label{sec:code}
% \iffalse
% \subsection{The documentation driver file}
%
% The next bit of code contains the documentation driver file for
% \TeX{}, i.e., the file that will produce the documentation you are
% currently reading. It will be extracted from this file by the
% \texttt{docstrip} program. Since it is the first code in the file
% one can alternatively process this file directly with \LaTeXe{} to
% obtain the documentation.
%
% \begin{macrocode}
%<*driver>
\documentclass{ltxdoc} \usepackage{latexsym}
\usepackage{pstricks,pst-node} \usepackage{pst-dbicons}
\parindent0pt\hfuzz2pt \setlength{\textwidth}{360pt}
\begin{document}
 \DocInput{pst-dbicons.dtx}
\end{document}
%</driver>
%    \end{macrocode}
%\fi
% \setcounter{CodelineNo}{0}
%\iffalse
%<*package>\fi
%    \begin{macrocode}
\typeout{Style `\basename', Version \fileversion\space <\filedate>}
\ProvidesPackage{pst-dbicons}[\filedate \space\fileversion]
%    \end{macrocode}
%
% \begin{macro}{\seticonparams}
% |\seticonparams{#1}{#2}|
% \Codelabel{seticonparams}
%    \begin{macrocode} 
\def\seticonparams#1#2{\expandafter\def\csname #1@parm\endcsname{[#2]}}
\seticonparams{entity}{fillstyle=none}
\seticonparams{relationship}{fillstyle=none}
\seticonparams{attribute}{fillstyle=none}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\purifylabel}
% \changes{v0.14}{02/11/21}{macro added}
% Macro |\@purifylabel| expands the string given in |#2|
% and stores the result in command given in |#1|.
% Supported TeX commands in string |#2|:
%   |\_|, |\textunderscore|
% Example: |\@purifylabel{\templabel}{has\_hq\_in}|, then use 
% |\templabel| as nodelabel for pstricks.
% \Codelabel{purifylabel}
%    \begin{macrocode} 
\def\dbi@purifylabel#1#2{%
  \begingroup
    \edef\_{\string_}%
    \edef\textunderscore{\string_}%
    \edef\x{\endgroup
      \def\noexpand#1{#2}%
    }%
  \x
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\entity}
% \changes{v0.11}{98/10/15}{added optional property of entities}
% |\entity[#1a]{#1b}[#2]|
% \Codelabel{entity}
%    \begin{macrocode} 
\def\entity{%
 \@ifnextchar[{\entity@i}{\entity@i[normal]}}
\def\entity@i[#1]#2{%
 \@ifnextchar[{\entity@ii{#1}{#2}}{\entity@ii{#1}{#2}[#2]}}
\def\entity@ii#1#2[#3]{\csname entity@#1\endcsname{#2}{#3}}
\def\entity@normal#1#2{%
  \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
  \rnode{\dbi@prfd@nodename}{\expandafter\psframebox\entity@parm{\strut#2}}}
\def\entity@weak#1#2{%
  {\psset{doubleline=true}%
   \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
   \rnode{\dbi@prfd@nodename}{\expandafter\psframebox\entity@parm{\strut#2}}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\attribute}
% |\attribute[#1]{#2}[#3]|
% \Codelabel{attribute}
%    \begin{macrocode} 
\def\attribute{%
 \@ifnextchar[{\attribute@i}{\attribute@i[sv]}}
\def\attribute@i[#1]#2{%
 \@ifnextchar[{\attribute@ii{#1}{#2}}{\attribute@ii{#1}{#2}[#2]}}
\def\attribute@ii#1#2[#3]{\csname attribute@#1\endcsname{#2}{#3}}
\def\attribute@mv#1#2{{\psset{doubleline=true}%
  \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
  \expandafter\ovalnode\attribute@parm{\dbi@prfd@nodename}{#2}}}
\def\attribute@sv#1#2{%
  \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
  \expandafter\ovalnode\attribute@parm{\dbi@prfd@nodename}{#2}}
\def\attribute@key#1#2{
  \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
  \expandafter\ovalnode\attribute@parm{\dbi@prfd@nodename}{\underline{#2}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\attributeof}
% |\attributeof{#1}[#2]{#3}[#4]{#5}[#6]|
%    \begin{macrocode} 
\newdimen\@attrdist
\@attrdist2em  % Default value for distance of attribute from entity
\def\attrdist#1{\@attrdist#1} % set default distance
%    \end{macrocode}
%
% \Codelabel{attributeof}
% \changes{v0.16}{2010/03/25}{fixed first optional argument}
%    \begin{macrocode} 
\def\attributeof#1{%
 \@ifnextchar[{\attributeof@i{#1}}{\attributeof@i{#1}[\@attrdist]}}
\def\attributeof@i#1[#2]#3{%
 \@ifnextchar[{\attributeof@ii{#1}[#2]{#3}}{\attributeof@ii{#1}[#2]{#3}[sv]}}
\def\attributeof@ii#1[#2]#3[#4]#5{%
 \@ifnextchar[{\attributeof@iii{#1}[#2]{#3}[#4]{#5}}%
              {\attributeof@iii{#1}[#2]{#3}[#4]{#5}[#5]}}
\def\attributeof@iii#1[#2]#3[#4]#5[#6]{%
  \SpecialCoor
  \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
  \uput{#2}[#3]{0}(\dbi@prfd@nodename){\attribute[#4]{#5}[#6]}%
  \NormalCoor
  \ncline{-}{#1}{#5}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\relationship}
% \changes{v0.11}{98/10/15}{added optional property of relationships}
% |\relationship[#1a]{#1b}[#2]|
% \Codelabel{relationship}
%    \begin{macrocode} 
\def\relationship{%
 \@ifnextchar[{\relationship@i}{\relationship@i[normal]}}
\def\relationship@i[#1]#2{%
 \@ifnextchar[{\relationship@ii{#1}{#2}}{\relationship@ii{#1}{#2}[#2]}}
\def\relationship@ii#1#2[#3]{\csname relationship@#1\endcsname{#2}{#3}}
\def\relationship@normal#1#2{%
   \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
   \expandafter\dianode\relationship@parm{\dbi@prfd@nodename}{#2}}
\def\relationship@weak#1#2{%
  {\psset{doubleline=true}%
   \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
   \expandafter\dianode\relationship@parm{\dbi@prfd@nodename}{#2}}}
\let\relationship@ident\relationship@weak
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\relationshipbetween}
% \changes{v0.11}{98/10/15}{added optional property of relationships}
% |\relationshipbetween[#1a]{#1b}(#2)[#3]/#4/{#5}(#6)[#7]/#8/{#9}[#10]/#11/(#12)|
% \Codelabel{relationshipbetween}
%    \begin{macrocode} 
\newtoks\rolepos
\rolepos{0.85}%
\newtoks\cardpos
\cardpos{0.5}%
\newif\ifdbi@recursive
\def\relationshipbetween{%
 \@ifnextchar[{\relationshipbetween@type}{\relationshipbetween@type[normal]}}
\def\relationshipbetween@type[#1]#2{\dbi@recursivefalse%
 \def\relationtype{#1}%
 \@ifnextchar({\relationshipbetween@i@role{#2}}%
              {\relationshipbetween@i@role{#2}(\relax)}}
\def\relationshipbetween@i@role#1(#2){%
 \@ifnextchar[{\relationshipbetween@i@card{#1}{#2}}%
              {\relationshipbetween@i@card{#1}{#2}[\relax]}}
\def\relationshipbetween@i@card#1#2[#3]{%
 \@ifnextchar/{\relationshipbetween@i@linetype{#1}{#2}{#3}}%
              {\relationshipbetween@i@linetype{#1}{#2}{#3}/\relax/}}%
\def\relationshipbetween@i@linetype#1#2#3/#4/#5{%
 \def\dbi@linecmd@i{#4}%
 \def\dbi@tempa{#1}\def\dbi@tempb{#5}%
 \ifx\dbi@tempa\dbi@tempb\dbi@recursivetrue\fi
 \ifx#4\relax
    \ifdbi@recursive
       \def\dbi@linecmd@i{\ncarc[arcangleA=10,arcangleB=45]}%
      \else\def\dbi@linecmd@i{\ncline}\fi\fi
 \@ifnextchar({\relationshipbetween@ii@role{#1}{#2}{#3}{#5}}%
              {\relationshipbetween@ii@role{#1}{#2}{#3}{#5}(\relax)}}%
\def\relationshipbetween@ii@role#1#2#3#4(#5){%
 \@ifnextchar[{\relationshipbetween@ii@card{#1}{#2}{#3}{#4}{#5}}%
              {\relationshipbetween@ii@card{#1}{#2}{#3}{#4}{#5}[\relax]}}
\def\relationshipbetween@ii@card#1#2#3#4#5[#6]{%
 \@ifnextchar/{\relationshipbetween@ii@linetype{#1}{#2}{#3}{#4}{#5}{#6}}%
              {\relationshipbetween@ii@linetype{#1}{#2}{#3}{#4}{#5}{#6}%
               /\relax/}}%
\def\relationshipbetween@ii@linetype#1#2#3#4#5#6/#7/#8{%
 \def\dbi@linecmd@ii{#7}%
 \ifx#7\relax
    \ifdbi@recursive
       \def\dbi@linecmd@ii{\ncarc[arcangleA=-10,arcangleB=-45]}%
      \else\def\dbi@linecmd@ii{\ncline}\fi\fi
 \@ifnextchar[{\relationshipbetween@optname{#1}{#2}{#3}{#4}{#5}{#6}{#8}}%
              {\relationshipbetween@optname{#1}{#2}{#3}{#4}{#5}{#6}{#8}[#8]}}%
\def\relationshipbetween@optname#1#2#3#4#5#6#7[#8]{%
 \@ifnextchar/{\relationshipbetween@linetype{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}%
              {\relationshipbetween@linetype{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
               /\ncline/}}%
\def\relationshipbetween@linetype#1#2#3#4#5#6#7#8/#9/{%
 \def\dbi@linecmd{#9}%
 \@ifnextchar({\relationshipbetween@pos{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}}%
              {\relationshipbetween@pos{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}(0.5)}}%
\def\relationshipbetween@pos#1#2#3#4#5#6#7#8(#9){%
   \ifdbi@recursive
     \relationshipbetween@rec{#1}{#2}{#3}{#5}{#6}{#7}{#8}(#9)\else
     \relationshipbetween@nonrec{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}(#9)\fi}
%    \end{macrocode}
%
% \Codelabel{relationshipbetweennonrec}
%    \begin{macrocode} 
\def\relationshipbetween@nonrec#1#2#3#4#5#6#7#8(#9){%
 \dbi@purifylabel{\dbi@prfd@nodename@i}{#1}%
 \dbi@purifylabel{\dbi@prfd@nodename@ii}{#4}%
 \dbi@purifylabel{\dbi@prfd@nodename@iii}{#7}%
 {\psset{linestyle=none}%
  \dbi@linecmd{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}}%
 \ncput[npos=#9]{\relationship[\relationtype]{#7}[#8]}%
 \dbi@linecmd@i{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@iii}%
  \ifx#3\relax\else\ncput*[npos=\the\cardpos]{#3}\fi
  \ifx#2\relax\else\ncput*[npos=\the\rolepos]{#2}\fi
 \dbi@linecmd@ii{-}{\dbi@prfd@nodename@ii}{\dbi@prfd@nodename@iii}%
  \ifx#6\relax\else\ncput*[npos=\the\cardpos]{#6}\fi
  \ifx#5\relax\else\ncput*[npos=\the\rolepos]{#5}\fi}
%    \end{macrocode}
%
% \Codelabel{relationshipbetweenrec}
%    \begin{macrocode} 
\def\relationshipbetween@rec#1#2#3#4#5#6#7(#8,#9){%
  \dbi@purifylabel{\dbi@prfd@nodename@i}{#1}%
  \dbi@purifylabel{\dbi@prfd@nodename@ii}{#6}%
  \SpecialCoor
  \uput{#8}[#9]{0}(\dbi@prfd@nodename@i)%
         {\relationship[\relationtype]{#6}[#7]}%
  \NormalCoor
  \dbi@linecmd@i{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}%
   \ifx#3\relax\else\ncput*[npos=\the\cardpos]{#3}\fi
   \ifx#2\relax\else\ncput*[npos=\the\rolepos]{#2}\fi
  \dbi@linecmd@ii{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}%
   \ifx#5\relax\else\ncput*[npos=\the\cardpos]{#5}\fi
   \ifx#4\relax\else\ncput*[npos=\the\rolepos]{#4}\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\inrelationship}
% \changes{v0.11}{98/10/15}{added optional property of relationships}
% |\inrelationship[#1a]{#1b}(#2)[#3]/#4/{#5}[#6](#7,#8)|
% \Codelabel{inrelationship}
%    \begin{macrocode} 
\def\inrelationship{%
 \@ifnextchar[{\inrelationship@type}{\inrelationship@type[normal]}}
\def\inrelationship@type[#1]#2{%
 \def\relationtype{#1}%
 \@ifnextchar({\inrelationship@role{#2}}%
              {\inrelationship@role{#2}(\relax)}}
\def\inrelationship@role#1(#2){%
 \@ifnextchar[{\inrelationship@card{#1}{#2}}%
              {\inrelationship@card{#1}{#2}[\relax]}}
\def\inrelationship@card#1#2[#3]{%
 \@ifnextchar/{\inrelationship@linetype{#1}{#2}{#3}}%
              {\inrelationship@linetype{#1}{#2}{#3}/\ncline/}}%
\def\inrelationship@linetype#1#2#3/#4/#5{%
 \dbi@purifylabel{\dbi@prfd@nodename@i}{#1}%
 \dbi@purifylabel{\dbi@prfd@nodename@ii}{#5}%
 \def\dbi@linecmd{#4}%
 \@ifnextchar[{\inrelationship@newrel{#1}{#2}{#3}{#5}}%
              {\@ifnextchar({%
                \inrelationship@newrel{#1}{#2}{#3}{#5}[#5]}%
               {\dbi@linecmd{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}
                \ifx#3\relax\else\ncput*[npos=\the\cardpos]{#3}\fi
                \ifx#2\relax\else\ncput*[npos=\the\rolepos]{#2}\fi}}}%
%    \end{macrocode}
%
% \Codelabel{inrelationshipnewrel}
%    \begin{macrocode} 
\def\inrelationship@newrel#1#2#3#4[#5]{%
 \@ifnextchar({\inrelationship@newrel@pos{#1}{#2}{#3}{#4}{#5}}%
              {\PackageError{\basename}{Position of relationship #4 
                undefined.}\@eha}}
\def\inrelationship@newrel@pos#1#2#3#4#5(#6,#7){%
  \SpecialCoor
  \dbi@purifylabel{\dbi@prfd@nodename@i}{#1}%
  \dbi@purifylabel{\dbi@prfd@nodename@ii}{#4}%
  \uput{#6}[#7]{0}(\dbi@prfd@nodename@i){\relationship[\relationtype]{#4}[#5]}%
  \NormalCoor
  \dbi@linecmd{-}{\dbi@prfd@nodename@i}{\dbi@prfd@nodename@ii}
  \ifx#3\relax\else\ncput*[npos=\the\cardpos]{#3}\fi
  \ifx#2\relax\else\ncput*[npos=\the\rolepos]{#2}\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\annote}
% \setcounter{CodelineNo}{0}
% \changes{v0.11}{98/09/24}{added annote}
%    \begin{macrocode} 
\def\annote#1#2(#3,#4){%
  \dbi@purifylabel{\dbi@prfd@nodename}{#1}%
  \SpecialCoor
  \uput{#3}[#4]{0}(\dbi@prfd@nodename){#2}%
  \NormalCoor}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\nodeconnections}
% \setcounter{CodelineNo}{0}
%    \begin{macrocode} 
\def\nodeconnections#1{\hbox to 0cm{\vbox to 0cm {#1}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\database}
% \changes{v0.13}{98/11/22}{added graphics parameters to database}
% \changes{v0.15}{05/09/09}{debugged vertical placement}
% |\database[#1]{#2}{#3}[#4]{#5}[#6]|
% \Codelabel{database}
%    \begin{macrocode} 
\def\database{\@ifnextchar[{\database@i}{\database@i[c]}}
\def\database@i[#1]#2#3{%
 \@ifnextchar[{\database@ii{#1}{#2}{#3}}%
              {\database@ii{#1}{#2}{#3}[fillstyle=none]}}
\def\database@ii#1#2#3[#4]#5{%
 \@ifnextchar[{\database@iii{#1}{#2}{#3}{#4}{#5}}%
              {\database@iii{#1}{#2}{#3}{#4}{#5}[#5]}}
\def\database@iii#1#2#3#4#5[#6]{%
 \psset{nodesep=0pt}%
 \dbi@purifylabel{\dbi@prfd@nodename}{#6}%
 \rnode{\dbi@prfd@nodename}{%
 \begin{tabular}[#1]{c}%
 \rnode{lu\dbi@prfd@nodename}{}\hspace{#2}\rnode{ru\dbi@prfd@nodename}{}\\[#3]
 \rnode{ll\dbi@prfd@nodename}{}\hspace{#2}\rnode{rl\dbi@prfd@nodename}{}%
 \end{tabular}}%
 \nodeconnections{%
 \ncbar[linestyle=none,#4,
        angleA=180,angleB=180,armB=0]{ru\dbi@prfd@nodename}{ll\dbi@prfd@nodename}
 \ncbar[linestyle=none,#4,
        angleA=0,angleB=0,armA=0]{ru\dbi@prfd@nodename}{ll\dbi@prfd@nodename}
 \nccurve[#4,angleA=90,angleB=90,ncurv=.6]{lu\dbi@prfd@nodename}{ru\dbi@prfd@nodename}%
      \ncput{\rnode{mu\dbi@prfd@nodename}{}}%
 \nccurve[angleA=-90,angleB=-90,ncurv=.6]{lu\dbi@prfd@nodename}{ru\dbi@prfd@nodename}%
      \ncput{\rnode{muf\dbi@prfd@nodename}{}}%
 \nccurve[#4,angleA=-90,angleB=-90,ncurv=.6]{ll\dbi@prfd@nodename}{rl\dbi@prfd@nodename}%
      \ncput{\rnode{ml\dbi@prfd@nodename}{}}%
 \ncline{lu\dbi@prfd@nodename}{ll\dbi@prfd@nodename}%
 \ncline{ru\dbi@prfd@nodename}{rl\dbi@prfd@nodename}%
 \ncline[linestyle=none]{muf\dbi@prfd@nodename}{ml\dbi@prfd@nodename}\ncput[npos=0.4]{#5}}}
%    \end{macrocode}
% \end{macro}
%
%\iffalse
%</package>\fi
% \GlossaryPrologue{}
%
% \IfFileExists{pst-dbicons.gls}{\PrintChanges}
% {\begin{quote}You should create the list of changes by 
% 
% ~~~ \texttt{makeindex -s gglo.ist -o pst-dbicons.gls pst-dbicons.glo}
%
% and running \texttt{latex pst-dbicons.drv} again.\end{quote}}
%
%
% \subsection{Acknowledgements}
%
% Thanx to Heiko Oberdiek for adding the handling of ids for
% internal use in postcsript (used in the |purifylabel| macro).
%
% \Finale
\endinput

% Local Variables:
% TeX-command-default: "LaTeX"
% TeX-master: t
% End:
%  mode: latex
