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