Class: FilterTable::Table
- Inherits:
- 
      Object
      
        - Object
- FilterTable::Table
 
- Defined in:
- lib/utils/filter.rb
Instance Attribute Summary collapse
- 
  
    
      #criteria_string  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute criteria_string. 
- 
  
    
      #raw_data  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute raw_data. 
- 
  
    
      #resource_instance  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute resource_instance. 
Instance Method Summary collapse
- #callback_for_lazy_field(field_name) ⇒ Object
- #create_eval_context_for_row(*_) ⇒ Object
- #entries ⇒ Object
- #field?(proposed_field) ⇒ Boolean
- #field_populated?(field_name) ⇒ Boolean
- #get_column_values(field) ⇒ Object
- 
  
    
      #initialize(resource_instance, raw_data, criteria_string)  ⇒ Table 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    A new instance of Table. 
- #is_field_lazy?(sought_field_name) ⇒ Boolean
- #list_fields ⇒ Object
- #mark_lazy_field_populated(field_name) ⇒ Object
- #params ⇒ Object
- #populate_lazy_field(field_name, criterion) ⇒ Object
- #resource ⇒ Object
- #to_s ⇒ Object (also: #inspect)
- 
  
    
      #where(conditions = {}, &block)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Filter the raw data based on criteria (as method params) or by evaling a block; then construct a new Table of the same class as ourselves, wrapping the filtered data, and return it. 
