activefacts 0.7.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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" -->