activerecord 3.2.22.5 → 4.2.11.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (236) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1632 -609
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +37 -41
  5. data/examples/performance.rb +31 -19
  6. data/examples/simple.rb +4 -4
  7. data/lib/active_record/aggregations.rb +56 -42
  8. data/lib/active_record/association_relation.rb +35 -0
  9. data/lib/active_record/associations/alias_tracker.rb +47 -36
  10. data/lib/active_record/associations/association.rb +73 -55
  11. data/lib/active_record/associations/association_scope.rb +143 -82
  12. data/lib/active_record/associations/belongs_to_association.rb +65 -25
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
  14. data/lib/active_record/associations/builder/association.rb +125 -31
  15. data/lib/active_record/associations/builder/belongs_to.rb +89 -61
  16. data/lib/active_record/associations/builder/collection_association.rb +69 -49
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +113 -42
  18. data/lib/active_record/associations/builder/has_many.rb +8 -64
  19. data/lib/active_record/associations/builder/has_one.rb +12 -51
  20. data/lib/active_record/associations/builder/singular_association.rb +23 -17
  21. data/lib/active_record/associations/collection_association.rb +251 -177
  22. data/lib/active_record/associations/collection_proxy.rb +963 -63
  23. data/lib/active_record/associations/foreign_association.rb +11 -0
  24. data/lib/active_record/associations/has_many_association.rb +113 -22
  25. data/lib/active_record/associations/has_many_through_association.rb +99 -39
  26. data/lib/active_record/associations/has_one_association.rb +43 -20
  27. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  28. data/lib/active_record/associations/join_dependency/join_association.rb +76 -107
  29. data/lib/active_record/associations/join_dependency/join_base.rb +7 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +30 -37
  31. data/lib/active_record/associations/join_dependency.rb +230 -156
  32. data/lib/active_record/associations/preloader/association.rb +96 -55
  33. data/lib/active_record/associations/preloader/collection_association.rb +3 -3
  34. data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
  35. data/lib/active_record/associations/preloader/has_one.rb +1 -1
  36. data/lib/active_record/associations/preloader/singular_association.rb +3 -3
  37. data/lib/active_record/associations/preloader/through_association.rb +62 -33
  38. data/lib/active_record/associations/preloader.rb +101 -79
  39. data/lib/active_record/associations/singular_association.rb +29 -13
  40. data/lib/active_record/associations/through_association.rb +30 -16
  41. data/lib/active_record/associations.rb +463 -345
  42. data/lib/active_record/attribute.rb +163 -0
  43. data/lib/active_record/attribute_assignment.rb +142 -151
  44. data/lib/active_record/attribute_decorators.rb +66 -0
  45. data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
  46. data/lib/active_record/attribute_methods/dirty.rb +137 -57
  47. data/lib/active_record/attribute_methods/primary_key.rb +50 -36
  48. data/lib/active_record/attribute_methods/query.rb +5 -4
  49. data/lib/active_record/attribute_methods/read.rb +73 -106
  50. data/lib/active_record/attribute_methods/serialization.rb +44 -94
  51. data/lib/active_record/attribute_methods/time_zone_conversion.rb +49 -45
  52. data/lib/active_record/attribute_methods/write.rb +57 -44
  53. data/lib/active_record/attribute_methods.rb +301 -141
  54. data/lib/active_record/attribute_set/builder.rb +106 -0
  55. data/lib/active_record/attribute_set.rb +81 -0
  56. data/lib/active_record/attributes.rb +147 -0
  57. data/lib/active_record/autosave_association.rb +246 -217
  58. data/lib/active_record/base.rb +70 -474
  59. data/lib/active_record/callbacks.rb +66 -28
  60. data/lib/active_record/coders/json.rb +13 -0
  61. data/lib/active_record/coders/yaml_column.rb +18 -21
  62. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +396 -219
  63. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  64. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -164
  65. data/lib/active_record/connection_adapters/abstract/query_cache.rb +29 -24
  66. data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -55
  67. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  68. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +125 -0
  69. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +261 -169
  70. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +50 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +707 -259
  72. data/lib/active_record/connection_adapters/abstract/transaction.rb +215 -0
  73. data/lib/active_record/connection_adapters/abstract_adapter.rb +298 -89
  74. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +466 -196
  75. data/lib/active_record/connection_adapters/column.rb +31 -245
  76. data/lib/active_record/connection_adapters/connection_specification.rb +275 -0
  77. data/lib/active_record/connection_adapters/mysql2_adapter.rb +45 -57
  78. data/lib/active_record/connection_adapters/mysql_adapter.rb +180 -123
  79. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +93 -0
  80. data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
  81. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +232 -0
  82. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +100 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +19 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +36 -0
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +108 -0
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +596 -0
  112. data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
  113. data/lib/active_record/connection_adapters/postgresql_adapter.rb +430 -999
  114. data/lib/active_record/connection_adapters/schema_cache.rb +52 -27
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +579 -22
  116. data/lib/active_record/connection_handling.rb +132 -0
  117. data/lib/active_record/core.rb +579 -0
  118. data/lib/active_record/counter_cache.rb +157 -105
  119. data/lib/active_record/dynamic_matchers.rb +119 -63
  120. data/lib/active_record/enum.rb +197 -0
  121. data/lib/active_record/errors.rb +94 -36
  122. data/lib/active_record/explain.rb +15 -63
  123. data/lib/active_record/explain_registry.rb +30 -0
  124. data/lib/active_record/explain_subscriber.rb +9 -5
  125. data/lib/active_record/fixture_set/file.rb +56 -0
  126. data/lib/active_record/fixtures.rb +302 -215
  127. data/lib/active_record/gem_version.rb +15 -0
  128. data/lib/active_record/inheritance.rb +143 -70
  129. data/lib/active_record/integration.rb +65 -12
  130. data/lib/active_record/legacy_yaml_adapter.rb +30 -0
  131. data/lib/active_record/locale/en.yml +8 -1
  132. data/lib/active_record/locking/optimistic.rb +73 -52
  133. data/lib/active_record/locking/pessimistic.rb +5 -5
  134. data/lib/active_record/log_subscriber.rb +24 -21
  135. data/lib/active_record/migration/command_recorder.rb +124 -32
  136. data/lib/active_record/migration/join_table.rb +15 -0
  137. data/lib/active_record/migration.rb +511 -213
  138. data/lib/active_record/model_schema.rb +91 -117
  139. data/lib/active_record/nested_attributes.rb +184 -130
  140. data/lib/active_record/no_touching.rb +52 -0
  141. data/lib/active_record/null_relation.rb +81 -0
  142. data/lib/active_record/persistence.rb +276 -117
  143. data/lib/active_record/query_cache.rb +19 -37
  144. data/lib/active_record/querying.rb +28 -18
  145. data/lib/active_record/railtie.rb +73 -40
  146. data/lib/active_record/railties/console_sandbox.rb +3 -4
  147. data/lib/active_record/railties/controller_runtime.rb +4 -3
  148. data/lib/active_record/railties/databases.rake +141 -416
  149. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  150. data/lib/active_record/readonly_attributes.rb +1 -4
  151. data/lib/active_record/reflection.rb +513 -154
  152. data/lib/active_record/relation/batches.rb +91 -43
  153. data/lib/active_record/relation/calculations.rb +199 -161
  154. data/lib/active_record/relation/delegation.rb +116 -25
  155. data/lib/active_record/relation/finder_methods.rb +362 -248
  156. data/lib/active_record/relation/merger.rb +193 -0
  157. data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
  158. data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
  159. data/lib/active_record/relation/predicate_builder.rb +135 -43
  160. data/lib/active_record/relation/query_methods.rb +928 -167
  161. data/lib/active_record/relation/spawn_methods.rb +48 -149
  162. data/lib/active_record/relation.rb +352 -207
  163. data/lib/active_record/result.rb +101 -10
  164. data/lib/active_record/runtime_registry.rb +22 -0
  165. data/lib/active_record/sanitization.rb +56 -59
  166. data/lib/active_record/schema.rb +19 -13
  167. data/lib/active_record/schema_dumper.rb +106 -63
  168. data/lib/active_record/schema_migration.rb +53 -0
  169. data/lib/active_record/scoping/default.rb +50 -57
  170. data/lib/active_record/scoping/named.rb +73 -109
  171. data/lib/active_record/scoping.rb +58 -123
  172. data/lib/active_record/serialization.rb +6 -2
  173. data/lib/active_record/serializers/xml_serializer.rb +12 -22
  174. data/lib/active_record/statement_cache.rb +111 -0
  175. data/lib/active_record/store.rb +168 -15
  176. data/lib/active_record/tasks/database_tasks.rb +299 -0
  177. data/lib/active_record/tasks/mysql_database_tasks.rb +159 -0
  178. data/lib/active_record/tasks/postgresql_database_tasks.rb +101 -0
  179. data/lib/active_record/tasks/sqlite_database_tasks.rb +55 -0
  180. data/lib/active_record/timestamp.rb +23 -16
  181. data/lib/active_record/transactions.rb +125 -79
  182. data/lib/active_record/type/big_integer.rb +13 -0
  183. data/lib/active_record/type/binary.rb +50 -0
  184. data/lib/active_record/type/boolean.rb +31 -0
  185. data/lib/active_record/type/date.rb +50 -0
  186. data/lib/active_record/type/date_time.rb +54 -0
  187. data/lib/active_record/type/decimal.rb +64 -0
  188. data/lib/active_record/type/decimal_without_scale.rb +11 -0
  189. data/lib/active_record/type/decorator.rb +14 -0
  190. data/lib/active_record/type/float.rb +19 -0
  191. data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
  192. data/lib/active_record/type/integer.rb +59 -0
  193. data/lib/active_record/type/mutable.rb +16 -0
  194. data/lib/active_record/type/numeric.rb +36 -0
  195. data/lib/active_record/type/serialized.rb +62 -0
  196. data/lib/active_record/type/string.rb +40 -0
  197. data/lib/active_record/type/text.rb +11 -0
  198. data/lib/active_record/type/time.rb +26 -0
  199. data/lib/active_record/type/time_value.rb +38 -0
  200. data/lib/active_record/type/type_map.rb +64 -0
  201. data/lib/active_record/type/unsigned_integer.rb +15 -0
  202. data/lib/active_record/type/value.rb +110 -0
  203. data/lib/active_record/type.rb +23 -0
  204. data/lib/active_record/validations/associated.rb +24 -16
  205. data/lib/active_record/validations/presence.rb +67 -0
  206. data/lib/active_record/validations/uniqueness.rb +123 -64
  207. data/lib/active_record/validations.rb +36 -29
  208. data/lib/active_record/version.rb +5 -7
  209. data/lib/active_record.rb +66 -46
  210. data/lib/rails/generators/active_record/migration/migration_generator.rb +53 -8
  211. data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +5 -1
  212. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  213. data/lib/rails/generators/active_record/migration.rb +11 -8
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -4
  215. data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
  216. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  217. data/lib/rails/generators/active_record.rb +3 -11
  218. metadata +101 -45
  219. data/examples/associations.png +0 -0
  220. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  221. data/lib/active_record/associations/join_helper.rb +0 -55
  222. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  223. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  224. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  225. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  226. data/lib/active_record/dynamic_finder_match.rb +0 -68
  227. data/lib/active_record/dynamic_scope_match.rb +0 -23
  228. data/lib/active_record/fixtures/file.rb +0 -65
  229. data/lib/active_record/identity_map.rb +0 -162
  230. data/lib/active_record/observer.rb +0 -121
  231. data/lib/active_record/session_store.rb +0 -360
  232. data/lib/active_record/test_case.rb +0 -73
  233. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  234. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  235. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  236. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,34 +1,53 @@
