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