turnkey producer still broken, will try to get it working on the plane...
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Producer / Turnkey.pm
CommitLineData
88f2d2fd 1package Turnkey::Node;
69c7a62f 2
3use strict;
4use Class::MakeMethods::Template::Hash (
5 new => [ 'new' ],
88f2d2fd 6 'array_of_objects -class Turnkey::Edge' => [ qw( edges ) ],
7 'array_of_objects -class Turnkey::CompoundEdge' => [ qw( compoundedges ) ],
8 'array_of_objects -class Turnkey::HyperEdge' => [ qw( hyperedges ) ],
9 'hash' => [ qw( many via has) ],
69c7a62f 10 scalar => [ qw( base name order primary_key primary_key_accessor table) ],
11);
12
13
88f2d2fd 14package Turnkey::Edge;
69c7a62f 15
88f2d2fd 16use strict;
17use Class::MakeMethods::Template::Hash (
18 new => ['new'],
19 scalar => [ qw( type ) ],
20 array => [ qw( traversals ) ],
21 object => [
22 'thisfield' => {class => 'SQL::Translator::Schema::Field'},
23 'thatfield' => {class => 'SQL::Translator::Schema::Field'},
24 'thisnode' => {class => 'Turnkey::Node'},
25 'thatnode' => {class => 'Turnkey::Node'},
26
27 ],
28);
29
30sub flip {
31 my $self = shift;
32 return Turnkey::Edge->new( thisfield => $self->thatfield,
33 thatfield => $self->thisfield,
34 thisnode => $self->thatnode,
35 thatnode => $self->thisnode,
36 type => $self->type eq 'import' ? 'export' : 'import'
37 );
69c7a62f 38}
39
69c7a62f 40
88f2d2fd 41package Turnkey::HyperEdge;
42
43use strict;
44use base qw(Turnkey::Edge);
45use Class::MakeMethods::Template::Hash (
46 'array_of_objects -class SQL::Translator::Schema::Field' => [ qw( thisviafield thatviafield thisfield thatfield) ],
47 'array_of_objects -class Turnkey::Node' => [ qw( thisnode thatnode ) ],
48 object => [ 'vianode' => {class => 'Turnkey::Node'} ],
49);
50
51
52package Turnkey::CompoundEdge;
53
54use strict;
55use base qw(Turnkey::Edge);
56use Class::MakeMethods::Template::Hash (
57 new => ['new'],
58 object => [
59 'via' => {class => 'Turnkey::Node'},
60 ],
61 'array_of_objects -class Turnkey::Edge' => [ qw( edges ) ],
62);
c00bb9f8 63
88f2d2fd 64
65package SQL::Translator::Producer::Turnkey;
c00bb9f8 66
67use strict;
68use vars qw[ $VERSION $DEBUG ];
88f2d2fd 69$VERSION = sprintf "%d.%02d", q$Revision: 1.6 $ =~ /(\d+)\.(\d+)/;
c00bb9f8 70$DEBUG = 1 unless defined $DEBUG;
71
72use SQL::Translator::Schema::Constants;
73use SQL::Translator::Utils qw(header_comment);
74use Data::Dumper;
75use Template;
76
77my %CDBI_auto_pkgs = (
78 MySQL => 'mysql',
79 PostgreSQL => 'Pg',
80 Oracle => 'Oracle',
81);
82
83# -------------------------------------------------------------------
84sub produce {
85 my $t = shift;
86 my $create = undef;
c00bb9f8 87 my $no_comments = $t->no_comments;
88 my $schema = $t->schema;
89 my $args = $t->producer_args;
c00bb9f8 90
88f2d2fd 91 my $parser_type = (split /::/, $t->parser_type)[-1];
92
93 local $DEBUG = $t->debug;
94
95 my %meta = (
96 format_fk => $t->format_fk_name,
97 template => $args->{'template'} || '',
98 baseclass => $args->{'main_pkg_name'} || $t->format_package_name('DBI'),
99 db_user => $args->{'db_user'} || '',
100 db_pass => $args->{'db_pass'} || '',
101 parser => $t->parser_type,
102 producer => __PACKAGE__,
103 dsn => $args->{'dsn'} || sprintf( 'dbi:%s:_', $CDBI_auto_pkgs{ $parser_type }
104 ? $CDBI_auto_pkgs{ $parser_type }
105 : $parser_type
106 )
107 );
108
c00bb9f8 109
c8515c9f 110 #
111 # build package objects
112 #
88f2d2fd 113 my %nodes;
114 my $order;
69c7a62f 115 foreach my $table ($schema->get_tables){
88f2d2fd 116
69c7a62f 117 die __PACKAGE__." table ".$table->name." doesn't have a primary key!" unless $table->primary_key;
118 die __PACKAGE__." table ".$table->name." can't have a composite primary key!" if ($table->primary_key->fields)[1];
c00bb9f8 119
88f2d2fd 120 my $node = Turnkey::Node->new();
121 $nodes{ $table->name } = $node;
c00bb9f8 122
88f2d2fd 123 $node->order( ++$order );
124 $node->name( $t->format_package_name($table->name) );
125 $node->base( $meta{'baseclass'} );
126 $node->table( $table );
127 $node->primary_key( ($table->primary_key->fields)[0] );
69c7a62f 128 # Primary key may have a differenct accessor method name
88f2d2fd 129 $node->primary_key_accessor(
130 defined($t->format_pk_name)
131 ? $t->format_pk_name->( $node->name, $node->primary_key )
132 : undef
133 );
134 }
c8515c9f 135
88f2d2fd 136 foreach my $node (values %nodes){
137 foreach my $field ($node->table->get_fields){
c8515c9f 138 next unless $field->is_foreign_key;
139
88f2d2fd 140 my $that = $nodes{ $field->foreign_key_reference->reference_table };
141 #this means we have an incomplete schema
142 next unless $that;
143
144 my $edge = Turnkey::Edge->new(
145 type => 'import',
146 thisnode => $node,
147 thisfield => $field,
148 thatnode => $that,
149 thatfield => ($field->foreign_key_reference->reference_fields)[0]
150 );
151
152
153 $node->has($that->name, $node->has($that->name)+1);
154 $that->many($node->name, $that->many($node->name)+1);
155
156
157 $node->push_edges( $edge );
158 $that->push_edges( $edge->flip );
c8515c9f 159 }
69c7a62f 160 }
c00bb9f8 161
c8515c9f 162 #
88f2d2fd 163 # type MM relationships
c8515c9f 164 #
88f2d2fd 165 foreach my $lnode (sort values %nodes){
166 next if $lnode->table->is_data;
167 foreach my $inode1 (sort values %nodes){
168 next if $inode1 eq $lnode;
169
170 my @inode1_imports = grep { $_->type eq 'import' and $_->thatnode eq $inode1 } $lnode->edges;
171 next unless @inode1_imports;
c8515c9f 172
88f2d2fd 173 foreach my $inode2 (sort values %nodes){
174 my %i = map {$_->thatnode->name => 1} grep { $_->type eq 'import'} $lnode->edges;
175 if(scalar(keys %i) == 1) {
c8515c9f 176 } else {
88f2d2fd 177 last if $inode1 eq $inode2;
c00bb9f8 178 }
88f2d2fd 179
180 next if $inode2 eq $lnode;
181 my @inode2_imports = grep { $_->type eq 'import' and $_->thatnode eq $inode2 } $lnode->edges;
182 next unless @inode2_imports;
183
184 my $cedge = Turnkey::CompoundEdge->new();
185 $cedge->via($lnode);
186
187 $cedge->push_edges( map {$_->flip} grep {$_->type eq 'import' and ($_->thatnode eq $inode1 or $_->thatnode eq $inode2)} $lnode->edges);
188
189 if(scalar(@inode1_imports) == 1 and scalar(@inode2_imports) == 1){
190 $cedge->type('one2one');
191
192 $inode1->via($inode2->name,$inode1->via($inode2->name)+1);
193 $inode2->via($inode1->name,$inode2->via($inode1->name)+1);
194 }
195 elsif(scalar(@inode1_imports) > 1 and scalar(@inode2_imports) == 1){
196 $cedge->type('many2one');
197
198 $inode1->via($inode2->name,$inode1->via($inode2->name)+1);
199 $inode2->via($inode1->name,$inode2->via($inode1->name)+1);
200 }
201 elsif(scalar(@inode1_imports) == 1 and scalar(@inode2_imports) > 1){
202 #handled above
203 }
204 elsif(scalar(@inode1_imports) > 1 and scalar(@inode2_imports) > 1){
205 $cedge->type('many2many');
206
207 $inode1->via($inode2->name,$inode1->via($inode2->name)+1);
208 $inode2->via($inode1->name,$inode2->via($inode1->name)+1);
209 }
210
211 $inode1->push_compoundedges($cedge);
212 $inode2->push_compoundedges($cedge) unless $inode1 eq $inode2;
213
c00bb9f8 214 }
69c7a62f 215 }
216 }
217
218 #
c8515c9f 219 # create methods
69c7a62f 220 #
88f2d2fd 221 foreach my $node_from (values %nodes){
222 next unless $node_from->table->is_data;
223 foreach my $cedge ( $node_from->compoundedges ){
224 my $hyperedge = Turnkey::HyperEdge->new;
69c7a62f 225
88f2d2fd 226 my $node_to;
c8515c9f 227
88f2d2fd 228 foreach my $edge ($cedge->edges){
229 if($edge->thisnode->name eq $node_from->name){
230 $hyperedge->vianode($edge->thatnode);
c8515c9f 231
88f2d2fd 232 if($edge->thatnode->name ne $cedge->via->name){
233 $node_to ||= $nodes{ $edge->thatnode->table->name };
234 }
c8515c9f 235
88f2d2fd 236 $hyperedge->push_thisnode($edge->thisnode);
237 $hyperedge->push_thisfield($edge->thisfield);
238 $hyperedge->push_thisviafield($edge->thatfield);
c8515c9f 239
88f2d2fd 240 } else {
c8515c9f 241
88f2d2fd 242 if($edge->thisnode->name ne $cedge->via->name){
243 $node_to ||= $nodes{ $edge->thisnode->table->name };
244 }
c8515c9f 245
88f2d2fd 246 $hyperedge->push_thatnode($edge->thisnode);
247 $hyperedge->push_thatfield($edge->thisfield);
248 $hyperedge->push_thatviafield($edge->thatfield);
249 }
250 }
251
252 if($hyperedge->count_thisnode == 1 and $hyperedge->count_thatnode == 1){ $hyperedge->type('one2one') }
253 elsif($hyperedge->count_thisnode > 1 and $hyperedge->count_thatnode == 1){ $hyperedge->type('many2one') }
254 elsif($hyperedge->count_thisnode == 1 and $hyperedge->count_thatnode > 1){ $hyperedge->type('one2many') }
255 elsif($hyperedge->count_thisnode > 1 and $hyperedge->count_thatnode > 1){ $hyperedge->type('many2many') }
256
257#warn $node_from->name ."\t". $node_to->name ."\t". $hyperedge->type ."\t". $hyperedge->vianode->name;
258
259 $node_from->push_hyperedges($hyperedge);
260 }
c8515c9f 261 }
c00bb9f8 262
88f2d2fd 263 $meta{"nodes"} = \%nodes;
264 return(translateForm($t, \%meta));
c00bb9f8 265}
266
267###########################################
268# Here documents for the tt2 templates #
269###########################################
270
88f2d2fd 271my $turnkey_dbi_tt2 = <<EOF;
272[% MACRO printPackage(node) BLOCK %]
273# --------------------------------------------
274
275package [% node.name %];
276use base '[% node.base %]';
277use Class::DBI::Pager;
278
279[% node.name %]->set_up_table('[% node.table.name %]');
280[% printPKAccessors(node.primary_key, node.table.name) %]
281[% printHasA(node.edges, node) %]
282[% printHasMany(node.edges, node) %]
283[% printHasCompound(node.compoundedges, node.hyperedges, node.name) %]
284[% END %]
285
286[% MACRO printPKAccessors(array, name) BLOCK %]
287#
288# Primary key accessors
289#
290[% FOREACH item = array %]
291sub id { shift->[% item %] }
292sub [% name %] { shift->[% item %] }
293[% END %]
294[% END %]
295
296[% MACRO printHasA(edges, name) BLOCK %]
297#
298# Has A
299#
300[% FOREACH edge = edges %]
301 [%- IF edge.type == 'import' -%]
302[% node.name %]->has_a([% edge.thisfield.name %] => '[% edge.thatnode.name %]');
303 [%- IF node.has(edge.thatnode.name) < 2 %]
304sub [% edge.thatnode.table.name %] { return shift->[% edge.thisfield.name %] }
305 [%- ELSE %]
306sub [% format_fk(edge.thisnode.table.name,edge.thisfield.name) %] { return shift->[% edge.thisfield.name %] }
307 [%- END %]
308 [%- END %]
309[% END %]
310[% END %]
311
312[% MACRO printHasMany(edges, node) BLOCK %]
313#
314# Has Many
315#
316[% FOREACH edge = edges %]
317 [%- IF edge.type == 'export' -%]
318[% node.name %]->has_many([% edge.thatnode.table.name %]_[% edge.thatfield.name %], '[% edge.thatnode.name %]' => '[% edge.thatfield.name %]');
319 [%- IF node.via(edge.thatnode.name) >= 1 %]
320sub [% edge.thatnode.table.name %]_[% format_fk(edge.thatnode.table.name,edge.thatfield.name) %]s { return shift->[% edge.thatnode.table.name %]_[% edge.thatfield.name %] }
321 [%- ELSIF edge.thatnode.table.is_data %]
322sub [% edge.thatnode.table.name %]s { return shift->[% edge.thatnode.table.name %]_[% edge.thatfield.name %] }
323 [%- END %]
324 [%- END %]
325[% END %]
326[% END %]
327
328[% MACRO printHasCompound(cedges,hedges,name) BLOCK %]
329#
330# Has Compound Many
331#
332[% FOREACH cedge = cedges %]
333[% FOREACH edge = cedge.edges %]
334 [%- NEXT IF edge.thisnode.name != name -%]
335sub [% cedge.via.table.name %]_[% format_fk(edge.thatnode.table.name,edge.thatfield.name) %]s { return shift->[% cedge.via.table.name %]_[% edge.thatfield.name %] }
336[% END %]
337[% END %]
338[% FOREACH h = hedges %]
339 [%- NEXT IF h.thisnode.name != name -%]
340 [%- IF h.type == 'one2one' %]
3411sub [% h.thatnode.table.name %]s { my \$self = shift; return map \$_->[% h.thatviafield.name %], \$self->[% h.vianode.table.name %]_[% h.thisviafield.name %] }
342 [%- ELSIF h.type == 'one2many' %]
3432
344 [%- ELSIF h.type == 'many2one' %]
3453sub [% h.thatnode.table.name %]s { my \$self = shift; return map \$_->[% h.thatviafield.name %], \$self->[% h.vianode.table.name %]_[% h.thisviafield.name %] }
346 [%- ELSIF h.type == 'many2many' %]
3474
348 [%- END %]
349[% END %]
350[% END %]
351
352[% MACRO printList(array) BLOCK %][% FOREACH item = array %][% item %] [% END %][% END %]
353package [% baseclass %];
354
355# Created by SQL::Translator::Producer::Turnkey
356# Template used: classdbi
357
358use strict;
359use base qw(Class::DBI::Pg);
360
361Durian::Model::DBI->set_db('Main', '[% db_str %]', '[% db_user %]', '[% db_pass %]');
362
363[% FOREACH node = nodes %]
364 [% printPackage(node.value) %]
365[% END %]
366EOF
367
c00bb9f8 368my $turnkey_atom_tt2 = <<'EOF';
369[% ###### DOCUMENT START ###### %]
370
88f2d2fd 371[% FOREACH node = linkable %]
c00bb9f8 372
373##############################################
374
88f2d2fd 375package Durian::Atom::[% node.key FILTER ucfirst %];
c00bb9f8 376
88f2d2fd 377[% pname = node.key FILTER ucfirst%]
c00bb9f8 378[% pkey = "Durian::Model::${pname}" %]
379
380use base qw(Durian::Atom);
381use Data::Dumper;
382
383sub can_render {
384 return 1;
385}
386
387sub render {
388 my $self = shift;
389 my $dbobject = shift;
390 # Assumption here that if it's not rendering on it's own dbobject
391 # then it's a list. This will be updated when AtomLists are implemented -boconnor
88f2d2fd 392 if(ref($dbobject) eq 'Durian::Model::[% node.key FILTER ucfirst %]') {
c00bb9f8 393 return(_render_record($dbobject));
394 }
395 else { return(_render_list($dbobject)); }
396}
397
398sub _render_record {
399 my $dbobject = shift;
400 my @output = ();
401 my $row = {};
402 my $field_hash = {};
88f2d2fd 403 [% FOREACH field = nodes.$pkey.columns_essential %]
c00bb9f8 404 $field_hash->{[% field %]} = $dbobject->[% field %]();
405 [% END %]
406 $row->{data} = $field_hash;
407 $row->{id} = $dbobject->id();
408 push @output, $row;
409 return(\@output);
410}
411
412sub _render_list {
413 my $dbobject = shift;
414 my @output = ();
88f2d2fd 415 my @objects = $dbobject->[% node.key %]s;
c00bb9f8 416 foreach my $object (@objects)
417 {
418 my $row = {};
419 my $field_hash = {};
88f2d2fd 420 [% FOREACH field = nodes.$pkey.columns_essential %]
c00bb9f8 421 $field_hash->{[% field %]} = $object->[% field %]();
422 [% END %]
423 $row->{data} = $field_hash;
424 $row->{id} = $object->id();
425 push @output, $row;
426 }
427 return(\@output);
428}
429
430sub head {
431 return 1;
432}
433
4341;
435
436[% END %]
437EOF
438
c00bb9f8 439my $turnkey_xml_tt2 = <<EOF;
440<?xml version="1.0" encoding="UTF-8"?>
441<!DOCTYPE Durian SYSTEM "Durian.dtd">
442<Durian>
443
444<!-- The basic layout is fixed -->
445 <container bgcolor="#FFFFFF" cellpadding="0" cellspacing="0" height="90%" orientation="vertical" type="root" width="100%" xlink:label="RootContainer">
446 <container cellpadding="3" cellspacing="0" orientation="horizontal" type="container" height="100%" width="100%" xlink:label="MiddleContainer">
447 <container align="center" cellpadding="2" cellspacing="0" class="leftbar" orientation="vertical" type="minor" width="0%" xlink:label="MidLeftContainer"/>
448 <container cellpadding="0" cellspacing="0" orientation="vertical" width="100%" type="major" xlink:label="MainContainer"/>
449 </container>
450 </container>
451
452<!-- Atom Classes -->
88f2d2fd 453[% FOREACH node = linkable %]
454 <atom class="Durian::Atom::[% node.key FILTER ucfirst %]" name="[% node.key FILTER ucfirst %]" xlink:label="[% node.key FILTER ucfirst %]Atom"/>
69c7a62f 455[%- END -%]
c00bb9f8 456
457<!-- Atom Bindings -->
458<atomatombindings>
459[% FOREACH focus_atom = linkable %]
460 [% FOREACH link_atom = focus_atom.value %]
461 <atomatombinding xlink:from="#[% focus_atom.key FILTER ucfirst %]Atom" xlink:to="#[% link_atom.key FILTER ucfirst %]Atom" xlink:label="[% focus_atom.key FILTER ucfirst %]Atom2[% link_atom.key FILTER ucfirst %]Atom"/>
69c7a62f 462 [%- END -%]
463[%- END -%]
c00bb9f8 464</atomatombindings>
465
466<atomcontainerbindings>
69c7a62f 467[% FOREACH focus_atom = linkable %]
468 <atomcontainerbindingslayout xlink:label="Durian::Model::[% focus_atom.key FILTER ucfirst %]">
469 [% FOREACH link_atom = focus_atom.value %]
470 <atomcontainerbinding xlink:from="#MidLeftContainer" xlink:label="MidLeftContainer2[% link_atom.key FILTER ucfirst %]Atom" xlink:to="#[% link_atom.key FILTER ucfirst %]Atom"/>
471 [%- END -%]
472 <atomcontainerbinding xlink:from="#MainContainer" xlink:label="MainContainer2[% focus_atom.key FILTER ucfirst %]Atom" xlink:to="#[% focus_atom.key FILTER ucfirst %]Atom"/>
473 </atomcontainerbindingslayout>
474 [%- END -%]
475</atomcontainerbindings>
476
477<uribindings>
478 <uribinding uri="/" class="Durian::Util::Frontpage"/>
479</uribindings>
480
481<classbindings>
482[% FOREACH focus_atom = linkable %]
483 <classbinding class="Durian::Model::[% focus_atom.key FILTER ucfirst %]" plugin="#[% focus_atom.key FILTER ucfirst %]Atom" rank="0"/>
484[%- END -%]
c00bb9f8 485
69c7a62f 486</classbindings>
c00bb9f8 487
488</Durian>
489EOF
490
491my $turnkey_template_tt2 = <<'EOF';
492[% TAGS [- -] %]
493[% MACRO renderpanel(panel,dbobject) BLOCK %]
494 <!-- begin panel: [% panel.label %] -->
495 <table border="0" width="[% panel.width %]" height="[% panel.height %]" bgcolor="[% panel.bgcolor %]" valign="top" cellpadding="[% panel.cellpadding %]" cellspacing="[% panel.cellspacing %]" align="[% panel.align %]" valign="[% panel.valign %]">
496 <tr>
497 [% FOREACH p = panel.containers %]
498 [% IF p.can_render(panel) %]
499 <td valign="top" class="[% p.class %]" align="[% panel.align %]" height="[% p.height || 1 %]" width="[% p.width %]">
500 [% IF p.type == 'Container' %]
501 [% renderpanel(p,dbobject) %]
502 [% ELSE %]
503 <table cellpadding="0" cellspacing="0" align="left" height="100%" width="100%">
504 [% IF p.name %]
505 <tr bgcolor="#4444FF" height="1">
506 <td><font color="#FFFFFF">[% p.name %][% IF panel.type == 'major' %]: [% dbobject.name %][% END %]</font></td>
507 <td align="right" width="0"><!--<nobr><img src="/images/v.gif"/><img src="/images/^.gif"/>[% IF p.delible == 'yes' %]<img src="/images/x.gif"/>[% END %]</nobr>--></td>
508 </tr>
509 [% END %]
510 <tr><td colspan="2" bgcolor="#FFFFFF">
511 <!-- begin atom: [% p.label %] -->
512 <table cellpadding="0" cellspacing="0" align="left" height="100%" width="100%"><!-- [% ref(atom) %] [% ref(dbobject) %] -->
513 [% renderatom(p,dbobject) %] <!-- used to be renderplugin(p,panel) -->
514 </table>
515 </table>
516 [% END %]
517 </td>
518 [% IF panel.orientation == 'vertical' %]
519 </tr><tr>
520 [% END %]
521 [% END %]
522 [% END %]
523 </tr>
524 </table>
525 <!-- end panel: [% panel.label %] -->
526[% END %]
527[% MACRO renderatom(atom, dbobject) SWITCH atom.name %]
88f2d2fd 528 [- FOREACH node = linkable -]
529 [% CASE '[- node.key FILTER ucfirst -]' %]
530 [% render[- node.key FILTER ucfirst -]Atom(atom.render(dbobject)) %]
c00bb9f8 531 [- END -]
532 [% CASE DEFAULT %]
533 [% renderlist(atom.render(dbobject)) %]
534[% END %]
88f2d2fd 535[- FOREACH node = linkable -]
536[% MACRO render[- node.key FILTER ucfirst -]Atom(lstArr) BLOCK %]
c00bb9f8 537 [% FOREACH record = lstArr %]
538 [% fields = record.data %]
88f2d2fd 539 [- pname = node.key FILTER ucfirst -]
c00bb9f8 540 [- pkey = "Durian::Model::${pname}" -]
88f2d2fd 541 [- FOREACH field = nodes.$pkey.columns_essential -]
c00bb9f8 542 <tr><td><b>[- field -]</b></td><td>[% fields.[- field -] %]</td></tr>
543 [- END -]
544 [% id = record.id %]
88f2d2fd 545 <tr><td><a href="?id=[% id %];class=Durian::Model::[- node.key FILTER ucfirst -]">Link</a></td><td></td></tr>
c00bb9f8 546 [% END %]
547[% END %]
548[- END -]
549[% MACRO renderlist(lstArr) BLOCK %]
550 [% FOREACH item = lstArr %]
551 <tr>[% item %]</tr>
552 [% END %]
553[% END %]
554EOF
555
88f2d2fd 556
c00bb9f8 557sub translateForm
558{
559 my $t = shift;
88f2d2fd 560 my $meta = shift;
561# my $output = shift;
c00bb9f8 562 my $args = $t->producer_args;
88f2d2fd 563 my $tt2 = $meta->{'template'};
c00bb9f8 564 my $tt2Ref;
69c7a62f 565
566 if ($tt2 eq 'atom') { $tt2Ref = \$turnkey_atom_tt2; }
567 elsif ($tt2 eq 'classdbi') { $tt2Ref = \$turnkey_dbi_tt2; }
568 elsif ($tt2 eq 'xml') { $tt2Ref = \$turnkey_xml_tt2; }
569 elsif ($tt2 eq 'template') { $tt2Ref = \$turnkey_template_tt2; }
570 else { die __PACKAGE__." didn't recognize your template option: $tt2" }
c00bb9f8 571
c00bb9f8 572 my $config = {
573 EVAL_PERL => 1, # evaluate Perl code blocks
574 };
575
576 # create Template object
577 my $template = Template->new($config);
578
579 my $result;
580 # specify input filename, or file handle, text reference, etc.
581 # process input template, substituting variables
88f2d2fd 582 $template->process($tt2Ref, $meta, \$result) || die $template->error();
c00bb9f8 583 return($result);
584}
585
5861;
587
588# -------------------------------------------------------------------
589
590=pod
591
592=head1 NAME
593
bcb3dbd2 594SQL::Translator::Producer::Turnkey - create Turnkey classes from schema
c00bb9f8 595
596=head1 SYNOPSIS
597
bcb3dbd2 598Creates output for use with the Turnkey project.
c00bb9f8 599
bcb3dbd2 600=head1 SEE ALSO
601
602L<http://turnkey.sourceforge.net>.
c00bb9f8 603
604=head1 AUTHORS
605
606Allen Day E<lt>allenday@ucla.eduE<gt>
607Ying Zhang E<lt>zyolive@yahoo.comE<gt>,
bcb3dbd2 608Brian O'Connor E<lt>brian.oconnor@excite.comE<gt>.