1
1
  require 'date'
2
2
  require 'bigdecimal'
3
3
  require 'bigdecimal/util'
4
+ require 'active_record/type'
4
5
  require 'active_support/core_ext/benchmark'
5
- require 'active_support/deprecation'
6
6
  require 'active_record/connection_adapters/schema_cache'
7
+ require 'active_record/connection_adapters/abstract/schema_dumper'
8
+ require 'active_record/connection_adapters/abstract/schema_creation'
7
9
  require 'monitor'
10
+ require 'arel/collectors/bind'
11
+ require 'arel/collectors/sql_string'
8
12
 
9
13
  module ActiveRecord
10
14
  module ConnectionAdapters # :nodoc:
11
15
  extend ActiveSupport::Autoload
12
16
 
13
17
  autoload :Column
18
+ autoload :ConnectionSpecification
19
+
20
+ autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do
21
+ autoload :IndexDefinition
22
+ autoload :ColumnDefinition
23
+ autoload :ChangeColumnDefinition
24
+ autoload :TableDefinition
25
+ autoload :Table
26
+ autoload :AlterTable
27
+ autoload :TimestampDefaultDeprecation
28
+ end
14
29
 
15
- autoload_under 'abstract' do
16
- autoload :IndexDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
17
- autoload :ColumnDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
18
- autoload :TableDefinition, 'active_record/connection_adapters/abstract/schema_definitions'
19
- autoload :Table, 'active_record/connection_adapters/abstract/schema_definitions'
30
+ autoload_at 'active_record/connection_adapters/abstract/connection_pool' do
31
+ autoload :ConnectionHandler
32
+ autoload :ConnectionManagement
33
+ end
20
34
 
