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