Commit | Line | Data |
969049ba |
1 | #!/usr/bin/env perl |
45df156a |
2 | |
44659089 |
3 | # ------------------------------------------------------------------- |
4 | # Copyright (C) 2002-2009 SQLFairy Authors |
5 | # |
6 | # This program is free software; you can redistribute it and/or |
7 | # modify it under the terms of the GNU General Public License as |
8 | # published by the Free Software Foundation; version 2. |
9 | # |
10 | # This program is distributed in the hope that it will be useful, but |
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | # General Public License for more details. |
14 | # |
15 | # You should have received a copy of the GNU General Public License |
16 | # along with this program; if not, write to the Free Software |
17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
18 | # 02111-1307 USA |
19 | # ------------------------------------------------------------------- |
20 | |
45df156a |
21 | =head1 NAME |
22 | |
42b19e6f |
23 | sqlt.cgi - CGI front-end for SQL::Translator |
45df156a |
24 | |
25 | =head1 DESCRIPTION |
26 | |
42b19e6f |
27 | Place this script in your "cgi-bin" directory and point your browser |
aee4b66e |
28 | to it. This script is meant to be a simple graphical interface to |
42b19e6f |
29 | all the parsers and producers of SQL::Translator. |
45df156a |
30 | |
31 | =cut |
32 | |
42b19e6f |
33 | # ------------------------------------------------------------------- |
34 | |
45df156a |
35 | use strict; |
969049ba |
36 | use warnings; |
45df156a |
37 | use CGI; |
38 | use SQL::Translator; |
39 | |
da06ac74 |
40 | use vars '$VERSION'; |
11ad2df9 |
41 | $VERSION = '1.59'; |
da06ac74 |
42 | |
45df156a |
43 | my $q = CGI->new; |
44 | |
45 | eval { |
46 | if ( $q->param ) { |
45df156a |
47 | my $data; |
48 | if ( $q->param('schema') ) { |
49 | $data = $q->param('schema'); |
50 | } |
51 | elsif ( my $fh = $q->upload('schema_file') ) { |
52 | local $/; |
53 | $data = <$fh>; |
54 | } |
55 | die "No schema provided!\n" unless $data; |
56 | |
57 | my $producer = $q->param('producer'); |
42b19e6f |
58 | my $output_type = $producer eq 'Diagram' |
59 | ? $q->param('diagram_output_type') |
60 | : $producer eq 'GraphViz' |
aee4b66e |
61 | ? $q->param('graphviz_output_type') |
db443c26 |
62 | : '' |
42b19e6f |
63 | ; |
64 | |
aee4b66e |
65 | my $t = SQL::Translator->new( |
42b19e6f |
66 | from => $q->param('parser'), |
67 | producer_args => { |
68 | add_drop_table => $q->param('add_drop_table'), |
69 | output_type => $output_type, |
70 | title => $q->param('title') || 'Schema', |
aee4b66e |
71 | natural_join => $q->param('natural_join') eq 'no' ? 0 : 1, |
72 | join_pk_only => $q->param('natural_join') eq 'pk_only' |
42b19e6f |
73 | ? 1 : 0, |
74 | add_color => $q->param('add_color'), |
75 | skip_fields => $q->param('skip_fields'), |
76 | show_fk_only => $q->param('show_fk_only'), |
77 | font_size => $q->param('font_size'), |
78 | no_columns => $q->param('no_columns'), |
79 | node_shape => $q->param('node_shape'), |
80 | layout => $q->param('layout') || '', |
81 | height => $q->param('height') || 0, |
82 | width => $q->param('width') || 0, |
83 | show_fields => $q->param('show_fields') || 0, |
84 | ttfile => $q->upload('template'), |
85 | validate => $q->param('validate'), |
86 | emit_empty_tags => $q->param('emit_empty_tags'), |
87 | attrib_values => $q->param('attrib_values'), |
88 | no_comments => !$q->param('comments'), |
89 | }, |
90 | parser_args => { |
91 | trim_fields => $q->param('trim_fields'), |
92 | scan_fields => $q->param('scan_fields'), |
93 | field_separator => $q->param('fs'), |
94 | record_separator => $q->param('rs'), |
95 | }, |
96 | ) or die SQL::Translator->error; |
97 | |
98 | my $image_type = ''; |
99 | my $text_type = 'plain'; |
100 | if ( $output_type =~ /(gif|png|jpeg)/ ) { |
101 | $image_type = $output_type; |
102 | } |
103 | elsif ( $output_type eq 'svg' ) { |
104 | $image_type = 'svg+xml'; |
105 | } |
106 | elsif ( $output_type =~ /gd/ ) { |
107 | $image_type = 'png'; |
108 | } |
109 | elsif ( $output_type eq 'ps' ) { |
110 | $text_type = 'postscript'; |
111 | } |
db443c26 |
112 | elsif ( $producer eq 'HTML' ) { |
113 | $text_type = 'html'; |
114 | } |
42b19e6f |
115 | |
116 | my $header_type = $image_type ? "image/$image_type" : "text/$text_type"; |
45df156a |
117 | |
118 | $t->data( $data ); |
119 | $t->producer( $producer ); |
120 | my $output = $t->translate or die $t->error; |
121 | |
122 | print $q->header( -type => $header_type ), $output; |
123 | } |
124 | else { |
125 | show_form( $q ); |
126 | } |
127 | }; |
128 | |
129 | if ( my $error = $@ ) { |
130 | print $q->header, $q->start_html('Error'), |
131 | $q->h1('Error'), $error, $q->end_html; |
132 | } |
133 | |
134 | # ------------------------------------------------------------------- |
135 | sub show_form { |
136 | my $q = shift; |
137 | my $title = 'SQL::Translator'; |
138 | |
aee4b66e |
139 | print $q->header, |
45df156a |
140 | $q->start_html( -title => $title ), |
141 | $q->h1( qq[<a href="http://sqlfairy.sourceforge.net">$title</a>] ), |
142 | $q->start_form(-enctype => 'multipart/form-data'), |
143 | $q->table( { -border => 1 }, |
aee4b66e |
144 | $q->Tr( |
45df156a |
145 | $q->td( [ |
42b19e6f |
146 | 'Upload your schema file:', |
147 | $q->filefield( -name => 'schema_file'), |
45df156a |
148 | ] ), |
149 | ), |
aee4b66e |
150 | $q->Tr( |
45df156a |
151 | $q->td( [ |
42b19e6f |
152 | 'Or paste your schema here:', |
aee4b66e |
153 | $q->textarea( |
154 | -name => 'schema', |
155 | -rows => 5, |
42b19e6f |
156 | -columns => 60, |
157 | ), |
45df156a |
158 | ] ), |
159 | ), |
aee4b66e |
160 | $q->Tr( |
45df156a |
161 | $q->td( [ |
162 | 'Parser:', |
163 | $q->radio_group( |
164 | -name => 'parser', |
aee4b66e |
165 | -values => [ qw( MySQL PostgreSQL Oracle |
166 | Sybase Excel XML-SQLFairy xSV |
42b19e6f |
167 | ) ], |
45df156a |
168 | -default => 'MySQL', |
169 | -rows => 3, |
170 | ), |
171 | ] ), |
172 | ), |
aee4b66e |
173 | $q->Tr( |
45df156a |
174 | $q->td( [ |
175 | 'Producer:', |
176 | $q->radio_group( |
177 | -name => 'producer', |
178 | -values => [ qw[ ClassDBI Diagram GraphViz HTML |
42b19e6f |
179 | MySQL Oracle POD PostgreSQL SQLite Sybase |
180 | TTSchema XML-SQLFairy |
45df156a |
181 | ] ], |
182 | -default => 'GraphViz', |
183 | -rows => 3, |
184 | ), |
185 | ] ), |
186 | ), |
aee4b66e |
187 | $q->Tr( |
42b19e6f |
188 | $q->td( |
189 | { -colspan => 2, -align => 'center' }, |
aee4b66e |
190 | $q->submit( |
191 | -name => 'submit', |
42b19e6f |
192 | -value => 'Submit', |
193 | ) |
194 | ), |
195 | ), |
aee4b66e |
196 | $q->Tr( |
197 | $q->th( |
198 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
199 | 'General Options:' |
42b19e6f |
200 | ), |
201 | ), |
aee4b66e |
202 | $q->Tr( |
45df156a |
203 | $q->td( [ |
42b19e6f |
204 | 'Validate Schema:', |
205 | $q->radio_group( |
206 | -name => 'validate', |
207 | -values => [ 1, 0 ], |
aee4b66e |
208 | -labels => { |
209 | 1 => 'Yes', |
210 | 0 => 'No' |
42b19e6f |
211 | }, |
212 | -default => 0, |
213 | -rows => 2, |
214 | ), |
45df156a |
215 | ] ), |
216 | ), |
aee4b66e |
217 | $q->Tr( |
218 | $q->th( |
219 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
220 | 'DB Producer Options:' |
42b19e6f |
221 | ), |
222 | ), |
aee4b66e |
223 | $q->Tr( |
45df156a |
224 | $q->td( [ |
42b19e6f |
225 | 'Add "DROP TABLE" statements:', |
45df156a |
226 | $q->radio_group( |
42b19e6f |
227 | -name => 'add_drop_table', |
228 | -values => [ 1, 0 ], |
aee4b66e |
229 | -labels => { |
230 | 1 => 'Yes', |
231 | 0 => 'No' |
42b19e6f |
232 | }, |
233 | -default => 0, |
45df156a |
234 | -rows => 2, |
235 | ), |
236 | ] ), |
237 | ), |
aee4b66e |
238 | $q->Tr( |
45df156a |
239 | $q->td( [ |
42b19e6f |
240 | 'Include comments:', |
241 | $q->radio_group( |
242 | -name => 'comments', |
243 | -values => [ 1, 0 ], |
aee4b66e |
244 | -labels => { |
245 | 1 => 'Yes', |
246 | 0 => 'No' |
42b19e6f |
247 | }, |
248 | -default => 1, |
249 | -rows => 2, |
250 | ), |
251 | ] ), |
252 | ), |
aee4b66e |
253 | $q->Tr( |
254 | $q->th( |
255 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
256 | 'HTML/POD/Diagram Producer Options:' |
42b19e6f |
257 | ), |
258 | ), |
aee4b66e |
259 | $q->Tr( |
42b19e6f |
260 | $q->td( [ |
261 | 'Title:', |
262 | $q->textfield('title'), |
263 | ] ), |
264 | ), |
aee4b66e |
265 | $q->Tr( |
266 | $q->th( |
267 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
268 | 'TTSchema Producer Options:' |
42b19e6f |
269 | ), |
270 | ), |
aee4b66e |
271 | $q->Tr( |
42b19e6f |
272 | $q->td( [ |
273 | 'Template:', |
274 | $q->filefield( -name => 'template'), |
275 | ] ), |
276 | ), |
aee4b66e |
277 | $q->Tr( |
278 | $q->th( |
279 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
42b19e6f |
280 | 'Graphical Producer Options' |
281 | ), |
282 | ), |
aee4b66e |
283 | $q->Tr( |
42b19e6f |
284 | $q->td( [ |
45df156a |
285 | 'Perform Natural Joins:', |
286 | $q->radio_group( |
287 | -name => 'natural_join', |
288 | -values => [ 'no', 'yes', 'pk_only' ], |
289 | -labels => { |
290 | no => 'No', |
291 | yes => 'Yes, on all like-named fields', |
292 | pk_only => 'Yes, but only from primary keys' |
293 | }, |
294 | -default => 'no', |
295 | -rows => 3, |
296 | ), |
297 | ] ), |
298 | ), |
aee4b66e |
299 | $q->Tr( |
45df156a |
300 | $q->td( [ |
301 | 'Skip These Fields in Natural Joins:', |
302 | $q->textarea( |
303 | -name => 'skip_fields', |
304 | -rows => 3, |
305 | -columns => 60, |
306 | ), |
307 | ] ), |
308 | ), |
aee4b66e |
309 | $q->Tr( |
45df156a |
310 | $q->td( [ |
42b19e6f |
311 | 'Show Only Foreign Keys:', |
312 | $q->radio_group( |
313 | -name => 'show_fk_only', |
314 | -values => [ 1, 0 ], |
315 | -default => 0, |
316 | -labels => { |
317 | 1 => 'Yes', |
318 | 0 => 'No', |
319 | }, |
320 | -rows => 2, |
321 | ), |
322 | ] ), |
323 | ), |
aee4b66e |
324 | $q->Tr( |
42b19e6f |
325 | $q->td( [ |
326 | 'Add Color:', |
45df156a |
327 | $q->radio_group( |
328 | -name => 'add_color', |
329 | -values => [ 1, 0 ], |
aee4b66e |
330 | -labels => { |
331 | 1 => 'Yes', |
332 | 0 => 'No' |
45df156a |
333 | }, |
334 | -default => 1, |
335 | -rows => 2, |
336 | ), |
337 | ] ), |
338 | ), |
aee4b66e |
339 | $q->Tr( |
45df156a |
340 | $q->td( [ |
42b19e6f |
341 | 'Show Field Names:', |
45df156a |
342 | $q->radio_group( |
42b19e6f |
343 | -name => 'show_fields', |
45df156a |
344 | -values => [ 1, 0 ], |
42b19e6f |
345 | -default => 1, |
45df156a |
346 | -labels => { |
347 | 1 => 'Yes', |
348 | 0 => 'No', |
349 | }, |
350 | -rows => 2, |
351 | ), |
352 | ] ), |
353 | ), |
aee4b66e |
354 | $q->Tr( |
355 | $q->th( |
356 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
42b19e6f |
357 | 'Diagram Producer Options' |
358 | ), |
359 | ), |
aee4b66e |
360 | $q->Tr( |
42b19e6f |
361 | $q->td( [ |
362 | 'Output Type:', |
363 | $q->radio_group( |
364 | -name => 'diagram_output_type', |
365 | -values => [ 'png', 'jpeg' ], |
366 | -default => 'png', |
367 | -rows => 2, |
368 | ), |
369 | ] ), |
370 | ), |
aee4b66e |
371 | $q->Tr( |
45df156a |
372 | $q->td( [ |
42b19e6f |
373 | 'Font Size:', |
45df156a |
374 | $q->radio_group( |
375 | -name => 'font_size', |
376 | -values => [ qw( small medium large ) ], |
377 | -default => 'medium', |
378 | -rows => 3, |
379 | ), |
380 | ] ), |
381 | ), |
aee4b66e |
382 | $q->Tr( |
45df156a |
383 | $q->td( [ |
42b19e6f |
384 | 'Number of Columns:', |
45df156a |
385 | $q->textfield('no_columns'), |
386 | ] ), |
387 | ), |
aee4b66e |
388 | $q->Tr( |
389 | $q->th( |
390 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
42b19e6f |
391 | 'GraphViz Producer Options' |
392 | ), |
393 | ), |
aee4b66e |
394 | $q->Tr( |
42b19e6f |
395 | $q->td( [ |
396 | 'Output Type:', |
397 | $q->radio_group( |
398 | -name => 'graphviz_output_type', |
399 | -values => [ qw( canon text ps hpgl pcl mif pic |
400 | gd gd2 gif jpeg png wbmp cmap ismap imap |
401 | vrml vtx mp fig svg plain |
402 | ) ], |
403 | -default => 'png', |
404 | -rows => 4, |
405 | ), |
406 | ] ), |
407 | ), |
aee4b66e |
408 | $q->Tr( |
45df156a |
409 | $q->td( [ |
42b19e6f |
410 | 'Layout:', |
45df156a |
411 | $q->radio_group( |
412 | -name => 'layout', |
413 | -values => [ qw( dot neato twopi ) ], |
414 | -default => 'dot', |
415 | -rows => 3, |
416 | ), |
417 | ] ), |
418 | ), |
aee4b66e |
419 | $q->Tr( |
45df156a |
420 | $q->td( [ |
42b19e6f |
421 | 'Node Shape:', |
45df156a |
422 | $q->radio_group( |
423 | -name => 'node_shape', |
aee4b66e |
424 | -values => [ qw( record plaintext ellipse |
425 | circle egg triangle box diamond trapezium |
426 | parallelogram house hexagon octagon |
45df156a |
427 | ) ], |
428 | -default => 'record', |
42b19e6f |
429 | -rows => 4, |
45df156a |
430 | ), |
431 | ] ), |
432 | ), |
aee4b66e |
433 | $q->Tr( |
45df156a |
434 | $q->td( [ |
42b19e6f |
435 | 'Height:', |
436 | $q->textfield( -name => 'height' ), |
437 | ] ), |
438 | ), |
aee4b66e |
439 | $q->Tr( |
42b19e6f |
440 | $q->td( [ |
441 | 'Width:', |
442 | $q->textfield( -name => 'width' ), |
443 | ] ), |
444 | ), |
aee4b66e |
445 | $q->Tr( |
446 | $q->th( |
447 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
448 | 'XML Producer Options:' |
42b19e6f |
449 | ), |
450 | ), |
aee4b66e |
451 | $q->Tr( |
42b19e6f |
452 | $q->td( [ |
453 | 'Use attributes for values:', |
45df156a |
454 | $q->radio_group( |
42b19e6f |
455 | -name => 'attrib-values', |
45df156a |
456 | -values => [ 1, 0 ], |
aee4b66e |
457 | -labels => { |
458 | 1 => 'Yes', |
459 | 0 => 'No' |
45df156a |
460 | }, |
42b19e6f |
461 | -default => 0, |
45df156a |
462 | -rows => 2, |
463 | ), |
464 | ] ), |
465 | ), |
aee4b66e |
466 | $q->Tr( |
45df156a |
467 | $q->td( [ |
42b19e6f |
468 | 'Emit Empty Tags:', |
469 | $q->radio_group( |
470 | -name => 'emit-empty-tags', |
471 | -values => [ 1, 0 ], |
aee4b66e |
472 | -labels => { |
473 | 1 => 'Yes', |
474 | 0 => 'No' |
42b19e6f |
475 | }, |
476 | -default => 0, |
477 | -rows => 2, |
478 | ), |
479 | ] ), |
480 | ), |
aee4b66e |
481 | $q->Tr( |
482 | $q->th( |
483 | { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, |
42b19e6f |
484 | 'xSV Parser Options' |
485 | ), |
486 | ), |
aee4b66e |
487 | $q->Tr( |
42b19e6f |
488 | $q->td( [ |
489 | 'Field Separator:', |
490 | $q->textfield( -name => 'fs' ), |
45df156a |
491 | ] ), |
492 | ), |
aee4b66e |
493 | $q->Tr( |
45df156a |
494 | $q->td( [ |
42b19e6f |
495 | 'Record Separator:', |
496 | $q->textfield( -name => 'rs' ), |
497 | ] ), |
498 | ), |
aee4b66e |
499 | $q->Tr( |
42b19e6f |
500 | $q->td( [ |
501 | 'Trim Whitespace Around Fields:', |
502 | $q->radio_group( |
503 | -name => 'trim_fields', |
504 | -values => [ 1, 0 ], |
505 | -default => 1, |
506 | -labels => { |
507 | 1 => 'Yes', |
508 | 0 => 'No', |
509 | }, |
510 | -rows => 2, |
511 | ), |
512 | ] ), |
513 | ), |
aee4b66e |
514 | $q->Tr( |
42b19e6f |
515 | $q->td( [ |
516 | 'Scan Fields for Data Type:', |
517 | $q->radio_group( |
518 | -name => 'scan_fields', |
519 | -values => [ 1, 0 ], |
520 | -default => 1, |
521 | -labels => { |
522 | 1 => 'Yes', |
523 | 0 => 'No', |
524 | }, |
525 | -rows => 2, |
526 | ), |
45df156a |
527 | ] ), |
528 | ), |
aee4b66e |
529 | $q->Tr( |
45df156a |
530 | $q->td( |
531 | { -colspan => 2, -align => 'center' }, |
aee4b66e |
532 | $q->submit( |
533 | -name => 'submit', |
45df156a |
534 | -value => 'Submit', |
42b19e6f |
535 | ) |
45df156a |
536 | ), |
537 | ), |
538 | ), |
539 | $q->end_form, |
540 | $q->end_html; |
541 | } |
542 | |
543 | # ------------------------------------------------------------------- |
544 | |
545 | =pod |
546 | |
547 | =head1 AUTHOR |
548 | |
969049ba |
549 | Ken Youens-Clark E<lt>kclark@cpan.orgE<gt>. |
45df156a |
550 | |
551 | =head1 SEE ALSO |
552 | |
478f608d |
553 | L<perl>, |
554 | L<SQL::Translator> |
45df156a |
555 | |
556 | =cut |