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