Commit | Line | Data |
69c7a62f |
1 | package Turnkey::Package; |
2 | |
3 | use strict; |
4 | use Class::MakeMethods::Template::Hash ( |
5 | new => [ 'new' ], |
6 | hash => [ qw( many ) ], |
7 | hash_of_arrays => [ qw( many_via) ], |
8 | scalar => [ qw( base name order primary_key primary_key_accessor table) ], |
9 | ); |
10 | |
11 | |
12 | # get_set => [ qw(order base name table primary_key primary_key_accessor) ], |
13 | # new_with_init => 'new', |
14 | #; |
15 | |
16 | sub init { |
17 | } |
18 | |
19 | 1; |
20 | |
c00bb9f8 |
21 | package SQL::Translator::Producer::Turnkey; |
22 | |
23 | # ------------------------------------------------------------------- |
69c7a62f |
24 | # $Id: Turnkey.pm,v 1.2 2003-08-29 05:38:56 allenday Exp $ |
c00bb9f8 |
25 | # ------------------------------------------------------------------- |
26 | # Copyright (C) 2003 Allen Day <allenday@ucla.edu>, |
69c7a62f |
27 | # Brian O'Connor <boconnor@ucla.edu>, |
c00bb9f8 |
28 | # Ying Zhang <zyolive@yahoo.com> |
29 | # |
30 | # This program is free software; you can redistribute it and/or |
31 | # modify it under the terms of the GNU General Public License as |
32 | # published by the Free Software Foundation; version 2. |
33 | # |
34 | # This program is distributed in the hope that it will be useful, but |
35 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
36 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
37 | # General Public License for more details. |
38 | # |
39 | # You should have received a copy of the GNU General Public License |
40 | # along with this program; if not, write to the Free Software |
41 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
42 | # 02111-1307 USA |
43 | # ------------------------------------------------------------------- |
44 | |
45 | use strict; |
46 | use vars qw[ $VERSION $DEBUG ]; |
69c7a62f |
47 | $VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/; |
c00bb9f8 |
48 | $DEBUG = 1 unless defined $DEBUG; |
49 | |
50 | use SQL::Translator::Schema::Constants; |
51 | use SQL::Translator::Utils qw(header_comment); |
52 | use Data::Dumper; |
53 | use Template; |
54 | |
55 | my %CDBI_auto_pkgs = ( |
56 | MySQL => 'mysql', |
57 | PostgreSQL => 'Pg', |
58 | Oracle => 'Oracle', |
59 | ); |
60 | |
61 | # ------------------------------------------------------------------- |
62 | sub produce { |
63 | my $t = shift; |
64 | my $create = undef; |
65 | local $DEBUG = $t->debug; |
66 | my $no_comments = $t->no_comments; |
67 | my $schema = $t->schema; |
68 | my $args = $t->producer_args; |
69 | my $db_user = $args->{'db_user'} || ''; |
70 | my $db_pass = $args->{'db_pass'} || ''; |
71 | my $main_pkg_name = $args->{'main_pkg_name'} || |
72 | $t->format_package_name('DBI'); |
73 | my $header = header_comment(__PACKAGE__, "# "); |
74 | my $parser_type = ( split /::/, $t->parser_type )[-1]; |
75 | my $from = $CDBI_auto_pkgs{ $parser_type } || ''; |
76 | my $dsn = $args->{'dsn'} || sprintf( 'dbi:%s:_', |
77 | $CDBI_auto_pkgs{ $parser_type } |
78 | ? $CDBI_auto_pkgs{ $parser_type } : $parser_type |
79 | ); |
80 | my $sep = '# ' . '-' x 67; |
81 | |
82 | # |
83 | # Identify "link tables" (have only PK and FK fields). |
84 | # |
85 | my %linkable; |
86 | my %linktable; |
69c7a62f |
87 | my %packages; |
88 | my $order; |
c00bb9f8 |
89 | |
c00bb9f8 |
90 | |
69c7a62f |
91 | foreach my $table ($schema->get_tables){ |
92 | die __PACKAGE__." table ".$table->name." doesn't have a primary key!" unless $table->primary_key; |
93 | die __PACKAGE__." table ".$table->name." can't have a composite primary key!" if ($table->primary_key->fields)[1]; |
c00bb9f8 |
94 | |
c00bb9f8 |
95 | |
69c7a62f |
96 | my $package = Turnkey::Package->new(); |
97 | $packages{ $package->name } = $package; |
c00bb9f8 |
98 | |
69c7a62f |
99 | $package->order( ++$order ); |
100 | $package->name( $t->format_package_name($table->name) ); |
101 | $package->base( $main_pkg_name ); |
102 | $package->table( $table ); |
103 | $package->primary_key( ($table->primary_key->fields)[0] ); |
104 | # Primary key may have a differenct accessor method name |
105 | $package->primary_key_accessor( |
106 | defined($t->format_pk_name) ? $t->format_pk_name->( $package->name, $package->primary_key ) |
107 | : undef |
108 | ); |
109 | } |
c00bb9f8 |
110 | |
69c7a62f |
111 | foreach my $maylink ( $schema->get_tables ){ |
112 | foreach my $left ($schema->get_tables){ |
113 | foreach my $right ($schema->get_tables){ |
114 | |
115 | next if $left->name eq $right->name; |
116 | |
117 | if( $maylink->can_link($left,$right) ){ |
118 | |
119 | $lpackage = $packages{$left->name}; |
120 | $rpackage = $packages{$right->name}; |
121 | |
122 | $lpackage->many_via($rpackage => $maylink); |
123 | $rpackage->many_via($lpackage => $maylink); |
124 | # $linktable{ $maylink->name } = $maylink; |
c00bb9f8 |
125 | } |
69c7a62f |
126 | |
c00bb9f8 |
127 | } |
69c7a62f |
128 | } |
129 | } |
130 | |
131 | # |
132 | # Iterate over all tables |
133 | # |
134 | for my $table_from ( $schema->get_tables ) { |
135 | my %linked; |
c00bb9f8 |
136 | |
69c7a62f |
137 | |
138 | next unless $table_from->is_data; |
139 | |
140 | if($table_from->is_data){ |
141 | foreach my $link ( keys %{ $linkable{ $table_from->name } } ) { |
142 | my $linkmethodname; |
c00bb9f8 |
143 | |
144 | if ( my $fk_xform = $t->format_fk_name ) { |
145 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
69c7a62f |
146 | $linkmethodname = $fk_xform->($linkable{$table->name}{$link}->name, |
c00bb9f8 |
147 | ($schema->get_table($link)->primary_key->fields)[0]).'s'; |
148 | } else { |
149 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
69c7a62f |
150 | $linkmethodname = $linkable{$table->name}{$link}->name.'_'. |
c00bb9f8 |
151 | ($schema->get_table($link)->primary_key->fields)[0].'s'; |
152 | } |
153 | |
154 | my @rk_fields = (); |
155 | my @lk_fields = (); |
69c7a62f |
156 | foreach my $field ($linkable{$table->name}{$link}->get_fields) { |
c00bb9f8 |
157 | next unless $field->is_foreign_key; |
158 | |
159 | next unless( |
69c7a62f |
160 | $field->foreign_key_reference->reference_table eq $table->name |
c00bb9f8 |
161 | || |
162 | $field->foreign_key_reference->reference_table eq $link |
163 | ); |
164 | push @lk_fields, ($field->foreign_key_reference->reference_fields)[0] |
165 | if $field->foreign_key_reference->reference_table eq $link; |
166 | push @rk_fields, $field->name |
69c7a62f |
167 | if $field->foreign_key_reference->reference_table eq $table->name; |
c00bb9f8 |
168 | } |
169 | |
170 | #if one possible traversal via link table |
171 | if (scalar(@rk_fields) == 1 and scalar(@lk_fields) == 1) { |
172 | foreach my $rk_field (@rk_fields) { |
173 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link } }, |
69c7a62f |
174 | push @{ $packages{ $package->name }{'has_many'}{$link}{'link_one_one'} }, |
c00bb9f8 |
175 | "sub ".$linkmethodname." { my \$self = shift; ". |
176 | "return map \$_->". |
177 | ($schema->get_table($link)->primary_key->fields)[0]. |
69c7a62f |
178 | ", \$self->".$linkable{$table->name}{$link}->name. |
c00bb9f8 |
179 | "_".$rk_field." }\n\n"; |
180 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link }{'one_one'} }, |
181 | # {link_method_name => $linkmethodname, primary_key_field => ($schema->get_table($link)->primary_key->fields)[0], |
182 | # table_name => $linkable{$table_name}{$link}->name, rk_field => $rk_field}; |
183 | } |
184 | #else there is more than one way to traverse it. ack! |
185 | #let's treat these types of link tables as a many-to-one (easier) |
186 | # |
187 | #NOTE: we need to rethink the link method name, as the cardinality |
188 | #has shifted on us. |
189 | } elsif (scalar(@rk_fields) == 1) { |
190 | foreach my $rk_field (@rk_fields) { |
191 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
192 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link } }, |
69c7a62f |
193 | push @{ $packages{ $package->name }{'has_many'}{ $link }{'link_many_one'} }, |
194 | "sub " . $linkable{$table->name}{$link}->name . |
c00bb9f8 |
195 | "s { my \$self = shift; return \$self->" . |
69c7a62f |
196 | $linkable{$table->name}{$link}->name . "_" . |
c00bb9f8 |
197 | $rk_field . "(\@_) }\n\n"; |
198 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link }{'many_one'} }, |
199 | # { |
200 | # table_name => $linkable{$table_name}{$link}->name, rk_field => $rk_field |
201 | # }; |
202 | } |
203 | } elsif (scalar(@lk_fields) == 1) { |
204 | #these will be taken care of on the other end... |
205 | } else { |
206 | #many many many. need multiple iterations here, data structure revision |
207 | #to handle N FK sources. This code has not been tested and likely doesn't |
208 | #work here |
209 | foreach my $rk_field (@rk_fields) { |
210 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
211 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link } }, |
69c7a62f |
212 | push @{ $packages{ $package->name }{'has_many'}{ $link }{'link_many_many'} }, |
213 | "sub " . $linkable{$table->name}{$link}->name . "_" . $rk_field . |
c00bb9f8 |
214 | "s { my \$self = shift; return \$self->" . |
69c7a62f |
215 | $linkable{$table->name}{$link}->name . "_" . |
c00bb9f8 |
216 | $rk_field . "(\@_) }\n\n"; |
217 | #push @{ $packages{ $table_pkg_name }{'has_many'}{ $link }{'many_many'} }, |
218 | # { |
219 | # table_name => $linkable{$table_name}{$link}->name, rk_field => $rk_field |
220 | # }; |
221 | } |
222 | } |
223 | } |
224 | } |
225 | |
226 | |
227 | # |
228 | # Use foreign keys to set up "has_a/has_many" relationships. |
229 | # |
230 | foreach my $field ( $table->get_fields ) { |
231 | if ( $field->is_foreign_key ) { |
232 | my $table_name = $table->name; |
233 | my $field_name = $field->name; |
234 | my $fk_method = $t->format_fk_name($table_name, $field_name); |
235 | my $fk = $field->foreign_key_reference; |
236 | my $ref_table = $fk->reference_table; |
237 | my $ref_pkg = $t->format_package_name($ref_table); |
238 | my $ref_field = ($fk->reference_fields)[0]; |
239 | |
69c7a62f |
240 | push @{ $packages{ $package->name }{'has_a'} }, |
241 | $package->name."->has_a( $field_name => '$ref_pkg');\n". |
242 | "sub $fk_method { return shift->$field_name }\n\n" |
c00bb9f8 |
243 | ; |
244 | |
245 | |
246 | # |
247 | # If this table "has a" to the other, then it follows |
248 | # that the other table "has many" of this one, right? |
249 | # |
250 | # No... there is the possibility of 1-1 cardinality |
251 | |
252 | #if there weren't M-M relationships via the has_many |
253 | #being set up here, create nice pluralized method alias |
254 | #rather for user as alt. to ugly tablename_fieldname name |
69c7a62f |
255 | if(! $packages{ $ref_pkg }{ 'has_many' }{ $table->name } ){ |
c00bb9f8 |
256 | # ADD CALLBACK FOR PLURALIZATION MANGLING HERE |
257 | #push @{ $packages{ $ref_pkg }{'has_many'}{ $table_name } }, |
258 | # "sub $table_name\s {\n return shift->$table_name\_$field_name\n}\n\n"; |
69c7a62f |
259 | push @{ $packages{ $ref_pkg }{'has_many'}{ $table->name }{'fk_pluralized'} }, |
260 | { table_name => $table->name, field_name => $field_name }; |
c00bb9f8 |
261 | |
262 | #else ugly |
263 | } else { |
264 | } |
265 | |
266 | #push @{ $packages{ $ref_pkg }{'has_many'}{ $table_name } }, |
267 | # "$ref_pkg->has_many(\n '${table_name}_${field_name}', ". |
268 | # "'$table_pkg_name' => '$field_name'\n);\n\n"; |
269 | push @{ $packages{ $ref_pkg }{'has_many'}{ $table_name }{pluralized} }, |
69c7a62f |
270 | { ref_pkg => $ref_pkg, table_pkg_name => $package->name, table_name => $table->name, field_name => $field_name }; |
c00bb9f8 |
271 | } |
272 | } |
273 | } |
274 | |
275 | my %metadata; |
276 | $metadata{"packages"} = \%packages; |
277 | $metadata{"linkable"} = \%linkable; |
278 | return(translateForm($t, \%metadata)); |
279 | } |
280 | |
281 | ########################################### |
282 | # Here documents for the tt2 templates # |
283 | ########################################### |
284 | |
285 | my $turnkey_atom_tt2 = <<'EOF'; |
286 | [% ###### DOCUMENT START ###### %] |
287 | |
288 | [% FOREACH package = linkable %] |
289 | |
290 | ############################################## |
291 | |
292 | package Durian::Atom::[% package.key FILTER ucfirst %]; |
293 | |
294 | [% pname = package.key FILTER ucfirst%] |
295 | [% pkey = "Durian::Model::${pname}" %] |
296 | |
297 | use base qw(Durian::Atom); |
298 | use Data::Dumper; |
299 | |
300 | sub can_render { |
301 | return 1; |
302 | } |
303 | |
304 | sub render { |
305 | my $self = shift; |
306 | my $dbobject = shift; |
307 | # Assumption here that if it's not rendering on it's own dbobject |
308 | # then it's a list. This will be updated when AtomLists are implemented -boconnor |
309 | if(ref($dbobject) eq 'Durian::Model::[% package.key FILTER ucfirst %]') { |
310 | return(_render_record($dbobject)); |
311 | } |
312 | else { return(_render_list($dbobject)); } |
313 | } |
314 | |
315 | sub _render_record { |
316 | my $dbobject = shift; |
317 | my @output = (); |
318 | my $row = {}; |
319 | my $field_hash = {}; |
320 | [% FOREACH field = packages.$pkey.columns_essential %] |
321 | $field_hash->{[% field %]} = $dbobject->[% field %](); |
322 | [% END %] |
323 | $row->{data} = $field_hash; |
324 | $row->{id} = $dbobject->id(); |
325 | push @output, $row; |
326 | return(\@output); |
327 | } |
328 | |
329 | sub _render_list { |
330 | my $dbobject = shift; |
331 | my @output = (); |
332 | my @objects = $dbobject->[% package.key %]s; |
333 | foreach my $object (@objects) |
334 | { |
335 | my $row = {}; |
336 | my $field_hash = {}; |
337 | [% FOREACH field = packages.$pkey.columns_essential %] |
338 | $field_hash->{[% field %]} = $object->[% field %](); |
339 | [% END %] |
340 | $row->{data} = $field_hash; |
341 | $row->{id} = $object->id(); |
342 | push @output, $row; |
343 | } |
344 | return(\@output); |
345 | } |
346 | |
347 | sub head { |
348 | return 1; |
349 | } |
350 | |
351 | 1; |
352 | |
353 | [% END %] |
354 | EOF |
355 | |
356 | my $turnkey_dbi_tt2 = <<EOF; |
357 | [% ####### MACRO START ###### %] |
358 | |
359 | [% MACRO printPackage(package) BLOCK %] |
360 | # -------------------------------------------- |
361 | package [% package.pkg_name %]; |
362 | use base '[% package.base %]'; |
363 | use Class::DBI::Pager; |
364 | |
365 | [% package.pkg_name %]->set_up_table('[% package.table %]'); |
366 | [% package.pkg_name %]->columns(Primary => qw/[% printList(package.columns_primary) %]/); |
367 | [% package.pkg_name %]->columns(Essential => qw/[% printList(package.columns_essential) %]/); |
368 | |
369 | [% printPKAccessors(package.columns_primary, package.table) %] |
370 | [% printHasMany(package.has_many, package.table) %] |
371 | [% printHasA(package.has_a, package.pkg_name) %] |
372 | |
373 | [% END %] |
374 | |
375 | [% MACRO printPKAccessors(array, name) BLOCK %] |
376 | # |
377 | # Primary key accessor |
378 | # |
379 | [% FOREACH item = array %] |
380 | sub [% name %] { |
381 | shift->[% item %]; |
382 | } |
383 | [% END %] |
384 | [% END %] |
385 | |
386 | [% MACRO printHasMany(hash, name) BLOCK %] |
387 | # |
388 | # Has Many |
389 | # |
390 | [% FOREACH group = hash %][% FOREACH item = group.value %][% FOREACH arr = item.value %] |
391 | # Key: [% group.key %] |
392 | # Relationship: [% item.key %] |
393 | [% IF item.key == 'fk_pluralized' %] |
394 | sub [% arr.table_name -%]s { |
395 | return shift->[% arr.table_name %]_[% arr.field_name %] |
396 | }; |
397 | [% ELSIF item.key == 'pluralized' %] |
398 | [% arr.ref_pkg %]->has_many('[% arr.table_name %]_[% arr.field_name %]', '[% arr.table_pkg_name %]' => '[% arr.field_name %]'); |
399 | [% ELSIF item.key == 'link_one_one' %] |
400 | [% FOREACH line = item.value %] |
401 | [% line %] |
402 | [% END %] |
403 | [% ELSIF item.key == 'link_many_one' %] |
404 | [% FOREACH line = item.value %] |
405 | [% line %] |
406 | [% END %] |
407 | [% ELSIF item.key == 'link_many_many' %] |
408 | [% FOREACH line = item.value %] |
409 | [% line %] |
410 | [% END %] |
411 | [% END %] |
412 | |
413 | [% END %][% END %][% END %][% END %] |
414 | |
415 | [% MACRO printHasA(hash, pkg_name) BLOCK %] |
416 | # |
417 | # Has A |
418 | # |
419 | [% #name %] |
420 | [% FOREACH item = hash %][% item %] |
421 | [% END %][% END %] |
422 | |
423 | [% MACRO printList(array) BLOCK %][% FOREACH item = array %][% item %] [% END %][% END %] |
424 | |
425 | |
426 | [% ###### DOCUMENT START ###### %] |
427 | |
428 | package Durian::Model::DBI; |
429 | |
430 | # Created by SQL::Translator::Producer::ClassDBI |
431 | # Template used AutoDBI.tt2 |
432 | |
433 | use strict; |
434 | use base qw(Class::DBI::Pg); |
435 | |
436 | Durian::Model::DBI->set_db('Main', '[% db_str %]', '[% db_user %]', '[% db_pass %]'); |
437 | |
438 | [% FOREACH package = packages %] |
439 | [% printPackage(package.value) %] |
440 | [% END %] |
441 | EOF |
442 | |
443 | my $turnkey_xml_tt2 = <<EOF; |
444 | <?xml version="1.0" encoding="UTF-8"?> |
445 | <!DOCTYPE Durian SYSTEM "Durian.dtd"> |
446 | <Durian> |
447 | |
448 | <!-- The basic layout is fixed --> |
449 | <container bgcolor="#FFFFFF" cellpadding="0" cellspacing="0" height="90%" orientation="vertical" type="root" width="100%" xlink:label="RootContainer"> |
450 | <container cellpadding="3" cellspacing="0" orientation="horizontal" type="container" height="100%" width="100%" xlink:label="MiddleContainer"> |
451 | <container align="center" cellpadding="2" cellspacing="0" class="leftbar" orientation="vertical" type="minor" width="0%" xlink:label="MidLeftContainer"/> |
452 | <container cellpadding="0" cellspacing="0" orientation="vertical" width="100%" type="major" xlink:label="MainContainer"/> |
453 | </container> |
454 | </container> |
455 | |
456 | <!-- Atom Classes --> |
457 | [% FOREACH package = linkable %] |
458 | <atom class="Durian::Atom::[% package.key FILTER ucfirst %]" name="[% package.key FILTER ucfirst %]" xlink:label="[% package.key FILTER ucfirst %]Atom"/> |
69c7a62f |
459 | [%- END -%] |
c00bb9f8 |
460 | |
461 | <!-- Atom Bindings --> |
462 | <atomatombindings> |
463 | [% FOREACH focus_atom = linkable %] |
464 | [% FOREACH link_atom = focus_atom.value %] |
465 | <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 |
466 | [%- END -%] |
467 | [%- END -%] |
c00bb9f8 |
468 | </atomatombindings> |
469 | |
470 | <atomcontainerbindings> |
69c7a62f |
471 | [% FOREACH focus_atom = linkable %] |
472 | <atomcontainerbindingslayout xlink:label="Durian::Model::[% focus_atom.key FILTER ucfirst %]"> |
473 | [% FOREACH link_atom = focus_atom.value %] |
474 | <atomcontainerbinding xlink:from="#MidLeftContainer" xlink:label="MidLeftContainer2[% link_atom.key FILTER ucfirst %]Atom" xlink:to="#[% link_atom.key FILTER ucfirst %]Atom"/> |
475 | [%- END -%] |
476 | <atomcontainerbinding xlink:from="#MainContainer" xlink:label="MainContainer2[% focus_atom.key FILTER ucfirst %]Atom" xlink:to="#[% focus_atom.key FILTER ucfirst %]Atom"/> |
477 | </atomcontainerbindingslayout> |
478 | [%- END -%] |
479 | </atomcontainerbindings> |
480 | |
481 | <uribindings> |
482 | <uribinding uri="/" class="Durian::Util::Frontpage"/> |
483 | </uribindings> |
484 | |
485 | <classbindings> |
486 | [% FOREACH focus_atom = linkable %] |
487 | <classbinding class="Durian::Model::[% focus_atom.key FILTER ucfirst %]" plugin="#[% focus_atom.key FILTER ucfirst %]Atom" rank="0"/> |
488 | [%- END -%] |
c00bb9f8 |
489 | |
69c7a62f |
490 | </classbindings> |
c00bb9f8 |
491 | |
492 | </Durian> |
493 | EOF |
494 | |
495 | my $turnkey_template_tt2 = <<'EOF'; |
496 | [% TAGS [- -] %] |
497 | [% MACRO renderpanel(panel,dbobject) BLOCK %] |
498 | <!-- begin panel: [% panel.label %] --> |
499 | <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 %]"> |
500 | <tr> |
501 | [% FOREACH p = panel.containers %] |
502 | [% IF p.can_render(panel) %] |
503 | <td valign="top" class="[% p.class %]" align="[% panel.align %]" height="[% p.height || 1 %]" width="[% p.width %]"> |
504 | [% IF p.type == 'Container' %] |
505 | [% renderpanel(p,dbobject) %] |
506 | [% ELSE %] |
507 | <table cellpadding="0" cellspacing="0" align="left" height="100%" width="100%"> |
508 | [% IF p.name %] |
509 | <tr bgcolor="#4444FF" height="1"> |
510 | <td><font color="#FFFFFF">[% p.name %][% IF panel.type == 'major' %]: [% dbobject.name %][% END %]</font></td> |
511 | <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> |
512 | </tr> |
513 | [% END %] |
514 | <tr><td colspan="2" bgcolor="#FFFFFF"> |
515 | <!-- begin atom: [% p.label %] --> |
516 | <table cellpadding="0" cellspacing="0" align="left" height="100%" width="100%"><!-- [% ref(atom) %] [% ref(dbobject) %] --> |
517 | [% renderatom(p,dbobject) %] <!-- used to be renderplugin(p,panel) --> |
518 | </table> |
519 | </table> |
520 | [% END %] |
521 | </td> |
522 | [% IF panel.orientation == 'vertical' %] |
523 | </tr><tr> |
524 | [% END %] |
525 | [% END %] |
526 | [% END %] |
527 | </tr> |
528 | </table> |
529 | <!-- end panel: [% panel.label %] --> |
530 | [% END %] |
531 | [% MACRO renderatom(atom, dbobject) SWITCH atom.name %] |
532 | [- FOREACH package = linkable -] |
533 | [% CASE '[- package.key FILTER ucfirst -]' %] |
534 | [% render[- package.key FILTER ucfirst -]Atom(atom.render(dbobject)) %] |
535 | [- END -] |
536 | [% CASE DEFAULT %] |
537 | [% renderlist(atom.render(dbobject)) %] |
538 | [% END %] |
539 | [- FOREACH package = linkable -] |
540 | [% MACRO render[- package.key FILTER ucfirst -]Atom(lstArr) BLOCK %] |
541 | [% FOREACH record = lstArr %] |
542 | [% fields = record.data %] |
543 | [- pname = package.key FILTER ucfirst -] |
544 | [- pkey = "Durian::Model::${pname}" -] |
545 | [- FOREACH field = packages.$pkey.columns_essential -] |
546 | <tr><td><b>[- field -]</b></td><td>[% fields.[- field -] %]</td></tr> |
547 | [- END -] |
548 | [% id = record.id %] |
549 | <tr><td><a href="?id=[% id %];class=Durian::Model::[- package.key FILTER ucfirst -]">Link</a></td><td></td></tr> |
550 | [% END %] |
551 | [% END %] |
552 | [- END -] |
553 | [% MACRO renderlist(lstArr) BLOCK %] |
554 | [% FOREACH item = lstArr %] |
555 | <tr>[% item %]</tr> |
556 | [% END %] |
557 | [% END %] |
558 | EOF |
559 | |
560 | sub translateForm |
561 | { |
562 | my $t = shift; |
563 | my $output = shift; |
564 | my $args = $t->producer_args; |
565 | my $tt2 = $args->{'template'}; |
566 | my $tt2Ref; |
69c7a62f |
567 | |
568 | if ($tt2 eq 'atom') { $tt2Ref = \$turnkey_atom_tt2; } |
569 | elsif ($tt2 eq 'classdbi') { $tt2Ref = \$turnkey_dbi_tt2; } |
570 | elsif ($tt2 eq 'xml') { $tt2Ref = \$turnkey_xml_tt2; } |
571 | elsif ($tt2 eq 'template') { $tt2Ref = \$turnkey_template_tt2; } |
572 | else { die __PACKAGE__." didn't recognize your template option: $tt2" } |
c00bb9f8 |
573 | |
574 | my $vars = { |
575 | packages => $output->{packages}, |
576 | linkable => $output->{linkable}, |
577 | linktable => $output->{linktable}, |
578 | db_str => $args->{db_str}, |
579 | db_user => $args->{db_user}, |
580 | db_pass => $args->{db_pass}, |
581 | }; |
582 | my $config = { |
583 | EVAL_PERL => 1, # evaluate Perl code blocks |
584 | }; |
585 | |
586 | # create Template object |
587 | my $template = Template->new($config); |
588 | |
589 | my $result; |
590 | # specify input filename, or file handle, text reference, etc. |
591 | # process input template, substituting variables |
592 | $template->process($tt2Ref, $vars, \$result) || die $template->error(); |
593 | return($result); |
594 | } |
595 | |
596 | 1; |
597 | |
598 | # ------------------------------------------------------------------- |
599 | |
600 | =pod |
601 | |
602 | =head1 NAME |
603 | |
604 | SQL::Translator::Producer::ClassDBI - create Class::DBI classes from schema |
605 | |
606 | =head1 SYNOPSIS |
607 | |
608 | Use this producer as you would any other from SQL::Translator. See |
609 | L<SQL::Translator> for details. |
610 | |
69c7a62f |
611 | This package utilizes SQL::Translator\'s formatting methods |
c00bb9f8 |
612 | format_package_name(), format_pk_name(), format_fk_name(), and |
613 | format_table_name() as it creates classes, one per table in the schema |
614 | provided. An additional base class is also created for database connectivity |
615 | configuration. See L<Class::DBI> for details on how this works. |
616 | |
617 | =head1 AUTHORS |
618 | |
619 | Allen Day E<lt>allenday@ucla.eduE<gt> |
620 | Ying Zhang E<lt>zyolive@yahoo.comE<gt>, |
621 | Ken Y. Clark E<lt>kclark@cpan.orgE<gt>, |
69c7a62f |
622 | Brian O\'Connor E<lt>brian.oconnor@excite.comE<gt>. |