aboutsummaryrefslogtreecommitdiffstats
path: root/lib/active_relation
diff options
context:
space:
mode:
authorJosh Susser <josh@hasmanythrough.com>2008-03-15 18:13:46 -0700
committerJosh Susser <josh@hasmanythrough.com>2008-03-15 18:13:46 -0700
commit9c00e8b0f0dc422e4bf5efa3fb79cda2cb0ac6a1 (patch)
treea5ce787629563b0265be9d35c1adf3a9504a4012 /lib/active_relation
parent5d7c8176f1df8df819dadb1973a202a1c2d9836d (diff)
parentcd9efb9eec6198f08b4fd5d754a33aa1b1669b37 (diff)
downloadrails-9c00e8b0f0dc422e4bf5efa3fb79cda2cb0ac6a1.tar.gz
rails-9c00e8b0f0dc422e4bf5efa3fb79cda2cb0ac6a1.tar.bz2
rails-9c00e8b0f0dc422e4bf5efa3fb79cda2cb0ac6a1.zip
merge changes from nick
Diffstat (limited to 'lib/active_relation')
-rw-r--r--lib/active_relation/.DS_Storebin6148 -> 6148 bytes
-rw-r--r--lib/active_relation/extensions.rb1
-rw-r--r--lib/active_relation/extensions/array.rb2
-rw-r--r--lib/active_relation/extensions/class.rb17
-rw-r--r--lib/active_relation/extensions/object.rb2
-rw-r--r--lib/active_relation/predicates.rb2
-rw-r--r--lib/active_relation/primitives.rb2
-rw-r--r--lib/active_relation/primitives/attribute.rb13
-rw-r--r--lib/active_relation/primitives/value.rb (renamed from lib/active_relation/primitives/scalar.rb)10
-rw-r--r--lib/active_relation/relations.rb1
-rw-r--r--lib/active_relation/relations/compound.rb2
-rw-r--r--lib/active_relation/relations/deletion.rb6
-rw-r--r--lib/active_relation/relations/insertion.rb6
-rw-r--r--lib/active_relation/relations/join.rb2
-rw-r--r--lib/active_relation/relations/relation.rb43
-rw-r--r--lib/active_relation/relations/table.rb2
-rw-r--r--lib/active_relation/relations/update.rb6
-rw-r--r--lib/active_relation/relations/writing.rb5
-rw-r--r--lib/active_relation/sessions/session.rb8
-rw-r--r--lib/active_relation/sql.rb40
20 files changed, 108 insertions, 62 deletions
diff --git a/lib/active_relation/.DS_Store b/lib/active_relation/.DS_Store
index 2a449ff62e..9918127870 100644
--- a/lib/active_relation/.DS_Store
+++ b/lib/active_relation/.DS_Store
Binary files differ
diff --git a/lib/active_relation/extensions.rb b/lib/active_relation/extensions.rb
index 8a024947ed..7268a5549b 100644
--- a/lib/active_relation/extensions.rb
+++ b/lib/active_relation/extensions.rb
@@ -1,3 +1,4 @@
require 'active_relation/extensions/object'
+require 'active_relation/extensions/class'
require 'active_relation/extensions/array'
require 'active_relation/extensions/hash'
diff --git a/lib/active_relation/extensions/array.rb b/lib/active_relation/extensions/array.rb
index aa4354a78a..4bd20d8121 100644
--- a/lib/active_relation/extensions/array.rb
+++ b/lib/active_relation/extensions/array.rb
@@ -2,7 +2,7 @@ class Array
def to_hash
Hash[*flatten]
end
-
+
def to_sql(strategy = nil)
"(#{collect(&:to_sql).join(', ')})"
end
diff --git a/lib/active_relation/extensions/class.rb b/lib/active_relation/extensions/class.rb
new file mode 100644
index 0000000000..0e5b728c26
--- /dev/null
+++ b/lib/active_relation/extensions/class.rb
@@ -0,0 +1,17 @@
+class Class
+ def abstract(*methods)
+ methods.each do |method|
+ define_method method do
+ raise NotImplementedError
+ end
+ end
+ end
+
+ def hash_on(delegatee)
+ define_method :eql? do |other|
+ self == other
+ end
+
+ delegate :hash, :to => delegatee
+ end
+end \ No newline at end of file
diff --git a/lib/active_relation/extensions/object.rb b/lib/active_relation/extensions/object.rb
index d13cf9aabb..90eb73f0b0 100644
--- a/lib/active_relation/extensions/object.rb
+++ b/lib/active_relation/extensions/object.rb
@@ -1,6 +1,6 @@
class Object
def bind(relation)
- ActiveRelation::Scalar.new(self, relation)
+ ActiveRelation::Value.new(self, relation)
end
def metaclass
diff --git a/lib/active_relation/predicates.rb b/lib/active_relation/predicates.rb
index ba926a86e5..12ddd1b48d 100644
--- a/lib/active_relation/predicates.rb
+++ b/lib/active_relation/predicates.rb
@@ -25,7 +25,7 @@ module ActiveRelation
end
def to_sql(strategy = nil)
- "#{operand1.to_sql(operand2.strategy)} #{predicate_sql} #{operand2.to_sql(operand1.strategy)}"
+ "#{operand2.format(operand1)} #{predicate_sql} #{operand1.format(operand2)}"
end
def descend
diff --git a/lib/active_relation/primitives.rb b/lib/active_relation/primitives.rb
index 7629256034..9909734d24 100644
--- a/lib/active_relation/primitives.rb
+++ b/lib/active_relation/primitives.rb
@@ -1,4 +1,4 @@
require 'active_relation/primitives/attribute'
-require 'active_relation/primitives/scalar'
+require 'active_relation/primitives/value'
require 'active_relation/primitives/expression'
diff --git a/lib/active_relation/primitives/attribute.rb b/lib/active_relation/primitives/attribute.rb
index baaae1973c..0fed676727 100644
--- a/lib/active_relation/primitives/attribute.rb
+++ b/lib/active_relation/primitives/attribute.rb
@@ -48,10 +48,7 @@ module ActiveRelation
module Congruence
def self.included(klass)
- klass.class_eval do
- alias_method :eql?, :==
- delegate :hash, :to => :name
- end
+ klass.hash_on :name
end
def history
@@ -114,15 +111,19 @@ module ActiveRelation
end
include Expressions
- def to_sql(strategy = self.strategy)
+ def to_sql(strategy = Sql::WhereCondition.new(engine))
strategy.attribute prefix, name, self.alias
end
+ def format(object)
+ object.to_sql(strategy)
+ end
+
+ private
def strategy
Sql::Attribute.new(self)
end
- private
def prefix
relation.prefix_for(self)
end
diff --git a/lib/active_relation/primitives/scalar.rb b/lib/active_relation/primitives/value.rb
index fa88404ee3..096c876ecd 100644
--- a/lib/active_relation/primitives/scalar.rb
+++ b/lib/active_relation/primitives/value.rb
@@ -1,17 +1,17 @@
module ActiveRelation
- class Scalar
+ class Value
attr_reader :value, :relation
def initialize(value, relation)
@value, @relation = value, relation
end
- def to_sql(strategy = self.strategy)
- strategy.scalar value
+ def to_sql(strategy = Sql::WhereCondition.new(relation.engine))
+ strategy.value value
end
- def strategy
- ActiveRelation::Sql::Scalar.new(relation.engine)
+ def format(object)
+ object.to_sql(Sql::Value.new(relation.engine))
end
def ==(other)
diff --git a/lib/active_relation/relations.rb b/lib/active_relation/relations.rb
index f992fca8be..7776fd3d18 100644
--- a/lib/active_relation/relations.rb
+++ b/lib/active_relation/relations.rb
@@ -1,5 +1,6 @@
require 'active_relation/relations/relation'
require 'active_relation/relations/compound'
+require 'active_relation/relations/writing'
require 'active_relation/relations/table'
require 'active_relation/relations/join'
require 'active_relation/relations/aggregation'
diff --git a/lib/active_relation/relations/compound.rb b/lib/active_relation/relations/compound.rb
index a10b7588e7..fac0939c6f 100644
--- a/lib/active_relation/relations/compound.rb
+++ b/lib/active_relation/relations/compound.rb
@@ -1,5 +1,7 @@
module ActiveRelation
class Compound < Relation
+ abstract :==, :descend
+
attr_reader :relation
delegate :joins, :selects, :orders, :groupings, :table_sql, :inserts, :limit,
:offset, :name, :alias, :aggregation?, :alias?, :prefix_for, :column_for,
diff --git a/lib/active_relation/relations/deletion.rb b/lib/active_relation/relations/deletion.rb
index f3d81baf27..0fcf523efe 100644
--- a/lib/active_relation/relations/deletion.rb
+++ b/lib/active_relation/relations/deletion.rb
@@ -1,5 +1,5 @@
module ActiveRelation
- class Deletion < Compound
+ class Deletion < Writing
def initialize(relation)
@relation = relation
end
@@ -12,6 +12,10 @@ module ActiveRelation
].compact.join("\n")
end
+ def call(connection = engine.connection)
+ connection.delete(to_sql)
+ end
+
def ==(other)
self.class == other.class and
relation == other.relation
diff --git a/lib/active_relation/relations/insertion.rb b/lib/active_relation/relations/insertion.rb
index 16fe3d5f46..ce065b64c1 100644
--- a/lib/active_relation/relations/insertion.rb
+++ b/lib/active_relation/relations/insertion.rb
@@ -1,5 +1,5 @@
module ActiveRelation
- class Insertion < Compound
+ class Insertion < Writing
attr_reader :record
def initialize(relation, record)
@@ -15,6 +15,10 @@ module ActiveRelation
].join("\n")
end
+ def call(connection = engine.connection)
+ connection.insert(to_sql)
+ end
+
def ==(other)
self.class == other.class and
relation == other.relation and
diff --git a/lib/active_relation/relations/join.rb b/lib/active_relation/relations/join.rb
index 043b237de7..4a57795280 100644
--- a/lib/active_relation/relations/join.rb
+++ b/lib/active_relation/relations/join.rb
@@ -61,7 +61,7 @@ module ActiveRelation
delegate :engine, :to => :relation
def table_sql
- relation.aggregation?? relation.to_sql(Sql::Aggregation.new(engine)) : relation.send(:table_sql)
+ relation.aggregation?? relation.to_sql(Sql::TableReference.new(engine)) : relation.send(:table_sql)
end
def selects
diff --git a/lib/active_relation/relations/relation.rb b/lib/active_relation/relations/relation.rb
index 1c97cc7035..15782cde06 100644
--- a/lib/active_relation/relations/relation.rb
+++ b/lib/active_relation/relations/relation.rb
@@ -1,5 +1,7 @@
module ActiveRelation
class Relation
+ abstract :attributes, :selects, :orders, :inserts, :groupings, :joins, :limit, :offset, :alias
+
def session
Session.new
end
@@ -102,38 +104,41 @@ module ActiveRelation
false
end
- def eql?(other)
- self == other
- end
-
- def to_sql(strategy = Sql::Relation.new(engine))
+ def to_sql(strategy = Sql::SelectStatement.new(engine))
strategy.select [
- "SELECT #{attributes.collect{ |a| a.to_sql(Sql::Projection.new(engine)) }.join(', ')}",
+ "SELECT #{attributes.collect{ |a| a.to_sql(Sql::SelectExpression.new(engine)) }.join(', ')}",
"FROM #{table_sql}",
- (joins unless joins.blank? ),
- ("WHERE #{selects.collect{|s| s.to_sql(Sql::Selection.new(engine))}.join("\n\tAND ")}" unless selects.blank? ),
- ("ORDER BY #{orders.collect(&:to_sql)}" unless orders.blank? ),
- ("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank? ),
- ("LIMIT #{limit}" unless limit.blank? ),
- ("OFFSET #{offset}" unless offset.blank? )
+ (joins unless joins.blank? ),
+ ("WHERE #{selects.collect{|s| s.to_sql(Sql::WhereClause.new(engine))}.join("\n\tAND ")}" unless selects.blank? ),
+ ("ORDER BY #{orders.collect(&:to_sql)}" unless orders.blank? ),
+ ("GROUP BY #{groupings.collect(&:to_sql)}" unless groupings.blank? ),
+ ("LIMIT #{limit}" unless limit.blank? ),
+ ("OFFSET #{offset}" unless offset.blank? )
].compact.join("\n"), self.alias
end
alias_method :to_s, :to_sql
-
- def attribute_for_name(name)
- attributes.detect { |a| a.alias_or_name.to_s == name.to_s }
+
+ def call(connection = engine.connection)
+ connection.select_all(to_sql)
end
+
+ module AttributeAccessors
+ def attribute_for_name(name)
+ attributes.detect { |a| a.alias_or_name.to_s == name.to_s }
+ end
- def attribute_for_attribute(attribute)
- attributes.detect { |a| a =~ attribute }
+ def attribute_for_attribute(attribute)
+ attributes.detect { |a| a =~ attribute }
+ end
end
+ include AttributeAccessors
def bind(relation)
self
end
- def strategy
- Sql::Predicate.new(engine)
+ def format(object)
+ object.to_sql(Sql::WhereCondition.new(engine))
end
def attributes; [] end
diff --git a/lib/active_relation/relations/table.rb b/lib/active_relation/relations/table.rb
index 84eb1213ee..4682298608 100644
--- a/lib/active_relation/relations/table.rb
+++ b/lib/active_relation/relations/table.rb
@@ -3,7 +3,7 @@ module ActiveRelation
cattr_accessor :engine
attr_reader :name, :engine
- delegate :hash, :to => :name
+ hash_on :name
def initialize(name, engine = Table.engine)
@name, @engine = name.to_s, engine
diff --git a/lib/active_relation/relations/update.rb b/lib/active_relation/relations/update.rb
index c50919af3e..a51f248866 100644
--- a/lib/active_relation/relations/update.rb
+++ b/lib/active_relation/relations/update.rb
@@ -1,5 +1,5 @@
module ActiveRelation
- class Update < Compound
+ class Update < Writing
attr_reader :assignments
def initialize(relation, assignments)
@@ -16,6 +16,10 @@ module ActiveRelation
].join("\n")
end
+ def call(connection = engine.connection)
+ connection.update(to_sql)
+ end
+
def ==(other)
self.class == other.class and
relation == other.relation and
diff --git a/lib/active_relation/relations/writing.rb b/lib/active_relation/relations/writing.rb
new file mode 100644
index 0000000000..3054e9b72f
--- /dev/null
+++ b/lib/active_relation/relations/writing.rb
@@ -0,0 +1,5 @@
+module ActiveRelation
+ class Writing < Compound
+ abstract :call, :to_sql
+ end
+end \ No newline at end of file
diff --git a/lib/active_relation/sessions/session.rb b/lib/active_relation/sessions/session.rb
index 4bdbe69978..fe917a0e4d 100644
--- a/lib/active_relation/sessions/session.rb
+++ b/lib/active_relation/sessions/session.rb
@@ -25,22 +25,22 @@ module ActiveRelation
module CRUD
def create(insert)
- insert.engine.insert(insert.to_sql)
+ insert.call(insert.engine.connection)
end
def read(select)
@read ||= Hash.new do |hash, select|
- hash[select] = select.engine.select_all(select.to_sql)
+ hash[select] = select.call(select.engine.connection)
end
@read[select]
end
def update(update)
- update.engine.update(update.to_sql)
+ update.call(update.engine.connection)
end
def delete(delete)
- delete.engine.delete(delete.to_sql)
+ delete.call(delete.engine.connection)
end
end
include CRUD
diff --git a/lib/active_relation/sql.rb b/lib/active_relation/sql.rb
index 99cfc66383..0d233b307e 100644
--- a/lib/active_relation/sql.rb
+++ b/lib/active_relation/sql.rb
@@ -4,9 +4,11 @@ module ActiveRelation
delegate :quote_table_name, :quote_column_name, :quote, :to => :engine
end
- # module Formatting Context / Strategy # unit test me!!!
- class Strategy
+ class Formatter
+ abstract :attribute, :select, :value
+
attr_reader :engine
+
include Quoting
def initialize(engine)
@@ -14,7 +16,7 @@ module ActiveRelation
end
end
- class Projection < Strategy
+ class SelectExpression < Formatter
def attribute(relation_name, attribute_name, aliaz)
"#{quote_table_name(relation_name)}.#{quote_column_name(attribute_name)}" + (aliaz ? " AS #{quote(aliaz.to_s)}" : "")
end
@@ -24,13 +26,19 @@ module ActiveRelation
end
end
- class Predicate < Strategy
+ class WhereClause < Formatter
+ def value(value)
+ value
+ end
+ end
+
+ class WhereCondition < Formatter
def attribute(relation_name, attribute_name, aliaz)
"#{quote_table_name(relation_name)}.#{quote_column_name(attribute_name)}"
end
- def scalar(scalar, column = nil)
- quote(scalar, column)
+ def value(value, column = nil)
+ quote(value, column)
end
def select(select_sql, aliaz)
@@ -38,35 +46,29 @@ module ActiveRelation
end
end
- class Selection < Strategy
- def scalar(scalar)
- scalar
- end
- end
-
- class Relation < Strategy
+ class SelectStatement < Formatter
def select(select_sql, aliaz)
select_sql
end
end
- class Aggregation < Strategy
+ class TableReference < Formatter
def select(select_sql, aliaz)
- "(#{select_sql}) AS #{engine.quote_table_name(aliaz)}"
+ "(#{select_sql}) AS #{quote_table_name(aliaz)}"
end
end
- class Attribute < Predicate
+ class Attribute < WhereCondition
def initialize(attribute)
@attribute, @engine = attribute, attribute.engine
end
- def scalar(scalar)
- quote(scalar, @attribute.column)
+ def value(value)
+ quote(value, @attribute.column)
end
end
- class Scalar < Predicate
+ class Value < WhereCondition
end
end
end \ No newline at end of file