Order of schema objects properties in XML changed to something more sensible
[dbsrgits/SQL-Translator.git] / t / 17sqlfxml-producer.t
1 #!/usr/bin/perl -w 
2 # vim:filetype=perl
3
4 # Before `make install' is performed this script should be runnable with
5 # `make test'. After `make install' it should work as `perl test.pl'
6
7 local $^W = 0;
8
9 use strict;
10 use Test::More;
11 use Test::Exception;
12
13 use Data::Dumper;
14 my %opt;
15 BEGIN { map { $opt{$_}=1 if s/^-// } @ARGV; }
16 use constant DEBUG => (exists $opt{d} ? 1 : 0);
17 use constant TRACE => (exists $opt{t} ? 1 : 0);
18
19 use FindBin qw/$Bin/;
20
21 my $file = "$Bin/data/mysql/sqlfxml-producer-basic.sql";
22
23
24 # Testing 1,2,3,4...
25 #=============================================================================
26
27 eval { require XML::Writer; };
28 if ($@ && $@ =~ m!locate XML::Writer.pm in!) {
29     plan skip_all => "You need XML::Writer to use XML::SQLFairy.";
30 }
31 eval { require Test::Differences; };
32 if ($@ && $@ =~ m!locate Test/Differences.pm in!) {
33     plan skip_all => "You need Test::Differences for this test.";
34 }
35 use Test::Differences;
36 plan tests => 18;
37
38 use SQL::Translator;
39 use SQL::Translator::Producer::XML::SQLFairy;
40
41 #
42 # emit_empty_tags => 0
43 #
44 {
45 my ($obj,$ans,$xml);
46
47 $ans = <<EOXML;
48 <sqlt:schema xmlns:sqlt="http://sqlfairy.sourceforge.net/sqlfairy.xml">
49   <sqlt:name></sqlt:name>
50   <sqlt:database></sqlt:database>
51   <sqlt:table>
52     <sqlt:name>Basic</sqlt:name>
53     <sqlt:order>1</sqlt:order>
54     <sqlt:fields>
55       <sqlt:field>
56         <sqlt:name>id</sqlt:name>
57         <sqlt:data_type>integer</sqlt:data_type>
58         <sqlt:size>10</sqlt:size>
59         <sqlt:is_nullable>0</sqlt:is_nullable>
60         <sqlt:is_auto_increment>1</sqlt:is_auto_increment>
61         <sqlt:is_primary_key>1</sqlt:is_primary_key>
62         <sqlt:is_foreign_key>0</sqlt:is_foreign_key>
63         <sqlt:comments>comment on id field</sqlt:comments>
64         <sqlt:order>1</sqlt:order>
65       </sqlt:field>
66       <sqlt:field>
67         <sqlt:name>title</sqlt:name>
68         <sqlt:data_type>varchar</sqlt:data_type>
69         <sqlt:size>100</sqlt:size>
70         <sqlt:is_nullable>0</sqlt:is_nullable>
71         <sqlt:default_value>hello</sqlt:default_value>
72         <sqlt:is_auto_increment>0</sqlt:is_auto_increment>
73         <sqlt:is_primary_key>0</sqlt:is_primary_key>
74         <sqlt:is_foreign_key>0</sqlt:is_foreign_key>
75         <sqlt:comments></sqlt:comments>
76         <sqlt:order>2</sqlt:order>
77       </sqlt:field>
78       <sqlt:field>
79         <sqlt:name>description</sqlt:name>
80         <sqlt:data_type>text</sqlt:data_type>
81         <sqlt:size>65535</sqlt:size>
82         <sqlt:is_nullable>1</sqlt:is_nullable>
83         <sqlt:default_value></sqlt:default_value>
84         <sqlt:is_auto_increment>0</sqlt:is_auto_increment>
85         <sqlt:is_primary_key>0</sqlt:is_primary_key>
86         <sqlt:is_foreign_key>0</sqlt:is_foreign_key>
87         <sqlt:comments></sqlt:comments>
88         <sqlt:order>3</sqlt:order>
89       </sqlt:field>
90       <sqlt:field>
91         <sqlt:name>email</sqlt:name>
92         <sqlt:data_type>varchar</sqlt:data_type>
93         <sqlt:size>255</sqlt:size>
94         <sqlt:is_nullable>1</sqlt:is_nullable>
95         <sqlt:is_auto_increment>0</sqlt:is_auto_increment>
96         <sqlt:is_primary_key>0</sqlt:is_primary_key>
97         <sqlt:is_foreign_key>0</sqlt:is_foreign_key>
98         <sqlt:comments></sqlt:comments>
99         <sqlt:order>4</sqlt:order>
100       </sqlt:field>
101     </sqlt:fields>
102     <sqlt:indices>
103       <sqlt:index>
104         <sqlt:name>titleindex</sqlt:name>
105         <sqlt:type>NORMAL</sqlt:type>
106         <sqlt:fields>title</sqlt:fields>
107         <sqlt:options></sqlt:options>
108       </sqlt:index>
109     </sqlt:indices>
110     <sqlt:constraints>
111       <sqlt:constraint>
112         <sqlt:name></sqlt:name>
113         <sqlt:type>PRIMARY KEY</sqlt:type>
114         <sqlt:fields>id</sqlt:fields>
115         <sqlt:reference_table></sqlt:reference_table>
116         <sqlt:on_delete></sqlt:on_delete>
117         <sqlt:on_update></sqlt:on_update>
118         <sqlt:match_type></sqlt:match_type>
119         <sqlt:expression></sqlt:expression>
120         <sqlt:options></sqlt:options>
121         <sqlt:deferrable>1</sqlt:deferrable>
122       </sqlt:constraint>
123       <sqlt:constraint>
124         <sqlt:name></sqlt:name>
125         <sqlt:type>UNIQUE</sqlt:type>
126         <sqlt:fields>email</sqlt:fields>
127         <sqlt:reference_table></sqlt:reference_table>
128         <sqlt:on_delete></sqlt:on_delete>
129         <sqlt:on_update></sqlt:on_update>
130         <sqlt:match_type></sqlt:match_type>
131         <sqlt:expression></sqlt:expression>
132         <sqlt:options></sqlt:options>
133         <sqlt:deferrable>1</sqlt:deferrable>
134       </sqlt:constraint>
135     </sqlt:constraints>
136   </sqlt:table>
137 </sqlt:schema>
138 EOXML
139
140 $obj = SQL::Translator->new(
141     debug          => DEBUG,
142     trace          => TRACE,
143     show_warnings  => 1,
144     add_drop_table => 1,
145     from           => 'MySQL',
146     to             => 'XML-SQLFairy',
147 );
148 lives_ok {$xml = $obj->translate($file);} "Translate (emit_empty_tags=>0) ran";
149 ok("$xml" ne ""                             ,"Produced something!");
150 print "XML:\n$xml" if DEBUG;
151 # Strip sqlf header with its variable date so we diff safely
152 $xml =~ s/^([^\n]*\n){7}//m; 
153 eq_or_diff $xml, $ans                       ,"XML looks right";
154
155 } # end emit_empty_tags=>0
156
157 #
158 # emit_empty_tags => 1
159 #
160 {
161 my ($obj,$ans,$xml);
162
163 $ans = <<EOXML;
164 <sqlt:schema xmlns:sqlt="http://sqlfairy.sourceforge.net/sqlfairy.xml">
165   <sqlt:name></sqlt:name>
166   <sqlt:database></sqlt:database>
167   <sqlt:table>
168     <sqlt:name>Basic</sqlt:name>
169     <sqlt:order>2</sqlt:order>
170     <sqlt:fields>
171       <sqlt:field>
172         <sqlt:name>id</sqlt:name>
173         <sqlt:data_type>integer</sqlt:data_type>
174         <sqlt:size>10</sqlt:size>
175         <sqlt:is_nullable>0</sqlt:is_nullable>
176         <sqlt:default_value></sqlt:default_value>
177         <sqlt:is_auto_increment>1</sqlt:is_auto_increment>
178         <sqlt:is_primary_key>1</sqlt:is_primary_key>
179         <sqlt:is_foreign_key>0</sqlt:is_foreign_key>
180         <sqlt:comments>comment on id field</sqlt:comments>
181         <sqlt:order>5</sqlt:order>
182       </sqlt:field>
183       <sqlt:field>
184         <sqlt:name>title</sqlt:name>
185         <sqlt:data_type>varchar</sqlt:data_type>
186         <sqlt:size>100</sqlt:size>
187         <sqlt:is_nullable>0</sqlt:is_nullable>
188         <sqlt:default_value>hello</sqlt:default_value>
189         <sqlt:is_auto_increment>0</sqlt:is_auto_increment>
190         <sqlt:is_primary_key>0</sqlt:is_primary_key>
191         <sqlt:is_foreign_key>0</sqlt:is_foreign_key>
192         <sqlt:comments></sqlt:comments>
193         <sqlt:order>6</sqlt:order>
194       </sqlt:field>
195       <sqlt:field>
196         <sqlt:name>description</sqlt:name>
197         <sqlt:data_type>text</sqlt:data_type>
198         <sqlt:size>65535</sqlt:size>
199         <sqlt:is_nullable>1</sqlt:is_nullable>
200         <sqlt:default_value></sqlt:default_value>
201         <sqlt:is_auto_increment>0</sqlt:is_auto_increment>
202         <sqlt:is_primary_key>0</sqlt:is_primary_key>
203         <sqlt:is_foreign_key>0</sqlt:is_foreign_key>
204         <sqlt:comments></sqlt:comments>
205         <sqlt:order>7</sqlt:order>
206       </sqlt:field>
207       <sqlt:field>
208         <sqlt:name>email</sqlt:name>
209         <sqlt:data_type>varchar</sqlt:data_type>
210         <sqlt:size>255</sqlt:size>
211         <sqlt:is_nullable>1</sqlt:is_nullable>
212         <sqlt:default_value></sqlt:default_value>
213         <sqlt:is_auto_increment>0</sqlt:is_auto_increment>
214         <sqlt:is_primary_key>0</sqlt:is_primary_key>
215         <sqlt:is_foreign_key>0</sqlt:is_foreign_key>
216         <sqlt:comments></sqlt:comments>
217         <sqlt:order>8</sqlt:order>
218       </sqlt:field>
219     </sqlt:fields>
220     <sqlt:indices>
221       <sqlt:index>
222         <sqlt:name>titleindex</sqlt:name>
223         <sqlt:type>NORMAL</sqlt:type>
224         <sqlt:fields>title</sqlt:fields>
225         <sqlt:options></sqlt:options>
226       </sqlt:index>
227     </sqlt:indices>
228     <sqlt:constraints>
229       <sqlt:constraint>
230         <sqlt:name></sqlt:name>
231         <sqlt:type>PRIMARY KEY</sqlt:type>
232         <sqlt:fields>id</sqlt:fields>
233         <sqlt:reference_table></sqlt:reference_table>
234         <sqlt:reference_fields></sqlt:reference_fields>
235         <sqlt:on_delete></sqlt:on_delete>
236         <sqlt:on_update></sqlt:on_update>
237         <sqlt:match_type></sqlt:match_type>
238         <sqlt:expression></sqlt:expression>
239         <sqlt:options></sqlt:options>
240         <sqlt:deferrable>1</sqlt:deferrable>
241       </sqlt:constraint>
242       <sqlt:constraint>
243         <sqlt:name></sqlt:name>
244         <sqlt:type>UNIQUE</sqlt:type>
245         <sqlt:fields>email</sqlt:fields>
246         <sqlt:reference_table></sqlt:reference_table>
247         <sqlt:reference_fields></sqlt:reference_fields>
248         <sqlt:on_delete></sqlt:on_delete>
249         <sqlt:on_update></sqlt:on_update>
250         <sqlt:match_type></sqlt:match_type>
251         <sqlt:expression></sqlt:expression>
252         <sqlt:options></sqlt:options>
253         <sqlt:deferrable>1</sqlt:deferrable>
254       </sqlt:constraint>
255     </sqlt:constraints>
256   </sqlt:table>
257 </sqlt:schema>
258 EOXML
259
260 $obj = SQL::Translator->new(
261     debug          => DEBUG,
262     trace          => TRACE,
263     show_warnings  => 1,
264     add_drop_table => 1,
265     from           => 'MySQL',
266     to             => 'XML-SQLFairy',
267     producer_args  => { emit_empty_tags => 1 },
268 );
269 lives_ok { $xml=$obj->translate($file); } "Translate (emit_empty_tags=>1) ran";
270 ok("$xml" ne ""                             ,"Produced something!");
271 print "XML emit_empty_tags=>1:\n$xml" if DEBUG;
272 # Strip sqlf header with its variable date so we diff safely
273 $xml =~ s/^([^\n]*\n){7}//m; 
274 eq_or_diff $xml, $ans                       ,"XML looks right";
275
276 } # end emit_empty_tags => 1
277
278 #
279 # attrib_values => 1
280 #
281 {
282 my ($obj,$ans,$xml);
283
284 $ans = <<EOXML;
285 <sqlt:schema name="" database="" xmlns:sqlt="http://sqlfairy.sourceforge.net/sqlfairy.xml">
286   <sqlt:table name="Basic" order="3">
287     <sqlt:fields>
288       <sqlt:field name="id" data_type="integer" size="10" is_nullable="0" is_auto_increment="1" is_primary_key="1" is_foreign_key="0" comments="comment on id field" order="9" />
289       <sqlt:field name="title" data_type="varchar" size="100" is_nullable="0" default_value="hello" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" comments="" order="10" />
290       <sqlt:field name="description" data_type="text" size="65535" is_nullable="1" default_value="" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" comments="" order="11" />
291       <sqlt:field name="email" data_type="varchar" size="255" is_nullable="1" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" comments="" order="12" />
292     </sqlt:fields>
293     <sqlt:indices>
294       <sqlt:index name="titleindex" type="NORMAL" fields="title" options="" />
295     </sqlt:indices>
296     <sqlt:constraints>
297       <sqlt:constraint name="" type="PRIMARY KEY" fields="id" reference_table="" on_delete="" on_update="" match_type="" expression="" options="" deferrable="1" />
298       <sqlt:constraint name="" type="UNIQUE" fields="email" reference_table="" on_delete="" on_update="" match_type="" expression="" options="" deferrable="1" />
299     </sqlt:constraints>
300   </sqlt:table>
301 </sqlt:schema>
302 EOXML
303
304 $obj = SQL::Translator->new(
305     debug          => DEBUG,
306     trace          => TRACE,
307     show_warnings  => 1,
308     add_drop_table => 1,
309     from           => "MySQL",
310     to             => "XML-SQLFairy",
311     producer_args  => { attrib_values => 1 },
312 );
313 lives_ok {$xml = $obj->translate($file);} "Translate (attrib_values=>1) ran";
314 ok("$xml" ne ""                             ,"Produced something!");
315 print "XML attrib_values=>1:\n$xml" if DEBUG;
316 # Strip sqlf header with its variable date so we diff safely
317 $xml =~ s/^([^\n]*\n){7}//m; 
318 eq_or_diff $xml, $ans                       ,"XML looks right";
319
320 } # end attrib_values => 1
321
322 #
323 # View
324 #
325 # Thanks to Ken for the schema setup lifted from 13schema.t
326 {
327 my ($obj,$ans,$xml);
328
329 $ans = <<EOXML;
330 <sqlt:schema xmlns:sqlt="http://sqlfairy.sourceforge.net/sqlfairy.xml">
331   <sqlt:name></sqlt:name>
332   <sqlt:database></sqlt:database>
333   <sqlt:view>
334     <sqlt:name>foo_view</sqlt:name>
335     <sqlt:sql>select name, age from person</sqlt:sql>
336     <sqlt:fields>name,age</sqlt:fields>
337     <sqlt:order>1</sqlt:order>
338   </sqlt:view>
339 </sqlt:schema>
340 EOXML
341
342     $obj = SQL::Translator->new(
343         debug          => DEBUG,
344         trace          => TRACE,
345         show_warnings  => 1,
346         add_drop_table => 1,
347         from           => "MySQL",
348         to             => "XML-SQLFairy",
349     );
350     my $s      = $obj->schema;
351     my $name   = 'foo_view';
352     my $sql    = 'select name, age from person';
353     my $fields = 'name, age';
354     my $v      = $s->add_view(
355         name   => $name,
356         sql    => $sql,
357         fields => $fields,
358         schema => $s,
359     ) or die $s->error;
360     
361     # As we have created a Schema we give translate a dummy string so that
362     # it will run the produce.
363     lives_ok {$xml =$obj->translate("FOO");} "Translate (View) ran";
364     ok("$xml" ne ""                             ,"Produced something!");
365     print "XML attrib_values=>1:\n$xml" if DEBUG;
366     # Strip sqlf header with its variable date so we diff safely
367     $xml =~ s/^([^\n]*\n){7}//m; 
368     eq_or_diff $xml, $ans                       ,"XML looks right";
369 } # end View
370
371 #
372 # Trigger
373 #
374 # Thanks to Ken for the schema setup lifted from 13schema.t
375 {
376 my ($obj,$ans,$xml);
377
378 $ans = <<EOXML;
379 <sqlt:schema xmlns:sqlt="http://sqlfairy.sourceforge.net/sqlfairy.xml">
380   <sqlt:name></sqlt:name>
381   <sqlt:database></sqlt:database>
382   <sqlt:trigger>
383     <sqlt:name>foo_trigger</sqlt:name>
384     <sqlt:database_event>insert</sqlt:database_event>
385     <sqlt:action>update modified=timestamp();</sqlt:action>
386     <sqlt:on_table>foo</sqlt:on_table>
387     <sqlt:perform_action_when>after</sqlt:perform_action_when>
388     <sqlt:order>1</sqlt:order>
389   </sqlt:trigger>
390 </sqlt:schema>
391 EOXML
392
393     $obj = SQL::Translator->new(
394         debug          => DEBUG,
395         trace          => TRACE,
396         show_warnings  => 1,
397         add_drop_table => 1,
398         from           => "MySQL",
399         to             => "XML-SQLFairy",
400     );
401     my $s                   = $obj->schema;
402     my $name                = 'foo_trigger';
403     my $perform_action_when = 'after';
404     my $database_event      = 'insert';
405     my $on_table            = 'foo';
406     my $action              = 'update modified=timestamp();';
407     my $t                   = $s->add_trigger(
408         name                => $name,
409         perform_action_when => $perform_action_when,
410         database_event      => $database_event,
411         on_table            => $on_table,
412         action              => $action,
413     ) or die $s->error;
414     
415     # As we have created a Schema we give translate a dummy string so that
416     # it will run the produce.
417     lives_ok {$xml =$obj->translate("FOO");} "Translate (Trigger) ran";
418     ok("$xml" ne ""                             ,"Produced something!");
419     print "XML attrib_values=>1:\n$xml" if DEBUG;
420     # Strip sqlf header with its variable date so we diff safely
421     $xml =~ s/^([^\n]*\n){7}//m; 
422     eq_or_diff $xml, $ans                       ,"XML looks right";
423 } # end Trigger
424
425 #
426 # Procedure
427 #
428 # Thanks to Ken for the schema setup lifted from 13schema.t
429 {
430 my ($obj,$ans,$xml);
431
432 $ans = <<EOXML;
433 <sqlt:schema xmlns:sqlt="http://sqlfairy.sourceforge.net/sqlfairy.xml">
434   <sqlt:name></sqlt:name>
435   <sqlt:database></sqlt:database>
436   <sqlt:procedure>
437     <sqlt:name>foo_proc</sqlt:name>
438     <sqlt:sql>select foo from bar</sqlt:sql>
439     <sqlt:parameters>foo,bar</sqlt:parameters>
440     <sqlt:owner>Nomar</sqlt:owner>
441     <sqlt:comments>Go Sox!</sqlt:comments>
442     <sqlt:order>1</sqlt:order>
443   </sqlt:procedure>
444 </sqlt:schema>
445 EOXML
446
447     $obj = SQL::Translator->new(
448         debug          => DEBUG,
449         trace          => TRACE,
450         show_warnings  => 1,
451         add_drop_table => 1,
452         from           => "MySQL",
453         to             => "XML-SQLFairy",
454     );
455     my $s          = $obj->schema;
456     my $name       = 'foo_proc';
457     my $sql        = 'select foo from bar';
458     my $parameters = 'foo, bar';
459     my $owner      = 'Nomar';
460     my $comments   = 'Go Sox!';
461     my $p          = $s->add_procedure(
462         name       => $name,
463         sql        => $sql,
464         parameters => $parameters,
465         owner      => $owner,
466         comments   => $comments,
467     ) or die $s->error;
468
469     # As we have created a Schema we give translate a dummy string so that
470     # it will run the produce.
471     lives_ok {$xml =$obj->translate("FOO");} "Translate (Procedure) ran";
472     ok("$xml" ne ""                             ,"Produced something!");
473     print "XML attrib_values=>1:\n$xml" if DEBUG;
474     # Strip sqlf header with its variable date so we diff safely
475     $xml =~ s/^([^\n]*\n){7}//m; 
476     eq_or_diff $xml, $ans                       ,"XML looks right";
477 } # end Procedure