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