aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
blob: 631e1752c42739b39d39ed3db2a659db4f98e5dc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
require "cases/helper"
require 'support/ddl_helper'

module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapterTest < ActiveRecord::MysqlTestCase
      include DdlHelper

      def setup
        @conn = ActiveRecord::Base.connection
      end

      def test_bad_connection_mysql
        assert_raise ActiveRecord::NoDatabaseError do
          configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'inexistent_activerecord_unittest')
          connection = ActiveRecord::Base.mysql_connection(configuration)
          connection.drop_table 'ex', if_exists: true
        end
      end

      def test_valid_column
        with_example_table do
          column = @conn.columns('ex').find { |col| col.name == 'id' }
          assert @conn.valid_type?(column.type)
        end
      end

      def test_invalid_column
        assert_not @conn.valid_type?(:foobar)
      end

      def test_client_encoding
        assert_equal Encoding::UTF_8, @conn.client_encoding
      end

      def test_exec_insert_number
        with_example_table do
          insert(@conn, 'number' => 10)

          result = @conn.exec_query('SELECT number FROM ex WHERE number = 10')

          assert_equal 1, result.rows.length
          # if there are no bind parameters, it will return a string (due to
          # the libmysql api)
          assert_equal '10', result.rows.last.last
        end
      end

      def test_exec_insert_string
        with_example_table do
          str = 'いただきます!'
          insert(@conn, 'number' => 10, 'data' => str)

          result = @conn.exec_query('SELECT number, data FROM ex WHERE number = 10')

          value = result.rows.last.last

          # FIXME: this should probably be inside the mysql AR adapter?
          value.force_encoding(@conn.client_encoding)

          # The strings in this file are utf-8, so transcode to utf-8
          value.encode!(Encoding::UTF_8)

          assert_equal str, value
        end
      end

      def test_tables_quoting
        @conn.tables(nil, "foo-bar", nil)
        flunk
      rescue => e
        # assertion for *quoted* database properly
        assert_match(/database 'foo-bar'/, e.inspect)
      end

      def test_pk_and_sequence_for
        with_example_table do
          pk, seq = @conn.pk_and_sequence_for('ex')
          assert_equal 'id', pk
          assert_equal @conn.default_sequence_name('ex', 'id'), seq
        end
      end

      def test_pk_and_sequence_for_with_non_standard_primary_key
        with_example_table '`code` INT auto_increment, PRIMARY KEY (`code`)' do
          pk, seq = @conn.pk_and_sequence_for('ex')
          assert_equal 'code', pk
          assert_equal @conn.default_sequence_name('ex', 'code'), seq
        end
      end

      def test_pk_and_sequence_for_with_custom_index_type_pk
        with_example_table '`id` INT auto_increment, PRIMARY KEY USING BTREE (`id`)' do
          pk, seq = @conn.pk_and_sequence_for('ex')
          assert_equal 'id', pk
          assert_equal @conn.default_sequence_name('ex', 'id'), seq
        end
      end

      def test_composite_primary_key
        with_example_table '`id` INT, `number` INT, foo INT, PRIMARY KEY (`id`, `number`)' do
          assert_nil @conn.primary_key('ex')
        end
      end

      def test_tinyint_integer_typecasting
        with_example_table '`status` TINYINT(4)' do
          insert(@conn, { 'status' => 2 }, 'ex')

          result = @conn.exec_query('SELECT status FROM ex')

          assert_equal 2, result.column_types['status'].deserialize(result.last['status'])
        end
      end

      def test_supports_extensions
        assert_not @conn.supports_extensions?, 'does not support extensions'
      end

      def test_respond_to_enable_extension
        assert @conn.respond_to?(:enable_extension)
      end

      def test_respond_to_disable_extension
        assert @conn.respond_to?(:disable_extension)
      end

      private
      def insert(ctx, data, table='ex')
        binds = data.map { |name, value|
          Relation::QueryAttribute.new(name, value, Type::Value.new)
        }
        columns = binds.map(&:name)

        sql = "INSERT INTO #{table} (#{columns.join(", ")})
               VALUES (#{(['?'] * columns.length).join(', ')})"

        ctx.exec_insert(sql, 'SQL', binds)
      end

      def with_example_table(definition = nil, &block)
        definition ||= <<-SQL
          `id` int auto_increment PRIMARY KEY,
          `number` integer,
          `data` varchar(255)
        SQL
        super(@conn, 'ex', definition, &block)
      end
    end
  end
end