mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Removed lib to avoid any conflict in merge
This commit is contained in:
parent
4b8526dddd
commit
ae1e0ac5e9
41 changed files with 0 additions and 1144 deletions
16
lib/arel.rb
16
lib/arel.rb
|
@ -1,16 +0,0 @@
|
|||
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
||||
|
||||
require 'rubygems'
|
||||
require 'active_support'
|
||||
require 'active_support/core_ext'
|
||||
require 'activerecord'
|
||||
require 'active_record/connection_adapters/abstract/quoting'
|
||||
|
||||
require 'arel/arel'
|
||||
require 'arel/extensions'
|
||||
require 'arel/sql'
|
||||
require 'arel/predicates'
|
||||
require 'arel/relations'
|
||||
require 'arel/engine'
|
||||
require 'arel/session'
|
||||
require 'arel/primitives'
|
BIN
lib/arel/.DS_Store
vendored
BIN
lib/arel/.DS_Store
vendored
Binary file not shown.
|
@ -1,3 +0,0 @@
|
|||
def Arel(name, engine = (Arel::Table.engine || ActiveRecord::Base.connection))
|
||||
Arel::Table.new(name, engine)
|
||||
end
|
|
@ -1,18 +0,0 @@
|
|||
module Arel
|
||||
# this file is currently just a hack to adapt between activerecord::base which holds the connection specification
|
||||
# and active relation. ultimately, this file should be in effect what the connection specification is in active record;
|
||||
# that is: a spec of the database (url, password, etc.), a quoting adapter layer, and a connection pool.
|
||||
class Engine
|
||||
def initialize(ar = nil)
|
||||
@ar = ar
|
||||
end
|
||||
|
||||
def connection
|
||||
@ar.connection
|
||||
end
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
@ar.connection.send(method, *args, &block)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,6 +0,0 @@
|
|||
require 'arel/extensions/object'
|
||||
require 'arel/extensions/class'
|
||||
require 'arel/extensions/array'
|
||||
require 'arel/extensions/hash'
|
||||
require 'arel/extensions/range'
|
||||
require 'arel/extensions/nil_class'
|
|
@ -1,13 +0,0 @@
|
|||
class Array
|
||||
def to_hash
|
||||
Hash[*flatten]
|
||||
end
|
||||
|
||||
def to_sql(formatter = nil)
|
||||
"(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")"
|
||||
end
|
||||
|
||||
def inclusion_predicate_sql
|
||||
"IN"
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
class Class
|
||||
def attributes(*attrs)
|
||||
@attributes = attrs
|
||||
attr_reader *attrs
|
||||
end
|
||||
|
||||
def deriving(*methods)
|
||||
methods.each { |m| derive m }
|
||||
end
|
||||
|
||||
def derive(method_name)
|
||||
methods = {
|
||||
:initialize => "
|
||||
def #{method_name}(#{@attributes.join(',')})
|
||||
#{@attributes.collect { |a| "@#{a} = #{a}" }.join("\n")}
|
||||
end
|
||||
",
|
||||
:== => "
|
||||
def ==(other)
|
||||
#{name} === other &&
|
||||
#{@attributes.collect { |a| "@#{a} == other.#{a}" }.join(" &&\n")}
|
||||
end
|
||||
"
|
||||
}
|
||||
class_eval methods[method_name], __FILE__, __LINE__
|
||||
end
|
||||
|
||||
def hash_on(delegatee)
|
||||
define_method :eql? do |other|
|
||||
self == other
|
||||
end
|
||||
|
||||
define_method :hash do
|
||||
@hash ||= delegatee.hash
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
class Hash
|
||||
def bind(relation)
|
||||
inject({}) do |bound, (key, value)|
|
||||
bound.merge(key.bind(relation) => value.bind(relation))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
class NilClass
|
||||
def equality_predicate_sql
|
||||
'IS'
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
class Object
|
||||
def bind(relation)
|
||||
Arel::Value.new(self, relation)
|
||||
end
|
||||
|
||||
def find_correlate_in(relation)
|
||||
bind(relation)
|
||||
end
|
||||
|
||||
def to_sql(formatter)
|
||||
formatter.scalar self
|
||||
end
|
||||
|
||||
def equality_predicate_sql
|
||||
'='
|
||||
end
|
||||
|
||||
def metaclass
|
||||
class << self
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,9 +0,0 @@
|
|||
class Range
|
||||
def to_sql(formatter = nil)
|
||||
formatter.range self.begin, self.end
|
||||
end
|
||||
|
||||
def inclusion_predicate_sql
|
||||
"BETWEEN"
|
||||
end
|
||||
end
|
|
@ -1,81 +0,0 @@
|
|||
module Arel
|
||||
class Predicate
|
||||
def or(other_predicate)
|
||||
Or.new(self, other_predicate)
|
||||
end
|
||||
|
||||
def and(other_predicate)
|
||||
And.new(self, other_predicate)
|
||||
end
|
||||
end
|
||||
|
||||
class Binary < Predicate
|
||||
attributes :operand1, :operand2
|
||||
deriving :initialize
|
||||
|
||||
def ==(other)
|
||||
self.class === other and
|
||||
@operand1 == other.operand1 and
|
||||
@operand2 == other.operand2
|
||||
end
|
||||
|
||||
def bind(relation)
|
||||
self.class.new(operand1.find_correlate_in(relation), operand2.find_correlate_in(relation))
|
||||
end
|
||||
|
||||
def to_sql(formatter = nil)
|
||||
"#{operand1.to_sql} #{predicate_sql} #{operand1.format(operand2)}"
|
||||
end
|
||||
alias_method :to_s, :to_sql
|
||||
end
|
||||
|
||||
class CompoundPredicate < Binary
|
||||
def to_sql(formatter = nil)
|
||||
"(#{operand1.to_sql(formatter)} #{predicate_sql} #{operand2.to_sql(formatter)})"
|
||||
end
|
||||
end
|
||||
|
||||
class Or < CompoundPredicate
|
||||
def predicate_sql; "OR" end
|
||||
end
|
||||
|
||||
class And < CompoundPredicate
|
||||
def predicate_sql; "AND" end
|
||||
end
|
||||
|
||||
class Equality < Binary
|
||||
def ==(other)
|
||||
Equality === other and
|
||||
((operand1 == other.operand1 and operand2 == other.operand2) or
|
||||
(operand1 == other.operand2 and operand2 == other.operand1))
|
||||
end
|
||||
|
||||
def predicate_sql
|
||||
operand2.equality_predicate_sql
|
||||
end
|
||||
end
|
||||
|
||||
class GreaterThanOrEqualTo < Binary
|
||||
def predicate_sql; '>=' end
|
||||
end
|
||||
|
||||
class GreaterThan < Binary
|
||||
def predicate_sql; '>' end
|
||||
end
|
||||
|
||||
class LessThanOrEqualTo < Binary
|
||||
def predicate_sql; '<=' end
|
||||
end
|
||||
|
||||
class LessThan < Binary
|
||||
def predicate_sql; '<' end
|
||||
end
|
||||
|
||||
class Match < Binary
|
||||
def predicate_sql; 'LIKE' end
|
||||
end
|
||||
|
||||
class In < Binary
|
||||
def predicate_sql; operand2.inclusion_predicate_sql end
|
||||
end
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
require 'arel/primitives/attribute'
|
||||
require 'arel/primitives/value'
|
||||
require 'arel/primitives/expression'
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
require 'set'
|
||||
|
||||
module Arel
|
||||
class Attribute
|
||||
attributes :relation, :name, :alias, :ancestor
|
||||
deriving :==
|
||||
delegate :engine, :christener, :to => :relation
|
||||
|
||||
def initialize(relation, name, options = {})
|
||||
@relation, @name, @alias, @ancestor = relation, name, options[:alias], options[:ancestor]
|
||||
end
|
||||
|
||||
def named?(hypothetical_name)
|
||||
(@alias || name).to_s == hypothetical_name.to_s
|
||||
end
|
||||
|
||||
def aggregation?
|
||||
false
|
||||
end
|
||||
|
||||
def column
|
||||
original_relation.column_for(self)
|
||||
end
|
||||
|
||||
def format(object)
|
||||
object.to_sql(Sql::Attribute.new(self))
|
||||
end
|
||||
|
||||
def to_sql(formatter = Sql::WhereCondition.new(relation))
|
||||
formatter.attribute self
|
||||
end
|
||||
|
||||
module Transformations
|
||||
def self.included(klass)
|
||||
klass.send :alias_method, :eql?, :==
|
||||
end
|
||||
|
||||
def hash
|
||||
@hash ||= history.size + name.hash + relation.hash
|
||||
end
|
||||
|
||||
def as(aliaz = nil)
|
||||
Attribute.new(relation, name, :alias => aliaz, :ancestor => self)
|
||||
end
|
||||
|
||||
def bind(new_relation)
|
||||
relation == new_relation ? self : Attribute.new(new_relation, name, :alias => @alias, :ancestor => self)
|
||||
end
|
||||
|
||||
def to_attribute
|
||||
self
|
||||
end
|
||||
end
|
||||
include Transformations
|
||||
|
||||
module Congruence
|
||||
def history
|
||||
@history ||= [self] + (ancestor ? ancestor.history : [])
|
||||
end
|
||||
|
||||
def join?
|
||||
relation.join?
|
||||
end
|
||||
|
||||
def root
|
||||
history.last
|
||||
end
|
||||
|
||||
def original_relation
|
||||
@original_relation ||= original_attribute.relation
|
||||
end
|
||||
|
||||
def original_attribute
|
||||
@original_attribute ||= history.detect { |a| !a.join? }
|
||||
end
|
||||
|
||||
def find_correlate_in(relation)
|
||||
relation[self] || self
|
||||
end
|
||||
|
||||
def descends_from?(other)
|
||||
history.include?(other)
|
||||
end
|
||||
|
||||
def /(other)
|
||||
other ? (history & other.history).size : 0
|
||||
end
|
||||
end
|
||||
include Congruence
|
||||
|
||||
module Predications
|
||||
def eq(other)
|
||||
Equality.new(self, other)
|
||||
end
|
||||
|
||||
def lt(other)
|
||||
LessThan.new(self, other)
|
||||
end
|
||||
|
||||
def lteq(other)
|
||||
LessThanOrEqualTo.new(self, other)
|
||||
end
|
||||
|
||||
def gt(other)
|
||||
GreaterThan.new(self, other)
|
||||
end
|
||||
|
||||
def gteq(other)
|
||||
GreaterThanOrEqualTo.new(self, other)
|
||||
end
|
||||
|
||||
def matches(regexp)
|
||||
Match.new(self, regexp)
|
||||
end
|
||||
|
||||
def in(array)
|
||||
In.new(self, array)
|
||||
end
|
||||
end
|
||||
include Predications
|
||||
|
||||
module Expressions
|
||||
def count(distinct = false)
|
||||
distinct ? Expression.new(self, "DISTINCT").count : Expression.new(self, "COUNT")
|
||||
end
|
||||
|
||||
def sum
|
||||
Expression.new(self, "SUM")
|
||||
end
|
||||
|
||||
def maximum
|
||||
Expression.new(self, "MAX")
|
||||
end
|
||||
|
||||
def minimum
|
||||
Expression.new(self, "MIN")
|
||||
end
|
||||
|
||||
def average
|
||||
Expression.new(self, "AVG")
|
||||
end
|
||||
end
|
||||
include Expressions
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
module Arel
|
||||
class Expression < Attribute
|
||||
attributes :attribute, :function_sql, :alias, :ancestor
|
||||
deriving :==
|
||||
delegate :relation, :to => :attribute
|
||||
alias_method :name, :alias
|
||||
|
||||
def initialize(attribute, function_sql, aliaz = nil, ancestor = nil)
|
||||
@attribute, @function_sql, @alias, @ancestor = attribute, function_sql, aliaz, ancestor
|
||||
end
|
||||
|
||||
def to_sql(formatter = Sql::SelectClause.new(relation))
|
||||
formatter.expression self
|
||||
end
|
||||
|
||||
def aggregation?
|
||||
true
|
||||
end
|
||||
|
||||
module Transformations
|
||||
def as(aliaz)
|
||||
Expression.new(attribute, function_sql, aliaz, self)
|
||||
end
|
||||
|
||||
def bind(new_relation)
|
||||
new_relation == relation ? self : Expression.new(attribute.bind(new_relation), function_sql, @alias, self)
|
||||
end
|
||||
|
||||
def to_attribute
|
||||
Attribute.new(relation, @alias, :ancestor => self)
|
||||
end
|
||||
end
|
||||
include Transformations
|
||||
end
|
||||
end
|
|
@ -1,32 +0,0 @@
|
|||
module Arel
|
||||
class Value
|
||||
attributes :value, :relation
|
||||
deriving :initialize, :==
|
||||
delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value
|
||||
|
||||
|
||||
def to_sql(formatter = Sql::WhereCondition.new(relation))
|
||||
if value =~ /^\(.*\)$/
|
||||
value
|
||||
else
|
||||
formatter.value value
|
||||
end
|
||||
end
|
||||
|
||||
def format(object)
|
||||
object.to_sql(Sql::Value.new(relation))
|
||||
end
|
||||
|
||||
def bind(relation)
|
||||
Value.new(value, relation)
|
||||
end
|
||||
|
||||
def aggregation?
|
||||
false
|
||||
end
|
||||
|
||||
def to_attribute
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
require 'arel/relations/relation'
|
||||
|
||||
require 'arel/relations/utilities'
|
||||
|
||||
require 'arel/relations/table'
|
||||
|
||||
require 'arel/relations/writes'
|
||||
require 'arel/relations/operations'
|
|
@ -1,8 +0,0 @@
|
|||
require 'arel/relations/operations/alias'
|
||||
require 'arel/relations/operations/group'
|
||||
require 'arel/relations/operations/join'
|
||||
require 'arel/relations/operations/order'
|
||||
require 'arel/relations/operations/project'
|
||||
require 'arel/relations/operations/where'
|
||||
require 'arel/relations/operations/skip'
|
||||
require 'arel/relations/operations/take'
|
|
@ -1,8 +0,0 @@
|
|||
module Arel
|
||||
class Alias < Compound
|
||||
include Recursion::BaseCase
|
||||
attributes :relation
|
||||
deriving :initialize
|
||||
alias_method :==, :equal?
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
module Arel
|
||||
class Group < Compound
|
||||
attributes :relation, :groupings
|
||||
deriving :==
|
||||
|
||||
def initialize(relation, *groupings, &block)
|
||||
@relation = relation
|
||||
@groupings = (groupings + (block_given?? [yield(relatoin)] : [])).collect { |g| g.bind(relation) }
|
||||
end
|
||||
|
||||
def externalizable?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,57 +0,0 @@
|
|||
module Arel
|
||||
class Join < Relation
|
||||
attributes :join_sql, :relation1, :relation2, :predicates
|
||||
deriving :==
|
||||
delegate :engine, :name, :to => :relation1
|
||||
hash_on :relation1
|
||||
|
||||
def initialize(join_sql, relation1, relation2 = Nil.instance, *predicates)
|
||||
@join_sql, @relation1, @relation2, @predicates = join_sql, relation1, relation2, predicates
|
||||
end
|
||||
|
||||
def table_sql(formatter = Sql::TableReference.new(self))
|
||||
relation1.externalize.table_sql(formatter)
|
||||
end
|
||||
|
||||
def joins(environment, formatter = Sql::TableReference.new(environment))
|
||||
@joins ||= begin
|
||||
this_join = [
|
||||
join_sql,
|
||||
relation2.externalize.table_sql(formatter),
|
||||
("ON" unless predicates.blank?),
|
||||
(ons + relation2.externalize.wheres).collect { |p| p.bind(environment).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ')
|
||||
].compact.join(" ")
|
||||
[relation1.joins(environment), this_join, relation2.joins(environment)].compact.join(" ")
|
||||
end
|
||||
end
|
||||
|
||||
def attributes
|
||||
@attributes ||= (relation1.externalize.attributes +
|
||||
relation2.externalize.attributes).collect { |a| a.bind(self) }
|
||||
end
|
||||
|
||||
def wheres
|
||||
# TESTME bind to self?
|
||||
relation1.externalize.wheres
|
||||
end
|
||||
|
||||
def ons
|
||||
@ons ||= @predicates.collect { |p| p.bind(self) }
|
||||
end
|
||||
|
||||
# TESTME
|
||||
def externalizable?
|
||||
relation1.externalizable? or relation2.externalizable?
|
||||
end
|
||||
|
||||
def join?
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class Relation
|
||||
def join?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
module Arel
|
||||
class Order < Compound
|
||||
attributes :relation, :orderings
|
||||
deriving :==
|
||||
|
||||
def initialize(relation, *orderings, &block)
|
||||
@relation = relation
|
||||
@orderings = (orderings + (block_given?? [yield(relation)] : [])).collect { |o| o.bind(relation) }
|
||||
end
|
||||
|
||||
# TESTME
|
||||
def orders
|
||||
(orderings + relation.orders).collect { |o| o.bind(self) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
module Arel
|
||||
class Project < Compound
|
||||
attributes :relation, :projections
|
||||
deriving :==
|
||||
|
||||
def initialize(relation, *projections, &block)
|
||||
@relation = relation
|
||||
@projections = (projections + (block_given?? [yield(relation)] : [])).collect { |p| p.bind(relation) }
|
||||
end
|
||||
|
||||
def attributes
|
||||
@attributes ||= projections.collect { |p| p.bind(self) }
|
||||
end
|
||||
|
||||
def externalizable?
|
||||
attributes.any?(&:aggregation?) or relation.externalizable?
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
module Arel
|
||||
class Skip < Compound
|
||||
attributes :relation, :skipped
|
||||
deriving :initialize, :==
|
||||
|
||||
def externalizable?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
module Arel
|
||||
class Take < Compound
|
||||
attributes :relation, :taken
|
||||
deriving :initialize, :==
|
||||
|
||||
def externalizable?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
module Arel
|
||||
class Where < Compound
|
||||
attributes :relation, :predicate
|
||||
deriving :==
|
||||
|
||||
def initialize(relation, *predicates, &block)
|
||||
predicate = block_given?? yield(relation) : predicates.shift
|
||||
@relation = predicates.empty?? relation : Where.new(relation, *predicates)
|
||||
@predicate = predicate.bind(@relation)
|
||||
end
|
||||
|
||||
def wheres
|
||||
@wheres ||= (relation.wheres + [predicate]).collect { |p| p.bind(self) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,169 +0,0 @@
|
|||
module Arel
|
||||
class Relation
|
||||
attr_reader :count
|
||||
|
||||
def session
|
||||
Session.new
|
||||
end
|
||||
|
||||
def count
|
||||
@count = "COUNT(*) AS count_all"
|
||||
end
|
||||
|
||||
def to_sql(formatter = Sql::SelectStatement.new(self))
|
||||
formatter.select select_sql, self
|
||||
end
|
||||
alias_method :to_s, :to_sql
|
||||
|
||||
def select_sql
|
||||
[
|
||||
"SELECT #{@count} #{attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }.join(', ') unless @count}",
|
||||
"FROM #{table_sql(Sql::TableReference.new(self))}",
|
||||
(joins(self) unless joins(self).blank? ),
|
||||
("WHERE #{wheres .collect { |w| w.to_sql(Sql::WhereClause.new(self)) }.join("\n\tAND ")}" unless wheres.blank? ),
|
||||
("GROUP BY #{groupings.collect { |g| g.to_sql(Sql::GroupClause.new(self)) }.join(', ')}" unless groupings.blank? ),
|
||||
("ORDER BY #{orders .collect { |o| o.to_sql(Sql::OrderClause.new(self)) }.join(', ')}" unless orders.blank? ),
|
||||
("LIMIT #{taken}" unless taken.blank? ),
|
||||
("OFFSET #{skipped}" unless skipped.blank? )
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
def inclusion_predicate_sql
|
||||
"IN"
|
||||
end
|
||||
|
||||
def call(connection = engine)
|
||||
results = connection.execute(to_sql)
|
||||
rows = []
|
||||
results.each do |row|
|
||||
rows << attributes.zip(row).to_hash
|
||||
end
|
||||
rows
|
||||
end
|
||||
|
||||
def bind(relation)
|
||||
self
|
||||
end
|
||||
|
||||
def root
|
||||
self
|
||||
end
|
||||
|
||||
def christener
|
||||
@christener ||= Sql::Christener.new
|
||||
end
|
||||
|
||||
module Enumerable
|
||||
include ::Enumerable
|
||||
|
||||
def each(&block)
|
||||
session.read(self).each(&block)
|
||||
end
|
||||
|
||||
def first
|
||||
session.read(self).first
|
||||
end
|
||||
end
|
||||
include Enumerable
|
||||
|
||||
module Operable
|
||||
def join(other_relation = nil, join_type = "INNER JOIN")
|
||||
case other_relation
|
||||
when String
|
||||
Join.new(other_relation, self)
|
||||
when Relation
|
||||
JoinOperation.new(join_type, self, other_relation)
|
||||
else
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
def outer_join(other_relation = nil)
|
||||
join(other_relation, "LEFT OUTER JOIN")
|
||||
end
|
||||
|
||||
[:where, :project, :order, :take, :skip, :group].each do |operation_name|
|
||||
operation = <<-OPERATION
|
||||
def #{operation_name}(*arguments, &block)
|
||||
arguments.all?(&:blank?) && !block_given?? self : #{operation_name.to_s.classify}.new(self, *arguments, &block)
|
||||
end
|
||||
OPERATION
|
||||
class_eval operation, __FILE__, __LINE__
|
||||
end
|
||||
|
||||
def alias
|
||||
Alias.new(self)
|
||||
end
|
||||
|
||||
module Writable
|
||||
def insert(record)
|
||||
session.create Insert.new(self, record); self
|
||||
end
|
||||
|
||||
def update(assignments)
|
||||
session.update Update.new(self, assignments)
|
||||
end
|
||||
|
||||
def delete
|
||||
session.delete Deletion.new(self)
|
||||
end
|
||||
end
|
||||
include Writable
|
||||
|
||||
JoinOperation = Struct.new(:join_sql, :relation1, :relation2) do
|
||||
def on(*predicates)
|
||||
Join.new(join_sql, relation1, relation2, *predicates)
|
||||
end
|
||||
end
|
||||
end
|
||||
include Operable
|
||||
|
||||
module AttributeAccessable
|
||||
def [](index)
|
||||
case index
|
||||
when Symbol, String
|
||||
find_attribute_matching_name(index)
|
||||
when Attribute, Expression
|
||||
find_attribute_matching_attribute(index)
|
||||
when Array
|
||||
index.collect { |i| self[i] }
|
||||
end
|
||||
end
|
||||
|
||||
def find_attribute_matching_name(name)
|
||||
attributes.detect { |a| a.named?(name) }
|
||||
end
|
||||
|
||||
def find_attribute_matching_attribute(attribute)
|
||||
matching_attributes(attribute).max do |a1, a2|
|
||||
(a1.original_attribute / attribute) <=> (a2.original_attribute / attribute)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def matching_attributes(attribute)
|
||||
(@matching_attributes ||= attributes.inject({}) do |hash, a|
|
||||
(hash[a.root] ||= []) << a
|
||||
hash
|
||||
end)[attribute.root] || []
|
||||
end
|
||||
|
||||
def has_attribute?(attribute)
|
||||
!matching_attributes(attribute).empty?
|
||||
end
|
||||
end
|
||||
include AttributeAccessable
|
||||
|
||||
module DefaultOperations
|
||||
def attributes; [] end
|
||||
def wheres; [] end
|
||||
def orders; [] end
|
||||
def inserts; [] end
|
||||
def groupings; [] end
|
||||
def joins(formatter = nil); nil end
|
||||
def taken; nil end
|
||||
def skipped; nil end
|
||||
end
|
||||
include DefaultOperations
|
||||
end
|
||||
end
|
|
@ -1,36 +0,0 @@
|
|||
module Arel
|
||||
class Table < Relation
|
||||
include Recursion::BaseCase
|
||||
|
||||
cattr_accessor :engine
|
||||
attr_reader :name, :engine
|
||||
hash_on :name
|
||||
|
||||
def initialize(name, engine = Table.engine)
|
||||
@name, @engine = name.to_s, engine
|
||||
end
|
||||
|
||||
def attributes
|
||||
@attributes ||= columns.collect do |column|
|
||||
Attribute.new(self, column.name.to_sym)
|
||||
end
|
||||
end
|
||||
|
||||
def column_for(attribute)
|
||||
has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s }
|
||||
end
|
||||
|
||||
def columns
|
||||
@columns ||= engine.columns(name, "#{name} Columns")
|
||||
end
|
||||
|
||||
def reset
|
||||
@attributes = @columns = nil
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
Table === other and
|
||||
name == other.name
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
require 'arel/relations/utilities/compound'
|
||||
require 'arel/relations/utilities/recursion'
|
||||
require 'arel/relations/utilities/nil'
|
||||
require 'arel/relations/utilities/externalization'
|
||||
require 'arel/relations/utilities/recursion'
|
|
@ -1,18 +0,0 @@
|
|||
module Arel
|
||||
class Compound < Relation
|
||||
attr_reader :relation
|
||||
hash_on :relation
|
||||
delegate :joins, :join?, :inserts, :taken, :skipped, :name, :externalizable?,
|
||||
:column_for, :engine, :table, :table_sql,
|
||||
:to => :relation
|
||||
|
||||
[:attributes, :wheres, :groupings, :orders].each do |operation_name|
|
||||
operation = <<-OPERATION
|
||||
def #{operation_name}
|
||||
@#{operation_name} ||= relation.#{operation_name}.collect { |o| o.bind(self) }
|
||||
end
|
||||
OPERATION
|
||||
class_eval operation, __FILE__, __LINE__
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,34 +0,0 @@
|
|||
module Arel
|
||||
class Externalization < Compound
|
||||
attributes :relation
|
||||
deriving :initialize, :==
|
||||
include Recursion::BaseCase
|
||||
|
||||
def wheres
|
||||
[]
|
||||
end
|
||||
|
||||
def table_sql(formatter = Sql::TableReference.new(relation))
|
||||
formatter.select relation.select_sql, self
|
||||
end
|
||||
|
||||
def attributes
|
||||
@attributes ||= relation.attributes.collect(&:to_attribute).collect { |a| a.bind(self) }
|
||||
end
|
||||
|
||||
# REMOVEME
|
||||
def name
|
||||
relation.name + '_external'
|
||||
end
|
||||
end
|
||||
|
||||
class Relation
|
||||
def externalize
|
||||
@externalized ||= externalizable?? Externalization.new(self) : self
|
||||
end
|
||||
|
||||
def externalizable?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
require 'singleton'
|
||||
|
||||
module Arel
|
||||
class Nil < Relation
|
||||
include Singleton
|
||||
|
||||
def table_sql(formatter = nil); '' end
|
||||
def name; '' end
|
||||
end
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
module Arel
|
||||
module Recursion
|
||||
module BaseCase
|
||||
def table
|
||||
self
|
||||
end
|
||||
|
||||
def table_sql(formatter = Sql::TableReference.new(self))
|
||||
formatter.table self
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,3 +0,0 @@
|
|||
require 'arel/relations/writes/delete'
|
||||
require 'arel/relations/writes/update'
|
||||
require 'arel/relations/writes/insert'
|
|
@ -1,19 +0,0 @@
|
|||
module Arel
|
||||
class Deletion < Compound
|
||||
attributes :relation
|
||||
deriving :initialize, :==
|
||||
|
||||
def to_sql(formatter = nil)
|
||||
[
|
||||
"DELETE",
|
||||
"FROM #{table_sql}",
|
||||
("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ),
|
||||
("LIMIT #{taken}" unless taken.blank? ),
|
||||
].compact.join("\n")
|
||||
end
|
||||
|
||||
def call(connection = engine)
|
||||
connection.delete(to_sql)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
module Arel
|
||||
class Insert < Compound
|
||||
attributes :relation, :record
|
||||
deriving :==
|
||||
|
||||
def initialize(relation, record)
|
||||
@relation, @record = relation, record.bind(relation)
|
||||
end
|
||||
|
||||
def to_sql(formatter = nil)
|
||||
[
|
||||
"INSERT",
|
||||
"INTO #{table_sql}",
|
||||
"(#{record.keys.map { |key| engine.quote_column_name(key.name) }.join(', ')})",
|
||||
"VALUES (#{record.map { |key, value| key.format(value) }.join(', ')})"
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
def call(connection = engine)
|
||||
connection.insert(to_sql)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,30 +0,0 @@
|
|||
module Arel
|
||||
class Update < Compound
|
||||
attributes :relation, :assignments
|
||||
deriving :==
|
||||
|
||||
def initialize(relation, assignments)
|
||||
@relation, @assignments = relation, assignments
|
||||
end
|
||||
|
||||
def to_sql(formatter = nil)
|
||||
[
|
||||
"UPDATE #{table_sql} SET",
|
||||
map_assignments,
|
||||
("WHERE #{wheres.map(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ),
|
||||
("LIMIT #{taken}" unless taken.blank? )
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
def call(connection = engine)
|
||||
connection.update(to_sql)
|
||||
end
|
||||
|
||||
def map_assignments
|
||||
assignments.collect do |attribute, value|
|
||||
attribute.respond_to?(:name) ?
|
||||
"#{engine.quote_column_name(attribute.name)} = #{attribute.format(value)}" : attribute
|
||||
end.join(",\n")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,47 +0,0 @@
|
|||
require 'singleton'
|
||||
|
||||
module Arel
|
||||
class Session
|
||||
class << self
|
||||
attr_accessor :instance
|
||||
alias_method :manufacture, :new
|
||||
|
||||
def start
|
||||
if @started
|
||||
yield
|
||||
else
|
||||
begin
|
||||
@started = true
|
||||
@instance = manufacture
|
||||
metaclass.send :alias_method, :new, :instance
|
||||
yield
|
||||
ensure
|
||||
metaclass.send :alias_method, :new, :manufacture
|
||||
@started = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module CRUD
|
||||
def create(insert)
|
||||
insert.call(insert.engine)
|
||||
end
|
||||
|
||||
def read(select)
|
||||
(@read ||= Hash.new do |hash, select|
|
||||
hash[select] = select.call(select.engine)
|
||||
end)[select]
|
||||
end
|
||||
|
||||
def update(update)
|
||||
update.call(update.engine)
|
||||
end
|
||||
|
||||
def delete(delete)
|
||||
delete.call(delete.engine)
|
||||
end
|
||||
end
|
||||
include CRUD
|
||||
end
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
require 'arel/sql/formatters'
|
||||
require 'arel/sql/christener'
|
|
@ -1,13 +0,0 @@
|
|||
module Arel
|
||||
module Sql
|
||||
class Christener
|
||||
def name_for(relation)
|
||||
@used_names ||= Hash.new(0)
|
||||
(@relation_names ||= Hash.new do |hash, relation|
|
||||
@used_names[name = relation.name] += 1
|
||||
hash[relation] = name + (@used_names[name] > 1 ? "_#{@used_names[name]}" : '')
|
||||
end)[relation.table]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,121 +0,0 @@
|
|||
module Arel
|
||||
module Sql
|
||||
class Formatter
|
||||
attr_reader :environment
|
||||
delegate :christener, :engine, :to => :environment
|
||||
delegate :name_for, :to => :christener
|
||||
delegate :quote_table_name, :quote_column_name, :quote, :to => :engine
|
||||
|
||||
def initialize(environment)
|
||||
@environment = environment
|
||||
end
|
||||
end
|
||||
|
||||
class SelectClause < Formatter
|
||||
def attribute(attribute)
|
||||
# FIXME this should check that the column exists
|
||||
if attribute.name.to_s =~ /^\w*$/
|
||||
"#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "")
|
||||
else
|
||||
attribute.name.to_s + (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "")
|
||||
end
|
||||
end
|
||||
|
||||
def expression(expression)
|
||||
if expression.function_sql == "DISTINCT"
|
||||
"#{expression.function_sql} #{expression.attribute.to_sql(self)}" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : '')
|
||||
else
|
||||
"#{expression.function_sql}(#{expression.attribute.to_sql(self)})" + (expression.alias ? " AS #{quote_column_name(expression.alias)}" : " AS #{expression.function_sql.to_s.downcase}_id")
|
||||
end
|
||||
end
|
||||
|
||||
def select(select_sql, table)
|
||||
"(#{select_sql}) AS #{quote_table_name(name_for(table))}"
|
||||
end
|
||||
|
||||
def value(value)
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
class PassThrough < Formatter
|
||||
def value(value)
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
class WhereClause < PassThrough
|
||||
end
|
||||
|
||||
class OrderClause < PassThrough
|
||||
def attribute(attribute)
|
||||
"#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}"
|
||||
end
|
||||
end
|
||||
|
||||
class GroupClause < PassThrough
|
||||
def attribute(attribute)
|
||||
"#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}"
|
||||
end
|
||||
end
|
||||
|
||||
class WhereCondition < Formatter
|
||||
def attribute(attribute)
|
||||
"#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}"
|
||||
end
|
||||
|
||||
def expression(expression)
|
||||
"#{expression.function_sql}(#{expression.attribute.to_sql(self)})"
|
||||
end
|
||||
|
||||
def value(value)
|
||||
value.to_sql(self)
|
||||
end
|
||||
|
||||
def scalar(value, column = nil)
|
||||
quote(value, column)
|
||||
end
|
||||
|
||||
def select(select_sql, table)
|
||||
"(#{select_sql})"
|
||||
end
|
||||
end
|
||||
|
||||
class SelectStatement < Formatter
|
||||
def select(select_sql, table)
|
||||
select_sql
|
||||
end
|
||||
end
|
||||
|
||||
class TableReference < Formatter
|
||||
def select(select_sql, table)
|
||||
"(#{select_sql}) AS #{quote_table_name(name_for(table))}"
|
||||
end
|
||||
|
||||
def table(table)
|
||||
if table.name =~ /^(\w|-)*$/
|
||||
quote_table_name(table.name) + (table.name != name_for(table) ? " AS " + quote_table_name(name_for(table)) : '')
|
||||
else
|
||||
table.name + (table.name != name_for(table) ? " AS " + (name_for(table)) : '')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Attribute < WhereCondition
|
||||
def scalar(scalar)
|
||||
quote(scalar, environment.column)
|
||||
end
|
||||
|
||||
def array(array)
|
||||
"(" + array.collect { |e| e.to_sql(self) }.join(', ') + ")"
|
||||
end
|
||||
|
||||
def range(left, right)
|
||||
"#{left} AND #{right}"
|
||||
end
|
||||
end
|
||||
|
||||
class Value < WhereCondition
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue