More DB2 producing
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator.pm
CommitLineData
16dc9970 1package SQL::Translator;
2
b346d8f1 3# ----------------------------------------------------------------------
44eb9098 4# $Id: Translator.pm,v 1.68 2005-06-09 02:02:00 grommit Exp $
b346d8f1 5# ----------------------------------------------------------------------
ad8eaeae 6# Copyright (C) 2002-4 The SQLFairy Authors
1fd8c91f 7#
077ebf34 8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; version 2.
ca10f295 11#
077ebf34 12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# General Public License for more details.
ca10f295 16#
077ebf34 17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20# 02111-1307 USA
ca10f295 21# -------------------------------------------------------------------
22
16dc9970 23use strict;
d529894e 24use vars qw( $VERSION $REVISION $DEFAULT_SUB $DEBUG $ERROR );
49e1eb70 25use base 'Class::Base';
c2d3a526 26
4b6a6341 27require 5.004;
28
556b0461 29$VERSION = '0.07';
44eb9098 30$REVISION = sprintf "%d.%02d", q$Revision: 1.68 $ =~ /(\d+)\.(\d+)/;
d529894e 31$DEBUG = 0 unless defined $DEBUG;
32$ERROR = "";
c2d3a526 33
34use Carp qw(carp);
16dc9970 35
841a3f1a 36use Data::Dumper;
0ffa0507 37use Class::Base;
3015bf96 38use File::Find;
c0c4aef9 39use File::Spec::Functions qw(catfile);
40use File::Basename qw(dirname);
41use IO::Dir;
45ee6be0 42use SQL::Translator::Schema;
c0c4aef9 43
b346d8f1 44# ----------------------------------------------------------------------
45# The default behavior is to "pass through" values (note that the
46# SQL::Translator instance is the first value ($_[0]), and the stuff
47# to be parsed is the second value ($_[1])
48# ----------------------------------------------------------------------
05a56b57 49$DEFAULT_SUB = sub { $_[0]->schema } unless defined $DEFAULT_SUB;
16dc9970 50
b346d8f1 51# ----------------------------------------------------------------------
c2d3a526 52# init([ARGS])
b346d8f1 53# The constructor.
dfb4c915 54#
b346d8f1 55# new takes an optional hash of arguments. These arguments may
56# include a parser, specified with the keys "parser" or "from",
57# and a producer, specified with the keys "producer" or "to".
dfb4c915 58#
b346d8f1 59# The values that can be passed as the parser or producer are
60# given directly to the parser or producer methods, respectively.
61# See the appropriate method description below for details about
62# what each expects/accepts.
b346d8f1 63# ----------------------------------------------------------------------
c2d3a526 64sub init {
49e1eb70 65 my ( $self, $config ) = @_;
49e1eb70 66 #
b346d8f1 67 # Set the parser and producer.
ca10f295 68 #
b346d8f1 69 # If a 'parser' or 'from' parameter is passed in, use that as the
70 # parser; if a 'producer' or 'to' parameter is passed in, use that
71 # as the producer; both default to $DEFAULT_SUB.
49e1eb70 72 #
73 $self->parser ($config->{'parser'} || $config->{'from'} || $DEFAULT_SUB);
c2d3a526 74 $self->producer($config->{'producer'} || $config->{'to'} || $DEFAULT_SUB);
ca10f295 75
10f36920 76 #
77 # Set up callbacks for formatting of pk,fk,table,package names in producer
78 # MOVED TO PRODUCER ARGS
79 #
80 #$self->format_table_name($config->{'format_table_name'});
81 #$self->format_package_name($config->{'format_package_name'});
82 #$self->format_fk_name($config->{'format_fk_name'});
83 #$self->format_pk_name($config->{'format_pk_name'});
7d5bcab8 84
49e1eb70 85 #
e2158c40 86 # Set the parser_args and producer_args
49e1eb70 87 #
88 for my $pargs ( qw[ parser_args producer_args ] ) {
89 $self->$pargs( $config->{$pargs} ) if defined $config->{ $pargs };
e2158c40 90 }
91
49e1eb70 92 #
185c34d5 93 # Initialize the filters.
94 #
95 if ( $config->{filters} && ref $config->{filters} eq "ARRAY" ) {
96 $self->filters( @{$config->{filters}} )
97 || return $self->error('Error inititializing filters: '.$self->error);
98 }
99
100 #
9398955f 101 # Set the data source, if 'filename' or 'file' is provided.
49e1eb70 102 #
c2d3a526 103 $config->{'filename'} ||= $config->{'file'} || "";
49e1eb70 104 $self->filename( $config->{'filename'} ) if $config->{'filename'};
9398955f 105
49e1eb70 106 #
185c34d5 107 # Finally, if there is a 'data' parameter, use that in
49e1eb70 108 # preference to filename and file
109 #
110 if ( my $data = $config->{'data'} ) {
111 $self->data( $data );
9398955f 112 }
113
d529894e 114 #
115 # Set various other options.
116 #
49e1eb70 117 $self->{'debug'} = defined $config->{'debug'} ? $config->{'debug'} : $DEBUG;
ca10f295 118
96844cae 119 $self->add_drop_table( $config->{'add_drop_table'} );
185c34d5 120
d529894e 121 $self->no_comments( $config->{'no_comments'} );
122
96844cae 123 $self->show_warnings( $config->{'show_warnings'} );
124
125 $self->trace( $config->{'trace'} );
126
3f4af30d 127 $self->validate( $config->{'validate'} );
128
ca10f295 129 return $self;
dfb4c915 130}
1fd8c91f 131
0f3778d0 132# ----------------------------------------------------------------------
133# add_drop_table([$bool])
134# ----------------------------------------------------------------------
96844cae 135sub add_drop_table {
136 my $self = shift;
137 if ( defined (my $arg = shift) ) {
138 $self->{'add_drop_table'} = $arg ? 1 : 0;
139 }
140 return $self->{'add_drop_table'} || 0;
141}
142
0f3778d0 143# ----------------------------------------------------------------------
144# no_comments([$bool])
145# ----------------------------------------------------------------------
d529894e 146sub no_comments {
147 my $self = shift;
148 my $arg = shift;
149 if ( defined $arg ) {
150 $self->{'no_comments'} = $arg ? 1 : 0;
151 }
152 return $self->{'no_comments'} || 0;
153}
154
e2158c40 155
0f3778d0 156# ----------------------------------------------------------------------
157# producer([$producer_spec])
158#
159# Get or set the producer for the current translator.
160# ----------------------------------------------------------------------
ca10f295 161sub producer {
f4a59b6c 162 shift->_tool({
185c34d5 163 name => 'producer',
f4a59b6c 164 path => "SQL::Translator::Producer",
185c34d5 165 default_sub => "produce",
f4a59b6c 166 }, @_);
167}
077ebf34 168
7a8e1f51 169# ----------------------------------------------------------------------
0f3778d0 170# producer_type()
7a8e1f51 171#
e2158c40 172# producer_type is an accessor that allows producer subs to get
173# information about their origin. This is poptentially important;
ca251f03 174# since all producer subs are called as subroutine references, there is
e2158c40 175# no way for a producer to find out which package the sub lives in
176# originally, for example.
7a8e1f51 177# ----------------------------------------------------------------------
178sub producer_type { $_[0]->{'producer_type'} }
e2158c40 179
7a8e1f51 180# ----------------------------------------------------------------------
0f3778d0 181# producer_args([\%args])
7a8e1f51 182#
e2158c40 183# Arbitrary name => value pairs of paramters can be passed to a
184# producer using this method.
52b828e8 185#
0f3778d0 186# If the first argument passed in is undef, then the hash of arguments
187# is cleared; all subsequent elements are added to the hash of name,
188# value pairs stored as producer_args.
7a8e1f51 189# ----------------------------------------------------------------------
f4a59b6c 190sub producer_args { shift->_args("producer", @_); }
ca10f295 191
0f3778d0 192# ----------------------------------------------------------------------
193# parser([$parser_spec])
194# ----------------------------------------------------------------------
ca10f295 195sub parser {
f4a59b6c 196 shift->_tool({
185c34d5 197 name => 'parser',
f4a59b6c 198 path => "SQL::Translator::Parser",
185c34d5 199 default_sub => "parse",
f4a59b6c 200 }, @_);
16dc9970 201}
1fd8c91f 202
f4a59b6c 203sub parser_type { $_[0]->{'parser_type'}; }
e2158c40 204
f4a59b6c 205sub parser_args { shift->_args("parser", @_); }
96844cae 206
f4a59b6c 207# ----------------------------------------------------------------------
185c34d5 208# e.g.
209# $sqlt->filters => [
210# sub { },
211# [ "NormalizeNames", field => "lc", tabel => "ucfirst" ],
212# [
213# "DataTypeMap",
214# "TEXT" => "BIGTEXT",
215# ],
216# ],
217# ----------------------------------------------------------------------
218sub filters {
219 my $self = shift;
220 my $filters = $self->{filters} ||= [];
221 return @$filters unless @_;
222
44eb9098 223 # Set. Convert args to list of [\&code,@args]
185c34d5 224 foreach (@_) {
44eb9098 225 my ($filt,@args) = ref($_) eq "ARRAY" ? @$_ : $_;
226 if ( isa($filt,"CODE") ) {
227 push @$filters, [$filt,@args];
185c34d5 228 next;
229 }
230 else {
44eb9098 231 $self->debug("Adding $filt filter. Args:".Dumper(\@args)."\n");
232 $filt = _load_sub("$filt\::filter", "SQL::Translator::Filter")
233 || return $self->error(__PACKAGE__->error);
234 push @$filters, [$filt,@args];
185c34d5 235 }
236 }
237 return @$filters;
238}
239
240# ----------------------------------------------------------------------
96844cae 241sub show_warnings {
242 my $self = shift;
243 my $arg = shift;
244 if ( defined $arg ) {
245 $self->{'show_warnings'} = $arg ? 1 : 0;
246 }
247 return $self->{'show_warnings'} || 0;
248}
249
ca10f295 250
0f3778d0 251# filename - get or set the filename
252sub filename {
253 my $self = shift;
254 if (@_) {
255 my $filename = shift;
256 if (-d $filename) {
257 my $msg = "Cannot use directory '$filename' as input source";
258 return $self->error($msg);
f69e9da3 259 } elsif (ref($filename) eq 'ARRAY') {
260 $self->{'filename'} = $filename;
261 $self->debug("Got array of files: ".join(', ',@$filename)."\n");
0f3778d0 262 } elsif (-f _ && -r _) {
263 $self->{'filename'} = $filename;
264 $self->debug("Got filename: '$self->{'filename'}'\n");
265 } else {
266 my $msg = "Cannot use '$filename' as input source: ".
267 "file does not exist or is not readable.";
268 return $self->error($msg);
269 }
270 }
ca10f295 271
0f3778d0 272 $self->{'filename'};
273}
ca10f295 274
0f3778d0 275# ----------------------------------------------------------------------
276# data([$data])
277#
278# if $self->{'data'} is not set, but $self->{'filename'} is, then
279# $self->{'filename'} is opened and read, with the results put into
280# $self->{'data'}.
281# ----------------------------------------------------------------------
282sub data {
283 my $self = shift;
ca10f295 284
0f3778d0 285 # Set $self->{'data'} based on what was passed in. We will
286 # accept a number of things; do our best to get it right.
287 if (@_) {
288 my $data = shift;
289 if (isa($data, "SCALAR")) {
290 $self->{'data'} = $data;
291 }
292 else {
293 if (isa($data, 'ARRAY')) {
294 $data = join '', @$data;
295 }
296 elsif (isa($data, 'GLOB')) {
297 local $/;
298 $data = <$data>;
299 }
300 elsif (! ref $data && @_) {
301 $data = join '', $data, @_;
302 }
303 $self->{'data'} = \$data;
304 }
305 }
9398955f 306
7a8e1f51 307 # If we have a filename but no data yet, populate.
9398955f 308 if (not $self->{'data'} and my $filename = $self->filename) {
49e1eb70 309 $self->debug("Opening '$filename' to get contents.\n");
9398955f 310 local *FH;
311 local $/;
312 my $data;
313
f69e9da3 314 my @files = ref($filename) eq 'ARRAY' ? @$filename : ($filename);
9398955f 315
f69e9da3 316 foreach my $file (@files) {
960b4e55 317 unless (open FH, $file) {
318 return $self->error("Can't read file '$file': $!");
319 }
9398955f 320
960b4e55 321 $data .= <FH>;
95a2cfb6 322
960b4e55 323 unless (close FH) {
324 return $self->error("Can't close file '$file': $!");
325 }
f69e9da3 326 }
95a2cfb6 327
f69e9da3 328 $self->{'data'} = \$data;
9398955f 329 }
9398955f 330
331 return $self->{'data'};
7a8e1f51 332}
9398955f 333
45ee6be0 334# ----------------------------------------------------------------------
a57ce769 335sub reset {
336#
337# Deletes the existing Schema object so that future calls to translate
338# don't append to the existing.
339#
340 my $self = shift;
341 $self->{'schema'} = undef;
342 return 1;
343}
344
345# ----------------------------------------------------------------------
45ee6be0 346sub schema {
347#
348# Returns the SQL::Translator::Schema object
349#
350 my $self = shift;
351
352 unless ( defined $self->{'schema'} ) {
47fed978 353 $self->{'schema'} = SQL::Translator::Schema->new(
10f36920 354 translator => $self,
47fed978 355 );
45ee6be0 356 }
d529894e 357
45ee6be0 358 return $self->{'schema'};
359}
360
361# ----------------------------------------------------------------------
d529894e 362sub trace {
363 my $self = shift;
364 my $arg = shift;
365 if ( defined $arg ) {
366 $self->{'trace'} = $arg ? 1 : 0;
367 }
368 return $self->{'trace'} || 0;
369}
370
371# ----------------------------------------------------------------------
0f3778d0 372# translate([source], [\%args])
373#
374# translate does the actual translation. The main argument is the
375# source of the data to be translated, which can be a filename, scalar
376# reference, or glob reference.
377#
378# Alternatively, translate takes optional arguements, which are passed
379# to the appropriate places. Most notable of these arguments are
380# parser and producer, which can be used to set the parser and
381# producer, respectively. This is the applications last chance to set
382# these.
383#
384# translate returns a string.
385# ----------------------------------------------------------------------
ca251f03 386sub translate {
387 my $self = shift;
388 my ($args, $parser, $parser_type, $producer, $producer_type);
389 my ($parser_output, $producer_output);
ca10f295 390
7a8e1f51 391 # Parse arguments
185c34d5 392 if (@_ == 1) {
7a8e1f51 393 # Passed a reference to a hash?
ca10f295 394 if (isa($_[0], 'HASH')) {
7a8e1f51 395 # yep, a hashref
49e1eb70 396 $self->debug("translate: Got a hashref\n");
ca10f295 397 $args = $_[0];
398 }
9398955f 399
0f3778d0 400 # Passed a GLOB reference, i.e., filehandle
401 elsif (isa($_[0], 'GLOB')) {
402 $self->debug("translate: Got a GLOB reference\n");
403 $self->data($_[0]);
404 }
405
7a8e1f51 406 # Passed a reference to a string containing the data
ca10f295 407 elsif (isa($_[0], 'SCALAR')) {
9398955f 408 # passed a ref to a string
49e1eb70 409 $self->debug("translate: Got a SCALAR reference (string)\n");
9398955f 410 $self->data($_[0]);
ca10f295 411 }
9398955f 412
7a8e1f51 413 # Not a reference; treat it as a filename
b346d8f1 414 elsif (! ref $_[0]) {
ca10f295 415 # Not a ref, it's a filename
49e1eb70 416 $self->debug("translate: Got a filename\n");
9398955f 417 $self->filename($_[0]);
ca10f295 418 }
9398955f 419
7a8e1f51 420 # Passed something else entirely.
b346d8f1 421 else {
422 # We're not impressed. Take your empty string and leave.
38254289 423 # return "";
424
7a8e1f51 425 # Actually, if data, parser, and producer are set, then we
426 # can continue. Too bad, because I like my comment
427 # (above)...
38254289 428 return "" unless ($self->data &&
429 $self->producer &&
430 $self->parser);
b346d8f1 431 }
16dc9970 432 }
433 else {
b346d8f1 434 # You must pass in a hash, or you get nothing.
435 return "" if @_ % 2;
ca10f295 436 $args = { @_ };
7a8e1f51 437 }
16dc9970 438
9398955f 439 # ----------------------------------------------------------------------
440 # Can specify the data to be transformed using "filename", "file",
7a8e1f51 441 # "data", or "datasource".
9398955f 442 # ----------------------------------------------------------------------
7a8e1f51 443 if (my $filename = ($args->{'filename'} || $args->{'file'})) {
9398955f 444 $self->filename($filename);
445 }
ca10f295 446
422298aa 447 if (my $data = ($args->{'data'} || $args->{'datasource'})) {
9398955f 448 $self->data($data);
16dc9970 449 }
ca10f295 450
9398955f 451 # ----------------------------------------------------------------
452 # Get the data.
453 # ----------------------------------------------------------------
454 my $data = $self->data;
077ebf34 455
9398955f 456 # ----------------------------------------------------------------
ca10f295 457 # Local reference to the parser subroutine
9398955f 458 # ----------------------------------------------------------------
ca10f295 459 if ($parser = ($args->{'parser'} || $args->{'from'})) {
460 $self->parser($parser);
16dc9970 461 }
7a8e1f51 462 $parser = $self->parser;
463 $parser_type = $self->parser_type;
16dc9970 464
9398955f 465 # ----------------------------------------------------------------
ca10f295 466 # Local reference to the producer subroutine
9398955f 467 # ----------------------------------------------------------------
ca10f295 468 if ($producer = ($args->{'producer'} || $args->{'to'})) {
469 $self->producer($producer);
16dc9970 470 }
7a8e1f51 471 $producer = $self->producer;
472 $producer_type = $self->producer_type;
16dc9970 473
9398955f 474 # ----------------------------------------------------------------
185c34d5 475 # Execute the parser, the filters and then execute the producer.
7a8e1f51 476 # Allowances are made for each piece to die, or fail to compile,
477 # since the referenced subroutines could be almost anything. In
478 # the future, each of these might happen in a Safe environment,
479 # depending on how paranoid we want to be.
9398955f 480 # ----------------------------------------------------------------
185c34d5 481
482 # Run parser
a57ce769 483 unless ( defined $self->{'schema'} ) {
484 eval { $parser_output = $parser->($self, $$data) };
485 if ($@ || ! $parser_output) {
486 my $msg = sprintf "translate: Error with parser '%s': %s",
487 $parser_type, ($@) ? $@ : " no results";
488 return $self->error($msg);
489 }
7a8e1f51 490 }
841a3f1a 491 $self->debug("Schema =\n", Dumper($self->schema), "\n");
492
185c34d5 493 # Validate the schema if asked to.
4b6a6341 494 if ($self->validate) {
3f4af30d 495 my $schema = $self->schema;
496 return $self->error('Invalid schema') unless $schema->is_valid;
497 }
498
185c34d5 499 # Run filters
500 my $filt_num = 0;
501 foreach ($self->filters) {
502 $filt_num++;
44eb9098 503 my ($code,@args) = @$_;
504 eval { $code->($self->schema, @args) };
185c34d5 505 my $err = $@ || $self->error || 0;
506 return $self->error("Error with filter $filt_num : $err") if $err;
507 }
508
509 # Run producer
3f4af30d 510 eval { $producer_output = $producer->($self) };
7a8e1f51 511 if ($@ || ! $producer_output) {
a5d57a52 512 my $err = $@ || $self->error || "no results";
513 my $msg = "translate: Error with producer '$producer_type': $err";
c2d3a526 514 return $self->error($msg);
7a8e1f51 515 }
516
517 return $producer_output;
16dc9970 518}
ca10f295 519
d529894e 520# ----------------------------------------------------------------------
0f3778d0 521# list_parsers()
522#
523# Hacky sort of method to list all available parsers. This has
524# several problems:
525#
526# - Only finds things in the SQL::Translator::Parser namespace
527#
528# - Only finds things that are located in the same directory
529# as SQL::Translator::Parser. Yeck.
530#
531# This method will fail in several very likely cases:
532#
533# - Parser modules in different namespaces
534#
535# - Parser modules in the SQL::Translator::Parser namespace that
536# have any XS componenets will be installed in
537# arch_lib/SQL/Translator.
538#
539# ----------------------------------------------------------------------
540sub list_parsers {
ca1f2237 541 return shift->_list("parser");
0f3778d0 542}
543
544# ----------------------------------------------------------------------
545# list_producers()
546#
547# See notes for list_parsers(), above; all the problems apply to
548# list_producers as well.
549# ----------------------------------------------------------------------
c0c4aef9 550sub list_producers {
ca1f2237 551 return shift->_list("producer");
0f3778d0 552}
553
c0c4aef9 554
0f3778d0 555# ======================================================================
556# Private Methods
557# ======================================================================
c0c4aef9 558
0f3778d0 559# ----------------------------------------------------------------------
560# _args($type, \%args);
561#
562# Gets or sets ${type}_args. Called by parser_args and producer_args.
563# ----------------------------------------------------------------------
564sub _args {
565 my $self = shift;
566 my $type = shift;
567 $type = "${type}_args" unless $type =~ /_args$/;
568
569 unless (defined $self->{$type} && isa($self->{$type}, 'HASH')) {
570 $self->{$type} = { };
571 }
572
573 if (@_) {
574 # If the first argument is an explicit undef (remember, we
575 # don't get here unless there is stuff in @_), then we clear
576 # out the producer_args hash.
577 if (! defined $_[0]) {
578 shift @_;
579 %{$self->{$type}} = ();
580 }
581
582 my $args = isa($_[0], 'HASH') ? shift : { @_ };
583 %{$self->{$type}} = (%{$self->{$type}}, %$args);
584 }
585
586 $self->{$type};
c0c4aef9 587}
588
d529894e 589# ----------------------------------------------------------------------
f4a59b6c 590# Does the get/set work for parser and producer. e.g.
591# return $self->_tool({
592# name => 'producer',
593# path => "SQL::Translator::Producer",
594# default_sub => "produce",
595# }, @_);
596# ----------------------------------------------------------------------
597sub _tool {
598 my ($self,$args) = (shift, shift);
599 my $name = $args->{name};
da3a97b7 600 return $self->{$name} unless @_; # get accessor
601
602 my $path = $args->{path};
603 my $default_sub = $args->{default_sub};
f4a59b6c 604 my $tool = shift;
da3a97b7 605
f4a59b6c 606 # passed an anonymous subroutine reference
607 if (isa($tool, 'CODE')) {
608 $self->{$name} = $tool;
609 $self->{"$name\_type"} = "CODE";
610 $self->debug("Got $name: code ref\n");
da3a97b7 611 }
f4a59b6c 612
da3a97b7 613 # Module name was passed directly
614 # We try to load the name; if it doesn't load, there's a
615 # possibility that it has a function name attached to it,
616 # so we give it a go.
f4a59b6c 617 else {
f4a59b6c 618 $tool =~ s/-/::/g if $tool !~ /::/;
da3a97b7 619 my ($code,$sub);
620 ($code,$sub) = _load_sub("$tool\::$default_sub", $path);
9c0bc5a5 621 unless ($code) {
622 if ( __PACKAGE__->error =~ m/Can't find module/ ) {
623 # Mod not found so try sub
624 ($code,$sub) = _load_sub("$tool", $path) unless $code;
625 die "Can't load $name subroutine '$tool' : ".__PACKAGE__->error
626 unless $code;
627 }
628 else {
629 die "Can't load $name '$tool' : ".__PACKAGE__->error;
630 }
631 }
185c34d5 632
f4a59b6c 633 # get code reference and assign
da3a97b7 634 my (undef,$module,undef) = $sub =~ m/((.*)::)?(\w+)$/;
635 $self->{$name} = $code;
636 $self->{"$name\_type"} = $sub eq "CODE" ? "CODE" : $module;
637 $self->debug("Got $name: $sub\n");
638 }
f4a59b6c 639
640 # At this point, $self->{$name} contains a subroutine
641 # reference that is ready to run
642
643 # Anything left? If so, it's args
644 my $meth = "$name\_args";
645 $self->$meth(@_) if (@_);
646
647 return $self->{$name};
648}
649
650# ----------------------------------------------------------------------
0f3778d0 651# _list($type)
652# ----------------------------------------------------------------------
653sub _list {
3015bf96 654 my $self = shift;
655 my $type = shift || return ();
ca1f2237 656 my $uctype = ucfirst lc $type;
ca1f2237 657
3015bf96 658 #
659 # First find all the directories where SQL::Translator
660 # parsers or producers (the "type") appear to live.
661 #
ca1f2237 662 load("SQL::Translator::$uctype") or return ();
663 my $path = catfile "SQL", "Translator", $uctype;
3015bf96 664 my @dirs;
ca1f2237 665 for (@INC) {
666 my $dir = catfile $_, $path;
4b6a6341 667 $self->debug("_list_${type}s searching $dir\n");
ca1f2237 668 next unless -d $dir;
3015bf96 669 push @dirs, $dir;
ca1f2237 670 }
c0c4aef9 671
3015bf96 672 #
673 # Now use File::File::find to look recursively in those
674 # directories for all the *.pm files, then present them
675 # with the slashes turned into dashes.
676 #
677 my %found;
678 find(
679 sub {
680 if ( -f && m/\.pm$/ ) {
681 my $mod = $_;
682 $mod =~ s/\.pm$//;
683 my $cur_dir = $File::Find::dir;
04db8601 684 my $base_dir = quotemeta catfile 'SQL', 'Translator', $uctype;
3015bf96 685
686 #
687 # See if the current directory is below the base directory.
688 #
689 if ( $cur_dir =~ m/$base_dir(.*)/ ) {
690 $cur_dir = $1;
691 $cur_dir =~ s!^/!!; # kill leading slash
692 $cur_dir =~ s!/!-!g; # turn other slashes into dashes
693 }
694 else {
695 $cur_dir = '';
696 }
697
698 $found{ join '-', map { $_ || () } $cur_dir, $mod } = 1;
699 }
700 },
701 @dirs
702 );
703
704 return sort { lc $a cmp lc $b } keys %found;
c0c4aef9 705}
706
d529894e 707# ----------------------------------------------------------------------
f4a59b6c 708# load(MODULE [,PATH[,PATH]...])
0f3778d0 709#
710# Loads a Perl module. Short circuits if a module is already loaded.
f4a59b6c 711#
712# MODULE - is the name of the module to load.
713#
714# PATH - optional list of 'package paths' to look for the module in. e.g
017580f4 715# If you called load('Super::Foo' => 'My', 'Other') it will
716# try to load the mod Super::Foo then My::Super::Foo then Other::Super::Foo.
f4a59b6c 717#
718# Returns package name of the module actually loaded or false and sets error.
719#
185c34d5 720# Note, you can't load a name from the root namespace (ie one without '::' in
f4a59b6c 721# it), therefore a single word name without a path fails.
0f3778d0 722# ----------------------------------------------------------------------
ca10f295 723sub load {
f4a59b6c 724 my $name = shift;
725 my @path;
726 push @path, "" if $name =~ /::/; # Empty path to check name on its own first
727 push @path, @_ if @_;
728
729 foreach (@path) {
730 my $module = $_ ? "$_\::$name" : $name;
731 my $file = $module; $file =~ s[::][/]g; $file .= ".pm";
732 __PACKAGE__->debug("Loading $name as $file\n");
733 return $module if $INC{$file}; # Already loaded
185c34d5 734
f4a59b6c 735 eval { require $file };
736 next if $@ =~ /Can't locate $file in \@INC/;
617f79f6 737 eval { $module->import() } unless $@;
017580f4 738 return __PACKAGE__->error("Error loading $name as $module : $@")
739 if $@ && $@ !~ /"SQL::Translator::Producer" is not exported/;
f4a59b6c 740
741 return $module; # Module loaded ok
742 }
ca1f2237 743
9c0bc5a5 744 return __PACKAGE__->error("Can't find module $name. Path:".join(",",@path));
da3a97b7 745}
746
747# ----------------------------------------------------------------------
748# Load the sub name given (including package), optionally using a base package
749# path. Returns code ref and name of sub loaded, including its package.
750# (\&code, $sub) = load_sub( 'MySQL::produce', "SQL::Translator::Producer" );
751# (\&code, $sub) = load_sub( 'MySQL::produce', @path );
752# ----------------------------------------------------------------------
753sub _load_sub {
754 my ($tool, @path) = @_;
185c34d5 755
da3a97b7 756 my (undef,$module,$func_name) = $tool =~ m/((.*)::)?(\w+)$/;
757 if ( my $module = load($module => @path) ) {
758 my $sub = "$module\::$func_name";
185c34d5 759 return wantarray ? ( \&{ $sub }, $sub ) : \&$sub;
760 }
da3a97b7 761 return undef;
1fd8c91f 762}
16dc9970 763
67e5ff53 764# ----------------------------------------------------------------------
7d5bcab8 765sub format_table_name {
1ea530d4 766 return shift->_format_name('_format_table_name', @_);
7d5bcab8 767}
768
67e5ff53 769# ----------------------------------------------------------------------
7d5bcab8 770sub format_package_name {
1ea530d4 771 return shift->_format_name('_format_package_name', @_);
7d5bcab8 772}
773
67e5ff53 774# ----------------------------------------------------------------------
7d5bcab8 775sub format_fk_name {
1ea530d4 776 return shift->_format_name('_format_fk_name', @_);
7d5bcab8 777}
778
67e5ff53 779# ----------------------------------------------------------------------
7d5bcab8 780sub format_pk_name {
1ea530d4 781 return shift->_format_name('_format_pk_name', @_);
782}
783
784# ----------------------------------------------------------------------
185c34d5 785# The other format_*_name methods rely on this one. It optionally
1ea530d4 786# accepts a subroutine ref as the first argument (or uses an identity
787# sub if one isn't provided or it doesn't already exist), and applies
788# it to the rest of the arguments (if any).
789# ----------------------------------------------------------------------
790sub _format_name {
f9a0c3b5 791 my $self = shift;
1ea530d4 792 my $field = shift;
793 my @args = @_;
8a990c91 794
1ea530d4 795 if (ref($args[0]) eq 'CODE') {
796 $self->{$field} = shift @args;
8a990c91 797 }
1ea530d4 798 elsif (! exists $self->{$field}) {
799 $self->{$field} = sub { return shift };
8a990c91 800 }
801
1ea530d4 802 return @args ? $self->{$field}->(@args) : $self->{$field};
7d5bcab8 803}
804
d529894e 805# ----------------------------------------------------------------------
0f3778d0 806# isa($ref, $type)
807#
808# Calls UNIVERSAL::isa($ref, $type). I think UNIVERSAL::isa is ugly,
809# but I like function overhead.
810# ----------------------------------------------------------------------
811sub isa($$) {
812 my ($ref, $type) = @_;
813 return UNIVERSAL::isa($ref, $type);
814}
c2d3a526 815
3f4af30d 816# ----------------------------------------------------------------------
c314ec98 817# version
818#
819# Returns the $VERSION of the main SQL::Translator package.
820# ----------------------------------------------------------------------
821sub version {
822 my $self = shift;
823 return $VERSION;
824}
825
826# ----------------------------------------------------------------------
3f4af30d 827sub validate {
3f4af30d 828 my ( $self, $arg ) = @_;
829 if ( defined $arg ) {
830 $self->{'validate'} = $arg ? 1 : 0;
831 }
832 return $self->{'validate'} || 0;
833}
834
16dc9970 8351;
16dc9970 836
389b318c 837# ----------------------------------------------------------------------
838# Who killed the pork chops?
839# What price bananas?
840# Are you my Angel?
841# Allen Ginsberg
842# ----------------------------------------------------------------------
843
844=pod
0f3778d0 845
846=head1 NAME
847
954f31f1 848SQL::Translator - manipulate structured data definitions (SQL and more)
0f3778d0 849
850=head1 SYNOPSIS
851
852 use SQL::Translator;
853
67e5ff53 854 my $translator = SQL::Translator->new(
855 # Print debug info
856 debug => 1,
857 # Print Parse::RecDescent trace
185c34d5 858 trace => 0,
67e5ff53 859 # Don't include comments in output
185c34d5 860 no_comments => 0,
67e5ff53 861 # Print name mutations, conflicts
185c34d5 862 show_warnings => 0,
67e5ff53 863 # Add "drop table" statements
185c34d5 864 add_drop_table => 1,
67e5ff53 865 # Validate schema object
185c34d5 866 validate => 1,
f9a0c3b5 867 # Make all table names CAPS in producers which support this option
67e5ff53 868 format_table_name => sub {my $tablename = shift; return uc($tablename)},
f9a0c3b5 869 # Null-op formatting, only here for documentation's sake
7d5bcab8 870 format_package_name => sub {return shift},
871 format_fk_name => sub {return shift},
872 format_pk_name => sub {return shift},
0f3778d0 873 );
874
875 my $output = $translator->translate(
389b318c 876 from => 'MySQL',
877 to => 'Oracle',
f9a0c3b5 878 # Or an arrayref of filenames, i.e. [ $file1, $file2, $file3 ]
185c34d5 879 filename => $file,
0f3778d0 880 ) or die $translator->error;
881
882 print $output;
883
884=head1 DESCRIPTION
885
2d993495 886This documentation covers the API for SQL::Translator. For a more general
887discussion of how to use the modules and scripts, please see
888L<SQL::Translator::Manual>.
889
29efc9fd 890SQL::Translator is a group of Perl modules that converts
891vendor-specific SQL table definitions into other formats, such as
892other vendor-specific SQL, ER diagrams, documentation (POD and HTML),
893XML, and Class::DBI classes. The main focus of SQL::Translator is
894SQL, but parsers exist for other structured data formats, including
895Excel spreadsheets and arbitrarily delimited text files. Through the
896separation of the code into parsers and producers with an object model
897in between, it's possible to combine any parser with any producer, to
898plug in custom parsers or producers, or to manipulate the parsed data
899via the built-in object model. Presently only the definition parts of
900SQL are handled (CREATE, ALTER), not the manipulation of data (INSERT,
901UPDATE, DELETE).
0f3778d0 902
903=head1 CONSTRUCTOR
904
5760246d 905The constructor is called C<new>, and accepts a optional hash of options.
0f3778d0 906Valid options are:
907
908=over 4
909
ca251f03 910=item *
911
912parser / from
913
914=item *
915
916parser_args
0f3778d0 917
ca251f03 918=item *
0f3778d0 919
ca251f03 920producer / to
0f3778d0 921
ca251f03 922=item *
0f3778d0 923
ca251f03 924producer_args
0f3778d0 925
ca251f03 926=item *
927
185c34d5 928filters
929
930=item *
931
ca251f03 932filename / file
933
934=item *
935
936data
937
938=item *
0f3778d0 939
ca251f03 940debug
0f3778d0 941
389b318c 942=item *
943
944add_drop_table
945
946=item *
947
948no_comments
949
950=item *
951
952trace
953
954=item *
955
956validate
957
0f3778d0 958=back
959
960All options are, well, optional; these attributes can be set via
961instance methods. Internally, they are; no (non-syntactical)
962advantage is gained by passing options to the constructor.
963
964=head1 METHODS
965
5760246d 966=head2 add_drop_table
0f3778d0 967
968Toggles whether or not to add "DROP TABLE" statements just before the
969create definitions.
970
5760246d 971=head2 no_comments
0f3778d0 972
973Toggles whether to print comments in the output. Accepts a true or false
974value, returns the current value.
975
5760246d 976=head2 producer
0f3778d0 977
5760246d 978The C<producer> method is an accessor/mutator, used to retrieve or
0f3778d0 979define what subroutine is called to produce the output. A subroutine
980defined as a producer will be invoked as a function (I<not a method>)
8e1fc861 981and passed its container C<SQL::Translator> instance, which it should
982call the C<schema> method on, to get the C<SQL::Translator::Schema>
983generated by the parser. It is expected that the function transform the
984schema structure to a string. The C<SQL::Translator> instance is also useful
985for informational purposes; for example, the type of the parser can be
5760246d 986retrieved using the C<parser_type> method, and the C<error> and
987C<debug> methods can be called when needed.
0f3778d0 988
ca251f03 989When defining a producer, one of several things can be passed in: A
5760246d 990module name (e.g., C<My::Groovy::Producer>), a module name relative to
991the C<SQL::Translator::Producer> namespace (e.g., C<MySQL>), a module
ca251f03 992name and function combination (C<My::Groovy::Producer::transmogrify>),
0f3778d0 993or a reference to an anonymous subroutine. If a full module name is
994passed in (for the purposes of this method, a string containing "::"
995is considered to be a module name), it is treated as a package, and a
ca251f03 996function called "produce" will be invoked: C<$modulename::produce>.
997If $modulename cannot be loaded, the final portion is stripped off and
0f3778d0 998treated as a function. In other words, if there is no file named
ca251f03 999F<My/Groovy/Producer/transmogrify.pm>, C<SQL::Translator> will attempt
5760246d 1000to load F<My/Groovy/Producer.pm> and use C<transmogrify> as the name of
1001the function, instead of the default C<produce>.
0f3778d0 1002
1003 my $tr = SQL::Translator->new;
1004
1005 # This will invoke My::Groovy::Producer::produce($tr, $data)
1006 $tr->producer("My::Groovy::Producer");
1007
1008 # This will invoke SQL::Translator::Producer::Sybase::produce($tr, $data)
1009 $tr->producer("Sybase");
1010
1011 # This will invoke My::Groovy::Producer::transmogrify($tr, $data),
1012 # assuming that My::Groovy::Producer::transmogrify is not a module
1013 # on disk.
1014 $tr->producer("My::Groovy::Producer::transmogrify");
1015
1016 # This will invoke the referenced subroutine directly, as
1017 # $subref->($tr, $data);
1018 $tr->producer(\&my_producer);
1019
5760246d 1020There is also a method named C<producer_type>, which is a string
1021containing the classname to which the above C<produce> function
0f3778d0 1022belongs. In the case of anonymous subroutines, this method returns
1023the string "CODE".
1024
5760246d 1025Finally, there is a method named C<producer_args>, which is both an
0f3778d0 1026accessor and a mutator. Arbitrary data may be stored in name => value
1027pairs for the producer subroutine to access:
1028
1029 sub My::Random::producer {
1030 my ($tr, $data) = @_;
1031 my $pr_args = $tr->producer_args();
1032
1033 # $pr_args is a hashref.
1034
5760246d 1035Extra data passed to the C<producer> method is passed to
1036C<producer_args>:
0f3778d0 1037
1038 $tr->producer("xSV", delimiter => ',\s*');
1039
1040 # In SQL::Translator::Producer::xSV:
1041 my $args = $tr->producer_args;
1042 my $delimiter = $args->{'delimiter'}; # value is ,\s*
1043
5760246d 1044=head2 parser
0f3778d0 1045
5760246d 1046The C<parser> method defines or retrieves a subroutine that will be
0f3778d0 1047called to perform the parsing. The basic idea is the same as that of
5760246d 1048C<producer> (see above), except the default subroutine name is
ca251f03 1049"parse", and will be invoked as C<$module_name::parse($tr, $data)>.
0f3778d0 1050Also, the parser subroutine will be passed a string containing the
1051entirety of the data to be parsed.
1052
1053 # Invokes SQL::Translator::Parser::MySQL::parse()
1054 $tr->parser("MySQL");
1055
1056 # Invokes My::Groovy::Parser::parse()
1057 $tr->parser("My::Groovy::Parser");
1058
1059 # Invoke an anonymous subroutine directly
1060 $tr->parser(sub {
1061 my $dumper = Data::Dumper->new([ $_[1] ], [ "SQL" ]);
1062 $dumper->Purity(1)->Terse(1)->Deepcopy(1);
1063 return $dumper->Dump;
1064 });
1065
5760246d 1066There is also C<parser_type> and C<parser_args>, which perform
1067analogously to C<producer_type> and C<producer_args>
0f3778d0 1068
185c34d5 1069=head2 filters
1070
1071Set or retreive the filters to run over the schema during the
1072translation, before the producer creates its output. Filters are sub
1073routines called, in order, with the schema object to filter as the 1st
44eb9098 1074arg and a hash of options (passed as a list) for the rest of the args.
1075They are free to do whatever they want to the schema object, which will be
1076handed to any following filters, then used by the producer.
185c34d5 1077
1078Filters are set as an array, which gives the order they run in.
1079Like parsers and producers, they can be defined by a module name, a
1080module name relative to the SQL::Translator::Filter namespace, a module
1081name and function name together or a reference to an anonymous subroutine.
1082When using a module name a function called C<filter> will be invoked in
44eb9098 1083that package to do the work.
1084
1085To pass args to the filter set it as an array ref with the 1st value giving
1086the filter (name or sub) and the rest its args. e.g.
185c34d5 1087
1088 $tr->filters(
1089 sub {
1090 my $schema = shift;
1091 # Do stuff to schema here!
1092 },
44eb9098 1093 DropFKeys,
1094 [ "Names", table => 'lc' ],
1095 [ "Foo", foo => "bar", hello => "world" ],
1096 [ "Filter5" ],
185c34d5 1097 );
1098
44eb9098 1099Although you normally set them in the constructor, which calls
185c34d5 1100through to filters. i.e.
1101
1102 my $translator = SQL::Translator->new(
1103 ...
1104 filters => [
1105 sub { ... },
44eb9098 1106 [ "Names", table => 'lc' ],
185c34d5 1107 ],
1108 ...
1109 );
1110
1111See F<t/36-filters.t> for more examples.
1112
1113Multiple set calls to filters are cumulative with new filters added to
1114the end of the current list.
1115
1116Returns the filters as a list of array refs, the 1st value being a
44eb9098 1117reference to the filter sub and the rest its args.
185c34d5 1118
5760246d 1119=head2 show_warnings
0f3778d0 1120
1121Toggles whether to print warnings of name conflicts, identifier
1122mutations, etc. Probably only generated by producers to let the user
1123know when something won't translate very smoothly (e.g., MySQL "enum"
1124fields into Oracle). Accepts a true or false value, returns the
1125current value.
1126
5760246d 1127=head2 translate
0f3778d0 1128
185c34d5 1129The C<translate> method calls the subroutine referenced by the
1130C<parser> data member, then calls any C<filters> and finally calls
1131the C<producer> sub routine (these members are described above).
1132It accepts as arguments a number of things, in key => value format,
1133including (potentially) a parser and a producer (they are passed
1134directly to the C<parser> and C<producer> methods).
0f3778d0 1135
5760246d 1136Here is how the parameter list to C<translate> is parsed:
0f3778d0 1137
1138=over
1139
1140=item *
1141
11421 argument means it's the data to be parsed; which could be a string
ca251f03 1143(filename) or a reference to a scalar (a string stored in memory), or a
0f3778d0 1144reference to a hash, which is parsed as being more than one argument
1145(see next section).
1146
1147 # Parse the file /path/to/datafile
1148 my $output = $tr->translate("/path/to/datafile");
1149
1150 # Parse the data contained in the string $data
1151 my $output = $tr->translate(\$data);
1152
1153=item *
1154
1155More than 1 argument means its a hash of things, and it might be
1156setting a parser, producer, or datasource (this key is named
1157"filename" or "file" if it's a file, or "data" for a SCALAR reference.
1158
1159 # As above, parse /path/to/datafile, but with different producers
1160 for my $prod ("MySQL", "XML", "Sybase") {
1161 print $tr->translate(
1162 producer => $prod,
1163 filename => "/path/to/datafile",
1164 );
1165 }
1166
1167 # The filename hash key could also be:
1168 datasource => \$data,
1169
1170You get the idea.
1171
1172=back
1173
5760246d 1174=head2 filename, data
0f3778d0 1175
5760246d 1176Using the C<filename> method, the filename of the data to be parsed
1177can be set. This method can be used in conjunction with the C<data>
1178method, below. If both the C<filename> and C<data> methods are
1179invoked as mutators, the data set in the C<data> method is used.
0f3778d0 1180
1181 $tr->filename("/my/data/files/create.sql");
1182
1183or:
1184
1185 my $create_script = do {
1186 local $/;
1187 open CREATE, "/my/data/files/create.sql" or die $!;
1188 <CREATE>;
1189 };
1190 $tr->data(\$create_script);
1191
5760246d 1192C<filename> takes a string, which is interpreted as a filename.
1193C<data> takes a reference to a string, which is used as the data to be
0f3778d0 1194parsed. If a filename is set, then that file is opened and read when
5760246d 1195the C<translate> method is called, as long as the data instance
0f3778d0 1196variable is not set.
1197
45ee6be0 1198=head2 schema
1199
1200Returns the SQL::Translator::Schema object.
1201
5760246d 1202=head2 trace
0f3778d0 1203
1204Turns on/off the tracing option of Parse::RecDescent.
1205
389b318c 1206=head2 validate
1207
1208Whether or not to validate the schema object after parsing and before
1209producing.
1210
c314ec98 1211=head2 version
1212
1213Returns the version of the SQL::Translator release.
1214
7a8e1f51 1215=head1 AUTHORS
16dc9970 1216
841a3f1a 1217The following people have contributed to the SQLFairy project:
1218
1219=over 4
1220
1221=item * Mark Addison <grommit@users.sourceforge.net>
1222
1223=item * Sam Angiuoli <angiuoli@users.sourceforge.net>
1224
d09e5700 1225=item * Dave Cash <dave@gnofn.org>
1226
841a3f1a 1227=item * Darren Chamberlain <dlc@users.sourceforge.net>
1228
1229=item * Ken Y. Clark <kclark@cpan.org>
1230
1231=item * Allen Day <allenday@users.sourceforge.net>
1232
1233=item * Paul Harrington <phrrngtn@users.sourceforge.net>
1234
1235=item * Mikey Melillo <mmelillo@users.sourceforge.net>
1236
1237=item * Chris Mungall <cjm@fruitfly.org>
1238
1239=item * Ross Smith II <rossta@users.sf.net>
1240
1241=item * Gudmundur A. Thorisson <mummi@cshl.org>
1242
1243=item * Chris To <christot@users.sourceforge.net>
1244
1245=item * Jason Williams <smdwilliams@users.sourceforge.net>
1246
1247=item * Ying Zhang <zyolive@yahoo.com>
1248
1249=back
1250
1251If you would like to contribute to the project, you can send patches
1252to the developers mailing list:
1253
1254 sqlfairy-developers@lists.sourceforge.net
1255
1256Or send us a message (with your Sourceforge username) asking to be
1257added to the project and what you'd like to contribute.
1258
dfb4c915 1259
ca10f295 1260=head1 COPYRIGHT
16dc9970 1261
ca10f295 1262This program is free software; you can redistribute it and/or modify
1263it under the terms of the GNU General Public License as published by
1264the Free Software Foundation; version 2.
dfb4c915 1265
ca10f295 1266This program is distributed in the hope that it will be useful, but
1267WITHOUT ANY WARRANTY; without even the implied warranty of
1268MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1269General Public License for more details.
16dc9970 1270
ca10f295 1271You should have received a copy of the GNU General Public License
1272along with this program; if not, write to the Free Software
1273Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
1274USA
16dc9970 1275
87bf8a3a 1276=head1 BUGS
1277
841a3f1a 1278Please use L<http://rt.cpan.org/> for reporting bugs.
1279
1280=head1 PRAISE
1281
1282If you find this module useful, please use
1283L<http://cpanratings.perl.org/rate/?distribution=SQL-Translator> to rate it.
87bf8a3a 1284
16dc9970 1285=head1 SEE ALSO
1286
abfa405a 1287L<perl>,
1288L<SQL::Translator::Parser>,
1289L<SQL::Translator::Producer>,
389b318c 1290L<Parse::RecDescent>,
1291L<GD>,
1292L<GraphViz>,
1293L<Text::RecordParser>,
841a3f1a 1294L<Class::DBI>,
389b318c 1295L<XML::Writer>.