Modified to call translator to get schema rather than passing.
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator.pm
CommitLineData
16dc9970 1package SQL::Translator;
2
b346d8f1 3# ----------------------------------------------------------------------
45ee6be0 4# $Id: Translator.pm,v 1.26 2003-05-09 16:51:47 kycl4rk 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
16dc9970 25use strict;
d529894e 26use vars qw( $VERSION $REVISION $DEFAULT_SUB $DEBUG $ERROR );
49e1eb70 27use base 'Class::Base';
c2d3a526 28
d529894e 29$VERSION = '0.01';
45ee6be0 30$REVISION = sprintf "%d.%02d", q$Revision: 1.26 $ =~ /(\d+)\.(\d+)/;
d529894e 31$DEBUG = 0 unless defined $DEBUG;
32$ERROR = "";
c2d3a526 33
34use Carp qw(carp);
16dc9970 35
c0c4aef9 36use File::Spec::Functions qw(catfile);
37use File::Basename qw(dirname);
38use IO::Dir;
45ee6be0 39use SQL::Translator::Schema;
c0c4aef9 40
b346d8f1 41# ----------------------------------------------------------------------
42# The default behavior is to "pass through" values (note that the
43# SQL::Translator instance is the first value ($_[0]), and the stuff
44# to be parsed is the second value ($_[1])
45# ----------------------------------------------------------------------
46$DEFAULT_SUB = sub { $_[1] } unless defined $DEFAULT_SUB;
16dc9970 47
b346d8f1 48# ----------------------------------------------------------------------
c2d3a526 49# init([ARGS])
b346d8f1 50# The constructor.
dfb4c915 51#
b346d8f1 52# new takes an optional hash of arguments. These arguments may
53# include a parser, specified with the keys "parser" or "from",
54# and a producer, specified with the keys "producer" or "to".
dfb4c915 55#
b346d8f1 56# The values that can be passed as the parser or producer are
57# given directly to the parser or producer methods, respectively.
58# See the appropriate method description below for details about
59# what each expects/accepts.
b346d8f1 60# ----------------------------------------------------------------------
c2d3a526 61sub init {
49e1eb70 62 my ( $self, $config ) = @_;
1fd8c91f 63
49e1eb70 64 #
b346d8f1 65 # Set the parser and producer.
ca10f295 66 #
b346d8f1 67 # If a 'parser' or 'from' parameter is passed in, use that as the
68 # parser; if a 'producer' or 'to' parameter is passed in, use that
69 # as the producer; both default to $DEFAULT_SUB.
49e1eb70 70 #
71 $self->parser ($config->{'parser'} || $config->{'from'} || $DEFAULT_SUB);
c2d3a526 72 $self->producer($config->{'producer'} || $config->{'to'} || $DEFAULT_SUB);
ca10f295 73
7d5bcab8 74 #
75 # Set up callbacks for formatting of pk,fk,table,package names in producer
76 #
77 $self->format_table_name($config->{'format_table_name'});
78 $self->format_package_name($config->{'format_package_name'});
79 $self->format_fk_name($config->{'format_fk_name'});
80 $self->format_pk_name($config->{'format_pk_name'});
81
49e1eb70 82 #
e2158c40 83 # Set the parser_args and producer_args
49e1eb70 84 #
85 for my $pargs ( qw[ parser_args producer_args ] ) {
86 $self->$pargs( $config->{$pargs} ) if defined $config->{ $pargs };
e2158c40 87 }
88
49e1eb70 89 #
9398955f 90 # Set the data source, if 'filename' or 'file' is provided.
49e1eb70 91 #
c2d3a526 92 $config->{'filename'} ||= $config->{'file'} || "";
49e1eb70 93 $self->filename( $config->{'filename'} ) if $config->{'filename'};
9398955f 94
49e1eb70 95 #
96 # Finally, if there is a 'data' parameter, use that in
97 # preference to filename and file
98 #
99 if ( my $data = $config->{'data'} ) {
100 $self->data( $data );
9398955f 101 }
102
d529894e 103 #
104 # Set various other options.
105 #
49e1eb70 106 $self->{'debug'} = defined $config->{'debug'} ? $config->{'debug'} : $DEBUG;
ca10f295 107
96844cae 108 $self->add_drop_table( $config->{'add_drop_table'} );
d529894e 109
110 $self->custom_translate( $config->{'xlate'} );
111
112 $self->no_comments( $config->{'no_comments'} );
113
96844cae 114 $self->show_warnings( $config->{'show_warnings'} );
115
116 $self->trace( $config->{'trace'} );
117
ca10f295 118 return $self;
dfb4c915 119}
1fd8c91f 120
0f3778d0 121# ----------------------------------------------------------------------
122# add_drop_table([$bool])
123# ----------------------------------------------------------------------
96844cae 124sub add_drop_table {
125 my $self = shift;
126 if ( defined (my $arg = shift) ) {
127 $self->{'add_drop_table'} = $arg ? 1 : 0;
128 }
129 return $self->{'add_drop_table'} || 0;
130}
131
132
0f3778d0 133# ----------------------------------------------------------------------
134# custom_translate([$bool])
135# ----------------------------------------------------------------------
d529894e 136sub custom_translate {
137 my $self = shift;
138 $self->{'custom_translate'} = shift if @_;
139 return $self->{'custom_translate'} || {};
140}
141
0f3778d0 142# ----------------------------------------------------------------------
143# no_comments([$bool])
144# ----------------------------------------------------------------------
d529894e 145sub no_comments {
146 my $self = shift;
147 my $arg = shift;
148 if ( defined $arg ) {
149 $self->{'no_comments'} = $arg ? 1 : 0;
150 }
151 return $self->{'no_comments'} || 0;
152}
153
e2158c40 154
0f3778d0 155# ----------------------------------------------------------------------
156# producer([$producer_spec])
157#
158# Get or set the producer for the current translator.
159# ----------------------------------------------------------------------
ca10f295 160sub producer {
1fd8c91f 161 my $self = shift;
b346d8f1 162
7a8e1f51 163 # producer as a mutator
ca10f295 164 if (@_) {
165 my $producer = shift;
b346d8f1 166
7a8e1f51 167 # Passed a module name (string containing "::")
ca10f295 168 if ($producer =~ /::/) {
077ebf34 169 my $func_name;
b346d8f1 170
7a8e1f51 171 # Module name was passed directly
b346d8f1 172 # We try to load the name; if it doesn't load, there's
173 # a possibility that it has a function name attached to
174 # it.
077ebf34 175 if (load($producer)) {
176 $func_name = "produce";
7a8e1f51 177 }
b346d8f1 178
7a8e1f51 179 # Module::function was passed
b346d8f1 180 else {
181 # Passed Module::Name::function; try to recover
077ebf34 182 my @func_parts = split /::/, $producer;
183 $func_name = pop @func_parts;
184 $producer = join "::", @func_parts;
b346d8f1 185
186 # If this doesn't work, then we have a legitimate
187 # problem.
077ebf34 188 load($producer) or die "Can't load $producer: $@";
7a8e1f51 189 }
077ebf34 190
7a8e1f51 191 # get code reference and assign
077ebf34 192 $self->{'producer'} = \&{ "$producer\::$func_name" };
193 $self->{'producer_type'} = $producer;
49e1eb70 194 $self->debug("Got producer: $producer\::$func_name\n");
7a8e1f51 195 }
b346d8f1 196
7a8e1f51 197 # passed an anonymous subroutine reference
b346d8f1 198 elsif (isa($producer, 'CODE')) {
ca10f295 199 $self->{'producer'} = $producer;
077ebf34 200 $self->{'producer_type'} = "CODE";
49e1eb70 201 $self->debug("Got producer: code ref\n");
7a8e1f51 202 }
b346d8f1 203
7a8e1f51 204 # passed a string containing no "::"; relative package name
b346d8f1 205 else {
ca10f295 206 my $Pp = sprintf "SQL::Translator::Producer::$producer";
207 load($Pp) or die "Can't load $Pp: $@";
077ebf34 208 $self->{'producer'} = \&{ "$Pp\::produce" };
209 $self->{'producer_type'} = $Pp;
49e1eb70 210 $self->debug("Got producer: $Pp\n");
7a8e1f51 211 }
b346d8f1 212
ca10f295 213 # At this point, $self->{'producer'} contains a subroutine
b346d8f1 214 # reference that is ready to run
e2158c40 215
7a8e1f51 216 # Anything left? If so, it's producer_args
217 $self->producer_args(@_) if (@_);
218 }
b346d8f1 219
ca10f295 220 return $self->{'producer'};
221};
077ebf34 222
7a8e1f51 223# ----------------------------------------------------------------------
0f3778d0 224# producer_type()
7a8e1f51 225#
e2158c40 226# producer_type is an accessor that allows producer subs to get
227# information about their origin. This is poptentially important;
ca251f03 228# since all producer subs are called as subroutine references, there is
e2158c40 229# no way for a producer to find out which package the sub lives in
230# originally, for example.
7a8e1f51 231# ----------------------------------------------------------------------
232sub producer_type { $_[0]->{'producer_type'} }
e2158c40 233
7a8e1f51 234# ----------------------------------------------------------------------
0f3778d0 235# producer_args([\%args])
7a8e1f51 236#
e2158c40 237# Arbitrary name => value pairs of paramters can be passed to a
238# producer using this method.
52b828e8 239#
0f3778d0 240# If the first argument passed in is undef, then the hash of arguments
241# is cleared; all subsequent elements are added to the hash of name,
242# value pairs stored as producer_args.
7a8e1f51 243# ----------------------------------------------------------------------
e2158c40 244sub producer_args {
245 my $self = shift;
0f3778d0 246 return $self->_args("producer", @_);
7a8e1f51 247}
ca10f295 248
0f3778d0 249# ----------------------------------------------------------------------
250# parser([$parser_spec])
251# ----------------------------------------------------------------------
ca10f295 252sub parser {
253 my $self = shift;
b346d8f1 254
7a8e1f51 255 # parser as a mutator
ca10f295 256 if (@_) {
257 my $parser = shift;
b346d8f1 258
7a8e1f51 259 # Passed a module name (string containing "::")
ca10f295 260 if ($parser =~ /::/) {
b346d8f1 261 my $func_name;
262
7a8e1f51 263 # Module name was passed directly
b346d8f1 264 # We try to load the name; if it doesn't load, there's
265 # a possibility that it has a function name attached to
266 # it.
267 if (load($parser)) {
268 $func_name = "parse";
7a8e1f51 269 }
b346d8f1 270
7a8e1f51 271 # Module::function was passed
b346d8f1 272 else {
273 # Passed Module::Name::function; try to recover
274 my @func_parts = split /::/, $parser;
275 $func_name = pop @func_parts;
276 $parser = join "::", @func_parts;
277
278 # If this doesn't work, then we have a legitimate
279 # problem.
280 load($parser) or die "Can't load $parser: $@";
7a8e1f51 281 }
b346d8f1 282
7a8e1f51 283 # get code reference and assign
b346d8f1 284 $self->{'parser'} = \&{ "$parser\::$func_name" };
077ebf34 285 $self->{'parser_type'} = $parser;
49e1eb70 286 $self->debug("Got parser: $parser\::$func_name\n");
7a8e1f51 287 }
b346d8f1 288
7a8e1f51 289 # passed an anonymous subroutine reference
49e1eb70 290 elsif ( isa( $parser, 'CODE' ) ) {
291 $self->{'parser'} = $parser;
077ebf34 292 $self->{'parser_type'} = "CODE";
49e1eb70 293 $self->debug("Got parser: code ref\n");
7a8e1f51 294 }
b346d8f1 295
7a8e1f51 296 # passed a string containing no "::"; relative package name
b346d8f1 297 else {
49e1eb70 298 my $Pp = "SQL::Translator::Parser::$parser";
299 load( $Pp ) or die "Can't load $Pp: $@";
300 $self->{'parser'} = \&{ "$Pp\::parse" };
077ebf34 301 $self->{'parser_type'} = $Pp;
49e1eb70 302 $self->debug("Got parser: $Pp\n");
7a8e1f51 303 }
b346d8f1 304
49e1eb70 305 #
b346d8f1 306 # At this point, $self->{'parser'} contains a subroutine
307 # reference that is ready to run
49e1eb70 308 #
309 $self->parser_args( @_ ) if (@_);
7a8e1f51 310 }
b346d8f1 311
ca10f295 312 return $self->{'parser'};
16dc9970 313}
1fd8c91f 314
d529894e 315# ----------------------------------------------------------------------
077ebf34 316sub parser_type { $_[0]->{'parser_type'} }
e2158c40 317
e2158c40 318sub parser_args {
319 my $self = shift;
0f3778d0 320 return $self->_args("parser", @_);
321}
96844cae 322
323sub show_warnings {
324 my $self = shift;
325 my $arg = shift;
326 if ( defined $arg ) {
327 $self->{'show_warnings'} = $arg ? 1 : 0;
328 }
329 return $self->{'show_warnings'} || 0;
330}
331
ca10f295 332
0f3778d0 333# filename - get or set the filename
334sub filename {
335 my $self = shift;
336 if (@_) {
337 my $filename = shift;
338 if (-d $filename) {
339 my $msg = "Cannot use directory '$filename' as input source";
340 return $self->error($msg);
95a2cfb6 341 } elsif (ref($filename) eq 'ARRAY') {
342 $self->{'filename'} = $filename;
343 $self->debug("Got array of files: ".join(', ',@$filename)."\n");
0f3778d0 344 } elsif (-f _ && -r _) {
345 $self->{'filename'} = $filename;
346 $self->debug("Got filename: '$self->{'filename'}'\n");
347 } else {
348 my $msg = "Cannot use '$filename' as input source: ".
349 "file does not exist or is not readable.";
350 return $self->error($msg);
351 }
352 }
ca10f295 353
0f3778d0 354 $self->{'filename'};
355}
ca10f295 356
0f3778d0 357# ----------------------------------------------------------------------
358# data([$data])
359#
360# if $self->{'data'} is not set, but $self->{'filename'} is, then
361# $self->{'filename'} is opened and read, with the results put into
362# $self->{'data'}.
363# ----------------------------------------------------------------------
364sub data {
365 my $self = shift;
ca10f295 366
0f3778d0 367 # Set $self->{'data'} based on what was passed in. We will
368 # accept a number of things; do our best to get it right.
369 if (@_) {
370 my $data = shift;
371 if (isa($data, "SCALAR")) {
372 $self->{'data'} = $data;
373 }
374 else {
375 if (isa($data, 'ARRAY')) {
376 $data = join '', @$data;
377 }
378 elsif (isa($data, 'GLOB')) {
379 local $/;
380 $data = <$data>;
381 }
382 elsif (! ref $data && @_) {
383 $data = join '', $data, @_;
384 }
385 $self->{'data'} = \$data;
386 }
387 }
9398955f 388
7a8e1f51 389 # If we have a filename but no data yet, populate.
9398955f 390 if (not $self->{'data'} and my $filename = $self->filename) {
49e1eb70 391 $self->debug("Opening '$filename' to get contents.\n");
9398955f 392 local *FH;
393 local $/;
394 my $data;
395
95a2cfb6 396 my @files = ref($filename) eq 'ARRAY' ? @$filename : ($filename);
9398955f 397
95a2cfb6 398 foreach my $file (@files) {
399 unless (open FH, $file) {
400 return $self->error("Can't read file '$file': $!");
401 }
9398955f 402
95a2cfb6 403 $data .= <FH>;
404
405 unless (close FH) {
406 return $self->error("Can't close file '$file': $!");
407 }
408 }
409
410 $self->{'data'} = \$data;
9398955f 411 }
9398955f 412
413 return $self->{'data'};
7a8e1f51 414}
9398955f 415
45ee6be0 416# ----------------------------------------------------------------------
417sub schema {
418#
419# Returns the SQL::Translator::Schema object
420#
421 my $self = shift;
422
423 unless ( defined $self->{'schema'} ) {
424 $self->{'schema'} = SQL::Translator::Schema->new;
425 }
d529894e 426
45ee6be0 427 return $self->{'schema'};
428}
429
430# ----------------------------------------------------------------------
d529894e 431sub trace {
432 my $self = shift;
433 my $arg = shift;
434 if ( defined $arg ) {
435 $self->{'trace'} = $arg ? 1 : 0;
436 }
437 return $self->{'trace'} || 0;
438}
439
440# ----------------------------------------------------------------------
0f3778d0 441# translate([source], [\%args])
442#
443# translate does the actual translation. The main argument is the
444# source of the data to be translated, which can be a filename, scalar
445# reference, or glob reference.
446#
447# Alternatively, translate takes optional arguements, which are passed
448# to the appropriate places. Most notable of these arguments are
449# parser and producer, which can be used to set the parser and
450# producer, respectively. This is the applications last chance to set
451# these.
452#
453# translate returns a string.
454# ----------------------------------------------------------------------
ca251f03 455sub translate {
456 my $self = shift;
457 my ($args, $parser, $parser_type, $producer, $producer_type);
458 my ($parser_output, $producer_output);
ca10f295 459
7a8e1f51 460 # Parse arguments
9398955f 461 if (@_ == 1) {
7a8e1f51 462 # Passed a reference to a hash?
ca10f295 463 if (isa($_[0], 'HASH')) {
7a8e1f51 464 # yep, a hashref
49e1eb70 465 $self->debug("translate: Got a hashref\n");
ca10f295 466 $args = $_[0];
467 }
9398955f 468
0f3778d0 469 # Passed a GLOB reference, i.e., filehandle
470 elsif (isa($_[0], 'GLOB')) {
471 $self->debug("translate: Got a GLOB reference\n");
472 $self->data($_[0]);
473 }
474
7a8e1f51 475 # Passed a reference to a string containing the data
ca10f295 476 elsif (isa($_[0], 'SCALAR')) {
9398955f 477 # passed a ref to a string
49e1eb70 478 $self->debug("translate: Got a SCALAR reference (string)\n");
9398955f 479 $self->data($_[0]);
ca10f295 480 }
9398955f 481
7a8e1f51 482 # Not a reference; treat it as a filename
b346d8f1 483 elsif (! ref $_[0]) {
ca10f295 484 # Not a ref, it's a filename
49e1eb70 485 $self->debug("translate: Got a filename\n");
9398955f 486 $self->filename($_[0]);
ca10f295 487 }
9398955f 488
7a8e1f51 489 # Passed something else entirely.
b346d8f1 490 else {
491 # We're not impressed. Take your empty string and leave.
38254289 492 # return "";
493
7a8e1f51 494 # Actually, if data, parser, and producer are set, then we
495 # can continue. Too bad, because I like my comment
496 # (above)...
38254289 497 return "" unless ($self->data &&
498 $self->producer &&
499 $self->parser);
b346d8f1 500 }
16dc9970 501 }
502 else {
b346d8f1 503 # You must pass in a hash, or you get nothing.
504 return "" if @_ % 2;
ca10f295 505 $args = { @_ };
7a8e1f51 506 }
16dc9970 507
9398955f 508 # ----------------------------------------------------------------------
509 # Can specify the data to be transformed using "filename", "file",
7a8e1f51 510 # "data", or "datasource".
9398955f 511 # ----------------------------------------------------------------------
7a8e1f51 512 if (my $filename = ($args->{'filename'} || $args->{'file'})) {
9398955f 513 $self->filename($filename);
514 }
ca10f295 515
422298aa 516 if (my $data = ($args->{'data'} || $args->{'datasource'})) {
9398955f 517 $self->data($data);
16dc9970 518 }
ca10f295 519
9398955f 520 # ----------------------------------------------------------------
521 # Get the data.
522 # ----------------------------------------------------------------
523 my $data = $self->data;
5457eaf0 524 unless (ref($data) eq 'SCALAR' and length $$data) {
c2d3a526 525 return $self->error("Empty data file!");
9398955f 526 }
077ebf34 527
9398955f 528 # ----------------------------------------------------------------
ca10f295 529 # Local reference to the parser subroutine
9398955f 530 # ----------------------------------------------------------------
ca10f295 531 if ($parser = ($args->{'parser'} || $args->{'from'})) {
532 $self->parser($parser);
16dc9970 533 }
7a8e1f51 534 $parser = $self->parser;
535 $parser_type = $self->parser_type;
16dc9970 536
9398955f 537 # ----------------------------------------------------------------
ca10f295 538 # Local reference to the producer subroutine
9398955f 539 # ----------------------------------------------------------------
ca10f295 540 if ($producer = ($args->{'producer'} || $args->{'to'})) {
541 $self->producer($producer);
16dc9970 542 }
7a8e1f51 543 $producer = $self->producer;
544 $producer_type = $self->producer_type;
16dc9970 545
9398955f 546 # ----------------------------------------------------------------
7a8e1f51 547 # Execute the parser, then execute the producer with that output.
548 # Allowances are made for each piece to die, or fail to compile,
549 # since the referenced subroutines could be almost anything. In
550 # the future, each of these might happen in a Safe environment,
551 # depending on how paranoid we want to be.
9398955f 552 # ----------------------------------------------------------------
45ee6be0 553 my $schema = $self->schema;
554 eval { $parser_output = $parser->($self, $$data, $schema) };
7a8e1f51 555 if ($@ || ! $parser_output) {
556 my $msg = sprintf "translate: Error with parser '%s': %s",
557 $parser_type, ($@) ? $@ : " no results";
c2d3a526 558 return $self->error($msg);
7a8e1f51 559 }
560
45ee6be0 561 eval { $producer_output = $producer->($self, $parser_output, $schema) };
7a8e1f51 562 if ($@ || ! $producer_output) {
563 my $msg = sprintf "translate: Error with producer '%s': %s",
564 $producer_type, ($@) ? $@ : " no results";
c2d3a526 565 return $self->error($msg);
7a8e1f51 566 }
567
568 return $producer_output;
16dc9970 569}
ca10f295 570
d529894e 571# ----------------------------------------------------------------------
0f3778d0 572# list_parsers()
573#
574# Hacky sort of method to list all available parsers. This has
575# several problems:
576#
577# - Only finds things in the SQL::Translator::Parser namespace
578#
579# - Only finds things that are located in the same directory
580# as SQL::Translator::Parser. Yeck.
581#
582# This method will fail in several very likely cases:
583#
584# - Parser modules in different namespaces
585#
586# - Parser modules in the SQL::Translator::Parser namespace that
587# have any XS componenets will be installed in
588# arch_lib/SQL/Translator.
589#
590# ----------------------------------------------------------------------
591sub list_parsers {
ca1f2237 592 return shift->_list("parser");
0f3778d0 593}
594
595# ----------------------------------------------------------------------
596# list_producers()
597#
598# See notes for list_parsers(), above; all the problems apply to
599# list_producers as well.
600# ----------------------------------------------------------------------
c0c4aef9 601sub list_producers {
ca1f2237 602 return shift->_list("producer");
0f3778d0 603}
604
c0c4aef9 605
0f3778d0 606# ======================================================================
607# Private Methods
608# ======================================================================
c0c4aef9 609
0f3778d0 610# ----------------------------------------------------------------------
611# _args($type, \%args);
612#
613# Gets or sets ${type}_args. Called by parser_args and producer_args.
614# ----------------------------------------------------------------------
615sub _args {
616 my $self = shift;
617 my $type = shift;
618 $type = "${type}_args" unless $type =~ /_args$/;
619
620 unless (defined $self->{$type} && isa($self->{$type}, 'HASH')) {
621 $self->{$type} = { };
622 }
623
624 if (@_) {
625 # If the first argument is an explicit undef (remember, we
626 # don't get here unless there is stuff in @_), then we clear
627 # out the producer_args hash.
628 if (! defined $_[0]) {
629 shift @_;
630 %{$self->{$type}} = ();
631 }
632
633 my $args = isa($_[0], 'HASH') ? shift : { @_ };
634 %{$self->{$type}} = (%{$self->{$type}}, %$args);
635 }
636
637 $self->{$type};
c0c4aef9 638}
639
0f3778d0 640
d529894e 641# ----------------------------------------------------------------------
0f3778d0 642# _list($type)
643# ----------------------------------------------------------------------
644sub _list {
ca1f2237 645 my $self = shift;
646 my $type = shift || return ();
647 my $uctype = ucfirst lc $type;
648 my %found;
649
650 load("SQL::Translator::$uctype") or return ();
651 my $path = catfile "SQL", "Translator", $uctype;
652 for (@INC) {
653 my $dir = catfile $_, $path;
654 $self->debug("_list_${type}s searching $dir");
655 next unless -d $dir;
656
657 my $dh = IO::Dir->new($dir);
658 for (grep /\.pm$/, $dh->read) {
659 s/\.pm$//;
660 $found{ join "::", "SQL::Translator::$uctype", $_ } = 1;
661 }
662 }
c0c4aef9 663
ca1f2237 664 return keys %found;
c0c4aef9 665}
666
d529894e 667# ----------------------------------------------------------------------
0f3778d0 668# load($module)
669#
670# Loads a Perl module. Short circuits if a module is already loaded.
671# ----------------------------------------------------------------------
ca10f295 672sub load {
673 my $module = do { my $m = shift; $m =~ s[::][/]g; "$m.pm" };
674 return 1 if $INC{$module};
ca1f2237 675
5760246d 676 eval {
677 require $module;
678 $module->import(@_);
679 };
ca1f2237 680
681 return __PACKAGE__->error($@) if ($@);
ca10f295 682 return 1;
1fd8c91f 683}
16dc9970 684
7d5bcab8 685sub format_table_name {
f9a0c3b5 686 my $self = shift;
687 my $sub = shift;
688 $self->{'_format_table_name'} = $sub if ref $sub eq 'CODE';
689 return $self->{'_format_table_name'}->( $sub, @_ )
690 if defined $self->{'_format_table_name'};
691 return $sub;
7d5bcab8 692}
693
694sub format_package_name {
f9a0c3b5 695 my $self = shift;
696 my $sub = shift;
697 $self->{'_format_package_name'} = $sub if ref $sub eq 'CODE';
698 return $self->{'_format_package_name'}->( $sub, @_ )
699 if defined $self->{'_format_package_name'};
700 return $sub;
7d5bcab8 701}
702
703sub format_fk_name {
f9a0c3b5 704 my $self = shift;
705 my $sub = shift;
706 $self->{'_format_fk_name'} = $sub if ref $sub eq 'CODE';
707 return $self->{'_format_fk_name'}->( $sub, @_ )
708 if defined $self->{'_format_fk_name'};
709 return $sub;
7d5bcab8 710}
711
712sub format_pk_name {
f9a0c3b5 713 my $self = shift;
714 my $sub = shift;
715 $self->{'_format_pk_name'} = $sub if ref $sub eq 'CODE';
716 return $self->{'_format_pk_name'}->( $sub, @_ )
717 if defined $self->{'_format_pk_name'};
718 return $sub;
7d5bcab8 719}
720
d529894e 721# ----------------------------------------------------------------------
0f3778d0 722# isa($ref, $type)
723#
724# Calls UNIVERSAL::isa($ref, $type). I think UNIVERSAL::isa is ugly,
725# but I like function overhead.
726# ----------------------------------------------------------------------
727sub isa($$) {
728 my ($ref, $type) = @_;
729 return UNIVERSAL::isa($ref, $type);
730}
c2d3a526 731
16dc9970 7321;
16dc9970 733#-----------------------------------------------------
734# Rescue the drowning and tie your shoestrings.
735# Henry David Thoreau
736#-----------------------------------------------------
737
0f3778d0 738__END__
739
740=head1 NAME
741
742SQL::Translator - convert schema from one database to another
743
744=head1 SYNOPSIS
745
746 use SQL::Translator;
747
748 my $translator = SQL::Translator->new(
87bf8a3a 749 debug => 1, # Print debug info
750 trace => 0, # Print Parse::RecDescent trace
751 no_comments => 0, # Don't include comments in output
752 show_warnings => 0, # Print name mutations, conflicts
753 add_drop_table => 1, # Add "drop table" statements
7d5bcab8 754
f9a0c3b5 755 # Make all table names CAPS in producers which support this option
7d5bcab8 756 format_table_name => sub {my $tablename = shift; return uc($tablename)},
f9a0c3b5 757
758 # Null-op formatting, only here for documentation's sake
7d5bcab8 759 format_package_name => sub {return shift},
760 format_fk_name => sub {return shift},
761 format_pk_name => sub {return shift},
0f3778d0 762 );
763
764 my $output = $translator->translate(
765 from => "MySQL",
766 to => "Oracle",
f9a0c3b5 767 # Or an arrayref of filenames, i.e. [ $file1, $file2, $file3 ]
768 filename => $file,
0f3778d0 769 ) or die $translator->error;
770
771 print $output;
772
773=head1 DESCRIPTION
774
775This module attempts to simplify the task of converting one database
776create syntax to another through the use of Parsers (which understand
777the source format) and Producers (which understand the destination
778format). The idea is that any Parser can be used with any Producer in
779the conversion process. So, if you wanted Postgres-to-Oracle, you
780would use the Postgres parser and the Oracle producer.
781
782=head1 CONSTRUCTOR
783
5760246d 784The constructor is called C<new>, and accepts a optional hash of options.
0f3778d0 785Valid options are:
786
787=over 4
788
ca251f03 789=item *
790
791parser / from
792
793=item *
794
795parser_args
0f3778d0 796
ca251f03 797=item *
0f3778d0 798
ca251f03 799producer / to
0f3778d0 800
ca251f03 801=item *
0f3778d0 802
ca251f03 803producer_args
0f3778d0 804
ca251f03 805=item *
806
807filename / file
808
809=item *
810
811data
812
813=item *
0f3778d0 814
ca251f03 815debug
0f3778d0 816
817=back
818
819All options are, well, optional; these attributes can be set via
820instance methods. Internally, they are; no (non-syntactical)
821advantage is gained by passing options to the constructor.
822
823=head1 METHODS
824
5760246d 825=head2 add_drop_table
0f3778d0 826
827Toggles whether or not to add "DROP TABLE" statements just before the
828create definitions.
829
5760246d 830=head2 custom_translate
0f3778d0 831
832Allows the user to override default translation of fields. For example,
833if a MySQL "text" field would normally be converted to a "long" for Oracle,
834the user could specify to change it to a "CLOB." Accepts a hashref where
835keys are the "from" value and values are the "to," returns the current
836value of the field.
837
5760246d 838=head2 no_comments
0f3778d0 839
840Toggles whether to print comments in the output. Accepts a true or false
841value, returns the current value.
842
5760246d 843=head2 producer
0f3778d0 844
5760246d 845The C<producer> method is an accessor/mutator, used to retrieve or
0f3778d0 846define what subroutine is called to produce the output. A subroutine
847defined as a producer will be invoked as a function (I<not a method>)
ca251f03 848and passed 2 parameters: its container C<SQL::Translator> instance and a
0f3778d0 849data structure. It is expected that the function transform the data
ca251f03 850structure to a string. The C<SQL::Transformer> instance is provided for
0f3778d0 851informational purposes; for example, the type of the parser can be
5760246d 852retrieved using the C<parser_type> method, and the C<error> and
853C<debug> methods can be called when needed.
0f3778d0 854
ca251f03 855When defining a producer, one of several things can be passed in: A
5760246d 856module name (e.g., C<My::Groovy::Producer>), a module name relative to
857the C<SQL::Translator::Producer> namespace (e.g., C<MySQL>), a module
ca251f03 858name and function combination (C<My::Groovy::Producer::transmogrify>),
0f3778d0 859or a reference to an anonymous subroutine. If a full module name is
860passed in (for the purposes of this method, a string containing "::"
861is considered to be a module name), it is treated as a package, and a
ca251f03 862function called "produce" will be invoked: C<$modulename::produce>.
863If $modulename cannot be loaded, the final portion is stripped off and
0f3778d0 864treated as a function. In other words, if there is no file named
ca251f03 865F<My/Groovy/Producer/transmogrify.pm>, C<SQL::Translator> will attempt
5760246d 866to load F<My/Groovy/Producer.pm> and use C<transmogrify> as the name of
867the function, instead of the default C<produce>.
0f3778d0 868
869 my $tr = SQL::Translator->new;
870
871 # This will invoke My::Groovy::Producer::produce($tr, $data)
872 $tr->producer("My::Groovy::Producer");
873
874 # This will invoke SQL::Translator::Producer::Sybase::produce($tr, $data)
875 $tr->producer("Sybase");
876
877 # This will invoke My::Groovy::Producer::transmogrify($tr, $data),
878 # assuming that My::Groovy::Producer::transmogrify is not a module
879 # on disk.
880 $tr->producer("My::Groovy::Producer::transmogrify");
881
882 # This will invoke the referenced subroutine directly, as
883 # $subref->($tr, $data);
884 $tr->producer(\&my_producer);
885
5760246d 886There is also a method named C<producer_type>, which is a string
887containing the classname to which the above C<produce> function
0f3778d0 888belongs. In the case of anonymous subroutines, this method returns
889the string "CODE".
890
5760246d 891Finally, there is a method named C<producer_args>, which is both an
0f3778d0 892accessor and a mutator. Arbitrary data may be stored in name => value
893pairs for the producer subroutine to access:
894
895 sub My::Random::producer {
896 my ($tr, $data) = @_;
897 my $pr_args = $tr->producer_args();
898
899 # $pr_args is a hashref.
900
5760246d 901Extra data passed to the C<producer> method is passed to
902C<producer_args>:
0f3778d0 903
904 $tr->producer("xSV", delimiter => ',\s*');
905
906 # In SQL::Translator::Producer::xSV:
907 my $args = $tr->producer_args;
908 my $delimiter = $args->{'delimiter'}; # value is ,\s*
909
5760246d 910=head2 parser
0f3778d0 911
5760246d 912The C<parser> method defines or retrieves a subroutine that will be
0f3778d0 913called to perform the parsing. The basic idea is the same as that of
5760246d 914C<producer> (see above), except the default subroutine name is
ca251f03 915"parse", and will be invoked as C<$module_name::parse($tr, $data)>.
0f3778d0 916Also, the parser subroutine will be passed a string containing the
917entirety of the data to be parsed.
918
919 # Invokes SQL::Translator::Parser::MySQL::parse()
920 $tr->parser("MySQL");
921
922 # Invokes My::Groovy::Parser::parse()
923 $tr->parser("My::Groovy::Parser");
924
925 # Invoke an anonymous subroutine directly
926 $tr->parser(sub {
927 my $dumper = Data::Dumper->new([ $_[1] ], [ "SQL" ]);
928 $dumper->Purity(1)->Terse(1)->Deepcopy(1);
929 return $dumper->Dump;
930 });
931
5760246d 932There is also C<parser_type> and C<parser_args>, which perform
933analogously to C<producer_type> and C<producer_args>
0f3778d0 934
5760246d 935=head2 show_warnings
0f3778d0 936
937Toggles whether to print warnings of name conflicts, identifier
938mutations, etc. Probably only generated by producers to let the user
939know when something won't translate very smoothly (e.g., MySQL "enum"
940fields into Oracle). Accepts a true or false value, returns the
941current value.
942
5760246d 943=head2 translate
0f3778d0 944
5760246d 945The C<translate> method calls the subroutines referenced by the
946C<parser> and C<producer> data members (described above). It accepts
0f3778d0 947as arguments a number of things, in key => value format, including
948(potentially) a parser and a producer (they are passed directly to the
5760246d 949C<parser> and C<producer> methods).
0f3778d0 950
5760246d 951Here is how the parameter list to C<translate> is parsed:
0f3778d0 952
953=over
954
955=item *
956
9571 argument means it's the data to be parsed; which could be a string
ca251f03 958(filename) or a reference to a scalar (a string stored in memory), or a
0f3778d0 959reference to a hash, which is parsed as being more than one argument
960(see next section).
961
962 # Parse the file /path/to/datafile
963 my $output = $tr->translate("/path/to/datafile");
964
965 # Parse the data contained in the string $data
966 my $output = $tr->translate(\$data);
967
968=item *
969
970More than 1 argument means its a hash of things, and it might be
971setting a parser, producer, or datasource (this key is named
972"filename" or "file" if it's a file, or "data" for a SCALAR reference.
973
974 # As above, parse /path/to/datafile, but with different producers
975 for my $prod ("MySQL", "XML", "Sybase") {
976 print $tr->translate(
977 producer => $prod,
978 filename => "/path/to/datafile",
979 );
980 }
981
982 # The filename hash key could also be:
983 datasource => \$data,
984
985You get the idea.
986
987=back
988
5760246d 989=head2 filename, data
0f3778d0 990
5760246d 991Using the C<filename> method, the filename of the data to be parsed
992can be set. This method can be used in conjunction with the C<data>
993method, below. If both the C<filename> and C<data> methods are
994invoked as mutators, the data set in the C<data> method is used.
0f3778d0 995
996 $tr->filename("/my/data/files/create.sql");
997
998or:
999
1000 my $create_script = do {
1001 local $/;
1002 open CREATE, "/my/data/files/create.sql" or die $!;
1003 <CREATE>;
1004 };
1005 $tr->data(\$create_script);
1006
5760246d 1007C<filename> takes a string, which is interpreted as a filename.
1008C<data> takes a reference to a string, which is used as the data to be
0f3778d0 1009parsed. If a filename is set, then that file is opened and read when
5760246d 1010the C<translate> method is called, as long as the data instance
0f3778d0 1011variable is not set.
1012
1013=pod
1014
45ee6be0 1015=head2 schema
1016
1017Returns the SQL::Translator::Schema object.
1018
5760246d 1019=head2 trace
0f3778d0 1020
1021Turns on/off the tracing option of Parse::RecDescent.
1022
49e1eb70 1023=pod
1024
7a8e1f51 1025=head1 AUTHORS
16dc9970 1026
ca251f03 1027Ken Y. Clark, E<lt>kclark@cpan.orgE<gt>,
1028darren chamberlain E<lt>darren@cpan.orgE<gt>,
1029Chris Mungall E<lt>cjm@fruitfly.orgE<gt>,
1030Allen Day E<lt>allenday@users.sourceforge.netE<gt>
dfb4c915 1031
ca10f295 1032=head1 COPYRIGHT
16dc9970 1033
ca10f295 1034This program is free software; you can redistribute it and/or modify
1035it under the terms of the GNU General Public License as published by
1036the Free Software Foundation; version 2.
dfb4c915 1037
ca10f295 1038This program is distributed in the hope that it will be useful, but
1039WITHOUT ANY WARRANTY; without even the implied warranty of
1040MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1041General Public License for more details.
16dc9970 1042
ca10f295 1043You should have received a copy of the GNU General Public License
1044along with this program; if not, write to the Free Software
1045Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
1046USA
16dc9970 1047
87bf8a3a 1048=head1 BUGS
1049
1050Please use http://rt.cpan.org/ for reporting bugs.
1051
16dc9970 1052=head1 SEE ALSO
1053
abfa405a 1054L<perl>,
1055L<SQL::Translator::Parser>,
1056L<SQL::Translator::Producer>,
1057L<Parse::RecDescent>
16dc9970 1058