35
+ autoload_under 'abstract' do
21
36
  autoload :SchemaStatements
22
37
  autoload :DatabaseStatements
23
38
  autoload :DatabaseLimits
24
39
  autoload :Quoting
25
-
26
40
  autoload :ConnectionPool
27
- autoload :ConnectionHandler, 'active_record/connection_adapters/abstract/connection_pool'
28
- autoload :ConnectionManagement, 'active_record/connection_adapters/abstract/connection_pool'
29
- autoload :ConnectionSpecification
30
-
31
41
  autoload :QueryCache
42
+ autoload :Savepoints
43
+ end
44
+
45
+ autoload_at 'active_record/connection_adapters/abstract/transaction' do
46
+ autoload :TransactionManager
47
+ autoload :NullTransaction
48
+ autoload :RealTransaction
49
+ autoload :SavepointTransaction
50
+ autoload :TransactionState
32
51
  end
33
52
 
34
53
  # Active Record supports multiple database systems. AbstractAdapter and
@@ -45,76 +64,136 @@ module ActiveRecord
45
64
  # Most of the methods in the adapter are useful during migrations. Most
46
65
  # notably, the instance methods provided by SchemaStatement are very useful.
47
66
  class AbstractAdapter
67
+ ADAPTER_NAME = 'Abstract'.freeze
48
68
  include Quoting, DatabaseStatements, SchemaStatements
