diff options
Diffstat (limited to 'lib/arel/engines/memory')
-rw-r--r-- | lib/arel/engines/memory/engine.rb | 16 | ||||
-rw-r--r-- | lib/arel/engines/memory/predicates.rb | 35 | ||||
-rw-r--r-- | lib/arel/engines/memory/primitives.rb | 27 | ||||
-rw-r--r-- | lib/arel/engines/memory/relations.rb | 5 | ||||
-rw-r--r-- | lib/arel/engines/memory/relations/array.rb | 25 | ||||
-rw-r--r-- | lib/arel/engines/memory/relations/compound.rb | 9 | ||||
-rw-r--r-- | lib/arel/engines/memory/relations/operations.rb | 61 | ||||
-rw-r--r-- | lib/arel/engines/memory/relations/writes.rb | 7 |
8 files changed, 185 insertions, 0 deletions
diff --git a/lib/arel/engines/memory/engine.rb b/lib/arel/engines/memory/engine.rb new file mode 100644 index 0000000000..c7ac9422d4 --- /dev/null +++ b/lib/arel/engines/memory/engine.rb @@ -0,0 +1,16 @@ +module Arel + module Memory + class Engine + module CRUD + def read(relation) + relation.eval + end + + def create(relation) + relation.eval + end + end + include CRUD + end + end +end diff --git a/lib/arel/engines/memory/predicates.rb b/lib/arel/engines/memory/predicates.rb new file mode 100644 index 0000000000..03d4f25b0a --- /dev/null +++ b/lib/arel/engines/memory/predicates.rb @@ -0,0 +1,35 @@ +module Arel + class Binary < Predicate + def eval(row) + operand1.eval(row).send(operator, operand2.eval(row)) + end + end + + class Equality < Binary + def operator; :== end + end + + class GreaterThanOrEqualTo < Binary + def operator; :>= end + end + + class GreaterThan < Binary + def operator; :> end + end + + class LessThanOrEqualTo < Binary + def operator; :<= end + end + + class LessThan < Binary + def operator; :< end + end + + class Match < Binary + def operator; :=~ end + end + + class In < Binary + def operator; :include? end + end +end diff --git a/lib/arel/engines/memory/primitives.rb b/lib/arel/engines/memory/primitives.rb new file mode 100644 index 0000000000..935b34f5ee --- /dev/null +++ b/lib/arel/engines/memory/primitives.rb @@ -0,0 +1,27 @@ +module Arel + class Attribute + def eval(row) + row[self] + end + end + + class Value + def eval(row) + value + end + end + + class Ordering + def eval(row1, row2) + (attribute.eval(row1) <=> attribute.eval(row2)) * direction + end + end + + class Descending < Ordering + def direction; -1 end + end + + class Ascending < Ordering + def direction; 1 end + end +end diff --git a/lib/arel/engines/memory/relations.rb b/lib/arel/engines/memory/relations.rb new file mode 100644 index 0000000000..c67af2d63b --- /dev/null +++ b/lib/arel/engines/memory/relations.rb @@ -0,0 +1,5 @@ +require 'arel/engines/memory/relations/array' +require 'arel/engines/memory/relations/operations' +require 'arel/engines/memory/relations/writes' +require 'arel/engines/memory/relations/compound' + diff --git a/lib/arel/engines/memory/relations/array.rb b/lib/arel/engines/memory/relations/array.rb new file mode 100644 index 0000000000..5e7c0a4ab1 --- /dev/null +++ b/lib/arel/engines/memory/relations/array.rb @@ -0,0 +1,25 @@ +module Arel + class Array < Relation + attributes :array, :attribute_names + include Recursion::BaseCase + deriving :==, :initialize + + def engine + @engine ||= Memory::Engine.new + end + + def attributes + @attributes ||= @attribute_names.collect do |name| + name.to_attribute(self) + end + end + + def format(attribute, value) + value + end + + def eval + @array.collect { |r| Row.new(self, r) } + end + end +end diff --git a/lib/arel/engines/memory/relations/compound.rb b/lib/arel/engines/memory/relations/compound.rb new file mode 100644 index 0000000000..6dda92a6a1 --- /dev/null +++ b/lib/arel/engines/memory/relations/compound.rb @@ -0,0 +1,9 @@ +module Arel + class Compound < Relation + delegate :array, :to => :relation + + def unoperated_rows + relation.call.collect { |row| row.bind(self) } + end + end +end diff --git a/lib/arel/engines/memory/relations/operations.rb b/lib/arel/engines/memory/relations/operations.rb new file mode 100644 index 0000000000..8e01938360 --- /dev/null +++ b/lib/arel/engines/memory/relations/operations.rb @@ -0,0 +1,61 @@ +module Arel + class Where < Compound + def eval + unoperated_rows.select { |row| predicate.eval(row) } + end + end + + class Order < Compound + def eval + unoperated_rows.sort do |row1, row2| + ordering = orderings.detect { |o| o.eval(row1, row2) != 0 } || orderings.last + ordering.eval(row1, row2) + end + end + end + + class Project < Compound + def eval + unoperated_rows.collect { |r| r.slice(*projections) } + end + end + + class Take < Compound + def eval + unoperated_rows[0, taken] + end + end + + class Skip < Compound + def eval + unoperated_rows[skipped..-1] + end + end + + class Group < Compound + def eval + raise NotImplementedError + end + end + + class Alias < Compound + def eval + unoperated_rows + end + end + + class Join < Relation + def eval + result = [] + relation1.call.each do |row1| + relation2.call.each do |row2| + combined_row = row1.combine(row2, self) + if predicates.all? { |p| p.eval(combined_row) } + result << combined_row + end + end + end + result + end + end +end diff --git a/lib/arel/engines/memory/relations/writes.rb b/lib/arel/engines/memory/relations/writes.rb new file mode 100644 index 0000000000..12c4f36c0d --- /dev/null +++ b/lib/arel/engines/memory/relations/writes.rb @@ -0,0 +1,7 @@ +module Arel + class Insert < Compound + def eval + unoperated_rows + [Row.new(self, record.values.collect(&:value))] + end + end +end |