Class: ActiveDataFrame::DataFrameProxy

Inherits:
Object
  • Object
show all
Defined in:
lib/active_data_frame/data_frame_proxy.rb

Direct Known Subclasses

Row, Table

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(block_type, data_frame_type, value_map: nil, singular_df_name: '', plural_df_name: '') ⇒ DataFrameProxy

Returns a new instance of DataFrameProxy.



9
10
11
12
13
14
15
16
# File 'lib/active_data_frame/data_frame_proxy.rb', line 9

def initialize(block_type, data_frame_type, value_map: nil, singular_df_name: '', plural_df_name: '')
  self.block_type       = block_type
  self.data_frame_type  = data_frame_type
  self.block_type_name  = block_type.table_name.gsub(/_blocks$/,'').gsub(/^blocks_/,'')
  self.value_map        = value_map
  self.singular_df_name = singular_df_name
  self.plural_df_name   = plural_df_name
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/active_data_frame/data_frame_proxy.rb', line 78

def method_missing(name, *args, &block)
  if name.to_s.end_with?(?=)
    is_assignment = true
    name = name.to_s.gsub(/=$/,'').to_sym
  end
  if column_name_map && column_map[name]
    is_assignment ? self.[]=(name, *args) : self[name]
  else
    super
  end
end

Instance Attribute Details

#block_typeObject

Returns the value of attribute block_type.



7
8
9
# File 'lib/active_data_frame/data_frame_proxy.rb', line 7

def block_type
  @block_type
end

#block_type_nameObject

Returns the value of attribute block_type_name.



7
8
9
# File 'lib/active_data_frame/data_frame_proxy.rb', line 7

def block_type_name
  @block_type_name
end

#data_frame_typeObject

Returns the value of attribute data_frame_type.



7
8
9
# File 'lib/active_data_frame/data_frame_proxy.rb', line 7

def data_frame_type
  @data_frame_type
end

#plural_df_nameObject

Returns the value of attribute plural_df_name.



7
8
9
# File 'lib/active_data_frame/data_frame_proxy.rb', line 7

def plural_df_name
  @plural_df_name
end

#singular_df_nameObject

Returns the value of attribute singular_df_name.



7
8
9
# File 'lib/active_data_frame/data_frame_proxy.rb', line 7

def singular_df_name
  @singular_df_name
end

#value_mapObject

Returns the value of attribute value_map.



7
8
9
# File 'lib/active_data_frame/data_frame_proxy.rb', line 7

def value_map
  @value_map
end

Class Method Details

.get_bounds(from, to, block_type, index = 0) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/active_data_frame/data_frame_proxy.rb', line 121

def self.get_bounds(from, to, block_type, index=0)
  from_block_index  = from / block_type::BLOCK_SIZE
  from_block_offset = from % block_type::BLOCK_SIZE
  to_block_index    = to / block_type::BLOCK_SIZE
  to_block_offset   = to % block_type::BLOCK_SIZE
  return Bounds.new(
    Point.new(from_block_index, from_block_offset, from),
    Point.new(to_block_index,   to_block_offset, to),
    (to - from) + 1,
    index
  )
end

.iterate_bounds(all_bounds, block_type) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/active_data_frame/data_frame_proxy.rb', line 148

def self.iterate_bounds(all_bounds, block_type)
  cursor = 0
  all_bounds.each do |bounds|
    index = bounds.from.index
    while index <= bounds.to.index
      left  = index == bounds.from.index ? bounds.from.offset : 0
      right = index == bounds.to.index   ? bounds.to.offset   : block_type::BLOCK_SIZE - 1
      size  = (right - left)+1
      yield index, left, right, cursor, size
      cursor += size
      index += 1
    end
  end
end

.suppress_logsObject



134
135
136
137
138
139
140
# File 'lib/active_data_frame/data_frame_proxy.rb', line 134

def self.suppress_logs
  return yield unless ActiveDataFrame.suppress_logs
  ActiveRecord::Base.logger, old_logger = nil,  ActiveRecord::Base.logger
  yield.tap do
    ActiveRecord::Base.logger = old_logger
  end
end

Instance Method Details

#[](*ranges) ⇒ Object



22
23
24
25
26
27
28
29
30
31
# File 'lib/active_data_frame/data_frame_proxy.rb', line 22

def [](*ranges)
  result = get(extract_ranges(ranges))
  if @value_map
    result.to_type(M::Typecode::OBJECT).mmap{|row| reverse_value_map[row]}.tap do |mapped|
      mapped.row_map = result.row_map
    end
  else
    result
  end
end

