arel 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (247) hide show
  1. data/MIT-LICENSE.txt +20 -0
  2. data/Manifest.txt +105 -0
  3. data/README.markdown +12 -32
  4. data/Rakefile +17 -0
  5. data/arel.gemspec +39 -0
  6. data/lib/arel.rb +30 -9
  7. data/lib/arel/attributes.rb +20 -0
  8. data/lib/arel/attributes/attribute.rb +190 -0
  9. data/lib/arel/compatibility/wheres.rb +33 -0
  10. data/lib/arel/crud.rb +37 -0
  11. data/lib/arel/delete_manager.rb +22 -0
  12. data/lib/arel/deprecated.rb +4 -0
  13. data/lib/arel/expression.rb +4 -0
  14. data/lib/arel/expressions.rb +23 -0
  15. data/lib/arel/insert_manager.rb +34 -0
  16. data/lib/arel/nodes.rb +44 -0
  17. data/lib/arel/nodes/and.rb +6 -0
  18. data/lib/arel/nodes/assignment.rb +6 -0
  19. data/lib/arel/nodes/avg.rb +6 -0
  20. data/lib/arel/nodes/between.rb +6 -0
  21. data/lib/arel/nodes/binary.rb +12 -0
  22. data/lib/arel/nodes/count.rb +13 -0
  23. data/lib/arel/nodes/delete_statement.rb +17 -0
  24. data/lib/arel/nodes/does_not_match.rb +6 -0
  25. data/lib/arel/nodes/equality.rb +9 -0
  26. data/lib/arel/nodes/exists.rb +11 -0
  27. data/lib/arel/nodes/function.rb +18 -0
  28. data/lib/arel/nodes/greater_than.rb +6 -0
  29. data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
  30. data/lib/arel/nodes/group.rb +11 -0
  31. data/lib/arel/nodes/grouping.rb +11 -0
  32. data/lib/arel/nodes/having.rb +11 -0
  33. data/lib/arel/nodes/in.rb +6 -0
  34. data/lib/arel/nodes/inner_join.rb +6 -0
  35. data/lib/arel/nodes/insert_statement.rb +19 -0
  36. data/lib/arel/nodes/join.rb +13 -0
  37. data/lib/arel/nodes/less_than.rb +6 -0
  38. data/lib/arel/nodes/less_than_or_equal.rb +6 -0
  39. data/lib/arel/nodes/lock.rb +6 -0
  40. data/lib/arel/nodes/matches.rb +6 -0
  41. data/lib/arel/nodes/max.rb +6 -0
  42. data/lib/arel/nodes/min.rb +6 -0
  43. data/lib/arel/nodes/node.rb +30 -0
  44. data/lib/arel/nodes/not_equal.rb +6 -0
  45. data/lib/arel/nodes/not_in.rb +6 -0
  46. data/lib/arel/nodes/offset.rb +11 -0
  47. data/lib/arel/nodes/on.rb +11 -0
  48. data/lib/arel/nodes/or.rb +6 -0
  49. data/lib/arel/nodes/ordering.rb +19 -0
  50. data/lib/arel/nodes/outer_join.rb +6 -0
  51. data/lib/arel/nodes/select_core.rb +25 -0
  52. data/lib/arel/nodes/select_statement.rb +22 -0
  53. data/lib/arel/nodes/sql_literal.rb +7 -0
  54. data/lib/arel/nodes/string_join.rb +11 -0
  55. data/lib/arel/nodes/sum.rb +6 -0
  56. data/lib/arel/nodes/table_alias.rb +21 -0
  57. data/lib/arel/nodes/unqualified_column.rb +19 -0
  58. data/lib/arel/nodes/update_statement.rb +21 -0
  59. data/lib/arel/nodes/values.rb +12 -0
  60. data/lib/arel/relation.rb +6 -0
  61. data/lib/arel/select_manager.rb +203 -0
  62. data/lib/arel/sql/engine.rb +10 -0
  63. data/lib/arel/sql_literal.rb +1 -10
  64. data/lib/arel/table.rb +126 -0
  65. data/lib/arel/tree_manager.rb +26 -0
  66. data/lib/arel/update_manager.rb +48 -0
  67. data/lib/arel/visitors.rb +30 -0
  68. data/lib/arel/visitors/dot.rb +233 -0
  69. data/lib/arel/visitors/join_sql.rb +38 -0
  70. data/lib/arel/visitors/mysql.rb +16 -0
  71. data/lib/arel/visitors/oracle.rb +69 -0
  72. data/lib/arel/visitors/order_clauses.rb +9 -0
  73. data/lib/arel/visitors/postgresql.rb +54 -0
  74. data/lib/arel/visitors/to_sql.rb +301 -0
  75. data/lib/arel/visitors/where_sql.rb +9 -0
  76. data/spec/activerecord_compat_spec.rb +18 -0
  77. data/spec/attributes/attribute_spec.rb +648 -0
  78. data/spec/attributes_spec.rb +33 -6
  79. data/spec/crud_spec.rb +69 -0
  80. data/spec/delete_manager_spec.rb +53 -0
  81. data/spec/insert_manager_spec.rb +141 -0
  82. data/spec/nodes/count_spec.rb +18 -0
  83. data/spec/nodes/delete_statement_spec.rb +15 -0
  84. data/spec/nodes/equality_spec.rb +72 -0
  85. data/spec/nodes/insert_statement_spec.rb +18 -0
  86. data/spec/nodes/or_spec.rb +20 -0
  87. data/spec/nodes/select_core_spec.rb +21 -0
  88. data/spec/nodes/select_statement_spec.rb +14 -0
  89. data/spec/nodes/sql_literal_spec.rb +26 -0
  90. data/spec/nodes/sum_spec.rb +12 -0
  91. data/spec/nodes/update_statement_spec.rb +18 -0
  92. data/spec/select_manager_spec.rb +581 -0
  93. data/spec/spec.opts +3 -0
  94. data/spec/spec_helper.rb +6 -21
  95. data/spec/support/fake_record.rb +89 -0
  96. data/spec/support/shared/tree_manager_shared.rb +9 -0
  97. data/spec/table_spec.rb +176 -0
  98. data/spec/update_manager_spec.rb +89 -0
  99. data/spec/visitors/join_sql_spec.rb +35 -0
  100. data/spec/visitors/oracle_spec.rb +111 -0
  101. data/spec/visitors/to_sql_spec.rb +134 -0
  102. metadata +160 -260
  103. data/lib/arel/algebra.rb +0 -10
  104. data/lib/arel/algebra/attributes.rb +0 -7
  105. data/lib/arel/algebra/attributes/attribute.rb +0 -304
  106. data/lib/arel/algebra/attributes/boolean.rb +0 -21
  107. data/lib/arel/algebra/attributes/decimal.rb +0 -9
  108. data/lib/arel/algebra/attributes/float.rb +0 -9
  109. data/lib/arel/algebra/attributes/integer.rb +0 -10
  110. data/lib/arel/algebra/attributes/string.rb +0 -10
  111. data/lib/arel/algebra/attributes/time.rb +0 -6
  112. data/lib/arel/algebra/core_extensions.rb +0 -3
  113. data/lib/arel/algebra/core_extensions/hash.rb +0 -7
  114. data/lib/arel/algebra/core_extensions/object.rb +0 -13
  115. data/lib/arel/algebra/core_extensions/symbol.rb +0 -9
  116. data/lib/arel/algebra/expression.rb +0 -56
  117. data/lib/arel/algebra/header.rb +0 -66
  118. data/lib/arel/algebra/ordering.rb +0 -31
  119. data/lib/arel/algebra/predicates.rb +0 -306
  120. data/lib/arel/algebra/relations.rb +0 -16
  121. data/lib/arel/algebra/relations/operations/from.rb +0 -14
  122. data/lib/arel/algebra/relations/operations/group.rb +0 -14
  123. data/lib/arel/algebra/relations/operations/having.rb +0 -14
  124. data/lib/arel/algebra/relations/operations/join.rb +0 -103
  125. data/lib/arel/algebra/relations/operations/lock.rb +0 -10
  126. data/lib/arel/algebra/relations/operations/order.rb +0 -23
  127. data/lib/arel/algebra/relations/operations/project.rb +0 -20
  128. data/lib/arel/algebra/relations/operations/skip.rb +0 -14
  129. data/lib/arel/algebra/relations/operations/take.rb +0 -18
  130. data/lib/arel/algebra/relations/operations/where.rb +0 -24
  131. data/lib/arel/algebra/relations/relation.rb +0 -205
  132. data/lib/arel/algebra/relations/row.rb +0 -29
  133. data/lib/arel/algebra/relations/utilities/compound.rb +0 -55
  134. data/lib/arel/algebra/relations/utilities/externalization.rb +0 -26
  135. data/lib/arel/algebra/relations/utilities/nil.rb +0 -7
  136. data/lib/arel/algebra/relations/writes.rb +0 -47
  137. data/lib/arel/algebra/value.rb +0 -53
  138. data/lib/arel/engines.rb +0 -2
  139. data/lib/arel/engines/memory.rb +0 -2
  140. data/lib/arel/engines/memory/engine.rb +0 -10
  141. data/lib/arel/engines/memory/relations.rb +0 -2
  142. data/lib/arel/engines/memory/relations/array.rb +0 -37
  143. data/lib/arel/engines/memory/relations/operations.rb +0 -9
  144. data/lib/arel/engines/sql.rb +0 -6
  145. data/lib/arel/engines/sql/attributes.rb +0 -45
  146. data/lib/arel/engines/sql/christener.rb +0 -20
  147. data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +0 -48
  148. data/lib/arel/engines/sql/compilers/mysql_compiler.rb +0 -11
  149. data/lib/arel/engines/sql/compilers/oracle_compiler.rb +0 -106
  150. data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +0 -50
  151. data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +0 -9
  152. data/lib/arel/engines/sql/core_extensions.rb +0 -4
  153. data/lib/arel/engines/sql/core_extensions/array.rb +0 -24
  154. data/lib/arel/engines/sql/core_extensions/nil_class.rb +0 -15
  155. data/lib/arel/engines/sql/core_extensions/object.rb +0 -19
  156. data/lib/arel/engines/sql/core_extensions/range.rb +0 -19
  157. data/lib/arel/engines/sql/engine.rb +0 -47
  158. data/lib/arel/engines/sql/formatters.rb +0 -138
  159. data/lib/arel/engines/sql/relations.rb +0 -3
  160. data/lib/arel/engines/sql/relations/compiler.rb +0 -153
  161. data/lib/arel/engines/sql/relations/table.rb +0 -100
  162. data/lib/arel/engines/sql/relations/utilities/nil.rb +0 -6
  163. data/lib/arel/recursion/base_case.rb +0 -13
  164. data/lib/arel/session.rb +0 -35
  165. data/lib/arel/version.rb +0 -3
  166. data/spec/algebra/unit/predicates/binary_spec.rb +0 -35
  167. data/spec/algebra/unit/predicates/equality_spec.rb +0 -29
  168. data/spec/algebra/unit/predicates/in_spec.rb +0 -12
  169. data/spec/algebra/unit/predicates/inequality_spec.rb +0 -32
  170. data/spec/algebra/unit/predicates/predicate_spec.rb +0 -22
  171. data/spec/algebra/unit/primitives/attribute_spec.rb +0 -175
  172. data/spec/algebra/unit/primitives/expression_spec.rb +0 -39
  173. data/spec/algebra/unit/primitives/value_spec.rb +0 -15
  174. data/spec/algebra/unit/relations/alias_spec.rb +0 -16
  175. data/spec/algebra/unit/relations/delete_spec.rb +0 -9
  176. data/spec/algebra/unit/relations/group_spec.rb +0 -10
  177. data/spec/algebra/unit/relations/insert_spec.rb +0 -9
  178. data/spec/algebra/unit/relations/join_spec.rb +0 -18
  179. data/spec/algebra/unit/relations/order_spec.rb +0 -21
  180. data/spec/algebra/unit/relations/project_spec.rb +0 -34
  181. data/spec/algebra/unit/relations/relation_spec.rb +0 -241
  182. data/spec/algebra/unit/relations/skip_spec.rb +0 -10
  183. data/spec/algebra/unit/relations/table_spec.rb +0 -38
  184. data/spec/algebra/unit/relations/take_spec.rb +0 -10
  185. data/spec/algebra/unit/relations/update_spec.rb +0 -9
  186. data/spec/algebra/unit/relations/where_spec.rb +0 -19
  187. data/spec/algebra/unit/session/session_spec.rb +0 -84
  188. data/spec/attributes/boolean_spec.rb +0 -57
  189. data/spec/attributes/float_spec.rb +0 -119
  190. data/spec/attributes/header_spec.rb +0 -42
  191. data/spec/attributes/integer_spec.rb +0 -119
  192. data/spec/attributes/string_spec.rb +0 -43
  193. data/spec/attributes/time_spec.rb +0 -24
  194. data/spec/engines/memory/integration/joins/cross_engine_spec.rb +0 -61
  195. data/spec/engines/memory/unit/relations/array_spec.rb +0 -33
  196. data/spec/engines/memory/unit/relations/insert_spec.rb +0 -28
  197. data/spec/engines/memory/unit/relations/join_spec.rb +0 -32
  198. data/spec/engines/memory/unit/relations/order_spec.rb +0 -28
  199. data/spec/engines/memory/unit/relations/project_spec.rb +0 -27
  200. data/spec/engines/memory/unit/relations/skip_spec.rb +0 -31
  201. data/spec/engines/memory/unit/relations/take_spec.rb +0 -28
  202. data/spec/engines/memory/unit/relations/where_spec.rb +0 -43
  203. data/spec/engines/sql/integration/joins/with_adjacency_spec.rb +0 -258
  204. data/spec/engines/sql/integration/joins/with_aggregations_spec.rb +0 -221
  205. data/spec/engines/sql/integration/joins/with_compounds_spec.rb +0 -137
  206. data/spec/engines/sql/unit/engine_spec.rb +0 -65
  207. data/spec/engines/sql/unit/predicates/binary_spec.rb +0 -140
  208. data/spec/engines/sql/unit/predicates/equality_spec.rb +0 -75
  209. data/spec/engines/sql/unit/predicates/in_spec.rb +0 -179
  210. data/spec/engines/sql/unit/predicates/noteq_spec.rb +0 -75
  211. data/spec/engines/sql/unit/predicates/predicates_spec.rb +0 -79
  212. data/spec/engines/sql/unit/primitives/attribute_spec.rb +0 -36
  213. data/spec/engines/sql/unit/primitives/expression_spec.rb +0 -28
  214. data/spec/engines/sql/unit/primitives/literal_spec.rb +0 -43
  215. data/spec/engines/sql/unit/primitives/value_spec.rb +0 -29
  216. data/spec/engines/sql/unit/relations/alias_spec.rb +0 -53
  217. data/spec/engines/sql/unit/relations/delete_spec.rb +0 -83
  218. data/spec/engines/sql/unit/relations/from_spec.rb +0 -64
  219. data/spec/engines/sql/unit/relations/group_spec.rb +0 -72
  220. data/spec/engines/sql/unit/relations/having_spec.rb +0 -78
  221. data/spec/engines/sql/unit/relations/insert_spec.rb +0 -143
  222. data/spec/engines/sql/unit/relations/join_spec.rb +0 -180
  223. data/spec/engines/sql/unit/relations/lock_spec.rb +0 -86
  224. data/spec/engines/sql/unit/relations/order_spec.rb +0 -161
  225. data/spec/engines/sql/unit/relations/project_spec.rb +0 -143
  226. data/spec/engines/sql/unit/relations/skip_spec.rb +0 -41
  227. data/spec/engines/sql/unit/relations/table_spec.rb +0 -122
  228. data/spec/engines/sql/unit/relations/take_spec.rb +0 -75
  229. data/spec/engines/sql/unit/relations/update_spec.rb +0 -203
  230. data/spec/engines/sql/unit/relations/where_spec.rb +0 -72
  231. data/spec/relations/join_spec.rb +0 -42
  232. data/spec/relations/relation_spec.rb +0 -31
  233. data/spec/shared/relation_spec.rb +0 -255
  234. data/spec/sql/christener_spec.rb +0 -70
  235. data/spec/support/connections/mysql_connection.rb +0 -14
  236. data/spec/support/connections/oracle_connection.rb +0 -17
  237. data/spec/support/connections/postgresql_connection.rb +0 -13
  238. data/spec/support/connections/sqlite3_connection.rb +0 -24
  239. data/spec/support/guards.rb +0 -28
  240. data/spec/support/matchers/disambiguate_attributes.rb +0 -28
  241. data/spec/support/matchers/hash_the_same_as.rb +0 -26
  242. data/spec/support/matchers/have_rows.rb +0 -18
  243. data/spec/support/model.rb +0 -67
  244. data/spec/support/schemas/mysql_schema.rb +0 -26
  245. data/spec/support/schemas/oracle_schema.rb +0 -20
  246. data/spec/support/schemas/postgresql_schema.rb +0 -26
  247. data/spec/support/schemas/sqlite3_schema.rb +0 -26
