activefacts 0.8.9 → 0.8.10
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/.gemtest +0 -0
- data/Manifest.txt +28 -33
- data/Rakefile +11 -12
- data/bin/cql +90 -46
- data/examples/CQL/Blog.cql +2 -1
- data/examples/CQL/CompanyDirectorEmployee.cql +2 -2
- data/examples/CQL/Death.cql +1 -1
- data/examples/CQL/Diplomacy.cql +9 -9
- data/examples/CQL/Genealogy.cql +3 -2
- data/examples/CQL/Insurance.cql +10 -7
- data/examples/CQL/JoinEquality.cql +2 -2
- data/examples/CQL/Marriage.cql +1 -1
- data/examples/CQL/Metamodel.cql +73 -53
- data/examples/CQL/MetamodelNext.cql +89 -67
- data/examples/CQL/OneToOnes.cql +2 -2
- data/examples/CQL/ServiceDirector.cql +10 -5
- data/examples/CQL/Supervision.cql +3 -3
- data/examples/CQL/Tests.Test5.Load.cql +1 -1
- data/examples/CQL/Warehousing.cql +4 -2
- data/lib/activefacts/cql/CQLParser.treetop +26 -60
- data/lib/activefacts/cql/Context.treetop +12 -2
- data/lib/activefacts/cql/Expressions.treetop +14 -30
- data/lib/activefacts/cql/FactTypes.treetop +165 -110
- data/lib/activefacts/cql/Language/English.treetop +167 -54
- data/lib/activefacts/cql/LexicalRules.treetop +16 -2
- data/lib/activefacts/cql/{Concepts.treetop → ObjectTypes.treetop} +36 -37
- data/lib/activefacts/cql/Terms.treetop +57 -27
- data/lib/activefacts/cql/ValueTypes.treetop +39 -13
- data/lib/activefacts/cql/compiler.rb +5 -3
- data/lib/activefacts/cql/compiler/{reading.rb → clause.rb} +407 -285
- data/lib/activefacts/cql/compiler/constraint.rb +178 -275
- data/lib/activefacts/cql/compiler/entity_type.rb +73 -64
- data/lib/activefacts/cql/compiler/expression.rb +418 -0
- data/lib/activefacts/cql/compiler/fact.rb +146 -145
- data/lib/activefacts/cql/compiler/fact_type.rb +197 -80
- data/lib/activefacts/cql/compiler/join.rb +159 -0
- data/lib/activefacts/cql/compiler/shared.rb +51 -23
- data/lib/activefacts/cql/compiler/value_type.rb +56 -2
- data/lib/activefacts/cql/parser.rb +15 -4
- data/lib/activefacts/generate/absorption.rb +7 -7
- data/lib/activefacts/generate/cql.rb +100 -37
- data/lib/activefacts/generate/oo.rb +28 -51
- data/lib/activefacts/generate/ordered.rb +60 -36
- data/lib/activefacts/generate/ruby.rb +6 -6
- data/lib/activefacts/generate/sql/server.rb +4 -4
- data/lib/activefacts/input/orm.rb +71 -53
- data/lib/activefacts/persistence.rb +1 -1
- data/lib/activefacts/persistence/columns.rb +27 -23
- data/lib/activefacts/persistence/foreignkey.rb +6 -6
- data/lib/activefacts/persistence/index.rb +17 -17
- data/lib/activefacts/persistence/{concept.rb → object_type.rb} +9 -9
- data/lib/activefacts/persistence/reference.rb +61 -36
- data/lib/activefacts/persistence/tables.rb +61 -59
- data/lib/activefacts/support.rb +54 -29
- data/lib/activefacts/version.rb +1 -1
- data/lib/activefacts/vocabulary/extensions.rb +99 -54
- data/lib/activefacts/vocabulary/metamodel.rb +43 -37
- data/lib/activefacts/vocabulary/verbaliser.rb +134 -109
- data/spec/absorption_spec.rb +8 -8
- data/spec/cql/comparison_spec.rb +91 -0
- data/spec/cql/contractions_spec.rb +251 -0
- data/spec/cql/entity_type_spec.rb +319 -0
- data/spec/cql/expressions_spec.rb +63 -0
- data/spec/cql/fact_type_matching_spec.rb +283 -0
- data/spec/cql/french_spec.rb +21 -0
- data/spec/cql/parser/bad_literals_spec.rb +86 -0
- data/spec/cql/parser/constraints_spec.rb +19 -0
- data/spec/cql/parser/entity_types_spec.rb +106 -0
- data/spec/cql/parser/expressions_spec.rb +179 -0
- data/spec/cql/parser/fact_types_spec.rb +41 -0
- data/spec/cql/parser/literals_spec.rb +312 -0
- data/spec/cql/parser/pragmas_spec.rb +89 -0
- data/spec/cql/parser/value_types_spec.rb +42 -0
- data/spec/cql/role_matching_spec.rb +147 -0
- data/spec/cql/samples_spec.rb +9 -9
- data/spec/cql_cql_spec.rb +1 -1
- data/spec/cql_dm_spec.rb +116 -0
- data/spec/cql_mysql_spec.rb +1 -1
- data/spec/cql_ruby_spec.rb +1 -1
- data/spec/cql_sql_spec.rb +3 -3
- data/spec/cql_symbol_tables_spec.rb +30 -30
- data/spec/cqldump_spec.rb +4 -4
- data/spec/helpers/array_matcher.rb +32 -27
- data/spec/helpers/diff_matcher.rb +6 -26
- data/spec/helpers/file_matcher.rb +41 -32
- data/spec/helpers/parse_to_ast_matcher.rb +76 -0
- data/spec/helpers/string_matcher.rb +32 -31
- data/spec/norma_cql_spec.rb +1 -1
- data/spec/norma_ruby_spec.rb +1 -1
- data/spec/norma_ruby_sql_spec.rb +1 -1
- data/spec/norma_sql_spec.rb +3 -1
- data/spec/norma_tables_spec.rb +1 -1
- data/spec/ruby_api_spec.rb +23 -0
- data/spec/spec_helper.rb +5 -4
- metadata +66 -66
- data/examples/CQL/OrienteeringER.cql +0 -58
- data/lib/activefacts/api.rb +0 -44
- data/lib/activefacts/api/concept.rb +0 -410
- data/lib/activefacts/api/constellation.rb +0 -128
- data/lib/activefacts/api/entity.rb +0 -256
- data/lib/activefacts/api/instance.rb +0 -60
- data/lib/activefacts/api/instance_index.rb +0 -80
- data/lib/activefacts/api/numeric.rb +0 -167
- data/lib/activefacts/api/role.rb +0 -80
- data/lib/activefacts/api/role_proxy.rb +0 -70
- data/lib/activefacts/api/role_values.rb +0 -117
- data/lib/activefacts/api/standard_types.rb +0 -87
- data/lib/activefacts/api/support.rb +0 -65
- data/lib/activefacts/api/value.rb +0 -135
- data/lib/activefacts/api/vocabulary.rb +0 -82
- data/spec/api/autocounter.rb +0 -82
- data/spec/api/constellation.rb +0 -130
- data/spec/api/entity_type.rb +0 -103
- data/spec/api/instance.rb +0 -461
- data/spec/api/roles.rb +0 -124
- data/spec/api/value_type.rb +0 -112
- data/spec/api_spec.rb +0 -13
- data/spec/cql/matching_spec.rb +0 -517
- data/spec/cql/unit_spec.rb +0 -394
- data/spec/spec.opts +0 -1
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts Runtime API
|
|
3
|
-
# Numeric and Date delegates and hacks to handle immediate types.
|
|
4
|
-
#
|
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
|
6
|
-
#
|
|
7
|
-
# These delegates are required because Integer & Float don't support new,
|
|
8
|
-
# and can't be sensibly subclassed. Just delegate to an instance var.
|
|
9
|
-
# Date and DateTime don't have a sensible new() method, so we monkey-patch one here.
|
|
10
|
-
#
|
|
11
|
-
require 'delegate'
|
|
12
|
-
require 'date'
|
|
13
|
-
|
|
14
|
-
# It's not possible to subclass Integer, so instead we delegate to it.
|
|
15
|
-
class Int < SimpleDelegator
|
|
16
|
-
def initialize(i = nil) #:nodoc:
|
|
17
|
-
__setobj__(Integer(i))
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def to_s #:nodoc:
|
|
21
|
-
__getobj__.to_s
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def hash #:nodoc:
|
|
25
|
-
__getobj__.hash ^ self.class.hash
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def eql?(o) #:nodoc:
|
|
29
|
-
self.class == o.class and __getobj__.eql?(Integer(o))
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def ==(o) #:nodoc:
|
|
33
|
-
__getobj__.==(o)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def inspect
|
|
37
|
-
"#{self.class.basename}:#{__getobj__.inspect}"
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# It's not possible to subclass Float, so instead we delegate to it.
|
|
42
|
-
class Real < SimpleDelegator
|
|
43
|
-
def initialize(r = nil) #:nodoc:
|
|
44
|
-
__setobj__(Float(r))
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def hash #:nodoc:
|
|
48
|
-
__getobj__.hash ^ self.class.hash
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def to_s #:nodoc:
|
|
52
|
-
__getobj__.to_s
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def eql?(o) #:nodoc:
|
|
56
|
-
self.class == o.class and __getobj__.eql?(Float(o))
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def ==(o) #:nodoc:
|
|
60
|
-
__getobj__.==(o)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def inspect #:nodoc:
|
|
64
|
-
"#{self.class.basename}:#{__getobj__.inspect}"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# A Date can be constructed from any Date subclass, not just using the normal date constructors.
|
|
69
|
-
class ::Date
|
|
70
|
-
class << self; alias_method :old_new, :new end
|
|
71
|
-
# Date.new cannot normally be called passing a Date as the parameter. This allows that.
|
|
72
|
-
def self.new(*a, &b)
|
|
73
|
-
#puts "Constructing date with #{a.inspect} from #{caller*"\n\t"}"
|
|
74
|
-
if (a.size == 1 && a[0].is_a?(Date))
|
|
75
|
-
a = a[0]
|
|
76
|
-
civil(a.year, a.month, a.day, a.start)
|
|
77
|
-
elsif (a.size == 1 && a[0].is_a?(String))
|
|
78
|
-
parse(a[0])
|
|
79
|
-
else
|
|
80
|
-
civil(*a, &b)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# A DateTime can be constructed from any Date or DateTime subclass
|
|
86
|
-
class ::DateTime
|
|
87
|
-
class << self; alias_method :old_new, :new end
|
|
88
|
-
# DateTime.new cannot normally be called passing a Date or DateTime as the parameter. This allows that.
|
|
89
|
-
def self.new(*a, &b)
|
|
90
|
-
#puts "Constructing DateTime with #{a.inspect} from #{caller*"\n\t"}"
|
|
91
|
-
if (a.size == 1)
|
|
92
|
-
a = a[0]
|
|
93
|
-
if (DateTime === a)
|
|
94
|
-
civil(a.year, a.month, a.day, a.hour, a.min, a.sec, a.start)
|
|
95
|
-
elsif (Date === a)
|
|
96
|
-
civil(a.year, a.month, a.day, a.start)
|
|
97
|
-
else
|
|
98
|
-
civil(*a, &b)
|
|
99
|
-
end
|
|
100
|
-
else
|
|
101
|
-
civil(*a, &b)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# The AutoCounter class is an integer, but only after the value
|
|
107
|
-
# has been established in the database.
|
|
108
|
-
# Construct it with the value :new to get an uncommitted value.
|
|
109
|
-
# You can use this new instance as a value of any role of this type, including to identify an entity instance.
|
|
110
|
-
# The assigned value will be filled out everywhere it needs to be, upon save.
|
|
111
|
-
class AutoCounter
|
|
112
|
-
def initialize(i = :new)
|
|
113
|
-
raise "AutoCounter #{self.class} may not be #{i.inspect}" unless i == :new or Integer === i
|
|
114
|
-
# puts "new AutoCounter #{self.class} from\n\t#{caller.select{|s| s !~ %r{rspec}}*"\n\t"}"
|
|
115
|
-
@value = i == :new ? nil : i
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Assign a definite value to an AutoCounter; this may only be done once
|
|
119
|
-
def assign(i)
|
|
120
|
-
raise ArgumentError if @value
|
|
121
|
-
@value = i.to_i
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Ask whether a definite value has been assigned
|
|
125
|
-
def defined?
|
|
126
|
-
!@value.nil?
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def to_s
|
|
130
|
-
if self.defined?
|
|
131
|
-
@value.to_s
|
|
132
|
-
else
|
|
133
|
-
"new_#{object_id}"
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# An AutoCounter may only be used in numeric expressions after a definite value has been assigned
|
|
138
|
-
def self.coerce(i)
|
|
139
|
-
raise ArgumentError unless @value
|
|
140
|
-
[ i.to_i, @value ]
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def inspect
|
|
144
|
-
"\#<AutoCounter "+to_s+">"
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def hash #:nodoc:
|
|
148
|
-
to_s.hash ^ self.class.hash
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def eql?(o) #:nodoc:
|
|
152
|
-
self.class == o.class and to_s.eql?(o.to_s)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def self.inherited(other) #:nodoc:
|
|
156
|
-
def other.identifying_role_values(*args)
|
|
157
|
-
return nil if args == [:new] # A new object has no identifying_role_values
|
|
158
|
-
return new(*args)
|
|
159
|
-
end
|
|
160
|
-
super
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
private
|
|
164
|
-
def clone
|
|
165
|
-
raise "Not allowed to clone AutoCounters"
|
|
166
|
-
end
|
|
167
|
-
end
|
data/lib/activefacts/api/role.rb
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts API
|
|
3
|
-
# Role class.
|
|
4
|
-
# Each accessor method created on an instance corresponds to a Role object in the instance's class.
|
|
5
|
-
# Binary fact types construct a Role at each end.
|
|
6
|
-
#
|
|
7
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
|
8
|
-
#
|
|
9
|
-
module ActiveFacts
|
|
10
|
-
module API
|
|
11
|
-
|
|
12
|
-
# A Role represents the relationship of one object to another (or to a boolean condition).
|
|
13
|
-
# Relationships (or binary fact types) have a Role at each end; one is declared using _has_one_
|
|
14
|
-
# or _one_to_one_, and the other is created on the counterpart class. Each Concept class maintains
|
|
15
|
-
# an array of the roles it plays.
|
|
16
|
-
class Role
|
|
17
|
-
attr_accessor :owner # The Concept to which this role belongs
|
|
18
|
-
attr_accessor :name # The name of the role (a Symbol)
|
|
19
|
-
attr_accessor :counterpart_concept # A Concept Class (may be temporarily a Symbol before the class is defined)
|
|
20
|
-
attr_accessor :counterpart # All roles except unaries have a binary counterpart
|
|
21
|
-
attr_accessor :unique # Is this role played by at most one instance, or more?
|
|
22
|
-
attr_accessor :mandatory # In a valid fact population, is this role required to be played?
|
|
23
|
-
attr_accessor :value_constraint # Counterpart Instances playing this role must meet this constraint
|
|
24
|
-
attr_reader :is_identifying # Is this an identifying role for owner?
|
|
25
|
-
|
|
26
|
-
def initialize(owner, counterpart_concept, counterpart, name, mandatory = false, unique = true)
|
|
27
|
-
@owner = owner
|
|
28
|
-
@counterpart_concept = counterpart_concept
|
|
29
|
-
@counterpart = counterpart
|
|
30
|
-
@name = name
|
|
31
|
-
@mandatory = mandatory
|
|
32
|
-
@unique = unique
|
|
33
|
-
@is_identifying = @owner.is_entity_type && @owner.identifying_role_names.include?(@name)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Is this role a unary (created by maybe)? If so, it has no counterpart
|
|
37
|
-
def unary?
|
|
38
|
-
# N.B. A role with a forward reference looks unary until it is resolved.
|
|
39
|
-
counterpart == nil
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def resolve_counterpart(vocabulary) #:nodoc:
|
|
43
|
-
return @counterpart_concept if @counterpart_concept.is_a?(Class) # Done already
|
|
44
|
-
klass = vocabulary.concept(@counterpart_concept) # Trigger the binding
|
|
45
|
-
raise "Cannot resolve role counterpart_concept #{@counterpart_concept.inspect} for role #{name} in vocabulary #{vocabulary.basename}; still forward-declared?" unless klass
|
|
46
|
-
@counterpart_concept = klass # Memoize a successful result
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def adapt(constellation, value) #:nodoc:
|
|
50
|
-
# If the value is a compatible class, use it (if in another constellation, clone it),
|
|
51
|
-
# else create a compatible object using the value as constructor parameters.
|
|
52
|
-
if value.is_a?(@counterpart_concept) # REVISIT: may be a non-primary subtype of counterpart_concept
|
|
53
|
-
value = value.__getobj__ if RoleProxy === value
|
|
54
|
-
# Check that the value is in a compatible constellation, clone if not:
|
|
55
|
-
if constellation && (vc = value.constellation) && vc != constellation
|
|
56
|
-
value = value.clone # REVISIT: There's sure to be things we should reset/clone here, like non-identifying roles
|
|
57
|
-
end
|
|
58
|
-
value.constellation = constellation if constellation
|
|
59
|
-
else
|
|
60
|
-
value = [value] unless Array === value
|
|
61
|
-
raise "No parameters were provided to identify an #{@counterpart_concept.basename} instance" if value == []
|
|
62
|
-
if constellation
|
|
63
|
-
value = constellation.send(@counterpart_concept.basename.to_sym, *value)
|
|
64
|
-
else
|
|
65
|
-
value = @counterpart_concept.new(*value)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
value
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# Every Concept has a Role collection
|
|
73
|
-
# REVISIT: You can enumerate the concept's own roles, or inherited roles as well.
|
|
74
|
-
class RoleCollection < Hash #:nodoc:
|
|
75
|
-
def verbalise
|
|
76
|
-
keys.sort_by(&:to_s).inspect
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts Runtime API
|
|
3
|
-
# RoleProxy class, still somewhat experimental
|
|
4
|
-
#
|
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
|
6
|
-
#
|
|
7
|
-
require 'delegate'
|
|
8
|
-
|
|
9
|
-
module ActiveFacts
|
|
10
|
-
module API
|
|
11
|
-
#
|
|
12
|
-
# When you use the accessor method created by has_one, one_to_one, or maybe, you get a RoleProxy for the actual value.
|
|
13
|
-
# This behaves almost exactly as the value, but it knows through which role you fetched it.
|
|
14
|
-
# That will allow it to verbalise itself using the correct reading for that role.
|
|
15
|
-
#
|
|
16
|
-
# Don't use "SomeClass === role_value" to test the type, use "role_value.is_a?(SomeClass)" instead.
|
|
17
|
-
#
|
|
18
|
-
# In future, retrieving a value by indexing into a RoleValues array will do the same thing.
|
|
19
|
-
#
|
|
20
|
-
class RoleProxy < SimpleDelegator
|
|
21
|
-
def initialize(role, o = nil) #:nodoc:
|
|
22
|
-
@role = role # REVISIT: Use this to implement verbalise()
|
|
23
|
-
__setobj__(o)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def method_missing(m, *a, &b) #:nodoc:
|
|
27
|
-
begin
|
|
28
|
-
super # Delegate first
|
|
29
|
-
rescue NoMethodError => e
|
|
30
|
-
__getobj__.method_missing(m, *a, &b)
|
|
31
|
-
rescue => e
|
|
32
|
-
raise
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def class #:nodoc:
|
|
37
|
-
__getobj__.class
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def is_a? klass #:nodoc:
|
|
41
|
-
__getobj__.is_a? klass
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def to_s #:nodoc:
|
|
45
|
-
__getobj__.to_s
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def object_id #:nodoc:
|
|
49
|
-
__getobj__.object_id
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# REVISIT: Should Proxies hash and eql? the same as their wards?
|
|
53
|
-
def hash #:nodoc:
|
|
54
|
-
__getobj__.hash ^ self.class.hash
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def eql?(o) #:nodoc:
|
|
58
|
-
self.class == o.class and __getobj__.eql?(o)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def ==(o) #:nodoc:
|
|
62
|
-
__getobj__.==(o)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def inspect #:nodoc:
|
|
66
|
-
"Proxy:#{__getobj__.inspect}"
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts Runtime API
|
|
3
|
-
# RoleValues, manages the set of instances involved in a many_to_one relationship.
|
|
4
|
-
#
|
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
|
6
|
-
#
|
|
7
|
-
# There are two implementations here, one using an array and one using a hash.
|
|
8
|
-
# The hash one has problems with keys being changed during object deletion, so
|
|
9
|
-
# cannot be used yet; a fix is upcoming and will improve performance of large sets.
|
|
10
|
-
#
|
|
11
|
-
module ActiveFacts
|
|
12
|
-
module API
|
|
13
|
-
|
|
14
|
-
class RoleValues #:nodoc:
|
|
15
|
-
include Enumerable
|
|
16
|
-
|
|
17
|
-
#=begin
|
|
18
|
-
def initialize
|
|
19
|
-
@a = []
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def each &b
|
|
23
|
-
# REVISIT: Provide a configuration variable to enable this heckling during testing:
|
|
24
|
-
#@a.sort_by{rand}.each &b
|
|
25
|
-
@a.each &b
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def size
|
|
29
|
-
@a.size
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def empty?
|
|
33
|
-
@a.size == 0
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def +(a)
|
|
37
|
-
@a.+(a.is_a?(RoleValues) ? Array(a) : a)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def -(a)
|
|
41
|
-
@a - a
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def single
|
|
45
|
-
@a.size > 1 ? nil : @a[0]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def update(old, value)
|
|
49
|
-
@a.delete(old) if old
|
|
50
|
-
@a << value if value
|
|
51
|
-
raise "Adding RoleProxy to RoleValues collection" if value && RoleProxy === value
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def verbalise
|
|
55
|
-
"["+@a.to_a.map{|e| e.verbalise}*", "+"]"
|
|
56
|
-
end
|
|
57
|
-
#=end
|
|
58
|
-
|
|
59
|
-
=begin
|
|
60
|
-
def initialize
|
|
61
|
-
@h = {}
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def each &b
|
|
65
|
-
@h.keys.each &b
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def size
|
|
69
|
-
@h.size
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def empty?
|
|
73
|
-
@h.size == 0
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def +(a)
|
|
77
|
-
@h.keys.+(a.is_a?(RoleValues) ? Array(a) : a)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def -(a)
|
|
81
|
-
@h.keys - a
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def single
|
|
85
|
-
@h.size > 1 ? nil : @h.keys[0]
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def update(old, value)
|
|
89
|
-
if old
|
|
90
|
-
unless @h.delete(old)
|
|
91
|
-
@h.each { |k, v|
|
|
92
|
-
next if k != old
|
|
93
|
-
puts "#{@h.object_id}: Didn't delete #{k.verbalise} (hash=#{k.hash}) matching #{old.verbalise} (hash=#{old.hash})"
|
|
94
|
-
puts "They are #{k.eql?(old) ? "" : "not "}eql?"
|
|
95
|
-
found = @h[k]
|
|
96
|
-
puts "found #{found.inspect}" if found
|
|
97
|
-
debugger
|
|
98
|
-
x = k.eql?(old)
|
|
99
|
-
y = old.eql?(k)
|
|
100
|
-
p y
|
|
101
|
-
}
|
|
102
|
-
raise "failed to delete #{old.verbalise}, have #{map{|e| e.verbalise}.inspect}"
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
puts "#{@h.object_id}: Adding #{value.inspect}" if value && (value.name == 'Meetingisboardmeeting' rescue false)
|
|
106
|
-
@h[value] = true if value
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def verbalise
|
|
110
|
-
"["+@h.keys.map{|e| e.verbalise}*", "+"]"
|
|
111
|
-
end
|
|
112
|
-
=end
|
|
113
|
-
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
end
|
|
117
|
-
end
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# ActiveFacts Runtime API
|
|
3
|
-
# Standard types extensions.
|
|
4
|
-
#
|
|
5
|
-
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
|
6
|
-
#
|
|
7
|
-
# These extensions add ActiveFacts Concept and Instance behaviour into base Ruby value classes,
|
|
8
|
-
# and allow any Class to become an Entity.
|
|
9
|
-
#
|
|
10
|
-
require 'date'
|
|
11
|
-
|
|
12
|
-
module ActiveFacts
|
|
13
|
-
module API
|
|
14
|
-
# Adapter module to add value_type to all potential value classes
|
|
15
|
-
module ValueClass #:nodoc:
|
|
16
|
-
def value_type *args, &block #:nodoc:
|
|
17
|
-
include ActiveFacts::API::Value
|
|
18
|
-
# the included method adds the Value::ClassMethods
|
|
19
|
-
initialise_value_type(*args, &block)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
require 'activefacts/api/numeric'
|
|
26
|
-
|
|
27
|
-
# Add the methods that convert our classes into Concept types:
|
|
28
|
-
|
|
29
|
-
ValueClasses = [String, Date, DateTime, Time, Int, Real, AutoCounter]
|
|
30
|
-
ValueClasses.each{|c|
|
|
31
|
-
c.send :extend, ActiveFacts::API::ValueClass
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
class TrueClass #:nodoc:
|
|
35
|
-
def verbalise(role_name = nil); role_name ? "#{role_name}: true" : "true"; end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
class NilClass #:nodoc:
|
|
39
|
-
def verbalise; "nil"; end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
class Class
|
|
43
|
-
# Make this Class into a Concept and if necessary its module into a Vocabulary.
|
|
44
|
-
# The parameters are the names (Symbols) of the identifying roles.
|
|
45
|
-
def identified_by *args
|
|
46
|
-
raise "#{basename} is not an entity type" if respond_to? :value_type # Don't make a ValueType into an EntityType
|
|
47
|
-
include ActiveFacts::API::Entity
|
|
48
|
-
initialise_entity_type(*args)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def is_entity_type
|
|
52
|
-
respond_to?(:identifying_role_names)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
require 'bigdecimal'
|
|
57
|
-
class Decimal < BigDecimal #:nodoc:
|
|
58
|
-
extend ActiveFacts::API::ValueClass
|
|
59
|
-
# The problem here is you can't pass a BigDecimal to BigDecimal.new. Fix it.
|
|
60
|
-
def self.new(v)
|
|
61
|
-
if v.is_a?(BigDecimal)
|
|
62
|
-
super(v.to_s)
|
|
63
|
-
else
|
|
64
|
-
super
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# These types are generated on conversion from NORMA's types:
|
|
70
|
-
class Char < String #:nodoc: # FixedLengthText
|
|
71
|
-
end
|
|
72
|
-
class Text < String #:nodoc: # LargeLengthText
|
|
73
|
-
end
|
|
74
|
-
class Image < String #:nodoc: # PictureRawData
|
|
75
|
-
end
|
|
76
|
-
class SignedInteger < Int #:nodoc:
|
|
77
|
-
end
|
|
78
|
-
class UnsignedInteger < Int #:nodoc:
|
|
79
|
-
end
|
|
80
|
-
class AutoTimeStamp < String #:nodoc: AutoTimeStamp
|
|
81
|
-
end
|
|
82
|
-
class Blob < String #:nodoc: VariableLengthRawData
|
|
83
|
-
end
|
|
84
|
-
unless Object.const_defined?("Money")
|
|
85
|
-
class Money < Decimal #:nodoc:
|
|
86
|
-
end
|
|
87
|
-
end
|