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