Class: InventoryRefresh::InventoryCollection
- Inherits:
-
Object
- Object
- InventoryRefresh::InventoryCollection
- Defined in:
- lib/inventory_refresh/inventory_collection.rb,
lib/inventory_refresh/inventory_collection/graph.rb,
lib/inventory_refresh/inventory_collection/builder.rb,
lib/inventory_refresh/inventory_collection/helpers.rb,
lib/inventory_refresh/inventory_collection/scanner.rb,
lib/inventory_refresh/inventory_collection/reference.rb,
lib/inventory_refresh/inventory_collection/index/proxy.rb,
lib/inventory_refresh/inventory_collection/data_storage.rb,
lib/inventory_refresh/inventory_collection/serialization.rb,
lib/inventory_refresh/inventory_collection/index/type/base.rb,
lib/inventory_refresh/inventory_collection/index/type/data.rb,
lib/inventory_refresh/inventory_collection/unconnected_edge.rb,
lib/inventory_refresh/inventory_collection/references_storage.rb,
lib/inventory_refresh/inventory_collection/index/type/local_db.rb,
lib/inventory_refresh/inventory_collection/index/type/skeletal.rb,
lib/inventory_refresh/inventory_collection/helpers/questions_helper.rb,
lib/inventory_refresh/inventory_collection/helpers/initialize_helper.rb,
lib/inventory_refresh/inventory_collection/helpers/associations_helper.rb
Overview
For more usage examples please follow spec examples in
-
spec/models/inventory_refresh/save_inventory/single_inventory_collection_spec.rb
-
spec/models/inventory_refresh/save_inventory/acyclic_graph_of_inventory_collections_spec.rb
-
spec/models/inventory_refresh/save_inventory/graph_of_inventory_collections_spec.rb
-
spec/models/inventory_refresh/save_inventory/graph_of_inventory_collections_targeted_refresh_spec.rb
-
spec/models/inventory_refresh/save_inventory/strategies_and_references_spec.rb
Defined Under Namespace
Modules: Helpers, Index Classes: Builder, DataStorage, Graph, Reference, ReferencesStorage, Scanner, Serialization, UnconnectedEdge
Instance Attribute Summary collapse
-
#all_manager_uuids ⇒ Array?
If present, InventoryCollection switches into delete_complement mode, where it will delete every record from the DB, that is not present in this list.
-
#all_manager_uuids_scope ⇒ Array?
Scope for applying :all_manager_uuids.
-
#all_manager_uuids_timestamp ⇒ String
Timestamp in UTC before fetching :all_manager_uuids.
-
#arel ⇒ Object
readonly
Returns the value of attribute arel.
-
#assert_graph_integrity ⇒ Object
readonly
Returns the value of attribute assert_graph_integrity.
-
#association ⇒ Object
readonly
Returns the value of attribute association.
-
#attributes_blacklist ⇒ Object
Returns the value of attribute attributes_blacklist.
-
#attributes_whitelist ⇒ Object
Returns the value of attribute attributes_whitelist.
-
#batch_extra_attributes ⇒ Object
readonly
Returns the value of attribute batch_extra_attributes.
-
#check_changed ⇒ Object
readonly
Returns the value of attribute check_changed.
-
#complete ⇒ Object
readonly
Returns the value of attribute complete.
-
#create_only ⇒ Object
readonly
Returns the value of attribute create_only.
-
#created_records ⇒ Object
readonly
Returns the value of attribute created_records.
-
#custom_reconnect_block ⇒ Object
readonly
Returns the value of attribute custom_reconnect_block.
-
#custom_save_block ⇒ Object
readonly
Returns the value of attribute custom_save_block.
-
#data_collection_finalized ⇒ Boolean
A true value marks that we collected all the data of the InventoryCollection, meaning we also collected all the references.
-
#data_storage ⇒ InventoryRefresh::InventoryCollection::DataStorage
An InventoryCollection encapsulating all data with indexes.
-
#default_values ⇒ Object
readonly
Returns the value of attribute default_values.
-
#delete_method ⇒ Object
readonly
Returns the value of attribute delete_method.
-
#deleted_records ⇒ Object
readonly
Returns the value of attribute deleted_records.
-
#dependees ⇒ Set
A set of InventoryCollection objects that depends on this InventoryCollection object.
-
#dependency_attributes ⇒ Object
readonly
Returns the value of attribute dependency_attributes.
-
#internal_attributes ⇒ Object
readonly
Returns the value of attribute internal_attributes.
-
#inventory_object_attributes ⇒ Object
readonly
Returns the value of attribute inventory_object_attributes.
-
#manager_ref ⇒ Object
readonly
Returns the value of attribute manager_ref.
-
#manager_ref_allowed_nil ⇒ Object
readonly
Returns the value of attribute manager_ref_allowed_nil.
-
#model_class ⇒ Object
readonly
Returns the value of attribute model_class.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#parent_inventory_collections ⇒ Array<Symbol>
parameters.
-
#references_storage ⇒ Object
readonly
Returns the value of attribute references_storage.
-
#retention_strategy ⇒ Object
readonly
Returns the value of attribute retention_strategy.
-
#saved ⇒ Boolean
True if this collection is already saved into the DB.
-
#saver_strategy ⇒ Object
readonly
Returns the value of attribute saver_strategy.
-
#strategy ⇒ Object
readonly
Returns the value of attribute strategy.
-
#targeted ⇒ Object
readonly
Returns the value of attribute targeted.
-
#targeted_arel ⇒ Object
readonly
Returns the value of attribute targeted_arel.
-
#targeted_scope ⇒ Object
readonly
Returns the value of attribute targeted_scope.
-
#transitive_dependency_attributes ⇒ Object
readonly
Returns the value of attribute transitive_dependency_attributes.
-
#unconnected_edges ⇒ Object
readonly
Returns the value of attribute unconnected_edges.
-
#update_only ⇒ Object
readonly
Returns the value of attribute update_only.
-
#updated_records ⇒ Object
readonly
Returns the value of attribute updated_records.
-
#use_ar_object ⇒ Object
readonly
Returns the value of attribute use_ar_object.
Instance Method Summary collapse
-
#base_class_name ⇒ String
Base class name of the model_class of this InventoryCollection.
- #base_columns ⇒ Object
-
#batch_size ⇒ Integer
Default batch size for talking to the DB.
-
#batch_size_pure_sql ⇒ Integer
Default batch size for talking to the DB if not using ApplicationRecord objects.
-
#blacklist_attributes!(attributes) ⇒ Array<Symbol>
Add passed attributes to blacklist.
-
#build_multi_selection_condition(hashes, keys = manager_ref) ⇒ String
Builds a multiselection conditions like (table1.a = a1 AND table2.b = b1) OR (table1.a = a2 AND table2.b = b2).
-
#clone ⇒ InventoryCollection
A shallow copy of InventoryCollection, the copy will share data_storage of the original collection, otherwise we would be copying a lot of records in memory.
-
#db_collection_for_comparison ⇒ ActiveRecord::Relation
A relation that can fetch all data of this InventoryCollection from the DB.
-
#db_collection_for_comparison_for(references) ⇒ ActiveRecord::Relation
Builds an ActiveRecord::Relation that can fetch all the references from the DB.
-
#dependencies ⇒ Array<InventoryRefresh::InventoryCollection>
All unique non saved dependencies.
-
#dependency_attributes_for(inventory_collections) ⇒ Array<InventoryRefresh::InventoryCollection>
Returns what attributes are causing a dependencies to certain InventoryCollection objects.
-
#filtered_dependency_attributes ⇒ Hash{Symbol => Set}
List attributes causing a dependency and filters them by attributes_blacklist and attributes_whitelist.
-
#fixed_attributes ⇒ Array<Symbol>
Attributes that are needed to be able to save the record, i.e.
-
#fixed_dependencies ⇒ Object
Returns fixed dependencies, which are the ones we can’t move, because we wouldn’t be able to save the data.
-
#full_collection_for_comparison ⇒ ActiveRecord::Relation
Relation that can fetch all the references from the DB.
-
#initialize(properties = {}) ⇒ InventoryCollection
constructor
A new instance of InventoryCollection.
-
#inspect ⇒ String
A concise form of the InventoryCollection for easy logging.
- #internal_columns ⇒ Object
- #internal_timestamp_columns ⇒ Object
-
#inventory_object?(value) ⇒ Boolean
True is value is kind of InventoryRefresh::InventoryObject.
-
#inventory_object_lazy?(value) ⇒ Boolean
True is value is kind of InventoryRefresh::InventoryObjectLazy.
-
#manager_ref_to_cols ⇒ Array<String>
Convert manager_ref list of attributes to list of DB columns.
-
#manager_uuids ⇒ Array<String>
Returns a list of stringified uuids of all scoped InventoryObjects, which is used for scoping in targeted mode.
-
#new_inventory_object(hash) ⇒ InventoryRefresh::InventoryObject
Creates InventoryRefresh::InventoryObject object from passed hash data.
-
#not_null_columns ⇒ Array
Array of column names that have not null constraint.
-
#object_index_with_keys(keys, record) ⇒ String
Builds string uuid from passed Object and keys.
- #resource_version_column ⇒ Object
-
#store_created_records(records) ⇒ Object
Caches what records were created, for later use, e.g.
-
#store_deleted_records(records) ⇒ Object
Caches what records were deleted/soft-deleted, for later use, e.g.
- #store_unconnected_edges(inventory_object, inventory_object_key, inventory_object_lazy) ⇒ Object
-
#store_updated_records(records) ⇒ Object
Caches what records were updated, for later use, e.g.
-
#targeted_arel_default ⇒ InventoryRefresh::ApplicationRecordIterator
Builds targeted query limiting the results by the :references defined in parent_inventory_collections.
-
#targeted_iterator_for(references, query = nil) ⇒ InventoryRefresh::ApplicationRecordIterator
Returns iterator for the passed references and a query.
-
#targeted_selection_for(references) ⇒ String
Builds a multiselection conditions like (table1.a = a1 AND table2.b = b1) OR (table1.a = a2 AND table2.b = b2) for passed references.
-
#to_s ⇒ String
A concise form of the inventoryCollection for easy logging.
-
#transform_references_to_hashes(references) ⇒ Array<Hash>
Gets targeted references and transforms them into list of hashes.
-
#uniq_keys_candidates(keys) ⇒ Array<ActiveRecord::ConnectionAdapters::IndexDefinition>
Find candidates for unique key.
-
#unique_index_columns ⇒ Array<Symbol>
All columns that are part of the best fit unique index.
-
#unique_index_for(keys) ⇒ ActiveRecord::ConnectionAdapters::IndexDefinition
Finds an index that fits the list of columns (keys) the best.
- #unique_index_keys ⇒ Object
-
#unique_indexes ⇒ Array<ActiveRecord::ConnectionAdapters::IndexDefinition>
Array of all unique indexes known to model.
-
#whitelist_attributes!(attributes) ⇒ Array<Symbol>
Add passed attributes to whitelist.
Methods included from Helpers::QuestionsHelper
#check_changed?, #complete?, #create_allowed?, #create_only?, #data_collection_finalized?, #delete_allowed?, #delete_complement_noop?, #noop?, #parallel_safe?, #saveable?, #saved?, #saving_noop?, #supports_column?, #supports_sti?, #targeted?, #update_only?, #use_ar_object?
Methods included from Helpers::InitializeHelper
#init_all_manager_uuids, #init_arels, #init_basic_properties, #init_changed_records_stats, #init_custom_procs, #init_data, #init_flags, #init_ic_relations, #init_model_attributes, #init_references, #init_storages, #init_strategies, #process_retention_strategy, #process_saver_strategy, #process_strategy
Methods included from Helpers::AssociationsHelper
#association_to_base_class_mapping, #association_to_foreign_key_mapping, #association_to_foreign_type_mapping, #belongs_to_associations, #fixed_foreign_keys, #foreign_key_to_association_mapping, #foreign_keys, #foreign_type_to_association_mapping
Constructor Details
#initialize(properties = {}) ⇒ InventoryCollection
Returns a new instance of InventoryCollection.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 140 def initialize(properties = {}) init_basic_properties(properties[:association], properties[:model_class], properties[:name], properties[:parent]) init_flags(properties[:complete], properties[:create_only], properties[:check_changed], properties[:update_only], properties[:use_ar_object], properties[:targeted], properties[:assert_graph_integrity]) init_strategies(properties[:strategy], properties[:saver_strategy], properties[:retention_strategy], properties[:delete_method]) init_references(properties[:manager_ref], properties[:manager_ref_allowed_nil], properties[:secondary_refs], properties[:manager_uuids]) init_all_manager_uuids(properties[:all_manager_uuids], properties[:all_manager_uuids_scope], properties[:all_manager_uuids_timestamp]) init_ic_relations(properties[:dependency_attributes], properties[:parent_inventory_collections]) init_arels(properties[:arel], properties[:targeted_arel]) init_custom_procs(properties[:custom_save_block], properties[:custom_reconnect_block]) init_model_attributes(properties[:attributes_blacklist], properties[:attributes_whitelist], properties[:inventory_object_attributes], properties[:batch_extra_attributes]) init_data(properties[:default_values]) init_storages init_changed_records_stats end |
Instance Attribute Details
#all_manager_uuids ⇒ Array?
If present, InventoryCollection switches into delete_complement mode, where it will delete every record from the DB, that is not present in this list. This is used for the batch processing, where we don’t know which InventoryObject should be deleted, but we know all manager_uuids of all InventoryObject objects that exists in the provider.
80 81 82 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 80 def all_manager_uuids @all_manager_uuids end |
#all_manager_uuids_scope ⇒ Array?
Returns Scope for applying :all_manager_uuids.
83 84 85 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 83 def all_manager_uuids_scope @all_manager_uuids_scope end |
#all_manager_uuids_timestamp ⇒ String
Returns Timestamp in UTC before fetching :all_manager_uuids.
86 87 88 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 86 def end |
#arel ⇒ Object (readonly)
Returns the value of attribute arel.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def arel @arel end |
#assert_graph_integrity ⇒ Object (readonly)
Returns the value of attribute assert_graph_integrity.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def assert_graph_integrity @assert_graph_integrity end |
#association ⇒ Object (readonly)
Returns the value of attribute association.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def association @association end |
#attributes_blacklist ⇒ Object
Returns the value of attribute attributes_blacklist.
95 96 97 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 95 def attributes_blacklist @attributes_blacklist end |
#attributes_whitelist ⇒ Object
Returns the value of attribute attributes_whitelist.
95 96 97 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 95 def attributes_whitelist @attributes_whitelist end |
#batch_extra_attributes ⇒ Object (readonly)
Returns the value of attribute batch_extra_attributes.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def batch_extra_attributes @batch_extra_attributes end |
#check_changed ⇒ Object (readonly)
Returns the value of attribute check_changed.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def check_changed @check_changed end |
#complete ⇒ Object (readonly)
Returns the value of attribute complete.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def complete @complete end |
#create_only ⇒ Object (readonly)
Returns the value of attribute create_only.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def create_only @create_only end |
#created_records ⇒ Object (readonly)
Returns the value of attribute created_records.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def created_records @created_records end |
#custom_reconnect_block ⇒ Object (readonly)
Returns the value of attribute custom_reconnect_block.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def custom_reconnect_block @custom_reconnect_block end |
#custom_save_block ⇒ Object (readonly)
Returns the value of attribute custom_save_block.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def custom_save_block @custom_save_block end |
#data_collection_finalized ⇒ Boolean
Returns A true value marks that we collected all the data of the InventoryCollection, meaning we also collected all the references.
63 64 65 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 63 def data_collection_finalized @data_collection_finalized end |
#data_storage ⇒ InventoryRefresh::InventoryCollection::DataStorage
Returns An InventoryCollection encapsulating all data with indexes.
67 68 69 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 67 def data_storage @data_storage end |
#default_values ⇒ Object (readonly)
Returns the value of attribute default_values.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def default_values @default_values end |
#delete_method ⇒ Object (readonly)
Returns the value of attribute delete_method.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def delete_method @delete_method end |
#deleted_records ⇒ Object (readonly)
Returns the value of attribute deleted_records.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def deleted_records @deleted_records end |
#dependees ⇒ Set
Returns A set of InventoryCollection objects that depends on this InventoryCollection object.
89 90 91 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 89 def dependees @dependees end |
#dependency_attributes ⇒ Object (readonly)
Returns the value of attribute dependency_attributes.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def dependency_attributes @dependency_attributes end |
#internal_attributes ⇒ Object (readonly)
Returns the value of attribute internal_attributes.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def internal_attributes @internal_attributes end |
#inventory_object_attributes ⇒ Object (readonly)
Returns the value of attribute inventory_object_attributes.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def inventory_object_attributes @inventory_object_attributes end |
#manager_ref ⇒ Object (readonly)
Returns the value of attribute manager_ref.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def manager_ref @manager_ref end |
#manager_ref_allowed_nil ⇒ Object (readonly)
Returns the value of attribute manager_ref_allowed_nil.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def manager_ref_allowed_nil @manager_ref_allowed_nil end |
#model_class ⇒ Object (readonly)
Returns the value of attribute model_class.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def model_class @model_class end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def name @name end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def parent @parent end |
#parent_inventory_collections ⇒ Array<Symbol>
Returns @see #parent_inventory_collections documentation of InventoryCollection.new’s initialize_ic_relations() parameters.
93 94 95 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 93 def parent_inventory_collections @parent_inventory_collections end |
#references_storage ⇒ Object (readonly)
Returns the value of attribute references_storage.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def references_storage @references_storage end |
#retention_strategy ⇒ Object (readonly)
Returns the value of attribute retention_strategy.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def retention_strategy @retention_strategy end |
#saved ⇒ Boolean
Returns true if this collection is already saved into the DB. E.g. InventoryCollections with DB only strategy are marked as saved. This causes InventoryCollection not being a dependency for any other InventoryCollection, since it is already persisted into the DB.
72 73 74 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 72 def saved @saved end |
#saver_strategy ⇒ Object (readonly)
Returns the value of attribute saver_strategy.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def saver_strategy @saver_strategy end |
#strategy ⇒ Object (readonly)
Returns the value of attribute strategy.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def strategy @strategy end |
#targeted ⇒ Object (readonly)
Returns the value of attribute targeted.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def targeted @targeted end |
#targeted_arel ⇒ Object (readonly)
Returns the value of attribute targeted_arel.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def targeted_arel @targeted_arel end |
#targeted_scope ⇒ Object (readonly)
Returns the value of attribute targeted_scope.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def targeted_scope @targeted_scope end |
#transitive_dependency_attributes ⇒ Object (readonly)
Returns the value of attribute transitive_dependency_attributes.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def transitive_dependency_attributes @transitive_dependency_attributes end |
#unconnected_edges ⇒ Object (readonly)
Returns the value of attribute unconnected_edges.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def unconnected_edges @unconnected_edges end |
#update_only ⇒ Object (readonly)
Returns the value of attribute update_only.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def update_only @update_only end |
#updated_records ⇒ Object (readonly)
Returns the value of attribute updated_records.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def updated_records @updated_records end |
#use_ar_object ⇒ Object (readonly)
Returns the value of attribute use_ar_object.
97 98 99 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 97 def use_ar_object @use_ar_object end |
Instance Method Details
#base_class_name ⇒ String
Returns Base class name of the model_class of this InventoryCollection.
445 446 447 448 449 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 445 def base_class_name return "" unless model_class @base_class_name ||= model_class.base_class.name end |
#base_columns ⇒ Object
305 306 307 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 305 def base_columns @base_columns ||= (unique_index_columns + internal_columns + not_null_columns).uniq end |
#batch_size ⇒ Integer
Returns default batch size for talking to the DB.
469 470 471 472 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 469 def batch_size # TODO(lsmola) mode to the settings 1000 end |
#batch_size_pure_sql ⇒ Integer
Returns default batch size for talking to the DB if not using ApplicationRecord objects.
475 476 477 478 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 475 def batch_size_pure_sql # TODO(lsmola) mode to the settings 10_000 end |
#blacklist_attributes!(attributes) ⇒ Array<Symbol>
Add passed attributes to blacklist. The manager_ref attributes cannot be blacklisted, otherwise we will not be able to identify the inventory_object. We do not automatically remove attributes causing fixed dependencies, so beware that without them, you won’t be able to create the record.
409 410 411 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 409 def blacklist_attributes!(attributes) self.attributes_blacklist += attributes - (fixed_attributes + internal_attributes) end |
#build_multi_selection_condition(hashes, keys = manager_ref) ⇒ String
Builds a multiselection conditions like (table1.a = a1 AND table2.b = b1) OR (table1.a = a2 AND table2.b = b2)
496 497 498 499 500 501 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 496 def build_multi_selection_condition(hashes, keys = manager_ref) arel_table = model_class.arel_table # We do pure SQL OR, since Arel is nesting every .or into another parentheses, otherwise this would be just # inject(:or) instead of to_sql with .join(" OR ") hashes.map { |hash| "(#{keys.map { |key| arel_table[key].eq(hash[key]) }.inject(:and).to_sql})" }.join(" OR ") end |
#clone ⇒ InventoryCollection
Returns a shallow copy of InventoryCollection, the copy will share data_storage of the original collection, otherwise we would be copying a lot of records in memory.
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 425 def clone cloned = self.class.new(:model_class => model_class, :manager_ref => manager_ref, :association => association, :parent => parent, :arel => arel, :strategy => strategy, :saver_strategy => saver_strategy, :custom_save_block => custom_save_block, # We want cloned IC to be update only, since this is used for cycle resolution :update_only => true, # Dependency attributes need to be a hard copy, since those will differ for each # InventoryCollection :dependency_attributes => dependency_attributes.clone) cloned.data_storage = data_storage cloned end |
#db_collection_for_comparison ⇒ ActiveRecord::Relation
Returns A relation that can fetch all data of this InventoryCollection from the DB.
504 505 506 507 508 509 510 511 512 513 514 515 516 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 504 def db_collection_for_comparison if targeted? if targeted_arel.respond_to?(:call) targeted_arel.call(self) elsif parent_inventory_collections.present? targeted_arel_default else targeted_iterator_for(targeted_scope.primary_references) end else full_collection_for_comparison end end |
#db_collection_for_comparison_for(references) ⇒ ActiveRecord::Relation
Builds an ActiveRecord::Relation that can fetch all the references from the DB
571 572 573 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 571 def db_collection_for_comparison_for(references) full_collection_for_comparison.where(targeted_selection_for(references)) end |
#dependencies ⇒ Array<InventoryRefresh::InventoryCollection>
Returns all unique non saved dependencies.
386 387 388 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 386 def dependencies filtered_dependency_attributes.values.map(&:to_a).flatten.uniq.reject(&:saved?) end |
#dependency_attributes_for(inventory_collections) ⇒ Array<InventoryRefresh::InventoryCollection>
Returns what attributes are causing a dependencies to certain InventoryCollection objects.
395 396 397 398 399 400 401 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 395 def dependency_attributes_for(inventory_collections) attributes = Set.new inventory_collections.each do |inventory_collection| attributes += filtered_dependency_attributes.select { |_key, value| value.include?(inventory_collection) }.keys end attributes end |
#filtered_dependency_attributes ⇒ Hash{Symbol => Set}
List attributes causing a dependency and filters them by attributes_blacklist and attributes_whitelist
345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 345 def filtered_dependency_attributes filtered_attributes = dependency_attributes if attributes_blacklist.present? filtered_attributes = filtered_attributes.reject { |key, _value| attributes_blacklist.include?(key) } end if attributes_whitelist.present? filtered_attributes = filtered_attributes.select { |key, _value| attributes_whitelist.include?(key) } end filtered_attributes end |
#fixed_attributes ⇒ Array<Symbol>
Attributes that are needed to be able to save the record, i.e. attributes that are part of the unique index and attributes with presence validation or NOT NULL constraint
363 364 365 366 367 368 369 370 371 372 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 363 def fixed_attributes if model_class presence_validators = model_class.validators.detect { |x| x.kind_of?(ActiveRecord::Validations::PresenceValidator) } end # Attributes that has to be always on the entity, so attributes making unique index of the record + attributes # that have presence validation fixed_attributes = manager_ref fixed_attributes += presence_validators.attributes if presence_validators.present? fixed_attributes end |
#fixed_dependencies ⇒ Object
Returns fixed dependencies, which are the ones we can’t move, because we wouldn’t be able to save the data
377 378 379 380 381 382 383 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 377 def fixed_dependencies fixed_attrs = fixed_attributes filtered_dependency_attributes.each_with_object(Set.new) do |(key, value), fixed_deps| fixed_deps.merge(value) if fixed_attrs.include?(key) end.reject(&:saved?) end |
#full_collection_for_comparison ⇒ ActiveRecord::Relation
Returns relation that can fetch all the references from the DB.
576 577 578 579 580 581 582 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 576 def full_collection_for_comparison return arel unless arel.nil? rel = parent.send(association) rel = rel.active if rel && supports_column?(:archived_at) && retention_strategy == :archive rel end |
#inspect ⇒ String
Returns a concise form of the InventoryCollection for easy logging.
464 465 466 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 464 def inspect to_s end |
#internal_columns ⇒ Object
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 276 def internal_columns return @internal_columns if @internal_columns @internal_columns = [] + @internal_columns << :type if supports_sti? @internal_columns += [resource_version_column, :resource_timestamps_max, :resource_timestamps, :resource_timestamp, :resource_counters_max, :resource_counters, :resource_counter].collect do |col| col if supports_column?(col) end.compact end |
#internal_timestamp_columns ⇒ Object
292 293 294 295 296 297 298 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 292 def return if = i[created_at created_on updated_at updated_on].collect do || if supports_column?() end.compact end |
#inventory_object?(value) ⇒ Boolean
Returns true is value is kind of InventoryRefresh::InventoryObject.
311 312 313 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 311 def inventory_object?(value) value.kind_of?(::InventoryRefresh::InventoryObject) end |
#inventory_object_lazy?(value) ⇒ Boolean
Returns true is value is kind of InventoryRefresh::InventoryObjectLazy.
317 318 319 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 317 def inventory_object_lazy?(value) value.kind_of?(::InventoryRefresh::InventoryObjectLazy) end |
#manager_ref_to_cols ⇒ Array<String>
Convert manager_ref list of attributes to list of DB columns
334 335 336 337 338 339 340 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 334 def manager_ref_to_cols # TODO(lsmola) this should contain the polymorphic _type, otherwise the IC with polymorphic unique key will get # conflicts manager_ref.map do |ref| association_to_foreign_key_mapping[ref] || ref end end |
#manager_uuids ⇒ Array<String>
Returns a list of stringified uuids of all scoped InventoryObjects, which is used for scoping in targeted mode
483 484 485 486 487 488 489 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 483 def manager_uuids # TODO(lsmola) LEGACY: this is still being used by :targetel_arel definitions and it expects array of strings raise "This works only for :manager_ref size 1" if manager_ref.size > 1 key = manager_ref.first transform_references_to_hashes(targeted_scope.primary_references).map { |x| x[key] } end |
#new_inventory_object(hash) ⇒ InventoryRefresh::InventoryObject
Creates InventoryRefresh::InventoryObject object from passed hash data
588 589 590 591 592 593 594 595 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 588 def new_inventory_object(hash) manager_ref.each do |x| # TODO(lsmola) with some effort, we can do this, but it's complex raise "A lazy_find with a :key can't be a part of the manager_uuid" if inventory_object_lazy?(hash[x]) && hash[x].key end inventory_object_class.new(self, hash) end |
#not_null_columns ⇒ Array
Returns Array of column names that have not null constraint.
301 302 303 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 301 def not_null_columns @not_null_constraint_columns ||= model_class.columns.reject(&:null).map { |x| x.name.to_sym } - [model_class.primary_key.to_sym] end |
#object_index_with_keys(keys, record) ⇒ String
Builds string uuid from passed Object and keys
326 327 328 329 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 326 def object_index_with_keys(keys, record) # TODO(lsmola) remove, last usage is in k8s reconnect logic build_stringified_reference_for_record(record, keys) end |
#resource_version_column ⇒ Object
272 273 274 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 272 def resource_version_column :resource_version end |
#store_created_records(records) ⇒ Object
Caches what records were created, for later use, e.g. post provision behavior
199 200 201 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 199 def store_created_records(records) @created_records.concat(records_identities(records)) end |
#store_deleted_records(records) ⇒ Object
Caches what records were deleted/soft-deleted, for later use, e.g. post provision behavior
213 214 215 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 213 def store_deleted_records(records) @deleted_records.concat(records_identities(records)) end |
#store_unconnected_edges(inventory_object, inventory_object_key, inventory_object_lazy) ⇒ Object
189 190 191 192 193 194 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 189 def store_unconnected_edges(inventory_object, inventory_object_key, inventory_object_lazy) (@unconnected_edges ||= []) << InventoryRefresh::InventoryCollection::UnconnectedEdge.new( inventory_object, inventory_object_key, inventory_object_lazy ) end |
#store_updated_records(records) ⇒ Object
Caches what records were updated, for later use, e.g. post provision behavior
206 207 208 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 206 def store_updated_records(records) @updated_records.concat(records_identities(records)) end |
#targeted_arel_default ⇒ InventoryRefresh::ApplicationRecordIterator
Builds targeted query limiting the results by the :references defined in parent_inventory_collections
521 522 523 524 525 526 527 528 529 530 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 521 def targeted_arel_default if parent_inventory_collections.collect { |x| x.model_class.base_class }.uniq.count > 1 raise "Multiple :parent_inventory_collections with different base class are not supported by default. Write "\ ":targeted_arel manually, or separate [#{self}] into 2 InventoryCollection objects." end parent_collection = parent_inventory_collections.first references = parent_inventory_collections.map { |x| x.targeted_scope.primary_references }.reduce({}, :merge!) parent_collection.targeted_iterator_for(references, full_collection_for_comparison) end |
#targeted_iterator_for(references, query = nil) ⇒ InventoryRefresh::ApplicationRecordIterator
Returns iterator for the passed references and a query
559 560 561 562 563 564 565 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 559 def targeted_iterator_for(references, query = nil) InventoryRefresh::ApplicationRecordIterator.new( :inventory_collection => self, :manager_uuids_set => references, :query => query ) end |
#targeted_selection_for(references) ⇒ String
Builds a multiselection conditions like (table1.a = a1 AND table2.b = b1) OR (table1.a = a2 AND table2.b = b2) for passed references
550 551 552 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 550 def targeted_selection_for(references) build_multi_selection_condition(transform_references_to_hashes(references)) end |
#to_s ⇒ String
Returns a concise form of the inventoryCollection for easy logging.
452 453 454 455 456 457 458 459 460 461 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 452 def to_s whitelist = ", whitelist: [#{attributes_whitelist.to_a.join(", ")}]" if attributes_whitelist.present? blacklist = ", blacklist: [#{attributes_blacklist.to_a.join(", ")}]" if attributes_blacklist.present? strategy_name = ", strategy: #{strategy}" if strategy name = model_class || association "InventoryCollection:<#{name}>#{whitelist}#{blacklist}#{strategy_name}" end |
#transform_references_to_hashes(references) ⇒ Array<Hash>
Gets targeted references and transforms them into list of hashes
536 537 538 539 540 541 542 543 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 536 def transform_references_to_hashes(references) if references.kind_of?(Array) # Sliced InventoryRefresh::InventoryCollection::TargetedScope references.map { |x| x.second.full_reference } else references.values.map(&:full_reference) end end |
#uniq_keys_candidates(keys) ⇒ Array<ActiveRecord::ConnectionAdapters::IndexDefinition>
Find candidates for unique key. Candidate must cover all columns we are passing as keys.
260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 260 def uniq_keys_candidates(keys) # Find all uniq indexes that that are covering our keys uniq_key_candidates = unique_indexes.each_with_object([]) { |i, obj| obj << i if (keys - i.columns.map(&:to_sym)).empty? } if unique_indexes.blank? || uniq_key_candidates.blank? raise "#{self} and its table #{model_class.table_name} must have a unique index defined "\ "covering columns #{keys} to be able to use saver_strategy :concurrent_safe_batch." end uniq_key_candidates end |
#unique_index_columns ⇒ Array<Symbol>
Returns all columns that are part of the best fit unique index.
218 219 220 221 222 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 218 def unique_index_columns return @unique_index_columns if @unique_index_columns @unique_index_columns = unique_index_for(unique_index_keys).columns.map(&:to_sym) end |
#unique_index_for(keys) ⇒ ActiveRecord::ConnectionAdapters::IndexDefinition
Finds an index that fits the list of columns (keys) the best
247 248 249 250 251 252 253 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 247 def unique_index_for(keys) @unique_index_for_keys_cache ||= {} return @unique_index_for_keys_cache[keys] if @unique_index_for_keys_cache[keys] # Take the uniq key having the least number of columns @unique_index_for_keys_cache[keys] = uniq_keys_candidates(keys).min_by { |x| x.columns.count } end |
#unique_index_keys ⇒ Object
224 225 226 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 224 def unique_index_keys @unique_index_keys ||= manager_ref_to_cols.map(&:to_sym) end |
#unique_indexes ⇒ Array<ActiveRecord::ConnectionAdapters::IndexDefinition>
Returns array of all unique indexes known to model.
229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 229 def unique_indexes return @unique_indexes if @unique_indexes @unique_indexes = model_class.connection.indexes(model_class.table_name).select(&:unique) if @unique_indexes.blank? raise "#{self} and its table #{model_class.table_name} must have a unique index defined, to"\ " be able to use saver_strategy :concurrent_safe_batch." end @unique_indexes end |
#whitelist_attributes!(attributes) ⇒ Array<Symbol>
Add passed attributes to whitelist. The manager_ref attributes always needs to be in the white list, otherwise we will not be able to identify theinventory_object. We do not automatically add attributes causing fixed dependencies, so beware that without them, you won’t be able to create the record.
419 420 421 |
# File 'lib/inventory_refresh/inventory_collection.rb', line 419 def whitelist_attributes!(attributes) self.attributes_whitelist += attributes + (fixed_attributes + internal_attributes) end |