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