Updated an example to make it happier.
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator.pm
CommitLineData
16dc9970 1package SQL::Translator;
2
b346d8f1 3# ----------------------------------------------------------------------
52b828e8 4# $Id: Translator.pm,v 1.13 2002-11-25 14:48:34 dlc Exp $
b346d8f1 5# ----------------------------------------------------------------------
d529894e 6# Copyright (C) 2002 Ken Y. Clark <kclark@cpan.org>,
077ebf34 7# darren chamberlain <darren@cpan.org>
1fd8c91f 8#
077ebf34 9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License as
11# published by the Free Software Foundation; version 2.
ca10f295 12#
077ebf34 13# This program is distributed in the hope that it will be useful, but
14# WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16# General Public License for more details.
ca10f295 17#
077ebf34 18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21# 02111-1307 USA
ca10f295 22# -------------------------------------------------------------------
23
24=head1 NAME
25
26SQL::Translator - convert schema from one database to another
27
28=head1 SYNOPSIS
29
30 use SQL::Translator;
d529894e 31
32 my $translator = SQL::Translator->new(
33 xlate => $xlate || {}, # Overrides for field translation
34 debug => $debug, # Print debug info
35 trace => $trace, # Print Parse::RecDescent trace
36 no_comments => $no_comments, # Don't include comments in output
37 );
38
49e1eb70 39 my $output = $translator->translate(
40 from => "MySQL",
41 to => "Oracle",
42 filename => $file,
43 ) or die $translator->error;
d529894e 44
ca10f295 45 print $output;
46
47=head1 DESCRIPTION
48
49This module attempts to simplify the task of converting one database
7a8e1f51 50create syntax to another through the use of Parsers (which understand
51the sourced format) and Producers (which understand the destination
52format). The idea is that any Parser can be used with any Producer in
53the conversion process. So, if you wanted PostgreSQL-to-Oracle, you
54would use the PostgreSQL parser and the Oracle producer.
ca10f295 55
56=cut
16dc9970 57
58use strict;
d529894e 59use vars qw( $VERSION $REVISION $DEFAULT_SUB $DEBUG $ERROR );
49e1eb70 60use base 'Class::Base';
c2d3a526 61
d529894e 62$VERSION = '0.01';
52b828e8 63$REVISION = sprintf "%d.%02d", q$Revision: 1.13 $ =~ /(\d+)\.(\d+)/;
d529894e 64$DEBUG = 0 unless defined $DEBUG;
65$ERROR = "";
c2d3a526 66
67use Carp qw(carp);
16dc9970 68
c0c4aef9 69use File::Spec::Functions qw(catfile);
70use File::Basename qw(dirname);
71use IO::Dir;
72
b346d8f1 73# ----------------------------------------------------------------------
74# The default behavior is to "pass through" values (note that the
75# SQL::Translator instance is the first value ($_[0]), and the stuff
76# to be parsed is the second value ($_[1])
77# ----------------------------------------------------------------------
78$DEFAULT_SUB = sub { $_[1] } unless defined $DEFAULT_SUB;
16dc9970 79
ca10f295 80=head1 CONSTRUCTOR
16dc9970 81
077ebf34 82The constructor is called B<new>, and accepts a optional hash of options.
ca10f295 83Valid options are:
16dc9970 84
ca10f295 85=over 4
86
87=item parser (aka from)
88
9398955f 89=item parser_args
90
ca10f295 91=item producer (aka to)
92
9398955f 93=item producer_args
94
95=item filename (aka file)
96
97=item data
98
99=item debug
ca10f295 100
101=back
102
103All options are, well, optional; these attributes can be set via
b346d8f1 104instance methods. Internally, they are; no (non-syntactical)
105advantage is gained by passing options to the constructor.
ca10f295 106
107=cut
108
b346d8f1 109# ----------------------------------------------------------------------
c2d3a526 110# init([ARGS])
b346d8f1 111# The constructor.
dfb4c915 112#
b346d8f1 113# new takes an optional hash of arguments. These arguments may
114# include a parser, specified with the keys "parser" or "from",
115# and a producer, specified with the keys "producer" or "to".
dfb4c915 116#
b346d8f1 117# The values that can be passed as the parser or producer are
118# given directly to the parser or producer methods, respectively.
119# See the appropriate method description below for details about
120# what each expects/accepts.
b346d8f1 121# ----------------------------------------------------------------------
c2d3a526 122sub init {
49e1eb70 123 my ( $self, $config ) = @_;
1fd8c91f 124
49e1eb70 125 #
b346d8f1 126 # Set the parser and producer.
ca10f295 127 #
b346d8f1 128 # If a 'parser' or 'from' parameter is passed in, use that as the
129 # parser; if a 'producer' or 'to' parameter is passed in, use that
130 # as the producer; both default to $DEFAULT_SUB.
49e1eb70 131 #
132 $self->parser ($config->{'parser'} || $config->{'from'} || $DEFAULT_SUB);
c2d3a526 133 $self->producer($config->{'producer'} || $config->{'to'} || $DEFAULT_SUB);
ca10f295 134
49e1eb70 135 #
e2158c40 136 # Set the parser_args and producer_args
49e1eb70 137 #
138 for my $pargs ( qw[ parser_args producer_args ] ) {
139 $self->$pargs( $config->{$pargs} ) if defined $config->{ $pargs };
e2158c40 140 }
141
49e1eb70 142 #
9398955f 143 # Set the data source, if 'filename' or 'file' is provided.
49e1eb70 144 #
c2d3a526 145 $config->{'filename'} ||= $config->{'file'} || "";
49e1eb70 146 $self->filename( $config->{'filename'} ) if $config->{'filename'};
9398955f 147
49e1eb70 148 #
149 # Finally, if there is a 'data' parameter, use that in
150 # preference to filename and file
151 #
152 if ( my $data = $config->{'data'} ) {
153 $self->data( $data );
9398955f 154 }
155
d529894e 156 #
157 # Set various other options.
158 #
49e1eb70 159 $self->{'debug'} = defined $config->{'debug'} ? $config->{'debug'} : $DEBUG;
ca10f295 160
d529894e 161 $self->trace( $config->{'trace'} );
162
163 $self->custom_translate( $config->{'xlate'} );
164
165 $self->no_comments( $config->{'no_comments'} );
166
ca10f295 167 return $self;
dfb4c915 168}
1fd8c91f 169
ca10f295 170=head1 METHODS
171
d529894e 172# ----------------------------------------------------------------------
173=head2 B<custom_translate>
174
175Allows the user to override default translation of fields. For example,
176if a MySQL "text" field would normally be converted to a "long" for Oracle,
177the user could specify to change it to a "CLOB." Accepts a hashref where
178keys are the "from" value and values are the "to," returns the current
179value of the field.
180
181=cut
182
183sub custom_translate {
184 my $self = shift;
185 $self->{'custom_translate'} = shift if @_;
186 return $self->{'custom_translate'} || {};
187}
188
189# ----------------------------------------------------------------------
190=head2 B<no_comments>
191
192Toggles whether to print comments in the output. Accepts a true or false
193value, returns the current value.
194
195=cut
196
197sub no_comments {
198 my $self = shift;
199 my $arg = shift;
200 if ( defined $arg ) {
201 $self->{'no_comments'} = $arg ? 1 : 0;
202 }
203 return $self->{'no_comments'} || 0;
204}
205
206# ----------------------------------------------------------------------
ca10f295 207=head2 B<producer>
208
209The B<producer> method is an accessor/mutator, used to retrieve or
210define what subroutine is called to produce the output. A subroutine
b346d8f1 211defined as a producer will be invoked as a function (not a method) and
212passed 2 parameters: its container SQL::Translator instance and a
213data structure. It is expected that the function transform the data
214structure to a string. The SQL::Transformer instance is provided for
215informational purposes; for example, the type of the parser can be
216retrieved using the B<parser_type> method, and the B<error> and
217B<debug> methods can be called when needed.
218
219When defining a producer, one of several things can be passed
220in: A module name (e.g., My::Groovy::Producer), a module name
221relative to the SQL::Translator::Producer namespace (e.g., MySQL), a
222module name and function combination (My::Groovy::Producer::transmogrify),
223or a reference to an anonymous subroutine. If a full module name is
224passed in (for the purposes of this method, a string containing "::"
225is considered to be a module name), it is treated as a package, and a
226function called "produce" will be invoked: $modulename::produce. If
227$modulename cannot be loaded, the final portion is stripped off and
228treated as a function. In other words, if there is no file named
229My/Groovy/Producer/transmogrify.pm, SQL::Translator will attempt to load
230My/Groovy/Producer.pm and use transmogrify as the name of the function,
231instead of the default "produce".
ca10f295 232
233 my $tr = SQL::Translator->new;
234
077ebf34 235 # This will invoke My::Groovy::Producer::produce($tr, $data)
ca10f295 236 $tr->producer("My::Groovy::Producer");
237
077ebf34 238 # This will invoke SQL::Translator::Producer::Sybase::produce($tr, $data)
ca10f295 239 $tr->producer("Sybase");
240
b346d8f1 241 # This will invoke My::Groovy::Producer::transmogrify($tr, $data),
242 # assuming that My::Groovy::Producer::transmogrify is not a module
243 # on disk.
e2158c40 244 $tr->producer("My::Groovy::Producer::transmogrify");
b346d8f1 245
077ebf34 246 # This will invoke the referenced subroutine directly, as
247 # $subref->($tr, $data);
ca10f295 248 $tr->producer(\&my_producer);
249
077ebf34 250There is also a method named B<producer_type>, which is a string
251containing the classname to which the above B<produce> function
252belongs. In the case of anonymous subroutines, this method returns
253the string "CODE".
254
e2158c40 255Finally, there is a method named B<producer_args>, which is both an
256accessor and a mutator. Arbitrary data may be stored in name => value
257pairs for the producer subroutine to access:
258
259 sub My::Random::producer {
260 my ($tr, $data) = @_;
261 my $pr_args = $tr->producer_args();
262
263 # $pr_args is a hashref.
264
265Extra data passed to the B<producer> method is passed to
266B<producer_args>:
267
268 $tr->producer("xSV", delimiter => ',\s*');
269
270 # In SQL::Translator::Producer::xSV:
271 my $args = $tr->producer_args;
7a8e1f51 272 my $delimiter = $args->{'delimiter'}; # value is ,\s*
e2158c40 273
ca10f295 274=cut
ca10f295 275
7a8e1f51 276# producer and producer_type
ca10f295 277sub producer {
1fd8c91f 278 my $self = shift;
b346d8f1 279
7a8e1f51 280 # producer as a mutator
ca10f295 281 if (@_) {
282 my $producer = shift;
b346d8f1 283
7a8e1f51 284 # Passed a module name (string containing "::")
ca10f295 285 if ($producer =~ /::/) {
077ebf34 286 my $func_name;
b346d8f1 287
7a8e1f51 288 # Module name was passed directly
b346d8f1 289 # We try to load the name; if it doesn't load, there's
290 # a possibility that it has a function name attached to
291 # it.
077ebf34 292 if (load($producer)) {
293 $func_name = "produce";
7a8e1f51 294 }
b346d8f1 295
7a8e1f51 296 # Module::function was passed
b346d8f1 297 else {
298 # Passed Module::Name::function; try to recover
077ebf34 299 my @func_parts = split /::/, $producer;
300 $func_name = pop @func_parts;
301 $producer = join "::", @func_parts;
b346d8f1 302
303 # If this doesn't work, then we have a legitimate
304 # problem.
077ebf34 305 load($producer) or die "Can't load $producer: $@";
7a8e1f51 306 }
077ebf34 307
7a8e1f51 308 # get code reference and assign
077ebf34 309 $self->{'producer'} = \&{ "$producer\::$func_name" };
310 $self->{'producer_type'} = $producer;
49e1eb70 311 $self->debug("Got producer: $producer\::$func_name\n");
7a8e1f51 312 }
b346d8f1 313
7a8e1f51 314 # passed an anonymous subroutine reference
b346d8f1 315 elsif (isa($producer, 'CODE')) {
ca10f295 316 $self->{'producer'} = $producer;
077ebf34 317 $self->{'producer_type'} = "CODE";
49e1eb70 318 $self->debug("Got producer: code ref\n");
7a8e1f51 319 }
b346d8f1 320
7a8e1f51 321 # passed a string containing no "::"; relative package name
b346d8f1 322 else {
ca10f295 323 my $Pp = sprintf "SQL::Translator::Producer::$producer";
324 load($Pp) or die "Can't load $Pp: $@";
077ebf34 325 $self->{'producer'} = \&{ "$Pp\::produce" };
326 $self->{'producer_type'} = $Pp;
49e1eb70 327 $self->debug("Got producer: $Pp\n");
7a8e1f51 328 }
b346d8f1 329
ca10f295 330 # At this point, $self->{'producer'} contains a subroutine
b346d8f1 331 # reference that is ready to run
e2158c40 332
7a8e1f51 333 # Anything left? If so, it's producer_args
334 $self->producer_args(@_) if (@_);
335 }
b346d8f1 336
ca10f295 337 return $self->{'producer'};
338};
077ebf34 339
7a8e1f51 340# ----------------------------------------------------------------------
341# producer_type
342#
e2158c40 343# producer_type is an accessor that allows producer subs to get
344# information about their origin. This is poptentially important;
345# since all producer subs are called as subroutine refernces, there is
346# no way for a producer to find out which package the sub lives in
347# originally, for example.
7a8e1f51 348# ----------------------------------------------------------------------
349sub producer_type { $_[0]->{'producer_type'} }
e2158c40 350
7a8e1f51 351# ----------------------------------------------------------------------
352# producer_args
353#
e2158c40 354# Arbitrary name => value pairs of paramters can be passed to a
355# producer using this method.
52b828e8 356#
357# XXX All calls to producer_args with a value clobbers old values!
358# Should probably check if $_[0] is undef, and delete stored
359# args if it is:
360#
361# if (@_) {
362# unless (defined $_[0]) {
363# %{ $self->{'producer_args'} } = ();
364# }
365# my $args = isa($_[0], 'HASH') ? shift : { @_ };
366# %{ $self->{'producer_args'} } = (
367# %{ $self->{'producer_args'} },
368# %{ $args }
369# );
370# }
7a8e1f51 371# ----------------------------------------------------------------------
e2158c40 372sub producer_args {
373 my $self = shift;
374 if (@_) {
375 my $args = isa($_[0], 'HASH') ? shift : { @_ };
376 $self->{'producer_args'} = $args;
377 }
378 $self->{'producer_args'};
7a8e1f51 379}
ca10f295 380
d529894e 381# ----------------------------------------------------------------------
ca10f295 382=head2 B<parser>
383
384The B<parser> method defines or retrieves a subroutine that will be
385called to perform the parsing. The basic idea is the same as that of
386B<producer> (see above), except the default subroutine name is
077ebf34 387"parse", and will be invoked as $module_name::parse($tr, $data).
388Also, the parser subroutine will be passed a string containing the
52b828e8 389entirety of the data to be parsed.
ca10f295 390
391 # Invokes SQL::Translator::Parser::MySQL::parse()
392 $tr->parser("MySQL");
393
394 # Invokes My::Groovy::Parser::parse()
395 $tr->parser("My::Groovy::Parser");
396
397 # Invoke an anonymous subroutine directly
398 $tr->parser(sub {
077ebf34 399 my $dumper = Data::Dumper->new([ $_[1] ], [ "SQL" ]);
ca10f295 400 $dumper->Purity(1)->Terse(1)->Deepcopy(1);
401 return $dumper->Dump;
402 });
403
e2158c40 404There is also B<parser_type> and B<parser_args>, which perform
405analogously to B<producer_type> and B<producer_args>
406
ca10f295 407=cut
408
ca10f295 409sub parser {
410 my $self = shift;
b346d8f1 411
7a8e1f51 412 # parser as a mutator
ca10f295 413 if (@_) {
414 my $parser = shift;
b346d8f1 415
7a8e1f51 416 # Passed a module name (string containing "::")
ca10f295 417 if ($parser =~ /::/) {
b346d8f1 418 my $func_name;
419
7a8e1f51 420 # Module name was passed directly
b346d8f1 421 # We try to load the name; if it doesn't load, there's
422 # a possibility that it has a function name attached to
423 # it.
424 if (load($parser)) {
425 $func_name = "parse";
7a8e1f51 426 }
b346d8f1 427
7a8e1f51 428 # Module::function was passed
b346d8f1 429 else {
430 # Passed Module::Name::function; try to recover
431 my @func_parts = split /::/, $parser;
432 $func_name = pop @func_parts;
433 $parser = join "::", @func_parts;
434
435 # If this doesn't work, then we have a legitimate
436 # problem.
437 load($parser) or die "Can't load $parser: $@";
7a8e1f51 438 }
b346d8f1 439
7a8e1f51 440 # get code reference and assign
b346d8f1 441 $self->{'parser'} = \&{ "$parser\::$func_name" };
077ebf34 442 $self->{'parser_type'} = $parser;
49e1eb70 443 $self->debug("Got parser: $parser\::$func_name\n");
7a8e1f51 444 }
b346d8f1 445
7a8e1f51 446 # passed an anonymous subroutine reference
49e1eb70 447 elsif ( isa( $parser, 'CODE' ) ) {
448 $self->{'parser'} = $parser;
077ebf34 449 $self->{'parser_type'} = "CODE";
49e1eb70 450 $self->debug("Got parser: code ref\n");
7a8e1f51 451 }
b346d8f1 452
7a8e1f51 453 # passed a string containing no "::"; relative package name
b346d8f1 454 else {
49e1eb70 455 my $Pp = "SQL::Translator::Parser::$parser";
456 load( $Pp ) or die "Can't load $Pp: $@";
457 $self->{'parser'} = \&{ "$Pp\::parse" };
077ebf34 458 $self->{'parser_type'} = $Pp;
49e1eb70 459 $self->debug("Got parser: $Pp\n");
7a8e1f51 460 }
b346d8f1 461
49e1eb70 462 #
b346d8f1 463 # At this point, $self->{'parser'} contains a subroutine
464 # reference that is ready to run
49e1eb70 465 #
466 $self->parser_args( @_ ) if (@_);
7a8e1f51 467 }
b346d8f1 468
ca10f295 469 return $self->{'parser'};
16dc9970 470}
1fd8c91f 471
d529894e 472# ----------------------------------------------------------------------
077ebf34 473sub parser_type { $_[0]->{'parser_type'} }
e2158c40 474
d529894e 475# ----------------------------------------------------------------------
52b828e8 476# XXX See notes on producer_args, above
e2158c40 477sub parser_args {
478 my $self = shift;
479 if (@_) {
480 my $args = isa($_[0], 'HASH') ? shift : { @_ };
481 $self->{'parser_args'} = $args;
482 }
483 $self->{'parser_args'};
7a8e1f51 484}
16dc9970 485
d529894e 486# ----------------------------------------------------------------------
ca10f295 487=head2 B<translate>
488
489The B<translate> method calls the subroutines referenced by the
490B<parser> and B<producer> data members (described above). It accepts
491as arguments a number of things, in key => value format, including
492(potentially) a parser and a producer (they are passed directly to the
493B<parser> and B<producer> methods).
494
495Here is how the parameter list to B<translate> is parsed:
496
497=over
498
499=item *
500
5011 argument means it's the data to be parsed; which could be a string
b346d8f1 502(filename) or a refernce to a scalar (a string stored in memory), or a
503reference to a hash, which is parsed as being more than one argument
504(see next section).
ca10f295 505
506 # Parse the file /path/to/datafile
507 my $output = $tr->translate("/path/to/datafile");
508
b346d8f1 509 # Parse the data contained in the string $data
ca10f295 510 my $output = $tr->translate(\$data);
511
512=item *
513
077ebf34 514More than 1 argument means its a hash of things, and it might be
515setting a parser, producer, or datasource (this key is named
b346d8f1 516"filename" or "file" if it's a file, or "data" for a SCALAR reference.
ca10f295 517
518 # As above, parse /path/to/datafile, but with different producers
519 for my $prod ("MySQL", "XML", "Sybase") {
520 print $tr->translate(
521 producer => $prod,
522 filename => "/path/to/datafile",
523 );
524 }
525
526 # The filename hash key could also be:
ca10f295 527 datasource => \$data,
528
529You get the idea.
530
531=back
532
d529894e 533# ----------------------------------------------------------------------
9398955f 534=head2 B<filename>, B<data>
535
536Using the B<filename> method, the filename of the data to be parsed
537can be set. This method can be used in conjunction with the B<data>
538method, below. If both the B<filename> and B<data> methods are
539invoked as mutators, the data set in the B<data> method is used.
540
541 $tr->filename("/my/data/files/create.sql");
542
543or:
544
545 my $create_script = do {
546 local $/;
547 open CREATE, "/my/data/files/create.sql" or die $!;
548 <CREATE>;
549 };
550 $tr->data(\$create_script);
551
552B<filename> takes a string, which is interpreted as a filename.
38254289 553B<data> takes a reference to a string, which is used as the data to be
9398955f 554parsed. If a filename is set, then that file is opened and read when
555the B<translate> method is called, as long as the data instance
556variable is not set.
557
ca10f295 558=cut
559
7a8e1f51 560# filename - get or set the filename
9398955f 561sub filename {
562 my $self = shift;
563 if (@_) {
7a8e1f51 564 my $filename = shift;
565 if (-d $filename) {
566 my $msg = "Cannot use directory '$filename' as input source";
c2d3a526 567 return $self->error($msg);
7a8e1f51 568 } elsif (-f _ && -r _) {
569 $self->{'filename'} = $filename;
49e1eb70 570 $self->debug("Got filename: '$self->{'filename'}'\n");
7a8e1f51 571 } else {
572 my $msg = "Cannot use '$filename' as input source: ".
573 "file does not exist or is not readable.";
c2d3a526 574 return $self->error($msg);
7a8e1f51 575 }
9398955f 576 }
7a8e1f51 577
9398955f 578 $self->{'filename'};
7a8e1f51 579}
9398955f 580
d529894e 581# ----------------------------------------------------------------------
7a8e1f51 582# data - get or set the data
9398955f 583# if $self->{'data'} is not set, but $self->{'filename'} is, then
584# $self->{'filename'} is opened and read, whith the results put into
585# $self->{'data'}.
586sub data {
587 my $self = shift;
588
7a8e1f51 589 # Set $self->{'data'} to $_[0], if it is provided.
9398955f 590 if (@_) {
591 my $data = shift;
592 if (isa($data, "SCALAR")) {
593 $self->{'data'} = $data;
594 }
595 elsif (! ref $data) {
596 $self->{'data'} = \$data;
597 }
598 }
9398955f 599
7a8e1f51 600 # If we have a filename but no data yet, populate.
9398955f 601 if (not $self->{'data'} and my $filename = $self->filename) {
49e1eb70 602 $self->debug("Opening '$filename' to get contents.\n");
9398955f 603 local *FH;
604 local $/;
605 my $data;
606
607 unless (open FH, $filename) {
49e1eb70 608 return $self->error("Can't read file '$filename': $!");
9398955f 609 }
610
611 $data = <FH>;
612 $self->{'data'} = \$data;
613
614 unless (close FH) {
49e1eb70 615 return $self->error("Can't close file '$filename': $!");
9398955f 616 }
617 }
9398955f 618
619 return $self->{'data'};
7a8e1f51 620}
9398955f 621
d529894e 622# ----------------------------------------------------------------------
623=pod
624
625=head2 B<trace>
626
627Turns on/off the tracing option of Parse::RecDescent.
628
629=cut
630
631sub trace {
632 my $self = shift;
633 my $arg = shift;
634 if ( defined $arg ) {
635 $self->{'trace'} = $arg ? 1 : 0;
636 }
637 return $self->{'trace'} || 0;
638}
639
640# ----------------------------------------------------------------------
16dc9970 641sub translate {
ca10f295 642 my $self = shift;
7a8e1f51 643 my ($args, $parser, $parser_type, $producer, $producer_type);
644 my ($parser_output, $producer_output);
ca10f295 645
7a8e1f51 646 # Parse arguments
9398955f 647 if (@_ == 1) {
7a8e1f51 648 # Passed a reference to a hash?
ca10f295 649 if (isa($_[0], 'HASH')) {
7a8e1f51 650 # yep, a hashref
49e1eb70 651 $self->debug("translate: Got a hashref\n");
ca10f295 652 $args = $_[0];
653 }
9398955f 654
7a8e1f51 655 # Passed a reference to a string containing the data
ca10f295 656 elsif (isa($_[0], 'SCALAR')) {
9398955f 657 # passed a ref to a string
49e1eb70 658 $self->debug("translate: Got a SCALAR reference (string)\n");
9398955f 659 $self->data($_[0]);
ca10f295 660 }
9398955f 661
7a8e1f51 662 # Not a reference; treat it as a filename
b346d8f1 663 elsif (! ref $_[0]) {
ca10f295 664 # Not a ref, it's a filename
49e1eb70 665 $self->debug("translate: Got a filename\n");
9398955f 666 $self->filename($_[0]);
ca10f295 667 }
9398955f 668
7a8e1f51 669 # Passed something else entirely.
b346d8f1 670 else {
671 # We're not impressed. Take your empty string and leave.
38254289 672 # return "";
673
7a8e1f51 674 # Actually, if data, parser, and producer are set, then we
675 # can continue. Too bad, because I like my comment
676 # (above)...
38254289 677 return "" unless ($self->data &&
678 $self->producer &&
679 $self->parser);
b346d8f1 680 }
16dc9970 681 }
682 else {
b346d8f1 683 # You must pass in a hash, or you get nothing.
684 return "" if @_ % 2;
ca10f295 685 $args = { @_ };
7a8e1f51 686 }
16dc9970 687
9398955f 688 # ----------------------------------------------------------------------
689 # Can specify the data to be transformed using "filename", "file",
7a8e1f51 690 # "data", or "datasource".
9398955f 691 # ----------------------------------------------------------------------
7a8e1f51 692 if (my $filename = ($args->{'filename'} || $args->{'file'})) {
9398955f 693 $self->filename($filename);
694 }
ca10f295 695
7a8e1f51 696 if (my $data = ($self->{'data'} || $self->{'datasource'})) {
9398955f 697 $self->data($data);
16dc9970 698 }
ca10f295 699
9398955f 700 # ----------------------------------------------------------------
701 # Get the data.
702 # ----------------------------------------------------------------
703 my $data = $self->data;
7a8e1f51 704 unless (length $$data) {
c2d3a526 705 return $self->error("Empty data file!");
9398955f 706 }
077ebf34 707
9398955f 708 # ----------------------------------------------------------------
ca10f295 709 # Local reference to the parser subroutine
9398955f 710 # ----------------------------------------------------------------
ca10f295 711 if ($parser = ($args->{'parser'} || $args->{'from'})) {
712 $self->parser($parser);
16dc9970 713 }
7a8e1f51 714 $parser = $self->parser;
715 $parser_type = $self->parser_type;
16dc9970 716
9398955f 717 # ----------------------------------------------------------------
ca10f295 718 # Local reference to the producer subroutine
9398955f 719 # ----------------------------------------------------------------
ca10f295 720 if ($producer = ($args->{'producer'} || $args->{'to'})) {
721 $self->producer($producer);
16dc9970 722 }
7a8e1f51 723 $producer = $self->producer;
724 $producer_type = $self->producer_type;
16dc9970 725
9398955f 726 # ----------------------------------------------------------------
7a8e1f51 727 # Execute the parser, then execute the producer with that output.
728 # Allowances are made for each piece to die, or fail to compile,
729 # since the referenced subroutines could be almost anything. In
730 # the future, each of these might happen in a Safe environment,
731 # depending on how paranoid we want to be.
9398955f 732 # ----------------------------------------------------------------
7a8e1f51 733 eval { $parser_output = $parser->($self, $$data) };
734 if ($@ || ! $parser_output) {
735 my $msg = sprintf "translate: Error with parser '%s': %s",
736 $parser_type, ($@) ? $@ : " no results";
c2d3a526 737 return $self->error($msg);
7a8e1f51 738 }
739
740 eval { $producer_output = $producer->($self, $parser_output) };
741 if ($@ || ! $producer_output) {
742 my $msg = sprintf "translate: Error with producer '%s': %s",
743 $producer_type, ($@) ? $@ : " no results";
c2d3a526 744 return $self->error($msg);
7a8e1f51 745 }
746
747 return $producer_output;
16dc9970 748}
ca10f295 749
d529894e 750# ----------------------------------------------------------------------
c0c4aef9 751sub list_producers {
752 require SQL::Translator::Producer;
753 my $path = catfile(dirname($INC{'SQL/Translator/Producer.pm'}), "Producer");
754 my $dh = IO::Dir->new($path);
755
756 my @available = map { join "::", "SQL::Translator::Producer", $_ }
757 grep /\.pm$/, $dh->read;
758
759 return @available;
760}
761
d529894e 762# ----------------------------------------------------------------------
c0c4aef9 763sub list_parsers {
764 require SQL::Translator::Parser;
765 my $path = catfile(dirname($INC{'SQL/Translator/Parser.pm'}), "Parser");
766 my $dh = IO::Dir->new($path);
767
768 my @available = map { join "::", "SQL::Translator::Parser", $_ }
769 grep /\.pm$/, $dh->read;
770
771 return @available;
772}
773
d529894e 774# ----------------------------------------------------------------------
ca10f295 775sub load {
776 my $module = do { my $m = shift; $m =~ s[::][/]g; "$m.pm" };
777 return 1 if $INC{$module};
778
779 eval { require $module };
780
781 return if ($@);
782 return 1;
1fd8c91f 783}
16dc9970 784
d529894e 785# ----------------------------------------------------------------------
c2d3a526 786sub isa { UNIVERSAL::isa($_[0], $_[1]) }
787
16dc9970 7881;
789
790#-----------------------------------------------------
791# Rescue the drowning and tie your shoestrings.
792# Henry David Thoreau
793#-----------------------------------------------------
794
49e1eb70 795=pod
796
7a8e1f51 797=head1 AUTHORS
16dc9970 798
d529894e 799Ken Y. Clark, E<lt>kclark@cpan.org<gt>,
800darren chamberlain E<lt>darren@cpan.orgE<gt>,
801Chris Mungall E<lt>cjm@fruitfly.orgE<gt>
dfb4c915 802
ca10f295 803=head1 COPYRIGHT
16dc9970 804
ca10f295 805This program is free software; you can redistribute it and/or modify
806it under the terms of the GNU General Public License as published by
807the Free Software Foundation; version 2.
dfb4c915 808
ca10f295 809This program is distributed in the hope that it will be useful, but
810WITHOUT ANY WARRANTY; without even the implied warranty of
811MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
812General Public License for more details.
16dc9970 813
ca10f295 814You should have received a copy of the GNU General Public License
815along with this program; if not, write to the Free Software
816Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
817USA
16dc9970 818
819=head1 SEE ALSO
820
ca10f295 821L<perl>, L<Parse::RecDescent>
16dc9970 822
823=cut