activefacts 0.8.9 → 0.8.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|