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