Permalink
Browse files

Standardize the interpretation of boolean columns in the Mysql and Sq…

…lite 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
  • Loading branch information...
1 parent e7059fd commit ea654654226924f9b900e7981fdbdbd452ca15d8 @jamis jamis committed Sep 25, 2005
View
@@ -1,5 +1,7 @@
*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;
+) 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|

0 comments on commit ea65465

Please sign in to comment.