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