aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sql_algebra
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sql_algebra')
-rw-r--r--lib/sql_algebra/predicates/binary_predicate.rb5
-rw-r--r--lib/sql_algebra/relations/attribute.rb12
-rw-r--r--lib/sql_algebra/relations/inner_join_operation.rb6
-rw-r--r--lib/sql_algebra/relations/inner_join_relation.rb5
-rw-r--r--lib/sql_algebra/relations/left_outer_join_operation.rb6
-rw-r--r--lib/sql_algebra/relations/left_outer_join_relation.rb5
-rw-r--r--lib/sql_algebra/relations/order_relation.rb4
-rw-r--r--lib/sql_algebra/relations/projection_relation.rb4
-rw-r--r--lib/sql_algebra/relations/selection_relation.rb2
-rw-r--r--lib/sql_algebra/relations/table_relation.rb2
-rw-r--r--lib/sql_algebra/sql_builder/conditions_builder.rb16
-rw-r--r--lib/sql_algebra/sql_builder/equals_condition_builder.rb18
-rw-r--r--lib/sql_algebra/sql_builder/inner_join_builder.rb5
-rw-r--r--lib/sql_algebra/sql_builder/join_builder.rb13
-rw-r--r--lib/sql_algebra/sql_builder/joins_builder.rb18
-rw-r--r--lib/sql_algebra/sql_builder/left_outer_join_builder.rb5
-rw-r--r--lib/sql_algebra/sql_builder/select_builder.rb63
-rw-r--r--lib/sql_algebra/sql_builder/sql_builder.rb28
-rw-r--r--lib/sql_algebra/sql_builder/sql_builder_adapter.rb22
19 files changed, 230 insertions, 9 deletions
diff --git a/lib/sql_algebra/predicates/binary_predicate.rb b/lib/sql_algebra/predicates/binary_predicate.rb
index 3e5b9ce193..9463f162c5 100644
--- a/lib/sql_algebra/predicates/binary_predicate.rb
+++ b/lib/sql_algebra/predicates/binary_predicate.rb
@@ -12,7 +12,10 @@ class BinaryPredicate < Predicate
def to_sql(builder = ConditionsBuilder.new)
builder.call do
- send(predicate_name, attribute1.to_sql(self), attribute2.to_sql(self))
+ send(predicate_name) do
+ attribute1.to_sql(self)
+ attribute2.to_sql(self)
+ end
end
end
end \ No newline at end of file
diff --git a/lib/sql_algebra/relations/attribute.rb b/lib/sql_algebra/relations/attribute.rb
index af448286f1..85d40dfb12 100644
--- a/lib/sql_algebra/relations/attribute.rb
+++ b/lib/sql_algebra/relations/attribute.rb
@@ -1,8 +1,8 @@
class Attribute
- attr_reader :relation, :attribute_name
+ attr_reader :relation, :attribute_name, :aliaz
- def initialize(relation, attribute_name)
- @relation, @attribute_name = relation, attribute_name
+ def initialize(relation, attribute_name, aliaz = nil)
+ @relation, @attribute_name, @aliaz = relation, attribute_name, aliaz
end
def eql?(other)
@@ -33,7 +33,9 @@ class Attribute
MatchPredicate.new(self, regexp)
end
- def to_sql(ignore_builder_because_i_can_only_exist_atomically = nil)
- ColumnBuilder.new(relation.table, attribute_name)
+ def to_sql(builder = SelectsBuilder.new)
+ builder.call do
+ column relation.table, attribute_name, aliaz
+ end
end
end \ No newline at end of file
diff --git a/lib/sql_algebra/relations/inner_join_operation.rb b/lib/sql_algebra/relations/inner_join_operation.rb
new file mode 100644
index 0000000000..6b5c5ce8d0
--- /dev/null
+++ b/lib/sql_algebra/relations/inner_join_operation.rb
@@ -0,0 +1,6 @@
+class InnerJoinOperation < JoinOperation
+ protected
+ def relation_class
+ InnerJoinRelation
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/relations/inner_join_relation.rb b/lib/sql_algebra/relations/inner_join_relation.rb
new file mode 100644
index 0000000000..1ef965a6f5
--- /dev/null
+++ b/lib/sql_algebra/relations/inner_join_relation.rb
@@ -0,0 +1,5 @@
+class InnerJoinRelation < JoinRelation
+ def join_name
+ :inner_join
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/relations/left_outer_join_operation.rb b/lib/sql_algebra/relations/left_outer_join_operation.rb
new file mode 100644
index 0000000000..fbb2a4e2ed
--- /dev/null
+++ b/lib/sql_algebra/relations/left_outer_join_operation.rb
@@ -0,0 +1,6 @@
+class LeftOuterJoinOperation < JoinOperation
+ protected
+ def relation_class
+ LeftOuterJoinRelation
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/relations/left_outer_join_relation.rb b/lib/sql_algebra/relations/left_outer_join_relation.rb
new file mode 100644
index 0000000000..c7722c394d
--- /dev/null
+++ b/lib/sql_algebra/relations/left_outer_join_relation.rb
@@ -0,0 +1,5 @@
+class LeftOuterJoinRelation < JoinRelation
+ def join_name
+ :left_outer_join
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/relations/order_relation.rb b/lib/sql_algebra/relations/order_relation.rb
index e3c29dcc27..384a007bc2 100644
--- a/lib/sql_algebra/relations/order_relation.rb
+++ b/lib/sql_algebra/relations/order_relation.rb
@@ -12,7 +12,9 @@ class OrderRelation < Relation
def to_sql(builder = SelectBuilder.new)
relation.to_sql(builder).call do
attributes.each do |attribute|
- order_by attribute.to_sql(self)
+ order_by do
+ attribute.to_sql(self)
+ end
end
end
end
diff --git a/lib/sql_algebra/relations/projection_relation.rb b/lib/sql_algebra/relations/projection_relation.rb
index ca5f0bfca4..0b5d645d79 100644
--- a/lib/sql_algebra/relations/projection_relation.rb
+++ b/lib/sql_algebra/relations/projection_relation.rb
@@ -11,7 +11,9 @@ class ProjectionRelation < Relation
def to_sql(builder = SelectBuilder.new)
relation.to_sql(builder).call do
- select attributes.collect { |a| a.to_sql(self) }
+ select do
+ attributes.collect { |a| a.to_sql(self) }
+ end
end
end
end \ No newline at end of file
diff --git a/lib/sql_algebra/relations/selection_relation.rb b/lib/sql_algebra/relations/selection_relation.rb
index cce93917c4..51461de7d2 100644
--- a/lib/sql_algebra/relations/selection_relation.rb
+++ b/lib/sql_algebra/relations/selection_relation.rb
@@ -17,4 +17,6 @@ class SelectionRelation < Relation
end
end
end
+
+ delegate :[], :to => :relation
end \ No newline at end of file
diff --git a/lib/sql_algebra/relations/table_relation.rb b/lib/sql_algebra/relations/table_relation.rb
index eee24e5d68..60bdfda8ee 100644
--- a/lib/sql_algebra/relations/table_relation.rb
+++ b/lib/sql_algebra/relations/table_relation.rb
@@ -7,7 +7,7 @@ class TableRelation < Relation
def to_sql(builder = SelectBuilder.new)
builder.call do
- select :*
+ select { all }
from table
end
end
diff --git a/lib/sql_algebra/sql_builder/conditions_builder.rb b/lib/sql_algebra/sql_builder/conditions_builder.rb
new file mode 100644
index 0000000000..5d42a36cec
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/conditions_builder.rb
@@ -0,0 +1,16 @@
+class ConditionsBuilder < SqlBuilder
+ def initialize(&block)
+ @conditions = []
+ super(&block)
+ end
+
+ def equals(&block)
+ @conditions << EqualsConditionBuilder.new(&block)
+ end
+
+ def to_s
+ @conditions.join(' AND ')
+ end
+
+ delegate :blank?, :to => :@conditions
+end \ No newline at end of file
diff --git a/lib/sql_algebra/sql_builder/equals_condition_builder.rb b/lib/sql_algebra/sql_builder/equals_condition_builder.rb
new file mode 100644
index 0000000000..016395556a
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/equals_condition_builder.rb
@@ -0,0 +1,18 @@
+class EqualsConditionBuilder < SqlBuilder
+ def initialize(&block)
+ @operands = []
+ super(&block)
+ end
+
+ def column(table, column, aliaz = nil)
+ @operands << (aliaz ? aliaz : "#{table}.#{column}")
+ end
+
+ def value(value)
+ @operands << value
+ end
+
+ def to_s
+ "#{@operands[0]} = #{@operands[1]}"
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/sql_builder/inner_join_builder.rb b/lib/sql_algebra/sql_builder/inner_join_builder.rb
new file mode 100644
index 0000000000..6aec703325
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/inner_join_builder.rb
@@ -0,0 +1,5 @@
+class InnerJoinBuilder < JoinBuilder
+ def join_type
+ "INNER JOIN"
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/sql_builder/join_builder.rb b/lib/sql_algebra/sql_builder/join_builder.rb
new file mode 100644
index 0000000000..28f4437dec
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/join_builder.rb
@@ -0,0 +1,13 @@
+class JoinBuilder < SqlBuilder
+ def initialize(table, &block)
+ @table = table
+ @conditions = ConditionsBuilder.new
+ super(&block)
+ end
+
+ delegate :call, :to => :@conditions
+
+ def to_s
+ "#{join_type} #{@table} ON #{@conditions}"
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/sql_builder/joins_builder.rb b/lib/sql_algebra/sql_builder/joins_builder.rb
new file mode 100644
index 0000000000..36a92e9922
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/joins_builder.rb
@@ -0,0 +1,18 @@
+class JoinsBuilder < SqlBuilder
+ def initialize(&block)
+ @joins = []
+ super(&block)
+ end
+
+ def inner_join(table, &block)
+ @joins << InnerJoinBuilder.new(table, &block)
+ end
+
+ def left_outer_join(table, &block)
+ @joins << LeftOuterJoinBuilder.new(table, &block)
+ end
+
+ def to_s
+ @joins.join(' ')
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/sql_builder/left_outer_join_builder.rb b/lib/sql_algebra/sql_builder/left_outer_join_builder.rb
new file mode 100644
index 0000000000..dad3f85810
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/left_outer_join_builder.rb
@@ -0,0 +1,5 @@
+class LeftOuterJoinBuilder < JoinBuilder
+ def join_type
+ "LEFT OUTER JOIN"
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/sql_builder/select_builder.rb b/lib/sql_algebra/sql_builder/select_builder.rb
new file mode 100644
index 0000000000..d4eb4feb56
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/select_builder.rb
@@ -0,0 +1,63 @@
+class SelectBuilder < SqlBuilder
+ def select(&block)
+ @selects = SelectsBuilder.new(&block)
+ end
+
+ def from(table, &block)
+ @table = table
+ @joins = JoinsBuilder.new(&block)
+ end
+ delegate :inner_join, :left_outer_join, :to => :@joins
+
+ def where(&block)
+ @conditions ||= ConditionsBuilder.new
+ @conditions.call(&block)
+ end
+
+ def order_by(&block)
+ @orders = OrderBuilder.new(&block)
+ end
+
+ def limit(i, offset = nil)
+ @limit = i
+ offset(offset) if offset
+ end
+
+ def offset(i)
+ @offset = i
+ end
+
+ def to_s
+ [select_clause,
+ from_clause,
+ where_clause,
+ order_by_clause,
+ limit_clause,
+ offset_clause].compact.join("\n")
+ end
+
+ private
+ def select_clause
+ "SELECT #{@selects}" unless @selects.blank?
+ end
+
+ def from_clause
+ "FROM #{@table} #{@joins}" unless @table.blank?
+ end
+
+ def where_clause
+ "WHERE #{@conditions}" unless @conditions.blank?
+ end
+
+ def order_by_clause
+ "ORDER BY #{@orders}" unless @orders.blank?
+ end
+
+ def limit_clause
+ "LIMIT #{@limit}" unless @limit.blank?
+ end
+
+ def offset_clause
+ "OFFSET #{@offset}" unless @offset.blank?
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/sql_builder/sql_builder.rb b/lib/sql_algebra/sql_builder/sql_builder.rb
new file mode 100644
index 0000000000..5cfbe578d5
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/sql_builder.rb
@@ -0,0 +1,28 @@
+class SqlBuilder
+ def initialize(&block)
+ @callers = []
+ call(&block) if block
+ end
+
+ def method_missing(method, *args)
+ @callers.last.send(method, *args)
+ end
+
+ def ==(other)
+ to_s == other.to_s
+ end
+
+ def to_s
+ end
+
+ def call(&block)
+ returning self do |builder|
+ @callers << eval("self", block.binding)
+ begin
+ instance_eval &block
+ ensure
+ @callers.pop
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/sql_algebra/sql_builder/sql_builder_adapter.rb b/lib/sql_algebra/sql_builder/sql_builder_adapter.rb
new file mode 100644
index 0000000000..9bb5271f33
--- /dev/null
+++ b/lib/sql_algebra/sql_builder/sql_builder_adapter.rb
@@ -0,0 +1,22 @@
+class SqlBuilderAdapter
+ instance_methods.each { |m| undef_method m unless m =~ /^__|^instance_eval|class/ }
+
+ def initialize(adaptee, &block)
+ @adaptee = adaptee
+ (class << self; self end).class_eval do
+ (adaptee.methods - instance_methods).each { |m| delegate m, :to => :@adaptee }
+ end
+ (class << self; self end).instance_exec(@adaptee, &block)
+ end
+
+ def call(&block)
+ @caller = eval("self", block.binding)
+ returning self do |adapter|
+ instance_eval(&block)
+ end
+ end
+
+ def method_missing(method, *args, &block)
+ @caller.send(method, *args, &block)
+ end
+end \ No newline at end of file