mysql tests are mostly passing

This commit is contained in:
Aaron Patterson
2010-10-13 10:23:00 -07:00
parent 9c7e2e4117
commit 77b1193ac1
3 changed files with 126 additions and 20 deletions

View File

@@ -3,6 +3,27 @@ require 'active_support/core_ext/kernel/requires'
require 'active_support/core_ext/object/blank'
require 'set'
begin
require 'mysql'
rescue LoadError
raise "!!! Missing the mysql gem. Add it to your Gemfile: gem 'mysql'"
end
unless defined?(Mysql::Result) && Mysql::Result.method_defined?(:each_hash)
raise "!!! Outdated mysql gem. Upgrade to 2.8.1 or later. In your Gemfile: gem 'mysql', '2.8.1'. Or use gem 'mysql2'"
end
class Mysql
class Time
###
# This monkey patch is for test_additional_columns_from_join_table
def to_date
Date.new(year, month, day)
end
end
end
module ActiveRecord
class Base
# Establishes a connection to the database that's used by all Active Record objects.
@@ -15,18 +36,6 @@ module ActiveRecord
password = config[:password].to_s
database = config[:database]
unless defined? Mysql
begin
require 'mysql'
rescue LoadError
raise "!!! Missing the mysql2 gem. Add it to your Gemfile: gem 'mysql2'"
end
unless defined?(Mysql::Result) && Mysql::Result.method_defined?(:each_hash)
raise "!!! Outdated mysql gem. Upgrade to 2.8.1 or later. In your Gemfile: gem 'mysql', '2.8.1'. Or use gem 'mysql2'"
end
end
mysql = Mysql.init
mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslca] || config[:sslkey]
@@ -39,6 +48,30 @@ module ActiveRecord
module ConnectionAdapters
class MysqlColumn < Column #:nodoc:
class << self
def string_to_time(value)
return super unless Mysql::Time === value
new_time(
value.year,
value.month,
value.day,
value.hour,
value.minute,
value.second,
value.second_part)
end
def string_to_dummy_time(v)
return super unless Mysql::Time === v
new_time(2000, 01, 01, v.hour, v.minute, v.second, v.second_part)
end
def string_to_date(v)
return super unless Mysql::Time === v
new_date(v.year, v.month, v.day)
end
end
def extract_default(default)
if sql_type =~ /blob/i || type == :text
if default.blank?
@@ -280,6 +313,24 @@ module ActiveRecord
rows
end
def exec(sql, name = 'SQL', bind_values = [])
log(sql, name) do
stmt = @connection.prepare(sql)
stmt.execute(*bind_values.map { |col, val|
col ? col.type_cast(val) : val
})
result = nil
if metadata = stmt.result_metadata
cols = metadata.fetch_fields.map { |field| field.name }
values = []
stmt.each { |thing| values << thing }
result = ActiveRecord::Result.new(cols, values)
end
stmt.close
result
end
end
# Executes an SQL query and returns a MySQL::Result object. Note that you have to free
# the Result object after you're done using it.
def execute(sql, name = nil) #:nodoc:
@@ -614,12 +665,9 @@ module ActiveRecord
execute("SET SQL_AUTO_IS_NULL=0", :skip_logging)
end
def select(sql, name = nil)
def select(sql, name = nil, binds = [])
@connection.query_with_result = true
result = execute(sql, name)
rows = []
result.each_hash { |row| rows << row }
result.free
rows = exec(sql, name, binds).to_a
@connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
rows
end

View File

@@ -43,6 +43,64 @@ class MysqlConnectionTest < ActiveRecord::TestCase
assert @connection.active?
end
def test_bind_value_substitute
bind_param = @connection.substitute_for('foo', [])
assert_equal Arel.sql('?'), bind_param
end
def test_exec_no_binds
@connection.exec('drop table if exists ex')
@connection.exec(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
result = @connection.exec('SELECT id, data FROM ex')
assert_equal 0, result.rows.length
assert_equal 2, result.columns.length
assert_equal %w{ id data }, result.columns
@connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
result = @connection.exec('SELECT id, data FROM ex')
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
assert_equal [[1, 'foo']], result.rows
end
def test_exec_with_binds
@connection.exec('drop table if exists ex')
@connection.exec(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
@connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
result = @connection.exec(
'SELECT id, data FROM ex WHERE id = ?', nil, [[nil, 1]])
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
assert_equal [[1, 'foo']], result.rows
end
def test_exec_typecasts_bind_vals
@connection.exec('drop table if exists ex')
@connection.exec(<<-eosql)
CREATE TABLE `ex` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
`data` varchar(255))
eosql
@connection.exec('INSERT INTO ex (id, data) VALUES (1, "foo")')
column = @connection.columns('ex').find { |col| col.name == 'id' }
result = @connection.exec(
'SELECT id, data FROM ex WHERE id = ?', nil, [[column, '1-fuu']])
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
assert_equal [[1, 'foo']], result.rows
end
# Test that MySQL allows multiple results for stored procedures
if Mysql.const_defined?(:CLIENT_MULTI_RESULTS)
def test_multi_results

View File

@@ -103,7 +103,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
if current_adapter?(:MysqlAdapter)
def test_read_attributes_before_type_cast_on_boolean
bool = Boolean.create({ "value" => false })
assert_equal "0", bool.reload.attributes_before_type_cast["value"]
assert_equal 0, bool.reload.attributes_before_type_cast["value"]
end
end
@@ -112,7 +112,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
developer = Developer.find(:first)
# Oracle adapter returns Time before type cast
unless current_adapter?(:OracleAdapter)
assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"]
assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s
else
assert_equal developer.created_at.to_s(:db) , developer.attributes_before_type_cast["created_at"].to_s(:db)
@@ -121,7 +121,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
assert_equal developer.created_at, nil
developer.created_at = "2010-03-21 21:23:32"
assert_equal developer.created_at_before_type_cast, "2010-03-21 21:23:32"
assert_equal developer.created_at_before_type_cast.to_s, "2010-03-21 21:23:32"
assert_equal developer.created_at, Time.parse("2010-03-21 21:23:32")
end
end