49
69
  include DatabaseLimits
50
70
  include QueryCache
51
71
  include ActiveSupport::Callbacks
52
72
  include MonitorMixin
73
+ include ColumnDumper
74
+
75
+ SIMPLE_INT = /\A\d+\z/
53
76
 
54
77
  define_callbacks :checkout, :checkin
55
78
 
56
79
  attr_accessor :visitor, :pool
57
- attr_reader :schema_cache, :last_use, :in_use, :logger
58
- alias :in_use? :in_use
80
+ attr_reader :schema_cache, :owner, :logger
81
+ alias :in_use? :owner
82
+
83
+ def self.type_cast_config_to_integer(config)
84
+ if config =~ SIMPLE_INT
85
+ config.to_i
86
+ else
87
+ config
88
+ end
89
+ end
90
+
91
+ def self.type_cast_config_to_boolean(config)
92
+ if config == "false"
93
+ false
94
+ else
95
+ config
96
+ end
97
+ end
98
+
99
+ attr_reader :prepared_statements
59
100
 
60
101
  def initialize(connection, logger = nil, pool = nil) #:nodoc:
61
102
  super()
62
103
 
63
- @active = nil
64
104
  @connection = connection
65
- @in_use = false
105
+ @owner = nil
66
106
  @instrumenter = ActiveSupport::Notifications.instrumenter
