Module: Metasploit::Model::Association::Tree
- Defined in:
- lib/metasploit/model/association/tree.rb
Overview
Functions for turning a compact tree of compact as passed to Search::Association::ClassMethods#search_associations into an expanded Search::Association::ClassMethods#search_association_tree.
Class Method Summary collapse
-
.expand(compact) ⇒ Hash{Symbol => Hash,nil}
Expands a
compactassociation into an expanded association tree. -
.merge(first_expanded, second_expanded) ⇒ nil, Hash{Symbol => nil,Hash}
Merges two expanded association trees.
-
.operators(expanded, options = {}) ⇒ Array<Metasploit::Model::Search::Operator::Association>
Calculates association operators for the
expandedassociation tree. -
.reflect_on_association_on_class(association, klass) ⇒ #klass
private
Return the association reflection for
associationonklass.
Class Method Details
.expand(compact) ⇒ Hash{Symbol => Hash,nil}
Expands a compact association into an expanded association tree.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/metasploit/model/association/tree.rb', line 13 def self.(compact) case compact when Array compact.reduce({}) { |hash, association| hash.merge((association)) } when Hash child_by_parent = compact child_by_parent.each_with_object({}) { |(parent, child), hash| hash[parent] = (child) } when Symbol association = compact {association => nil} end end |
.merge(first_expanded, second_expanded) ⇒ nil, Hash{Symbol => nil,Hash}
Unlike Hash#deep_merge, second_expanded's values aren't favored over first's values. Instead whichever
side is present is used and if both first and second_expanded are present, then their Hash#keys' values are
recursively merged.
Merges two expanded association trees.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/metasploit/model/association/tree.rb', line 41 def self.merge(, ) if .nil? && .nil? nil elsif !.nil? && .nil? elsif .nil? && !.nil? else first_keys = .keys key_set = Set.new(first_keys) second_keys = .keys key_set.merge(second_keys) key_set.each_with_object({}) do |key, merged| first_child = [key] second_child = [key] merged[key] = merge(first_child, second_child) end end end |
.operators(expanded, options = {}) ⇒ Array<Metasploit::Model::Search::Operator::Association>
Calculates association operators for the expanded association tree.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/metasploit/model/association/tree.rb', line 71 def self.operators(, ={}) ||= {} .assert_valid_keys(:class) klass = .fetch(:class) .flat_map { |parent_association, child_tree| reflection = reflect_on_association_on_class(parent_association, klass) association_class = reflection.klass association_search_with_operators = association_class.search_with_operator_by_name.each_value child_tree_operators = operators( child_tree, class: reflection.klass ) [association_search_with_operators, child_tree_operators].flat_map { |enumerator| enumerator.map { |source_operator| Metasploit::Model::Search::Operator::Association.new( association: parent_association, klass: klass, source_operator: source_operator ) } } } end |
.reflect_on_association_on_class(association, klass) ⇒ #klass (private)
Return the association reflection for association on klass.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/metasploit/model/association/tree.rb', line 109 def self.reflect_on_association_on_class(association, klass) begin reflection = klass.reflect_on_association(association) rescue NameError raise NameError, "#{self} does not respond to reflect_on_association. " \ "It can be added to ActiveModels by including Metasploit::Model::Association into the class." end unless reflection raise Metasploit::Model::Association::Error.new( model: klass, name: association ) end reflection end |