1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Detect mutations of arrays and array members

This commit is contained in:
Sean Griffin 2014-06-17 17:05:34 -06:00
parent 7f7e2f12ab
commit ba29c28a47
3 changed files with 41 additions and 12 deletions

View file

@ -1,3 +1,7 @@
* Detect in-place modifications of PG array types
*Sean Griffin*
* Add `bin/rake db:purge` task to empty the current database.
*Yves Senn*

View file

@ -3,6 +3,20 @@ module ActiveRecord
module PostgreSQL
module OID # :nodoc:
class Array < Type::Value
include Type::Mutable
# Loads pg_array_parser if available. String parsing can be
# performed quicker by a native extension, which will not create
# a large amount of Ruby objects that will need to be garbage
# collected. pg_array_parser has a C and Java extension
begin
require 'pg_array_parser'
include PgArrayParser
rescue LoadError
require 'active_record/connection_adapters/postgresql/array_parser'
include PostgreSQL::ArrayParser
end
attr_reader :subtype, :delimiter
delegate :type, to: :subtype
@ -31,18 +45,6 @@ module ActiveRecord
end
end
# Loads pg_array_parser if available. String parsing can be
# performed quicker by a native extension, which will not create
# a large amount of Ruby objects that will need to be garbage
# collected. pg_array_parser has a C and Java extension
begin
require 'pg_array_parser'
include PgArrayParser
rescue LoadError
require 'active_record/connection_adapters/postgresql/array_parser'
include PostgreSQL::ArrayParser
end
private
def type_cast_array(value, method)

View file

@ -16,6 +16,7 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
t.string 'tags', array: true
t.integer 'ratings', array: true
t.datetime :datetimes, array: true
t.hstore :hstores, array: true
end
end
@column = PgArray.columns_hash['tags']
@ -221,6 +222,28 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
assert_equal %({hello,;"world;"}), semicolon_delim.type_cast_for_database(strings)
end
def test_mutate_array
x = PgArray.create!(tags: %w(one two))
x.tags << "three"
x.save!
x.reload
assert_equal %w(one two three), x.tags
assert_not x.changed?
end
def test_mutate_value_in_array
x = PgArray.create!(hstores: [{ a: 'a' }, { b: 'b' }])
x.hstores.first['a'] = 'c'
x.save!
x.reload
assert_equal [{ 'a' => 'c' }, { 'b' => 'b' }], x.hstores
assert_not x.changed?
end
def test_datetime_with_timezone_awareness
tz = "Pacific Time (US & Canada)"