67
- @last_use = false
68
107
  @logger = logger
69
- @open_transactions = 0
70
108
  @pool = pool
71
- @query_cache = Hash.new { |h,sql| h[sql] = {} }
72
- @query_cache_enabled = false
73
109
  @schema_cache = SchemaCache.new self
74
110
  @visitor = nil
111
+ @prepared_statements = false
112
+ end
113
+
114
+ class Version
115
+ include Comparable
116
+
117
+ def initialize(version_string)
118
+ @version = version_string.split('.').map(&:to_i)
119
+ end
120
+
121
+ def <=>(version_string)
122
+ @version <=> version_string.split('.').map(&:to_i)
123
+ end
124
+ end
125
+
126
+ class BindCollector < Arel::Collectors::Bind
127
+ def compile(bvs, conn)
128
+ super(bvs.map { |bv| conn.quote(*bv.reverse) })
129
+ end
130
+ end
131
+
132
+ class SQLString < Arel::Collectors::SQLString
133
+ def compile(bvs, conn)
134
+ super(bvs)
135
+ end
136
+ end
137
+
138
+ def collector
139
+ if prepared_statements
140
+ SQLString.new
141
+ else
142
+ BindCollector.new
143
+ end
144
+ end
145
+
146
+ def valid_type?(type)
147
+ true
148
+ end
149
+
150
+ def schema_creation
151
+ SchemaCreation.new self
75
152
  end
76
153
 
77
154
  def lease
78
155
  synchronize do
79
- unless in_use
80
- @in_use = true
81
- @last_use = Time.now
156
+ unless in_use?
157
+ @owner = Thread.current
82
158
  end
83
159
  end
84
160
  end
85
161
 
162
+ def schema_cache=(cache)
163
+ cache.connection = self
164
+ @schema_cache = cache
165
+ end
166
+
86
167
  def expire
87
- @in_use = false
168
+ @owner = nil
169
+ end
170
+
171
+ def unprepared_statement
172
+ old_prepared_statements, @prepared_statements = @prepared_statements, false
173
+ yield
174
+ ensure
175
+ @prepared_statements = old_prepared_statements
88
176
  end
89
177
 
90
178
  # Returns the human-readable name of the adapter. Use mixed case - one
91
179
  # can always use downcase if needed.
92
180
  def adapter_name
93
- 'Abstract'
181
+ self.class::ADAPTER_NAME
94
182
  end
95
183
 
96
- # Does this adapter support migrations? Backend specific, as the
97
- # abstract adapter always returns +false+.
184
+ # Does this adapter support migrations?
98
185
  def supports_migrations?
99
186
  false
100
187
  end
101
188
 
102
189
  # Can this adapter determine the primary key for tables not attached
103
- # to an Active Record class, such as join tables? Backend specific, as
104
- # the abstract adapter always returns +false+.
190
+ # to an Active Record class, such as join tables?
105
191
  def supports_primary_key?
106
192
  false
107
193
  end
108
194
 
109
- # Does this adapter support using DISTINCT within COUNT? This is +true+
110
- # for all adapters except sqlite.
111
- def supports_count_distinct?
112
- true
113
- end
114
-
115
195
  # Does this adapter support DDL rollbacks in transactions? That is, would
