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