arel-compat 0.4.0
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/History.txt +25 -0
- data/README.markdown +182 -0
- data/lib/arel.rb +13 -0
- data/lib/arel/algebra.rb +10 -0
- data/lib/arel/algebra/attributes.rb +7 -0
- data/lib/arel/algebra/attributes/attribute.rb +270 -0
- data/lib/arel/algebra/attributes/boolean.rb +21 -0
- data/lib/arel/algebra/attributes/decimal.rb +9 -0
- data/lib/arel/algebra/attributes/float.rb +9 -0
- data/lib/arel/algebra/attributes/integer.rb +10 -0
- data/lib/arel/algebra/attributes/string.rb +10 -0
- data/lib/arel/algebra/attributes/time.rb +6 -0
- data/lib/arel/algebra/core_extensions.rb +4 -0
- data/lib/arel/algebra/core_extensions/class.rb +32 -0
- data/lib/arel/algebra/core_extensions/hash.rb +11 -0
- data/lib/arel/algebra/core_extensions/object.rb +30 -0
- data/lib/arel/algebra/core_extensions/symbol.rb +9 -0
- data/lib/arel/algebra/expression.rb +43 -0
- data/lib/arel/algebra/header.rb +67 -0
- data/lib/arel/algebra/ordering.rb +23 -0
- data/lib/arel/algebra/predicates.rb +190 -0
- data/lib/arel/algebra/relations.rb +17 -0
- data/lib/arel/algebra/relations/operations/alias.rb +7 -0
- data/lib/arel/algebra/relations/operations/from.rb +6 -0
- data/lib/arel/algebra/relations/operations/group.rb +12 -0
- data/lib/arel/algebra/relations/operations/having.rb +17 -0
- data/lib/arel/algebra/relations/operations/join.rb +69 -0
- data/lib/arel/algebra/relations/operations/lock.rb +12 -0
- data/lib/arel/algebra/relations/operations/order.rb +19 -0
- data/lib/arel/algebra/relations/operations/project.rb +20 -0
- data/lib/arel/algebra/relations/operations/skip.rb +7 -0
- data/lib/arel/algebra/relations/operations/take.rb +11 -0
- data/lib/arel/algebra/relations/operations/where.rb +17 -0
- data/lib/arel/algebra/relations/relation.rb +136 -0
- data/lib/arel/algebra/relations/row.rb +26 -0
- data/lib/arel/algebra/relations/utilities/compound.rb +54 -0
- data/lib/arel/algebra/relations/utilities/externalization.rb +24 -0
- data/lib/arel/algebra/relations/utilities/nil.rb +7 -0
- data/lib/arel/algebra/relations/writes.rb +36 -0
- data/lib/arel/algebra/value.rb +14 -0
- data/lib/arel/engines.rb +2 -0
- data/lib/arel/engines/memory.rb +4 -0
- data/lib/arel/engines/memory/engine.rb +16 -0
- data/lib/arel/engines/memory/predicates.rb +99 -0
- data/lib/arel/engines/memory/primitives.rb +27 -0
- data/lib/arel/engines/memory/relations.rb +5 -0
- data/lib/arel/engines/memory/relations/array.rb +35 -0
- data/lib/arel/engines/memory/relations/compound.rb +9 -0
- data/lib/arel/engines/memory/relations/operations.rb +67 -0
- data/lib/arel/engines/memory/relations/writes.rb +7 -0
- data/lib/arel/engines/sql.rb +8 -0
- data/lib/arel/engines/sql/attributes.rb +40 -0
- data/lib/arel/engines/sql/christener.rb +14 -0
- data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +48 -0
- data/lib/arel/engines/sql/compilers/mysql_compiler.rb +11 -0
- data/lib/arel/engines/sql/compilers/oracle_compiler.rb +95 -0
- data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +42 -0
- data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +9 -0
- data/lib/arel/engines/sql/core_extensions.rb +4 -0
- data/lib/arel/engines/sql/core_extensions/array.rb +24 -0
- data/lib/arel/engines/sql/core_extensions/nil_class.rb +15 -0
- data/lib/arel/engines/sql/core_extensions/object.rb +19 -0
- data/lib/arel/engines/sql/core_extensions/range.rb +19 -0
- data/lib/arel/engines/sql/engine.rb +55 -0
- data/lib/arel/engines/sql/formatters.rb +122 -0
- data/lib/arel/engines/sql/predicates.rb +103 -0
- data/lib/arel/engines/sql/primitives.rb +97 -0
- data/lib/arel/engines/sql/relations.rb +10 -0
- data/lib/arel/engines/sql/relations/compiler.rb +118 -0
- data/lib/arel/engines/sql/relations/operations/alias.rb +5 -0
- data/lib/arel/engines/sql/relations/operations/join.rb +33 -0
- data/lib/arel/engines/sql/relations/relation.rb +65 -0
- data/lib/arel/engines/sql/relations/table.rb +88 -0
- data/lib/arel/engines/sql/relations/utilities/compound.rb +10 -0
- data/lib/arel/engines/sql/relations/utilities/externalization.rb +14 -0
- data/lib/arel/engines/sql/relations/utilities/nil.rb +6 -0
- data/lib/arel/engines/sql/relations/utilities/recursion.rb +13 -0
- data/lib/arel/engines/sql/relations/writes.rb +19 -0
- data/lib/arel/session.rb +51 -0
- data/lib/arel/version.rb +3 -0
- data/spec/algebra/unit/predicates/binary_spec.rb +35 -0
- data/spec/algebra/unit/predicates/equality_spec.rb +29 -0
- data/spec/algebra/unit/predicates/in_spec.rb +12 -0
- data/spec/algebra/unit/primitives/attribute_spec.rb +181 -0
- data/spec/algebra/unit/primitives/expression_spec.rb +45 -0
- data/spec/algebra/unit/primitives/value_spec.rb +15 -0
- data/spec/algebra/unit/relations/alias_spec.rb +16 -0
- data/spec/algebra/unit/relations/delete_spec.rb +9 -0
- data/spec/algebra/unit/relations/group_spec.rb +10 -0
- data/spec/algebra/unit/relations/insert_spec.rb +9 -0
- data/spec/algebra/unit/relations/join_spec.rb +25 -0
- data/spec/algebra/unit/relations/order_spec.rb +21 -0
- data/spec/algebra/unit/relations/project_spec.rb +34 -0
- data/spec/algebra/unit/relations/relation_spec.rb +187 -0
- data/spec/algebra/unit/relations/skip_spec.rb +10 -0
- data/spec/algebra/unit/relations/table_spec.rb +38 -0
- data/spec/algebra/unit/relations/take_spec.rb +10 -0
- data/spec/algebra/unit/relations/update_spec.rb +9 -0
- data/spec/algebra/unit/relations/where_spec.rb +19 -0
- data/spec/algebra/unit/session/session_spec.rb +84 -0
- data/spec/attributes/boolean_spec.rb +57 -0
- data/spec/attributes/float_spec.rb +119 -0
- data/spec/attributes/header_spec.rb +42 -0
- data/spec/attributes/integer_spec.rb +119 -0
- data/spec/attributes/string_spec.rb +43 -0
- data/spec/attributes/time_spec.rb +24 -0
- data/spec/engines/memory/integration/joins/cross_engine_spec.rb +51 -0
- data/spec/engines/memory/unit/relations/array_spec.rb +32 -0
- data/spec/engines/memory/unit/relations/insert_spec.rb +28 -0
- data/spec/engines/memory/unit/relations/join_spec.rb +31 -0
- data/spec/engines/memory/unit/relations/order_spec.rb +27 -0
- data/spec/engines/memory/unit/relations/project_spec.rb +27 -0
- data/spec/engines/memory/unit/relations/skip_spec.rb +26 -0
- data/spec/engines/memory/unit/relations/take_spec.rb +26 -0
- data/spec/engines/memory/unit/relations/where_spec.rb +39 -0
- data/spec/engines/sql/integration/joins/with_adjacency_spec.rb +258 -0
- data/spec/engines/sql/integration/joins/with_aggregations_spec.rb +221 -0
- data/spec/engines/sql/integration/joins/with_compounds_spec.rb +137 -0
- data/spec/engines/sql/unit/engine_spec.rb +45 -0
- data/spec/engines/sql/unit/predicates/binary_spec.rb +140 -0
- data/spec/engines/sql/unit/predicates/equality_spec.rb +75 -0
- data/spec/engines/sql/unit/predicates/in_spec.rb +179 -0
- data/spec/engines/sql/unit/predicates/noteq_spec.rb +75 -0
- data/spec/engines/sql/unit/predicates/predicates_spec.rb +79 -0
- data/spec/engines/sql/unit/primitives/attribute_spec.rb +36 -0
- data/spec/engines/sql/unit/primitives/expression_spec.rb +28 -0
- data/spec/engines/sql/unit/primitives/literal_spec.rb +43 -0
- data/spec/engines/sql/unit/primitives/value_spec.rb +29 -0
- data/spec/engines/sql/unit/relations/alias_spec.rb +53 -0
- data/spec/engines/sql/unit/relations/delete_spec.rb +83 -0
- data/spec/engines/sql/unit/relations/from_spec.rb +64 -0
- data/spec/engines/sql/unit/relations/group_spec.rb +72 -0
- data/spec/engines/sql/unit/relations/having_spec.rb +78 -0
- data/spec/engines/sql/unit/relations/insert_spec.rb +143 -0
- data/spec/engines/sql/unit/relations/join_spec.rb +180 -0
- data/spec/engines/sql/unit/relations/lock_spec.rb +86 -0
- data/spec/engines/sql/unit/relations/order_spec.rb +161 -0
- data/spec/engines/sql/unit/relations/project_spec.rb +143 -0
- data/spec/engines/sql/unit/relations/skip_spec.rb +41 -0
- data/spec/engines/sql/unit/relations/table_spec.rb +129 -0
- data/spec/engines/sql/unit/relations/take_spec.rb +49 -0
- data/spec/engines/sql/unit/relations/update_spec.rb +203 -0
- data/spec/engines/sql/unit/relations/where_spec.rb +72 -0
- data/spec/relations/join_spec.rb +42 -0
- data/spec/relations/relation_spec.rb +31 -0
- data/spec/shared/relation_spec.rb +255 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/check.rb +6 -0
- data/spec/support/connections/mysql_connection.rb +14 -0
- data/spec/support/connections/oracle_connection.rb +17 -0
- data/spec/support/connections/postgresql_connection.rb +13 -0
- data/spec/support/connections/sqlite3_connection.rb +24 -0
- data/spec/support/guards.rb +28 -0
- data/spec/support/matchers.rb +4 -0
- data/spec/support/matchers/be_like.rb +24 -0
- data/spec/support/matchers/disambiguate_attributes.rb +28 -0
- data/spec/support/matchers/hash_the_same_as.rb +26 -0
- data/spec/support/matchers/have_rows.rb +18 -0
- data/spec/support/model.rb +62 -0
- data/spec/support/schemas/mysql_schema.rb +26 -0
- data/spec/support/schemas/oracle_schema.rb +20 -0
- data/spec/support/schemas/postgresql_schema.rb +26 -0
- data/spec/support/schemas/sqlite3_schema.rb +26 -0
- metadata +258 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
module Arel
|
2
|
+
class SqlLiteral < String
|
3
|
+
def relation
|
4
|
+
nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_sql(formatter = nil)
|
8
|
+
self
|
9
|
+
end
|
10
|
+
|
11
|
+
include Attribute::Expressions
|
12
|
+
end
|
13
|
+
|
14
|
+
class Attribute
|
15
|
+
def column
|
16
|
+
original_relation.column_for(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def format(object)
|
20
|
+
object.to_sql(Sql::Attribute.new(self))
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_sql(formatter = Sql::WhereCondition.new(relation))
|
24
|
+
formatter.attribute self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Value
|
29
|
+
def inclusion_predicate_sql
|
30
|
+
value.inclusion_predicate_sql
|
31
|
+
end
|
32
|
+
|
33
|
+
def exclusion_predicate_sql
|
34
|
+
value.exclusion_predicate_sql
|
35
|
+
end
|
36
|
+
|
37
|
+
def equality_predicate_sql
|
38
|
+
value.equality_predicate_sql
|
39
|
+
end
|
40
|
+
|
41
|
+
def inequality_predicate_sql
|
42
|
+
value.inequality_predicate_sql
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_sql(formatter = Sql::WhereCondition.new(relation))
|
46
|
+
formatter.value value
|
47
|
+
end
|
48
|
+
|
49
|
+
def format(object)
|
50
|
+
object.to_sql(Sql::Value.new(relation))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Ordering
|
55
|
+
def to_sql(formatter = Sql::OrderClause.new(relation))
|
56
|
+
formatter.ordering self
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Ascending < Ordering
|
61
|
+
def direction_sql; 'ASC' end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Descending < Ordering
|
65
|
+
def direction_sql; 'DESC' end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Expression < Attribute
|
69
|
+
def to_sql(formatter = Sql::SelectClause.new(relation))
|
70
|
+
formatter.expression self
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Count < Expression
|
75
|
+
def function_sql; 'COUNT' end
|
76
|
+
end
|
77
|
+
|
78
|
+
class Distinct < Expression
|
79
|
+
def function_sql; 'DISTINCT' end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Sum < Expression
|
83
|
+
def function_sql; 'SUM' end
|
84
|
+
end
|
85
|
+
|
86
|
+
class Maximum < Expression
|
87
|
+
def function_sql; 'MAX' end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Minimum < Expression
|
91
|
+
def function_sql; 'MIN' end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Average < Expression
|
95
|
+
def function_sql; 'AVG' end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,10 @@
|
|
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
|
+
require 'arel/engines/sql/relations/utilities/nil'
|
5
|
+
require 'arel/engines/sql/relations/compiler'
|
6
|
+
require 'arel/engines/sql/relations/relation'
|
7
|
+
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'
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Arel
|
2
|
+
module SqlCompiler
|
3
|
+
class GenericCompiler
|
4
|
+
attr_reader :relation
|
5
|
+
|
6
|
+
def initialize(relation)
|
7
|
+
@relation = relation
|
8
|
+
end
|
9
|
+
|
10
|
+
def select_sql
|
11
|
+
query = build_query \
|
12
|
+
"SELECT #{select_clauses.join(', ')}",
|
13
|
+
"FROM #{from_clauses}",
|
14
|
+
(joins(self) unless joins(self).blank? ),
|
15
|
+
("WHERE #{where_clauses.join(' AND ')}" unless wheres.blank? ),
|
16
|
+
("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ),
|
17
|
+
("HAVING #{having_clauses.join(' AND ')}" unless havings.blank? ),
|
18
|
+
("ORDER BY #{order_clauses.join(', ')}" unless orders.blank? )
|
19
|
+
engine.add_limit_offset!(query,{ :limit => taken, :offset => skipped }) if taken || skipped
|
20
|
+
query << " #{locked}" unless locked.blank?
|
21
|
+
query
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_sql
|
25
|
+
build_query \
|
26
|
+
"DELETE",
|
27
|
+
"FROM #{table_sql}",
|
28
|
+
("WHERE #{wheres.collect(&:to_sql).join(' AND ')}" unless wheres.blank? ),
|
29
|
+
(add_limit_on_delete(taken) unless taken.blank? )
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_limit_on_delete(taken)
|
33
|
+
"LIMIT #{taken}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def insert_sql(include_returning = true)
|
37
|
+
insertion_attributes_values_sql = if record.is_a?(Value)
|
38
|
+
record.value
|
39
|
+
else
|
40
|
+
attributes = record.keys.sort_by do |attribute|
|
41
|
+
attribute.name.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
first = attributes.collect do |key|
|
45
|
+
engine.quote_column_name(key.name)
|
46
|
+
end.join(', ')
|
47
|
+
|
48
|
+
second = attributes.collect do |key|
|
49
|
+
key.format(record[key])
|
50
|
+
end.join(', ')
|
51
|
+
|
52
|
+
build_query "(#{first})", "VALUES (#{second})"
|
53
|
+
end
|
54
|
+
|
55
|
+
build_query \
|
56
|
+
"INSERT",
|
57
|
+
"INTO #{table_sql}",
|
58
|
+
insertion_attributes_values_sql,
|
59
|
+
("RETURNING #{engine.quote_column_name(primary_key)}" if include_returning && compiler.supports_insert_with_returning?)
|
60
|
+
end
|
61
|
+
|
62
|
+
def supports_insert_with_returning?
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
def update_sql
|
67
|
+
build_query \
|
68
|
+
"UPDATE #{table_sql} SET",
|
69
|
+
assignment_sql,
|
70
|
+
build_update_conditions_sql
|
71
|
+
end
|
72
|
+
|
73
|
+
protected
|
74
|
+
def method_missing(method, *args, &block)
|
75
|
+
relation.send(method, *args, &block)
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_query(*parts)
|
79
|
+
parts.compact.join(" ")
|
80
|
+
end
|
81
|
+
|
82
|
+
def assignment_sql
|
83
|
+
if assignments.respond_to?(:collect)
|
84
|
+
attributes = assignments.keys.sort_by do |attribute|
|
85
|
+
attribute.name.to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
attributes.map do |attribute|
|
89
|
+
value = assignments[attribute]
|
90
|
+
"#{engine.quote_column_name(attribute.name)} = #{attribute.format(value)}"
|
91
|
+
end.join(", ")
|
92
|
+
else
|
93
|
+
assignments.value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def build_update_conditions_sql
|
98
|
+
conditions = ""
|
99
|
+
conditions << " WHERE #{wheres.collect(&:to_sql).join(' AND ')}" unless wheres.blank?
|
100
|
+
conditions << " ORDER BY #{order_clauses.join(', ')}" unless orders.blank?
|
101
|
+
|
102
|
+
unless taken.blank?
|
103
|
+
conditions = limited_update_conditions(conditions, taken)
|
104
|
+
end
|
105
|
+
|
106
|
+
conditions
|
107
|
+
end
|
108
|
+
|
109
|
+
def limited_update_conditions(conditions, taken)
|
110
|
+
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})"
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Arel
|
2
|
+
class Join
|
3
|
+
def table_sql(formatter = Sql::TableReference.new(self))
|
4
|
+
relation1.externalize.table_sql(formatter)
|
5
|
+
end
|
6
|
+
|
7
|
+
def joins(environment, formatter = Sql::TableReference.new(environment))
|
8
|
+
@joins ||= begin
|
9
|
+
this_join = [
|
10
|
+
join_sql,
|
11
|
+
relation2.externalize.table_sql(formatter),
|
12
|
+
("ON" unless predicates.blank?),
|
13
|
+
(ons + relation2.externalize.wheres).collect { |p| p.bind(environment.relation).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ')
|
14
|
+
].compact.join(" ")
|
15
|
+
[relation1.joins(environment), this_join, relation2.joins(environment)].compact.join(" ")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class InnerJoin < Join
|
21
|
+
def join_sql; "INNER JOIN" end
|
22
|
+
end
|
23
|
+
|
24
|
+
class OuterJoin < Join
|
25
|
+
def join_sql; "LEFT OUTER JOIN" end
|
26
|
+
end
|
27
|
+
|
28
|
+
class StringJoin < Join
|
29
|
+
def joins(environment, formatter = Sql::TableReference.new(environment))
|
30
|
+
[relation1.joins(environment), relation2].compact.join(" ")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Arel
|
2
|
+
module Relation
|
3
|
+
@@connection_tables_primary_keys = {}
|
4
|
+
|
5
|
+
def compiler
|
6
|
+
@compiler ||= begin
|
7
|
+
"Arel::SqlCompiler::#{engine.adapter_name}Compiler".constantize.new(self)
|
8
|
+
rescue
|
9
|
+
Arel::SqlCompiler::GenericCompiler.new(self)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_sql(formatter = Sql::SelectStatement.new(self))
|
14
|
+
formatter.select compiler.select_sql, self
|
15
|
+
end
|
16
|
+
|
17
|
+
def christener
|
18
|
+
@christener ||= Sql::Christener.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def inclusion_predicate_sql
|
22
|
+
"IN"
|
23
|
+
end
|
24
|
+
|
25
|
+
def exclusion_predicate_sql
|
26
|
+
"NOT IN"
|
27
|
+
end
|
28
|
+
|
29
|
+
def primary_key
|
30
|
+
connection_id = engine.connection.object_id
|
31
|
+
if @@connection_tables_primary_keys[connection_id] && @@connection_tables_primary_keys[connection_id].has_key?(table.name)
|
32
|
+
@@connection_tables_primary_keys[connection_id][table.name]
|
33
|
+
else
|
34
|
+
@@connection_tables_primary_keys[connection_id] ||= {}
|
35
|
+
@@connection_tables_primary_keys[connection_id][table.name] = engine.connection.primary_key(table.name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def from_clauses
|
42
|
+
sources.blank? ? table_sql(Sql::TableReference.new(self)) : sources
|
43
|
+
end
|
44
|
+
|
45
|
+
def select_clauses
|
46
|
+
attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def where_clauses
|
50
|
+
wheres.collect { |w| w.to_sql(Sql::WhereClause.new(self)) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def group_clauses
|
54
|
+
groupings.collect { |g| g.to_sql(Sql::GroupClause.new(self)) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def having_clauses
|
58
|
+
havings.collect { |g| g.to_sql(Sql::HavingClause.new(self)) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def order_clauses
|
62
|
+
orders.collect { |o| o.to_sql(Sql::OrderClause.new(self)) }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Arel
|
2
|
+
class Table
|
3
|
+
include Relation, Recursion::BaseCase
|
4
|
+
|
5
|
+
cattr_accessor :engine, :tables
|
6
|
+
attr_reader :name, :engine, :table_alias, :options
|
7
|
+
|
8
|
+
def initialize(name, options = {})
|
9
|
+
@name = name.to_s
|
10
|
+
@table_exists = nil
|
11
|
+
|
12
|
+
if options.is_a?(Hash)
|
13
|
+
@options = options
|
14
|
+
@engine = options[:engine] || Table.engine
|
15
|
+
@table_alias = options[:as].to_s if options[:as].present? && options[:as].to_s != @name
|
16
|
+
else
|
17
|
+
@engine = options # Table.new('foo', engine)
|
18
|
+
end
|
19
|
+
|
20
|
+
if @engine.connection
|
21
|
+
begin
|
22
|
+
require "arel/engines/sql/compilers/#{@engine.adapter_name.downcase}_compiler"
|
23
|
+
@@tables ||= engine.tables
|
24
|
+
rescue LoadError
|
25
|
+
raise "#{@engine.adapter_name} is not supported by Arel."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def as(table_alias)
|
31
|
+
Table.new(name, options.merge(:as => table_alias))
|
32
|
+
end
|
33
|
+
|
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
|
+
def attributes
|
43
|
+
return @attributes if defined?(@attributes)
|
44
|
+
if table_exists?
|
45
|
+
@attributes ||= begin
|
46
|
+
attrs = columns.collect do |column|
|
47
|
+
Sql::Attributes.for(column).new(column, self, column.name.to_sym)
|
48
|
+
end
|
49
|
+
Header.new(attrs)
|
50
|
+
end
|
51
|
+
else
|
52
|
+
Header.new
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def eql?(other)
|
57
|
+
self == other
|
58
|
+
end
|
59
|
+
|
60
|
+
def hash
|
61
|
+
@hash ||= :name.hash
|
62
|
+
end
|
63
|
+
|
64
|
+
def column_for(attribute)
|
65
|
+
has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s }
|
66
|
+
end
|
67
|
+
|
68
|
+
def columns
|
69
|
+
@columns ||= engine.columns(name, "#{name} Columns")
|
70
|
+
end
|
71
|
+
|
72
|
+
def reset
|
73
|
+
@columns = nil
|
74
|
+
@attributes = Header.new([])
|
75
|
+
end
|
76
|
+
|
77
|
+
def ==(other)
|
78
|
+
Table === other and
|
79
|
+
name == other.name and
|
80
|
+
table_alias == other.table_alias
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def Table(name, engine = Arel::Table.engine)
|
86
|
+
Arel::Table.new(name, engine)
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Arel
|
2
|
+
class Externalization < Compound
|
3
|
+
include Recursion::BaseCase
|
4
|
+
|
5
|
+
def table_sql(formatter = Sql::TableReference.new(relation))
|
6
|
+
formatter.select relation.compiler.select_sql, self
|
7
|
+
end
|
8
|
+
|
9
|
+
# REMOVEME
|
10
|
+
def name
|
11
|
+
relation.name + '_external'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|