提交 b93b39ef 编写于 作者: S Sean Griffin

Remove most type related predicates from `Column`

Remaining are `limit`, `precision`, `scale`, and `type` (the symbol
version). These will remain on the column, since they mirror the options
to the `column` method in the schema definition DSL
上级 155b1b7f
......@@ -104,11 +104,11 @@ def key_conversion_required?
end
def association_key_type
@klass.column_for_attribute(association_key_name).type
@klass.type_for_attribute(association_key_name.to_s).type
end
def owner_key_type
@model.column_for_attribute(owner_key_name).type
@model.type_for_attribute(owner_key_name.to_s).type
end
def load_slices(slices)
......
......@@ -15,6 +15,7 @@ def query_attribute(attr_name)
when false, nil then false
else
column = self.class.columns_hash[attr_name]
type = self.class.type_for_attribute(attr_name)
if column.nil?
if Numeric === value || value !~ /[^0-9]/
!value.to_i.zero?
......@@ -22,7 +23,7 @@ def query_attribute(attr_name)
return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
!value.blank?
end
elsif column.number?
elsif type.number?
!value.zero?
else
!value.blank?
......
......@@ -46,9 +46,10 @@ def migration_keys
private
def schema_default(column)
default = column.type_cast_from_database(column.default)
type = lookup_cast_type_from_column(column)
default = type.type_cast_from_database(column.default)
unless default.nil?
column.type_cast_for_schema(default)
type.type_cast_for_schema(default)
end
end
end
......
......@@ -14,11 +14,7 @@ module Format
attr_reader :name, :cast_type, :null, :sql_type, :default, :default_function
delegate :type, :precision, :scale, :limit, :klass, :accessor,
:text?, :number?, :binary?, :changed?,
:type_cast_from_user, :type_cast_from_database, :type_cast_for_database,
:type_cast_for_schema,
to: :cast_type
delegate :precision, :scale, :limit, :type, to: :cast_type
# Instantiates a new column in the table.
#
......
......@@ -210,7 +210,7 @@ def inspect
elsif !connected?
"#{super} (call '#{super}.connection' to establish a connection)"
elsif table_exists?
attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
attr_list = column_types.map { |name, type| "#{name}: #{type.type}" } * ', '
"#{super}(#{attr_list})"
else
"#{super}(Table doesn't exist)"
......
......@@ -661,7 +661,7 @@ def table_rows
row[association.foreign_type] = $1
end
fk_type = association.active_record.columns_hash[fk_name].type
fk_type = association.active_record.type_for_attribute(fk_name).type
row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
end
when :has_many
......@@ -691,7 +691,7 @@ def name
end
def primary_key_type
@association.klass.column_types[@association.klass.primary_key].type
@association.klass.type_for_attribute(@association.klass.primary_key).type
end
end
......@@ -711,7 +711,7 @@ def primary_key_name
end
def primary_key_type
@primary_key_type ||= model_class && model_class.column_types[model_class.primary_key].type
@primary_key_type ||= model_class && model_class.type_for_attribute(model_class.primary_key).type
end
def add_join_records(rows, row, association)
......
......@@ -180,9 +180,9 @@ class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
def compute_type
klass = @serializable.class
column = klass.columns_hash[name] || Type::Value.new
cast_type = klass.type_for_attribute(name)
type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] || column.type
type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] || cast_type.type
{ :text => :string,
:time => :datetime }[type] || type
......
......@@ -59,7 +59,8 @@ def build_relation(klass, table, attribute, value) #:nodoc:
end
column = klass.columns_hash[attribute_name]
value = klass.type_for_attribute(attribute_name).type_cast_for_database(value)
cast_type = klass.type_for_attribute(attribute_name)
value = cast_type.type_cast_for_database(value)
value = klass.connection.type_cast(value)
if value.is_a?(String) && column.limit
value = value.to_s[0, column.limit]
......@@ -67,7 +68,7 @@ def build_relation(klass, table, attribute, value) #:nodoc:
value = Arel::Nodes::Quoted.new(value)
comparison = if !options[:case_sensitive] && value && column.text?
comparison = if !options[:case_sensitive] && value && cast_type.text?
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
klass.connection.case_insensitive_comparison(table, attribute, column, value)
else
......
......@@ -25,6 +25,7 @@ def setup
end
end
@column = PgArray.columns_hash['tags']
@type = PgArray.type_for_attribute("tags")
end
teardown do
......@@ -36,13 +37,14 @@ def test_column
assert_equal :string, @column.type
assert_equal "character varying", @column.sql_type
assert @column.array?
assert_not @column.number?
assert_not @column.binary?
assert_not @type.number?
assert_not @type.binary?
ratings_column = PgArray.columns_hash['ratings']
assert_equal :integer, ratings_column.type
type = PgArray.type_for_attribute("ratings")
assert ratings_column.array?
assert_not ratings_column.number?
assert_not type.number?
end
def test_default
......@@ -94,9 +96,9 @@ def test_change_column_default_with_array
end
def test_type_cast_array
assert_equal(['1', '2', '3'], @column.type_cast_from_database('{1,2,3}'))
assert_equal([], @column.type_cast_from_database('{}'))
assert_equal([nil], @column.type_cast_from_database('{NULL}'))
assert_equal(['1', '2', '3'], @type.type_cast_from_database('{1,2,3}'))
assert_equal([], @type.type_cast_from_database('{}'))
assert_equal([nil], @type.type_cast_from_database('{NULL}'))
end
def test_type_cast_integers
......@@ -208,7 +210,7 @@ def test_string_quoting_rules_match_pg_behavior
x = PgArray.create!(tags: tags)
x.reload
assert_equal x.tags_before_type_cast, PgArray.columns_hash['tags'].type_cast_for_database(tags)
assert_equal x.tags_before_type_cast, PgArray.type_for_attribute('tags').type_cast_for_database(tags)
end
def test_quoting_non_standard_delimiters
......
......@@ -26,18 +26,22 @@ def test_bit_string_column
column = PostgresqlBitString.columns_hash["a_bit"]
assert_equal :bit, column.type
assert_equal "bit(8)", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlBitString.type_for_attribute("a_bit")
assert_not type.number?
assert_not type.binary?
end
def test_bit_string_varying_column
column = PostgresqlBitString.columns_hash["a_bit_varying"]
assert_equal :bit_varying, column.type
assert_equal "bit varying(4)", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlBitString.type_for_attribute("a_bit_varying")
assert_not type.number?
assert_not type.binary?
end
def test_default
......
......@@ -17,6 +17,7 @@ def setup
end
end
@column = ByteaDataType.columns_hash['payload']
@type = ByteaDataType.type_for_attribute("payload")
end
teardown do
......@@ -40,16 +41,16 @@ def test_type_cast_binary_converts_the_encoding
data = "\u001F\x8B"
assert_equal('UTF-8', data.encoding.name)
assert_equal('ASCII-8BIT', @column.type_cast_from_database(data).encoding.name)
assert_equal('ASCII-8BIT', @type.type_cast_from_database(data).encoding.name)
end
def test_type_cast_binary_value
data = "\u001F\x8B".force_encoding("BINARY")
assert_equal(data, @column.type_cast_from_database(data))
assert_equal(data, @type.type_cast_from_database(data))
end
def test_type_case_nil
assert_equal(nil, @column.type_cast_from_database(nil))
assert_equal(nil, @type.type_cast_from_database(nil))
end
def test_read_value
......
......@@ -32,9 +32,11 @@ def test_column
column = Citext.columns_hash['cival']
assert_equal :citext, column.type
assert_equal 'citext', column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = Citext.type_for_attribute('cival')
assert_not type.number?
assert_not type.binary?
end
def test_change_table_supports_json
......
......@@ -50,9 +50,11 @@ def test_column
column = PostgresqlComposite.columns_hash["address"]
assert_nil column.type
assert_equal "full_address", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlComposite.type_for_attribute("address")
assert_not type.number?
assert_not type.binary?
end
def test_composite_mapping
......@@ -111,9 +113,11 @@ def test_column
column = PostgresqlComposite.columns_hash["address"]
assert_equal :full_address, column.type
assert_equal "full_address", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlComposite.type_for_attribute("address")
assert_not type.number?
assert_not type.binary?
end
def test_composite_mapping
......
......@@ -29,9 +29,11 @@ def test_column
column = PostgresqlDomain.columns_hash["price"]
assert_equal :decimal, column.type
assert_equal "custom_money", column.sql_type
assert column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlDomain.type_for_attribute("price")
assert type.number?
assert_not type.binary?
end
def test_domain_acts_like_basetype
......
......@@ -31,9 +31,11 @@ def test_column
column = PostgresqlEnum.columns_hash["current_mood"]
assert_equal :enum, column.type
assert_equal "mood", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlEnum.type_for_attribute("current_mood")
assert_not type.number?
assert_not type.binary?
end
def test_enum_defaults
......
......@@ -21,9 +21,11 @@ def test_tsvector_column
column = Tsvector.columns_hash["text_vector"]
assert_equal :tsvector, column.type
assert_equal "tsvector", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = Tsvector.type_for_attribute("text_vector")
assert_not type.number?
assert_not type.binary?
end
def test_update_tsvector
......
......@@ -26,9 +26,11 @@ def test_column
column = PostgresqlPoint.columns_hash["x"]
assert_equal :point, column.type
assert_equal "point", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlPoint.type_for_attribute("x")
assert_not type.number?
assert_not type.binary?
end
def test_default
......
......@@ -29,6 +29,7 @@ def setup
end
end
@column = Hstore.columns_hash['tags']
@type = Hstore.type_for_attribute("tags")
end
teardown do
......@@ -54,9 +55,10 @@ def test_disable_enable_hstore
def test_column
assert_equal :hstore, @column.type
assert_equal "hstore", @column.sql_type
assert_not @column.number?
assert_not @column.binary?
assert_not @column.array?
assert_not @type.number?
assert_not @type.binary?
end
def test_default
......@@ -110,10 +112,10 @@ def test_cast_value_on_write
end
def test_type_cast_hstore
assert_equal({'1' => '2'}, @column.type_cast_from_database("\"1\"=>\"2\""))
assert_equal({}, @column.type_cast_from_database(""))
assert_equal({'key'=>nil}, @column.type_cast_from_database('key => NULL'))
assert_equal({'c'=>'}','"a"'=>'b "a b'}, @column.type_cast_from_database(%q(c=>"}", "\"a\""=>"b \"a b")))
assert_equal({'1' => '2'}, @type.type_cast_from_database("\"1\"=>\"2\""))
assert_equal({}, @type.type_cast_from_database(""))
assert_equal({'key'=>nil}, @type.type_cast_from_database('key => NULL'))
assert_equal({'c'=>'}','"a"'=>'b "a b'}, @type.type_cast_from_database(%q(c=>"}", "\"a\""=>"b \"a b")))
end
def test_with_store_accessors
......@@ -165,47 +167,47 @@ def test_changes_in_place
end
def test_gen1
assert_equal(%q(" "=>""), @column.cast_type.type_cast_for_database({' '=>''}))
assert_equal(%q(" "=>""), @type.type_cast_for_database({' '=>''}))
end
def test_gen2
assert_equal(%q(","=>""), @column.cast_type.type_cast_for_database({','=>''}))
assert_equal(%q(","=>""), @type.type_cast_for_database({','=>''}))
end
def test_gen3
assert_equal(%q("="=>""), @column.cast_type.type_cast_for_database({'='=>''}))
assert_equal(%q("="=>""), @type.type_cast_for_database({'='=>''}))
end
def test_gen4
assert_equal(%q(">"=>""), @column.cast_type.type_cast_for_database({'>'=>''}))
assert_equal(%q(">"=>""), @type.type_cast_for_database({'>'=>''}))
end
def test_parse1
assert_equal({'a'=>nil,'b'=>nil,'c'=>'NuLl','null'=>'c'}, @column.type_cast_from_database('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
assert_equal({'a'=>nil,'b'=>nil,'c'=>'NuLl','null'=>'c'}, @type.type_cast_from_database('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
end
def test_parse2
assert_equal({" " => " "}, @column.type_cast_from_database("\\ =>\\ "))
assert_equal({" " => " "}, @type.type_cast_from_database("\\ =>\\ "))
end
def test_parse3
assert_equal({"=" => ">"}, @column.type_cast_from_database("==>>"))
assert_equal({"=" => ">"}, @type.type_cast_from_database("==>>"))
end
def test_parse4
assert_equal({"=a"=>"q=w"}, @column.type_cast_from_database('\=a=>q=w'))
assert_equal({"=a"=>"q=w"}, @type.type_cast_from_database('\=a=>q=w'))
end
def test_parse5
assert_equal({"=a"=>"q=w"}, @column.type_cast_from_database('"=a"=>q\=w'))
assert_equal({"=a"=>"q=w"}, @type.type_cast_from_database('"=a"=>q\=w'))
end
def test_parse6
assert_equal({"\"a"=>"q>w"}, @column.type_cast_from_database('"\"a"=>q>w'))
assert_equal({"\"a"=>"q>w"}, @type.type_cast_from_database('"\"a"=>q>w'))
end
def test_parse7
assert_equal({"\"a"=>"q\"w"}, @column.type_cast_from_database('\"a=>q"w'))
assert_equal({"\"a"=>"q\"w"}, @type.type_cast_from_database('\"a=>q"w'))
end
def test_rewrite
......
......@@ -34,9 +34,11 @@ def test_column
column = JsonDataType.columns_hash["payload"]
assert_equal column_type, column.type
assert_equal column_type.to_s, column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = JsonDataType.type_for_attribute("payload")
assert_not type.number?
assert_not type.binary?
end
def test_default
......@@ -78,16 +80,16 @@ def test_cast_value_on_write
end
def test_type_cast_json
column = JsonDataType.columns_hash["payload"]
type = JsonDataType.type_for_attribute("payload")
data = "{\"a_key\":\"a_value\"}"
hash = column.type_cast_from_database(data)
hash = type.type_cast_from_database(data)
assert_equal({'a_key' => 'a_value'}, hash)
assert_equal({'a_key' => 'a_value'}, column.type_cast_from_database(data))
assert_equal({'a_key' => 'a_value'}, type.type_cast_from_database(data))
assert_equal({}, column.type_cast_from_database("{}"))
assert_equal({'key'=>nil}, column.type_cast_from_database('{"key": null}'))
assert_equal({'c'=>'}','"a"'=>'b "a b'}, column.type_cast_from_database(%q({"c":"}", "\"a\"":"b \"a b"})))
assert_equal({}, type.type_cast_from_database("{}"))
assert_equal({'key'=>nil}, type.type_cast_from_database('{"key": null}'))
assert_equal({'c'=>'}','"a"'=>'b "a b'}, type.type_cast_from_database(%q({"c":"}", "\"a\"":"b \"a b"})))
end
def test_rewrite
......
......@@ -30,9 +30,11 @@ def test_column
column = Ltree.columns_hash['path']
assert_equal :ltree, column.type
assert_equal "ltree", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = Ltree.type_for_attribute('path')
assert_not type.number?
assert_not type.binary?
end
def test_write
......
......@@ -25,9 +25,11 @@ def test_column
assert_equal :money, column.type
assert_equal "money", column.sql_type
assert_equal 2, column.scale
assert column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlMoney.type_for_attribute("wealth")
assert type.number?
assert_not type.binary?
end
def test_default
......@@ -46,11 +48,11 @@ def test_money_values
end
def test_money_type_cast
column = PostgresqlMoney.columns_hash['wealth']
assert_equal(12345678.12, column.type_cast_from_user("$12,345,678.12"))
assert_equal(12345678.12, column.type_cast_from_user("$12.345.678,12"))
assert_equal(-1.15, column.type_cast_from_user("-$1.15"))
assert_equal(-2.25, column.type_cast_from_user("($2.25)"))
type = PostgresqlMoney.type_for_attribute('wealth')
assert_equal(12345678.12, type.type_cast_from_user("$12,345,678.12"))
assert_equal(12345678.12, type.type_cast_from_user("$12.345.678,12"))
assert_equal(-1.15, type.type_cast_from_user("-$1.15"))
assert_equal(-2.25, type.type_cast_from_user("($2.25)"))
end
def test_schema_dumping
......
......@@ -23,27 +23,33 @@ def test_cidr_column
column = PostgresqlNetworkAddress.columns_hash["cidr_address"]
assert_equal :cidr, column.type
assert_equal "cidr", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlNetworkAddress.type_for_attribute("cidr_address")
assert_not type.number?
assert_not type.binary?
end
def test_inet_column
column = PostgresqlNetworkAddress.columns_hash["inet_address"]
assert_equal :inet, column.type
assert_equal "inet", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlNetworkAddress.type_for_attribute("inet_address")
assert_not type.number?
assert_not type.binary?
end
def test_macaddr_column
column = PostgresqlNetworkAddress.columns_hash["mac_address"]
assert_equal :macaddr, column.type
assert_equal "macaddr", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = PostgresqlNetworkAddress.type_for_attribute("mac_address")
assert_not type.number?
assert_not type.binary?
end
def test_network_types
......
......@@ -49,9 +49,11 @@ def test_data_type_of_uuid_types
column = UUIDType.columns_hash["guid"]
assert_equal :uuid, column.type
assert_equal "uuid", column.sql_type
assert_not column.number?
assert_not column.binary?
assert_not column.array?
type = UUIDType.type_for_attribute("guid")
assert_not type.number?
assert_not type.binary?
end
def test_treat_blank_uuid_as_nil
......
......@@ -68,8 +68,8 @@ def test_create_table_with_defaults
five = columns.detect { |c| c.name == "five" } unless mysql
assert_equal "hello", one.default
assert_equal true, two.type_cast_from_database(two.default)
assert_equal false, three.type_cast_from_database(three.default)
assert_equal true, connection.lookup_cast_type_from_column(two).type_cast_from_database(two.default)
assert_equal false, connection.lookup_cast_type_from_column(three).type_cast_from_database(three.default)
assert_equal '1', four.default
assert_equal "hello", five.default unless mysql
end
......
......@@ -196,7 +196,7 @@ def test_change_column
old_columns = connection.columns(TestModel.table_name)
assert old_columns.find { |c|
default = c.type_cast_from_database(c.default)
default = connection.lookup_cast_type_from_column(c).type_cast_from_database(c.default)
c.name == 'approved' && c.type == :boolean && default == true
}
......@@ -204,11 +204,11 @@ def test_change_column
new_columns = connection.columns(TestModel.table_name)
assert_not new_columns.find { |c|
default = c.type_cast_from_database(c.default)
default = connection.lookup_cast_type_from_column(c).type_cast_from_database(c.default)
c.name == 'approved' and c.type == :boolean and default == true
}
assert new_columns.find { |c|
default = c.type_cast_from_database(c.default)
default = connection.lookup_cast_type_from_column(c).type_cast_from_database(c.default)
c.name == 'approved' and c.type == :boolean and default == false
}
change_column :test_models, :approved, :boolean, :default => true
......
......@@ -86,18 +86,15 @@ def test_non_existent_columns_return_null_object
assert_equal "attribute_that_doesnt_exist", column.name
assert_equal nil, column.sql_type
assert_equal nil, column.type
assert_not column.number?
assert_not column.text?
assert_not column.binary?
end
def test_non_existent_columns_are_identity_types
column = @first.column_for_attribute("attribute_that_doesnt_exist")
def test_non_existent_types_are_identity_types
type = @first.type_for_attribute("attribute_that_doesnt_exist")
object = Object.new
assert_equal object, column.type_cast_from_database(object)
assert_equal object, column.type_cast_from_user(object)
assert_equal object, column.type_cast_for_database(object)
assert_equal object, type.type_cast_from_database(object)
assert_equal object, type.type_cast_from_user(object)
assert_equal object, type.type_cast_for_database(object)
end
def test_reflection_klass_for_nested_class_name
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册