generic comments mechanism, MySQL specific support
[dbsrgits/DBIx-Class-Schema-Loader.git] / t / 10_02mysql_common.t
1 use strict;
2 use File::Slurp qw(slurp);
3 use Test::More;
4 use lib qw(t/lib);
5 use dbixcsl_common_tests;
6 use utf8;
7 use Encode 'decode';
8
9 my $dsn         = $ENV{DBICTEST_MYSQL_DSN} || '';
10 my $user        = $ENV{DBICTEST_MYSQL_USER} || '';
11 my $password    = $ENV{DBICTEST_MYSQL_PASS} || '';
12 my $test_innodb = $ENV{DBICTEST_MYSQL_INNODB} || 0;
13
14 my $skip_rels_msg = 'You need to set the DBICTEST_MYSQL_INNODB environment variable to test relationships.';
15
16 my $innodb = $test_innodb ? q{Engine=InnoDB} : '';
17
18 my $tester = dbixcsl_common_tests->new(
19     vendor           => 'Mysql',
20     auto_inc_pk      => 'INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT',
21     innodb           => $innodb,
22     dsn              => $dsn,
23     user             => $user,
24     password         => $password,
25     connect_info_opts=> { on_connect_call => 'set_strict_mode' },
26     loader_options   => { preserve_case => 1 },
27     skip_rels        => $test_innodb ? 0 : $skip_rels_msg,
28     quote_char       => '`',
29     no_inline_rels   => 1,
30     no_implicit_rels => 1,
31     data_types  => {
32         # http://dev.mysql.com/doc/refman/5.5/en/data-type-overview.html
33         # Numeric Types
34         'bit'         => { data_type => 'bit', size => 1 },
35         'bit(11)'     => { data_type => 'bit', size => 11 },
36
37         'bool'        => { data_type => 'tinyint' },
38         'boolean'     => { data_type => 'tinyint' },
39         'tinyint'     => { data_type => 'tinyint' },
40         'tinyint unsigned'
41                       => { data_type => 'tinyint',   extra => { unsigned => 1 } },
42         'smallint'    => { data_type => 'smallint' },
43         'smallint unsigned'
44                       => { data_type => 'smallint',  extra => { unsigned => 1 } },
45         'mediumint'   => { data_type => 'mediumint' },
46         'mediumint unsigned'
47                       => { data_type => 'mediumint', extra => { unsigned => 1 } },
48         'int'         => { data_type => 'integer' },
49         'int unsigned'
50                       => { data_type => 'integer',   extra => { unsigned => 1 } },
51         'integer'     => { data_type => 'integer' },
52         'integer unsigned'
53                       => { data_type => 'integer',   extra => { unsigned => 1 } },
54         'integer not null'
55                       => { data_type => 'integer' },
56         'bigint'      => { data_type => 'bigint' },
57         'bigint unsigned'
58                       => { data_type => 'bigint',    extra => { unsigned => 1 } },
59
60         'serial'      => { data_type => 'bigint', is_auto_increment => 1, extra => { unsigned => 1 } },
61
62         'float'       => { data_type => 'float' },
63         'float unsigned'
64                       => { data_type => 'float',     extra => { unsigned => 1 } },
65         'double'      => { data_type => 'double precision' },
66         'double unsigned'
67                       => { data_type => 'double precision', extra => { unsigned => 1 } },
68         'double precision' =>
69                          { data_type => 'double precision' },
70         'double precision unsigned'
71                       => { data_type => 'double precision', extra => { unsigned => 1 } },
72
73         # we skip 'real' because its alias depends on the 'REAL AS FLOAT' setting
74
75         'float(2)'    => { data_type => 'float' },
76         'float(24)'   => { data_type => 'float' },
77         'float(25)'   => { data_type => 'double precision' },
78
79         'float(3,3)'  => { data_type => 'float', size => [3,3] },
80         'double(3,3)' => { data_type => 'double precision', size => [3,3] },
81         'double precision(3,3)'
82                       => { data_type => 'double precision', size => [3,3] },
83
84         'decimal'     => { data_type => 'decimal' },
85         'decimal unsigned'
86                       => { data_type => 'decimal', extra => { unsigned => 1 } },
87         'dec'         => { data_type => 'decimal' },
88         'numeric'     => { data_type => 'decimal' },
89         'fixed'       => { data_type => 'decimal' },
90
91         'decimal(3)'   => { data_type => 'decimal', size => [3,0] },
92
93         'decimal(3,3)' => { data_type => 'decimal', size => [3,3] },
94         'dec(3,3)'     => { data_type => 'decimal', size => [3,3] },
95         'numeric(3,3)' => { data_type => 'decimal', size => [3,3] },
96         'fixed(3,3)'   => { data_type => 'decimal', size => [3,3] },
97
98         # Date and Time Types
99         'date'        => { data_type => 'date', datetime_undef_if_invalid => 1 },
100         'datetime'    => { data_type => 'datetime', datetime_undef_if_invalid => 1 },
101         'timestamp default current_timestamp'
102                       => { data_type => 'timestamp', default_value => \'current_timestamp', datetime_undef_if_invalid => 1 },
103         'time'        => { data_type => 'time' },
104         'year'        => { data_type => 'year' },
105         'year(4)'     => { data_type => 'year' },
106         'year(2)'     => { data_type => 'year', size => 2 },
107
108         # String Types
109         'char'         => { data_type => 'char',      size => 1  },
110         'char(11)'     => { data_type => 'char',      size => 11 },
111         'varchar(20)'  => { data_type => 'varchar',   size => 20 },
112         'binary'       => { data_type => 'binary',    size => 1  },
113         'binary(11)'   => { data_type => 'binary',    size => 11 },
114         'varbinary(20)'=> { data_type => 'varbinary', size => 20 },
115
116         'tinyblob'    => { data_type => 'tinyblob' },
117         'tinytext'    => { data_type => 'tinytext' },
118         'blob'        => { data_type => 'blob' },
119
120         # text(M) types will map to the appropriate type, length is not stored
121         'text'        => { data_type => 'text' },
122
123         'mediumblob'  => { data_type => 'mediumblob' },
124         'mediumtext'  => { data_type => 'mediumtext' },
125         'longblob'    => { data_type => 'longblob' },
126         'longtext'    => { data_type => 'longtext' },
127
128         "enum('foo','bar','baz')"
129                       => { data_type => 'enum', extra => { list => [qw/foo bar baz/] } },
130         "enum('foo \\'bar\\' baz', 'foo ''bar'' quux')"
131                       => { data_type => 'enum', extra => { list => [q{foo 'bar' baz}, q{foo 'bar' quux}] } },
132         "set('foo \\'bar\\' baz', 'foo ''bar'' quux')"
133                       => { data_type => 'set', extra => { list => [q{foo 'bar' baz}, q{foo 'bar' quux}] } },
134         "set('foo','bar','baz')"
135                       => { data_type => 'set',  extra => { list => [qw/foo bar baz/] } },
136
137         # RT#68717
138         "enum('11,10 (<500)/0 DUN','4,90 (<120)/0 EUR') NOT NULL default '11,10 (<500)/0 DUN'"
139                       => { data_type => 'enum', extra => { list => ['11,10 (<500)/0 DUN', '4,90 (<120)/0 EUR'] }, default_value => '11,10 (<500)/0 DUN' },
140         "set('11_10 (<500)/0 DUN','4_90 (<120)/0 EUR') NOT NULL default '11_10 (<500)/0 DUN'"
141                       => { data_type => 'set', extra => { list => ['11_10 (<500)/0 DUN', '4_90 (<120)/0 EUR'] }, default_value => '11_10 (<500)/0 DUN' },
142         "enum('19,90 (<500)/0 EUR','4,90 (<120)/0 EUR','7,90 (<200)/0 CHF','300 (<6000)/0 CZK','4,90 (<100)/0 EUR','39 (<900)/0 DKK','299 (<5000)/0 EEK','9,90 (<250)/0 EUR','3,90 (<100)/0 GBP','3000 (<70000)/0 HUF','4000 (<70000)/0 JPY','13,90 (<200)/0 LVL','99 (<2500)/0 NOK','39 (<1000)/0 PLN','1000 (<20000)/0 RUB','49 (<2500)/0 SEK','29 (<600)/0 USD','19,90 (<600)/0 EUR','0 EUR','0 CHF') NOT NULL default '19,90 (<500)/0 EUR'"
143                       => { data_type => 'enum', extra => { list => ['19,90 (<500)/0 EUR','4,90 (<120)/0 EUR','7,90 (<200)/0 CHF','300 (<6000)/0 CZK','4,90 (<100)/0 EUR','39 (<900)/0 DKK','299 (<5000)/0 EEK','9,90 (<250)/0 EUR','3,90 (<100)/0 GBP','3000 (<70000)/0 HUF','4000 (<70000)/0 JPY','13,90 (<200)/0 LVL','99 (<2500)/0 NOK','39 (<1000)/0 PLN','1000 (<20000)/0 RUB','49 (<2500)/0 SEK','29 (<600)/0 USD','19,90 (<600)/0 EUR','0 EUR','0 CHF'] }, default_value => '19,90 (<500)/0 EUR' },
144     },
145     extra => {
146         create => [
147             qq{
148                 CREATE TABLE `mysql_loader-test1` (
149                     id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'The\15\12Column',
150                     value varchar(100)
151                 ) $innodb COMMENT 'The\15\12Table'
152             },
153             q{
154                 CREATE VIEW mysql_loader_test2 AS SELECT * FROM `mysql_loader-test1`
155             },
156             # RT#68717
157             qq{
158                 CREATE TABLE `mysql_loader_test3` (
159                   `ISO3_code` char(3) NOT NULL default '',
160                   `lang_pref` enum('de','en','fr','nl','dk','es','se') NOT NULL,
161                   `vat` decimal(4,2) default '16.00',
162                   `price_group` enum('EUR_DEFAULT','GBP_GBR','EUR_AUT_BEL_FRA_IRL_NLD','EUR_DNK_SWE','EUR_AUT','EUR_BEL','EUR_FIN','EUR_FRA','EUR_IRL','EUR_NLD','EUR_DNK','EUR_POL','EUR_PRT','EUR_SWE','CHF_CHE','DKK_DNK','SEK_SWE','NOK_NOR','USD_USA','CZK_CZE','PLN_POL','RUB_RUS','HUF_HUN','SKK_SVK','JPY_JPN','LVL_LVA','ROL_ROU','EEK_EST') NOT NULL default 'EUR_DEFAULT',
163                   `del_group` enum('19,90 (<500)/0 EUR','4,90 (<120)/0 EUR','7,90 (<200)/0 CHF','300 (<6000)/0 CZK','4,90 (<100)/0 EUR','39 (<900)/0 DKK','299 (<5000)/0 EEK','9,90 (<250)/0 EUR','3,90 (<100)/0 GBP','3000 (<70000)/0 HUF','4000 (<70000)/0 JPY','13,90 (<200)/0 LVL','99 (<2500)/0 NOK','39 (<1000)/0 PLN','1000 (<20000)/0 RUB','49 (<2500)/0 SEK','29 (<600)/0 USD','19,90 (<600)/0 EUR','0 EUR','0 CHF') NOT NULL default '19,90 (<500)/0 EUR',
164                   `express_del_group` enum('NO','39 EUR (EXPRESS)','59 EUR (EXPRESS)','79 CHF (EXPRESS)','49 EUR (EXPRESS)','990 CZK (EXPRESS)','19,9 EUR (EXPRESS)','290 DKK (EXPRESS)','990 EEK (EXPRESS)','39 GBP (EXPRESS)','14000 HUF (EXPRESS)','49 LVL (EXPRESS)','590 NOK (EXPRESS)','250 PLN (EXPRESS)','490 SEK (EXPRESS)') NOT NULL default 'NO',
165                   `pmethod` varchar(255) NOT NULL default 'VISA,MASTER',
166                   `delivery_time` varchar(5) default NULL,
167                   `express_delivery_time` varchar(5) default NULL,
168                   `eu` int(1) default '0',
169                   `cod_costs` varchar(12) default NULL,
170                   PRIMARY KEY (`ISO3_code`)
171                 ) $innodb
172             },
173         ],
174         pre_drop_ddl => [ 'DROP VIEW mysql_loader_test2', ],
175         drop => [ 'mysql_loader-test1', 'mysql_loader_test3' ],
176         count => 5,
177         run => sub {
178             my ($schema, $monikers, $classes) = @_;
179
180             is $monikers->{'mysql_loader-test1'}, 'MysqlLoaderTest1',
181                 'table with dash correctly monikerized';
182
183             my $rsrc = $schema->source('MysqlLoaderTest2');
184
185             is $rsrc->column_info('value')->{data_type}, 'varchar',
186                 'view introspected successfully';
187
188             $rsrc = $schema->source('MysqlLoaderTest3');
189
190             is_deeply $rsrc->column_info('del_group')->{extra}{list}, ['19,90 (<500)/0 EUR','4,90 (<120)/0 EUR','7,90 (<200)/0 CHF','300 (<6000)/0 CZK','4,90 (<100)/0 EUR','39 (<900)/0 DKK','299 (<5000)/0 EEK','9,90 (<250)/0 EUR','3,90 (<100)/0 GBP','3000 (<70000)/0 HUF','4000 (<70000)/0 JPY','13,90 (<200)/0 LVL','99 (<2500)/0 NOK','39 (<1000)/0 PLN','1000 (<20000)/0 RUB','49 (<2500)/0 SEK','29 (<600)/0 USD','19,90 (<600)/0 EUR','0 EUR','0 CHF'],
191                 'hairy enum introspected correctly';
192
193             my $class    = $classes->{'mysql_loader-test1'};
194             my $filename = $schema->_loader->get_dump_filename($class);
195
196             my $code = decode('UTF-8', scalar slurp $filename);
197
198             like $code, qr/^=head1 NAME\n\n^$class - The\nTable\n\n^=cut\n/m,
199                 'table comment';
200
201             like $code, qr/^=head2 id\n\n(.+:.+\n)+\nThe\nColumn\n\n/m,
202                 'column comment and attrs';
203
204         },
205     },
206 );
207
208 if( !$dsn || !$user ) {
209     $tester->skip_tests('You need to set the DBICTEST_MYSQL_DSN, DBICTEST_MYSQL_USER, and DBICTEST_MYSQL_PASS environment variables');
210 }
211 else {
212     diag $skip_rels_msg if not $test_innodb;
213     $tester->run_tests();
214 }
215
216 # vim:et sts=4 sw=4 tw=0: