activefacts 0.8.13 → 0.8.15
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.
- data/Manifest.txt +6 -0
- data/Rakefile +68 -41
- data/TODO +308 -0
- data/lib/activefacts/cql/FactTypes.treetop +1 -1
- data/lib/activefacts/generate/dm.rb +273 -0
- data/lib/activefacts/generate/help.rb +45 -0
- data/lib/activefacts/generate/html/glossary.rb +209 -0
- data/lib/activefacts/generate/json.rb +334 -0
- data/lib/activefacts/generate/records.rb +45 -0
- data/lib/activefacts/generate/version.rb +25 -0
- data/lib/activefacts/version.rb +8 -1
- metadata +220 -36
- data/.gemtest +0 -0
- data/examples/CQL/MetamodelNext.cql +0 -477
data/Manifest.txt
CHANGED
@@ -74,13 +74,19 @@ lib/activefacts/cql/nodes.rb
|
|
74
74
|
lib/activefacts/cql/parser.rb
|
75
75
|
lib/activefacts/generate/absorption.rb
|
76
76
|
lib/activefacts/generate/cql.rb
|
77
|
+
lib/activefacts/generate/dm.rb
|
78
|
+
lib/activefacts/generate/help.rb
|
79
|
+
lib/activefacts/generate/html/glossary.rb
|
80
|
+
lib/activefacts/generate/json.rb
|
77
81
|
lib/activefacts/generate/null.rb
|
78
82
|
lib/activefacts/generate/oo.rb
|
79
83
|
lib/activefacts/generate/ordered.rb
|
84
|
+
lib/activefacts/generate/records.rb
|
80
85
|
lib/activefacts/generate/ruby.rb
|
81
86
|
lib/activefacts/generate/sql/mysql.rb
|
82
87
|
lib/activefacts/generate/sql/server.rb
|
83
88
|
lib/activefacts/generate/text.rb
|
89
|
+
lib/activefacts/generate/version.rb
|
84
90
|
lib/activefacts/input/cql.rb
|
85
91
|
lib/activefacts/input/orm.rb
|
86
92
|
lib/activefacts/persistence.rb
|
data/Rakefile
CHANGED
@@ -1,64 +1,91 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require 'rspec'
|
7
|
-
require 'rspec/core/rake_task'
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'fileutils'
|
4
|
+
require File.dirname(__FILE__) + '/lib/activefacts'
|
8
5
|
|
9
|
-
|
6
|
+
def File.read_utf(path)
|
7
|
+
open path, 'rb' do |f|
|
8
|
+
f.read.sub %r/\A\xEF\xBB\xBF/, ''
|
9
|
+
end
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
+
def paragraphs_of path, *paragraphs
|
13
|
+
File.read_utf(path).delete("\r").split(/\n\n+/).values_at(*paragraphs)
|
14
|
+
end
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
require 'jeweler'
|
17
|
+
Jeweler::Tasks.new do |gem|
|
18
|
+
gem.name = "activefacts"
|
19
|
+
gem.homepage = "http://github.com/cjheath/activefacts"
|
20
|
+
gem.license = "MIT"
|
21
|
+
gem.version = ActiveFacts::VERSION
|
22
|
+
gem.summary = "A semantic modeling and query language (CQL) and application runtime (the Constellation API)"
|
23
|
+
gem.description = %q{
|
19
24
|
ActiveFacts provides a semantic modeling language, the Constellation
|
20
25
|
Query Language (CQL). CQL combines natural language verbalisation and
|
21
26
|
formal logic, producing a formal language that reads like plain
|
22
27
|
English. ActiveFacts converts semantic models from CQL to relational
|
23
28
|
and object models in SQL, Ruby and other languages.
|
24
29
|
}
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
30
|
+
# gem.url = "http://dataconstellation.com/ActiveFacts/"
|
31
|
+
|
32
|
+
gem.email = "cjh@dataconstellation.com"
|
33
|
+
gem.authors = ["Clifford Heath"]
|
34
|
+
gem.add_dependency "activefacts-api", "~>0.9.1"
|
35
|
+
gem.add_dependency "treetop"
|
36
|
+
gem.add_dependency "nokogiri"
|
37
|
+
gem.add_development_dependency "rspec", "~> 2.3.0"
|
38
|
+
gem.add_development_dependency "bundler", "~> 1.0.0"
|
39
|
+
gem.add_development_dependency "jeweler", "~> 1.5.2"
|
40
|
+
# gem.add_development_dependency "rcov", ">= 0"
|
41
|
+
gem.add_development_dependency "rdoc", ">= 2.4.2"
|
42
|
+
|
43
|
+
# gem.changes = paragraphs_of("History.txt", 0..1).join("\n\n")
|
44
|
+
gem.extensions = ['lib/activefacts/cql/Rakefile']
|
45
|
+
gem.post_install_message = 'For more information on ActiveFacts, see http://dataconstellation.com/ActiveFacts'
|
46
|
+
|
47
|
+
gem.files = File.open("Manifest.txt"){|f| f.read.split(/\n/)}
|
48
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{|f| f.sub('bin/', '')}
|
49
|
+
gem.rdoc_options = ['-S'] +
|
42
50
|
# RDoc used to have these options: -A has_one -A one_to_one -A maybe
|
43
51
|
%w{
|
44
52
|
-x lib/activefacts/cql/.*.rb
|
45
53
|
-x lib/activefacts/vocabulary/.*.rb
|
46
54
|
}
|
47
|
-
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
48
|
-
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
49
|
-
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
50
|
-
p.rsync_args = '-av --delete --ignore-errors'
|
51
55
|
end
|
56
|
+
Jeweler::RubygemsDotOrgTasks.new
|
57
|
+
|
58
|
+
# Dir['tasks/**/*.rake'].each { |t| load t }
|
59
|
+
|
60
|
+
require 'rspec'
|
61
|
+
require 'rspec/core/rake_task'
|
52
62
|
|
53
|
-
|
54
|
-
Dir['tasks/**/*.rake'].each { |t| load t }
|
63
|
+
gem "rspec", :require => "spec/rake/spectask"
|
55
64
|
|
56
|
-
|
57
|
-
# task :default => [:spec, :features]
|
65
|
+
task :default => :spec
|
58
66
|
|
59
|
-
|
67
|
+
desc "Run Rspec tests"
|
68
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
60
69
|
t.ruby_opts = ['-I', "lib"]
|
70
|
+
t.rspec_opts = %w{-f d}
|
61
71
|
# t.pattern = FileList['spec/**/*_spec.rb']
|
62
72
|
# t.rcov = true
|
63
73
|
# t.rcov_opts = ['--exclude', 'spec,/usr/lib/ruby' ]
|
64
74
|
end
|
75
|
+
|
76
|
+
desc "Run RSpec tests and produce coverage files (results viewable in coverage/index.html)"
|
77
|
+
RSpec::Core::RakeTask.new(:coverage) do |spec|
|
78
|
+
if RUBY_VERSION < '1.9'
|
79
|
+
spec.rcov_opts = [
|
80
|
+
'--exclude', 'spec',
|
81
|
+
'--exclude', 'gem/*'
|
82
|
+
]
|
83
|
+
spec.rcov = true
|
84
|
+
else
|
85
|
+
spec.rspec_opts = ['--require', 'simplecov_helper']
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
task :cov => :coverage
|
90
|
+
task :rcov => :coverage
|
91
|
+
task :simplecov => :coverage
|
data/TODO
ADDED
@@ -0,0 +1,308 @@
|
|
1
|
+
ActiveFacts ToDo list
|
2
|
+
|
3
|
+
Metamodel
|
4
|
+
ALWAYS Integrate Metamodel changes through lib/activefacts/vocabulary/metamodel.rb
|
5
|
+
SOON Add Terms for Object Types
|
6
|
+
using Words? (which include adjectives/rolenames)
|
7
|
+
Notes (Extend context notes)
|
8
|
+
comments in CQL?
|
9
|
+
Derivation notes?
|
10
|
+
HelpText?
|
11
|
+
FBM Standards Metamodel
|
12
|
+
Migrate towards standard terminology
|
13
|
+
Make ORM model emit good CQL
|
14
|
+
Use UUIDs
|
15
|
+
Renamed from ("Person (was called User) ...")
|
16
|
+
Multiple revisions?
|
17
|
+
Extensions (new vocabularies?) for Metamodel
|
18
|
+
security
|
19
|
+
processes
|
20
|
+
discussion/conversation
|
21
|
+
Implement abstract supertypes?
|
22
|
+
Allow Object naming "Paris means City 'Paris'"
|
23
|
+
Use subtype extension in Metamodel (based on abstract SBVR supertypes as shown?)
|
24
|
+
Meaning
|
25
|
+
Concept
|
26
|
+
NounConcept
|
27
|
+
ObjectType
|
28
|
+
RolePlaying
|
29
|
+
FactType
|
30
|
+
Fact
|
31
|
+
Value
|
32
|
+
Query
|
33
|
+
Lexeme (language/locale sensitive text)
|
34
|
+
Term
|
35
|
+
Reading (template text, adjectives)
|
36
|
+
Value (literal)
|
37
|
+
Or just have per-locale syntax parser/generator to/from canonical form?
|
38
|
+
Role names
|
39
|
+
need to attach to RoleRefs instead of Roles
|
40
|
+
Refactor RoleRef and RoleSequence so RoleSequence isn't re-used out of context
|
41
|
+
Index/access-path/ordering pragmas
|
42
|
+
Temporal literals (expressions using current time)
|
43
|
+
Temporal: e.g. Date/Time {{/not} {after/before}} Date/Time
|
44
|
+
SOON Refactor Derived Fact Types (Queries) using new terminology
|
45
|
+
|
46
|
+
CQL
|
47
|
+
Object Types
|
48
|
+
ValueTypes
|
49
|
+
Change so Data Types are not inherited
|
50
|
+
Implement named parameters
|
51
|
+
Autogenerated
|
52
|
+
On assert (UUID)
|
53
|
+
On save (ID, Timestamp, etc)
|
54
|
+
Partial auto-counters (Role, *Ordinal*)
|
55
|
+
Implement base VTs
|
56
|
+
SOON "vt is written;" syntax
|
57
|
+
Entity Types
|
58
|
+
SOON "Et is identified;" forward-reference syntax
|
59
|
+
Allow other possessive pronouns "Ship is identified by her Name"
|
60
|
+
Allow shorthand for multi-part identification
|
61
|
+
"Person is identified by his given-Name and family-Name;"
|
62
|
+
Subtypes
|
63
|
+
Support Role subtypes as distinct (subtype migration allowed)
|
64
|
+
Subtyping fact type role names?
|
65
|
+
Object Names
|
66
|
+
"Paris means City 'Paris'"
|
67
|
+
|
68
|
+
Joins
|
69
|
+
SOON Anti-joins (no, none, negation, "it is not the case that", etc)
|
70
|
+
SOON Double-contraction "Person who came to Party and was not invited to"
|
71
|
+
SOON Outer joins ("maybe")
|
72
|
+
SOON Compile Value join nodes
|
73
|
+
STARTED, DIFFICULT Implement comparison operators as derived fact types (<, etc)
|
74
|
+
Automatically detect type conversion joins
|
75
|
+
|
76
|
+
Queries
|
77
|
+
Expression clauses
|
78
|
+
Redo grammar as normal clause (A < B -> A rel B)
|
79
|
+
User-defined expression operators/clauses?
|
80
|
+
Fact Type Negation (A rel no B, no A rel B)
|
81
|
+
"returning" clause
|
82
|
+
Invoke queries using defined role names:
|
83
|
+
Company has young Person (as Director) where ...
|
84
|
+
(invoke as "Company has young Director")
|
85
|
+
Temporal terms and phrases
|
86
|
+
"now" "4 year ago", "3 minutes from now"
|
87
|
+
Temporal ValueType to act as a Universal fact type over the domain
|
88
|
+
e.g. Time.hour -> all possible hours
|
89
|
+
Figure out what base constraints propagate to the result set
|
90
|
+
Allow "which" to project roles from a query "which Person gatecrashed Party?"
|
91
|
+
Value range restrictions (in {1,2,4}) instead of (restricted to {...})
|
92
|
+
|
93
|
+
Linguistic aspects
|
94
|
+
UTF-8 Support
|
95
|
+
Other languages
|
96
|
+
Define syntax for and handle Gender
|
97
|
+
French
|
98
|
+
Spanish
|
99
|
+
Use filename to select (Bar.fr.cql or Bar.cql.fr?)
|
100
|
+
Use metamodel predicates instead of pragmas
|
101
|
+
e.g. for "Object type is independent", say "Object Type 'Foo' is independent";
|
102
|
+
How to handle Fact Type names in the above syntax? Objectify? But need ring constraint roles.
|
103
|
+
Vocabulary name is implicit here...
|
104
|
+
SOON Allow more than one Business Context Note per item
|
105
|
+
Fact type binding
|
106
|
+
Use non-local role names in fact type matching?
|
107
|
+
Check that subscripts are being tested properly
|
108
|
+
Implement some/that binding
|
109
|
+
subscripts not necessary where "that" is unambiguous.
|
110
|
+
which/that: "which Person likes that Person?"
|
111
|
+
Double-hyphen for hyphenated adjectives
|
112
|
+
|
113
|
+
Constraints
|
114
|
+
SOON Implement "maybe" to make min-frequency non-mandatory
|
115
|
+
Value Literal syntax constraints
|
116
|
+
Regexp: "vt is written to match /xyz/"
|
117
|
+
Regexp for role values
|
118
|
+
subtype of Value Constraint
|
119
|
+
PEG Grammars for literals? (extend CQL grammar)
|
120
|
+
Ring constraints
|
121
|
+
how to handle ambiguous rings, e.g. in ternaries?
|
122
|
+
how to handle multiple rings in one FT?
|
123
|
+
Think about syntax to allow this
|
124
|
+
Populate Ring Types in metamodel (five unaries?)
|
125
|
+
Constraint names (esp Presence Constraints, they become index names)
|
126
|
+
Temporal Modeling ([at most] one at a time)
|
127
|
+
single table mapping
|
128
|
+
two tables mappings (current/history)
|
129
|
+
Add Exclusion constraint syntax using negative clause:
|
130
|
+
Person is ceo if and only if no Manager manages (that?) Person
|
131
|
+
Similar case exists for subset constraint?
|
132
|
+
A rel B only if no B rel C - think through
|
133
|
+
Delay creation of default identifying constraints for objectified fact types
|
134
|
+
Perhaps before relational/object mapping?
|
135
|
+
Or don't create them at all - handle missing PI for OFTs instead
|
136
|
+
Asserted instances
|
137
|
+
"including {'foo', 'bar', ...}" akin to "restricted to"...
|
138
|
+
|
139
|
+
Importing vocabularies
|
140
|
+
Distinguish "import" from "use"?
|
141
|
+
Bind to imported ValueTypes (and other object types?)
|
142
|
+
Base vocabularies for SQL
|
143
|
+
Multiple SQL base vocabs, using db pref to choose between.
|
144
|
+
|
145
|
+
CQL Verbaliser
|
146
|
+
SOON Detect new fact types that would be interpreted as an existing (only adjectives differ), and use single reading (before double-reading) e.g. other-Role of RingConstraint
|
147
|
+
Implement some/that binding
|
148
|
+
use some/that where "that" is unambiguous
|
149
|
+
Don't emit some/that until binding will use it properly
|
150
|
+
Instance data verbalisation
|
151
|
+
Emit objectification joins
|
152
|
+
Contractions (use Verbaliser!)
|
153
|
+
Emit example fact from ORM2009 presentation
|
154
|
+
Output clustering
|
155
|
+
Emit Value Types just before first use
|
156
|
+
Emit Constraints as soon as possible
|
157
|
+
Choose "focus" items with most 1st and 2nd generation dependencies, and do all precursors/followers before choosing another
|
158
|
+
Left-contraction of joins "Xyz is ... and is ...;"
|
159
|
+
|
160
|
+
Units
|
161
|
+
SOON Store sample data with specified unit
|
162
|
+
Handle storing numeric Instance values (noted to be in the lexical form; but strings aren't!)
|
163
|
+
SOON Save Units on ValueTypes
|
164
|
+
Generate conversion formula to fundamental types
|
165
|
+
|
166
|
+
CQL Shell
|
167
|
+
Save definitions, including instances
|
168
|
+
/sql; generate the SQL for this vocabulary
|
169
|
+
/valid; check all metamodel constraints over the vocabulary, and/or vocabulary constraints over the population
|
170
|
+
Queries
|
171
|
+
/population {open, check, create} database_name
|
172
|
+
/ruby
|
173
|
+
/cql
|
174
|
+
|
175
|
+
NORMA reader
|
176
|
+
NORMA Joins
|
177
|
+
Detect and store implicit joins in presence constraints (if needed???)
|
178
|
+
Convert all NORMA Join paths
|
179
|
+
NORMA input: Warn when preferred reading role order doesn't match the preferred identifier for objectified FTs
|
180
|
+
Import instance data for objectified fact types
|
181
|
+
Double-hyphen for hyphenated adjectives
|
182
|
+
|
183
|
+
Generators
|
184
|
+
Ruby generator
|
185
|
+
Emit a module method for each example population
|
186
|
+
|
187
|
+
Relational Composition
|
188
|
+
Subtype Mapping
|
189
|
+
extension (subtype in separate table)
|
190
|
+
partition (separate and include all supertype roles)
|
191
|
+
Make sure all test scenarios are covered
|
192
|
+
Transforms
|
193
|
+
Rails ID injection
|
194
|
+
Subtype discriminator injection where no mandatory role on subtype
|
195
|
+
Don't introduce additional discriminator for sub-sub-type
|
196
|
+
Detect non-exclusive subtypes and discriminate combinations
|
197
|
+
Column name generation
|
198
|
+
Provide alternative generation pattern(s) (snake-case)
|
199
|
+
Duplicate column names (detect, handle)
|
200
|
+
SQL Generation
|
201
|
+
Auto-generated column types
|
202
|
+
IDentity fields
|
203
|
+
GUIDs
|
204
|
+
partial auto-counters (Ordinal)
|
205
|
+
Timestamps
|
206
|
+
other auto-counters?
|
207
|
+
Foreign Key fields
|
208
|
+
Index both ends
|
209
|
+
Determine cascading based on mandatory-ness
|
210
|
+
Emit triggers where PK is in a subtype (and view was generated)
|
211
|
+
Existing database/vocabulary
|
212
|
+
Minimal impact vs refactor and migrate
|
213
|
+
|
214
|
+
Runtime API
|
215
|
+
Autogenerated Data Types
|
216
|
+
GUID, Ordinal
|
217
|
+
Entity
|
218
|
+
Save identifying roles as Role objects not symbols
|
219
|
+
SOON Propagate retract() properly (replace delete?)
|
220
|
+
Subtype migration
|
221
|
+
Replace instance by instance of different class, de-/re-assign all roles?
|
222
|
+
Re-use same role proxy/ies?
|
223
|
+
Role value array proxy class
|
224
|
+
Handle sorting by residual fields in counterpart's key
|
225
|
+
Detect & preserve adds/deletes
|
226
|
+
Correctly handle values across multiple constellations or in no constellation
|
227
|
+
Verbalisation
|
228
|
+
SOON Add readings to API
|
229
|
+
Redo all verbalisation to use readings
|
230
|
+
Use existing verbalise for to_s
|
231
|
+
Ensure that all objects and classes verbalise and to_s
|
232
|
+
SOON verbalise Role Value Array
|
233
|
+
verbalise takes optional "verbalisation context" object
|
234
|
+
Which objects have already been verbalised
|
235
|
+
What role names and/or subscripts have been assigned
|
236
|
+
Possible to implement as a single-pass process?
|
237
|
+
Queries
|
238
|
+
Query DSL/API in Ruby?
|
239
|
+
CQL Query conversion to SQL (via Ruby?)
|
240
|
+
Constellation boundaries
|
241
|
+
Record unpopulated roles and object types during query execution (nil != mu)
|
242
|
+
Hard vs soft boundary (Auto-fetch vs exception)
|
243
|
+
RDBMS Platform Support
|
244
|
+
DataObjects (SQL Server, MySQL, PostgreSQL, Oracle, DB2)
|
245
|
+
Enumerate tables instead of needing "table" keyword
|
246
|
+
Log changes to allow update
|
247
|
+
|
248
|
+
Database reverse engineering
|
249
|
+
Read Linda Bird's PhD thesis
|
250
|
+
Extract raw schema info
|
251
|
+
Tables
|
252
|
+
Columns & types
|
253
|
+
Null constraints
|
254
|
+
Unique & primary keys
|
255
|
+
Foreign keys
|
256
|
+
Check constraints
|
257
|
+
Naming Heuristics
|
258
|
+
Rails
|
259
|
+
Intuition (FK naming)
|
260
|
+
Load Rails models
|
261
|
+
Detect pluralisation
|
262
|
+
intuit common reference modes (e.g. thing_ID)
|
263
|
+
Examine data for likely FKs
|
264
|
+
count, min, max, median, distinct, count(NULL)
|
265
|
+
Check non-violation of possible FKs:
|
266
|
+
select count(*) where not exists ...
|
267
|
+
Decompose to elementary form
|
268
|
+
Schema transform by manual selection (GUI?)
|
269
|
+
Deabsorb (incl to use existing type)
|
270
|
+
Alias name
|
271
|
+
Project subclass using discriminator
|
272
|
+
... other transforms
|
273
|
+
|
274
|
+
Test stubs/mocks
|
275
|
+
Quality/usage metrics
|
276
|
+
Mock API
|
277
|
+
Mock data
|
278
|
+
Use sample population as test data
|
279
|
+
incorporate Faker, Machinist, etc
|
280
|
+
|
281
|
+
Packaging and documentation
|
282
|
+
Split into multiple gems?
|
283
|
+
|
284
|
+
Example models
|
285
|
+
Convert microformat RDF: http://microformats.org/about, http://www.data-vocabulary.org/
|
286
|
+
|
287
|
+
APRIMO
|
288
|
+
Overall design
|
289
|
+
Subscription, list/search models, friends
|
290
|
+
Diagram view
|
291
|
+
CQL view
|
292
|
+
Object type browser
|
293
|
+
Object Types
|
294
|
+
Fact Types
|
295
|
+
Constraints
|
296
|
+
Instance data
|
297
|
+
Query builder
|
298
|
+
AJAX
|
299
|
+
Design JSON API
|
300
|
+
Server
|
301
|
+
Stand-alone???
|
302
|
+
Metamodel Diagrams
|
303
|
+
Convert from metamodel to JSON
|
304
|
+
Database
|
305
|
+
Derived Fact Types
|
306
|
+
Constellation declarations
|
307
|
+
Process models
|
308
|
+
Units
|