Skip to content

Commit e7ee31b

Browse files
Add test for Japanese characters in table definition and errors
The test is taken from DBD::MariaDB and adopted to DBD::mysql. There are two runs of all tests: * one without mysql_enable_utf8 option * one with enabled mysql_enable_utf8 option There are XXX comments for situations which not follow mysql_enable_utf8 option.
1 parent f9eab6a commit e7ee31b

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

MANIFEST

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ t/51bind_type_guessing.t
5353
t/52comment.t
5454
t/53comment.t
5555
t/55utf8.t
56+
t/55utf8_jp.t
5657
t/55utf8mb4.t
5758
t/56connattr.t
5859
t/57trackgtid.t

t/55utf8_jp.t

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
use strict;
2+
use warnings;
3+
4+
use Test::More;
5+
use DBI;
6+
use Encode;
7+
8+
use constant STRICT_DECODE => 1;
9+
10+
use vars qw($test_dsn $test_user $test_password);
11+
use lib 't', '.';
12+
require "lib.pl";
13+
14+
sub skip_rt_102404 {
15+
skip "(Perl 5.13.1 and DBI 1.635) or DBI 1.639 is required due to bug RT 102404", $_[0] unless ($] >= 5.013001 and eval { DBI->VERSION(1.635) }) or eval { DBI->VERSION(1.639) };
16+
}
17+
18+
sub for_db {
19+
my ($mysql_enable_utf8, $value) = @_; # Value is in internal Perl Unicode.
20+
21+
my $ret;
22+
if ($mysql_enable_utf8 == 1) {
23+
$ret = $value;
24+
} else {
25+
$ret = Encode::encode('UTF-8', $value);
26+
}
27+
28+
return $ret;
29+
}
30+
31+
my $dbh;
32+
my $test_dsn = 'DBI:mysql:database=test';
33+
my $test_user = 'skim';
34+
my $test_password = 'IecohPh6';
35+
eval {$dbh= DBI->connect($test_dsn, $test_user, $test_password,
36+
{ RaiseError => 1, PrintError => 1, AutoCommit => 0 });};
37+
if ($@) {
38+
plan skip_all => "no database connection";
39+
}
40+
$dbh->disconnect();
41+
42+
plan tests => 22 * 2;
43+
44+
# All in internal Perl Unicode
45+
my $jpnTable = "\N{U+8868}"; # Japanese table
46+
my $jpnGender = "\N{U+6027}\N{U+5225}"; # Japanese word "gender"
47+
my $jpnYamadaTaro = "\N{U+5c71}\N{U+7530}\N{U+592a}\N{U+90ce}"; # a Japanese person name
48+
my $jpnMale = "\N{U+7537}"; # Japanese word "male"
49+
my $jpnErr = qr/\x{4ed8}\x{8fd1}.*\x{884c}\x{76ee}/; # Use \x{...} instead \N{U+...} due to Perl 5.12.0 bug
50+
51+
foreach my $mysql_enable_utf8 (0, 1) {
52+
$dbh = DBI->connect($test_dsn, $test_user, $test_password,
53+
{ RaiseError => 1, PrintError => 1, AutoCommit => 0, $mysql_enable_utf8 ? (mysql_enable_utf8 => 1) : () });
54+
if ($mysql_enable_utf8) {
55+
diag "Enabled mysql_enable_utf8.";
56+
} else {
57+
diag "Disabled mysql_enable_utf8.";
58+
}
59+
60+
eval {
61+
$dbh->do("SET lc_messages = 'ja_JP'");
62+
} or do {
63+
$dbh->disconnect();
64+
plan skip_all => "Server lc_messages ja_JP are needed for this test";
65+
};
66+
67+
my $jpnTable_db = for_db($mysql_enable_utf8, $jpnTable);
68+
my $jpnGender_db = for_db($mysql_enable_utf8, $jpnGender);
69+
my $jpnYamadaTaro_db = for_db($mysql_enable_utf8, $jpnYamadaTaro);
70+
my $jpnMale_db = for_db($mysql_enable_utf8, $jpnMale);
71+
72+
my $sth;
73+
my $row;
74+
75+
ok($dbh->do("DROP TABLE IF EXISTS $jpnTable_db"), 'Drop table.');
76+
77+
ok($dbh->do(<<"END"
78+
CREATE TEMPORARY TABLE $jpnTable_db (
79+
name VARCHAR(20),
80+
$jpnGender_db CHAR(1)
81+
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
82+
END
83+
), 'Create temporay table with Japanese characters.');
84+
85+
ok($sth = $dbh->prepare("INSERT INTO $jpnTable_db (name, $jpnGender_db) VALUES (?, ?)"), 'Prepare insert statement.');
86+
ok($sth->execute($jpnYamadaTaro_db, $jpnMale_db), 'Execute insert statement with Japanese values.');
87+
88+
ok($sth = $dbh->prepare("SELECT * FROM $jpnTable_db"), 'Prepare select statement.');
89+
ok($sth->execute(), 'Execute select statement.');
90+
ok($row = $sth->fetchrow_hashref(), 'Fetch hashref.');
91+
92+
is($row->{name}, $jpnYamadaTaro_db, "Value of 'name'.");
93+
ok(!exists $row->{$jpnGender}, 'Not exists key in internal Perl Unicode.'); # XXX
94+
is($row->{Encode::encode('UTF-8', $jpnGender)}, $jpnMale_db, 'Exists key in octets and value.'); # XXX
95+
96+
is_deeply($sth->{NAME}, [ 'name', Encode::encode('UTF-8', $jpnGender) ], 'Statement column name is in octets.'); # XXX
97+
is_deeply($sth->{mysql_table}, [ Encode::encode('UTF-8', $jpnTable), Encode::encode('UTF-8', $jpnTable) ], 'Statement table name is in octets.'); # XXX
98+
99+
my $warn;
100+
my $dieerr;
101+
my $dbierr;
102+
my $failed;
103+
104+
$failed = 0;
105+
$dieerr = undef;
106+
$dbierr = undef;
107+
$dbh->{HandleError} = sub { $dbierr = $_[0]; die $_[0]; };
108+
eval {
109+
$sth = $dbh->prepare("foo");
110+
$sth->execute();
111+
1;
112+
} or do {
113+
$dieerr = $@;
114+
$failed = 1;
115+
};
116+
$dbh->{HandleError} = undef;
117+
118+
ok($failed, 'Execution of bad statement is failing (HandleError version).');
119+
like(Encode::decode('UTF-8', $dbierr), $jpnErr, 'DBI error is in octets (HandleError version).'); # XXX
120+
like(Encode::decode('UTF-8', $DBI::errstr), $jpnErr, 'DBI::errstr is in octets (HandleError version).'); # XXX
121+
like(Encode::decode('UTF-8', $dbh->errstr), $jpnErr, 'DBI handler errstr() method is in octets (HandleError version).'); # XXX
122+
123+
SKIP : {
124+
skip_rt_102404 1;
125+
like(Encode::decode('UTF-8', $dieerr), $jpnErr, 'Error from eval is in octets (HandleError version).');
126+
}
127+
128+
$failed = 0;
129+
$warn = undef;
130+
$dieerr = undef;
131+
$dbh->{PrintError} = 1;
132+
$SIG{__WARN__} = sub { $warn = $_[0] };
133+
eval {
134+
$sth = $dbh->prepare("foo");
135+
$sth->execute();
136+
1;
137+
} or do {
138+
$dieerr = $@;
139+
$failed = 1;
140+
};
141+
$dbh->{PrintError} = 0;
142+
$SIG{__WARN__} = 'DEFAULT';
143+
144+
ok($failed, 'Execution of bad statement is failing (PrintError version).');
145+
like(Encode::decode('UTF-8', $DBI::errstr), $jpnErr, 'DBI::errstr is in octets (PrintError version).'); # XXX
146+
like(Encode::decode('UTF-8', $dbh->errstr), $jpnErr, 'DBI handler errstr() method is in octets (PrintError version).'); # XXX
147+
148+
SKIP : {
149+
skip_rt_102404 2;
150+
like(Encode::decode('UTF-8', $warn), $jpnErr, 'Warning is in octets (PrintError version).'); # XXX
151+
like(Encode::decode('UTF-8', $dieerr), $jpnErr, 'Error from eval is in octets (PrintError version).'); # XXX
152+
}
153+
154+
$dbh->disconnect();
155+
}
156+
done_testing;

0 commit comments

Comments
 (0)