|
| 1 | +use strict; |
| 2 | +use warnings; |
| 3 | + |
| 4 | +use Test::More; |
| 5 | +use DBI; |
| 6 | +use Encode; |
| 7 | + |
| 8 | +use vars qw($test_dsn $test_user $test_password); |
| 9 | +use lib 't', '.'; |
| 10 | +require "lib.pl"; |
| 11 | + |
| 12 | +sub for_db { |
| 13 | + my ($mysql_enable_utf8, $value) = @_; # Value is in internal Perl Unicode. |
| 14 | + |
| 15 | + my $ret; |
| 16 | + if ($mysql_enable_utf8 >= 1) { |
| 17 | + $ret = $value; |
| 18 | + } else { |
| 19 | + $ret = Encode::encode('UTF-8', $value); |
| 20 | + } |
| 21 | + |
| 22 | + return $ret; |
| 23 | +} |
| 24 | + |
| 25 | +my $dbh; |
| 26 | +eval { |
| 27 | + $dbh = DBI->connect($test_dsn, $test_user, $test_password, |
| 28 | + { RaiseError => 1, PrintError => 1, AutoCommit => 0 }); |
| 29 | +}; |
| 30 | +if ($@) { |
| 31 | + plan skip_all => "no database connection"; |
| 32 | +} |
| 33 | +$dbh->disconnect(); |
| 34 | + |
| 35 | +plan tests => 11 * 3 + 11 * 2; |
| 36 | + |
| 37 | +# All in internal Perl Unicode |
| 38 | +my $jpnTable = "\N{U+8868}"; # Japanese table |
| 39 | +my $jpnColumn = "\N{U+6027}\N{U+5225}"; # Japanese column - word "gender" |
| 40 | +my $jpnData1 = "\N{U+5c71}\N{U+7530}\N{U+592a}\N{U+90ce}"; # Japanese data - person name |
| 41 | +my $jpnData2 = "\N{U+7537}"; # Japanese daya - word "male" |
| 42 | +my $chiTable = "\N{U+5927}\N{U+99AC}"; # Chinese table XXX MySQL doesn't support utf8mb4 in table names |
| 43 | +my $chiColumn = "\N{U+5C0F}\N{U+96EA}\N{U+4EBA}"; # Chinese column XXX MySQL doesn't support utf8mb4 in column names |
| 44 | +my $chiData1 = "\N{U+30001}"; # Chinese data |
| 45 | +my $chiData2 = "\N{U+30002}"; # Chinese data |
| 46 | + |
| 47 | +foreach my $mysql_enable_utf8 (0, 1, 2) { |
| 48 | + my %utf8_params = (); |
| 49 | + if ($mysql_enable_utf8 == 1) { |
| 50 | + $utf8_params{'mysql_enable_utf8'} = 1; |
| 51 | + diag "Enabled mysql_enable_utf8."; |
| 52 | + } elsif ($mysql_enable_utf8 == 2) { |
| 53 | + $utf8_params{'mysql_enable_utf8mb4'} = 1; |
| 54 | + diag "Enabled mysql_enable_utf8mb4."; |
| 55 | + } else { |
| 56 | + diag "Disabled mysql_enable_utf8."; |
| 57 | + } |
| 58 | + $dbh = DBI->connect($test_dsn, $test_user, $test_password, |
| 59 | + { RaiseError => 1, PrintError => 1, AutoCommit => 1, %utf8_params }); |
| 60 | + |
| 61 | + my $jpnTable_db = for_db($mysql_enable_utf8, $jpnTable); |
| 62 | + my $jpnColumn_db = for_db($mysql_enable_utf8, $jpnColumn); |
| 63 | + my $jpnData1_db = for_db($mysql_enable_utf8, $jpnData1); |
| 64 | + my $jpnData2_db = for_db($mysql_enable_utf8, $jpnData2); |
| 65 | + my ($chiTable_db, $chiColumn_db, $chiData1_db, $chiData2_db); |
| 66 | + if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) { |
| 67 | + $chiTable_db = for_db($mysql_enable_utf8, $chiTable); |
| 68 | + $chiColumn_db = for_db($mysql_enable_utf8, $chiColumn); |
| 69 | + $chiData1_db = for_db($mysql_enable_utf8, $chiData1); |
| 70 | + $chiData2_db = for_db($mysql_enable_utf8, $chiData2); |
| 71 | + } |
| 72 | + |
| 73 | + my $sth; |
| 74 | + my $row; |
| 75 | + |
| 76 | + ok($dbh->do("DROP TABLE IF EXISTS $jpnTable_db"), 'Drop table for Japanese testing.'); |
| 77 | + if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) { |
| 78 | + ok($dbh->do("DROP TABLE IF EXISTS $chiTable_db"), 'Drop table for Chinese testings.'); |
| 79 | + } |
| 80 | + |
| 81 | + ok($dbh->do(<<"END" |
| 82 | +CREATE TABLE IF NOT EXISTS $jpnTable_db ( |
| 83 | + name VARCHAR(20), |
| 84 | + $jpnColumn_db CHAR(1) |
| 85 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
| 86 | +END |
| 87 | + ), 'Create temporay table with Japanese characters.'); |
| 88 | + if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) { |
| 89 | + ok($dbh->do(<<"END" |
| 90 | +CREATE TABLE IF NOT EXISTS $chiTable_db ( |
| 91 | + name VARCHAR(20), |
| 92 | + $chiColumn_db CHAR(1) |
| 93 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
| 94 | +END |
| 95 | + ), 'Create temporay table with Chinese characters.'); |
| 96 | + } |
| 97 | + |
| 98 | + ok($sth = $dbh->prepare("INSERT INTO $jpnTable_db (name, $jpnColumn_db) VALUES (?, ?)"), 'Prepare insert statement with Japanese values.'); |
| 99 | + ok($sth->execute($jpnData1_db, $jpnData2_db), 'Execute insert statement with Japanese values.'); |
| 100 | + if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) { |
| 101 | + ok($sth = $dbh->prepare("INSERT INTO $chiTable_db (name, $chiColumn_db) VALUES (?, ?)"), 'Prepare insert statement with Chinese values.'); |
| 102 | + ok($sth->execute($chiData1_db, $chiData2_db), 'Execute insert statement with Chinese values.'); |
| 103 | + } |
| 104 | + |
| 105 | + ok($sth = $dbh->prepare("SELECT * FROM $jpnTable_db"), 'Prepare select statement with Japanese values.'); |
| 106 | + ok($sth->execute(), 'Execute select statement with Japanese values.'); |
| 107 | + ok($row = $sth->fetchrow_hashref(), 'Fetch hashref with Japanese values.'); |
| 108 | + is($row->{name}, $jpnData1_db, "Japanese value."); |
| 109 | + ok(!exists $row->{$jpnColumn}, 'Not exists Japanese key in internal Perl Unicode.'); # XXX |
| 110 | + is($row->{Encode::encode('UTF-8', $jpnColumn)}, $jpnData2_db, 'Exists Japanese key in octets and value.'); # XXX |
| 111 | + is_deeply($sth->{NAME}, [ 'name', Encode::encode('UTF-8', $jpnColumn) ], 'Statement Japanese column name is in octets.'); # XXX |
| 112 | + is_deeply($sth->{mysql_table}, [ Encode::encode('UTF-8', $jpnTable), Encode::encode('UTF-8', $jpnTable) ], 'Statement Japanese table name is in octets.'); # XXX |
| 113 | + if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) { |
| 114 | + ok($sth = $dbh->prepare("SELECT * FROM $chiTable_db"), 'Prepare select statement with Chinese values.'); |
| 115 | + ok($sth->execute(), 'Execute select statement with Chinese values.'); |
| 116 | + ok($row = $sth->fetchrow_hashref(), 'Fetch hashref with Chinese values.'); |
| 117 | + is($row->{name}, $chiData1_db, "Chinese value."); |
| 118 | + ok(!exists $row->{$chiColumn}, 'Not exists Chinese key in internal Perl Unicode.'); # XXX |
| 119 | + is($row->{Encode::encode('UTF-8', $chiColumn)}, $chiData2_db, 'Exists Chinese key in octets and value.'); # XXX |
| 120 | + is_deeply($sth->{NAME}, [ 'name', Encode::encode('UTF-8', $chiColumn) ], 'Statement Chinese column name is in octets.'); # XXX |
| 121 | + is_deeply($sth->{mysql_table}, [ Encode::encode('UTF-8', $chiTable), Encode::encode('UTF-8', $chiTable) ], 'Statement Chinese table name is in octets.'); # XXX |
| 122 | + } |
| 123 | + |
| 124 | + $sth->finish(); |
| 125 | + $dbh->disconnect(); |
| 126 | +} |
| 127 | +done_testing; |
0 commit comments