activefacts 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +83 -0
  3. data/README.rdoc +81 -0
  4. data/Rakefile +41 -0
  5. data/bin/afgen +46 -0
  6. data/bin/cql +52 -0
  7. data/examples/CQL/Address.cql +46 -0
  8. data/examples/CQL/Blog.cql +54 -0
  9. data/examples/CQL/CompanyDirectorEmployee.cql +51 -0
  10. data/examples/CQL/Death.cql +16 -0
  11. data/examples/CQL/Genealogy.cql +95 -0
  12. data/examples/CQL/Marriage.cql +18 -0
  13. data/examples/CQL/Metamodel.cql +238 -0
  14. data/examples/CQL/MultiInheritance.cql +19 -0
  15. data/examples/CQL/OilSupply.cql +47 -0
  16. data/examples/CQL/Orienteering.cql +108 -0
  17. data/examples/CQL/PersonPlaysGame.cql +17 -0
  18. data/examples/CQL/SchoolActivities.cql +31 -0
  19. data/examples/CQL/SimplestUnary.cql +12 -0
  20. data/examples/CQL/SubtypePI.cql +32 -0
  21. data/examples/CQL/Warehousing.cql +99 -0
  22. data/examples/CQL/WindowInRoomInBldg.cql +22 -0
  23. data/lib/activefacts.rb +10 -0
  24. data/lib/activefacts/api.rb +25 -0
  25. data/lib/activefacts/api/concept.rb +384 -0
  26. data/lib/activefacts/api/constellation.rb +106 -0
  27. data/lib/activefacts/api/entity.rb +239 -0
  28. data/lib/activefacts/api/instance.rb +54 -0
  29. data/lib/activefacts/api/numeric.rb +158 -0
  30. data/lib/activefacts/api/role.rb +94 -0
  31. data/lib/activefacts/api/standard_types.rb +67 -0
  32. data/lib/activefacts/api/support.rb +59 -0
  33. data/lib/activefacts/api/value.rb +122 -0
  34. data/lib/activefacts/api/vocabulary.rb +120 -0
  35. data/lib/activefacts/cql.rb +31 -0
  36. data/lib/activefacts/cql/CQLParser.treetop +104 -0
  37. data/lib/activefacts/cql/Concepts.treetop +112 -0
  38. data/lib/activefacts/cql/DataTypes.treetop +66 -0
  39. data/lib/activefacts/cql/Expressions.treetop +113 -0
  40. data/lib/activefacts/cql/FactTypes.treetop +185 -0
  41. data/lib/activefacts/cql/Language/English.treetop +92 -0
  42. data/lib/activefacts/cql/LexicalRules.treetop +169 -0
  43. data/lib/activefacts/cql/Rakefile +6 -0
  44. data/lib/activefacts/cql/parser.rb +88 -0
  45. data/lib/activefacts/generate/absorption.rb +87 -0
  46. data/lib/activefacts/generate/cql.rb +441 -0
  47. data/lib/activefacts/generate/cql/html.rb +397 -0
  48. data/lib/activefacts/generate/null.rb +19 -0
  49. data/lib/activefacts/generate/ordered.rb +557 -0
  50. data/lib/activefacts/generate/ruby.rb +326 -0
  51. data/lib/activefacts/generate/sql/server.rb +164 -0
  52. data/lib/activefacts/generate/text.rb +21 -0
  53. data/lib/activefacts/input/cql.rb +1268 -0
  54. data/lib/activefacts/input/orm.rb +926 -0
  55. data/lib/activefacts/persistence.rb +1 -0
  56. data/lib/activefacts/persistence/composition.rb +653 -0
  57. data/lib/activefacts/support.rb +51 -0
  58. data/lib/activefacts/version.rb +3 -0
  59. data/lib/activefacts/vocabulary.rb +6 -0
  60. data/lib/activefacts/vocabulary/extensions.rb +343 -0
  61. data/lib/activefacts/vocabulary/metamodel.rb +303 -0
  62. data/script/txt2html +71 -0
  63. data/spec/absorption_spec.rb +95 -0
  64. data/spec/api/autocounter.rb +82 -0
  65. data/spec/api/constellation.rb +130 -0
  66. data/spec/api/entity_type.rb +101 -0
  67. data/spec/api/instance.rb +428 -0
  68. data/spec/api/roles.rb +122 -0
  69. data/spec/api/value_type.rb +112 -0
  70. data/spec/api_spec.rb +14 -0
  71. data/spec/cql_cql_spec.rb +58 -0
  72. data/spec/cql_parse_spec.rb +31 -0
  73. data/spec/cql_ruby_spec.rb +60 -0
  74. data/spec/cql_sql_spec.rb +54 -0
  75. data/spec/cql_symbol_tables_spec.rb +259 -0
  76. data/spec/cql_unit_spec.rb +336 -0
  77. data/spec/cqldump_spec.rb +169 -0
  78. data/spec/norma_cql_spec.rb +48 -0
  79. data/spec/norma_ruby_spec.rb +50 -0
  80. data/spec/norma_sql_spec.rb +45 -0
  81. data/spec/norma_tables_spec.rb +94 -0
  82. data/spec/spec.opts +1 -0
  83. data/spec/spec_helper.rb +10 -0
  84. metadata +173 -0
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.6.0 2008-11-27
2
+
3
+ * 1 major enhancement:
4
+ * Initial public release
data/Manifest.txt ADDED
@@ -0,0 +1,83 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/afgen
6
+ bin/cql
7
+ examples/CQL/Address.cql
8
+ examples/CQL/Blog.cql
9
+ examples/CQL/CompanyDirectorEmployee.cql
10
+ examples/CQL/Death.cql
11
+ examples/CQL/Genealogy.cql
12
+ examples/CQL/Marriage.cql
13
+ examples/CQL/Metamodel.cql
14
+ examples/CQL/MultiInheritance.cql
15
+ examples/CQL/OilSupply.cql
16
+ examples/CQL/Orienteering.cql
17
+ examples/CQL/PersonPlaysGame.cql
18
+ examples/CQL/SchoolActivities.cql
19
+ examples/CQL/SimplestUnary.cql
20
+ examples/CQL/SubtypePI.cql
21
+ examples/CQL/Warehousing.cql
22
+ examples/CQL/WindowInRoomInBldg.cql
23
+ lib/activefacts.rb
24
+ lib/activefacts/api.rb
25
+ lib/activefacts/api/concept.rb
26
+ lib/activefacts/api/constellation.rb
27
+ lib/activefacts/api/entity.rb
28
+ lib/activefacts/api/instance.rb
29
+ lib/activefacts/api/numeric.rb
30
+ lib/activefacts/api/role.rb
31
+ lib/activefacts/api/standard_types.rb
32
+ lib/activefacts/api/support.rb
33
+ lib/activefacts/api/value.rb
34
+ lib/activefacts/api/vocabulary.rb
35
+ lib/activefacts/cql.rb
36
+ lib/activefacts/cql/Rakefile
37
+ lib/activefacts/cql/CQLParser.treetop
38
+ lib/activefacts/cql/Concepts.treetop
39
+ lib/activefacts/cql/DataTypes.treetop
40
+ lib/activefacts/cql/Expressions.treetop
41
+ lib/activefacts/cql/FactTypes.treetop
42
+ lib/activefacts/cql/Language/English.treetop
43
+ lib/activefacts/cql/LexicalRules.treetop
44
+ lib/activefacts/cql/parser.rb
45
+ lib/activefacts/generate/absorption.rb
46
+ lib/activefacts/generate/cql.rb
47
+ lib/activefacts/generate/cql/html.rb
48
+ lib/activefacts/generate/null.rb
49
+ lib/activefacts/generate/ordered.rb
50
+ lib/activefacts/generate/ruby.rb
51
+ lib/activefacts/generate/sql/server.rb
52
+ lib/activefacts/generate/text.rb
53
+ lib/activefacts/input/cql.rb
54
+ lib/activefacts/input/orm.rb
55
+ lib/activefacts/persistence.rb
56
+ lib/activefacts/persistence/composition.rb
57
+ lib/activefacts/support.rb
58
+ lib/activefacts/version.rb
59
+ lib/activefacts/vocabulary.rb
60
+ lib/activefacts/vocabulary/extensions.rb
61
+ lib/activefacts/vocabulary/metamodel.rb
62
+ script/txt2html
63
+ spec/absorption_spec.rb
64
+ spec/api/autocounter.rb
65
+ spec/api/constellation.rb
66
+ spec/api/entity_type.rb
67
+ spec/api/instance.rb
68
+ spec/api/roles.rb
69
+ spec/api/value_type.rb
70
+ spec/api_spec.rb
71
+ spec/cql_cql_spec.rb
72
+ spec/cql_parse_spec.rb
73
+ spec/cql_ruby_spec.rb
74
+ spec/cql_sql_spec.rb
75
+ spec/cql_symbol_tables_spec.rb
76
+ spec/cql_unit_spec.rb
77
+ spec/cqldump_spec.rb
78
+ spec/norma_cql_spec.rb
79
+ spec/norma_ruby_spec.rb
80
+ spec/norma_sql_spec.rb
81
+ spec/norma_tables_spec.rb
82
+ spec/spec.opts
83
+ spec/spec_helper.rb
data/README.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ = activefacts
2
+
3
+ * http://dataconstellation.com/ActiveFacts/
4
+
5
+ == DESCRIPTION:
6
+
7
+ ActiveFacts is a semantic modeling toolkit, comprising an implementation
8
+ of the Constellation Query Language, the Constellation API, and code
9
+ generators that receive CQL or ORM (Object Role Modeling files, from
10
+ NORMA) to emit CQL, Ruby and SQL.
11
+
12
+ Semantic modeling is a refinement of fact-based modeling techniques
13
+ that draw on natural language verbalisation and formal logic. Fact
14
+ based modeling is essentially the same as relational modeling in the
15
+ sixth normal form. The tools provided here automatically condense
16
+ that to third normal form for efficient storage. They also generate
17
+ object models as a Ruby module which has an effective mapping to
18
+ both the original semantic model and to the generated SQL.
19
+
20
+ The result is a formal language that reads like plain English, and
21
+ allows creation of relational and object models that are guaranteed
22
+ equivalent, and much more stable in the face of schema evolution than
23
+ SQL is.
24
+
25
+ == FEATURES/PROBLEMS:
26
+
27
+ * Queries are parsed, but not yet generated to SQL. DDL is complete.
28
+
29
+ * SQL generation handles some one-to-one relationships wrongly,
30
+ including subtypes when independent of the supertype's table.
31
+
32
+ * The Constellation API lacks SQL persistence (but is already useful;
33
+ the CQL compiler uses the generated Ruby code extensively)
34
+
35
+ * Re-invoking a fact type to add new readings doesn't work
36
+
37
+ * Some types of external constraints (when adjectives mis-match)
38
+ don't yet pass the CQL parser's semantic analysis.
39
+
40
+ * Validation of semantic models (and many other areas) is incomplete
41
+
42
+ * There's no interactive CQL interpreter yet; the cql command merely
43
+ shows the parse tree.
44
+
45
+ == SYNOPSIS:
46
+
47
+ afgen --sql/server myfile.cql
48
+ afgen --ruby myfile.cql
49
+ afgen --cql myfile.orm
50
+
51
+ == REQUIREMENTS:
52
+
53
+ * Treetop parser generator
54
+ * Optional: NORMA, see <http://www.ormfoundation.org/files/>
55
+ (needs Visual Studio pro edition), if you want to use ORM
56
+
57
+ == INSTALL:
58
+
59
+ * sudo gem install activefacts
60
+
61
+ == LICENSE:
62
+
63
+ Copyright (c) 2008 Clifford Heath.
64
+
65
+ This software is provided 'as-is', without any express or implied warranty.
66
+ In no event will the authors be held liable for any damages arising from the
67
+ use of this software.
68
+
69
+ Permission is granted to anyone to use this software for any purpose,
70
+ including commercial applications, and to alter it and redistribute it
71
+ freely, subject to the following restrictions:
72
+
73
+ 1. The origin of this software must not be misrepresented; you must not
74
+ claim that you wrote the original software. If you use this software
75
+ in a product, an acknowledgment in the product documentation would be
76
+ appreciated but is not required.
77
+
78
+ 2. Altered source versions must be plainly marked as such, and must not be
79
+ misrepresented as being the original software.
80
+
81
+ 3. This notice may not be removed or altered from any source distribution.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen spec spec/rake/spectask].each { |f| require f }
2
+
3
+ require File.dirname(__FILE__) + '/lib/activefacts'
4
+
5
+ # Generate all the Rake tasks
6
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
7
+ $hoe = Hoe.new('activefacts', ActiveFacts::VERSION) do |p|
8
+ p.developer('Clifford Heath', 'cjh@dataconstellation.org')
9
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
+ p.post_install_message = 'For more information on ActiveFacts, see http://dataconstellation.com/ActiveFacts'
11
+ p.rubyforge_name = "cjheath@rubyforge.org"
12
+ p.extra_deps = [
13
+ ['treetop','>= 1.2.4'],
14
+ ]
15
+ p.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ]
18
+ p.spec_extras[:extensions] = 'lib/activefacts/cql/Rakefile'
19
+ p.spec_extras[:rdoc_options] = [
20
+ "-x", "lib/activefacts/cql/.*.rb",
21
+ "-x", "lib/activefacts/vocabulary/.*.rb",
22
+ "-x", "lib/activefacts/persistence/.*.rb",
23
+ ]
24
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
25
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
26
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
27
+ p.rsync_args = '-av --delete --ignore-errors'
28
+ end
29
+
30
+ require 'newgem/tasks' # load /tasks/*.rake
31
+ Dir['tasks/**/*.rake'].each { |t| load t }
32
+
33
+ # TODO - want other tests/tasks run by default? Add them to the list
34
+ # task :default => [:spec, :features]
35
+
36
+ Spec::Rake::SpecTask.new(:spec) do |t|
37
+ t.ruby_opts = ['-I', "lib"]
38
+ t.spec_files = FileList['spec/**/*_spec.rb']
39
+ # t.rcov = true
40
+ # t.rcov_opts = ['--exclude', 'spec,/usr/lib/ruby' ]
41
+ end
data/bin/afgen ADDED
@@ -0,0 +1,46 @@
1
+ #! env ruby
2
+ #
3
+ # Read an ORM2 Vocabulary from a NORMA, CQL or other file
4
+ #
5
+ # Copyright (c) 2007 Clifford Heath. Read the LICENSE file.
6
+ #
7
+ $:.unshift File.dirname(File.expand_path(__FILE__))+"/../lib"
8
+
9
+ require 'rubygems'
10
+ require 'ruby-debug'
11
+ require 'activefacts'
12
+ require 'activefacts/vocabulary'
13
+
14
+ arg = ARGV.shift
15
+
16
+ # Load the required generator, or the default "text" generator:
17
+ generator = "text"
18
+ if arg =~ /^--([^=]*)(?:=(.*))?/
19
+ generator = $1
20
+ generator_options = ($2||"").split(/,/)
21
+ arg = ARGV.shift
22
+ end
23
+ output_handler = "activefacts/generate/#{generator.downcase}"
24
+ require output_handler
25
+ output_class = generator.upcase.gsub(%r{[/\\]+},'::')
26
+ output_klass = eval("ActiveFacts::Generate::#{output_class}")
27
+ raise "Expected #{output_handler} to define #{output_class}" unless output_klass
28
+
29
+ # Load the file type input method
30
+ extension = arg.sub(/\A.*\./,'').downcase
31
+ input_handler = "activefacts/input/#{extension}"
32
+ require input_handler
33
+ input_class = extension.upcase
34
+ input_klass = ActiveFacts::Input.const_get(input_class.to_sym)
35
+ raise "Expected #{input_handler} to define #{input_class}" unless input_klass
36
+
37
+ # Read the input file:
38
+ begin
39
+ vocabulary = input_klass.readfile(arg)
40
+ rescue => e
41
+ puts "#{e.message}"
42
+ puts "#{e}:\n\t#{e.backtrace*"\n\t"}" if debug
43
+ end
44
+
45
+ # Generate the output:
46
+ output_klass.new(vocabulary, *generator_options).generate if vocabulary
data/bin/cql ADDED
@@ -0,0 +1,52 @@
1
+ #! env ruby
2
+ #
3
+ # Interactive CQL command-line.
4
+ # Copyright (c) 2007 Clifford Heath. Read the LICENSE file.
5
+ #
6
+
7
+ require 'activefacts'
8
+ require 'activefacts/cql/parser'
9
+ require 'readline'
10
+
11
+ puts "This is a stub for the CQL interactive commandline. At the moment it only parses CQL and shows the parse trees."
12
+
13
+ parser = ActiveFacts::CQLParser.new
14
+ parser.root = :definition
15
+ statement = nil
16
+ while line = Readline::readline(statement ? "CQL+ " : "CQL? ", [])
17
+ statement = statement ? statement + "\n"+line : line
18
+ if line =~ %r{\A/}
19
+ # meta-commands start with /
20
+ case (words = line.split).shift
21
+ when "/root"
22
+ parser.root = words[0] && words[0].to_sym || :definition
23
+ puts "ok"
24
+ else
25
+ puts "Unknown metacommand #{line}, did you mean /root <rule>?"
26
+ end
27
+ statement = nil
28
+ elsif parser.root != :definition or
29
+ line.gsub(/(['"])([^\1\\]|\\.)*\1/,'') =~ /;/
30
+ # After stripping string literals the line contains a ';', it's the last line of the command:
31
+ begin
32
+ result = parser.parse(statement)
33
+ if result
34
+ begin
35
+ p result.value
36
+ rescue => e
37
+ puts e.to_s+":"
38
+ p result # In case the root is changed and there's no value()
39
+ end
40
+ #p parser.definition(result)
41
+ else
42
+ p parser.failure_reason
43
+ end
44
+ rescue => e
45
+ puts e
46
+ puts "\t"+e.backtrace*"\n\t"
47
+ end
48
+ statement = nil
49
+ end
50
+ end
51
+ puts
52
+
@@ -0,0 +1,46 @@
1
+ vocabulary Address;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ City is defined as VariableLengthText(64);
7
+ CompanyName is defined as VariableLengthText();
8
+ FamilyName is defined as VariableLengthText(20);
9
+ GivenNames is defined as VariableLengthText(20);
10
+ Number is defined as VariableLengthText(12);
11
+ Postcode is defined as VariableLengthText();
12
+ StreetLine is defined as VariableLengthText(64);
13
+
14
+ /*
15
+ * Entity Types
16
+ */
17
+ Company is identified by its Name;
18
+
19
+ Family is identified by its Name;
20
+
21
+ Person is identified by Family and GivenNames where
22
+ Person is of one Family,
23
+ Family includes Person,
24
+ Person has one GivenNames;
25
+
26
+ Street is identified by first-StreetLine and second-StreetLine and third-StreetLine where
27
+ Street includes one first-StreetLine,
28
+ Street includes at most one second-StreetLine,
29
+ Street includes at most one third-StreetLine;
30
+
31
+ Address is identified by street-Number and Street and City and Postcode where
32
+ Address is at at most one street-Number,
33
+ Address is at one Street,
34
+ Address is in one City,
35
+ Address is in at most one Postcode,
36
+ Postcode is of Address;
37
+ Company has head office at at most one Address;
38
+ Person lives at at most one Address;
39
+
40
+ /*
41
+ * Constraints:
42
+ */
43
+ Street includes third-StreetLine
44
+ only if Street includes second-StreetLine;
45
+ Street includes second-StreetLine
46
+ only if Street includes first-StreetLine;
@@ -0,0 +1,54 @@
1
+ vocabulary Blog;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ AuthorId is defined as AutoCounter();
7
+ CommentId is defined as AutoCounter();
8
+ Name is defined as VariableLengthText(64);
9
+ Ordinal is defined as UnsignedInteger(32);
10
+ PostId is defined as AutoCounter();
11
+ Style is defined as VariableLengthText(20);
12
+ Text is defined as LargeLengthText();
13
+ TopicId is defined as AutoCounter();
14
+
15
+ /*
16
+ * Entity Types
17
+ */
18
+ Author is identified by its Id;
19
+ author-Name is of at most one Author,
20
+ Author is called one Name;
21
+
22
+ Comment is identified by its Id;
23
+ Author wrote Comment,
24
+ Comment was written by one Author;
25
+
26
+ Content is identified by Style and Text where
27
+ Content is of at most one Style,
28
+ Content has one Text,
29
+ Text is of Content;
30
+ Content provides text of at most one Comment,
31
+ Comment consists of one text-Content;
32
+
33
+ Post is identified by its Id;
34
+ Post was written by one Author;
35
+ Paragraph is where
36
+ Post includes Ordinal paragraph;
37
+ Content is of at most one Paragraph,
38
+ Paragraph contains one Content;
39
+ Paragraph has Comment,
40
+ Comment is on one Paragraph;
41
+
42
+ Topic is identified by its Id;
43
+ Post belongs to one Topic,
44
+ Topic contains Post;
45
+ Topic belongs to at most one parent-Topic [acyclic];
46
+ Topic is called one topic-Name,
47
+ Name is of at most one Topic;
48
+
49
+ /*
50
+ * Constraints:
51
+ */
52
+ for each Content exactly one of these holds:
53
+ Content provides text of Comment,
54
+ Content is of Paragraph;
@@ -0,0 +1,51 @@
1
+ vocabulary CompanyDirector;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ CompanyName is defined as VariableLengthText(48);
7
+ EmployeeNr is defined as SignedInteger(32);
8
+ Name is defined as VariableLengthText(48);
9
+
10
+ /*
11
+ * Entity Types
12
+ */
13
+ Company is identified by its Name where
14
+ Company is called CompanyName;
15
+ Company is listed;
16
+
17
+ Meeting is identified by Date and Meeting is board meeting and Company where
18
+ Meeting is held on one Date,
19
+ Meeting is board meeting,
20
+ Company held Meeting,
21
+ Meeting is held by one Company;
22
+
23
+ Person is identified by given-Name and family-Name where
24
+ Person has one given-Name,
25
+ given-Name is of Person,
26
+ family-Name is of Person,
27
+ Person is called at most one family-Name;
28
+ Person was born on at most one birth-Date;
29
+ Attendance is where
30
+ Person (as Attendee) attended Meeting,
31
+ Meeting was attended by Attendee;
32
+ Directorship is where
33
+ Person (as Director) directs Company,
34
+ Company is directed by at least one Director;
35
+ Directorship began on one appointment-Date;
36
+
37
+ Employee is a kind of Person identified by its Nr;
38
+ Employee works at one Company,
39
+ Company employs Employee;
40
+
41
+ Manager is a kind of Employee;
42
+ Employee is supervised by at most one Manager [acyclic],
43
+ Manager supervises Employee;
44
+ Manager is ceo;
45
+
46
+ /*
47
+ * Constraints:
48
+ */
49
+ for each Employee exactly one of these holds:
50
+ that Employee is ceo,
51
+ that Employee is supervised by some Manager;