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