aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
blob: a2c933d96aa845b2e53a5e1058bd4f0fed406f74 (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
# encoding: utf-8

require "cases/helper"

module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapterTest < ActiveRecord::TestCase
      def setup
        @conn = ActiveRecord::Base.connection
        @conn.exec_query('drop table if exists ex')
        @conn.exec_query(<<-eosql)
          CREATE TABLE `ex` (
            `id` int(11) auto_increment PRIMARY KEY,
            `number` integer,
            `data` varchar(255))
        eosql
      end

      def test_valid_column
        column = @conn.columns('ex').find { |col| col.name == 'id' }
        assert @conn.valid_type?(column.type)
      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
        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

      def test_exec_insert_string
        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

      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
        pk, seq = @conn.pk_and_sequence_for('ex')
        assert_equal 'id', pk
        assert_equal @conn.default_sequence_name('ex', 'id'), seq
      end

      def test_pk_and_sequence_for_with_non_standard_primary_key
        @conn.exec_query('drop table if exists ex_with_non_standard_pk')
        @conn.exec_query(<<-eosql)
          CREATE TABLE `ex_with_non_standard_pk` (
            `code` INT(11) auto_increment,
             PRIMARY KEY  (`code`))
        eosql
        pk, seq = @conn.pk_and_sequence_for('ex_with_non_standard_pk')
        assert_equal 'code', pk
        assert_equal @conn.default_sequence_name('ex_with_non_standard_pk', 'code'), seq
      end

      def test_pk_and_sequence_for_with_custom_index_type_pk
        @conn.exec_query('drop table if exists ex_with_custom_index_type_pk')
        @conn.exec_query(<<-eosql)
          CREATE TABLE `ex_with_custom_index_type_pk` (
            `id` INT(11) auto_increment,
             PRIMARY KEY  USING BTREE (`id`))
        eosql
        pk, seq = @conn.pk_and_sequence_for('ex_with_custom_index_type_pk')
        assert_equal 'id', pk
        assert_equal @conn.default_sequence_name('ex_with_custom_index_type_pk', 'id'), seq
      end

      def test_tinyint_integer_typecasting
        @conn.exec_query('drop table if exists ex_with_non_boolean_tinyint_column')
        @conn.exec_query(<<-eosql)
          CREATE TABLE `ex_with_non_boolean_tinyint_column` (
            `status` TINYINT(4))
        eosql
        insert(@conn, { 'status' => 2 }, 'ex_with_non_boolean_tinyint_column')

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

        assert_equal 2, result.column_types['status'].type_cast(result.last['status'])
      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|
          [ctx.columns(table).find { |x| x.name == name }, value]
        }
        columns = binds.map(&:first).map(&:name)

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

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