activefacts 0.7.3 → 0.8.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/LICENSE +19 -0
  2. data/Manifest.txt +24 -2
  3. data/Rakefile +25 -3
  4. data/bin/afgen +1 -1
  5. data/bin/cql +13 -2
  6. data/css/offline.css +3 -0
  7. data/css/orm2.css +24 -0
  8. data/css/print.css +8 -0
  9. data/css/style-print.css +357 -0
  10. data/css/style.css +387 -0
  11. data/download.html +85 -0
  12. data/examples/CQL/Address.cql +3 -3
  13. data/examples/CQL/Blog.cql +13 -14
  14. data/examples/CQL/CompanyDirectorEmployee.cql +4 -4
  15. data/examples/CQL/Death.cql +3 -2
  16. data/examples/CQL/Genealogy.cql +13 -11
  17. data/examples/CQL/Marriage.cql +2 -2
  18. data/examples/CQL/Metamodel.cql +136 -93
  19. data/examples/CQL/MultiInheritance.cql +2 -2
  20. data/examples/CQL/OilSupply.cql +14 -10
  21. data/examples/CQL/Orienteering.cql +22 -19
  22. data/examples/CQL/PersonPlaysGame.cql +3 -2
  23. data/examples/CQL/SchoolActivities.cql +4 -2
  24. data/examples/CQL/SimplestUnary.cql +1 -1
  25. data/examples/CQL/SubtypePI.cql +6 -7
  26. data/examples/CQL/Warehousing.cql +16 -19
  27. data/examples/CQL/unit.cql +584 -0
  28. data/examples/index.html +276 -0
  29. data/examples/intro.html +497 -0
  30. data/examples/local.css +20 -0
  31. data/index.html +96 -0
  32. data/lib/activefacts/api/concept.rb +48 -46
  33. data/lib/activefacts/api/constellation.rb +43 -23
  34. data/lib/activefacts/api/entity.rb +2 -2
  35. data/lib/activefacts/api/instance.rb +6 -2
  36. data/lib/activefacts/api/instance_index.rb +5 -0
  37. data/lib/activefacts/api/value.rb +8 -2
  38. data/lib/activefacts/api/vocabulary.rb +15 -10
  39. data/lib/activefacts/cql/CQLParser.treetop +109 -88
  40. data/lib/activefacts/cql/Concepts.treetop +32 -10
  41. data/lib/activefacts/cql/Context.treetop +34 -0
  42. data/lib/activefacts/cql/Expressions.treetop +9 -9
  43. data/lib/activefacts/cql/FactTypes.treetop +30 -31
  44. data/lib/activefacts/cql/Language/English.treetop +50 -0
  45. data/lib/activefacts/cql/LexicalRules.treetop +2 -1
  46. data/lib/activefacts/cql/Terms.treetop +117 -0
  47. data/lib/activefacts/cql/ValueTypes.treetop +152 -0
  48. data/lib/activefacts/cql/compiler.rb +1718 -0
  49. data/lib/activefacts/cql/parser.rb +124 -57
  50. data/lib/activefacts/generate/absorption.rb +1 -1
  51. data/lib/activefacts/generate/cql.rb +111 -100
  52. data/lib/activefacts/generate/cql/html.rb +5 -5
  53. data/lib/activefacts/generate/oo.rb +3 -3
  54. data/lib/activefacts/generate/ordered.rb +51 -19
  55. data/lib/activefacts/generate/ruby.rb +10 -8
  56. data/lib/activefacts/generate/sql/mysql.rb +14 -10
  57. data/lib/activefacts/generate/sql/server.rb +29 -24
  58. data/lib/activefacts/input/cql.rb +9 -1264
  59. data/lib/activefacts/input/orm.rb +213 -200
  60. data/lib/activefacts/persistence/columns.rb +11 -10
  61. data/lib/activefacts/persistence/index.rb +15 -18
  62. data/lib/activefacts/persistence/reference.rb +17 -17
  63. data/lib/activefacts/persistence/tables.rb +50 -51
  64. data/lib/activefacts/version.rb +1 -1
  65. data/lib/activefacts/vocabulary/extensions.rb +79 -8
  66. data/lib/activefacts/vocabulary/metamodel.rb +183 -114
  67. data/spec/absorption_ruby_spec.rb +99 -0
  68. data/spec/absorption_spec.rb +3 -4
  69. data/spec/api/constellation.rb +1 -1
  70. data/spec/api/entity_type.rb +3 -1
  71. data/spec/api/instance.rb +4 -2
  72. data/spec/api/roles.rb +8 -6
  73. data/spec/api_spec.rb +1 -2
  74. data/spec/cql/context_spec.rb +71 -0
  75. data/spec/cql/samples_spec.rb +154 -0
  76. data/spec/cql/unit_spec.rb +375 -0
  77. data/spec/cql_cql_spec.rb +31 -21
  78. data/spec/cql_mysql_spec.rb +70 -0
  79. data/spec/cql_parse_spec.rb +15 -9
  80. data/spec/cql_ruby_spec.rb +27 -13
  81. data/spec/cql_sql_spec.rb +42 -16
  82. data/spec/cql_symbol_tables_spec.rb +2 -3
  83. data/spec/cqldump_spec.rb +7 -7
  84. data/spec/helpers/file_matcher.rb +39 -0
  85. data/spec/norma_cql_spec.rb +20 -12
  86. data/spec/norma_ruby_spec.rb +6 -3
  87. data/spec/norma_sql_spec.rb +6 -3
  88. data/spec/norma_tables_spec.rb +6 -4
  89. data/spec/spec_helper.rb +27 -8
  90. data/status.html +69 -0
  91. data/why.html +60 -0
  92. metadata +34 -11
  93. data/lib/activefacts/cql/DataTypes.treetop +0 -81
  94. data/spec/cql_unit_spec.rb +0 -330
