提交 ea654654 编写于 作者: J Jamis Buck

Standardize the interpretation of boolean columns in the Mysql and Sqlite...

Standardize the interpretation of boolean columns in the Mysql and Sqlite adapters. (Use MysqlAdapter.emulate_booleans = false to disable this behavior)


git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2335 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 e7059fd2
*SVN*
* Standardize the interpretation of boolean columns in the Mysql and Sqlite adapters. (Use MysqlAdapter.emulate_booleans = false to disable this behavior)
* Added new symbol-driven approach to activating observers with Base#observers= [DHH]. Example:
ActiveRecord::Base.observers = :cacher, :garbage_collector
......
......@@ -158,7 +158,9 @@ class Column # :nodoc:
# The type parameter should either contain :integer, :float, :datetime, :date, :text, or :string
# The sql_type is just used for extracting the limit, such as 10 in "varchar(10)"
def initialize(name, default, sql_type = nil, null = true)
@name, @default, @type, @null = name, type_cast(default), simplified_type(sql_type), null
@name, @type, @null = name, simplified_type(sql_type), null
# have to do this one separately because type_cast depends on #type
@default = type_cast(default)
@limit = extract_limit(sql_type) unless sql_type.nil?
end
......@@ -337,6 +339,9 @@ def commit_db_transaction() end
# raises an exception or returns false.
def rollback_db_transaction() end
def quoted_true() "'t'" end
def quoted_false() "'f'" end
def quote(value, column = nil)
case value
when String
......@@ -348,8 +353,8 @@ def quote(value, column = nil)
"'#{quote_string(value)}'" # ' (for ruby-mode)
end
when NilClass then "NULL"
when TrueClass then (column && column.type == :boolean ? "'t'" : "1")
when FalseClass then (column && column.type == :boolean ? "'f'" : "0")
when TrueClass then (column && column.type == :boolean ? quoted_true : "1")
when FalseClass then (column && column.type == :boolean ? quoted_false : "0")
when Float, Fixnum, Bignum then value.to_s
when Date then "'#{value.to_s}'"
when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
......@@ -502,7 +507,7 @@ def type_to_sql(type, limit = nil)
def add_column_options!(sql, options)
sql << " NOT NULL" if options[:null] == false
sql << " DEFAULT '#{options[:default]}'" unless options[:default].nil?
sql << " DEFAULT #{quote(options[:default], options[:column])}" unless options[:default].nil?
end
protected
......@@ -574,7 +579,7 @@ def type_to_sql(name, limit)
end
def add_column_options!(sql, options)
base.add_column_options!(sql, options)
base.add_column_options!(sql, options.merge(:column => self))
end
end
......
......@@ -41,6 +41,14 @@ def self.mysql_connection(config) # :nodoc:
end
module ConnectionAdapters
class MysqlColumn < Column #:nodoc:
private
def simplified_type(field_type)
return :boolean if MysqlAdapter.emulate_booleans && field_type.downcase == "tinyint(1)"
super
end
end
# The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with
# the faster C-based MySQL/Ruby adapter (available both as a gem and from http://www.tmtm.org/en/mysql/ruby/).
#
......@@ -56,7 +64,17 @@ module ConnectionAdapters
# * <tt>:sslcert</tt> -- Necessary to use MySQL with an SSL connection
# * <tt>:sslcapath</tt> -- Necessary to use MySQL with an SSL connection
# * <tt>:sslcipher</tt> -- Necessary to use MySQL with an SSL connection
#
# By default, the MysqlAdapter will consider all columns of type tinyint(1)
# as boolean. If you wish to disable this emulation (which was the default
# behavior in versions 0.13.1 and earlier) you can add the following line
# to your environment.rb file:
#
# ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans = false
class MysqlAdapter < AbstractAdapter
@@emulate_booleans = true
cattr_accessor :emulate_booleans
LOST_CONNECTION_ERROR_MESSAGES = [
"Server shutdown in progress",
"Broken pipe",
......@@ -126,7 +144,7 @@ def indexes(table_name, name = nil)
def columns(table_name, name = nil)
sql = "SHOW FIELDS FROM #{table_name}"
columns = []
execute(sql, name).each { |field| columns << Column.new(field[0], field[4], field[1], field[2] == "YES") }
execute(sql, name).each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") }
columns
end
......@@ -184,6 +202,9 @@ def rollback_db_transaction
end
def quoted_true() "1" end
def quoted_false() "0" end
def quote_column_name(name)
"`#{name}`"
end
......
......@@ -99,7 +99,7 @@ def native_database_types
:time => { :name => "datetime" },
:date => { :name => "date" },
:binary => { :name => "blob" },
:boolean => { :name => "integer" }
:boolean => { :name => "boolean" }
}
end
......
......@@ -26,7 +26,7 @@ CREATE TABLE `topics` (
`bonus_time` time default NULL,
`last_read` date default NULL,
`content` text,
`approved` tinyint(1) default 1,
`approved` tinyint default 1,
`replies_count` int(11) default 0,
`parent_id` int(11) default NULL,
`type` varchar(50) default NULL,
......@@ -190,4 +190,4 @@ CREATE TABLE `fk_test_has_fk` (
`fk_id` INTEGER NOT NULL,
FOREIGN KEY (`fk_id`) REFERENCES `fk_test_has_pk`(`id`)
) TYPE=InnoDB;
\ No newline at end of file
) TYPE=InnoDB;
......@@ -68,6 +68,29 @@ def test_create_table_with_not_null_column
ensure
Person.connection.drop_table :testings rescue nil
end
def test_create_table_with_defaults
Person.connection.create_table :testings do |t|
t.column :one, :string, :default => "hello"
t.column :two, :boolean, :default => true
t.column :three, :boolean, :default => false
t.column :four, :integer, :default => 1
end
columns = Person.connection.columns(:testings)
one = columns.detect { |c| c.name == "one" }
two = columns.detect { |c| c.name == "two" }
three = columns.detect { |c| c.name == "three" }
four = columns.detect { |c| c.name == "four" }
assert_equal "hello", one.default
assert_equal true, two.default
assert_equal false, three.default
assert_equal 1, four.default
ensure
Person.connection.drop_table :testings rescue nil
end
def test_add_column_not_null
Person.connection.create_table :testings do |t|
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册