116
- # CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL,
117
- # SQL Server, and others support this. MySQL and others do not.
196
+ # CREATE TABLE or ALTER TABLE get rolled back by a transaction?
118
197
  def supports_ddl_transactions?
119
198
  false
120
199
  end
@@ -123,8 +202,7 @@ module ActiveRecord
123
202
  false
124
203
  end
125
204
 
126
- # Does this adapter support savepoints? PostgreSQL and MySQL do,
127
- # SQLite < 3.6.8 does not.
205
+ # Does this adapter support savepoints?
128
206
  def supports_savepoints?
129
207
  false
130
208
  end
@@ -132,7 +210,6 @@ module ActiveRecord
132
210
  # Should primary key values be selected from their corresponding
133
211
  # sequence before the insert statement? If true, next_sequence_value
134
212
  # is called before each insert to set the record's primary key.
135
- # This is false for all adapters but Firebird.
136
213
  def prefetch_primary_key?(table_name = nil)
137
214
  false
138
215
  end
@@ -142,23 +219,66 @@ module ActiveRecord
142
219
  false
143
220
  end
144
221
 
145
- # Does this adapter support explain? As of this writing sqlite3,
146
- # mysql2, and postgresql are the only ones that do.
222
+ # Does this adapter support partial indices?
223
+ def supports_partial_index?
224
+ false
225
+ end
226
+
227
+ # Does this adapter support explain?
147
228
  def supports_explain?
148
229
  false
149
230
  end
150
231
 
151
- # QUOTING ==================================================
232
+ # Does this adapter support setting the isolation level for a transaction?
233
+ def supports_transaction_isolation?
234
+ false
235
+ end
152
236
 
153
- # Override to return the quoted table name. Defaults to column quoting.
154
- def quote_table_name(name)
155
- quote_column_name(name)
237
+ # Does this adapter support database extensions?
238
+ def supports_extensions?
239
+ false
156
240
  end
157
241
 
158
- # Returns a bind substitution value given a +column+ and list of current
159
- # +binds+
160
- def substitute_at(column, index)
161
- Arel::Nodes::BindParam.new '?'
242
+ # Does this adapter support creating indexes in the same statement as
243
+ # creating the table?
244
+ def supports_indexes_in_create?
245
+ false
246
+ end
247
+
248
+ # Does this adapter support creating foreign key constraints?
249
+ def supports_foreign_keys?
250
+ false
251
+ end
252
+
253
+ # Does this adapter support views?
254
+ def supports_views?
255
+ false
256
+ end
257
+
258
+ # This is meant to be implemented by the adapters that support extensions
259
+ def disable_extension(name)
260
+ end
261
+
262
+ # This is meant to be implemented by the adapters that support extensions
263
+ def enable_extension(name)
264
+ end
265
+
266
+ # A list of extensions, to be filled in by adapters that support them.
267
+ def extensions
268
+ []
269
+ end
270
+
271
+ # A list of index algorithms, to be filled by adapters that support them.
272
+ def index_algorithms
273
+ {}
274
+ end
275
+
276
+ # QUOTING ==================================================
277
+
278
+ # Returns a bind substitution value given a bind +column+
279
+ # NOTE: The column param is currently being used by the sqlserver-adapter
280
+ def substitute_at(column, _unused = 0)
281
+ Arel::Nodes::BindParam.new
162
282
  end
163
283
 
164
284
  # REFERENTIAL INTEGRITY ====================================
@@ -174,19 +294,21 @@ module ActiveRecord
174
294
  # checking whether the database is actually capable of responding, i.e. whether
175
295
  # the connection isn't stale.
176
296
  def active?
177
- @active != false
178
297
  end
179
298
 
180
299
  # Disconnects from the database if already connected, and establishes a
181
- # new connection with the database.
300
+ # new connection with the database. Implementors should call super if they
301
+ # override the default implementation.
182
302
  def reconnect!
