activefacts-api 1.9.10 → 1.9.11
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.
- 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)
|