take out duplicate docs
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Producer / TT / Base.pm
CommitLineData
f5f03b78 1package SQL::Translator::Producer::TT::Base;
2
44659089 3# -------------------------------------------------------------------
4# Copyright (C) 2002-2009 SQLFairy Authors
5#
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License as
8# published by the Free Software Foundation; version 2.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13# General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18# 02111-1307 USA
19# -------------------------------------------------------------------
20
11a8c77a 21=pod
f5f03b78 22
23=head1 NAME
24
11a8c77a 25SQL::Translator::Producer::TT::Base - TT (Template Toolkit) based Producer base
26class.
f5f03b78 27
28=cut
29
f5f03b78 30use strict;
31
da06ac74 32use vars qw[ $VERSION @EXPORT_OK ];
11ad2df9 33$VERSION = '1.59';
f5f03b78 34
35use Template;
36use Data::Dumper;
bfd86e76 37use IO::Handle;
f5f03b78 38use Exporter;
39use base qw(Exporter);
40@EXPORT_OK = qw(produce);
41
42use SQL::Translator::Utils 'debug';
43
44# Hack to convert the produce call into an object. ALL sub-classes need todo
45# this so that the correct class gets created.
46sub produce {
47 return __PACKAGE__->new( translator => shift )->run;
48};
49
50sub new {
51 my $proto = shift;
52 my $class = ref $proto || $proto;
53 my %args = @_;
54
55 my $me = bless {}, $class;
56 $me->{translator} = delete $args{translator} || die "Need a translator.";
57
58 return $me;
59}
60
61sub translator { shift->{translator}; }
62sub schema { shift->{translator}->schema(@_); }
63
7f3fc883 64# Util args access method.
f5f03b78 65# No args - Return hashref (the actual hash in Translator) or hash of args.
66# 1 arg - Return that named args value.
67# Args - List of names. Return values of the given arg names in list context
68# or return as hashref in scalar context. Any names given that don't
7f3fc883 69# exist in the args are returned as undef.
f5f03b78 70sub args {
71 my $me = shift;
72
73 # No args
74 unless (@_) {
7f3fc883 75 return wantarray
f5f03b78 76 ? %{ $me->{translator}->producer_args }
77 : $me->{translator}->producer_args
78 ;
79 }
80
81 # 1 arg. Return the value whatever the context.
82 return $me->{translator}->producer_args->{$_[0]} if @_ == 1;
83
84 # More args so return values list or hash ref
85 my %args = %{ $me->{translator}->producer_args };
86 return wantarray ? @args{@_} : { map { ($_=>$args{$_}) } @_ };
87}
88
89# Run the produce and return the result.
90sub run {
91 my $me = shift;
92 my $scma = $me->schema;
93 my %args = %{$me->args};
94 my $tmpl = $me->tt_schema or die "No template!";
95
96 debug "Processing template $tmpl\n";
97 my $out;
7f3fc883 98 my $tt = Template->new(
f5f03b78 99 #DEBUG => $me->translator->debug,
7f3fc883 100 ABSOLUTE => 1, # Set so we can use from the command line sensibly
101 RELATIVE => 1, # Maybe the cmd line code should set it! Security!
102 $me->tt_config, # Hook for sub-classes to add config
103 %args, # Allow any TT opts to be passed in the producer_args
f5f03b78 104 ) || die "Failed to initialize Template object: ".Template->error;
105
7f3fc883 106 $tt->process( $tmpl, {
107 $me->tt_default_vars,
108 $me->tt_vars, # Sub-class hook for adding vars
109 }, \$out )
f5f03b78 110 or die "Error processing template '$tmpl': ".$tt->error;
111
112 return $out;
113}
114
11a8c77a 115
116# Sub class hooks
117#-----------------------------------------------------------------------------
118
119sub tt_config { () };
120
bfd86e76 121sub tt_schema {
122 my $me = shift;
123 my $class = ref $me;
124
125 my $file = $me->args("ttfile");
126 return $file if $file;
127
128 no strict 'refs';
129 my $ref = *{"$class\:\:DATA"}{IO};
130 if ( $ref->opened ) {
131 local $/ = undef; # Slurp mode
132 return \<$ref>;
133 }
134
135 undef;
136};
f5f03b78 137
f5f03b78 138sub tt_default_vars {
139 my $me = shift;
140 return (
141 translator => $me->translator,
bfd86e76 142 schema => $me->pre_process_schema($me->translator->schema),
f5f03b78 143 );
144}
145
bfd86e76 146sub pre_process_schema { $_[1] }
147
7f3fc883 148sub tt_vars { () };
149
f5f03b78 1501;
151
f5f03b78 152=pod
153
11a8c77a 154=head1 SYNOPSIS
155
466c88de 156 # Create a producer using a template in the __DATA__ section.
11a8c77a 157 package SQL::Translator::Producer::Foo;
158
159 use base qw/SQL::Translator::Producer::TT::Base/;
160
f33f9d70 161 # Convert produce call into a method call on our new class
11a8c77a 162 sub produce { return __PACKAGE__->new( translator => shift )->run; };
163
11a8c77a 164 # Configure the Template object.
165 sub tt_config { ( INTERPOLATE => 1 ); }
166
167 # Extra vars to add to the template
168 sub tt_vars { ( foo => "bar" ); }
169
bfd86e76 170 # Put template in DATA section (or use file with ttfile producer arg)
171 __DATA__
172 Schema
f33f9d70 173
bfd86e76 174 Database: [% schema.database %]
175 Foo: $foo
176 ...
177
11a8c77a 178=head1 DESCRIPTION
179
11a8c77a 180A base class producer designed to be sub-classed to create new TT based
181producers cheaply - by simply giving the template to use and sprinkling in some
182extra template variables and config.
183
466c88de 184You can find an introduction to this module in L<SQL::Translator::Manual>.
185
11a8c77a 186The 1st thing the module does is convert the produce sub routine call we get
f33f9d70 187from SQL::Translator into a method call on an object, which we can then
188sub-class. This is done with the following code which needs to appear in B<all>
189sub classes.
11a8c77a 190
191 # Convert produce call into an object method call
192 sub produce { return __PACKAGE__->new( translator => shift )->run; };
193
194See L<PRODUCER OBJECT> below for details.
195
f33f9d70 196The upshot of this is we can make new template producers by sub classing this
197base class, adding the above snippet and a template.
198The module also provides a number of hooks into the templating process,
199see L<SUB CLASS HOOKS> for details.
11a8c77a 200
201See the L<SYNOPSIS> above for an example of creating a simple producer using
202a single template stored in the producers DATA section.
203
204=head1 SUB CLASS HOOKS
205
f33f9d70 206Sub-classes can override these methods to control the templating by giving
11a8c77a 207the template source, adding variables and giving config to the Tempate object.
208
209=head2 tt_config
210
211 sub tt_config { ( INTERPOLATE => 1 ); }
212
f33f9d70 213Return hash of Template config to add to that given to the L<Template> C<new>
214method.
11a8c77a 215
216=head2 tt_schema
217
218 sub tt_schema { "foo.tt"; }
219 sub tt_schema { local $/ = undef; \<DATA>; }
220
f33f9d70 221The template to use, return a file name or a scalar ref of TT
222source, or an L<IO::Handle>. See L<Template> for details, as the return from
223this is passed on to it's C<produce> method.
11a8c77a 224
225The default implimentation uses the producer arg C<ttfile> as a filename to read
f33f9d70 226the template from. If the arg isn't there it will look for a C<__DATA__> section
bfd86e76 227in the class, reading it as template source if found. Returns undef if both
228these fail, causing the produce call to fail with a 'no template!' error.
11a8c77a 229
230=head2 tt_vars
231
232 sub tt_vars { ( foo => "bar" ); }
233
f33f9d70 234Return hash of template vars to use in the template. Nothing added here
11a8c77a 235by default, but see L<tt_default_vars> for the variables you get for free.
236
237=head2 tt_default_vars
238
239Return a hash-ref of the default vars given to the template.
240You wouldn't normally over-ride this, just inherit the default implimentation,
241to get the C<translator> & C<schema> variables, then over-ride L<tt_vars> to add
242your own.
243
244The current default variables are:
245
246=over 4
247
248=item schema
249
250The schema to template.
251
252=item translator
253
254The L<SQL::Translator> object.
255
256=back
257
bfd86e76 258=head2 pre_process_schema
259
260WARNING: This method is Experimental so may change!
261
f33f9d70 262Called with the L<SQL::Translator::Schema> object and should return one (it
ea93df61 263doesn't have to be the same one) that will become the C<schema> varibale used
f33f9d70 264in the template.
bfd86e76 265
266Gets called from tt_default_vars.
267
11a8c77a 268=head1 PRODUCER OBJECT
269
270The rest of the methods in the class set up a sub-classable producer object.
271You normally just inherit them.
272
273=head2 new
274
275 my $tt_producer = TT::Base->new( translator => $translator );
276
277Construct a new TT Producer object. Takes a single, named arg of the
278L<SQL::Translator> object running the translation. Dies if this is not given.
279
280=head2 translator
281
282Return the L<SQL::Translator> object.
283
284=head2 schema
285
286Return the L<SQL::Translator::Schema> we are translating. This is equivilent
287to C<< $tt_producer->translator->schema >>.
288
f33f9d70 289=head2 run
290
291Called to actually produce the output, calling the sub class hooks. Returns the
292produced text.
293
11a8c77a 294=head2 args
295
296Util wrapper method around C<< TT::Base->translator->producer_args >> for
297(mostley) readonly access to the producer args. How it works depends on the
298number of arguments you give it and the context.
299
300 No args - Return hashref (the actual hash in Translator) or hash of args.
301 1 arg - Return value of the arg with the passed name.
f33f9d70 302 2+ args - List of names. In list context returns values of the given arg
303 names, returns as a hashref in scalar context. Any names given
304 that don't exist in the args are returned as undef.
11a8c77a 305
f33f9d70 306This is still a bit messy but is a handy way to access the producer args when
307you use your own to drive the templating.
11a8c77a 308
f33f9d70 309=head1 SEE ALSO
f5f03b78 310
f33f9d70 311L<perl>,
312L<SQL::Translator>,
313L<Template>.
f5f03b78 314
315=head1 TODO
316
11a8c77a 317- Add support for a sqlf template repository, set as an INCLUDE_PATH,
318so that sub-classes can easily include file based templates using relative
319paths.
f5f03b78 320
f33f9d70 321- Pass in template vars from the producer args and command line.
322
f5f03b78 323- Merge in TT::Table.
324
11a8c77a 325- Hooks to pre-process the schema and post-process the output.
326
f33f9d70 327=head1 AUTHOR
f5f03b78 328
f33f9d70 329Mark Addison E<lt>grommit@users.sourceforge.netE<gt>.
f5f03b78 330
331=cut