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