arel 0.4.0 → 1.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +24 -0
- data/lib/arel.rb +3 -1
- data/lib/arel/algebra/attributes/attribute.rb +175 -141
- data/lib/arel/algebra/core_extensions.rb +0 -1
- data/lib/arel/algebra/core_extensions/hash.rb +5 -9
- data/lib/arel/algebra/core_extensions/object.rb +0 -4
- data/lib/arel/algebra/expression.rb +37 -24
- data/lib/arel/algebra/header.rb +5 -6
- data/lib/arel/algebra/ordering.rb +13 -5
- data/lib/arel/algebra/predicates.rb +143 -27
- data/lib/arel/algebra/relations.rb +0 -1
- data/lib/arel/algebra/relations/operations/from.rb +10 -2
- data/lib/arel/algebra/relations/operations/group.rb +8 -6
- data/lib/arel/algebra/relations/operations/having.rb +3 -6
- data/lib/arel/algebra/relations/operations/join.rb +52 -18
- data/lib/arel/algebra/relations/operations/lock.rb +4 -6
- data/lib/arel/algebra/relations/operations/order.rb +11 -7
- data/lib/arel/algebra/relations/operations/project.rb +10 -10
- data/lib/arel/algebra/relations/operations/skip.rb +10 -3
- data/lib/arel/algebra/relations/operations/take.rb +10 -3
- data/lib/arel/algebra/relations/operations/where.rb +12 -6
- data/lib/arel/algebra/relations/relation.rb +161 -92
- data/lib/arel/algebra/relations/row.rb +8 -5
- data/lib/arel/algebra/relations/utilities/compound.rb +34 -33
- data/lib/arel/algebra/relations/utilities/externalization.rb +10 -8
- data/lib/arel/algebra/relations/writes.rb +24 -13
- data/lib/arel/algebra/value.rb +41 -2
- data/lib/arel/engines/memory.rb +0 -2
- data/lib/arel/engines/memory/engine.rb +3 -9
- data/lib/arel/engines/memory/relations.rb +0 -3
- data/lib/arel/engines/memory/relations/array.rb +5 -3
- data/lib/arel/engines/memory/relations/operations.rb +2 -60
- data/lib/arel/engines/sql.rb +0 -2
- data/lib/arel/engines/sql/christener.rb +12 -6
- data/lib/arel/engines/sql/compilers/oracle_compiler.rb +34 -23
- data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +23 -15
- data/lib/arel/engines/sql/engine.rb +19 -27
- data/lib/arel/engines/sql/formatters.rb +26 -10
- data/lib/arel/engines/sql/relations.rb +0 -7
- data/lib/arel/engines/sql/relations/compiler.rb +70 -35
- data/lib/arel/engines/sql/relations/table.rb +44 -32
- data/lib/arel/{engines/sql/relations/utilities/recursion.rb → recursion/base_case.rb} +0 -0
- data/lib/arel/session.rb +24 -40
- data/lib/arel/sql_literal.rb +13 -0
- data/lib/arel/version.rb +1 -1
- data/spec/algebra/unit/predicates/inequality_spec.rb +32 -0
- data/spec/algebra/unit/predicates/predicate_spec.rb +22 -0
- data/spec/algebra/unit/primitives/attribute_spec.rb +3 -9
- data/spec/algebra/unit/primitives/expression_spec.rb +1 -7
- data/spec/algebra/unit/relations/join_spec.rb +0 -7
- data/spec/algebra/unit/relations/project_spec.rb +3 -3
- data/spec/algebra/unit/relations/relation_spec.rb +74 -25
- data/spec/algebra/unit/session/session_spec.rb +7 -7
- data/spec/engines/memory/integration/joins/cross_engine_spec.rb +20 -10
- data/spec/engines/memory/unit/relations/array_spec.rb +6 -5
- data/spec/engines/memory/unit/relations/join_spec.rb +7 -6
- data/spec/engines/memory/unit/relations/order_spec.rb +7 -6
- data/spec/engines/memory/unit/relations/project_spec.rb +6 -6
- data/spec/engines/memory/unit/relations/skip_spec.rb +10 -5
- data/spec/engines/memory/unit/relations/take_spec.rb +7 -5
- data/spec/engines/memory/unit/relations/where_spec.rb +13 -9
- data/spec/engines/sql/unit/engine_spec.rb +20 -0
- data/spec/engines/sql/unit/relations/group_spec.rb +2 -2
- data/spec/engines/sql/unit/relations/order_spec.rb +5 -5
- data/spec/engines/sql/unit/relations/project_spec.rb +4 -4
- data/spec/engines/sql/unit/relations/table_spec.rb +0 -7
- data/spec/engines/sql/unit/relations/take_spec.rb +26 -0
- data/spec/engines/sql/unit/relations/where_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -4
- data/spec/sql/christener_spec.rb +70 -0
- data/spec/support/model.rb +7 -2
- metadata +109 -23
- data/lib/arel/algebra/core_extensions/class.rb +0 -32
- data/lib/arel/algebra/relations/operations/alias.rb +0 -7
- data/lib/arel/engines/memory/predicates.rb +0 -99
- data/lib/arel/engines/memory/primitives.rb +0 -27
- data/lib/arel/engines/memory/relations/compound.rb +0 -9
- data/lib/arel/engines/memory/relations/writes.rb +0 -7
- data/lib/arel/engines/sql/predicates.rb +0 -103
- data/lib/arel/engines/sql/primitives.rb +0 -97
- data/lib/arel/engines/sql/relations/operations/alias.rb +0 -5
- data/lib/arel/engines/sql/relations/operations/join.rb +0 -33
- data/lib/arel/engines/sql/relations/relation.rb +0 -65
- data/lib/arel/engines/sql/relations/utilities/compound.rb +0 -10
- data/lib/arel/engines/sql/relations/utilities/externalization.rb +0 -14
- data/lib/arel/engines/sql/relations/writes.rb +0 -19
@@ -3,28 +3,36 @@ module Arel
|
|
3
3
|
class PostgreSQLCompiler < GenericCompiler
|
4
4
|
|
5
5
|
def select_sql
|
6
|
-
if !orders.blank? && using_distinct_on?
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
if !relation.orders.blank? && using_distinct_on?
|
7
|
+
selects = relation.select_clauses
|
8
|
+
joins = relation.joins(self)
|
9
|
+
wheres = relation.where_clauses
|
10
|
+
groups = relation.group_clauses
|
11
|
+
havings = relation.having_clauses
|
12
|
+
orders = relation.order_clauses
|
13
|
+
|
14
|
+
subquery_clauses = [ "",
|
15
|
+
"SELECT #{selects.kind_of?(::Array) ? selects.join("") : selects.to_s}",
|
16
|
+
"FROM #{relation.from_clauses}",
|
17
|
+
joins,
|
18
|
+
("WHERE #{wheres.join(' AND ')}" unless wheres.empty?),
|
19
|
+
("GROUP BY #{groups.join(', ')}" unless groups.empty?),
|
20
|
+
("HAVING #{havings.join(' AND ')}" unless havings.empty?)
|
21
|
+
].compact.join ' '
|
22
|
+
subquery_clauses << " #{locked}" unless locked.blank?
|
15
23
|
|
16
24
|
build_query \
|
17
|
-
"SELECT * FROM (#{
|
18
|
-
"ORDER BY #{aliased_orders(
|
19
|
-
("LIMIT #{taken}" unless taken.blank? ),
|
20
|
-
("OFFSET #{skipped}" unless skipped.blank? )
|
25
|
+
"SELECT * FROM (#{build_query subquery_clauses}) AS id_list",
|
26
|
+
"ORDER BY #{aliased_orders(orders)}",
|
27
|
+
("LIMIT #{relation.taken}" unless relation.taken.blank? ),
|
28
|
+
("OFFSET #{relation.skipped}" unless relation.skipped.blank? )
|
21
29
|
else
|
22
30
|
super
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
34
|
def using_distinct_on?
|
27
|
-
select_clauses.any? { |x| x =~ /DISTINCT ON/ }
|
35
|
+
relation.select_clauses.any? { |x| x =~ /DISTINCT ON/ }
|
28
36
|
end
|
29
37
|
|
30
38
|
def aliased_orders(orders)
|
@@ -35,7 +43,7 @@ module Arel
|
|
35
43
|
end
|
36
44
|
|
37
45
|
def supports_insert_with_returning?
|
38
|
-
engine.postgresql_version >= 80200
|
46
|
+
engine.connection.send(:postgresql_version) >= 80200
|
39
47
|
end
|
40
48
|
end
|
41
49
|
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
module Arel
|
2
2
|
module Sql
|
3
3
|
class Engine
|
4
|
-
|
5
4
|
def initialize(ar = nil)
|
6
5
|
@ar = ar
|
7
6
|
end
|
8
7
|
|
9
8
|
def connection
|
10
|
-
@ar
|
9
|
+
@ar && @ar.connection
|
11
10
|
end
|
12
11
|
|
13
12
|
def adapter_name
|
@@ -20,36 +19,29 @@ module Arel
|
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
primary_key_value = if relation.primary_key.blank?
|
30
|
-
nil
|
31
|
-
elsif relation.record.is_a?(Hash)
|
32
|
-
attribute = relation.record.detect { |attr, _| attr.name.to_s == relation.primary_key.to_s }
|
33
|
-
attribute && attribute.last.value
|
34
|
-
end
|
35
|
-
|
36
|
-
connection.insert(relation.to_sql(false), nil, relation.primary_key, primary_key_value)
|
22
|
+
def create(relation)
|
23
|
+
primary_key_value = if relation.primary_key.blank?
|
24
|
+
nil
|
25
|
+
elsif relation.record.is_a?(Hash)
|
26
|
+
attribute = relation.record.detect { |attr, _| attr.name.to_s == relation.primary_key.to_s }
|
27
|
+
attribute && attribute.last.value
|
37
28
|
end
|
38
29
|
|
39
|
-
|
40
|
-
|
41
|
-
Array.new(rows, relation.attributes)
|
42
|
-
end
|
30
|
+
connection.insert(relation.to_sql(false), nil, relation.primary_key, primary_key_value)
|
31
|
+
end
|
43
32
|
|
44
|
-
|
45
|
-
|
46
|
-
|
33
|
+
def read(relation)
|
34
|
+
rows = connection.select_rows(relation.to_sql)
|
35
|
+
Array.new(rows, relation.attributes)
|
36
|
+
end
|
47
37
|
|
48
|
-
|
49
|
-
|
50
|
-
|
38
|
+
def update(relation)
|
39
|
+
connection.update(relation.to_sql)
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete(relation)
|
43
|
+
connection.delete(relation.to_sql)
|
51
44
|
end
|
52
|
-
include CRUD
|
53
45
|
end
|
54
46
|
end
|
55
47
|
end
|
@@ -1,13 +1,28 @@
|
|
1
1
|
module Arel
|
2
2
|
module Sql
|
3
3
|
class Formatter
|
4
|
-
attr_reader :environment
|
5
|
-
delegate :christener, :engine, :to => :environment
|
6
|
-
delegate :name_for, :to => :christener
|
7
|
-
delegate :quote_table_name, :quote_column_name, :quote, :to => :engine
|
4
|
+
attr_reader :environment, :christener, :engine
|
8
5
|
|
9
6
|
def initialize(environment)
|
10
7
|
@environment = environment
|
8
|
+
@christener = environment.christener
|
9
|
+
@engine = environment.engine
|
10
|
+
end
|
11
|
+
|
12
|
+
def name_for thing
|
13
|
+
@christener.name_for thing
|
14
|
+
end
|
15
|
+
|
16
|
+
def quote_column_name name
|
17
|
+
@engine.connection.quote_column_name name
|
18
|
+
end
|
19
|
+
|
20
|
+
def quote_table_name name
|
21
|
+
@engine.connection.quote_table_name name
|
22
|
+
end
|
23
|
+
|
24
|
+
def quote value, column = nil
|
25
|
+
@engine.connection.quote value, column
|
11
26
|
end
|
12
27
|
end
|
13
28
|
|
@@ -97,12 +112,13 @@ module Arel
|
|
97
112
|
end
|
98
113
|
|
99
114
|
def table(table)
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
115
|
+
table_name = table.name
|
116
|
+
return table_name if table_name =~ /\s/
|
117
|
+
|
118
|
+
unique_name = name_for(table)
|
119
|
+
|
120
|
+
quote_table_name(table_name) +
|
121
|
+
(table_name != unique_name ? " #{quote_table_name(unique_name)}" : '')
|
106
122
|
end
|
107
123
|
end
|
108
124
|
|
@@ -1,10 +1,3 @@
|
|
1
|
-
require 'arel/engines/sql/relations/utilities/compound'
|
2
|
-
require 'arel/engines/sql/relations/utilities/recursion'
|
3
|
-
require 'arel/engines/sql/relations/utilities/externalization'
|
4
1
|
require 'arel/engines/sql/relations/utilities/nil'
|
5
2
|
require 'arel/engines/sql/relations/compiler'
|
6
|
-
require 'arel/engines/sql/relations/relation'
|
7
3
|
require 'arel/engines/sql/relations/table'
|
8
|
-
require 'arel/engines/sql/relations/operations/join'
|
9
|
-
require 'arel/engines/sql/relations/operations/alias'
|
10
|
-
require 'arel/engines/sql/relations/writes'
|
@@ -1,32 +1,65 @@
|
|
1
1
|
module Arel
|
2
2
|
module SqlCompiler
|
3
3
|
class GenericCompiler
|
4
|
-
attr_reader :relation
|
4
|
+
attr_reader :relation, :engine
|
5
5
|
|
6
6
|
def initialize(relation)
|
7
7
|
@relation = relation
|
8
|
+
@engine = relation.engine
|
9
|
+
end
|
10
|
+
|
11
|
+
def christener
|
12
|
+
relation.christener
|
8
13
|
end
|
9
14
|
|
10
15
|
def select_sql
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
projections = @relation.projections
|
17
|
+
if Count === projections.first && projections.size == 1 &&
|
18
|
+
(relation.taken.present? || relation.wheres.present?) && relation.joins(self).blank?
|
19
|
+
subquery = [
|
20
|
+
"SELECT 1 FROM #{relation.from_clauses}", build_clauses
|
21
|
+
].join ' '
|
22
|
+
query = "SELECT COUNT(*) AS count_id FROM (#{subquery}) AS subquery"
|
23
|
+
else
|
24
|
+
query = [
|
25
|
+
"SELECT #{relation.select_clauses.join(', ')}",
|
26
|
+
"FROM #{relation.from_clauses}",
|
27
|
+
build_clauses
|
28
|
+
].compact.join ' '
|
29
|
+
end
|
30
|
+
query
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_clauses
|
34
|
+
joins = relation.joins(self)
|
35
|
+
wheres = relation.where_clauses
|
36
|
+
groups = relation.group_clauses
|
37
|
+
havings = relation.having_clauses
|
38
|
+
orders = relation.order_clauses
|
39
|
+
|
40
|
+
clauses = [ "",
|
41
|
+
joins,
|
42
|
+
("WHERE #{wheres.join(' AND ')}" unless wheres.empty?),
|
43
|
+
("GROUP BY #{groups.join(', ')}" unless groups.empty?),
|
44
|
+
("HAVING #{havings.join(' AND ')}" unless havings.empty?),
|
45
|
+
("ORDER BY #{orders.join(', ')}" unless orders.empty?)
|
46
|
+
].compact.join ' '
|
47
|
+
|
48
|
+
offset = relation.skipped
|
49
|
+
limit = relation.taken
|
50
|
+
@engine.connection.add_limit_offset!(clauses, :limit => limit,
|
51
|
+
:offset => offset) if offset || limit
|
52
|
+
|
53
|
+
clauses << " #{locked}" unless locked.blank?
|
54
|
+
clauses unless clauses.blank?
|
22
55
|
end
|
23
56
|
|
24
57
|
def delete_sql
|
25
58
|
build_query \
|
26
59
|
"DELETE",
|
27
|
-
"FROM #{table_sql}",
|
28
|
-
("WHERE #{wheres.collect
|
29
|
-
(add_limit_on_delete(taken) unless taken.blank? )
|
60
|
+
"FROM #{relation.table_sql}",
|
61
|
+
("WHERE #{relation.wheres.collect { |x| x.to_sql }.join(' AND ')}" unless relation.wheres.blank? ),
|
62
|
+
(add_limit_on_delete(relation.taken) unless relation.taken.blank? )
|
30
63
|
end
|
31
64
|
|
32
65
|
def add_limit_on_delete(taken)
|
@@ -34,19 +67,19 @@ module Arel
|
|
34
67
|
end
|
35
68
|
|
36
69
|
def insert_sql(include_returning = true)
|
37
|
-
insertion_attributes_values_sql = if record.is_a?(Value)
|
38
|
-
record.value
|
70
|
+
insertion_attributes_values_sql = if relation.record.is_a?(Value)
|
71
|
+
relation.record.value
|
39
72
|
else
|
40
|
-
attributes = record.keys.sort_by do |attribute|
|
73
|
+
attributes = relation.record.keys.sort_by do |attribute|
|
41
74
|
attribute.name.to_s
|
42
75
|
end
|
43
76
|
|
44
77
|
first = attributes.collect do |key|
|
45
|
-
engine.quote_column_name(key.name)
|
78
|
+
@engine.connection.quote_column_name(key.name)
|
46
79
|
end.join(', ')
|
47
80
|
|
48
81
|
second = attributes.collect do |key|
|
49
|
-
key.format(record[key])
|
82
|
+
key.format(relation.record[key])
|
50
83
|
end.join(', ')
|
51
84
|
|
52
85
|
build_query "(#{first})", "VALUES (#{second})"
|
@@ -54,9 +87,9 @@ module Arel
|
|
54
87
|
|
55
88
|
build_query \
|
56
89
|
"INSERT",
|
57
|
-
"INTO #{table_sql}",
|
90
|
+
"INTO #{relation.table_sql}",
|
58
91
|
insertion_attributes_values_sql,
|
59
|
-
("RETURNING #{engine.quote_column_name(primary_key)}" if include_returning && compiler.supports_insert_with_returning?)
|
92
|
+
("RETURNING #{engine.connection.quote_column_name(relation.primary_key)}" if include_returning && relation.compiler.supports_insert_with_returning?)
|
60
93
|
end
|
61
94
|
|
62
95
|
def supports_insert_with_returning?
|
@@ -65,14 +98,15 @@ module Arel
|
|
65
98
|
|
66
99
|
def update_sql
|
67
100
|
build_query \
|
68
|
-
"UPDATE #{table_sql} SET",
|
101
|
+
"UPDATE #{relation.table_sql} SET",
|
69
102
|
assignment_sql,
|
70
103
|
build_update_conditions_sql
|
71
104
|
end
|
72
105
|
|
73
|
-
|
74
|
-
|
75
|
-
|
106
|
+
protected
|
107
|
+
|
108
|
+
def locked
|
109
|
+
relation.locked
|
76
110
|
end
|
77
111
|
|
78
112
|
def build_query(*parts)
|
@@ -80,25 +114,26 @@ module Arel
|
|
80
114
|
end
|
81
115
|
|
82
116
|
def assignment_sql
|
83
|
-
if assignments.respond_to?(:collect)
|
84
|
-
attributes = assignments.keys.sort_by do |attribute|
|
117
|
+
if relation.assignments.respond_to?(:collect)
|
118
|
+
attributes = relation.assignments.keys.sort_by do |attribute|
|
85
119
|
attribute.name.to_s
|
86
120
|
end
|
87
121
|
|
88
122
|
attributes.map do |attribute|
|
89
|
-
value = assignments[attribute]
|
90
|
-
"#{engine.quote_column_name(attribute.name)} = #{attribute.format(value)}"
|
123
|
+
value = relation.assignments[attribute]
|
124
|
+
"#{@engine.connection.quote_column_name(attribute.name)} = #{attribute.format(value)}"
|
91
125
|
end.join(", ")
|
92
126
|
else
|
93
|
-
assignments.value
|
127
|
+
relation.assignments.value
|
94
128
|
end
|
95
129
|
end
|
96
130
|
|
97
131
|
def build_update_conditions_sql
|
98
132
|
conditions = ""
|
99
|
-
conditions << " WHERE #{wheres.
|
100
|
-
conditions << " ORDER BY #{order_clauses.join(', ')}" unless orders.blank?
|
133
|
+
conditions << " WHERE #{relation.wheres.map { |x| x.to_sql }.join(' AND ')}" unless relation.wheres.blank?
|
134
|
+
conditions << " ORDER BY #{relation.order_clauses.join(', ')}" unless relation.orders.blank?
|
101
135
|
|
136
|
+
taken = relation.taken
|
102
137
|
unless taken.blank?
|
103
138
|
conditions = limited_update_conditions(conditions, taken)
|
104
139
|
end
|
@@ -108,8 +143,8 @@ module Arel
|
|
108
143
|
|
109
144
|
def limited_update_conditions(conditions, taken)
|
110
145
|
conditions << " LIMIT #{taken}"
|
111
|
-
quoted_primary_key = engine.quote_column_name(primary_key)
|
112
|
-
"WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{engine.connection.quote_table_name table.name} #{conditions})"
|
146
|
+
quoted_primary_key = @engine.connection.quote_column_name(relation.primary_key)
|
147
|
+
"WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{@engine.connection.quote_table_name relation.table.name} #{conditions})"
|
113
148
|
end
|
114
149
|
|
115
150
|
end
|
@@ -2,17 +2,36 @@ module Arel
|
|
2
2
|
class Table
|
3
3
|
include Relation, Recursion::BaseCase
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
@@engine = nil
|
6
|
+
@@tables = nil
|
7
|
+
class << self # FIXME: Do we really need these?
|
8
|
+
def engine; @@engine; end
|
9
|
+
def engine= e; @@engine = e; end
|
10
|
+
|
11
|
+
def tables; @@tables; end
|
12
|
+
def tables= e; @@tables = e; end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :name, :engine, :table_alias, :options, :christener
|
16
|
+
attr_reader :table_exists
|
17
|
+
alias :table_exists? :table_exists
|
7
18
|
|
8
19
|
def initialize(name, options = {})
|
9
20
|
@name = name.to_s
|
10
21
|
@table_exists = nil
|
22
|
+
@table_alias = nil
|
23
|
+
@christener = Sql::Christener.new
|
24
|
+
@attributes = nil
|
25
|
+
@matching_attributes = nil
|
11
26
|
|
12
27
|
if options.is_a?(Hash)
|
13
28
|
@options = options
|
14
29
|
@engine = options[:engine] || Table.engine
|
15
|
-
|
30
|
+
|
31
|
+
if options[:as]
|
32
|
+
as = options[:as].to_s
|
33
|
+
@table_alias = as unless as == @name
|
34
|
+
end
|
16
35
|
else
|
17
36
|
@engine = options # Table.new('foo', engine)
|
18
37
|
end
|
@@ -20,10 +39,18 @@ module Arel
|
|
20
39
|
if @engine.connection
|
21
40
|
begin
|
22
41
|
require "arel/engines/sql/compilers/#{@engine.adapter_name.downcase}_compiler"
|
23
|
-
@@tables ||= engine.tables
|
24
42
|
rescue LoadError
|
25
|
-
|
43
|
+
begin
|
44
|
+
# try to load an externally defined compiler, in case this adapter has defined the compiler on its own.
|
45
|
+
require "#{@engine.adapter_name.downcase}/arel_compiler"
|
46
|
+
rescue LoadError
|
47
|
+
raise "#{@engine.adapter_name} is not supported by Arel."
|
48
|
+
end
|
26
49
|
end
|
50
|
+
|
51
|
+
@@tables ||= engine.connection.tables
|
52
|
+
@table_exists = @@tables.include?(name) ||
|
53
|
+
@engine.connection.table_exists?(name)
|
27
54
|
end
|
28
55
|
end
|
29
56
|
|
@@ -31,42 +58,24 @@ module Arel
|
|
31
58
|
Table.new(name, options.merge(:as => table_alias))
|
32
59
|
end
|
33
60
|
|
34
|
-
def table_exists?
|
35
|
-
if @table_exists
|
36
|
-
true
|
37
|
-
else
|
38
|
-
@table_exists = @@tables.include?(name) || engine.table_exists?(name)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
61
|
def attributes
|
43
|
-
return @attributes if
|
62
|
+
return @attributes if @attributes
|
44
63
|
if table_exists?
|
45
|
-
|
46
|
-
|
47
|
-
Sql::Attributes.for(column).new(column, self, column.name.to_sym)
|
48
|
-
end
|
49
|
-
Header.new(attrs)
|
64
|
+
attrs = columns.collect do |column|
|
65
|
+
Sql::Attributes.for(column).new(column, self, column.name.to_sym)
|
50
66
|
end
|
67
|
+
@attributes = Header.new(attrs)
|
51
68
|
else
|
52
69
|
Header.new
|
53
70
|
end
|
54
71
|
end
|
55
72
|
|
56
|
-
def eql?(other)
|
57
|
-
self == other
|
58
|
-
end
|
59
|
-
|
60
|
-
def hash
|
61
|
-
@hash ||= :name.hash
|
62
|
-
end
|
63
|
-
|
64
73
|
def column_for(attribute)
|
65
74
|
has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s }
|
66
75
|
end
|
67
76
|
|
68
77
|
def columns
|
69
|
-
@columns ||= engine.columns(name, "#{name} Columns")
|
78
|
+
@columns ||= engine.connection.columns(name, "#{name} Columns")
|
70
79
|
end
|
71
80
|
|
72
81
|
def reset
|
@@ -74,10 +83,13 @@ module Arel
|
|
74
83
|
@attributes = Header.new([])
|
75
84
|
end
|
76
85
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
86
|
+
private
|
87
|
+
def matching_attributes
|
88
|
+
@matching_attributes ||= Hash[attributes.map { |a| [a.root, true] }]
|
89
|
+
end
|
90
|
+
|
91
|
+
def has_attribute?(attribute)
|
92
|
+
matching_attributes.key? attribute.root
|
81
93
|
end
|
82
94
|
end
|
83
95
|
end
|