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