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