foobara 0.0.142 → 0.1.2
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/.ruby-version +1 -1
- data/CHANGELOG.md +25 -0
- data/projects/builtin_types/lib/foobara/builtin_types.rb +1 -0
- data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_defaults_from_element_types_to_root.rb +9 -2
- data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/desugarizers/symbolize_defaults.rb +1 -1
- data/projects/builtin_types/src/attributes/supported_transformers/defaults/type_declaration_extension/extend_attributes_type_declaration/type_declaration_validators/hash_with_symbolic_keys.rb +1 -1
- data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/desugarizers/alphabetize_required.rb +5 -5
- data/projects/builtin_types/src/attributes/supported_validators/required/type_declaration_extension/extend_attributes_type_declaration/desugarizers/move_required_from_element_types_to_root.rb +12 -2
- data/projects/builtin_types/src/builtin_types.rb +1 -1
- data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_desugarizer.rb +10 -2
- data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/class_type_desugarizer.rb +7 -2
- data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_class_desugarizer.rb +3 -4
- data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/instance_of_symbol_desugarizer.rb +3 -4
- data/projects/builtin_types/src/duck/supported_validators/instance_of/type_declaration_extension/extend_registered_type_declaration/type_declaration_validators/is_valid_class.rb +1 -1
- data/projects/builtin_types/src/duck/supported_validators/instance_of.rb +1 -0
- data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/cast_one_of.rb +4 -3
- data/projects/builtin_types/src/duck/supported_validators/one_of/type_declaration_extension/extend_registered_type_declaration/desugarizers/module_desugarizer.rb +3 -3
- data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/desugarizers/set_size.rb +1 -1
- data/projects/builtin_types/src/tuple/supported_processors/element_type_declarations/type_declaration_extension/extend_tuple_type_declaration/type_declaration_validators/size_matches.rb +2 -4
- data/projects/command/src/command_pattern_implementation/concerns/inputs_type.rb +12 -12
- data/projects/command/src/command_pattern_implementation/concerns/reflection.rb +4 -2
- data/projects/command/src/command_pattern_implementation/concerns/result_type.rb +0 -4
- data/projects/command_connectors/src/command_connector.rb +41 -16
- data/projects/command_connectors/src/command_registry.rb +7 -4
- data/projects/command_connectors/src/transformed_command.rb +55 -43
- data/projects/command_connectors/src/transformers/auth_errors_transformer.rb +1 -0
- data/projects/command_connectors/src/transformers/entity_to_primary_key_inputs_transformer.rb +4 -0
- data/projects/common/src/possible_error.rb +27 -21
- data/projects/detached_entity/src/concerns/types.rb +7 -1
- data/projects/detached_entity/src/detached_entity_type.rb +10 -0
- data/projects/detached_entity/src/extensions/builtin_types/detached_entity/validators/model_instance_is_valid.rb +1 -1
- data/projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/hash_desugarizer.rb +6 -9
- data/projects/detached_entity/src/extensions/type_declarations/handlers/extend_detached_entity_type_declaration/primary_key_desugarizer.rb +2 -1
- data/projects/domain/src/domain_module_extension.rb +12 -4
- data/projects/domain/src/is_manifestable.rb +19 -7
- data/projects/entity/src/concerns/types.rb +6 -1
- data/projects/foobara/lib/foobara/all.rb +4 -4
- data/projects/manifest/src/foobara/manifest/type.rb +11 -2
- data/projects/manifest/src/foobara/manifest/type_declaration.rb +46 -2
- data/projects/model/src/concerns/aliases.rb +8 -0
- data/projects/model/src/concerns/reflection.rb +2 -2
- data/projects/model/src/concerns/types.rb +35 -20
- data/projects/model/src/extensions/builtin_types/model/validators/model_instance_is_valid.rb +12 -8
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/array_with_symbolic_elements.rb +1 -1
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/attributes_handler_desugarizer.rb +15 -1
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/delegates_desugarizer.rb +7 -5
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/hash_desugarizer.rb +4 -7
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/model_class_desugarizer.rb +0 -2
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/move_private_from_element_types_to_root.rb +28 -9
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/symbolize_private.rb +8 -7
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration/to_type_transformer.rb +4 -7
- data/projects/model/src/extensions/type_declarations/handlers/extend_model_type_declaration.rb +14 -2
- data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/hash_desugarizer.rb +8 -9
- data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/model_class_type_desugarizer.rb +6 -2
- data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/mutable_validator.rb +5 -2
- data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/normalize_mutable_attributes_desugarizer.rb +8 -7
- data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration/to_type_transformer.rb +4 -1
- data/projects/model/src/extensions/type_declarations/handlers/extend_registered_model_type_declaration.rb +20 -5
- data/projects/model/src/extensions/type_declarations/handlers/registered_type_declaration/model_class_desugarizer.rb +23 -5
- data/projects/model/src/extensions/type_declarations/lazy_element_types/model.rb +18 -0
- data/projects/model_attribute_helpers/src/attribute_helpers.rb +44 -26
- data/projects/namespace/src/is_namespace.rb +58 -90
- data/projects/namespace/src/namespace/lookup_mode.rb +13 -2
- data/projects/namespace/src/namespace_helpers.rb +1 -0
- data/projects/namespace/src/prefixless_registry.rb +2 -0
- data/projects/persistence/src/entity_base/transaction/concerns/state_transitions.rb +20 -1
- data/projects/persistence/src/entity_base/transaction.rb +14 -11
- data/projects/persistence/src/entity_base/transaction_table.rb +10 -49
- data/projects/persistence/src/entity_base.rb +39 -0
- data/projects/persistence/src/persistence.rb +4 -0
- data/projects/type_declarations/src/attributes.rb +15 -9
- data/projects/type_declarations/src/attributes_transformers/from_yaml.rb +1 -1
- data/projects/type_declarations/src/desugarizer_pipeline.rb +9 -0
- data/projects/type_declarations/src/dsl/attributes.rb +14 -5
- data/projects/type_declarations/src/handlers/extend_array_type_declaration/array_desugarizer.rb +24 -4
- data/projects/type_declarations/src/handlers/extend_array_type_declaration/element_type_declaration_desugarizer.rb +23 -9
- data/projects/type_declarations/src/handlers/extend_array_type_declaration/to_type_transformer.rb +3 -7
- data/projects/type_declarations/src/handlers/extend_array_type_declaration/type_set_to_array_desugarizer.rb +15 -4
- data/projects/type_declarations/src/handlers/extend_array_type_declaration.rb +12 -2
- data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/key_type_declaration_desugarizer.rb +48 -0
- data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/to_type_transformer.rb +3 -11
- data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration/value_type_declaration_desugarizer.rb +51 -0
- data/projects/type_declarations/src/handlers/extend_associative_array_type_declaration.rb +12 -2
- data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/dsl_desugarizer.rb +1 -1
- data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/element_type_declarations_desugarizer.rb +17 -7
- data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/hash_desugarizer.rb +16 -19
- data/projects/type_declarations/src/handlers/extend_attributes_type_declaration/to_type_transformer.rb +3 -6
- data/projects/type_declarations/src/handlers/extend_attributes_type_declaration.rb +13 -2
- data/projects/type_declarations/src/handlers/extend_registered_type_declaration/to_type_transformer.rb +3 -3
- data/projects/type_declarations/src/handlers/extend_registered_type_declaration.rb +16 -4
- data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/array_desugarizer.rb +20 -6
- data/projects/type_declarations/src/handlers/extend_tuple_type_declaration/to_type_transformer.rb +3 -9
- data/projects/type_declarations/src/handlers/extend_tuple_type_declaration.rb +12 -2
- data/projects/type_declarations/src/handlers/registered_type_declaration/to_type_transformer.rb +7 -9
- data/projects/type_declarations/src/handlers/registered_type_declaration.rb +22 -7
- data/projects/type_declarations/src/lazy_element_types/array.rb +19 -0
- data/projects/type_declarations/src/lazy_element_types/attributes.rb +27 -0
- data/projects/type_declarations/src/lazy_element_types/hash.rb +38 -0
- data/projects/type_declarations/src/lazy_element_types/tuple.rb +23 -0
- data/projects/type_declarations/src/sensitive_type_remover.rb +6 -1
- data/projects/type_declarations/src/sensitive_type_removers/attributes.rb +2 -0
- data/projects/type_declarations/src/type_builder.rb +46 -21
- data/projects/type_declarations/src/type_declaration.rb +295 -0
- data/projects/type_declarations/src/type_declaration_handler.rb +10 -11
- data/projects/type_declarations/src/type_declarations.rb +18 -88
- data/projects/types/src/type.rb +34 -9
- data/projects/value/src/mutator.rb +1 -4
- data/projects/value/src/processor/casting.rb +7 -2
- data/projects/value/src/processor/pipeline.rb +9 -1
- data/projects/value/src/processor.rb +0 -8
- data/projects/value/src/transformer.rb +1 -3
- data/projects/value/src/validator.rb +0 -2
- data/projects/weak_object_set/src/weak_object_set.rb +2 -0
- metadata +11 -8
- data/projects/type_declarations/src/handlers/registered_type_declaration/desugarizer_metadata_cleanup_desugarizer.rb +0 -29
- data/projects/type_declarations/src/handlers/registered_type_declaration/short_type_name_desugarizer.rb +0 -62
- data/projects/type_declarations/src/handlers/registered_type_declaration/strict_desugarizer.rb +0 -32
- data/projects/type_declarations/src/handlers/registered_type_declaration/strict_stringified_desugarizer.rb +0 -39
- data/projects/type_declarations/src/handlers/registered_type_declaration/symbol_desugarizer.rb +0 -30
- data/projects/type_declarations/src/handlers/registered_type_declaration/type_desugarizer.rb +0 -24
@@ -54,7 +54,7 @@ module Foobara
|
|
54
54
|
end
|
55
55
|
|
56
56
|
unless include_delegates
|
57
|
-
declaration = Foobara::TypeDeclarations::Attributes.reject(declaration, *
|
57
|
+
declaration = Foobara::TypeDeclarations::Attributes.reject(declaration, *foobara_delegates.keys)
|
58
58
|
end
|
59
59
|
|
60
60
|
Domain.current.foobara_type_from_declaration(declaration)
|
@@ -80,9 +80,11 @@ module Foobara
|
|
80
80
|
if type.extends?(BuiltinTypes[:entity])
|
81
81
|
target_class = type.target_class
|
82
82
|
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
set_foobara_type_declaration_value_at(
|
84
|
+
declaration,
|
85
|
+
DataPath.new(data_path).path,
|
86
|
+
target_class.foobara_attributes_for_aggregate_update(initial: false)
|
87
|
+
)
|
86
88
|
end
|
87
89
|
end
|
88
90
|
|
@@ -111,9 +113,12 @@ module Foobara
|
|
111
113
|
# TODO: do we really need declaration_data? Why cant we use the type directly?
|
112
114
|
# TODO: make this work with the type directly for performance reasons.
|
113
115
|
primary_key_type_declaration = target_class.foobara_primary_key_type.declaration_data
|
114
|
-
|
115
|
-
|
116
|
-
|
116
|
+
|
117
|
+
set_foobara_type_declaration_value_at(
|
118
|
+
declaration,
|
119
|
+
DataPath.new(data_path).path,
|
120
|
+
primary_key_type_declaration
|
121
|
+
)
|
117
122
|
end
|
118
123
|
end
|
119
124
|
|
@@ -131,31 +136,44 @@ module Foobara
|
|
131
136
|
TypeDeclarations::Handlers::ExtendAttributesTypeDeclaration
|
132
137
|
)
|
133
138
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
139
|
+
declaration = TypeDeclaration.new(type: :attributes, element_type_declarations:)
|
140
|
+
declaration.is_absolutified = true
|
141
|
+
declaration.is_duped = true
|
142
|
+
|
143
|
+
handler.desugarize(declaration).declaration_data
|
138
144
|
end
|
139
145
|
|
140
146
|
private
|
141
147
|
|
142
|
-
def
|
143
|
-
return declaration if path_parts.empty?
|
144
|
-
|
148
|
+
def set_foobara_type_declaration_value_at(declaration, path_parts, value)
|
145
149
|
path_part, *path_parts = path_parts
|
146
150
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
151
|
+
case path_part
|
152
|
+
when :"#"
|
153
|
+
if path_parts.empty?
|
154
|
+
declaration[:element_type_declaration] = value
|
155
|
+
else
|
156
|
+
set_foobara_type_declaration_value_at(
|
157
|
+
declaration[:element_type_declaration],
|
158
|
+
path_parts,
|
159
|
+
value
|
160
|
+
)
|
161
|
+
end
|
162
|
+
when Symbol, Integer
|
163
|
+
if path_parts.empty?
|
164
|
+
declaration[:element_type_declarations][path_part] = value
|
165
|
+
else
|
166
|
+
set_foobara_type_declaration_value_at(
|
167
|
+
declaration[:element_type_declarations][path_part],
|
168
|
+
path_parts,
|
169
|
+
value
|
170
|
+
)
|
171
|
+
end
|
172
|
+
else
|
173
|
+
# :nocov:
|
174
|
+
raise "Bad path part #{path_part}"
|
175
|
+
# :nocov:
|
176
|
+
end
|
159
177
|
end
|
160
178
|
end
|
161
179
|
end
|
@@ -98,9 +98,12 @@ module Foobara
|
|
98
98
|
scopedish
|
99
99
|
end
|
100
100
|
|
101
|
+
# TODO: make this thread-safe
|
101
102
|
def foobara_register(scoped)
|
102
103
|
foobara_registry.register(scoped)
|
103
104
|
|
105
|
+
# TODO: do we really need to clear the whole cache? Why not just the possible
|
106
|
+
# impacted keys based on scoped.scoped_path ?
|
104
107
|
IsNamespace.clear_lru_cache!
|
105
108
|
# awkward??
|
106
109
|
scoped.scoped_namespace = self
|
@@ -134,48 +137,29 @@ module Foobara
|
|
134
137
|
IsNamespace.lru_cache
|
135
138
|
end
|
136
139
|
|
137
|
-
def foobara_lookup(
|
138
|
-
|
139
|
-
filter: nil,
|
140
|
-
mode: LookupMode::GENERAL,
|
141
|
-
visited: nil,
|
142
|
-
initial: true
|
143
|
-
)
|
144
|
-
# TODO: make it so this is only necessary when initial
|
140
|
+
def foobara_lookup(path, filter: nil, mode: LookupMode::GENERAL)
|
141
|
+
LookupMode.validate!(mode)
|
145
142
|
path = Namespace.to_registry_path(path)
|
146
|
-
visited_key = [path, mode, initial, self]
|
147
143
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
return value if found
|
144
|
+
lru_cache.cached([path, mode, self, filter]) do
|
145
|
+
visited = Set.new
|
146
|
+
foobara_lookup_without_cache(path, filter:, mode:, visited:)
|
152
147
|
end
|
148
|
+
end
|
153
149
|
|
154
|
-
|
150
|
+
def foobara_lookup_without_cache(path, filter:, mode:, visited:)
|
151
|
+
visited_key = [path, mode, self]
|
152
|
+
return nil if visited.include?(visited_key)
|
155
153
|
|
156
|
-
visited ||= Set.new
|
157
154
|
visited << visited_key
|
158
155
|
|
159
|
-
LookupMode.validate!(mode)
|
160
|
-
|
161
156
|
if mode == LookupMode::RELAXED
|
162
|
-
scoped =
|
163
|
-
path,
|
164
|
-
filter:,
|
165
|
-
mode: LookupMode::GENERAL,
|
166
|
-
visited:,
|
167
|
-
initial: false
|
168
|
-
)
|
169
|
-
if scoped
|
170
|
-
if initial
|
171
|
-
lru_cache.set_if_missing(lru_key, scoped)
|
172
|
-
end
|
157
|
+
scoped = foobara_lookup_without_cache(path, filter:, mode: LookupMode::GENERAL, visited:)
|
173
158
|
|
174
|
-
|
175
|
-
end
|
159
|
+
return scoped if scoped
|
176
160
|
|
177
161
|
candidates = foobara_children.map do |namespace|
|
178
|
-
namespace.
|
162
|
+
namespace.foobara_lookup_without_cache(path, filter:, mode:, visited:)
|
179
163
|
end.compact
|
180
164
|
|
181
165
|
if candidates.size > 1
|
@@ -186,11 +170,7 @@ module Foobara
|
|
186
170
|
end
|
187
171
|
|
188
172
|
scoped = candidates.first ||
|
189
|
-
foobara_parent_namespace&.
|
190
|
-
|
191
|
-
if initial
|
192
|
-
lru_cache.set_if_missing(lru_key, scoped)
|
193
|
-
end
|
173
|
+
foobara_parent_namespace&.foobara_lookup_without_cache(path, filter:, mode:, visited:)
|
194
174
|
|
195
175
|
return scoped
|
196
176
|
end
|
@@ -204,25 +184,41 @@ module Foobara
|
|
204
184
|
path = path[(foobara_root_namespace.scoped_path.size + 1)..]
|
205
185
|
end
|
206
186
|
|
207
|
-
return
|
187
|
+
return foobara_lookup_without_cache(path, filter:, mode: LookupMode::ABSOLUTE, visited:)
|
188
|
+
end
|
189
|
+
|
190
|
+
root = foobara_root_namespace
|
191
|
+
|
192
|
+
if mode == LookupMode::ABSOLUTE
|
193
|
+
[
|
194
|
+
root,
|
195
|
+
*root.foobara_depends_on_namespaces.map(&:foobara_root_namespace)
|
196
|
+
].uniq.each do |namespace|
|
197
|
+
scoped = namespace.foobara_lookup_without_cache(path,
|
198
|
+
filter:,
|
199
|
+
mode: LookupMode::CHILDREN_ONLY,
|
200
|
+
visited:)
|
201
|
+
return scoped if scoped
|
202
|
+
end
|
203
|
+
|
204
|
+
return nil
|
205
|
+
end
|
206
|
+
|
207
|
+
if mode == LookupMode::ABSOLUTE_SINGLE_NAMESPACE
|
208
|
+
return foobara_root_namespace.foobara_lookup_without_cache(path,
|
209
|
+
filter:,
|
210
|
+
mode: LookupMode::CHILDREN_ONLY,
|
211
|
+
visited:)
|
208
212
|
end
|
209
213
|
|
210
214
|
partial = foobara_registry.lookup(path, filter)
|
211
215
|
|
212
216
|
if mode == LookupMode::DIRECT
|
213
|
-
if initial
|
214
|
-
lru_cache.set_if_missing(lru_key, partial)
|
215
|
-
end
|
216
|
-
|
217
217
|
return partial
|
218
218
|
end
|
219
219
|
|
220
220
|
if partial
|
221
221
|
if partial.scoped_path == path
|
222
|
-
if initial
|
223
|
-
lru_cache.set_if_missing(lru_key, partial)
|
224
|
-
end
|
225
|
-
|
226
222
|
return partial
|
227
223
|
end
|
228
224
|
end
|
@@ -236,23 +232,15 @@ module Foobara
|
|
236
232
|
scoped = _lookup_in(path, to_consider, filter:, visited:)
|
237
233
|
|
238
234
|
if scoped
|
239
|
-
if initial
|
240
|
-
lru_cache.set_if_missing(lru_key, scoped)
|
241
|
-
end
|
242
|
-
|
243
235
|
return scoped
|
244
236
|
end
|
245
237
|
|
246
|
-
if
|
247
|
-
scoped = foobara_parent_namespace.
|
248
|
-
path, filter:, mode: LookupMode::STRICT, visited
|
238
|
+
if (mode == LookupMode::GENERAL || mode == LookupMode::STRICT) && foobara_parent_namespace
|
239
|
+
scoped = foobara_parent_namespace.foobara_lookup_without_cache(
|
240
|
+
path, filter:, mode: LookupMode::STRICT, visited:
|
249
241
|
)
|
250
242
|
|
251
243
|
if scoped
|
252
|
-
if initial
|
253
|
-
lru_cache.set_if_missing(lru_key, scoped)
|
254
|
-
end
|
255
|
-
|
256
244
|
return scoped
|
257
245
|
end
|
258
246
|
end
|
@@ -261,10 +249,6 @@ module Foobara
|
|
261
249
|
scoped = _lookup_in(path, foobara_depends_on_namespaces, filter:, visited:)
|
262
250
|
|
263
251
|
if scoped
|
264
|
-
if initial
|
265
|
-
lru_cache.set_if_missing(lru_key, scoped)
|
266
|
-
end
|
267
|
-
|
268
252
|
return scoped
|
269
253
|
end
|
270
254
|
end
|
@@ -277,7 +261,7 @@ module Foobara
|
|
277
261
|
end
|
278
262
|
|
279
263
|
candidates = to_consider.map do |namespace|
|
280
|
-
namespace.
|
264
|
+
namespace.foobara_lookup_without_cache(path, filter:, mode:, visited:)
|
281
265
|
end.compact
|
282
266
|
|
283
267
|
if candidates.size > 1
|
@@ -286,27 +270,7 @@ module Foobara
|
|
286
270
|
# :nocov:
|
287
271
|
end
|
288
272
|
|
289
|
-
|
290
|
-
|
291
|
-
if scoped
|
292
|
-
if initial
|
293
|
-
lru_cache.set_if_missing(lru_key, scoped)
|
294
|
-
end
|
295
|
-
|
296
|
-
return scoped
|
297
|
-
end
|
298
|
-
|
299
|
-
# As a last resort we'll see if we're trying to fetch a builtin type from a different namespace
|
300
|
-
# TODO: these lookup modes are really confusing and were designed prior to having multiple root
|
301
|
-
# namespaces playing a role in command connectors.
|
302
|
-
if initial
|
303
|
-
scoped = Namespace.global.foobara_lookup(path, filter:, mode: LookupMode::ABSOLUTE, visited:, initial: false)
|
304
|
-
|
305
|
-
if scoped.is_a?(Types::Type) && scoped.builtin?
|
306
|
-
lru_cache.set_if_missing(lru_key, scoped)
|
307
|
-
scoped
|
308
|
-
end
|
309
|
-
end
|
273
|
+
candidates.first || partial
|
310
274
|
end
|
311
275
|
|
312
276
|
def foobara_parent_namespace
|
@@ -328,9 +292,10 @@ module Foobara
|
|
328
292
|
def foobara_each(filter: nil, mode: Namespace::LookupMode::GENERAL, &)
|
329
293
|
foobara_registry.each_scoped(filter:, &)
|
330
294
|
|
331
|
-
|
332
|
-
|
333
|
-
|
295
|
+
if mode == LookupMode::GENERAL ||
|
296
|
+
mode == LookupMode::CHILDREN_ONLY ||
|
297
|
+
mode == LookupMode::ABSOLUTE ||
|
298
|
+
mode == LookupMode::ABSOLUTE_SINGLE_NAMESPACE
|
334
299
|
foobara_children.each do |child|
|
335
300
|
child.foobara_each(filter:, mode:, &)
|
336
301
|
end
|
@@ -414,6 +379,10 @@ module Foobara
|
|
414
379
|
Foobara::Namespace::UnambiguousRegistry
|
415
380
|
when Foobara::Namespace::BaseRegistry::WouldMakeRegistryAmbiguousError
|
416
381
|
Foobara::Namespace::AmbiguousRegistry
|
382
|
+
else
|
383
|
+
# :nocov:
|
384
|
+
raise ArgumentError, "Not sure how to upgrade a #{error.class}"
|
385
|
+
# :nocov:
|
417
386
|
end
|
418
387
|
|
419
388
|
old_registry = foobara_registry
|
@@ -442,19 +411,18 @@ module Foobara
|
|
442
411
|
end
|
443
412
|
|
444
413
|
matching_children.sort_by(&:first).reverse.each do |(matching_child_score, matching_child)|
|
445
|
-
scoped = matching_child.
|
414
|
+
scoped = matching_child.foobara_lookup_without_cache(
|
446
415
|
path[matching_child_score..],
|
447
|
-
mode: LookupMode::
|
416
|
+
mode: LookupMode::CHILDREN_ONLY,
|
448
417
|
filter:,
|
449
|
-
visited
|
450
|
-
initial: false
|
418
|
+
visited:
|
451
419
|
)
|
452
420
|
|
453
421
|
return scoped if scoped
|
454
422
|
end
|
455
423
|
|
456
424
|
last_resort.uniq.each do |namespace|
|
457
|
-
scoped = namespace.
|
425
|
+
scoped = namespace.foobara_lookup_without_cache(path, filter:, mode: LookupMode::CHILDREN_ONLY, visited:)
|
458
426
|
return scoped if scoped
|
459
427
|
end
|
460
428
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Foobara
|
2
2
|
class Namespace
|
3
|
-
# TODO: need to define these better
|
3
|
+
# TODO: need to define these better/more intuitively
|
4
4
|
# use-cases
|
5
5
|
# 1. general: just general lookup. find it wherever the heck it might be
|
6
6
|
# children: y
|
@@ -17,6 +17,14 @@ module Foobara
|
|
17
17
|
# 4. absolute
|
18
18
|
# children: y
|
19
19
|
# parent: n
|
20
|
+
# dependent: y
|
21
|
+
# 5. absolute_single_namespace
|
22
|
+
# children: y
|
23
|
+
# parent: n
|
24
|
+
# dependent: n
|
25
|
+
# 6. children_only (internal use... absolute and absolute_single_namespace jump to top, children only does not)
|
26
|
+
# children: y
|
27
|
+
# parent: n
|
20
28
|
# dependent: n
|
21
29
|
# TODO: don't we have an enumerated class/project for this?
|
22
30
|
module LookupMode
|
@@ -25,7 +33,10 @@ module Foobara
|
|
25
33
|
DIRECT = :direct
|
26
34
|
STRICT = :strict
|
27
35
|
ABSOLUTE = :absolute
|
28
|
-
|
36
|
+
ABSOLUTE_SINGLE_NAMESPACE = :absolute_single_namespace
|
37
|
+
CHILDREN_ONLY = :children_only
|
38
|
+
|
39
|
+
ALL = [GENERAL, RELAXED, DIRECT, STRICT, ABSOLUTE, ABSOLUTE_SINGLE_NAMESPACE, CHILDREN_ONLY].freeze
|
29
40
|
|
30
41
|
class << self
|
31
42
|
def validate!(mode)
|
@@ -243,6 +243,7 @@ module Foobara
|
|
243
243
|
# I guess we could just iterate over all objects and patch up any with matching prefixes?
|
244
244
|
# is this expensive to have to look at all of them or no? I guess at least it's a one-time thing.
|
245
245
|
# TODO: somehow look things up by prefixes since we know mod's path
|
246
|
+
# TODO: can't there be multiple namespace roots??
|
246
247
|
Foobara.foobara_root_namespace.foobara_each do |scoped|
|
247
248
|
parent = scoped.scoped_namespace
|
248
249
|
next if parent == mod
|
@@ -80,7 +80,26 @@ module Foobara
|
|
80
80
|
|
81
81
|
# TODO: this belongs elsewhere
|
82
82
|
def each_table(&)
|
83
|
-
tables.
|
83
|
+
@ordered_tables ||= if tables.size <= 1
|
84
|
+
tables.values
|
85
|
+
else
|
86
|
+
entity_class_to_table = {}
|
87
|
+
entity_classes = []
|
88
|
+
|
89
|
+
tables.each_value do |table|
|
90
|
+
entity_class = table.entity_class
|
91
|
+
entity_classes << entity_class
|
92
|
+
entity_class_to_table[entity_class] = table
|
93
|
+
end
|
94
|
+
|
95
|
+
ordered_entity_classes = EntityBase.order_entity_classes(entity_classes)
|
96
|
+
|
97
|
+
ordered_entity_classes.map do |entity_class|
|
98
|
+
entity_class_to_table[entity_class]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
@ordered_tables.each(&)
|
84
103
|
end
|
85
104
|
|
86
105
|
def rollback!(because_of = nil)
|
@@ -62,7 +62,20 @@ module Foobara
|
|
62
62
|
# :nocov:
|
63
63
|
end
|
64
64
|
|
65
|
-
tables[entity_class]
|
65
|
+
table = tables[entity_class]
|
66
|
+
|
67
|
+
if table
|
68
|
+
table
|
69
|
+
else
|
70
|
+
if defined?(@ordered_tables)
|
71
|
+
# TODO: test this path
|
72
|
+
# :nocov:
|
73
|
+
remove_instance_variable(:@ordered_tables)
|
74
|
+
# :nocov:
|
75
|
+
end
|
76
|
+
|
77
|
+
tables[entity_class] = TransactionTable.new(self, entity_class)
|
78
|
+
end
|
66
79
|
end
|
67
80
|
|
68
81
|
def updated(record)
|
@@ -149,16 +162,6 @@ module Foobara
|
|
149
162
|
table_for(entity).track_created(entity)
|
150
163
|
end
|
151
164
|
|
152
|
-
def created?(record)
|
153
|
-
table_for(record).created?(record)
|
154
|
-
end
|
155
|
-
|
156
|
-
# WARNING! this seems to bypass validations, hmmm....
|
157
|
-
def flush_created_record!(record)
|
158
|
-
table_for(record).flush_created_record!(record)
|
159
|
-
end
|
160
|
-
|
161
|
-
# convenience method...
|
162
165
|
def perform(&)
|
163
166
|
entity_base.using_transaction(self, &)
|
164
167
|
end
|
@@ -642,11 +642,12 @@ module Foobara
|
|
642
642
|
|
643
643
|
def flush_created!
|
644
644
|
marked_created.each do |record|
|
645
|
-
flush_created_associations!(record)
|
646
|
-
|
647
645
|
# TODO: do this in bulk
|
648
646
|
attributes = entity_attributes_crud_driver_table.insert(to_persistable(record))
|
649
|
-
|
647
|
+
primary_key_attribute = entity_class.primary_key_attribute
|
648
|
+
primary_key = attributes[primary_key_attribute]
|
649
|
+
|
650
|
+
record.write_attributes_without_callbacks(primary_key_attribute => primary_key)
|
650
651
|
|
651
652
|
# we need to update finding the tracked object by key and removing/reading it seems to be the simplest
|
652
653
|
# way to accomplish that at the moment
|
@@ -660,48 +661,10 @@ module Foobara
|
|
660
661
|
marked_created.clear
|
661
662
|
end
|
662
663
|
|
663
|
-
def flush_created_record!(record)
|
664
|
-
flush_created_associations!(record)
|
665
|
-
|
666
|
-
unmark_created(record)
|
667
|
-
|
668
|
-
attributes = entity_attributes_crud_driver_table.insert(to_persistable(record))
|
669
|
-
record.write_attributes_without_callbacks(attributes)
|
670
|
-
|
671
|
-
# we need to update finding the tracked object by key and removing/reading it seems to be the simplest
|
672
|
-
# way to accomplish that at the moment
|
673
|
-
tracked(record)
|
674
|
-
|
675
|
-
record.is_persisted = record.is_loaded = true
|
676
|
-
record.is_created = false
|
677
|
-
record.save_persisted_attributes
|
678
|
-
end
|
679
|
-
|
680
|
-
def flush_created_associations!(record)
|
681
|
-
entity_class.associations.each_key do |association_data_path|
|
682
|
-
DataPath.values_at(association_data_path, record).each do |associated_record|
|
683
|
-
next unless associated_record.created?
|
684
|
-
|
685
|
-
transaction = Persistence::EntityBase::Transaction.open_transaction_for(associated_record)
|
686
|
-
|
687
|
-
unless transaction
|
688
|
-
# :nocov:
|
689
|
-
raise "No open transaction for #{associated_record}"
|
690
|
-
# :nocov:
|
691
|
-
end
|
692
|
-
|
693
|
-
if transaction.created?(associated_record)
|
694
|
-
transaction.flush_created_record!(associated_record)
|
695
|
-
end
|
696
|
-
end
|
697
|
-
end
|
698
|
-
end
|
699
|
-
|
700
664
|
def flush_updated_and_hard_deleted!
|
701
665
|
# TODO: use bulk operations to improve performance...
|
702
666
|
marked_updated.each do |record|
|
703
|
-
|
704
|
-
record.write_attributes_without_callbacks(attributes)
|
667
|
+
entity_attributes_crud_driver_table.update(to_persistable(record))
|
705
668
|
record.save_persisted_attributes
|
706
669
|
end
|
707
670
|
|
@@ -753,16 +716,14 @@ module Foobara
|
|
753
716
|
|
754
717
|
def normalize_attributes(attributes)
|
755
718
|
if attributes
|
756
|
-
|
757
|
-
attributes = attributes.transform_keys(&:to_sym)
|
719
|
+
attributes = attributes.transform_keys(&:to_sym)
|
758
720
|
|
759
|
-
|
760
|
-
|
721
|
+
primary_key_name = entity_class.primary_key_attribute
|
722
|
+
primary_key_value = attributes[primary_key_name]
|
761
723
|
|
762
|
-
|
724
|
+
attributes[primary_key_name] = entity_class.primary_key_type.cast!(primary_key_value)
|
763
725
|
|
764
|
-
|
765
|
-
end
|
726
|
+
attributes
|
766
727
|
end
|
767
728
|
end
|
768
729
|
end
|
@@ -21,6 +21,45 @@ module Foobara
|
|
21
21
|
end.call
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
def order_entity_classes(entity_classes)
|
26
|
+
return entity_classes if entity_classes.size <= 1
|
27
|
+
|
28
|
+
without_associations, with_associations = entity_classes.partition do |entity_class|
|
29
|
+
entity_class.associations.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
if with_associations.size > 1
|
33
|
+
i = 0
|
34
|
+
end_at = with_associations.size - 1
|
35
|
+
|
36
|
+
while i < end_at
|
37
|
+
entity_class = with_associations[i]
|
38
|
+
associations = entity_class.associations.values.uniq
|
39
|
+
|
40
|
+
changed = false
|
41
|
+
|
42
|
+
j = i + 1
|
43
|
+
|
44
|
+
while j <= end_at
|
45
|
+
other = with_associations[j]
|
46
|
+
|
47
|
+
if associations.include?(other.foobara_type)
|
48
|
+
with_associations[j] = entity_class
|
49
|
+
with_associations[i] = other
|
50
|
+
changed = true
|
51
|
+
break
|
52
|
+
end
|
53
|
+
|
54
|
+
j += 1
|
55
|
+
end
|
56
|
+
|
57
|
+
i += 1 unless changed
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
without_associations + with_associations
|
62
|
+
end
|
24
63
|
end
|
25
64
|
|
26
65
|
def initialize(name, entity_attributes_crud_driver:)
|
@@ -99,6 +99,10 @@ module Foobara
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def objects_to_bases(objects)
|
102
|
+
if objects.size > 1 && objects.all? { |o| o.is_a?(::Class) && o < Entity }
|
103
|
+
objects = EntityBase.order_entity_classes(objects)
|
104
|
+
end
|
105
|
+
|
102
106
|
objects.map do |object|
|
103
107
|
object_to_base(object)
|
104
108
|
end.uniq
|