Constructor Details
#initialize(resource_instance, raw_data, criteria_string) ⇒ Table
Returns a new instance of Table.
| 87 88 89 90 91 92 93 | # File 'lib/utils/filter.rb', line 87 def initialize(resource_instance, raw_data, criteria_string) @resource_instance = resource_instance @raw_data = raw_data @raw_data = [] if @raw_data.nil? @criteria_string = criteria_string @populated_lazy_columns = {} end | 
Instance Attribute Details
#criteria_string ⇒ Object (readonly)
Returns the value of attribute criteria_string.
| 86 87 88 | # File 'lib/utils/filter.rb', line 86 def criteria_string @criteria_string end | 
#raw_data ⇒ Object (readonly)
Returns the value of attribute raw_data.
| 86 87 88 | # File 'lib/utils/filter.rb', line 86 def raw_data @raw_data end | 
#resource_instance ⇒ Object (readonly)
Returns the value of attribute resource_instance.
| 86 87 88 | # File 'lib/utils/filter.rb', line 86 def resource_instance @resource_instance end | 
Instance Method Details
#callback_for_lazy_field(field_name) ⇒ Object
| 212 213 214 215 216 217 | # File 'lib/utils/filter.rb', line 212 def callback_for_lazy_field(field_name) return unless is_field_lazy?(field_name) custom_properties_schema.values.find do |property_struct| property_struct.field_name == field_name end.opts[:lazy] end | 
#create_eval_context_for_row(*_) ⇒ Object
| 140 141 142 143 144 | # File 'lib/utils/filter.rb', line 140 def create_eval_context_for_row(*_) raise "#{self.class} must not be used on its own. It must be inherited "\ 'and the #create_eval_context_for_row method must be implemented. This is an internal '\ 'error and should not happen.' end | 
#entries ⇒ Object
| 155 156 157 158 159 160 | # File 'lib/utils/filter.rb', line 155 def entries row_criteria_string = resource.to_s + criteria_string + ' one entry' raw_data.map do |row| create_eval_context_for_row(row, row_criteria_string) end end | 
#field?(proposed_field) ⇒ Boolean
| 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | # File 'lib/utils/filter.rb', line 174 def field?(proposed_field) # Currently we only know about a field if it is present in a at least one row of the raw data. # If we have no rows in the raw data, assume all fields are acceptable (and rely on failing to match on value, nil) return true if raw_data.empty? # Most resources have Symbol keys in their raw data. Some have Strings (looking at you, `shadow`). is_field = false is_field ||= list_fields.include?(proposed_field.to_s) is_field ||= list_fields.include?(proposed_field.to_sym) is_field ||= is_field_lazy?(proposed_field.to_s) is_field ||= is_field_lazy?(proposed_field.to_sym) is_field end | 
#field_populated?(field_name) ⇒ Boolean
| 219 220 221 | # File 'lib/utils/filter.rb', line 219 def field_populated?(field_name) @populated_lazy_columns[field_name] end | 
#get_column_values(field) ⇒ Object
| 162 163 164 165 166 | # File 'lib/utils/filter.rb', line 162 def get_column_values(field) raw_data.map do |row| row[field] end end | 
#is_field_lazy?(sought_field_name) ⇒ Boolean
| 205 206 207 208 209 210 | # File 'lib/utils/filter.rb', line 205 def is_field_lazy?(sought_field_name) custom_properties_schema.values.any? do |property_struct| sought_field_name == property_struct.field_name && \ property_struct.opts[:lazy] end end | 
#list_fields ⇒ Object
| 168 169 170 171 172 | # File 'lib/utils/filter.rb', line 168 def list_fields @__fields_in_raw_data ||= raw_data.reduce([]) do |fields, row| fields.concat(row.keys).uniq end end | 
#mark_lazy_field_populated(field_name) ⇒ Object
| 223 224 225 | # File 'lib/utils/filter.rb', line 223 def mark_lazy_field_populated(field_name) @populated_lazy_columns[field_name] = true end | 
#params ⇒ Object
| 150 151 152 153 | # File 'lib/utils/filter.rb', line 150 def params # TODO: consider deprecating raw_data end | 
#populate_lazy_field(field_name, criterion) ⇒ Object
| 195 196 197 198 199 200 201 202 203 | # File 'lib/utils/filter.rb', line 195 def populate_lazy_field(field_name, criterion) return unless is_field_lazy?(field_name) return if field_populated?(field_name) raw_data.each do |row| next if row.key?(field_name) # skip row if pre-existing data is present callback_for_lazy_field(field_name).call(row, criterion, self) end mark_lazy_field_populated(field_name) end | 
#resource ⇒ Object
| 146 147 148 | # File 'lib/utils/filter.rb', line 146 def resource resource_instance end | 
#to_s ⇒ Object Also known as: inspect
| 189 190 191 | # File 'lib/utils/filter.rb', line 189 def to_s resource.to_s + criteria_string end | 
#where(conditions = {}, &block) ⇒ Object
Filter the raw data based on criteria (as method params) or by evaling a block; then construct a new Table of the same class as ourselves, wrapping the filtered data, and return it.
| 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | # File 'lib/utils/filter.rb', line 98 def where(conditions = {}, &block) return self if !conditions.is_a?(Hash) return self if conditions.empty? && !block_given? # Initialize the details of the new Table. new_criteria_string = criteria_string filtered_raw_data = raw_data # If we were provided params, interpret them as criteria to be evaluated # against the raw data. Criteria are assumed to be hash keys. conditions.each do |raw_field_name, desired_value| raise(ArgumentError, "'#{decorate_symbols(raw_field_name)}' is not a recognized criterion - expected one of #{decorate_symbols(list_fields).join(', ')}'") unless field?(raw_field_name) populate_lazy_field(raw_field_name, desired_value) if is_field_lazy?(raw_field_name) new_criteria_string += " #{raw_field_name} == #{desired_value.inspect}" filtered_raw_data = filter_raw_data(filtered_raw_data, raw_field_name, desired_value) end # If we were given a block, make a special Struct for each row, that has an accessor # for each field declared using `register_custom_property`, then instance-eval the block # against the struct. if block_given? # Perform the filtering. filtered_raw_data = filtered_raw_data.find_all { |row_as_hash| create_eval_context_for_row(row_as_hash, '').instance_eval(&block) } # Try to interpret the block for updating the stringification. src = Trace.new # Swallow any exceptions raised here. # See https://github.com/chef/inspec/issues/2929 begin src.instance_eval(&block) rescue # rubocop: disable Lint/HandleExceptions # Yes, robocop, ignoring all exceptions is normally # a bad idea. Here, an exception just means we don't # understand what was in a `where` block, so we can't # meaningfully sytringify it. We still have a decent # default stringification. end new_criteria_string += Trace.to_ruby(src) end self.class.new(resource, filtered_raw_data, new_criteria_string) end |