183
- @active = true
303
+ clear_cache!
304
+ reset_transaction
184
305
  end
185
306
 
186
307
  # Disconnects from the database if already connected. Otherwise, this
187
308
  # method does nothing.
188
309
  def disconnect!
189
- @active = false
310
+ clear_cache!
311
+ reset_transaction
190
312
  end
191
313
 
192
314
  # Reset the state of this connection, directing the DBMS to clear
@@ -207,7 +329,6 @@ module ActiveRecord
207
329
  end
208
330
 
209
331
  # Returns true if its required to reload the connection between requests for development mode.
210
- # This is not the case for Ruby/MySQL and it's not necessary for any adapters except SQLite.
211
332
  def requires_reloading?
212
333
  false
213
334
  end
@@ -229,68 +350,156 @@ module ActiveRecord
229
350
  @connection
230
351
  end
231
352
 
232
- attr_reader :open_transactions
353
+ def create_savepoint(name = nil)
354
+ end
233
355
 
234
- def increment_open_transactions
235
- @open_transactions += 1
356
+ def release_savepoint(name = nil)
236
357
  end
237
358
 
238
- def decrement_open_transactions
239
- @open_transactions -= 1
359
+ def case_sensitive_modifier(node, table_attribute)
360
+ node
240
361
  end
241
362
 
242
- def transaction_joinable=(joinable)
243
- @transaction_joinable = joinable
363
+ def case_sensitive_comparison(table, attribute, column, value)
364
+ table_attr = table[attribute]
365
+ value = case_sensitive_modifier(value, table_attr) unless value.nil?
366
+ table_attr.eq(value)
244
367
  end
245
368
 
246
- def create_savepoint
369
+ def case_insensitive_comparison(table, attribute, column, value)
370
+ table[attribute].lower.eq(table.lower(value))
247
371
  end
248
372
 
249
- def rollback_to_savepoint
373
+ def current_savepoint_name
374
+ current_transaction.savepoint_name
250
375
  end
251
376
 
252
- def release_savepoint
377
+ # Check the connection back in to the connection pool
378
+ def close
379
+ pool.checkin self
253
380
  end
254
381
 
255
- def case_sensitive_modifier(node)
256
- node
382
+ def type_map # :nodoc:
383
+ @type_map ||= Type::TypeMap.new.tap do |mapping|
384
+ initialize_type_map(mapping)
385
+ end
257
386
  end
258
387
 
259
- def case_insensitive_comparison(table, attribute, column, value)
260
- table[attribute].lower.eq(table.lower(value))
388
+ def new_column(name, default, cast_type, sql_type = nil, null = true)
389
+ Column.new(name, default, cast_type, sql_type, null)
261
390
  end
262
391
 
263
- def current_savepoint_name
264
- "active_record_#{open_transactions}"
392
+ def lookup_cast_type(sql_type) # :nodoc:
393
+ type_map.lookup(sql_type)
265
394
  end
266
395
 
267
- # Check the connection back in to the connection pool
268
- def close
269
- pool.checkin self
396
+ def column_name_for_operation(operation, node) # :nodoc:
397
+ visitor.accept(node, collector).value
270
398
  end
271
399
 
272
400
  protected
273
401
 