#[]=(from, values) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/active_data_frame/data_frame_proxy.rb', line 33

def []=(from, values)

  from = column_map[from] if column_map && column_map[from]
  if values.kind_of?(Hash)
    values = verify_and_cleanse_hash_values(values)
  else
    values = Array(values).flatten.map(&@value_map.method(:[])) if @value_map
    values = M[values, typecode: block_type::TYPECODE].to_a.flatten
  end
  set(from, values)
end

#blocks_between(bounds, block_scope: scope) ⇒ Object



167
168
169
170
171
172
173
# File 'lib/active_data_frame/data_frame_proxy.rb', line 167

def blocks_between(bounds, block_scope: scope)
  bounds[1..-1].reduce(
    block_scope.where( block_type.table_name => { period_index: match_range(bounds[0].from.index,bounds[0].to.index)})
  ) do | or_chain, bound|
    or_chain.or(block_scope.where( block_type.table_name => { period_index: match_range(bound.from.index,bound.to.index)}))
  end
end

#clear(*ranges) ⇒ Object



56
57
58
59
60
# File 'lib/active_data_frame/data_frame_proxy.rb', line 56

def clear(*ranges)
  extract_ranges(ranges).each do |r|
    set(r.first, V.blank(columns: r.last - r.first, typecode: block_type::TYPECODE).to_a, trim: true)
  end
end

#column_mapObject



62
63
64
# File 'lib/active_data_frame/data_frame_proxy.rb', line 62

def column_map
  data_frame_type.column_map(self.singular_df_name)
end

#column_name_mapObject



66
67
68
# File 'lib/active_data_frame/data_frame_proxy.rb', line 66

def column_name_map
  data_frame_type.column_name_map(self.singular_df_name)
end

#databaseObject



74
75
76
# File 'lib/active_data_frame/data_frame_proxy.rb', line 74

def database
  @database ||= Database.for_types(block: block_type, df: data_frame_type)
end

#extract_ranges(ranges) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/active_data_frame/data_frame_proxy.rb', line 90

def extract_ranges(ranges)
  ranges = unmap_ranges(ranges, column_map) if column_map
  ranges.map do |range|
    case range
    when Range then range
    when Integer then range..range
    else raise "Unexpected index for data frame proxy #{range}, expecting either a Range or an Integer"
    end
  end
end

#get_bounds(from, to, index = 0) ⇒ Object



117
118
119
# File 'lib/active_data_frame/data_frame_proxy.rb', line 117

def get_bounds(from, to, index=0)
  self.class.get_bounds(from, to, block_type, index)
end

#iterate_bounds(all_bounds) ⇒ Object



142
143
144
145
146
# File 'lib/active_data_frame/data_frame_proxy.rb', line 142

def iterate_bounds(all_bounds)
  self.class.iterate_bounds(all_bounds, block_type) do |index, left, right, cursor, size|
    yield index, left, right, cursor, size
  end
end

#match_range(from, to) ⇒ Object



163
164
165
# File 'lib/active_data_frame/data_frame_proxy.rb', line 163

def match_range(from, to)
  from == to ? from : from..to
end

#range_sizeObject



101
102
103
# File 'lib/active_data_frame/data_frame_proxy.rb', line 101

def range_size
  0
end

#reverse_column_mapObject



70
71
72
# File 'lib/active_data_frame/data_frame_proxy.rb', line 70

def reverse_column_map
  data_frame_type.reverse_column_map(self.singular_df_name)
end

#reverse_value_mapObject



18
19
20
# File 'lib/active_data_frame/data_frame_proxy.rb', line 18

def reverse_value_map
  @reverse_value_map ||= value_map.invert
end

#unmap_ranges(ranges, map) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/active_data_frame/data_frame_proxy.rb', line 105

def unmap_ranges(ranges, map)
  ranges.map do |range|
    case range
    when Range
      first       = (map[range.first] rescue nil) || range.first
      ends        = (map[range.end] rescue nil) || range.end
      range.exclude_end? ? first...ends : first..ends
    else map[range] || range
    end
  end
end

#verify_and_cleanse_hash_values(map) ⇒ Object



45
46
47
48
49
50
51
52
53
54
# File 'lib/active_data_frame/data_frame_proxy.rb', line 45

def verify_and_cleanse_hash_values(map)
  length = nil
  map.transform_values do |values|
    values = Array(values).flatten.map(&@value_map.method(:[])) if @value_map
    cleansed = M[values, typecode: block_type::TYPECODE].to_a.flatten
    raise "All streams provided via a hash must be of the same length" if length && length != cleansed.length
    length ||= cleansed.length
    cleansed
  end
end