class ActiveTsv::Relation
Constants
- BUF_SIZE
Attributes
group_values[RW]
model[R]
order_values[RW]
where_values[RW]
Public Class Methods
new(model)
click to toggle source
# File lib/active_tsv/relation.rb, line 14 def initialize(model) @model = model @where_values = [] @order_values = [] @group_values = [] end
Public Instance Methods
==(other)
click to toggle source
# File lib/active_tsv/relation.rb, line 27 def ==(other) where_values == other.where_values && order_values == other.order_values && group_values == other.group_values end
count()
click to toggle source
Calls superclass method
# File lib/active_tsv/relation.rb, line 121 def count if @group_values.empty? super else h = if @group_values.one? group_by { |i| i[@group_values.first] } else group_by { |i| @group_values.map { |c| i[c] } } end h.each do |k, v| h[k] = v.count end h end end
each(*args, &block)
click to toggle source
# File lib/active_tsv/relation.rb, line 149 def each(*args, &block) to_a.each(*args, &block) end
exists?()
click to toggle source
# File lib/active_tsv/relation.rb, line 75 def exists? !first.nil? end
find(*ids)
click to toggle source
# File lib/active_tsv/relation.rb, line 33 def find(*ids) case ids.length when 0 raise ActiveTsv::RecordNotFound, "Couldn't find #{@model} without an ID" when 1 id = ids.first record = where(@model.primary_key => id).first unless record raise ActiveTsv::RecordNotFound, "Couldn't find #{@model} with '#{@model.primary_key}'=#{id}" end record else records = where(@model.primary_key => ids).to_a unless ids.length == records.length raise ActiveTsv::RecordNotFound, "Couldn't find all #{@model} with '#{@model.primary_key}': (#{ids.join(', ')}) (found #{records.length} results, but was looking for #{ids.length})" end records end end
first()
click to toggle source
# File lib/active_tsv/relation.rb, line 79 def first if @order_values.empty? each_model.first else to_a.first end end
group(*columns)
click to toggle source
# File lib/active_tsv/relation.rb, line 143 def group(*columns) @group_values += columns @group_values.uniq! self end
initialize_copy(copy)
click to toggle source
# File lib/active_tsv/relation.rb, line 21 def initialize_copy(copy) copy.where_values = where_values.dup copy.order_values = order_values.dup copy.group_values = group_values.dup end
inspect()
click to toggle source
# File lib/active_tsv/relation.rb, line 157 def inspect a = to_value_a.take(11).map! { |i| @model.new(i) }.map!(&:inspect) a[10] = '...' if a.length == 11 "#<#{self.class.name} [#{a.join(', ')}]>" end
last()
click to toggle source
# File lib/active_tsv/relation.rb, line 87 def last if @where_values.empty? && @order_values.empty? last_value = File.open(@model.table_path, "r:#{@model.encoding}:UTF-8") do |f| f.seek(0, IO::SEEK_END) buf_size = [f.size, self.class::BUF_SIZE].min while true f.seek(-buf_size, IO::SEEK_CUR) buf = f.read(buf_size) if index = buf.rindex($INPUT_RECORD_SEPARATOR, -2) f.seek(-buf_size + index + 1, IO::SEEK_CUR) break f.read.chomp else f.seek(-buf_size, IO::SEEK_CUR) end end end @model.new(CSV.new(last_value, col_sep: @model::SEPARATER).shift) else @model.new(to_value_a.last) end end
maximum(column)
click to toggle source
# File lib/active_tsv/relation.rb, line 164 def maximum(column) pluck(column).max end
minimum(column)
click to toggle source
# File lib/active_tsv/relation.rb, line 168 def minimum(column) pluck(column).min end
order(*columns)
click to toggle source
# File lib/active_tsv/relation.rb, line 137 def order(*columns) @order_values += order_conditions(columns) @order_values.uniq! self end
pluck(*fields)
click to toggle source
# File lib/active_tsv/relation.rb, line 63 def pluck(*fields) key_to_value_index = @model.column_names.each_with_index.to_h if fields.empty? to_value_a elsif fields.one? to_value_a.map! { |v| v[key_to_value_index[fields.first.to_s]] } else indexes = fields.map(&:to_s).map! { |field| key_to_value_index[field] } to_value_a.map! { |v| v.values_at(*indexes) } end end
take(n = nil)
click to toggle source
# File lib/active_tsv/relation.rb, line 109 def take(n = nil) if n if @order_values.empty? each_model.take(n) else to_value_a.take(n).map! { |i| @model.new(i) } end else first end end
to_a()
click to toggle source
# File lib/active_tsv/relation.rb, line 153 def to_a to_value_a.map! { |v| @model.new(v) } end
where(where_value = nil)
click to toggle source
# File lib/active_tsv/relation.rb, line 53 def where(where_value = nil) if where_value dup.tap do |r| r.where_values << Condition::Equal.new(where_value) end else WhereChain.new(dup) end end
Private Instance Methods
each_value() { |value| ... }
click to toggle source
# File lib/active_tsv/relation.rb, line 196 def each_value return to_enum(__method__) unless block_given? key_to_value_index = @model.column_names.each_with_index.to_h @model.open do |csv| csv.gets if !@model.custom_column_name? csv.each do |value| yield value if @where_values.all? do |cond| case cond when Condition::Equal cond.values.all? do |k, v| index = key_to_value_index[k.to_s] raise StatementInvalid, "no such column: #{k}" unless index if v.respond_to?(:to_a) v.to_a.any? { |vv| value[index] == vv.to_s } else value[index] == v.to_s end end when Condition::NotEqual cond.values.all? do |k, v| index = key_to_value_index[k.to_s] raise StatementInvalid, "no such column: #{k}" unless index if v.respond_to?(:to_a) !v.to_a.any? { |vv| value[index] == vv.to_s } else !(value[index] == v.to_s) end end end end end
to_value_a()
click to toggle source
# File lib/active_tsv/relation.rb, line 174 def to_value_a ret = each_value.to_a if @order_values.empty?.! key_to_value_index = @model.column_names.each_with_index.to_h if @order_values.one? order_condition = @order_values.first index = key_to_value_index[order_condition.column] ret.sort_by! { |i| i[index] } ret.reverse! if order_condition.descending? else ret.sort! do |a, b| @order_values.each.with_index(1) do |order_condition, index| comp = a[key_to_value_index[order_condition.column]] <=> b[key_to_value_index[order_condition.column]] break 0 if comp == 0 && index == @order_values.length break comp * order_condition.to_i if comp != 0 end end end end ret end