Module: Oinky::RowSet

Included in:
Index, Table
Defined in:
lib/oinky/query.rb,
lib/oinky.rb

Overview

Add dataset filtering to the rowset (applies to both tables and indices) The indexes are not used autmatically. An index is only used if the filter is applied to an index using positional specification.

Instance Method Summary collapse

Instance Method Details

#__each_filtered(c, terminate, filter) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/oinky/query.rb', line 90

def __each_filtered(c,terminate,filter)
  Enumerator.new {|blk|
    if c.is_valid?
      v = c.select_all
      while true
        blk.yield v if filter.call(v)
        c.seek_next
        break unless c.is_valid?
        v = c.select_all
        break if terminate and terminate.call(v)
      end
    end
  }
end

#__make_filter_proc(f) ⇒ Object

Raises:

  • (ArgumentError)


104
105
106
107
108
109
110
111
112
# File 'lib/oinky/query.rb', line 104

def __make_filter_proc(f)
  if [String,Integer,Fixnum,Float,DateTime].find_index(f.class)
    return lambda{|v| v == f}
  end
  if f.is_a? Proc
    return f
  end
  raise ArgumentError.new("Hash value must be proc or value.")
end

#__rs_filter(f, c, t) ⇒ Object



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
139
140
141
142
143
# File 'lib/oinky/query.rb', line 113

def __rs_filter(f,c,t)
  if f.is_a? Hash
    p = {}
    cols = @table.columns
    f.each{|k,kf|
      unless cols[k]
        raise ArgumentError.new("Unknown column name in hash filter.")
      end
      p[k] = __make_filter_proc(kf)
    }
    f = lambda {|v|
      r = true
      p.each{|k,kf|
        r &&= kf.call(v[k])
      }
    }
  end
  unless f.is_a? Proc
    raise ArgumentError.new("Invalid argument to filter.  Need Proc or Hash.")
  end

  seq = __each_filtered(c,t,f)
  if block_given?
    seq.each {|v|
      yield v
    }
    return self
  else
    return seq
  end
end

#cursor_eachObject



744
745
746
747
748
749
750
751
752
753
754
755
756
757
# File 'lib/oinky.rb', line 744

def cursor_each
  e = Enumerator.new {|blk|
    c = self.new_cursor
    while c.is_valid?
      blk.yield c
      c.seek_next
    end
  }
  if block_given?
    e.each{|k| yield k}
  else
    return e
  end
end

#each(cs = nil) ⇒ Object



759
760
761
762
763
764
765
766
767
768
769
770
771
# File 'lib/oinky.rb', line 759

def each(cs = nil)
  # Making the selector first will be most efficient
  cs = @table.select_columns(cs)

  e = ValuesEnumerator.new {|blk|
    self.cursor_each { |c| blk.yield c.select(cs) }
  }
  if block_given?
    e.each{|k| yield k}
  else
    return e
  end
end

#filter(f) ⇒ Object



144
145
146
# File 'lib/oinky/query.rb', line 144

def filter(f)
  __rs_filter(f,new_cursor(),nil)
end

#new_cursor(*a) ⇒ Object



773
774
775
# File 'lib/oinky.rb', line 773

def new_cursor(*a)
  self.class::Cursor.new(self, *a)
end