274
- def log(sql, name = "SQL", binds = [])
275
- @instrumenter.instrument(
276
- "sql.active_record",
277
- :sql => sql,
278
- :name => name,
279
- :connection_id => object_id,
280
- :binds => binds) { yield }
281
- rescue Exception => e
282
- message = "#{e.class.name}: #{e.message}: #{sql}"
283
- @logger.debug message if @logger
284
- exception = translate_exception(e, message)
285
- exception.set_backtrace e.backtrace
286
- raise exception
402
+ def initialize_type_map(m) # :nodoc:
403
+ register_class_with_limit m, %r(boolean)i, Type::Boolean
404
+ register_class_with_limit m, %r(char)i, Type::String
405
+ register_class_with_limit m, %r(binary)i, Type::Binary
406
+ register_class_with_limit m, %r(text)i, Type::Text
407
+ register_class_with_limit m, %r(date)i, Type::Date
408
+ register_class_with_limit m, %r(time)i, Type::Time
409
+ register_class_with_limit m, %r(datetime)i, Type::DateTime
410
+ register_class_with_limit m, %r(float)i, Type::Float
411
+ register_class_with_limit m, %r(int)i, Type::Integer
412
+
413
+ m.alias_type %r(blob)i, 'binary'
414
+ m.alias_type %r(clob)i, 'text'
415
+ m.alias_type %r(timestamp)i, 'datetime'
416
+ m.alias_type %r(numeric)i, 'decimal'
417
+ m.alias_type %r(number)i, 'decimal'
418
+ m.alias_type %r(double)i, 'float'
419
+
420
+ m.register_type(%r(decimal)i) do |sql_type|
421
+ scale = extract_scale(sql_type)
422
+ precision = extract_precision(sql_type)
423
+
424
+ if scale == 0
425
+ # FIXME: Remove this class as well
426
+ Type::DecimalWithoutScale.new(precision: precision)
427
+ else
428
+ Type::Decimal.new(precision: precision, scale: scale)
429
+ end
430
+ end
431
+ end
432
+
433
+ def reload_type_map # :nodoc:
434
+ type_map.clear
435
+ initialize_type_map(type_map)
436
+ end
437
+
438
+ def register_class_with_limit(mapping, key, klass) # :nodoc:
439
+ mapping.register_type(key) do |*args|
440
+ limit = extract_limit(args.last)
441
+ klass.new(limit: limit)
287
442
  end
443
+ end
288
444
 
289
- def translate_exception(e, message)
290
- # override in derived class
291
- ActiveRecord::StatementInvalid.new(message)
445
+ def extract_scale(sql_type) # :nodoc:
446
+ case sql_type
447
+ when /\((\d+)\)/ then 0
448
+ when /\((\d+)(,(\d+))\)/ then $3.to_i
292
449
  end
450
+ end
293
451
 
452
+ def extract_precision(sql_type) # :nodoc:
453
+ $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
454
+ end
455
+
456
+ def extract_limit(sql_type) # :nodoc:
457
+ case sql_type
458
+ when /^bigint/i
459
+ 8
460
+ when /\((.*)\)/
461
+ $1.to_i
462
+ end
463
+ end
464
+
465
+ def translate_exception_class(e, sql)
466
+ begin
467
+ message = "#{e.class.name}: #{e.message}: #{sql}"
468
+ rescue Encoding::CompatibilityError
469
+ message = "#{e.class.name}: #{e.message.force_encoding sql.encoding}: #{sql}"
470
+ end
471
+
472
+ exception = translate_exception(e, message)
473
+ exception.set_backtrace e.backtrace
474
+ exception
475
+ end
476
+
477
+ def log(sql, name = "SQL", binds = [], statement_name = nil)
478
+ @instrumenter.instrument(
479
+ "sql.active_record",
480
+ :sql => sql,
481
+ :name => name,
482
+ :connection_id => object_id,
483
+ :statement_name => statement_name,
484
+ :binds => binds) { yield }
485
+ rescue => e
486
+ raise translate_exception_class(e, sql)
487
+ end
488
+
489
+ def translate_exception(exception, message)
490
+ # override in derived class
491
+ ActiveRecord::StatementInvalid.new(message, exception)
492
+ end
493
+
494
+ def without_prepared_statement?(binds)
495
+ !prepared_statements || binds.empty?
496
+ end
497
+
498
+ def column_for(table_name, column_name) # :nodoc:
499
+ column_name = column_name.to_s
500
+ columns(table_name).detect { |c| c.name == column_name } ||
501
+ raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
502
+ end
294
503
  end
295
504
  end
296
505
  end