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