arel 1.0.1 → 2.0.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.
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