infopark_fiona7 1.2.0.0.1 → 1.2.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/scrivito_patches/models/obj.js +2 -6
- data/infopark_fiona7.gemspec +1 -1
- data/lib/fiona7/attribute_readers/attribute_reader.rb +17 -0
- data/lib/fiona7/attribute_readers/binary_as_binary.rb +12 -0
- data/lib/fiona7/attribute_readers/binary_as_linklist.rb +26 -0
- data/lib/fiona7/attribute_readers/date_as_date.rb +18 -0
- data/lib/fiona7/attribute_readers/factory.rb +91 -0
- data/lib/fiona7/attribute_readers/helpers/html_deserializer.rb +21 -0
- data/lib/fiona7/attribute_readers/helpers/json_deserializer.rb +11 -0
- data/lib/fiona7/attribute_readers/helpers/link_deserializer.rb +32 -0
- data/lib/fiona7/attribute_readers/html_as_html.rb +14 -0
- data/lib/fiona7/attribute_readers/link_as_linklist.rb +13 -0
- data/lib/fiona7/attribute_readers/linklist_as_linklist.rb +15 -0
- data/lib/fiona7/attribute_readers/multienum_as_multienum.rb +12 -0
- data/lib/fiona7/attribute_readers/multienum_as_text.rb +14 -0
- data/lib/fiona7/attribute_readers/number_as_string.rb +11 -0
- data/lib/fiona7/attribute_readers/reference_as_linklist.rb +14 -0
- data/lib/fiona7/attribute_readers/reference_as_string.rb +11 -0
- data/lib/fiona7/attribute_readers/referencelist_as_linklist.rb +16 -0
- data/lib/fiona7/attribute_readers/referencelist_as_text.rb +14 -0
- data/lib/fiona7/attribute_readers/simple.rb +18 -0
- data/lib/fiona7/attribute_readers/stringlist_as_text.rb +18 -0
- data/lib/fiona7/attribute_readers/widgetlist_as_linklist.rb +33 -0
- data/lib/fiona7/attribute_type_mapper.rb +76 -0
- data/lib/fiona7/attribute_writers/attribute_writer.rb +16 -0
- data/lib/fiona7/attribute_writers/binary_as_binary.rb +74 -0
- data/lib/fiona7/attribute_writers/binary_as_linklist.rb +86 -0
- data/lib/fiona7/attribute_writers/date_as_date.rb +11 -0
- data/lib/fiona7/attribute_writers/factory.rb +90 -0
- data/lib/fiona7/attribute_writers/helpers/html_serializer.rb +21 -0
- data/lib/fiona7/attribute_writers/helpers/json_serializer.rb +11 -0
- data/lib/fiona7/attribute_writers/helpers/link_serializer.rb +37 -0
- data/lib/fiona7/attribute_writers/html_as_html.rb +12 -0
- data/lib/fiona7/attribute_writers/link_as_linklist.rb +18 -0
- data/lib/fiona7/attribute_writers/linklist_as_linklist.rb +16 -0
- data/lib/fiona7/attribute_writers/multienum_as_multienum.rb +11 -0
- data/lib/fiona7/attribute_writers/multienum_as_text.rb +12 -0
- data/lib/fiona7/attribute_writers/number_as_string.rb +11 -0
- data/lib/fiona7/attribute_writers/reference_as_linklist.rb +17 -0
- data/lib/fiona7/attribute_writers/reference_as_string.rb +11 -0
- data/lib/fiona7/attribute_writers/referencelist_as_linklist.rb +19 -0
- data/lib/fiona7/attribute_writers/referencelist_as_text.rb +13 -0
- data/lib/fiona7/attribute_writers/simple.rb +11 -0
- data/lib/fiona7/attribute_writers/stringlist_as_text.rb +16 -0
- data/lib/fiona7/attribute_writers/widgetlist_as_linklist.rb +33 -0
- data/lib/fiona7/builder/obj_builder.rb +12 -201
- data/lib/fiona7/controllers/rest_api/obj_controller.rb +23 -5
- data/lib/fiona7/engine.rb +39 -0
- data/lib/fiona7/json/obj_decorator.rb +29 -121
- data/lib/fiona7/prefetch/obj_prefetch.rb +42 -0
- data/lib/fiona7/prefetch/widget_resolver_prefetch.rb +36 -0
- data/lib/fiona7/scrivito_patches/date_attribute.rb +16 -0
- data/lib/fiona7/tools/attribute_remover.rb +70 -0
- data/lib/fiona7/type_register.rb +9 -1
- data/lib/fiona7/version.rb +1 -1
- data/lib/fiona7/widget_resolver.rb +6 -6
- metadata +51 -4
@@ -15,6 +15,9 @@ require 'fiona7/assert'
|
|
15
15
|
require 'fiona7/json/reverse_obj_decorator'
|
16
16
|
require 'fiona7/json/typeless_obj_decorator'
|
17
17
|
|
18
|
+
require 'fiona7/prefetch/obj_prefetch'
|
19
|
+
require 'fiona7/prefetch/widget_resolver_prefetch'
|
20
|
+
|
18
21
|
module Fiona7
|
19
22
|
module Controllers
|
20
23
|
module RestAPI
|
@@ -61,10 +64,13 @@ module Fiona7
|
|
61
64
|
# FIXME: code duplication with fetch_by_id
|
62
65
|
obj_ids = payload.with_indifferent_access[:ids]
|
63
66
|
klass = revision_id.start_with?('f') ? ReleasedObj : EditedObj
|
64
|
-
objs = klass.where(obj_id: obj_ids)
|
65
|
-
objs_arr = obj_ids.map {|obj_id| objs.find {|o| o.id == obj_id.to_i } }
|
66
67
|
|
67
|
-
|
68
|
+
# preloads all objects in one query
|
69
|
+
objs_arr = Prefetch::ObjPrefetch.new(klass, obj_ids).find_many(obj_ids)
|
70
|
+
# preloads all widgets in one query
|
71
|
+
widget_prefetch = Prefetch::WidgetResolverPrefetch.new(klass, objs_arr.compact)
|
72
|
+
|
73
|
+
decorated = objs_arr.map {|obj| obj ? Fiona7::JSON::ReverseObjDecorator.new(klass, obj, widget_prefetch.widget_resolver(obj)) : nil }
|
68
74
|
response = ::JSON.parse(::ActiveSupport::JSON.encode({"results" => decorated}))
|
69
75
|
return response
|
70
76
|
end
|
@@ -112,11 +118,23 @@ module Fiona7
|
|
112
118
|
conti = {}
|
113
119
|
end
|
114
120
|
|
121
|
+
# This simulates the behavior of the backend:
|
122
|
+
# In absence of other input backend always sorts by ID
|
123
|
+
# or SCORE if an elastic search for such request would
|
124
|
+
# produce a score.
|
125
|
+
if (params[:query]||[]).any?{|op| (op[:operator]||op["operator"]).to_s =~ /search/ }
|
126
|
+
default_sort_order = :desc
|
127
|
+
default_sort_by = :_score
|
128
|
+
else
|
129
|
+
default_sort_order = :asc
|
130
|
+
default_sort_by = :id
|
131
|
+
end
|
132
|
+
|
115
133
|
offset = conti[:offset] || params[:offset] || 0
|
116
134
|
# 10 is the default value in original implementation
|
117
135
|
size = conti[:size] || params[:size] || 10
|
118
|
-
order = (conti[:sort_order] || params[:sort_order] ||
|
119
|
-
sort = (conti[:sort_by] || params[:sort_by] ||
|
136
|
+
order = (conti[:sort_order] || params[:sort_order] || default_sort_order).to_sym
|
137
|
+
sort = (conti[:sort_by] || params[:sort_by] || default_sort_by).to_sym
|
120
138
|
|
121
139
|
if params[:query].present?
|
122
140
|
normalize_query_params(params[:query])
|
data/lib/fiona7/engine.rb
CHANGED
@@ -59,6 +59,9 @@ require 'fiona7/type_synchronizer'
|
|
59
59
|
require 'fiona7/naive_search_engine'
|
60
60
|
require 'fiona7/verity_search_engine'
|
61
61
|
|
62
|
+
# tools
|
63
|
+
require 'fiona7/tools/attribute_remover'
|
64
|
+
|
62
65
|
module Fiona7
|
63
66
|
mattr_accessor :mode
|
64
67
|
mattr_accessor :login
|
@@ -71,6 +74,42 @@ module Fiona7
|
|
71
74
|
:release_obj => []
|
72
75
|
}
|
73
76
|
|
77
|
+
# Allows to specify custom typing for virtual attribute types
|
78
|
+
# Besides the built in mapping:
|
79
|
+
# link: :linklist,
|
80
|
+
# reference: :linklist,
|
81
|
+
# referencelist: :linklist,
|
82
|
+
# widgetlist: :linklist,
|
83
|
+
# binary: :linklist,
|
84
|
+
# number: :string,
|
85
|
+
# stringlist: :text
|
86
|
+
#
|
87
|
+
# Following other options are supported:
|
88
|
+
# reference: :string,
|
89
|
+
# referencelist: :text
|
90
|
+
#
|
91
|
+
# Custom mappings can be specified per obj_class:
|
92
|
+
#
|
93
|
+
# custom_attribute_types = {
|
94
|
+
# 'MyPage' => {
|
95
|
+
# child_order: :text
|
96
|
+
# }
|
97
|
+
# }
|
98
|
+
#
|
99
|
+
# or per attribute:
|
100
|
+
#
|
101
|
+
# custom_attribute_types = {
|
102
|
+
# child_order: :text
|
103
|
+
# }
|
104
|
+
#
|
105
|
+
# or using a callable entity like a proc:
|
106
|
+
#
|
107
|
+
# custom_attribute_types = lambda do |obj_class, attribute|
|
108
|
+
# :text if attribute == :child_order
|
109
|
+
# end
|
110
|
+
mattr_accessor :custom_attribute_types
|
111
|
+
self.custom_attribute_types = {}
|
112
|
+
|
74
113
|
mattr_accessor :search_engine
|
75
114
|
self.search_engine = Fiona7::VeritySearchEngine
|
76
115
|
|
@@ -6,10 +6,11 @@ module Fiona7
|
|
6
6
|
end
|
7
7
|
|
8
8
|
require 'fiona7/assert'
|
9
|
-
require 'fiona7/link_converter/fiona_to_scrivito'
|
10
9
|
require 'fiona7/json/widget_decorator'
|
11
10
|
require 'fiona7/widget_resolver'
|
12
|
-
require 'fiona7/
|
11
|
+
require 'fiona7/prefetch/obj_prefetch'
|
12
|
+
|
13
|
+
require 'fiona7/attribute_readers/factory'
|
13
14
|
|
14
15
|
module Fiona7
|
15
16
|
module JSON
|
@@ -18,12 +19,10 @@ module Fiona7
|
|
18
19
|
@klass = klass
|
19
20
|
@obj = obj
|
20
21
|
|
21
|
-
@link_converter = LinkConverter::FionaToScrivito.new(obj)
|
22
|
-
|
23
22
|
if widget_resolver
|
24
23
|
@widget_resolver = widget_resolver
|
25
24
|
elsif (widget_links = @obj.attr_values["X_widget_pool"])
|
26
|
-
@widget_resolver = WidgetResolver.new(widget_links,
|
25
|
+
@widget_resolver = WidgetResolver.new(widget_links, Prefetch::ObjPrefetch.new(klass))
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
@@ -58,137 +57,46 @@ module Fiona7
|
|
58
57
|
|
59
58
|
def add_custom_attributes(attrs, *args)
|
60
59
|
type_definition = Fiona7::TypeRegister.instance.read_mangled(@obj.obj_class)
|
60
|
+
factory = Fiona7::AttributeReaders::Factory.new(@obj, type_definition, @widget_resolver)
|
61
|
+
|
61
62
|
type_definition.attrs.each do |attribute|
|
62
63
|
virtual_attribute_name = attribute.name
|
63
64
|
real_attribute_name = attribute.real_name
|
64
65
|
virtual_attribute_type = attribute.type.to_sym
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
when :html
|
87
|
-
deserialize_html(@obj[real_attribute_name])
|
88
|
-
when :markdown
|
89
|
-
nil
|
90
|
-
when :binary
|
91
|
-
if !Fiona7.mode == :legacy || !@obj.binary?
|
92
|
-
deserialize_binary(@obj.attr_values[real_attribute_name].try(:first))
|
93
|
-
else
|
94
|
-
{id: Fiona7::BlobIdGenerator.new(@obj.id, @obj.last_changed).call}
|
95
|
-
end
|
96
|
-
when :enum, :multienum, :text, :string
|
97
|
-
if real_attribute_name == "suppress_export"
|
98
|
-
@obj[real_attribute_name].to_s
|
99
|
-
else
|
100
|
-
@obj[real_attribute_name]
|
101
|
-
end
|
102
|
-
when :number
|
103
|
-
@obj[real_attribute_name].to_f
|
104
|
-
when :stringlist
|
105
|
-
if Fiona7.mode == :legacy && real_attribute_name == "channels"
|
106
|
-
@obj["channels"] || []
|
107
|
-
else
|
108
|
-
# TODO: get rid of this rescue nil
|
109
|
-
::JSON.parse(@obj[real_attribute_name]) rescue nil
|
110
|
-
end
|
66
|
+
# This is probably the most important line in this whole class.
|
67
|
+
# An intuitive way of reading the real attribute type
|
68
|
+
# would be to just look-up in the attribute definition.
|
69
|
+
#
|
70
|
+
# But this approach is wrong. Consider the following case:
|
71
|
+
# An attribute :child_order is created with real type :linklist
|
72
|
+
# This proves problematic (because of the unwanted links in CMS)
|
73
|
+
# and is later changed to :text. But the CMS still contains
|
74
|
+
# "old" objects with :child_order modelled as :linklist.
|
75
|
+
# Therefore we must lookup the correct typing in the attribute itself.
|
76
|
+
#
|
77
|
+
# It is also possible that the obj does not have any content for the
|
78
|
+
# attribute. In this case we just use the type provided by
|
79
|
+
# the type definition.
|
80
|
+
real_attribute_type = ((@obj.attr_dict.send(:attr_defs) || {})[real_attribute_name.to_s]||{})["type"] ||
|
81
|
+
attribute.real_type
|
82
|
+
|
83
|
+
worker = factory.call(real_attribute_name, virtual_attribute_type, real_attribute_type)
|
84
|
+
if worker.nil?
|
85
|
+
Rails.logger.error("Unable to deserialize #{virtual_attribute_name} in #{type_definition.name}")
|
86
|
+
val = nil
|
111
87
|
else
|
112
|
-
|
113
|
-
false,
|
114
|
-
"Unknown attribute type #{virtual_attribute_type} for attribute: #{virtual_attribute_name}"
|
115
|
-
)
|
88
|
+
val = worker.call
|
116
89
|
end
|
117
90
|
|
118
91
|
# TODO: better handling for attribute types
|
119
92
|
if virtual_attribute_type == :text
|
120
93
|
virtual_attribute_type = :string
|
121
94
|
end
|
122
|
-
attrs[virtual_attribute_name] = [val, virtual_attribute_type]
|
123
|
-
end
|
124
|
-
end
|
125
95
|
|
126
|
-
|
127
|
-
if link
|
128
|
-
deserialized = {
|
129
|
-
# remove possible external prefix for protcol-less urls
|
130
|
-
url: link["url"].try(:gsub, /\Aexternal:/, ''),
|
131
|
-
title: link["title"],
|
132
|
-
target: link["target"],
|
133
|
-
# content service uses destination
|
134
|
-
destination: link["destination"].to_s,
|
135
|
-
# rest api uses obj_id
|
136
|
-
obj_id: link["destination"].to_s,
|
137
|
-
query: link["search"],
|
138
|
-
fragment: link["fragment"]
|
139
|
-
}
|
140
|
-
|
141
|
-
# TODO: refactor this code
|
142
|
-
if deserialized[:url].present?
|
143
|
-
deserialized.delete(:destination)
|
144
|
-
deserialized.delete(:obj_id)
|
145
|
-
end
|
146
|
-
|
147
|
-
deserialized
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def deserialize_reference(link)
|
152
|
-
if link && link["type"] == "internal"
|
153
|
-
link["destination"].to_s
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def deserialize_widget_field(linklist)
|
158
|
-
if !linklist.empty?
|
159
|
-
widget_ids = []
|
160
|
-
widgets = linklist.map do |link|
|
161
|
-
widget_id = link["title"]
|
162
|
-
# sometimes a released page references an unreleased widget
|
163
|
-
# it is then impossible to load it into widget_pool
|
164
|
-
# but the reference in the widgetlist field is still there
|
165
|
-
# therefore we need to check if the widget has been loaded
|
166
|
-
# into the pool - only then it can be included
|
167
|
-
if valid_widget_id?(widget_id)
|
168
|
-
widget_ids << widget_id
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
widget_ids
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
def deserialize_html(html)
|
177
|
-
@link_converter.convert(html)
|
178
|
-
end
|
179
|
-
|
180
|
-
def deserialize_binary(link)
|
181
|
-
if link
|
182
|
-
binary_id = link["title"]
|
183
|
-
if binary_id.length == 32 && binary_id =~ /0{16,}0*[0-9]+/
|
184
|
-
{id: binary_id}
|
185
|
-
end
|
96
|
+
attrs[virtual_attribute_name] = [val, virtual_attribute_type]
|
186
97
|
end
|
187
98
|
end
|
188
99
|
|
189
|
-
def valid_widget_id?(widget_id)
|
190
|
-
@widget_resolver && @widget_resolver.path_map[widget_id]
|
191
|
-
end
|
192
100
|
|
193
101
|
def replace_widget_pool(attrs, *args)
|
194
102
|
if (widget_links = @obj.attr_values["X_widget_pool"]) && @widget_resolver
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Fiona7
|
4
|
+
module Prefetch
|
5
|
+
class ObjPrefetch
|
6
|
+
def initialize(klass, prefetch_ids=[])
|
7
|
+
self.klass = klass
|
8
|
+
self.prefetched_ids = Set.new
|
9
|
+
self.object_id_map = {}
|
10
|
+
|
11
|
+
self.prefetch_objects(prefetch_ids)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns an object with given ID or nil if no matching object found
|
15
|
+
def find_one(id)
|
16
|
+
self.find_many([id]).first
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns an array with objects for given IDs.
|
20
|
+
# The array is ordered according to the IDs given.
|
21
|
+
# For missing objects the array is filled with nil values
|
22
|
+
def find_many(ids)
|
23
|
+
self.prefetch_objects(ids)
|
24
|
+
ids.map { |id| self.object_id_map[id.to_i] }
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
attr_accessor :klass, :prefetched_ids, :object_id_map
|
29
|
+
|
30
|
+
def prefetch_objects(prefetch_ids)
|
31
|
+
missing = prefetch_ids.select {|id| !self.prefetched_ids.include?(id) }
|
32
|
+
|
33
|
+
return if missing.empty?
|
34
|
+
|
35
|
+
self.klass.where(obj_id: missing).each do |obj|
|
36
|
+
self.prefetched_ids << obj.id
|
37
|
+
self.object_id_map[obj.id] = obj
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'fiona7/prefetch/obj_prefetch'
|
2
|
+
require 'fiona7/widget_resolver'
|
3
|
+
|
4
|
+
module Fiona7
|
5
|
+
module Prefetch
|
6
|
+
class WidgetResolverPrefetch
|
7
|
+
def initialize(klass, objects=[])
|
8
|
+
widget_object_ids = self.collect_widget_object_ids(objects)
|
9
|
+
|
10
|
+
self.obj_prefetch = ObjPrefetch.new(klass, widget_object_ids)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns a widget resolver for given object.
|
14
|
+
# If the object is already known to the prefetcher,
|
15
|
+
# then widgets will be loaded from memory,
|
16
|
+
# instead of database.
|
17
|
+
def widget_resolver(object)
|
18
|
+
WidgetResolver.new(
|
19
|
+
object.attr_values["X_widget_pool"]||[],
|
20
|
+
self.obj_prefetch
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
attr_accessor :obj_prefetch
|
26
|
+
|
27
|
+
def collect_widget_object_ids(objects)
|
28
|
+
objects.map do |object|
|
29
|
+
(object.attr_values["X_widget_pool"]||[]).map do |widget_hash|
|
30
|
+
widget_hash["destination"].try(:to_i)
|
31
|
+
end
|
32
|
+
end.flatten.compact
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'scrivito/date_attribute'
|
2
|
+
|
3
|
+
module Scrivito
|
4
|
+
module DateAttribute
|
5
|
+
def self.deserialize_from_backend(iso_date_time)
|
6
|
+
return nil unless iso_date_time
|
7
|
+
#return nil if iso_date.to_s.blank?
|
8
|
+
|
9
|
+
if iso_date_time.to_s =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/
|
10
|
+
Time.utc($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i).in_time_zone
|
11
|
+
else
|
12
|
+
raise "The value is not a valid ISO date time: #{iso_date_time.inspect}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'fiona7/obj_class_name_mangler'
|
2
|
+
require 'fiona7/attribute_name_mangler'
|
3
|
+
|
4
|
+
module Fiona7
|
5
|
+
module Tools
|
6
|
+
# This class is used to remove attributes from obj classes.
|
7
|
+
# Normally it is not required, because the user can just
|
8
|
+
# remove an attribute from the model definition and the
|
9
|
+
# attribute becomes invisible.
|
10
|
+
# The attribute still persists, but becomes inaccessible.
|
11
|
+
#
|
12
|
+
# In some cases it may be required to garbage collect
|
13
|
+
# the removed attribute, for example to change the type
|
14
|
+
# of an attribute, the attribute has to be removed first.
|
15
|
+
#
|
16
|
+
# This class behaves differently for different configrations.
|
17
|
+
# In standalone mode the attribute is removed from
|
18
|
+
# the specified obj class and also from CMS.
|
19
|
+
# In legacy mode the attribute is removed from
|
20
|
+
# the specified obj class. If there are no more obj classes
|
21
|
+
# referencing this attribute, it also gets deleted from CMS.
|
22
|
+
class AttributeRemover
|
23
|
+
def initialize(obj_class, attr_name)
|
24
|
+
self.obj_class = ObjClassNameMangler.new(obj_class).mangle
|
25
|
+
self.attr_name = AttributeNameMangler.new(attr_name, obj_class).mangle
|
26
|
+
|
27
|
+
self.original_attr_name = attr_name
|
28
|
+
self.original_obj_class = obj_class
|
29
|
+
end
|
30
|
+
|
31
|
+
def remove
|
32
|
+
if rc_attr = RailsConnector::Attribute.find_by_attribute_name(self.attr_name)
|
33
|
+
# fetch the names of all obj classes referencing this attribute
|
34
|
+
obj_classes = rc_attr.obj_class_defs.map(&:name)
|
35
|
+
if obj_classes.include?(self.obj_class)
|
36
|
+
cm_obj_class = Reactor::Cm::ObjClass.get(self.obj_class)
|
37
|
+
# this removes the attribute from the obj class
|
38
|
+
cm_obj_class.attributes = (cm_obj_class.attributes - [self.attr_name])
|
39
|
+
# flush reactor cache
|
40
|
+
RailsConnector::Meta::EagerLoader.instance.forget_obj_class(self.obj_class)
|
41
|
+
# flush type register caches
|
42
|
+
Fiona7::TypeRegister.instance.send(:load, self.original_obj_class)
|
43
|
+
if typedef = Fiona7::TypeRegister.instance.usr_defs[self.original_obj_class]
|
44
|
+
# There is a very subtle bug hidden here:
|
45
|
+
# If you have an enum or multienum attribute, remove it and
|
46
|
+
# trigger synchronize (via write request) it will be created
|
47
|
+
# as string or text.
|
48
|
+
#
|
49
|
+
# Easiest way to prevent this bug is to restart the app
|
50
|
+
# between the requests.
|
51
|
+
typedef.remove_attribute(self.original_attr_name)
|
52
|
+
end
|
53
|
+
# one reference less!
|
54
|
+
obj_classes.delete(self.obj_class)
|
55
|
+
end
|
56
|
+
|
57
|
+
# NOTE: this will always be true in standlone mode
|
58
|
+
if obj_classes.empty?
|
59
|
+
# attribute can be garbage collected
|
60
|
+
cm_attr = Reactor::Cm::Attribute.get(self.attr_name)
|
61
|
+
cm_attr.delete!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
attr_accessor :obj_class, :attr_name, :original_obj_class, :original_attr_name
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|