activerecord 4.1.16 → 4.2.0.beta1
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 +4 -4
- data/CHANGELOG.md +634 -2185
- data/README.rdoc +15 -10
- data/lib/active_record.rb +2 -1
- data/lib/active_record/aggregations.rb +12 -8
- data/lib/active_record/associations.rb +58 -33
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/association_scope.rb +53 -21
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- 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/has_and_belongs_to_many.rb +2 -11
- 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 +32 -44
- data/lib/active_record/associations/collection_proxy.rb +1 -10
- data/lib/active_record/associations/has_many_association.rb +60 -14
- data/lib/active_record/associations/has_many_through_association.rb +34 -23
- data/lib/active_record/associations/has_one_association.rb +0 -1
- data/lib/active_record/associations/join_dependency.rb +7 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +18 -14
- data/lib/active_record/associations/preloader.rb +2 -2
- data/lib/active_record/associations/preloader/association.rb +9 -5
- data/lib/active_record/associations/preloader/through_association.rb +3 -3
- data/lib/active_record/associations/singular_association.rb +16 -1
- data/lib/active_record/associations/through_association.rb +6 -22
- data/lib/active_record/attribute.rb +131 -0
- data/lib/active_record/attribute_assignment.rb +19 -11
- data/lib/active_record/attribute_decorators.rb +66 -0
- data/lib/active_record/attribute_methods.rb +53 -90
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -2
- data/lib/active_record/attribute_methods/dirty.rb +85 -42
- data/lib/active_record/attribute_methods/primary_key.rb +6 -8
- data/lib/active_record/attribute_methods/read.rb +14 -57
- data/lib/active_record/attribute_methods/serialization.rb +12 -146
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +32 -40
- data/lib/active_record/attribute_methods/write.rb +8 -23
- data/lib/active_record/attribute_set.rb +77 -0
- data/lib/active_record/attribute_set/builder.rb +32 -0
- data/lib/active_record/attributes.rb +122 -0
- data/lib/active_record/autosave_association.rb +11 -21
- data/lib/active_record/base.rb +9 -19
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +69 -45
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -42
- data/lib/active_record/connection_adapters/abstract/quoting.rb +59 -60
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +37 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +102 -21
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +9 -33
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +178 -55
- data/lib/active_record/connection_adapters/abstract/transaction.rb +120 -115
- data/lib/active_record/connection_adapters/abstract_adapter.rb +143 -57
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +156 -107
- data/lib/active_record/connection_adapters/column.rb +13 -244
- data/lib/active_record/connection_adapters/connection_specification.rb +6 -20
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -15
- data/lib/active_record/connection_adapters/mysql_adapter.rb +55 -143
- 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 +39 -20
- data/lib/active_record/connection_adapters/postgresql/oid.rb +29 -388
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +96 -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 +14 -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 +27 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +17 -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 +76 -0
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -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 +85 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +26 -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/quoting.rb +42 -122
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +154 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +86 -34
- data/lib/active_record/connection_adapters/postgresql/utils.rb +66 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +188 -452
- data/lib/active_record/connection_adapters/schema_cache.rb +14 -28
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +54 -47
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +119 -22
- data/lib/active_record/counter_cache.rb +60 -6
- data/lib/active_record/enum.rb +9 -10
- data/lib/active_record/errors.rb +27 -26
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/fixtures.rb +52 -45
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +33 -8
- data/lib/active_record/integration.rb +4 -4
- data/lib/active_record/locking/optimistic.rb +34 -16
- data/lib/active_record/migration.rb +22 -32
- data/lib/active_record/migration/command_recorder.rb +19 -2
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/model_schema.rb +39 -48
- data/lib/active_record/nested_attributes.rb +8 -18
- data/lib/active_record/persistence.rb +39 -22
- data/lib/active_record/query_cache.rb +3 -3
- data/lib/active_record/querying.rb +1 -8
- data/lib/active_record/railtie.rb +17 -10
- data/lib/active_record/railties/databases.rake +47 -42
- data/lib/active_record/readonly_attributes.rb +0 -1
- data/lib/active_record/reflection.rb +225 -92
- data/lib/active_record/relation.rb +35 -11
- data/lib/active_record/relation/batches.rb +0 -2
- data/lib/active_record/relation/calculations.rb +28 -32
- data/lib/active_record/relation/delegation.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +42 -20
- data/lib/active_record/relation/merger.rb +0 -1
- data/lib/active_record/relation/predicate_builder.rb +1 -22
- data/lib/active_record/relation/predicate_builder/array_handler.rb +16 -11
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +0 -4
- data/lib/active_record/relation/query_methods.rb +98 -62
- data/lib/active_record/relation/spawn_methods.rb +6 -7
- data/lib/active_record/result.rb +16 -9
- data/lib/active_record/sanitization.rb +8 -1
- data/lib/active_record/schema.rb +0 -1
- data/lib/active_record/schema_dumper.rb +51 -9
- data/lib/active_record/schema_migration.rb +4 -0
- data/lib/active_record/scoping/default.rb +5 -4
- data/lib/active_record/serializers/xml_serializer.rb +3 -7
- data/lib/active_record/statement_cache.rb +79 -5
- data/lib/active_record/store.rb +5 -5
- data/lib/active_record/tasks/database_tasks.rb +37 -5
- data/lib/active_record/tasks/mysql_database_tasks.rb +10 -16
- data/lib/active_record/tasks/postgresql_database_tasks.rb +2 -2
- data/lib/active_record/timestamp.rb +9 -7
- data/lib/active_record/transactions.rb +35 -21
- data/lib/active_record/type.rb +20 -0
- data/lib/active_record/type/binary.rb +40 -0
- data/lib/active_record/type/boolean.rb +19 -0
- data/lib/active_record/type/date.rb +46 -0
- data/lib/active_record/type/date_time.rb +43 -0
- data/lib/active_record/type/decimal.rb +40 -0
- data/lib/active_record/type/decimal_without_scale.rb +11 -0
- data/lib/active_record/type/float.rb +19 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +19 -0
- data/lib/active_record/type/integer.rb +23 -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 +51 -0
- data/lib/active_record/type/string.rb +36 -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 +48 -0
- data/lib/active_record/type/value.rb +101 -0
- data/lib/active_record/validations.rb +21 -16
- data/lib/active_record/validations/uniqueness.rb +9 -23
- 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 +71 -14
- data/lib/active_record/connection_adapters/postgresql/cast.rb +0 -168
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module ActiveRecord
|
3
2
|
# = Active Record Timestamp
|
4
3
|
#
|
@@ -48,8 +47,9 @@ module ActiveRecord
|
|
48
47
|
current_time = current_time_from_proper_timezone
|
49
48
|
|
50
49
|
all_timestamp_attributes.each do |column|
|
51
|
-
|
52
|
-
|
50
|
+
column = column.to_s
|
51
|
+
if has_attribute?(column) && !attribute_present?(column)
|
52
|
+
write_attribute(column, current_time)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -99,9 +99,11 @@ module ActiveRecord
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update)
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
timestamp_names
|
103
|
+
.map { |attr| self[attr] }
|
104
|
+
.compact
|
105
|
+
.map(&:to_time)
|
106
|
+
.max
|
105
107
|
end
|
106
108
|
|
107
109
|
def current_time_from_proper_timezone
|
@@ -112,7 +114,7 @@ module ActiveRecord
|
|
112
114
|
def clear_timestamp_attributes
|
113
115
|
all_timestamp_attributes_in_model.each do |attribute_name|
|
114
116
|
self[attribute_name] = nil
|
115
|
-
|
117
|
+
clear_attribute_changes([attribute_name])
|
116
118
|
end
|
117
119
|
end
|
118
120
|
end
|
@@ -1,15 +1,25 @@
|
|
1
|
-
require 'thread'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
# See ActiveRecord::Transactions::ClassMethods for documentation.
|
5
3
|
module Transactions
|
6
4
|
extend ActiveSupport::Concern
|
7
5
|
ACTIONS = [:create, :destroy, :update]
|
6
|
+
CALLBACK_WARN_MESSAGE = <<-EOF
|
7
|
+
Currently, Active Record will rescue any errors raised within
|
8
|
+
after_rollback/after_commit callbacks and print them to the logs. In the next
|
9
|
+
version, these errors will no longer be rescued. Instead, they will simply
|
10
|
+
bubble just like other Active Record callbacks.
|
11
|
+
|
12
|
+
You can opt into the new behavior and remove this warning by setting
|
13
|
+
config.active_record.raise_in_transactional_callbacks to true.
|
14
|
+
EOF
|
8
15
|
|
9
16
|
included do
|
10
17
|
define_callbacks :commit, :rollback,
|
11
18
|
terminator: ->(_, result) { result == false },
|
12
19
|
scope: [:kind, :name]
|
20
|
+
|
21
|
+
mattr_accessor :raise_in_transactional_callbacks, instance_writer: false
|
22
|
+
self.raise_in_transactional_callbacks = false
|
13
23
|
end
|
14
24
|
|
15
25
|
# = Active Record Transactions
|
@@ -225,6 +235,9 @@ module ActiveRecord
|
|
225
235
|
def after_commit(*args, &block)
|
226
236
|
set_options_for_callbacks!(args)
|
227
237
|
set_callback(:commit, :after, *args, &block)
|
238
|
+
unless ActiveRecord::Base.raise_in_transactional_callbacks
|
239
|
+
ActiveSupport::Deprecation.warn(CALLBACK_WARN_MESSAGE)
|
240
|
+
end
|
228
241
|
end
|
229
242
|
|
230
243
|
# This callback is called after a create, update, or destroy are rolled back.
|
@@ -233,6 +246,9 @@ module ActiveRecord
|
|
233
246
|
def after_rollback(*args, &block)
|
234
247
|
set_options_for_callbacks!(args)
|
235
248
|
set_callback(:rollback, :after, *args, &block)
|
249
|
+
unless ActiveRecord::Base.raise_in_transactional_callbacks
|
250
|
+
ActiveSupport::Deprecation.warn(CALLBACK_WARN_MESSAGE)
|
251
|
+
end
|
236
252
|
end
|
237
253
|
|
238
254
|
private
|
@@ -249,7 +265,7 @@ module ActiveRecord
|
|
249
265
|
|
250
266
|
def assert_valid_transaction_action(actions)
|
251
267
|
if (actions - ACTIONS).any?
|
252
|
-
raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS}"
|
268
|
+
raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS.join(",")}"
|
253
269
|
end
|
254
270
|
end
|
255
271
|
end
|
@@ -292,16 +308,16 @@ module ActiveRecord
|
|
292
308
|
#
|
293
309
|
# Ensure that it is not called if the object was never persisted (failed create),
|
294
310
|
# but call it after the commit of a destroyed object.
|
295
|
-
def committed! #:nodoc:
|
296
|
-
run_callbacks :commit if destroyed? || persisted?
|
311
|
+
def committed!(should_run_callbacks = true) #:nodoc:
|
312
|
+
run_callbacks :commit if should_run_callbacks && destroyed? || persisted?
|
297
313
|
ensure
|
298
|
-
|
314
|
+
force_clear_transaction_record_state
|
299
315
|
end
|
300
316
|
|
301
317
|
# Call the +after_rollback+ callbacks. The +force_restore_state+ argument indicates if the record
|
302
318
|
# state should be rolled back to the beginning or just to the last savepoint.
|
303
|
-
def rolledback!(force_restore_state = false) #:nodoc:
|
304
|
-
run_callbacks :rollback
|
319
|
+
def rolledback!(force_restore_state = false, should_run_callbacks = true) #:nodoc:
|
320
|
+
run_callbacks :rollback if should_run_callbacks
|
305
321
|
ensure
|
306
322
|
restore_transaction_record_state(force_restore_state)
|
307
323
|
clear_transaction_record_state
|
@@ -328,7 +344,7 @@ module ActiveRecord
|
|
328
344
|
begin
|
329
345
|
status = yield
|
330
346
|
rescue ActiveRecord::Rollback
|
331
|
-
|
347
|
+
clear_transaction_record_state
|
332
348
|
status = nil
|
333
349
|
end
|
334
350
|
|
@@ -341,7 +357,7 @@ module ActiveRecord
|
|
341
357
|
|
342
358
|
# Save the new record state and id of a record so it can be restored later if a transaction fails.
|
343
359
|
def remember_transaction_record_state #:nodoc:
|
344
|
-
@_start_transaction_state[:id] = id
|
360
|
+
@_start_transaction_state[:id] = id
|
345
361
|
unless @_start_transaction_state.include?(:new_record)
|
346
362
|
@_start_transaction_state[:new_record] = @new_record
|
347
363
|
end
|
@@ -349,13 +365,18 @@ module ActiveRecord
|
|
349
365
|
@_start_transaction_state[:destroyed] = @destroyed
|
350
366
|
end
|
351
367
|
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
|
352
|
-
@_start_transaction_state[:frozen?] =
|
368
|
+
@_start_transaction_state[:frozen?] = frozen?
|
353
369
|
end
|
354
370
|
|
355
371
|
# Clear the new record state and id of a record.
|
356
372
|
def clear_transaction_record_state #:nodoc:
|
357
373
|
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
|
358
|
-
|
374
|
+
force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
|
375
|
+
end
|
376
|
+
|
377
|
+
# Force to clear the transaction record state.
|
378
|
+
def force_clear_transaction_record_state #:nodoc:
|
379
|
+
@_start_transaction_state.clear
|
359
380
|
end
|
360
381
|
|
361
382
|
# Restore the new record state and id of a record that was previously saved by a call to save_record_state.
|
@@ -364,17 +385,10 @@ module ActiveRecord
|
|
364
385
|
transaction_level = (@_start_transaction_state[:level] || 0) - 1
|
365
386
|
if transaction_level < 1 || force
|
366
387
|
restore_state = @_start_transaction_state
|
367
|
-
|
368
|
-
@attributes = @attributes.dup if @attributes.frozen?
|
388
|
+
thaw unless restore_state[:frozen?]
|
369
389
|
@new_record = restore_state[:new_record]
|
370
390
|
@destroyed = restore_state[:destroyed]
|
371
|
-
|
372
|
-
write_attribute(self.class.primary_key, restore_state[:id])
|
373
|
-
else
|
374
|
-
@attributes.delete(self.class.primary_key)
|
375
|
-
@attributes_cache.delete(self.class.primary_key)
|
376
|
-
end
|
377
|
-
@attributes.freeze if was_frozen
|
391
|
+
write_attribute(self.class.primary_key, restore_state[:id])
|
378
392
|
end
|
379
393
|
end
|
380
394
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_record/type/mutable'
|
2
|
+
require 'active_record/type/numeric'
|
3
|
+
require 'active_record/type/time_value'
|
4
|
+
require 'active_record/type/value'
|
5
|
+
|
6
|
+
require 'active_record/type/binary'
|
7
|
+
require 'active_record/type/boolean'
|
8
|
+
require 'active_record/type/date'
|
9
|
+
require 'active_record/type/date_time'
|
10
|
+
require 'active_record/type/decimal'
|
11
|
+
require 'active_record/type/decimal_without_scale'
|
12
|
+
require 'active_record/type/float'
|
13
|
+
require 'active_record/type/integer'
|
14
|
+
require 'active_record/type/serialized'
|
15
|
+
require 'active_record/type/string'
|
16
|
+
require 'active_record/type/text'
|
17
|
+
require 'active_record/type/time'
|
18
|
+
|
19
|
+
require 'active_record/type/type_map'
|
20
|
+
require 'active_record/type/hash_lookup_type_map'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Type
|
3
|
+
class Binary < Value # :nodoc:
|
4
|
+
def type
|
5
|
+
:binary
|
6
|
+
end
|
7
|
+
|
8
|
+
def binary?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def type_cast(value)
|
13
|
+
if value.is_a?(Data)
|
14
|
+
value.to_s
|
15
|
+
else
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def type_cast_for_database(value)
|
21
|
+
return if value.nil?
|
22
|
+
Data.new(super)
|
23
|
+
end
|
24
|
+
|
25
|
+
class Data # :nodoc:
|
26
|
+
def initialize(value)
|
27
|
+
@value = value.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
@value
|
32
|
+
end
|
33
|
+
|
34
|
+
def hex
|
35
|
+
@value.unpack('H*')[0]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Type
|
3
|
+
class Boolean < Value # :nodoc:
|
4
|
+
def type
|
5
|
+
:boolean
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def cast_value(value)
|
11
|
+
if value == ''
|
12
|
+
nil
|
13
|
+
else
|
14
|
+
ConnectionAdapters::Column::TRUE_VALUES.include?(value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Type
|
3
|
+
class Date < Value # :nodoc:
|
4
|
+
def type
|
5
|
+
:date
|
6
|
+
end
|
7
|
+
|
8
|
+
def klass
|
9
|
+
::Date
|
10
|
+
end
|
11
|
+
|
12
|
+
def type_cast_for_schema(value)
|
13
|
+
"'#{value.to_s(:db)}'"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def cast_value(value)
|
19
|
+
if value.is_a?(::String)
|
20
|
+
return if value.empty?
|
21
|
+
fast_string_to_date(value) || fallback_string_to_date(value)
|
22
|
+
elsif value.respond_to?(:to_date)
|
23
|
+
value.to_date
|
24
|
+
else
|
25
|
+
value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def fast_string_to_date(string)
|
30
|
+
if string =~ ConnectionAdapters::Column::Format::ISO_DATE
|
31
|
+
new_date $1.to_i, $2.to_i, $3.to_i
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def fallback_string_to_date(string)
|
36
|
+
new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
|
37
|
+
end
|
38
|
+
|
39
|
+
def new_date(year, mon, mday)
|
40
|
+
if year && year != 0
|
41
|
+
::Date.new(year, mon, mday) rescue nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Type
|
3
|
+
class DateTime < Value # :nodoc:
|
4
|
+
include TimeValue
|
5
|
+
|
6
|
+
def type
|
7
|
+
:datetime
|
8
|
+
end
|
9
|
+
|
10
|
+
def type_cast_for_database(value)
|
11
|
+
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
12
|
+
|
13
|
+
if value.acts_like?(:time)
|
14
|
+
value.send(zone_conversion_method)
|
15
|
+
else
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def cast_value(string)
|
23
|
+
return string unless string.is_a?(::String)
|
24
|
+
return if string.empty?
|
25
|
+
|
26
|
+
fast_string_to_time(string) || fallback_string_to_time(string)
|
27
|
+
end
|
28
|
+
|
29
|
+
# '0.123456' -> 123456
|
30
|
+
# '1.123456' -> 123456
|
31
|
+
def microseconds(time)
|
32
|
+
time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
|
33
|
+
end
|
34
|
+
|
35
|
+
def fallback_string_to_time(string)
|
36
|
+
time_hash = ::Date._parse(string)
|
37
|
+
time_hash[:sec_fraction] = microseconds(time_hash)
|
38
|
+
|
39
|
+
new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Type
|
3
|
+
class Decimal < Value # :nodoc:
|
4
|
+
include Numeric
|
5
|
+
|
6
|
+
def type
|
7
|
+
:decimal
|
8
|
+
end
|
9
|
+
|
10
|
+
def type_cast_for_schema(value)
|
11
|
+
value.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def cast_value(value)
|
17
|
+
case value
|
18
|
+
when ::Float
|
19
|
+
BigDecimal(value, float_precision)
|
20
|
+
when ::Numeric, ::String
|
21
|
+
BigDecimal(value, precision.to_i)
|
22
|
+
else
|
23
|
+
if value.respond_to?(:to_d)
|
24
|
+
value.to_d
|
25
|
+
else
|
26
|
+
cast_value(value.to_s)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def float_precision
|
32
|
+
if precision.to_i > ::Float::DIG + 1
|
33
|
+
::Float::DIG + 1
|
34
|
+
else
|
35
|
+
precision.to_i
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Type
|
3
|
+
class HashLookupTypeMap < TypeMap # :nodoc:
|
4
|
+
delegate :key?, to: :@mapping
|
5
|
+
|
6
|
+
def lookup(type, *args)
|
7
|
+
@mapping.fetch(type, proc { default_value }).call(type, *args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch(type, *args, &block)
|
11
|
+
@mapping.fetch(type, block).call(type, *args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def alias_type(type, alias_type)
|
15
|
+
register_type(type) { |_, *args| lookup(alias_type, *args) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Type
|
3
|
+
class Integer < Value # :nodoc:
|
4
|
+
include Numeric
|
5
|
+
|
6
|
+
def type
|
7
|
+
:integer
|
8
|
+
end
|
9
|
+
|
10
|
+
alias type_cast_for_database type_cast
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def cast_value(value)
|
15
|
+
case value
|
16
|
+
when true then 1
|
17
|
+
when false then 0
|
18
|
+
else value.to_i rescue nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|