@@ -1,50 +0,0 @@
1
- module Arel
2
- module SqlCompiler
3
- class PostgreSQLCompiler < GenericCompiler
4
-
5
- def select_sql
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?
23
-
24
- build_query \
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? )
29
- else
30
- super
31
- end
32
- end
33
-
34
- def using_distinct_on?
35
- relation.select_clauses.any? { |x| x =~ /DISTINCT ON/ }
36
- end
37
-
38
- def aliased_orders(orders)
39
- # PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this
40
- # by wrapping the +sql+ string as a sub-select and ordering in that query.
41
- order = orders.join(', ').split(/,/).map { |s| s.strip }.reject(&:blank?)
42
- order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{'DESC' if s =~ /\bdesc$/i}" }.join(', ')
43
- end
44
-
45
- def supports_insert_with_returning?
46
- engine.connection.send(:postgresql_version) >= 80200
47
- end
48
- end
49
- end
50
- end
@@ -1,9 +0,0 @@
1
- module Arel
2
- module SqlCompiler
3
- class SQLiteCompiler < GenericCompiler
4
- def locked
5
- nil
6
- end
7
- end
8
- end
9
- end
@@ -1,4 +0,0 @@
1
- require 'arel/engines/sql/core_extensions/object'
2
- require 'arel/engines/sql/core_extensions/array'
3
- require 'arel/engines/sql/core_extensions/range'
4
- require 'arel/engines/sql/core_extensions/nil_class'
@@ -1,24 +0,0 @@
1
- module Arel
2
- module Sql
3
- module ArrayExtensions
4
- def to_sql(formatter = nil)
5
- if any?
6
- "(" + collect { |e| e.to_sql(formatter) }.join(', ') + ")"
7
- else
8
- "(NULL)"
9
- end
10
- end
11
-
12
- def inclusion_predicate_sql
13
- "IN"
14
- end
15
-
16
- def exclusion_predicate_sql
17
- "NOT IN"
18
- end
19
-
20
- Array.send(:include, self)
21
- end
22
- end
23
- end
24
-
@@ -1,15 +0,0 @@
1
- module Arel
2
- module Sql
3
- module NilClassExtensions
4
- def equality_predicate_sql
5
- 'IS'
6
- end
7
-
8
- def inequality_predicate_sql
9
- 'IS NOT'
10
- end
11
-
12
- NilClass.send(:include, self)
13
- end
14
- end
15
- end
@@ -1,19 +0,0 @@
1
- module Arel
2
- module Sql
3
- module ObjectExtensions
4
- def to_sql(formatter)
5
- formatter.scalar self
6
- end
7
-
8
- def equality_predicate_sql
9
- '='
10
- end
11
-
12
- def inequality_predicate_sql
13
- '!='
14
- end
15
-
16
- Object.send(:include, self)
17
- end
18
- end
19
- end
@@ -1,19 +0,0 @@
1
- module Arel
2
- module Sql
3
- module RangeExtensions
4
- def to_sql(formatter = nil)
5
- formatter.range self.begin, self.end
6
- end
7
-
8
- def inclusion_predicate_sql
9
- "BETWEEN"
10
- end
11
-
12
- def exclusion_predicate_sql
13
- "NOT BETWEEN"
14
- end
15
-
16
- Range.send(:include, self)
17
- end
18
- end
19
- end
@@ -1,47 +0,0 @@
1
- module Arel
2
- module Sql
3
- class Engine
4
- def initialize(ar = nil)
5
- @ar = ar
6
- end
7
-
8
- def connection
9
- @ar && @ar.connection
10
- end
11
-
12
- def adapter_name
13
- @adapter_name ||= case (name = connection.adapter_name)
14
- # map OracleEnanced adapter to Oracle
15
- when /Oracle/
16
- 'Oracle'
17
- else
18
- name
19
- end
20
- end
21
-
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
28
- end
29
-
30
- connection.insert(relation.to_sql(false), nil, relation.primary_key, primary_key_value)
31
- end
32
-
33
- def read(relation)
34
- rows = connection.select_rows(relation.to_sql)
35
- Array.new(rows, relation.attributes)
36
- end
37
-
38
- def update(relation)
39
- connection.update(relation.to_sql)
40
- end
41
-
42
- def delete(relation)
43
- connection.delete(relation.to_sql)
44
- end
45
- end
46
- end
47
- end
@@ -1,138 +0,0 @@
1
- module Arel
2
- module Sql
3
- class Formatter
4
- attr_reader :environment, :christener, :engine
5
-
6
- def initialize(environment)
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
26
- end
27
- end
28
-
29
- class SelectClause < Formatter
30
- def attribute(attribute)
31
- "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}" +
32
- (attribute.alias ? " AS #{quote(attribute.alias.to_s)}" : "")
33
- end
34
-
35
- def expression(expression)
36
- if expression.function_sql == "DISTINCT"
37
- "#{expression.function_sql} #{expression.attribute.to_sql(self)}" +
38
- (expression.alias ? " AS #{quote_column_name(expression.alias)}" : '')
39
- else
40
- "#{expression.function_sql}(#{expression.attribute.to_sql(self)})" +
41
- (expression.alias ? " AS #{quote_column_name(expression.alias)}" : " AS #{expression.function_sql.to_s.downcase}_id")
42
- end
43
- end
44
-
45
- def select(select_sql, table)
46
- "(#{select_sql}) AS #{quote_table_name(name_for(table))}"
47
- end
48
-
49
- def value(value)
50
- value
51
- end
52
- end
53
-
54
- class PassThrough < Formatter
55
- def value(value)
56
- value
57
- end
58
- end
59
-
60
- class WhereClause < PassThrough
61
- end
62
-
63
- class OrderClause < PassThrough
64
- def ordering(ordering)
65
- "#{quote_table_name(name_for(ordering.attribute.original_relation))}.#{quote_column_name(ordering.attribute.name)} #{ordering.direction_sql}"
66
- end
67
- end
68
-
69
- class GroupClause < PassThrough
70
- def attribute(attribute)
71
- "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}"
72
- end
73
- end
74
-
75
- class HavingClause < PassThrough
76
- def attribute(attribute)
77
- attribute
78
- end
79
- end
80
-
81
- class WhereCondition < Formatter
82
- def attribute(attribute)
83
- "#{quote_table_name(name_for(attribute.original_relation))}.#{quote_column_name(attribute.name)}"
84
- end
85
-
86
- def expression(expression)
87
- "#{expression.function_sql}(#{expression.attribute.to_sql(self)})"
88
- end
89
-
90
- def value(value)
91
- value.to_sql(self)
92
- end
93
-
94
- def scalar(value, column = nil)
95
- quote(value, column)
96
- end
97
-
98
- def select(select_sql, table)
99
- "(#{select_sql})"
100
- end
101
- end
102
-
103
- class SelectStatement < Formatter
104
- def select(select_sql, table)
105
- select_sql
106
- end
107
- end
108
-
109
- class TableReference < Formatter
110
- def select(select_sql, table)
111
- "(#{select_sql}) #{quote_table_name(name_for(table))}"
112
- end
113
-
114
- def table(table)
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)}" : '')
122
- end
123
- end
124
-
125
- class Attribute < WhereCondition
126
- def scalar(scalar)
127
- quote(scalar, environment.column)
128
- end
129
-
130
- def range(left, right)
131
- "#{scalar(left)} AND #{scalar(right)}"
132
- end
133
- end
134
-
135
- class Value < WhereCondition
136
- end
137
- end
138
- end
@@ -1,3 +0,0 @@
1
- require 'arel/engines/sql/relations/utilities/nil'
2
- require 'arel/engines/sql/relations/compiler'
3
- require 'arel/engines/sql/relations/table'
@@ -1,153 +0,0 @@
1
- module Arel
2
- module SqlCompiler
3
- class GenericCompiler
4
- attr_reader :relation, :engine
5
-
6
- def initialize(relation)
7
- @relation = relation
8
- @engine = relation.engine
9
- end
10
-
11
- def christener
12
- relation.christener
13
- end
14
-
15
- def select_sql
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?
55
- end
56
-
57
- def delete_sql
58
- build_query \
59
- "DELETE",
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? )
63
- end
64
-
65
- def add_limit_on_delete(taken)
66
- "LIMIT #{taken}"
67
- end
68
-
69
- def insert_sql(include_returning = true)
70
- insertion_attributes_values_sql = if relation.record.is_a?(Value)
71
- relation.record.value
72
- else
73
- attributes = relation.record.keys.sort_by do |attribute|
74
- attribute.name.to_s
75
- end
76
-
77
- first = attributes.collect do |key|
78
- @engine.connection.quote_column_name(key.name)
79
- end.join(', ')
80
-
81
- second = attributes.collect do |key|
82
- key.format(relation.record[key])
83
- end.join(', ')
84
-
85
- build_query "(#{first})", "VALUES (#{second})"
86
- end
87
-
88
- build_query \
89
- "INSERT",
90
- "INTO #{relation.table_sql}",
91
- insertion_attributes_values_sql,
92
- ("RETURNING #{engine.connection.quote_column_name(relation.primary_key)}" if include_returning && relation.compiler.supports_insert_with_returning?)
93
- end
94
-
95
- def supports_insert_with_returning?
96
- false
97
- end
98
-
99
- def update_sql
100
- build_query \
101
- "UPDATE #{relation.table_sql} SET",
102
- assignment_sql,
103
- build_update_conditions_sql
104
- end
105
-
106
- protected
107
-
108
- def locked
109
- relation.locked
110
- end
111
-
112
- def build_query(*parts)
113
- parts.compact.join(" ")
114
- end
115
-
116
- def assignment_sql
117
- if relation.assignments.respond_to?(:collect)
118
- attributes = relation.assignments.keys.sort_by do |attribute|
119
- attribute.name.to_s
120
- end
121
-
122
- attributes.map do |attribute|
123
- value = relation.assignments[attribute]
124
- "#{@engine.connection.quote_column_name(attribute.name)} = #{attribute.format(value)}"
125
- end.join(", ")
126
- else
127
- relation.assignments.value
128
- end
129
- end
130
-
131
- def build_update_conditions_sql
132
- conditions = ""
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?
135
-
136
- taken = relation.taken
137
- unless taken.blank?
138
- conditions = limited_update_conditions(conditions, taken)
139
- end
140
-
141
- conditions
142
- end
143
-
144
- def limited_update_conditions(conditions, taken)
145
- conditions << " LIMIT #{taken}"
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})"
148
- end
149
-
150
- end
151
-
152
- end
153
- end