Module: Bmg::Relation

Includes:
Algebra, Enumerable
Included in:
Operator, Reader, Empty, InMemory, Sql::Relation
Defined in:
lib/bmg/writer/xlsx.rb,
lib/bmg/relation.rb,
lib/bmg/relation/empty.rb,
lib/bmg/relation/proxy.rb,
lib/bmg/relation/spied.rb,
lib/bmg/relation/in_memory.rb,
lib/bmg/relation/materialized.rb,
lib/bmg/relation/in_memory/mutable.rb

Overview

module Writer

Defined Under Namespace

Modules: Proxy Classes: Empty, InMemory, Materialized, Spied

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Algebra

#allbut, #autosummarize, #autowrap, #constants, #extend, #group, #image, #join, #left_join, #matching, #materialize, #not_matching, #page, #project, #rename, #restrict, #spied, #summarize, #transform, #ungroup, #union, #unspied, #unwrap

Methods included from Algebra::Shortcuts

#exclude, #image, #images, #join, #left_join, #matching, #not_matching, #prefix, #rxmatch, #suffix, #ungroup, #unwrap, #where

Class Method Details

.empty(type = Type::ANY) ⇒ Object

Raises:

  • (ArgumentError)


11
12
13
14
# File 'lib/bmg/relation.rb', line 11

def self.empty(type = Type::ANY)
  raise ArgumentError, "Missing type" if type.nil?
  Relation::Empty.new(type)
end

.new(operand, type = Type::ANY) ⇒ Object

Raises:

  • (ArgumentError)


6
7
8
9
# File 'lib/bmg/relation.rb', line 6

def self.new(operand, type = Type::ANY)
  raise ArgumentError, "Missing type" if type.nil?
  operand.is_a?(Relation) ? operand : Bmg.in_memory(operand, type)
end

Instance Method Details

#_countObject



127
128
129
# File 'lib/bmg/relation.rb', line 127

def _count
  to_a.size
end

#bind(binding) ⇒ Object



16
17
18
# File 'lib/bmg/relation.rb', line 16

def bind(binding)
  self
end

#countObject



119
120
121
122
123
124
125
# File 'lib/bmg/relation.rb', line 119

def count
  if type.knows_keys?
    project(type.keys.first)._count
  else
    self._count
  end
end

#debug(max_level = nil, on = STDERR) ⇒ Object

Returns a String representing the query plan



156
157
158
159
# File 'lib/bmg/relation.rb', line 156

def debug(max_level = nil, on = STDERR)
  on.puts(self.inspect)
  self
end

#delete(*args, &bl) ⇒ Object

Raises:



85
86
87
# File 'lib/bmg/relation.rb', line 85

def delete(*args, &bl)
  raise InvalidUpdateError, "Cannot delete from #{self.class.name}"
end

#empty?Boolean

Returns:

  • (Boolean)


48
49
50
51
# File 'lib/bmg/relation.rb', line 48

def empty?
  each{|t| return false }
  true
end

#insert(*args, &bl) ⇒ Object

Raises:



77
78
79
# File 'lib/bmg/relation.rb', line 77

def insert(*args, &bl)
  raise InvalidUpdateError, "Cannot insert into #{self.class.name}"
end

#oneObject

Returns the only tuple that the relation contains. Throws a OneException when there is no tuple or more than one



66
67
68
# File 'lib/bmg/relation.rb', line 66

def one
  one_or_yield{ raise OneError, "Relation is empty" }
end

#one_or_nilObject

Returns the only tuple that the relation contains. Returns nil if the relation is empty. Throws a OneException when the relation contains more than one tuple



73
74
75
# File 'lib/bmg/relation.rb', line 73

def one_or_nil
  one_or_yield{ nil }
end

#to_astObject

Converts to an sexpr expression.



151
152
153
# File 'lib/bmg/relation.rb', line 151

def to_ast
  raise "Bmg is missing a feature!"
end

#to_csv(options = {}, string_or_io = nil, preferences = nil) ⇒ Object

Writes the relation data to CSV.

‘string_or_io` and `options` are what CSV::new itself recognizes, default options are CSV’s.

When no string_or_io is used, the method uses a string.

The method always returns the string_or_io.



144
145
146
147
148
# File 'lib/bmg/relation.rb', line 144

def to_csv(options = {}, string_or_io = nil, preferences = nil)
  options, string_or_io = {}, options unless options.is_a?(Hash)
  string_or_io, preferences = nil, string_or_io if string_or_io.is_a?(Hash)
  Writer::Csv.new(options, preferences).call(self, string_or_io)
end

#to_json(*args, &bl) ⇒ Object

Returns a json representation



132
133
134
# File 'lib/bmg/relation.rb', line 132

def to_json(*args, &bl)
  to_a.to_json(*args, &bl)
end

#to_xlsx(options = {}, path = nil, preferences = nil) ⇒ Object



62
63
64
65
# File 'lib/bmg/writer/xlsx.rb', line 62

def to_xlsx(options = {}, path = nil, preferences = nil)
  options, path = {}, options unless options.is_a?(Hash)
  Writer::Xlsx.new(options, preferences).call(self, path)
end

#typeObject



20
21
22
# File 'lib/bmg/relation.rb', line 20

def type
  Bmg::Type::ANY
end

#update(*args, &bl) ⇒ Object

Raises:



81
82
83
# File 'lib/bmg/relation.rb', line 81

def update(*args, &bl)
  raise InvalidUpdateError, "Cannot update #{self.class.name}"
end

#visit(&visitor) ⇒ Object



89
90
91
# File 'lib/bmg/relation.rb', line 89

def visit(&visitor)
  _visit(nil, visitor)
end

#with_type(type) ⇒ Object



24
25
26
27
28
# File 'lib/bmg/relation.rb', line 24

def with_type(type)
  dup.tap{|r|
    r.type = type
  }
end

#with_type_attrlistObject



30
31
32
33
34
# File 'lib/bmg/relation.rb', line 30

def with_type_attrlist
  return self if type.knows_attrlist?
  attrs = self.first.keys
  with_type(type.with_attrlist(attrs))
end

#with_typecheckObject



36
37
38
39
40
# File 'lib/bmg/relation.rb', line 36

def with_typecheck
  dup.tap{|r|
    r.type = r.type.with_typecheck
  }
end

#without_typecheckObject



42
43
44
45
46
# File 'lib/bmg/relation.rb', line 42

def without_typecheck
  dup.tap{|r|
    r.type = r.type.with_typecheck
  }
end

#y_by_x(y, x, options = {}) ⇒ Object



98
99
100
101
102
# File 'lib/bmg/relation.rb', line 98

def y_by_x(y, x, options = {})
  each_with_object({}) do |tuple, h|
    h[tuple[x]] = tuple[y]
  end
end

#ys_by_x(y, x, options = {}) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/bmg/relation.rb', line 104

def ys_by_x(y, x, options = {})
  ordering = options[:order]
  projection = [y, ordering].compact.uniq
  by_x = each_with_object({}) do |tuple,h|
    h[tuple[x]] ||= []
    h[tuple[x]] << TupleAlgebra.project(tuple, projection)
  end
  by_x.each_with_object({}) do |(x,ys),h|
    ys = ys.sort{|y1,y2| y1[ordering] <=> y2[ordering] } if ordering
    ys = ys.map{|t| t[y] }
    ys = ys.uniq if options[:distinct]
    h[x] = ys
  end
end