activefacts-api 1.9.10 → 1.9.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/activefacts/api/constellation.rb +2 -1
- data/lib/activefacts/api/entity.rb +14 -14
- data/lib/activefacts/api/instance.rb +3 -3
- data/lib/activefacts/api/object_type.rb +8 -8
- data/lib/activefacts/api/role_values.rb +16 -6
- data/lib/activefacts/api/support.rb +0 -6
- data/lib/activefacts/api/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25d2b489a8eae8b845892def91b49758612dfdde
|
4
|
+
data.tar.gz: 8682af38486aad1436f16503398a1e8d74915a61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9506523f2552e1ae21b3e06f5c555b0bd5d99680e2d58b3f8bf6d13469e35193ee46119d9670dd2226f77c837e5a77730493a9f95f858d43402f065198b61c4c
|
7
|
+
data.tar.gz: 45dd288ac6fa9b6eccddf7579aba79e7e3dee85d3e1149f49fc5e4ebd26745a2ccd89f567eaa188d02bb460a1b0819385f23a1e749188184dab6f35eeee52573
|
@@ -75,7 +75,8 @@ module ActiveFacts
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def define_class_accessor m, klass
|
78
|
-
singleton_class.
|
78
|
+
singleton_class.
|
79
|
+
send(:define_method, m) do |*args|
|
79
80
|
if args.size == 0
|
80
81
|
# Return the collection of all instances of this class in the constellation:
|
81
82
|
instances[klass]
|
@@ -32,9 +32,9 @@ module ActiveFacts
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def initialize_existential_roles(klass, arg_hash)
|
35
|
-
#
|
36
|
-
|
37
|
-
initialize_existential_roles(
|
35
|
+
# Assign the identifying attributes of all superclasses first
|
36
|
+
klass.supertypes_transitive.each do |supertype|
|
37
|
+
initialize_existential_roles(supertype, arg_hash)
|
38
38
|
end
|
39
39
|
|
40
40
|
irns = klass.identifying_role_names
|
@@ -159,9 +159,9 @@ module ActiveFacts
|
|
159
159
|
# identified by this entity. Save the current key and
|
160
160
|
# class for each such instance.
|
161
161
|
# This function is transitive!
|
162
|
-
def
|
163
|
-
|
164
|
-
|
162
|
+
def collect_instance_index_updates role
|
163
|
+
instance_index_updates = []
|
164
|
+
propagation_roles = []
|
165
165
|
|
166
166
|
# Consider the object itself and all its supertypes
|
167
167
|
([self.class]+self.class.supertypes_transitive).map do |supertype|
|
@@ -169,7 +169,7 @@ module ActiveFacts
|
|
169
169
|
|
170
170
|
old_key = identifying_role_values(supertype)
|
171
171
|
# puts "Need to reindex #{self.class} as #{supertype} from #{old_key.inspect}"
|
172
|
-
|
172
|
+
instance_index_updates << [constellation.instances[supertype], self, old_key]
|
173
173
|
|
174
174
|
supertype.
|
175
175
|
all_role.
|
@@ -178,29 +178,29 @@ module ActiveFacts
|
|
178
178
|
next unless counterpart = propagation_role.counterpart # And the role is not unary
|
179
179
|
if counterpart.is_identifying # This object identifies another
|
180
180
|
# puts "Changing #{propagation_role.inspect} affects #{counterpart.inspect}"
|
181
|
-
|
181
|
+
propagation_roles << propagation_role
|
182
182
|
else
|
183
183
|
next if counterpart.unique # But a one-to-many
|
184
184
|
next unless value = send(propagation_role.getter) # A value is set
|
185
185
|
role_values = value.send(counterpart.getter) # This is the index we have to change
|
186
186
|
# puts "Changing #{role.inspect} of a #{self.class} requires updating #{propagation_role.counterpart.inspect}"
|
187
|
-
|
187
|
+
instance_index_updates << [role_values, self, old_key]
|
188
188
|
end
|
189
189
|
end
|
190
190
|
end
|
191
191
|
|
192
|
-
|
192
|
+
propagation_roles.each do |role|
|
193
193
|
affected_instances = Array(send(role.getter))
|
194
194
|
# puts "considering #{affected_instances.size} #{role.object_type.name} instances that include #{role.inspect}: #{affected_instances.map(&:identifying_role_values).inspect}"
|
195
195
|
affected_instances.each do |counterpart|
|
196
|
-
|
196
|
+
instance_index_updates.concat(counterpart.collect_instance_index_updates(role.counterpart))
|
197
197
|
end
|
198
198
|
end
|
199
|
-
|
199
|
+
instance_index_updates
|
200
200
|
end
|
201
201
|
|
202
|
-
def
|
203
|
-
|
202
|
+
def apply_instance_index_updates instance_index_updates
|
203
|
+
instance_index_updates.each do |index, entity, old_key|
|
204
204
|
new_key = entity.identifying_role_values(index.object_type)
|
205
205
|
# puts "Reindexing #{klass} from #{old_key.inspect} to #{new_key.inspect}"
|
206
206
|
|
@@ -77,14 +77,14 @@ module ActiveFacts
|
|
77
77
|
# The counterpart roles get cleared automatically.
|
78
78
|
klasses = [self.class]+self.class.supertypes_transitive
|
79
79
|
|
80
|
-
|
80
|
+
key_by_type = {}
|
81
81
|
self.class.all_role_transitive.each do |_, role|
|
82
82
|
next unless role.counterpart and
|
83
83
|
role.unique and
|
84
84
|
!role.counterpart.unique and
|
85
85
|
counterpart = send(role.getter)
|
86
86
|
role_values = counterpart.send(role.counterpart.getter)
|
87
|
-
|
87
|
+
key_by_type[role.object_type] ||= identifying_role_values(role.object_type)
|
88
88
|
end
|
89
89
|
|
90
90
|
# Nullify the counterpart role of objects we identify first, before damaging our identifying_role_values:
|
@@ -124,7 +124,7 @@ module ActiveFacts
|
|
124
124
|
counterpart_instance.send(counterpart.setter, nil, false)
|
125
125
|
else
|
126
126
|
rv = counterpart_instance.send(role.counterpart.getter)
|
127
|
-
rv.delete_instance(self,
|
127
|
+
rv.delete_instance(self, key_by_type[role.object_type])
|
128
128
|
|
129
129
|
if (rv.empty? && !counterpart_instance.class.is_entity_type)
|
130
130
|
counterpart_instance.retract if counterpart_instance.plays_no_role
|
@@ -260,16 +260,16 @@ module ActiveFacts
|
|
260
260
|
|
261
261
|
if role.is_identifying and (options&CHECKED_IDENTIFYING_ROLE) == 0
|
262
262
|
check_identification_change_legality(role, value)
|
263
|
-
|
263
|
+
instance_index_updates = collect_instance_index_updates(role)
|
264
264
|
end
|
265
265
|
|
266
266
|
instance_variable_set(role.variable, value)
|
267
267
|
|
268
|
-
if
|
268
|
+
if instance_index_updates
|
269
269
|
@constellation.when_admitted do
|
270
270
|
# REVISIT: Consider whether we want to provide a way to find all instances
|
271
271
|
# playing/not playing this boolean role, analogous to true.all_thing_as_role_name...
|
272
|
-
|
272
|
+
apply_instance_index_updates(instance_index_updates) # Propagate dependent key changes
|
273
273
|
end
|
274
274
|
end
|
275
275
|
|
@@ -314,7 +314,7 @@ module ActiveFacts
|
|
314
314
|
check_identification_change_legality(role, value)
|
315
315
|
|
316
316
|
# puts "Starting to analyse impact of changing 1-1 #{role.inspect} to #{value.inspect}"
|
317
|
-
|
317
|
+
instance_index_updates = collect_instance_index_updates(role)
|
318
318
|
end
|
319
319
|
|
320
320
|
instance_variable_set(role_var, value)
|
@@ -328,7 +328,7 @@ module ActiveFacts
|
|
328
328
|
# Assign self to the new counterpart
|
329
329
|
value.send(role.counterpart.setter, self, options) if value && (options&SKIP_MUTUAL_PROPAGATION) == 0
|
330
330
|
|
331
|
-
|
331
|
+
apply_instance_index_updates(instance_index_updates) if instance_index_updates # Propagate dependent key changes
|
332
332
|
end
|
333
333
|
|
334
334
|
unless @constellation.loggers.empty? or options != 0
|
@@ -363,12 +363,12 @@ module ActiveFacts
|
|
363
363
|
check_identification_change_legality(role, value)
|
364
364
|
|
365
365
|
# puts "Starting to analyse impact of changing 1-N #{role.inspect} to #{value.inspect}"
|
366
|
-
|
366
|
+
instance_index_updates = collect_instance_index_updates(role)
|
367
367
|
end
|
368
368
|
|
369
369
|
if old and (options&SKIP_MUTUAL_PROPAGATION) == 0
|
370
370
|
old_role_values = old.send(getter = role.counterpart.getter)
|
371
|
-
old_key =
|
371
|
+
old_key = identifying_role_values(role.object_type)
|
372
372
|
end
|
373
373
|
|
374
374
|
instance_variable_set(role_var, value)
|
@@ -388,7 +388,7 @@ module ActiveFacts
|
|
388
388
|
rv.add_instance(self, identifying_role_values(role.object_type))
|
389
389
|
end
|
390
390
|
|
391
|
-
|
391
|
+
apply_instance_index_updates(instance_index_updates) if instance_index_updates # Propagate dependent key changes
|
392
392
|
end
|
393
393
|
|
394
394
|
unless @constellation.loggers.empty? or options != 0
|
@@ -11,6 +11,7 @@ module ActiveFacts
|
|
11
11
|
attr_accessor :role
|
12
12
|
attr_accessor :sort
|
13
13
|
attr_accessor :index_roles
|
14
|
+
|
14
15
|
def object_type
|
15
16
|
@role.object_type
|
16
17
|
end
|
@@ -21,7 +22,11 @@ module ActiveFacts
|
|
21
22
|
@sort = API::sorted
|
22
23
|
@excluded_role = excluded_role
|
23
24
|
@a = @sort ? RBTree.new : []
|
24
|
-
|
25
|
+
if @excluded_role
|
26
|
+
@index_roles = role.object_type.identifying_roles.dup
|
27
|
+
@index_roles.delete_at(@excluded_role)
|
28
|
+
@index_roles.freeze
|
29
|
+
end
|
25
30
|
end
|
26
31
|
|
27
32
|
def +(a)
|
@@ -68,17 +73,19 @@ module ActiveFacts
|
|
68
73
|
KeyArray.new(a)
|
69
74
|
end
|
70
75
|
|
76
|
+
# Return the full key for the object according to the object_type of this role
|
71
77
|
def index_values object
|
72
|
-
if @
|
73
|
-
@index_roles.map
|
78
|
+
if @excluded_role
|
79
|
+
@index_roles.map do |r|
|
74
80
|
role_value = object.send(r.name)
|
75
81
|
role_value.identifying_role_values((c = r.counterpart) ? c.object_type : role_value.class)
|
76
|
-
|
82
|
+
end
|
77
83
|
else
|
78
|
-
object.identifying_role_values
|
84
|
+
object.identifying_role_values(role.object_type)
|
79
85
|
end
|
80
86
|
end
|
81
87
|
|
88
|
+
# The key must include the excluded role, if any
|
82
89
|
def add_instance(value, key)
|
83
90
|
if @sort
|
84
91
|
# Exclude the excluded role, if any:
|
@@ -89,9 +96,12 @@ module ActiveFacts
|
|
89
96
|
end
|
90
97
|
end
|
91
98
|
|
99
|
+
# The key must include the excluded role, if any
|
92
100
|
def delete_instance(value, key)
|
93
101
|
if @sort
|
94
|
-
|
102
|
+
if key.size != role.object_type.identifying_roles.size
|
103
|
+
raise "Internal error: incorrectly-sized key #{key.inspect} to delete_instance"
|
104
|
+
end
|
95
105
|
(key = key.dup).delete_at(@excluded_role) if @excluded_role
|
96
106
|
deleted = @a.delete(form_key(key))
|
97
107
|
else
|
@@ -11,12 +11,6 @@ unless Object.const_defined?("Infinity")
|
|
11
11
|
Infinity = 1.0/0.0
|
12
12
|
end
|
13
13
|
|
14
|
-
class Symbol #:nodoc:
|
15
|
-
def to_proc
|
16
|
-
Proc.new{|*args| args.shift.__send__(self, *args)}
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
14
|
class String #:nodoc:
|
21
15
|
# This may be overridden by a version from ActiveSupport. For our purposes, either will work.
|
22
16
|
def camelcase(first_letter = :upper)
|