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