add casting support in the AR driver specifically for handling default column values - this is a temporary (but working) fix as I'm looking into how I can do this in C
This commit is contained in:
parent
03c8d5dcea
commit
6e977f756f
|
@ -13,6 +13,7 @@ module ActiveRecord
|
||||||
|
|
||||||
module ConnectionAdapters
|
module ConnectionAdapters
|
||||||
class Mysql2Column < Column
|
class Mysql2Column < Column
|
||||||
|
BOOL = "tinyint(1)".freeze
|
||||||
def extract_default(default)
|
def extract_default(default)
|
||||||
if sql_type =~ /blob/i || type == :text
|
if sql_type =~ /blob/i || type == :text
|
||||||
if default.blank?
|
if default.blank?
|
||||||
|
@ -49,10 +50,20 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def type_cast(value)
|
def type_cast(value)
|
||||||
if type == :boolean
|
return nil if value.nil?
|
||||||
self.class.value_to_boolean(value)
|
case type
|
||||||
else
|
when :string then value
|
||||||
value
|
when :text then value
|
||||||
|
when :integer then value.to_i rescue value ? 1 : 0 unless value.is_a?(Fixnum)
|
||||||
|
when :float then value.to_f unless value.is_a?(Float)
|
||||||
|
when :decimal then self.class.value_to_decimal(value) unless value.class == BigDecimal
|
||||||
|
when :datetime then self.class.string_to_time(value) unless value.class == Time
|
||||||
|
when :timestamp then self.class.string_to_time(value) unless value.class == Time
|
||||||
|
when :time then self.class.string_to_dummy_time(value) unless value.class == Time
|
||||||
|
when :date then self.class.string_to_date(value) unless value.class == Date
|
||||||
|
when :binary then value
|
||||||
|
when :boolean then self.class.value_to_boolean(value)
|
||||||
|
else value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,8 +73,9 @@ module ActiveRecord
|
||||||
|
|
||||||
private
|
private
|
||||||
def simplified_type(field_type)
|
def simplified_type(field_type)
|
||||||
return :boolean if Mysql2Adapter.emulate_booleans && field_type.downcase.index("tinyint(1)")
|
return :boolean if Mysql2Adapter.emulate_booleans && field_type.downcase.index(BOOL)
|
||||||
return :string if field_type =~ /enum/i
|
return :string if field_type =~ /enum/i
|
||||||
|
return :integer if field_type =~ /year/i
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
|
||||||
require 'active_record'
|
require 'active_record'
|
||||||
require 'active_record/connection_adapters/mysql2_adapter'
|
require 'active_record/connection_adapters/mysql2_adapter'
|
||||||
|
|
||||||
|
class Mysql2Test2 < ActiveRecord::Base
|
||||||
|
set_table_name "mysql2_test2"
|
||||||
|
end
|
||||||
|
|
||||||
describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
|
describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
|
||||||
it "should be able to connect" do
|
it "should be able to connect" do
|
||||||
lambda {
|
lambda {
|
||||||
|
@ -20,4 +24,85 @@ describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
|
||||||
@connection.execute("SELECT NOW() as n").first['n'].class.should eql(Time)
|
@connection.execute("SELECT NOW() as n").first['n'].class.should eql(Time)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "columns" do
|
||||||
|
before(:all) do
|
||||||
|
ActiveRecord::Base.establish_connection(:adapter => 'mysql2', :database => 'test')
|
||||||
|
Mysql2Test2.connection.execute %[
|
||||||
|
CREATE TABLE IF NOT EXISTS mysql2_test2 (
|
||||||
|
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||||
|
`null_test` varchar(10) DEFAULT NULL,
|
||||||
|
`bit_test` bit(64) NOT NULL DEFAULT b'1',
|
||||||
|
`tiny_int_test` tinyint(4) NOT NULL DEFAULT '1',
|
||||||
|
`small_int_test` smallint(6) NOT NULL DEFAULT '1',
|
||||||
|
`medium_int_test` mediumint(9) NOT NULL DEFAULT '1',
|
||||||
|
`int_test` int(11) NOT NULL DEFAULT '1',
|
||||||
|
`big_int_test` bigint(20) NOT NULL DEFAULT '1',
|
||||||
|
`float_test` float(10,3) NOT NULL DEFAULT '1.000',
|
||||||
|
`double_test` double(10,3) NOT NULL DEFAULT '1.000',
|
||||||
|
`decimal_test` decimal(10,3) NOT NULL DEFAULT '1.000',
|
||||||
|
`date_test` date NOT NULL DEFAULT '2010-01-01',
|
||||||
|
`date_time_test` datetime NOT NULL DEFAULT '2010-01-01 00:00:00',
|
||||||
|
`timestamp_test` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`time_test` time NOT NULL DEFAULT '00:00:00',
|
||||||
|
`year_test` year(4) NOT NULL DEFAULT '2010',
|
||||||
|
`char_test` char(10) NOT NULL DEFAULT 'abcdefghij',
|
||||||
|
`varchar_test` varchar(10) NOT NULL DEFAULT 'abcdefghij',
|
||||||
|
`binary_test` binary(10) NOT NULL DEFAULT 'abcdefghij',
|
||||||
|
`varbinary_test` varbinary(10) NOT NULL DEFAULT 'abcdefghij',
|
||||||
|
`tiny_blob_test` tinyblob NOT NULL,
|
||||||
|
`tiny_text_test` tinytext,
|
||||||
|
`blob_test` blob,
|
||||||
|
`text_test` text,
|
||||||
|
`medium_blob_test` mediumblob,
|
||||||
|
`medium_text_test` mediumtext,
|
||||||
|
`long_blob_test` longblob,
|
||||||
|
`long_text_test` longtext,
|
||||||
|
`enum_test` enum('val1','val2') NOT NULL DEFAULT 'val1',
|
||||||
|
`set_test` set('val1','val2') NOT NULL DEFAULT 'val1,val2',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
Mysql2Test2.connection.execute "INSERT INTO mysql2_test2 (null_test) VALUES (NULL)"
|
||||||
|
@test_result = Mysql2Test2.connection.execute("SELECT * FROM mysql2_test2 ORDER BY id DESC LIMIT 1").first
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:all) do
|
||||||
|
Mysql2Test2.connection.execute("DELETE FROM mysql2_test WHERE id=#{@test_result['id']}")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "default value should be cast to the expected type of the field" do
|
||||||
|
test = Mysql2Test2.new
|
||||||
|
test.null_test.should be_nil
|
||||||
|
test.bit_test.should eql("b'1'")
|
||||||
|
test.tiny_int_test.should eql(1)
|
||||||
|
test.small_int_test.should eql(1)
|
||||||
|
test.medium_int_test.should eql(1)
|
||||||
|
test.int_test.should eql(1)
|
||||||
|
test.big_int_test.should eql(1)
|
||||||
|
test.float_test.should eql('1.0000'.to_f)
|
||||||
|
test.double_test.should eql('1.0000'.to_f)
|
||||||
|
test.decimal_test.should eql(BigDecimal.new('1.0000'))
|
||||||
|
test.date_test.should eql(Date.parse('2010-01-01'))
|
||||||
|
test.date_time_test.should eql(Time.parse('2010-01-01 00:00:00'))
|
||||||
|
test.timestamp_test.should be_nil
|
||||||
|
test.time_test.class.should eql(Time)
|
||||||
|
test.year_test.should eql(2010)
|
||||||
|
test.char_test.should eql('abcdefghij')
|
||||||
|
test.varchar_test.should eql('abcdefghij')
|
||||||
|
test.binary_test.should eql('abcdefghij')
|
||||||
|
test.varbinary_test.should eql('abcdefghij')
|
||||||
|
test.tiny_blob_test.should eql("")
|
||||||
|
test.tiny_text_test.should be_nil
|
||||||
|
test.blob_test.should be_nil
|
||||||
|
test.text_test.should be_nil
|
||||||
|
test.medium_blob_test.should be_nil
|
||||||
|
test.medium_text_test.should be_nil
|
||||||
|
test.long_blob_test.should be_nil
|
||||||
|
test.long_text_test.should be_nil
|
||||||
|
test.long_blob_test.should be_nil
|
||||||
|
test.enum_test.should eql('val1')
|
||||||
|
test.set_test.should eql('val1,val2')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
Loading…
Reference in New Issue