activerecord 4.1.8 → 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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1165 -1591
- data/README.rdoc +15 -10
- data/lib/active_record/aggregations.rb +15 -8
- data/lib/active_record/association_relation.rb +13 -0
- data/lib/active_record/associations/alias_tracker.rb +3 -12
- data/lib/active_record/associations/association.rb +16 -4
- data/lib/active_record/associations/association_scope.rb +84 -43
- data/lib/active_record/associations/belongs_to_association.rb +28 -10
- data/lib/active_record/associations/builder/association.rb +16 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -29
- data/lib/active_record/associations/builder/collection_association.rb +5 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +9 -14
- data/lib/active_record/associations/builder/has_many.rb +1 -1
- data/lib/active_record/associations/builder/has_one.rb +2 -2
- data/lib/active_record/associations/builder/singular_association.rb +8 -1
- data/lib/active_record/associations/collection_association.rb +87 -30
- data/lib/active_record/associations/collection_proxy.rb +33 -35
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +83 -22
- data/lib/active_record/associations/has_many_through_association.rb +49 -26
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +25 -15
- data/lib/active_record/associations/join_dependency/join_part.rb +0 -1
- data/lib/active_record/associations/join_dependency.rb +26 -12
- data/lib/active_record/associations/preloader/association.rb +14 -10
- data/lib/active_record/associations/preloader/through_association.rb +4 -3
- data/lib/active_record/associations/preloader.rb +37 -26
- data/lib/active_record/associations/singular_association.rb +17 -2
- data/lib/active_record/associations/through_association.rb +16 -12
- data/lib/active_record/associations.rb +158 -49
- data/lib/active_record/attribute.rb +163 -0
- data/lib/active_record/attribute_assignment.rb +20 -12
- data/lib/active_record/attribute_decorators.rb +66 -0
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +107 -43
- data/lib/active_record/attribute_methods/primary_key.rb +7 -8
- data/lib/active_record/attribute_methods/query.rb +1 -1
- data/lib/active_record/attribute_methods/read.rb +22 -59
- data/lib/active_record/attribute_methods/serialization.rb +16 -150
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -28
- data/lib/active_record/attribute_methods/write.rb +9 -24
- data/lib/active_record/attribute_methods.rb +57 -95
- data/lib/active_record/attribute_set/builder.rb +106 -0
- data/lib/active_record/attribute_set.rb +81 -0
- data/lib/active_record/attributes.rb +147 -0
- data/lib/active_record/autosave_association.rb +30 -12
- data/lib/active_record/base.rb +13 -24
- data/lib/active_record/callbacks.rb +6 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +85 -53
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +52 -50
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +60 -60
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +39 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +139 -57
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -34
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +271 -74
- data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -118
- data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -60
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +295 -141
- data/lib/active_record/connection_adapters/column.rb +29 -240
- data/lib/active_record/connection_adapters/connection_specification.rb +15 -24
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +17 -33
- data/lib/active_record/connection_adapters/mysql_adapter.rb +68 -145
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +15 -27
- data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -25
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +100 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +19 -0
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +29 -385
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +46 -136
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +134 -43
- data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -477
- data/lib/active_record/connection_adapters/schema_cache.rb +14 -28
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -75
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +163 -40
- data/lib/active_record/counter_cache.rb +60 -6
- data/lib/active_record/enum.rb +10 -12
- data/lib/active_record/errors.rb +53 -30
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixtures.rb +62 -74
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +35 -10
- data/lib/active_record/integration.rb +4 -4
- data/lib/active_record/legacy_yaml_adapter.rb +30 -0
- data/lib/active_record/locking/optimistic.rb +46 -26
- data/lib/active_record/migration/command_recorder.rb +19 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +79 -47
- data/lib/active_record/model_schema.rb +52 -58
- data/lib/active_record/nested_attributes.rb +18 -8
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +48 -27
- data/lib/active_record/query_cache.rb +3 -3
- data/lib/active_record/querying.rb +10 -7
- data/lib/active_record/railtie.rb +19 -14
- data/lib/active_record/railties/databases.rake +55 -56
- data/lib/active_record/readonly_attributes.rb +0 -1
- data/lib/active_record/reflection.rb +281 -117
- data/lib/active_record/relation/batches.rb +0 -1
- data/lib/active_record/relation/calculations.rb +41 -37
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +71 -48
- data/lib/active_record/relation/merger.rb +39 -29
- data/lib/active_record/relation/predicate_builder/array_handler.rb +32 -13
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +42 -12
- data/lib/active_record/relation/query_methods.rb +130 -73
- data/lib/active_record/relation/spawn_methods.rb +10 -3
- data/lib/active_record/relation.rb +57 -25
- data/lib/active_record/result.rb +18 -7
- data/lib/active_record/sanitization.rb +12 -2
- data/lib/active_record/schema.rb +0 -1
- data/lib/active_record/schema_dumper.rb +59 -28
- data/lib/active_record/schema_migration.rb +5 -4
- data/lib/active_record/scoping/default.rb +6 -4
- data/lib/active_record/scoping/named.rb +4 -0
- data/lib/active_record/serializers/xml_serializer.rb +3 -7
- data/lib/active_record/statement_cache.rb +95 -10
- data/lib/active_record/store.rb +5 -5
- data/lib/active_record/tasks/database_tasks.rb +61 -8
- data/lib/active_record/tasks/mysql_database_tasks.rb +32 -17
- data/lib/active_record/tasks/postgresql_database_tasks.rb +20 -9
- data/lib/active_record/timestamp.rb +9 -7
- data/lib/active_record/transactions.rb +54 -28
- data/lib/active_record/type/big_integer.rb +13 -0
- data/lib/active_record/type/binary.rb +50 -0
- data/lib/active_record/type/boolean.rb +31 -0
- data/lib/active_record/type/date.rb +50 -0
- data/lib/active_record/type/date_time.rb +54 -0
- data/lib/active_record/type/decimal.rb +64 -0
- data/lib/active_record/type/decimal_without_scale.rb +11 -0
- data/lib/active_record/type/decorator.rb +14 -0
- data/lib/active_record/type/float.rb +19 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
- data/lib/active_record/type/integer.rb +59 -0
- data/lib/active_record/type/mutable.rb +16 -0
- data/lib/active_record/type/numeric.rb +36 -0
- data/lib/active_record/type/serialized.rb +62 -0
- data/lib/active_record/type/string.rb +40 -0
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +26 -0
- data/lib/active_record/type/time_value.rb +38 -0
- data/lib/active_record/type/type_map.rb +64 -0
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type/value.rb +110 -0
- data/lib/active_record/type.rb +23 -0
- data/lib/active_record/validations/associated.rb +5 -3
- data/lib/active_record/validations/presence.rb +5 -3
- data/lib/active_record/validations/uniqueness.rb +24 -20
- data/lib/active_record/validations.rb +25 -19
- data/lib/active_record.rb +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -4
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb +1 -1
- metadata +66 -11
- data/lib/active_record/connection_adapters/postgresql/cast.rb +0 -168
@@ -1,20 +1,7 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionAdapters
|
3
|
-
class Transaction #:nodoc:
|
4
|
-
attr_reader :connection
|
5
|
-
|
6
|
-
def initialize(connection)
|
7
|
-
@connection = connection
|
8
|
-
@state = TransactionState.new
|
9
|
-
end
|
10
|
-
|
11
|
-
def state
|
12
|
-
@state
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
3
|
class TransactionState
|
17
|
-
|
4
|
+
attr_reader :parent
|
18
5
|
|
19
6
|
VALID_STATES = Set.new([:committed, :rolledback, nil])
|
20
7
|
|
@@ -35,6 +22,10 @@ module ActiveRecord
|
|
35
22
|
@state == :rolledback
|
36
23
|
end
|
37
24
|
|
25
|
+
def completed?
|
26
|
+
committed? || rolledback?
|
27
|
+
end
|
28
|
+
|
38
29
|
def set_state(state)
|
39
30
|
if !VALID_STATES.include?(state)
|
40
31
|
raise ArgumentError, "Invalid transaction state: #{state}"
|
@@ -43,127 +34,106 @@ module ActiveRecord
|
|
43
34
|
end
|
44
35
|
end
|
45
36
|
|
46
|
-
class
|
47
|
-
def
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
def
|
52
|
-
RealTransaction.new(connection, self, options)
|
53
|
-
end
|
54
|
-
|
55
|
-
def closed?
|
56
|
-
true
|
57
|
-
end
|
58
|
-
|
59
|
-
def open?
|
60
|
-
false
|
61
|
-
end
|
62
|
-
|
63
|
-
def joinable?
|
64
|
-
false
|
65
|
-
end
|
66
|
-
|
67
|
-
# This is a noop when there are no open transactions
|
68
|
-
def add_record(record)
|
69
|
-
end
|
37
|
+
class NullTransaction #:nodoc:
|
38
|
+
def initialize; end
|
39
|
+
def closed?; true; end
|
40
|
+
def open?; false; end
|
41
|
+
def joinable?; false; end
|
42
|
+
def add_record(record); end
|
70
43
|
end
|
71
44
|
|
72
|
-
class
|
73
|
-
attr_reader :parent, :records
|
74
|
-
attr_writer :joinable
|
75
|
-
|
76
|
-
def initialize(connection, parent, options = {})
|
77
|
-
super connection
|
78
|
-
|
79
|
-
@parent = parent
|
80
|
-
@records = []
|
81
|
-
@finishing = false
|
82
|
-
@joinable = options.fetch(:joinable, true)
|
83
|
-
end
|
84
|
-
|
85
|
-
# This state is necessary so that we correctly handle stuff that might
|
86
|
-
# happen in a commit/rollback. But it's kinda distasteful. Maybe we can
|
87
|
-
# find a better way to structure it in the future.
|
88
|
-
def finishing?
|
89
|
-
@finishing
|
90
|
-
end
|
45
|
+
class Transaction #:nodoc:
|
91
46
|
|
92
|
-
|
93
|
-
|
94
|
-
end
|
47
|
+
attr_reader :connection, :state, :records, :savepoint_name
|
48
|
+
attr_writer :joinable
|
95
49
|
|
96
|
-
def
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
50
|
+
def initialize(connection, options)
|
51
|
+
@connection = connection
|
52
|
+
@state = TransactionState.new
|
53
|
+
@records = []
|
54
|
+
@joinable = options.fetch(:joinable, true)
|
102
55
|
end
|
103
56
|
|
104
|
-
def
|
105
|
-
|
106
|
-
parent.begin
|
107
|
-
else
|
108
|
-
SavepointTransaction.new(connection, self, options)
|
109
|
-
end
|
57
|
+
def add_record(record)
|
58
|
+
records << record
|
110
59
|
end
|
111
60
|
|
112
61
|
def rollback
|
113
|
-
@
|
114
|
-
perform_rollback
|
115
|
-
parent
|
116
|
-
end
|
117
|
-
|
118
|
-
def commit
|
119
|
-
@finishing = true
|
120
|
-
perform_commit
|
121
|
-
parent
|
122
|
-
end
|
123
|
-
|
124
|
-
def add_record(record)
|
125
|
-
if record.has_transactional_callbacks?
|
126
|
-
records << record
|
127
|
-
else
|
128
|
-
record.set_transaction_state(@state)
|
129
|
-
end
|
62
|
+
@state.set_state(:rolledback)
|
130
63
|
end
|
131
64
|
|
132
65
|
def rollback_records
|
133
|
-
|
134
|
-
|
66
|
+
ite = records.uniq
|
67
|
+
while record = ite.shift
|
135
68
|
begin
|
136
|
-
record.rolledback!
|
69
|
+
record.rolledback! full_rollback?
|
137
70
|
rescue => e
|
71
|
+
raise if ActiveRecord::Base.raise_in_transactional_callbacks
|
138
72
|
record.logger.error(e) if record.respond_to?(:logger) && record.logger
|
139
73
|
end
|
140
74
|
end
|
75
|
+
ensure
|
76
|
+
ite.each do |i|
|
77
|
+
i.rolledback!(full_rollback?, false)
|
78
|
+
end
|
141
79
|
end
|
142
80
|
|
143
|
-
def
|
81
|
+
def commit
|
144
82
|
@state.set_state(:committed)
|
145
|
-
|
83
|
+
end
|
84
|
+
|
85
|
+
def commit_records
|
86
|
+
ite = records.uniq
|
87
|
+
while record = ite.shift
|
146
88
|
begin
|
147
89
|
record.committed!
|
148
90
|
rescue => e
|
91
|
+
raise if ActiveRecord::Base.raise_in_transactional_callbacks
|
149
92
|
record.logger.error(e) if record.respond_to?(:logger) && record.logger
|
150
93
|
end
|
151
94
|
end
|
95
|
+
ensure
|
96
|
+
ite.each do |i|
|
97
|
+
i.committed!(false)
|
98
|
+
end
|
152
99
|
end
|
153
100
|
|
154
|
-
def
|
155
|
-
|
101
|
+
def full_rollback?; true; end
|
102
|
+
def joinable?; @joinable; end
|
103
|
+
def closed?; false; end
|
104
|
+
def open?; !closed?; end
|
105
|
+
end
|
106
|
+
|
107
|
+
class SavepointTransaction < Transaction
|
108
|
+
|
109
|
+
def initialize(connection, savepoint_name, options)
|
110
|
+
super(connection, options)
|
111
|
+
if options[:isolation]
|
112
|
+
raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
|
113
|
+
end
|
114
|
+
connection.create_savepoint(@savepoint_name = savepoint_name)
|
156
115
|
end
|
157
116
|
|
158
|
-
def
|
159
|
-
|
117
|
+
def rollback
|
118
|
+
connection.rollback_to_savepoint(savepoint_name)
|
119
|
+
super
|
120
|
+
rollback_records
|
160
121
|
end
|
161
|
-
end
|
162
122
|
|
163
|
-
|
164
|
-
|
123
|
+
def commit
|
124
|
+
connection.release_savepoint(savepoint_name)
|
165
125
|
super
|
126
|
+
parent = connection.transaction_manager.current_transaction
|
127
|
+
records.each { |r| parent.add_record(r) }
|
128
|
+
end
|
129
|
+
|
130
|
+
def full_rollback?; false; end
|
131
|
+
end
|
166
132
|
|
133
|
+
class RealTransaction < Transaction
|
134
|
+
|
135
|
+
def initialize(connection, options)
|
136
|
+
super
|
167
137
|
if options[:isolation]
|
168
138
|
connection.begin_isolated_db_transaction(options[:isolation])
|
169
139
|
else
|
@@ -171,38 +141,75 @@ module ActiveRecord
|
|
171
141
|
end
|
172
142
|
end
|
173
143
|
|
174
|
-
def
|
144
|
+
def rollback
|
175
145
|
connection.rollback_db_transaction
|
146
|
+
super
|
176
147
|
rollback_records
|
177
148
|
end
|
178
149
|
|
179
|
-
def
|
150
|
+
def commit
|
180
151
|
connection.commit_db_transaction
|
152
|
+
super
|
181
153
|
commit_records
|
182
154
|
end
|
183
155
|
end
|
184
156
|
|
185
|
-
class
|
186
|
-
def initialize(connection
|
187
|
-
|
188
|
-
|
189
|
-
|
157
|
+
class TransactionManager #:nodoc:
|
158
|
+
def initialize(connection)
|
159
|
+
@stack = []
|
160
|
+
@connection = connection
|
161
|
+
end
|
190
162
|
|
191
|
-
|
192
|
-
|
163
|
+
def begin_transaction(options = {})
|
164
|
+
transaction =
|
165
|
+
if @stack.empty?
|
166
|
+
RealTransaction.new(@connection, options)
|
167
|
+
else
|
168
|
+
SavepointTransaction.new(@connection, "active_record_#{@stack.size}", options)
|
169
|
+
end
|
170
|
+
@stack.push(transaction)
|
171
|
+
transaction
|
172
|
+
end
|
173
|
+
|
174
|
+
def commit_transaction
|
175
|
+
@stack.pop.commit
|
176
|
+
end
|
177
|
+
|
178
|
+
def rollback_transaction
|
179
|
+
@stack.pop.rollback
|
180
|
+
end
|
181
|
+
|
182
|
+
def within_new_transaction(options = {})
|
183
|
+
transaction = begin_transaction options
|
184
|
+
yield
|
185
|
+
rescue Exception => error
|
186
|
+
rollback_transaction if transaction
|
187
|
+
raise
|
188
|
+
ensure
|
189
|
+
unless error
|
190
|
+
if Thread.current.status == 'aborting'
|
191
|
+
rollback_transaction if transaction
|
192
|
+
else
|
193
|
+
begin
|
194
|
+
commit_transaction
|
195
|
+
rescue Exception
|
196
|
+
transaction.rollback unless transaction.state.completed?
|
197
|
+
raise
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
193
201
|
end
|
194
202
|
|
195
|
-
def
|
196
|
-
|
197
|
-
rollback_records
|
203
|
+
def open_transactions
|
204
|
+
@stack.size
|
198
205
|
end
|
199
206
|
|
200
|
-
def
|
201
|
-
@
|
202
|
-
@state.parent = parent.state
|
203
|
-
connection.release_savepoint
|
204
|
-
records.each { |r| parent.add_record(r) }
|
207
|
+
def current_transaction
|
208
|
+
@stack.last || NULL_TRANSACTION
|
205
209
|
end
|
210
|
+
|
211
|
+
private
|
212
|
+
NULL_TRANSACTION = NullTransaction.new
|
206
213
|
end
|
207
214
|
end
|
208
215
|
end
|