1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
module Arel
class Table
include Arel::Crud
include Arel::FactoryMethods
@engine = nil
class << self; attr_accessor :engine; end
attr_accessor :name, :engine, :aliases, :table_alias
# TableAlias and Table both have a #table_name which is the name of the underlying table
alias :table_name :name
def initialize name, engine = Table.engine
@name = name.to_s
@engine = engine
@columns = nil
@aliases = []
@table_alias = nil
@primary_key = nil
if Hash === engine
@engine = engine[:engine] || Table.engine
# Sometime AR sends an :as parameter to table, to let the table know
# that it is an Alias. We may want to override new, and return a
# TableAlias node?
@table_alias = engine[:as] unless engine[:as].to_s == @name
end
end
def primary_key
if $VERBOSE
warn <<-eowarn
primary_key (#{caller.first}) is deprecated and will be removed in Arel 4.0.0
eowarn
end
@primary_key ||= begin
primary_key_name = @engine.connection.primary_key(name)
# some tables might be without primary key
primary_key_name && self[primary_key_name]
end
end
def alias name = "#{self.name}_2"
Nodes::TableAlias.new(self, name).tap do |node|
@aliases << node
end
end
def from table
SelectManager.new(@engine, table)
end
def joins manager
if $VERBOSE
warn "joins is deprecated and will be removed in 4.0.0"
warn "please remove your call to joins from #{caller.first}"
end
nil
end
def join relation, klass = Nodes::InnerJoin
return from(self) unless relation
case relation
when String, Nodes::SqlLiteral
raise if relation.blank?
klass = Nodes::StringJoin
end
from(self).join(relation, klass)
end
def group *columns
from(self).group(*columns)
end
def order *expr
from(self).order(*expr)
end
def where condition
from(self).where condition
end
def project *things
from(self).project(*things)
end
def take amount
from(self).take amount
end
def skip amount
from(self).skip amount
end
def having expr
from(self).having expr
end
def columns
if $VERBOSE
warn <<-eowarn
(#{caller.first}) Arel::Table#columns is deprecated and will be removed in
Arel 4.0.0 with no replacement. PEW PEW PEW!!!
eowarn
end
@columns ||=
attributes_for @engine.connection.columns(@name, "#{@name} Columns")
end
def [] name
::Arel::Attribute.new self, name
end
def select_manager
SelectManager.new(@engine)
end
def insert_manager
InsertManager.new(@engine)
end
def hash
# Perf note: aliases, table alias and engine is excluded from the hash
# aliases can have a loop back to this table breaking hashes in parent
# relations, for the vast majority of cases @name is unique to a query
@name.hash
end
def eql? other
self.class == other.class &&
self.name == other.name &&
self.engine == other.engine &&
self.aliases == other.aliases &&
self.table_alias == other.table_alias
end
alias :== :eql?
private
def attributes_for columns
return nil unless columns
columns.map do |column|
Attributes.for(column).new self, column.name.to_sym
end
end
@@table_cache = nil
def self.table_cache engine # :nodoc:
if $VERBOSE
warn <<-eowarn
(#{caller.first}) Arel::Table.table_cache is deprecated and will be removed in
Arel 4.0.0 with no replacement. PEW PEW PEW!!!
eowarn
end
@@table_cache ||= Hash[engine.connection.tables.map { |x| [x,true] }]
end
end
end
|