@@ -0,0 +1,276 @@
1
+ <!--#include virtual="/header.html" -->
2
+ <!--#include virtual="navbar.html" -->
3
+
4
+ <link rel="stylesheet" href="../css/offline.css" media="screen" type="text/css" />
5
+ <link rel="stylesheet" href="../css/print.css" media="print" type="text/css" />
6
+
7
+ <div id="sidebar"></div>
8
+
9
+ <div id="top" class="content">
10
+
11
+ <h2>ActiveFacts Example Models</h2>
12
+ <p class="offline noprint"><font size="-1">Copyright (c) 2007 Clifford Heath.</font></p>
13
+
14
+ <!-- Things to show only in the offline version -->
15
+ <div class="localnav offline noprint">
16
+ <ul>
17
+ <li id="nav-home"><a href="/ActiveFacts/" title="Home">Home</a></li>
18
+ <li><a title="CompanyDirectorEmployee" href="#CompanyDirectorEmployee"> Company and People </a></li>
19
+ <li><a title="Blog" href="#Blog"> Blog </a></li>
20
+ <li><a title="SchoolActivities" href="#SchoolActivities"> School Activities </a></li>
21
+ <li><a title="Orienteering" href="#Orienteering"> Orienteering </a></li>
22
+ <li><a title="Metamodel" href="#Metamodel"> Metamodel </a></li>
23
+ <li><a title="All Examples" href="#AllExamples"> Table of all examples </a></li>
24
+ </ul>
25
+ </div>
26
+
27
+ <p>The example models presented here were created as Object Role Models
28
+ using <a href="http://www.ormfoundation.org/files/">NORMA</a>. The
29
+ ActiveFacts generator <em>afgen</em> was used to convert them from ORM2
30
+ to CQL, SQL and Ruby code using ActiveFacts. They're all available here
31
+ as PNG images and in the other formats.
32
+
33
+ </p><p>
34
+ To make a start learning Object Role Modeling, read the
35
+ <a href="intro.html">Introduction to ORM2</a> or check the Resources page
36
+ for other sites.
37
+
38
+ </p><p>
39
+ The CQL code here formatted and laid out is <em>exactly</em> as it was generated.
40
+ It's interesting how cleverly the semantic clustering algorithm works!
41
+
42
+ </p><p class="offline">
43
+ If you're looking at a Subversion checkout of the project on Windows,
44
+ and have Visual Studio (pro) with NORMA installed, you can open
45
+ the solution <a href="norma/ExampleModels.sln">here</a>.
46
+ Otherwise, you won't be able to edit the ORM2 files, but never fear,
47
+ you can do all the same things by editing the CQL text.
48
+ </p>
49
+
50
+ <a name="CompanyDirectorEmployee"></a>
51
+ <h4>CompanyDirectorEmployee</h4>
52
+ <p>This is my main introductory model. It shows the relationships of a person
53
+ to a company of which they are a director or employee.
54
+ </p>
55
+
56
+ <a name="Blog"></a>
57
+ <h4>Blog</h4>
58
+ <p>The Blog model supports a hierarchy of topics, Posts by Authors, each Post
59
+ consisting of a series of styled Paragraphs. Comments may be made on individual
60
+ Paragraphs.
61
+ </p>
62
+
63
+ <a name="SchoolActivities"></a>
64
+ <h4>SchoolActivities</h4>
65
+ <p>This model represents students representing their school in school-sanctioned activities.
66
+ It includes the ternary StudentParticipation <em>Fact Type</em>, which represents a student's
67
+ participation in a school-sanctioned activity.
68
+ The model has constraints that allow a given Student to participate only in a given
69
+ Activity for a single School, only representing the School in which they're enrolled, and
70
+ only if the School sanctions that activity.
71
+ </p>
72
+
73
+ <a name="Orienteering"></a>
74
+ <h4>Orienteering </h4>
75
+ <p>A model for the sport of Orienteering, broken into three diagrams for
76
+ administration, registration and scoring. These diagrams also reflect areas
77
+ of interest to folk in different roles, an idea which could inspire the use
78
+ of the division as security domains. However, for an object showing on multiple
79
+ diagrams, ORM2 doesn't indicate with which diagram it has a primary affinity.
80
+ In CQL, it might be better to structure this as three separate <em>vocabularies</em>.
81
+
82
+ </p><p>
83
+ The author is involved in orienteering in his local association (which publishes a
84
+ program and results at <a href="http://street.orienteering.com.au">street.orienteering.com.au</a>
85
+ and the <a href="http://www.vicorienteering.asn.au/parkstreet/"> Victorian Orienteering
86
+ Association</a>) and he used this model to construct a scoring system using low-power
87
+ microprocessors distributed around the course.
88
+ </p>
89
+
90
+ <a name="Metamodel"></a>
91
+ <h4>Metamodel </h4>
92
+ <p>The Metamodel encodes the meaning of an ORM2 or CQL model. All features of the
93
+ ORM2 and CQL languages have a representation here, as well as a few CQL features
94
+ that haven't yet been implemented yet. The generated Ruby code is <em>used as the
95
+ intermediate form</em> inside the CQL language implementation.
96
+ </p>
97
+
98
+ <a name="AllExamples"></a>
99
+
100
+ <h3>Table of all examples</h3>
101
+ <!-- Table below here is generated automatically -->
102
+ <table class="examples" width="100%">
103
+ <tr>
104
+ <th>Model Name</th>
105
+ <td></td>
106
+ <td></td>
107
+ <td></td>
108
+ <th>Diagrams</th>
109
+ </tr>
110
+
111
+ <tr>
112
+ <td>Address</td>
113
+ <td><a href="CQL/Address.cql">CQL</a></td>
114
+ <td><a href="ruby/Address.rb">Ruby</a></td>
115
+ <td><a href="SQL/Address.sql">SQL</a></td>
116
+ <td>
117
+ <a href="images/Address.png">Address</a><br>
118
+ </tr>
119
+
120
+ <tr>
121
+ <td>Blog</td>
122
+ <td><a href="CQL/Blog.cql">CQL</a></td>
123
+ <td><a href="ruby/Blog.rb">Ruby</a></td>
124
+ <td><a href="SQL/Blog.sql">SQL</a></td>
125
+ <td>
126
+ <a href="images/Blog.png">Blog</a><br>
127
+ </tr>
128
+
129
+ <tr>
130
+ <td>CompanyDirectorEmployee</td>
131
+ <td><a href="CQL/CompanyDirectorEmployee.cql">CQL</a></td>
132
+ <td><a href="ruby/CompanyDirectorEmployee.rb">Ruby</a></td>
133
+ <td><a href="SQL/CompanyDirectorEmployee.sql">SQL</a></td>
134
+ <td>
135
+ <a href="images/CompanyDirectorEmployee.png">CompanyDirectorEmployee</a><br>
136
+ </tr>
137
+
138
+ <tr>
139
+ <td>Death</td>
140
+ <td><a href="CQL/Death.cql">CQL</a></td>
141
+ <td><a href="ruby/Death.rb">Ruby</a></td>
142
+ <td><a href="SQL/Death.sql">SQL</a></td>
143
+ <td>
144
+ <a href="images/Death.png">Death</a><br>
145
+ </tr>
146
+
147
+ <tr>
148
+ <td>Genealogy</td>
149
+ <td><a href="CQL/Genealogy.cql">CQL</a></td>
150
+ <td><a href="ruby/Genealogy.rb">Ruby</a></td>
151
+ <td><a href="SQL/Genealogy.sql">SQL</a></td>
152
+ <td>
153
+ <a href="images/Genealogy.png">Genealogy</a><br>
154
+ </tr>
155
+
156
+ <tr>
157
+ <td>Insurance</td>
158
+ <td><a href="CQL/Insurance.cql">CQL</a></td>
159
+ <td><a href="ruby/Insurance.rb">Ruby</a></td>
160
+ <td><a href="SQL/Insurance.sql">SQL</a></td>
161
+ <td>
162
+ <a href="images/Insurance/Claim.png">Claim</a><br>
163
+ <a href="images/Insurance/Insurance.png">Insurance</a><br>
164
+ <a href="images/Insurance/Person.png">Person</a><br>
165
+ <a href="images/Insurance/Policy.png">Policy</a><br>
166
+ </tr>
167
+
168
+ <tr>
169
+ <td>Marriage</td>
170
+ <td><a href="CQL/Marriage.cql">CQL</a></td>
171
+ <td><a href="ruby/Marriage.rb">Ruby</a></td>
172
+ <td><a href="SQL/Marriage.sql">SQL</a></td>
173
+ <td>
174
+ <a href="images/Marriage.png">Marriage</a><br>
175
+ </tr>
176
+
177
+ <tr>
178
+ <td>Metamodel</td>
179
+ <td><a href="CQL/Metamodel.cql">CQL</a></td>
180
+ <td><a href="ruby/Metamodel.rb">Ruby</a></td>
181
+ <td><a href="SQL/Metamodel.sql">SQL</a></td>
182
+ <td>
183
+ <a href="images/Metamodel/Constraints.png">Constraints</a><br>
184
+ <a href="images/Metamodel/Import.png">Import</a><br>
185
+ <a href="images/Metamodel/Objects.png">Objects</a><br>
186
+ <a href="images/Metamodel/Populations.png">Populations</a><br>
187
+ <a href="images/Metamodel/Values.png">Values</a><br>
188
+ </tr>
189
+
190
+ <tr>
191
+ <td>MultiInheritance</td>
192
+ <td><a href="CQL/MultiInheritance.cql">CQL</a></td>
193
+ <td><a href="ruby/MultiInheritance.rb">Ruby</a></td>
194
+ <td><a href="SQL/MultiInheritance.sql">SQL</a></td>
195
+ <td>
196
+ <a href="images/MultiInheritance.png">MultiInheritance</a><br>
197
+ </tr>
198
+
199
+ <tr>
200
+ <td>OilSupply</td>
201
+ <td><a href="CQL/OilSupply.cql">CQL</a></td>
202
+ <td><a href="ruby/OilSupply.rb">Ruby</a></td>
203
+ <td><a href="SQL/OilSupply.sql">SQL</a></td>
204
+ <td>
205
+ <a href="images/OilSupply.png">OilSupply</a><br>
206
+ </tr>
207
+
208
+ <tr>
209
+ <td>Orienteering</td>
210
+ <td><a href="CQL/Orienteering.cql">CQL</a></td>
211
+ <td><a href="ruby/Orienteering.rb">Ruby</a></td>
212
+ <td><a href="SQL/Orienteering.sql">SQL</a></td>
213
+ <td>
214
+ <a href="images/Orienteering/Administration.png">Administration</a><br>
215
+ <a href="images/Orienteering/Registration.png">Registration</a><br>
216
+ <a href="images/Orienteering/Scoring.png">Scoring</a><br>
217
+ </tr>
218
+
219
+ <tr>
220
+ <td>OrienteeringER</td>
221
+ <td><a href="CQL/OrienteeringER.cql">CQL</a></td>
222
+ <td><a href="ruby/OrienteeringER.rb">Ruby</a></td>
223
+ <td><a href="SQL/OrienteeringER.sql">SQL</a></td>
224
+ <td>
225
+ <a href="images/OrienteeringER.png">OrienteeringER</a><br>
226
+ </tr>
227
+
228
+ <tr>
229
+ <td>PersonPlaysGame</td>
230
+ <td><a href="CQL/PersonPlaysGame.cql">CQL</a></td>
231
+ <td><a href="ruby/PersonPlaysGame.rb">Ruby</a></td>
232
+ <td><a href="SQL/PersonPlaysGame.sql">SQL</a></td>
233
+ <td>
234
+ <a href="images/PersonPlaysGame.png">PersonPlaysGame</a><br>
235
+ </tr>
236
+
237
+ <tr>
238
+ <td>SchoolActivities</td>
239
+ <td><a href="CQL/SchoolActivities.cql">CQL</a></td>
240
+ <td><a href="ruby/SchoolActivities.rb">Ruby</a></td>
241
+ <td><a href="SQL/SchoolActivities.sql">SQL</a></td>
242
+ <td>
243
+ <a href="images/SchoolActivities.png">SchoolActivities</a><br>
244
+ </tr>
245
+
246
+ <tr>
247
+ <td>SimplestUnary</td>
248
+ <td><a href="CQL/SimplestUnary.cql">CQL</a></td>
249
+ <td><a href="ruby/SimplestUnary.rb">Ruby</a></td>
250
+ <td><a href="SQL/SimplestUnary.sql">SQL</a></td>
251
+ <td>
252
+ <a href="images/SimplestUnary.png">SimplestUnary</a><br>
253
+ </tr>
254
+
255
+ <tr>
256
+ <td>Warehousing</td>
257
+ <td><a href="CQL/Warehousing.cql">CQL</a></td>
258
+ <td><a href="ruby/Warehousing.rb">Ruby</a></td>
259
+ <td><a href="SQL/Warehousing.sql">SQL</a></td>
260
+ <td>
261
+ <a href="images/Warehousing.png">Warehousing</a><br>
262
+ </tr>
263
+
264
+ <tr>
265
+ <td>WindowInRoomInBldg</td>
266
+ <td><a href="CQL/WindowInRoomInBldg.cql">CQL</a></td>
267
+ <td><a href="ruby/WindowInRoomInBldg.rb">Ruby</a></td>
268
+ <td><a href="SQL/WindowInRoomInBldg.sql">SQL</a></td>
269
+ <td>
270
+ <a href="images/WindowInRoomInBldg.png">WindowInRoomInBldg</a><br>
271
+ </tr>
272
+ </table>
273
+
274
+ </div>
275
+
276
+ <!--#include virtual="/footer.html" -->
@@ -0,0 +1,497 @@
1
+ <!--#include virtual="/header.html" -->
2
+ <!--#include virtual="navbar.html" -->
3
+
4
+ <link rel="stylesheet" href="../css/offline.css" media="screen" type="text/css" />
5
+ <link rel="stylesheet" href="../css/print.css" media="print" type="text/css" />
6
+
7
+ <div id="top" class="content">
8
+ <h2>Introduction to Object Role Modeling</h2>
9
+ <p class="offline" ><font size="-1">Copyright (c) 2007 Clifford Heath.</font></p>
10
+
11
+ <div class="localnav offline noprint">
12
+ <a href="#top"><strong>Example Models</strong></a><br/>
13
+ <a href="#CompanyDirectorEmployee"> Company </a><br/>
14
+ <a href="#SchoolActivities"> School Activities </a><br/>
15
+ <a href="#Death"> Death </a><br/>
16
+ <a href="#Address"> Address</a><br/>
17
+ <a href="#Orienteering"> Orienteering </a><br/>
18
+ <a href="#AllExamples"> Table of all examples </a><br/>
19
+ </div>
20
+
21
+ <p> Congratulations, you're just a few minutes away from knowing a more
22
+ agile way to design good database schemas. These models were created in ORM2
23
+ using <a href="http://www.ormfoundation.org/files/">NORMA</a>.
24
+ ORM2 terminology is <em>emphasised</em> on first use.
25
+ </p>
26
+
27
+ <a name="CompanyDirectorEmployee"></a>
28
+ <h3>CompanyDirectorEmployee</h3>
29
+ <p>This model shows the some of the relationships of a person to a company of
30
+ which they are a director or employee.
31
+ </p>
32
+
33
+ <table class="examples" width="100%">
34
+ <tr>
35
+ <td style='width:25%; border:0;'>View the generated:</td>
36
+ <td><a href="CQL/CompanyDirectorEmployee.cql">CQL</a></td>
37
+ <td><a href="ruby/CompanyDirectorEmployee.rb">Ruby</a></td>
38
+ <td><a href="SQL/CompanyDirectorEmployee.sql">SQL</a></td>
39
+ </tr>
40
+ </table>
41
+
42
+ <p><center>
43
+ <img src="images/CompanyDirectorEmployee.png" width="700" height="420" class="hangleft"></p>
44
+ </center>
45
+ </p>
46
+
47
+ <p>This model includes examples of the features of ORM2 you'll be seeing most often.</p>
48
+ <ul>
49
+ <li><i>Entity Types</i> (<b>Person</b>, <b>Company</b>) and <i>Value Types</i>
50
+ (Name, Date). Collectively, ActiveFacts calls them Concepts. Value types
51
+ have a dashed outline.
52
+ </li>
53
+
54
+ <li>Entity <i>Identification schemes</i>: Person is identified by the pair
55
+ of values (given-Name, family-Name), as indicated by the circle with two
56
+ lines across it. Company is identified by a single CompanyName, but since
57
+ this is a common pattern, it's included within the Company shape, which
58
+ is called a <b>reference mode</b>. Every Entity Type must have some
59
+ identification scheme or preferred identifier, which enables us to tell
60
+ the instances apart.
61
+ </li>
62
+
63
+ <li><i>Subtype:</i> <b>Employee</b> and <b>Manager</b> are subtypes.
64
+ Employee has a dashed arrow, because it has its own identification scheme,
65
+ it doesn't use Persons's scheme. An EntityType may have multiple supertypes,
66
+ and an instance may play any role of its supertypes (so we can record the
67
+ Birth-Date of an Employee, for example).
68
+ </li>
69
+
70
+ <li><i>Fact Types</i> define relationships between concepts. They're displayed
71
+ as a series of one or more <i>Role</i> boxes. For example, the fact type
72
+ "Person has given-Name" has two roles, played by Person and Name.
73
+ The <b>unary fact type</b> <i>Meeting is board meeting</i> indicates a
74
+ true/false condition with respect to a meeting.
75
+ </li>
76
+
77
+ <li><i>Objectified Fact Type:</i> <b>Directorship</b> and <b>Meeting</b> are
78
+ fact types that are also entities, and thus can play other roles, such as
79
+ the role of Directorship in "Directorship began on appointment-Date".
80
+ </li>
81
+
82
+ <li><i>Fact Readings</i> are displayed as text under each fact type. A fact
83
+ type may have many readings, though only the preferred one is shown on the
84
+ diagram. Binary fact types may display a reading for each direction. An
85
+ arrow is displayed if a single reading is to be read in the opposite order
86
+ from the obvious one.
87
+ </li>
88
+
89
+ <li><i>Uniqueness constraints</i>: The horizontal lines above the fact types
90
+ are uniqueness constraints (UC). A UC covering a single role allows that
91
+ role's player to occur only once all the instances of that fact type (what
92
+ we call the <b>population</b> of that fact type). A UC that covers two or
93
+ more roles allows any combination of those players, but only once for each
94
+ combination. An </b>external</b> UC may connect to roles in more than one
95
+ fact type, and is shown as a circle with a line across it. If any of the
96
+ UC lines is doubles, that UC acts as a preferred identifier for the indicated
97
+ entity type.
98
+ </li>
99
+
100
+ <li><i>Mandatory constraint</i>: The heavy dot on some role connectors (like
101
+ the one on the Company role box of Director) is a mandatory constraint that
102
+ requires every company to have at least one director. A mandatory constraint
103
+ may also be shown as a hollow dot, which says <i>should</i>, rather than
104
+ <i>must</i>.
105
+ </li>
106
+
107
+ <li><i>External Mandatory constraint</i>: The circle containing a crossed dot
108
+ which is joined to "is ceo" and "Employee is supervised by Manager" is a
109
+ mandatory exclusion constraint. The cross (X) indicates exclusion (only one)
110
+ and the dot indicates mandatory (at least one). Both types may also occur
111
+ separately.
112
+ </li>
113
+
114
+ <li><i>Ring constraint</i>: A Ring constraint is attached to the "Employee is
115
+ supervised by Manager". This one is acyclic, indicating that an Employee
116
+ may not supervise themselves, or anyone who supervises them, and so on.
117
+ There are a number of other types of ring constraints.
118
+ </li>
119
+
120
+ <li><i>Role Value Restriction</i>: The Date value recorded for a person's birth
121
+ date may not be before the year 1900. Other Date values don't have this
122
+ same restriction.
123
+ </li>
124
+
125
+ </ul>
126
+
127
+ <br clear="all">
128
+ <a name="SchoolActivities">
129
+ </a>
130
+ <h3>SchoolActivities
131
+ </h3>
132
+ <p>This model represents students representing their school in school-sanctioned activities.
133
+ </p>
134
+
135
+ <p align="center"><img src="images/SchoolActivities.png"></p>
136
+
137
+ <p>
138
+ The model has three interesting constraints:
139
+ <dl>
140
+ <dt> Uniqueness over <em>Student represents School in Activity</em>:</dt>
141
+ <dd> Allows a given Student may only participate in a given Activity for a single School</dd>
142
+ <dt> <b>Subset</b> from Participation to Enrollment</dt>
143
+ <dd> Only for the School in which they're enrolled</dd>
144
+ <dt> <b>Subset</b> from Participation to Sanctions</dt>
145
+ <dd> Only if the School sanctions that activity.</dd>
146
+ </p>
147
+
148
+ <p> The rules of <em>elementarity</em> require that every fact type having N roles has
149
+ a uniqueness constraint over either N or N-1 roles, and never over fewer roles.
150
+ This is satisfied here by the StudentParticipation having a uniqueness constraint
151
+ over two of its three roles.
152
+ </p>
153
+
154
+ <p>
155
+ The subset constraints work like this. The student is enrolled in exactly one school,
156
+ and the set of (School, Student) pairs is a superset of the (School, Student) pair
157
+ inside the StudentParticipation ternary. In simple terms, this requires that each
158
+ student who participates in some activity may only do so as a representative of the
159
+ school in which they're enrolled, and not for any other school. The other subset
160
+ constraint requires that such participation may only occur for an activity that is
161
+ sanctioned by that school. The direction of the subset arrow is consistent with the
162
+ arrows used in sub-typing, as shown in the next case.
163
+ </p>
164
+
165
+ <br clear="all">
166
+ <a name="Death"></a>
167
+ <h3>Death</h3>
168
+ <img src="images/Death.png" align="right">
169
+ This example is more a curiosity than anything else, serving to illustrate a case
170
+ that you might not otherwise think was possible. Person may play a unary role in
171
+ the fact type &quot;is dead&quot;. If they are in fact dead, we might wish to
172
+ record some facts about the event of their death, so we nest (objectify) the
173
+ &quot;is dead&quot; fact type as a new entity, Death. This allows us to
174
+ associate their death with a value indicating the cause of death. The uniqueness
175
+ constraint requires that we record only one cause of death.
176
+ <p>
177
+
178
+ <br clear="all">
179
+ <a name="Address">
180
+ </a>
181
+ <h3>
182
+ Address
183
+ </h3>
184
+
185
+ <p>The Address model shows how a mass of fine semantic detail can be turned into
186
+ an efficient relational database structure, through the miracle of <em>absorption</em>.
187
+ </p>
188
+
189
+ <table class="examples" width="100%">
190
+ <tr>
191
+ <td style='width:25%; border:0;'>View the generated:</td>
192
+ <td><a href="CQL/Address.cql">CQL</a></td>
193
+ <td><a href="ruby/Address.rb">Ruby</a></td>
194
+ <td><a href="SQL/Address.sql">SQL</a></td>
195
+ </tr>
196
+ </table>
197
+ </p>
198
+
199
+ <p align="center"><img src="images/Address.png" class="hangleft">
200
+
201
+ <p>Note that the preferred identifier for Street covers all its functional roles.
202
+ Essentially that means that whereever we have a Street, all the attributes of that
203
+ street must be provided; so we can include them in more than one table without
204
+ breaking the relational <a href="http://en.wikipedia.org/wiki/Third_normal_form">Third
205
+ Normal Form</a>, which would introduce unsafe duplication.
206
+
207
+ </p><p>
208
+ The same thing pertains for Address, so we can have an Address in both the Company
209
+ and Person tables without breaking normalisation. Here's the generated SQL created
210
+ by <em>afgen</em>:
211
+
212
+ </p> <p>
213
+ <img src="images/Address.SQL.png" align="left">
214
+ </p>
215
+ <br clear="all">
216
+
217
+ <p>Note also that the SQL doesn't enforce the uniqueness constraint requiring
218
+ that each Address occurs once only. There's no need to. Each Address is
219
+ identified by its roles, but more than one person may live at the same address,
220
+ and a company might have its HQ there too. If you want all the distinct addresses,
221
+ you can write an SQL UNION query for that.
222
+ </p>
223
+
224
+ <p>If you want an Address table anyhow, you can mark it as <em>independent</em>,
225
+ which is an instruction to the absorption process that an instance of this entity
226
+ type might exist apart from any other roles it might play. Independent entity types
227
+ are shown in ORM2 as having an exclamation point <b>!</b> after their name. In
228
+ order to represent an independent entity type in SQL, a separate table is always
229
+ needed.
230
+ </p>
231
+
232
+ <p> If you were to add a functional role to Address that's not part of its
233
+ identifier, the rules of normalisation gazump absorption and Address will become
234
+ an independent table. In that case, Company and Person would have each a large
235
+ multi-part foreign key into the new Address table, so it might be preferable to
236
+ introduce a <i>surrogate key</i> in the form of a database-allocated unique integer
237
+ into the address entity, and mark that key as the preferred identifier instead.
238
+ This can be done with <em>minimal</em> change to the semantic model, so any queries
239
+ you have will probably still <b>just work</b> - this is a key advantage of the
240
+ semantic approach.
241
+ </p>
242
+
243
+ <p>
244
+ Note that the absorption process must know <b>all</b> the entity types, fact types,
245
+ and constraints for the model. If you add a single fact type or change a constraint,
246
+ that might require that some concepts are represented in new tables, or different ones,
247
+ and these changes can <b>cascade</b>, so that a small change in the conceptual model
248
+ requires a large database migration. If you've written your program using the
249
+ Constellation API, you'll have <em>minimal rework</em>.
250
+ </p>
251
+
252
+ <br clear="all">
253
+ <h3>
254
+ <a name="Orienteering">
255
+ </a>
256
+ Orienteering
257
+ </h3>
258
+ <p>Here's a three-part model of a system for the sport of Orienteering. The
259
+ three parts cover administration, registration and scoring respectively, which
260
+ also happens to map areas of interest to folk in different roles. Any feature
261
+ may show on more than one diagram, and the ORM2 rules don't indicate that such
262
+ an element has a special affinity with any diagram on which it appears.
263
+ Concepts that appear in more than one place are shown with a drop-shadow. The
264
+ diagrams are presented without much comment, and after that, the absorbed
265
+ (compound) form is shown as an entity-relationship diagram. </p>
266
+
267
+ <a name="Administration"></a>
268
+ <h3>
269
+ Administration
270
+ </h3>
271
+ <p align="center"><img src="images/Orienteering/Administration.png">
272
+ </p>
273
+
274
+ <p>
275
+ A couple of new features are shown here. <i>Number</i> has a <b>Value restriction</b>,
276
+ which is similar to the role value restrictions we saw before, except it applies
277
+ to all <i>Number</i>s.
278
+ </p>
279
+
280
+ <p>Also here you'll see an external mandatory constraint without an exclusive
281
+ cross. This one requires that an event is either part of a series, or has a name,
282
+ or <b>both</b>. If and only if the event is part of a series, it must also have a
283
+ number in that series - this is shown by the <b>equality constraint</b>, a
284
+ circle with an = sign in it. </p>
285
+ <br clear="all">
286
+ </p>
287
+
288
+ <a name="Registration"></a>
289
+ <h3>
290
+ Registration
291
+ </h3>
292
+
293
+ <p align="center"><img src="images/Orienteering/Registration.png"></p>
294
+
295
+ <br clear="all">
296
+ <a name="Scoring"></a>
297
+ </p>
298
+ <h3>
299
+ Scoring
300
+ </h3>
301
+
302
+ <p align="center"><img src="images/Orienteering/Scoring.png">
303
+ <table class="examples" width="100%">
304
+ <tr>
305
+ <td style='width:25%; border:0;'>View the generated:</td>
306
+ <td><a href="CQL/Orienteering.cql">CQL</a></td>
307
+ <td><a href="ruby/Orienteering.rb">Ruby</a></td>
308
+ <td><a href="SQL/Orienteering.sql">SQL</a></td>
309
+ </tr>
310
+ </table>
311
+ </p>
312
+
313
+ <p>This model also shows the resultant score for a given Entrant's
314
+ Entry to a given Event. This value will be computed from the times
315
+ of their visits to punches during the event, according to a scoring
316
+ method as advised. The asterisks indicate that the role value is
317
+ derived from other values in the model, or that some values may
318
+ be derived and others now.
319
+
320
+ <br clear="all">
321
+ </p>
322
+
323
+ <div class="noprint">
324
+ <a name="AllExamples"></a>
325
+
326
+ <h3>Table of all examples</h3>
327
+ <!-- Table below here is generated automatically -->
328
+ <table class="examples" width="100%">
329
+ <tr>
330
+ <td>Address</td>
331
+ <td><a href="CQL/Address.cql">CQL</a></td>
332
+ <td><a href="ruby/Address.rb">Ruby</a></td>
333
+ <td><a href="SQL/Address.sql">SQL</a></td>
334
+ <td>
335
+ <a href="images/Address.png">Address</a><br>
336
+ </tr>
337
+
338
+ <a name="Blog"></a>
339
+ <tr>
340
+ <td>Blog</td>
341
+ <td><a href="CQL/Blog.cql">CQL</a></td>
342
+ <td><a href="ruby/Blog.rb">Ruby</a></td>
343
+ <td><a href="SQL/Blog.sql">SQL</a></td>
344
+ <td>
345
+ <a href="images/Blog.png">Blog</a><br>
346
+ </tr>
347
+
348
+ <tr>
349
+ <td>CompanyDirectorEmployee</td>
350
+ <td><a href="CQL/CompanyDirectorEmployee.cql">CQL</a></td>
351
+ <td><a href="ruby/CompanyDirectorEmployee.rb">Ruby</a></td>
352
+ <td><a href="SQL/CompanyDirectorEmployee.sql">SQL</a></td>
353
+ <td>
354
+ <a href="images/CompanyDirectorEmployee.png">CompanyDirectorEmployee</a><br>
355
+ </tr>
356
+
357
+ <tr>
358
+ <td>Death</td>
359
+ <td><a href="CQL/Death.cql">CQL</a></td>
360
+ <td><a href="ruby/Death.rb">Ruby</a></td>
361
+ <td><a href="SQL/Death.sql">SQL</a></td>
362
+ <td>
363
+ <a href="images/Death.png">Death</a><br>
364
+ </tr>
365
+
366
+ <tr>
367
+ <td>Genealogy</td>
368
+ <td><a href="CQL/Genealogy.cql">CQL</a></td>
369
+ <td><a href="ruby/Genealogy.rb">Ruby</a></td>
370
+ <td><a href="SQL/Genealogy.sql">SQL</a></td>
371
+ <td>
372
+ <a href="images/Genealogy.png">Genealogy</a><br>
373
+ </tr>
374
+
375
+ <tr>
376
+ <td>Insurance</td>
377
+ <td><a href="CQL/Insurance.cql">CQL</a></td>
378
+ <td><a href="ruby/Insurance.rb">Ruby</a></td>
379
+ <td><a href="SQL/Insurance.sql">SQL</a></td>
380
+ <td>
381
+ <a href="images/Insurance/Claim.png">Claim</a><br>
382
+ <a href="images/Insurance/Insurance.png">Insurance</a><br>
383
+ <a href="images/Insurance/Person.png">Person</a><br>
384
+ <a href="images/Insurance/Policy.png">Policy</a><br>
385
+ </tr>
386
+
387
+ <tr>
388
+ <td>Marriage</td>
389
+ <td><a href="CQL/Marriage.cql">CQL</a></td>
390
+ <td><a href="ruby/Marriage.rb">Ruby</a></td>
391
+ <td><a href="SQL/Marriage.sql">SQL</a></td>
392
+ <td>
393
+ <a href="images/Marriage.png">Marriage</a><br>
394
+ </tr>
395
+
396
+ <a name="Metamodel"></a>
397
+ <tr>
398
+ <td>Metamodel</td>
399
+ <td><a href="CQL/Metamodel.cql">CQL</a></td>
400
+ <td><a href="ruby/Metamodel.rb">Ruby</a></td>
401
+ <td><a href="SQL/Metamodel.sql">SQL</a></td>
402
+ <td>
403
+ <a href="images/Metamodel/Constraints.png">Constraints</a><br>
404
+ <a href="images/Metamodel/Import.png">Import</a><br>
405
+ <a href="images/Metamodel/Objects.png">Objects</a><br>
406
+ <a href="images/Metamodel/Populations.png">Populations</a><br>
407
+ <a href="images/Metamodel/Values.png">Values</a><br>
408
+ </tr>
409
+
410
+ <tr>
411
+ <td>MultiInheritance</td>
412
+ <td><a href="CQL/MultiInheritance.cql">CQL</a></td>
413
+ <td><a href="ruby/MultiInheritance.rb">Ruby</a></td>
414
+ <td><a href="SQL/MultiInheritance.sql">SQL</a></td>
415
+ <td>
416
+ <a href="images/MultiInheritance.png">MultiInheritance</a><br>
417
+ </tr>
418
+
419
+ <tr>
420
+ <td>OilSupply</td>
421
+ <td><a href="CQL/OilSupply.cql">CQL</a></td>
422
+ <td><a href="ruby/OilSupply.rb">Ruby</a></td>
423
+ <td><a href="SQL/OilSupply.sql">SQL</a></td>
424
+ <td>
425
+ <a href="images/OilSupply.png">OilSupply</a><br>
426
+ </tr>
427
+
428
+ <tr>
429
+ <td>Orienteering</td>
430
+ <td><a href="CQL/Orienteering.cql">CQL</a></td>
431
+ <td><a href="ruby/Orienteering.rb">Ruby</a></td>
432
+ <td><a href="SQL/Orienteering.sql">SQL</a></td>
433
+ <td>
434
+ <a href="images/Orienteering/Administration.png">Administration</a><br>
435
+ <a href="images/Orienteering/Registration.png">Registration</a><br>
436
+ <a href="images/Orienteering/Scoring.png">Scoring</a><br>
437
+ </tr>
438
+
439
+ <tr>
440
+ <td>OrienteeringER</td>
441
+ <td><a href="CQL/OrienteeringER.cql">CQL</a></td>
442
+ <td><a href="ruby/OrienteeringER.rb">Ruby</a></td>
443
+ <td><a href="SQL/OrienteeringER.sql">SQL</a></td>
444
+ <td>
445
+ <a href="images/OrienteeringER.png">OrienteeringER</a><br>
446
+ </tr>
447
+
448
+ <tr>
449
+ <td>PersonPlaysGame</td>
450
+ <td><a href="CQL/PersonPlaysGame.cql">CQL</a></td>
451
+ <td><a href="ruby/PersonPlaysGame.rb">Ruby</a></td>
452
+ <td><a href="SQL/PersonPlaysGame.sql">SQL</a></td>
453
+ <td>
454
+ <a href="images/PersonPlaysGame.png">PersonPlaysGame</a><br>
455
+ </tr>
456
+
457
+ <tr>
458
+ <td>SchoolActivities</td>
459
+ <td><a href="CQL/SchoolActivities.cql">CQL</a></td>
460
+ <td><a href="ruby/SchoolActivities.rb">Ruby</a></td>
461
+ <td><a href="SQL/SchoolActivities.sql">SQL</a></td>
462
+ <td>
463
+ <a href="images/SchoolActivities.png">SchoolActivities</a><br>
464
+ </tr>
465
+
466
+ <tr>
467
+ <td>SimplestUnary</td>
468
+ <td><a href="CQL/SimplestUnary.cql">CQL</a></td>
469
+ <td><a href="ruby/SimplestUnary.rb">Ruby</a></td>
470
+ <td><a href="SQL/SimplestUnary.sql">SQL</a></td>
471
+ <td>
472
+ <a href="images/SimplestUnary.png">SimplestUnary</a><br>
473
+ </tr>
474
+
475
+ <tr>
476
+ <td>Warehousing</td>
477
+ <td><a href="CQL/Warehousing.cql">CQL</a></td>
478
+ <td><a href="ruby/Warehousing.rb">Ruby</a></td>
479
+ <td><a href="SQL/Warehousing.sql">SQL</a></td>
480
+ <td>
481
+ <a href="images/Warehousing.png">Warehousing</a><br>
482
+ </tr>
483
+
484
+ <tr>
485
+ <td>WindowInRoomInBldg</td>
486
+ <td><a href="CQL/WindowInRoomInBldg.cql">CQL</a></td>
487
+ <td><a href="ruby/WindowInRoomInBldg.rb">Ruby</a></td>
488
+ <td><a href="SQL/WindowInRoomInBldg.sql">SQL</a></td>
489
+ <td>
490
+ <a href="images/WindowInRoomInBldg.png">WindowInRoomInBldg</a><br>
491
+ </tr>
492
+ </table>
493
+ </div>
494
+
495
+ </div>
496
+
497
+ <!--#include virtual="/footer.html" -->